show device icon and name in session list

This commit is contained in:
MaysWind
2020-11-17 21:49:01 +08:00
parent 4c706282d5
commit 68233852e7
12 changed files with 135 additions and 4 deletions
+5
View File
@@ -10705,6 +10705,11 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
"ua-parser-js": {
"version": "0.7.22",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz",
"integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q=="
},
"uglify-js": {
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
+1
View File
@@ -15,6 +15,7 @@
"framework7-vue": "^5.7.14",
"js-cookie": "^2.2.1",
"moment": "^2.29.1",
"ua-parser-js": "^0.7.22",
"vue": "^2.6.12",
"vue-clipboard2": "^0.3.1",
"vue-i18n": "^8.22.1",
+4
View File
@@ -107,6 +107,10 @@ body {
display: none;
}
.list-item-media-valign-middle .item-media {
align-self: normal !important;
}
.lab-list-item-error-info div.item-footer {
color: var(--f7-input-error-text-color)
}
+18
View File
@@ -65,10 +65,28 @@ const allAccountIcons = {
f7Icon: 'bitcoin'
}
};
const deviceIcons = {
mobile: {
f7Icon: 'device_phone_portrait'
},
tablet: {
f7Icon: 'device_tablet_portrait'
},
wearable: {
f7Icon: 'device_phone_portrait'
},
desktop: {
f7Icon: 'device_desktop'
},
tv: {
f7Icon: 'tv'
}
};
export default {
allAccountIcons: allAccountIcons,
defaultAccountIconId: defaultAccountIconId,
defaultAccountIcon: allAccountIcons[defaultAccountIconId],
totalAccountIconCount: totalAccountIconCount,
deviceIcons: deviceIcons,
};
+6
View File
@@ -152,6 +152,12 @@ const licenses = [
copyright: 'Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors',
url: 'https://github.com/js-cookie/js-cookie',
licenseUrl: 'https://github.com/js-cookie/js-cookie/blob/master/LICENSE'
},
{
name: 'UAParser.js',
copyright: 'Copyright (c) 2012-2019 Faisal Salman <f@faisalman.com>',
url: 'https://github.com/faisalman/ua-parser-js',
licenseUrl: 'https://github.com/faisalman/ua-parser-js/blob/master/license.md'
}
];
+36
View File
@@ -0,0 +1,36 @@
import utils from "../lib/utils.js";
export default function (token) {
const ua = utils.parseUserAgent(token.userAgent);
let result = '';
if (ua.device.model) {
result = ua.device.model;
} else if (ua.os.name) {
result = ua.os.name;
if (ua.os.version) {
result += ' ' + ua.os.version;
}
}
if (ua.browser.name) {
let browserInfo = ua.browser.name;
if (ua.browser.version) {
browserInfo += ' ' + ua.browser.version;
}
if (result) {
result += ' (' + browserInfo + ')';
} else {
result = browserInfo;
}
}
if (!result) {
return 'Unknown Device';
}
return result;
}
+22
View File
@@ -0,0 +1,22 @@
import icons from "../consts/icon.js";
import utils from "../lib/utils.js";
export default function (token) {
const ua = utils.parseUserAgent(token.userAgent);
if (!ua || !ua.device) {
return icons.deviceIcons.desktop.f7Icon;
}
if (ua.device.type === 'mobile') {
return icons.deviceIcons.mobile.f7Icon;
} else if (ua.device.type === 'wearable') {
return icons.deviceIcons.wearable.f7Icon;
} else if (ua.device.type === 'tablet') {
return icons.deviceIcons.tablet.f7Icon;
} else if (ua.device.type === 'smarttv') {
return icons.deviceIcons.tv.f7Icon;
} else {
return icons.deviceIcons.desktop.f7Icon;
}
}
+23 -1
View File
@@ -1,4 +1,5 @@
import accountConstants from '../consts/account.js'
import uaParser from 'ua-parser-js';
import accountConstants from '../consts/account.js';
function isFunction(val) {
return typeof(val) === 'function';
@@ -28,6 +29,26 @@ function isBoolean(val) {
return typeof(val) === 'boolean';
}
function parseUserAgent(ua) {
const uaParseRet = uaParser(ua);
return {
device: {
vendor: uaParseRet.device.vendor,
model: uaParseRet.device.model,
type: uaParseRet.device.type
},
os: {
name: uaParseRet.os.name,
version: uaParseRet.os.version
},
browser: {
name: uaParseRet.browser.name,
version: uaParseRet.browser.version
}
};
}
function getCategorizedAccounts(allAccounts) {
const ret = {};
@@ -104,6 +125,7 @@ export default {
isString,
isNumber,
isBoolean,
parseUserAgent,
getCategorizedAccounts,
getAccountByAccountId,
getAllFilteredAccountsBalance,
+1
View File
@@ -380,6 +380,7 @@ export default {
'Unable to get session list': 'Unable to get session list',
'Current': 'Current',
'Other Device': 'Other Device',
'Unknown Device': 'Unknown Device',
'Are you sure you want to logout from this session?': 'Are you sure you want to logout from this session?',
'Unable to logout from this session': 'Unable to logout from this session',
'Are you sure you want to logout all other sessions?': 'Are you sure you want to logout all other sessions?',
+1
View File
@@ -380,6 +380,7 @@ export default {
'Unable to get session list': '无法获取会话列表',
'Current': '当前',
'Other Device': '其他设备',
'Unknown Device': '未知设备',
'Are you sure you want to logout from this session?': '您确定是否要退出该会话?',
'Unable to logout from this session': '无法退出该会话',
'Are you sure you want to logout all other sessions?': '您确定是否要退出其他所有会话?',
+4
View File
@@ -25,6 +25,8 @@ import userstate from './lib/userstate.js';
import utils from './lib/utils.js';
import currencyFilter from './filters/currency.js';
import accountIconFilter from './filters/accountIcon.js';
import tokenDeviceFilter from './filters/tokenDevice.js';
import tokenIconFilter from './filters/tokenIcon.js';
import App from './Mobile.vue';
Vue.use(VueI18n);
@@ -151,6 +153,8 @@ Vue.prototype.$user = userstate;
Vue.filter('currency', (value, currencyCode) => currencyFilter({ i18n }, value, currencyCode));
Vue.filter('accountIcon', (value) => accountIconFilter(value));
Vue.filter('tokenDevice', (value) => tokenDeviceFilter(value));
Vue.filter('tokenIcon', (value) => tokenIconFilter(value));
Vue.prototype.$setLanguage(settings.getLanguage() || getDefaultLanguage());
+14 -3
View File
@@ -11,8 +11,12 @@
<f7-card class="skeleton-text" v-if="loading">
<f7-card-content :padding="false">
<f7-list media-list>
<f7-list-item title="Token Name" after="MM/DD/YYYY HH:mm:ss"
text="Mozilla/5.0 (OS Name & Version or Device Name; CPU Architecture ...) AppleWebKit/Version (KHTML, like Gecko) Software Name/Version Software Name/Version ..."></f7-list-item>
<f7-list-item class="list-item-media-valign-middle"
title="Current"
text="Device Name (Browser xx.x.xxxx.xx)">
<f7-icon slot="media" f7="device_phone_portrait"></f7-icon>
<small slot="after">MM/DD/YYYY HH:mm:ss</small>
</f7-list-item>
</f7-list>
</f7-card-content>
</f7-card>
@@ -20,7 +24,14 @@
<f7-card v-else-if="!loading">
<f7-card-content :padding="false">
<f7-list media-list>
<f7-list-item swipeout v-for="token in tokens" :key="token.tokenId" :id="token | tokenDomId" :title="token | tokenTitle | t" :after="token.createdAt | moment($t('format.datetime.long'))" :text="token.userAgent">
<f7-list-item class="list-item-media-valign-middle" swipeout
v-for="token in tokens"
:key="token.tokenId"
:id="token | tokenDomId"
:title="token | tokenTitle | t"
:text="token | tokenDevice | t">
<f7-icon slot="media" :f7="token | tokenIcon"></f7-icon>
<small slot="after">{{ token.createdAt | moment($t('format.datetime.long')) }}</small>
<f7-swipeout-actions right v-if="!token.isCurrent">
<f7-swipeout-button color="red" :text="$t('Log Out')" @click="revoke(token)"></f7-swipeout-button>
</f7-swipeout-actions>