add switch to mobile/desktop device in login/unlock page
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<v-dialog width="400" v-model="showState">
|
||||||
|
<v-card>
|
||||||
|
<v-toolbar color="primary">
|
||||||
|
<v-toolbar-title>{{ $t('global.app.title') }}</v-toolbar-title>
|
||||||
|
</v-toolbar>
|
||||||
|
<v-card-text class="pa-4">
|
||||||
|
<p>{{ $t('You can scan the below QR code on your mobile device.') }}</p>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-text class="pa-4 w-100 d-flex justify-center">
|
||||||
|
<img alt="qrcode" class="img-url-qrcode" :src="mobileUrlQrCodePath" />
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn :href="mobileVersionPath">{{$t('Switch to Mobile Version') }}</v-btn>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn @click="showState = false">{{ $t('Close') }}</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getMobileUrlQrCodePath } from '@/lib/qrcode.js';
|
||||||
|
import { getMobileVersionPath } from '@/lib/version.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: [
|
||||||
|
'show'
|
||||||
|
],
|
||||||
|
emits: [
|
||||||
|
'update:show'
|
||||||
|
],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mobileUrlQrCodePath: getMobileUrlQrCodePath(),
|
||||||
|
mobileVersionPath: getMobileVersionPath(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showState: {
|
||||||
|
get: function () {
|
||||||
|
return this.show;
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
this.$emit('update:show', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -66,6 +66,7 @@ import AmountInput from '@/components/desktop/AmountInput.vue';
|
|||||||
import StepsBar from '@/components/desktop/StepsBar.vue';
|
import StepsBar from '@/components/desktop/StepsBar.vue';
|
||||||
import ConfirmDialog from '@/components/desktop/ConfirmDialog.vue';
|
import ConfirmDialog from '@/components/desktop/ConfirmDialog.vue';
|
||||||
import SnackBar from '@/components/desktop/SnackBar.vue';
|
import SnackBar from '@/components/desktop/SnackBar.vue';
|
||||||
|
import SwitchToMobileDialog from '@/components/desktop/SwitchToMobileDialog.vue';
|
||||||
|
|
||||||
import '@/styles/desktop/template/base/libs/vuetify/_index.scss';
|
import '@/styles/desktop/template/base/libs/vuetify/_index.scss';
|
||||||
import '@/styles/desktop/template/template/index.scss';
|
import '@/styles/desktop/template/template/index.scss';
|
||||||
@@ -352,6 +353,7 @@ app.component('AmountInput', AmountInput);
|
|||||||
app.component('StepsBar', StepsBar);
|
app.component('StepsBar', StepsBar);
|
||||||
app.component('ConfirmDialog', ConfirmDialog);
|
app.component('ConfirmDialog', ConfirmDialog);
|
||||||
app.component('SnackBar', SnackBar);
|
app.component('SnackBar', SnackBar);
|
||||||
|
app.component('SwitchToMobileDialog', SwitchToMobileDialog);
|
||||||
|
|
||||||
app.config.globalProperties.$version = getVersion();
|
app.config.globalProperties.$version = getVersion();
|
||||||
app.config.globalProperties.$buildTime = getBuildTime();
|
app.config.globalProperties.$buildTime = getBuildTime();
|
||||||
|
|||||||
@@ -89,6 +89,14 @@
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="12" class="py-0 mt-1 mb-4">
|
||||||
|
<div class="d-flex align-center justify-space-between flex-wrap">
|
||||||
|
<a href="javascript:void(0);" @click="showMobileQrCode = true">
|
||||||
|
<span class="nav-item-title">{{ $t('Use on Mobile Device') }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn block :disabled="inputIsEmpty || logining || verifying"
|
<v-btn block :disabled="inputIsEmpty || logining || verifying"
|
||||||
@click="login" v-if="!show2faInput">
|
@click="login" v-if="!show2faInput">
|
||||||
@@ -143,6 +151,7 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
<switch-to-mobile-dialog v-model:show="showMobileQrCode" />
|
||||||
<snack-bar ref="snackbar" />
|
<snack-bar ref="snackbar" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -177,6 +186,7 @@ export default {
|
|||||||
verifying: false,
|
verifying: false,
|
||||||
show2faInput: false,
|
show2faInput: false,
|
||||||
twoFAVerifyType: 'passcode',
|
twoFAVerifyType: 'passcode',
|
||||||
|
showMobileQrCode: false,
|
||||||
icons: {
|
icons: {
|
||||||
eye: mdiEyeOutline,
|
eye: mdiEyeOutline,
|
||||||
eyeSlash: mdiEyeOffOutline,
|
eyeSlash: mdiEyeOffOutline,
|
||||||
|
|||||||
@@ -161,26 +161,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layout-overlay" :class="{ 'visible': showVerticalOverlayMenu }" @click="showVerticalOverlayMenu = false"></div>
|
<switch-to-mobile-dialog v-model:show="showMobileQrCode" />
|
||||||
|
|
||||||
<v-dialog width="400" v-model="showMobileQrCode">
|
<div class="layout-overlay" :class="{ 'visible': showVerticalOverlayMenu }" @click="showVerticalOverlayMenu = false"></div>
|
||||||
<v-card>
|
|
||||||
<v-toolbar color="primary">
|
|
||||||
<v-toolbar-title>{{ $t('global.app.title') }}</v-toolbar-title>
|
|
||||||
</v-toolbar>
|
|
||||||
<v-card-text class="pa-4">
|
|
||||||
<p>{{ $t('You can scan the below QR code on your mobile device.') }}</p>
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-text class="pa-4 w-100 d-flex justify-center">
|
|
||||||
<img alt="qrcode" class="img-url-qrcode" :src="mobileUrlQrCodePath" />
|
|
||||||
</v-card-text>
|
|
||||||
<v-card-actions>
|
|
||||||
<v-btn :href="mobileVersionPath">{{$t('Switch to Mobile Version') }}</v-btn>
|
|
||||||
<v-spacer></v-spacer>
|
|
||||||
<v-btn @click="showMobileQrCode = false">{{ $t('Close') }}</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
|
|
||||||
<v-overlay class="justify-center align-center" :persistent="true" v-model="showLoading">
|
<v-overlay class="justify-center align-center" :persistent="true" v-model="showLoading">
|
||||||
<v-progress-circular indeterminate></v-progress-circular>
|
<v-progress-circular indeterminate></v-progress-circular>
|
||||||
@@ -200,8 +183,6 @@ import { useSettingsStore } from '@/stores/setting.js';
|
|||||||
import { useUserStore } from '@/stores/user.js';
|
import { useUserStore } from '@/stores/user.js';
|
||||||
|
|
||||||
import { getSystemTheme } from '@/lib/ui.js';
|
import { getSystemTheme } from '@/lib/ui.js';
|
||||||
import { getMobileUrlQrCodePath } from '@/lib/qrcode.js';
|
|
||||||
import { getMobileVersionPath } from '@/lib/version.js';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mdiMenu,
|
mdiMenu,
|
||||||
@@ -258,12 +239,6 @@ export default {
|
|||||||
const { mdAndDown } = useDisplay();
|
const { mdAndDown } = useDisplay();
|
||||||
return mdAndDown.value;
|
return mdAndDown.value;
|
||||||
},
|
},
|
||||||
mobileUrlQrCodePath() {
|
|
||||||
return getMobileUrlQrCodePath();
|
|
||||||
},
|
|
||||||
mobileVersionPath() {
|
|
||||||
return getMobileVersionPath();
|
|
||||||
},
|
|
||||||
currentNickName() {
|
currentNickName() {
|
||||||
return this.userStore.currentUserNickname || this.$t('User');
|
return this.userStore.currentUserNickname || this.$t('User');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,6 +35,14 @@
|
|||||||
v-model="pinCode" @pincode:confirm="unlockByPin" />
|
v-model="pinCode" @pincode:confirm="unlockByPin" />
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="12" class="py-0 mt-4 mb-4">
|
||||||
|
<div class="d-flex align-center justify-space-between flex-wrap">
|
||||||
|
<a href="javascript:void(0);" @click="showMobileQrCode = true">
|
||||||
|
<span class="nav-item-title">{{ $t('Use on Mobile Device') }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn block :disabled="!isPinCodeValid(pinCode) || verifyingByWebAuthn"
|
<v-btn block :disabled="!isPinCodeValid(pinCode) || verifyingByWebAuthn"
|
||||||
@click="unlockByPin(pinCode)">
|
@click="unlockByPin(pinCode)">
|
||||||
@@ -91,6 +99,7 @@
|
|||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
|
<switch-to-mobile-dialog v-model:show="showMobileQrCode" />
|
||||||
<confirm-dialog ref="confirmDialog"/>
|
<confirm-dialog ref="confirmDialog"/>
|
||||||
<snack-bar ref="snackbar" />
|
<snack-bar ref="snackbar" />
|
||||||
</div>
|
</div>
|
||||||
@@ -113,7 +122,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pinCode: '',
|
pinCode: '',
|
||||||
verifyingByWebAuthn: false
|
verifyingByWebAuthn: false,
|
||||||
|
showMobileQrCode: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<f7-block class="login-page-tile margin-vertical-half">{{ $t('global.app.title') }}</f7-block>
|
<f7-block class="login-page-tile margin-vertical-half">{{ $t('global.app.title') }}</f7-block>
|
||||||
</f7-login-screen-title>
|
</f7-login-screen-title>
|
||||||
|
|
||||||
<f7-list form dividers>
|
<f7-list form dividers class="margin-bottom-half">
|
||||||
<f7-list-input
|
<f7-list-input
|
||||||
type="text"
|
type="text"
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
@@ -27,7 +27,19 @@
|
|||||||
></f7-list-input>
|
></f7-list-input>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
|
||||||
<f7-list>
|
<f7-list class="no-margin-vertical">
|
||||||
|
<f7-list-item>
|
||||||
|
<template #title>
|
||||||
|
<small>
|
||||||
|
<f7-link external :href="desktopVersionPath">{{ $t('Switch to Desktop Version') }}</f7-link>
|
||||||
|
</small>
|
||||||
|
</template>
|
||||||
|
<template #after>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list class="margin-top-half">
|
||||||
<f7-list-button :class="{ 'disabled': inputIsEmpty || logining }" :text="$t('Log In')" @click="login"></f7-list-button>
|
<f7-list-button :class="{ 'disabled': inputIsEmpty || logining }" :text="$t('Log In')" @click="login"></f7-list-button>
|
||||||
<f7-block-footer>
|
<f7-block-footer>
|
||||||
<span>{{ $t('Don\'t have an account?') }}</span>
|
<span>{{ $t('Don\'t have an account?') }}</span>
|
||||||
@@ -116,6 +128,7 @@ import { useSettingsStore } from '@/stores/setting.js';
|
|||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
|
||||||
|
|
||||||
import { isUserRegistrationEnabled } from '@/lib/server_settings.js';
|
import { isUserRegistrationEnabled } from '@/lib/server_settings.js';
|
||||||
|
import { getDesktopVersionPath } from '@/lib/version.js';
|
||||||
import { isModalShowing } from '@/lib/ui.mobile.js';
|
import { isModalShowing } from '@/lib/ui.mobile.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -140,6 +153,9 @@ export default {
|
|||||||
version() {
|
version() {
|
||||||
return 'v' + this.$version;
|
return 'v' + this.$version;
|
||||||
},
|
},
|
||||||
|
desktopVersionPath() {
|
||||||
|
return getDesktopVersionPath();
|
||||||
|
},
|
||||||
allLanguages() {
|
allLanguages() {
|
||||||
return this.$locale.getAllLanguageInfos();
|
return this.$locale.getAllLanguageInfos();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<f7-block class="login-page-tile margin-vertical-half">{{ $t('global.app.title') }}</f7-block>
|
<f7-block class="login-page-tile margin-vertical-half">{{ $t('global.app.title') }}</f7-block>
|
||||||
</f7-login-screen-title>
|
</f7-login-screen-title>
|
||||||
|
|
||||||
<f7-list form>
|
<f7-list form class="margin-bottom-half">
|
||||||
<f7-list-item class="no-padding no-margin">
|
<f7-list-item class="no-padding no-margin">
|
||||||
<template #inner>
|
<template #inner>
|
||||||
<div class="display-flex justify-content-center full-line">{{ $t('Unlock Application') }}</div>
|
<div class="display-flex justify-content-center full-line">{{ $t('Unlock Application') }}</div>
|
||||||
@@ -16,7 +16,19 @@
|
|||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
|
||||||
<f7-list>
|
<f7-list class="no-margin-vertical">
|
||||||
|
<f7-list-item>
|
||||||
|
<template #title>
|
||||||
|
<small>
|
||||||
|
<f7-link external :href="desktopVersionPath">{{ $t('Switch to Desktop Version') }}</f7-link>
|
||||||
|
</small>
|
||||||
|
</template>
|
||||||
|
<template #after>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list class="margin-top-half">
|
||||||
<f7-list-button :class="{ 'disabled': !isPinCodeValid(pinCode) }" :text="$t('Unlock By PIN Code')" @click="unlockByPin"></f7-list-button>
|
<f7-list-button :class="{ 'disabled': !isPinCodeValid(pinCode) }" :text="$t('Unlock By PIN Code')" @click="unlockByPin"></f7-list-button>
|
||||||
<f7-list-button v-if="isWebAuthnAvailable" :text="$t('Unlock By WebAuthn')" @click="unlockByWebAuthn"></f7-list-button>
|
<f7-list-button v-if="isWebAuthnAvailable" :text="$t('Unlock By WebAuthn')" @click="unlockByWebAuthn"></f7-list-button>
|
||||||
<f7-block-footer>
|
<f7-block-footer>
|
||||||
@@ -66,6 +78,7 @@ import { useExchangeRatesStore } from '@/stores/exchangeRates.js';
|
|||||||
|
|
||||||
import logger from '@/lib/logger.js';
|
import logger from '@/lib/logger.js';
|
||||||
import webauthn from '@/lib/webauthn.js';
|
import webauthn from '@/lib/webauthn.js';
|
||||||
|
import { getDesktopVersionPath } from '@/lib/version.js';
|
||||||
import { isModalShowing } from '@/lib/ui.mobile.js';
|
import { isModalShowing } from '@/lib/ui.mobile.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -82,6 +95,9 @@ export default {
|
|||||||
version() {
|
version() {
|
||||||
return 'v' + this.$version;
|
return 'v' + this.$version;
|
||||||
},
|
},
|
||||||
|
desktopVersionPath() {
|
||||||
|
return getDesktopVersionPath();
|
||||||
|
},
|
||||||
allLanguages() {
|
allLanguages() {
|
||||||
return this.$locale.getAllLanguageInfos();
|
return this.$locale.getAllLanguageInfos();
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user