show device icon and name in session list
This commit is contained in:
Generated
+5
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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?',
|
||||
|
||||
@@ -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?': '您确定是否要退出其他所有会话?',
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user