Skip to content

Commit

Permalink
wip: Provide additional details information about the browser capabil…
Browse files Browse the repository at this point in the history
…ities #1005
  • Loading branch information
cnouguier committed Dec 6, 2024
1 parent 4b5f5f9 commit c8992c5
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 62 deletions.
9 changes: 4 additions & 5 deletions core/client/components/action/KBugReportAction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import _ from 'lodash'
import config from 'config'
import { ref } from 'vue'
import { i18n } from '../../i18n'
import { getPlatform } from '../../utils/utils.platform'
import { actionProps } from '../../utils/utils.actions'
import { i18n } from '../../i18n.js'
import { Platform } from '../../platform.js'
import { actionProps } from '../../utils/utils.actions.js'
import { useVersion } from '../../composables'
import KAction from './KAction.vue'
Expand All @@ -20,7 +20,6 @@ const props = defineProps(_.omit(actionProps, ['toggle', 'url', 'handler', 'rout
// Data
const { clientVersionName, apiVersionName } = useVersion()
const platform = getPlatform()
// Setup bug report info
const bugReport = {
Expand All @@ -32,8 +31,8 @@ const bugReport = {
}),
body: i18n.t('KAbout.BUG_REPORT_BODY')
}
_.forOwn(platform, (value, key) => { bugReport.body += `${key}: ${value}%0D%0A` })
bugReport.body += `domain: ${_.get(config, 'domain')}%0D%0A`
bugReport.body += `flavor: ${_.get(config, 'flavor')}%0D%0A`
bugReport.body += JSON.stringify(Platform.getData(), null, 2)
const url = ref(`mailto:${bugReport.address}?subject=${bugReport.subject}&body=${bugReport.body}`)
</script>
158 changes: 123 additions & 35 deletions core/client/components/app/KPlatform.vue
Original file line number Diff line number Diff line change
@@ -1,48 +1,136 @@
<template>
<q-markup-table>
<thead class="bg-grey-3">
<tr>
<th class="text-left">{{ $t('KPlatform.PROPERTY') }}</th>
<th>
<div class="row items-center">
<div>{{ $t('KPlatform.VALUE') }}</div>
<q-space />
<KAction
id="copy-info"
icon="las la-copy"
tooltip="KPlatform.COPY_INFO"
:handler="copy"
/>
</div>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(value, prop) in platform" :key="prop">
<td>{{ prop }}</td>
<td>{{ value === true ? $t('YES') : value === false ? $t('NO') : value }}</td>
</tr>
</tbody>
</q-markup-table>
<!--
User agent && copy action
-->
<div>
<div class="full-width row justify-between items-center">
<div class="q-pa-sm col-11 bg-grey-3">{{ $t('KPlatform.USER_AGENT') }}</div>

<KAction
id="copy-clipboard"
icon="las la-copy"
:handler="copy"
tooltip="KPlatform.COPY_INFO"
renderer="fab"
color="primary"
class="col-1"
/>
</div>
<div class="q-px-md q-py-sm full-width text-caption">{{ Platform.getData().userAgent }}</div>
</div>
<!--
Application
-->
<div>
<div class="full-width q-pa-sm bg-grey-3">{{ $t('KPlatform.APPLICATION') }}</div>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in applicationProperties()" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value === true ? $t('YES') : value === false ? $t('NO') : value }}</q-item-section>
</q-item>
</template>
</q-list>
<q-expansion-item
:label="$t('KPlatform.PERMISSIONS')"
expand-separator
dense
header-class="bg-grey-2"
class="q-pa-sm"
>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in Platform.getData().application.permissions" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value === 'granted' ? $t('KPlatform.PERMISSION_GRANTED') : $t('KPlatform.PERMISSION_PROMPT') }}</q-item-section>
</q-item>
</template>
</q-list>
</q-expansion-item>
</div>
<!--
Browser
-->
<div>
<div class="full-width q-pa-sm bg-grey-3">{{ $t('KPlatform.BROWSER') }}</div>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in browserProperties()" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value === true ? $t('YES') : value === false ? $t('NO') : value }}</q-item-section>
</q-item>
</template>
</q-list>
<q-expansion-item
:label="$t('KPlatform.LOCALE')"
expand-separator
dense
header-class="bg-grey-2"
default-opened
class="q-pa-sm"
>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in Platform.getData().browser.locale" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value }}</q-item-section>
</q-item>
</template>
</q-list>
</q-expansion-item>
<q-expansion-item
:label="$t('KPlatform.WEBGL')"
expand-separator
dense
header-class="bg-grey-2"
class="q-pa-sm"
>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in Platform.getData().browser.webgl" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value }}</q-item-section>
</q-item>
</template>
</q-list>
</q-expansion-item>
</div>
<!-- System -->
<div>
<div class="full-width q-pa-sm bg-grey-3">{{ $t('KPlatform.SYSTEM') }}</div>
<q-list class="q-pa-sm" separator dense>
<template v-for="(value, prop) in systemProperties()" :key="prop">
<q-item>
<q-item-section class="text-caption">{{ prop }}</q-item-section>
<q-item-section class="text-caption">{{ value === true ? $t('YES') : value === false ? $t('NO') : value }}</q-item-section>
</q-item>
</template>
</q-list>
</div>
</template>

<script setup>
import { useQuasar, copyToClipboard } from 'quasar'
import { Notify, copyToClipboard } from 'quasar'
import { i18n } from '../../i18n.js'
import { getPlatform } from '../../utils/utils.platform'
import { Platform } from '../../platform.js'
import KAction from '../action/KAction.vue'
// data
const $q = useQuasar()
const platform = getPlatform()
// function
// Functions
function applicationProperties () {
return _.pick(Platform.getData().application, ['mode', 'iframe'])
}
function browserProperties () {
return _.pick(Platform.getData().browser, ['name', 'version'])
}
function systemProperties () {
return Platform.getData().system
}
async function copy () {
try {
await copyToClipboard(JSON.stringify(platform, null, 2))
$q.notify({ type: 'positive', message: i18n.t('KPlatform.INFO_COPIED') })
await copyToClipboard(JSON.stringify(Platform.getData(), null, 2))
Notify.create({ type: 'positive', message: i18n.t('KPlatform.INFO_COPIED') })
} catch (error) {
$q.notify({ type: 'negative', message: i18n.t('KPositionIndicator.CANNOT_COPY_INFO') })
Notify.create({ type: 'negative', message: i18n.t('KPositionIndicator.CANNOT_COPY_INFO') })
}
}
</script>
Expand Down
3 changes: 1 addition & 2 deletions core/client/directives/v-hover.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getPlatform } from '../utils/utils.platform.js'
const Platform = getPlatform()
import { Platform } from '../platform.js'

export const vHover = {

Expand Down
13 changes: 10 additions & 3 deletions core/client/i18n/core_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,16 @@
"MORE_ABOUT_KALISIO": "More about Kalisio"
},
"KPlatform": {
"PROPERTY": "Property",
"VALUE": "Value",
"COPY_INFO": "Copy info",
"USER_AGENT": "User agent",
"APPLICATION": "Application",
"PERMISSIONS": "Permissions",
"PERMISSION_GRANTED": "Granted",
"PERMISSION_PROMPT": "Prompt",
"BROWSER": "Browser",
"LOCALE": "Locale",
"WEBGL": "WebGL support",
"SYSTEM": "System",
"COPY_INFO": "Copy info to clipboard",
"INFO_COPIED": "Platform info copied",
"CANNOT_COPY_INFO": "Cannot copy platform info"
},
Expand Down
13 changes: 10 additions & 3 deletions core/client/i18n/core_fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,16 @@
"MORE_ABOUT_KALISIO": "En savoir plus sur Kalisio"
},
"KPlatform": {
"PROPERTY": "Propriété",
"VALUE": "Valeur",
"COPY_INFO": "Copier les informations",
"USER_AGENT": "Agent utilisateur",
"APPLICATION": "Application",
"PERMISSIONS": "Permissions",
"PERMISSION_GRANTED": "Autorisé",
"PERMISSION_PROMPT": "Sur demande",
"BROWSER": "Navigateur",
"LOCALE": "Locale",
"WEBGL": "Support WebGL",
"SYSTEM": "Système",
"COPY_INFO": "Copier les informations en mémoire",
"INFO_COPIED": "Informations système copiées",
"CANNOT_COPY_INFO": "Impossible de copier les informations systèmes"
},
Expand Down
42 changes: 32 additions & 10 deletions core/client/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,40 @@ import logger from 'loglevel'
import config from 'config'
import { getFingerprint, getFingerprintData } from '@thumbmarkjs/thumbmarkjs'
import { Platform as QPlatform } from 'quasar'
import { getLocale } from './utils/utils.locale.js'

const Fingerprint = {
export const Platform = {
async initialize () {
// use Quasar platform data
_.merge(this, _.omit(QPlatform, ['install', '__installed']))
// use fingerprint data
this.fingerprint = await getFingerprint()
const fingerprintData = await getFingerprintData()
this.permissions = _.get(fingerprintData, 'permissions')
this.hardware = {
video: _.get(fingerprintData, 'hardware.videocard'),
audio: _.get(fingerprintData, 'audio')
this.fingerprintData = await getFingerprintData()
// use locale
this.locale = getLocale()
// use build data
this.is.pwa = _.get(config, 'buildMode', 'spa') === 'pwa'
logger.debug('[KDK] Platform initialized with:', this)
},
getData () {
return {
userAgent: this.userAgent,
application: {
mode: this.is.pwa ? 'PWA' : 'SPA',
iframe: this.within.iframe,
permissions: _.get(this.fingerprintData, 'permissions')
},
browser: Object.assign({},
_.get(this.fingerprintData, 'system.browser'),
{ locale: _.get(this.fingerprintData, 'locales') },
{ webgl: _.get(this.fingerprintData, 'hardware.videocard') }
),
system: {
os: _.get(this.fingerprintData, 'system.platform'),
desktop: this.is.desktop || false,
mobile: this.is.mobile || false,
touch: this.is.touch || false
}
}
logger.debug('[KDK] Platform initialized:', this)
}
}

export const Platform = Object.assign(QPlatform, Fingerprint, { pwa: _.get(config, 'buildMode', 'spa') === 'pwa'})
}
7 changes: 3 additions & 4 deletions map/client/navigator.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import _ from 'lodash'
import logger from 'loglevel'
import config from 'config'
import { Platform } from '../../core/client/platform.js'
import { Store } from '../../core/client/store.js'
import { getPlatform } from '../../core/client/utils/utils.platform.js'

export const Navigator = {

Expand All @@ -27,9 +27,8 @@ export const Navigator = {
}))
// Define the default app
let defaultApp = 'google-maps'
const platform = getPlatform()
if (platform.ios) defaultApp = 'apple-plan'
if (platform.android) defaultApp = 'google-maps'
if (Platform.ios) defaultApp = 'apple-plan'
if (Platform.android) defaultApp = 'google-maps'
Store.set('navigator.default', defaultApp)
logger.debug('[KDK] Navigator initialized with configuration:', Store.get('navigator'))
},
Expand Down

0 comments on commit c8992c5

Please sign in to comment.