add refresh browser cache when client version not match server version

This commit is contained in:
MaysWind
2025-06-30 00:39:28 +08:00
parent 801c0f8572
commit 96b7c69283
29 changed files with 332 additions and 42 deletions
+43 -8
View File
@@ -1,25 +1,41 @@
import { computed } from 'vue';
import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useSystemsStore } from '@/stores/system.ts';
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import type { VersionInfo } from '@/core/version.ts';
import type { LatestExchangeRateResponse } from '@/models/exchange_rate.ts';
import { getMapProvider } from '@/lib/server_settings.ts';
import { getMapWebsite } from '@/lib/map/index.ts';
import { getLicense, getThirdPartyLicenses } from '@/lib/licenses.ts';
import { getVersion, getBuildTime } from '@/lib/version.ts';
import { formatDisplayVersion, getClientDisplayVersion, getClientBuildTime } from '@/lib/version.ts';
import { clearBrowserCaches } from '@/lib/ui/common.ts';
export function useAboutPageBase() {
const { tt, formatUnixTimeToLongDateTime } = useI18n();
const systemsStore = useSystemsStore();
const exchangeRatesStore = useExchangeRatesStore();
const version = `v${getVersion()}`;
const clientVersion = `${getClientDisplayVersion()}`;
const buildTime = computed<string>(() => {
const time = getBuildTime();
const serverVersion = ref<VersionInfo | null>(null);
const clientVersionMatchServerVersion = ref<boolean>(true);
const serverDisplayVersion = computed<string>(() => {
if (!serverVersion.value) {
return '';
}
return formatDisplayVersion(serverVersion.value);
});
const clientBuildTime = computed<string>(() => {
const time = getClientBuildTime();
if (!time) {
return time;
@@ -40,16 +56,35 @@ export function useAboutPageBase() {
const licenseLines = computed<string[]>(() => getLicense().replace(/\r/g, '').split('\n'));
const thirdPartyLicenses = computed<LicenseInfo[]>(() => getThirdPartyLicenses());
function refreshBrowserCache(): void {
clearBrowserCaches().then(() => {
location.reload();
});
}
function init(): void {
systemsStore.checkIfClientVersionMatchServerVersion().then(({ match, version }) => {
serverVersion.value = version;
clientVersionMatchServerVersion.value = match;
});
}
return {
// constants
version,
clientVersion,
// states
clientVersionMatchServerVersion,
// computed states
buildTime,
serverDisplayVersion,
clientBuildTime,
exchangeRatesData,
isUserCustomExchangeRates,
mapProviderName,
mapProviderWebsite,
licenseLines,
thirdPartyLicenses
thirdPartyLicenses,
// functions
refreshBrowserCache,
init
};
}
+2 -2
View File
@@ -9,7 +9,7 @@ import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import type { AuthResponse } from '@/models/auth_response.ts';
import { getLoginPageTips } from '@/lib/server_settings.ts';
import { getVersion } from '@/lib/version.ts';
import { getClientDisplayVersion } from '@/lib/version.ts';
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
export function useLoginPageBase() {
@@ -19,7 +19,7 @@ export function useLoginPageBase() {
const settingsStore = useSettingsStore();
const exchangeRatesStore = useExchangeRatesStore();
const version = `v${getVersion()}`;
const version = `${getClientDisplayVersion()}`;
const username = ref<string>('');
const password = ref<string>('');
+2 -2
View File
@@ -11,7 +11,7 @@ import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import { isWebAuthnSupported } from '@/lib/webauthn.ts';
import { hasWebAuthnConfig } from '@/lib/userstate.ts';
import { getVersion } from '@/lib/version.ts';
import { getClientDisplayVersion } from '@/lib/version.ts';
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
export function useUnlockPageBase() {
@@ -24,7 +24,7 @@ export function useUnlockPageBase() {
const transactionsStore = useTransactionsStore();
const exchangeRatesStore = useExchangeRatesStore();
const version: string = `v${getVersion()}`;
const version: string = `${getClientDisplayVersion()}`;
const pinCode = ref<string>('');
+28 -7
View File
@@ -1,22 +1,34 @@
<template>
<v-row class="match-height">
<v-col cols="12">
<v-card :title="tt('global.app.title')">
<v-card>
<template #title>
<div class="d-flex align-center">
<span>{{ tt('global.app.title') }}</span>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" @click="refreshBrowserCache"
v-if="!clientVersionMatchServerVersion">
<v-icon :icon="mdiWebRefresh" size="24" />
<v-tooltip activator="parent">{{ tt('Refresh Browser Cache') }}</v-tooltip>
</v-btn>
</div>
</template>
<v-card-text>
<v-row no-gutters>
<v-col cols="12" md="2">
<span class="text-body-1">{{ tt('Version') }}</span>
</v-col>
<v-col cols="12" md="10" class="mb-6">
<span class="text-body-1">{{ version }}</span>
<span class="text-body-1">{{ clientVersion }}</span>
</v-col>
</v-row>
<v-row no-gutters v-if="buildTime">
<v-row no-gutters v-if="clientBuildTime">
<v-col cols="12" md="2">
<span class="text-body-1">{{ tt('Build Time') }}</span>
</v-col>
<v-col cols="12" md="10" class="mb-6">
<span class="text-body-1">{{ buildTime }}</span>
<span class="text-body-1">{{ clientBuildTime }}</span>
</v-col>
</v-row>
<v-row no-gutters>
@@ -123,15 +135,24 @@
import { useI18n } from '@/locales/helpers.ts';
import { useAboutPageBase } from '@/views/base/AboutPageBase.ts';
import {
mdiWebRefresh
} from '@mdi/js';
const { tt } = useI18n();
const {
version,
buildTime,
clientVersion,
clientVersionMatchServerVersion,
clientBuildTime,
exchangeRatesData,
isUserCustomExchangeRates,
mapProviderName,
mapProviderWebsite,
licenseLines,
thirdPartyLicenses
thirdPartyLicenses,
refreshBrowserCache,
init
} = useAboutPageBase();
init();
</script>
+2 -2
View File
@@ -101,7 +101,7 @@ import { useRootStore } from '@/stores/index.ts';
import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
import { ThemeType } from '@/core/theme.ts';
import { getVersion } from '@/lib/version.ts';
import { getClientDisplayVersion } from '@/lib/version.ts';
import {
mdiChevronLeft,
@@ -115,7 +115,7 @@ const { tt } = useI18n();
const rootStore = useRootStore();
const version = `v${getVersion()}`;
const version = `${getClientDisplayVersion()}`;
const snackbar = useTemplateRef<SnackBarType>('snackbar');
+2 -2
View File
@@ -130,7 +130,7 @@ import { useRootStore } from '@/stores/index.ts';
import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
import { ThemeType } from '@/core/theme.ts';
import { getVersion } from '@/lib/version.ts';
import { getClientDisplayVersion } from '@/lib/version.ts';
import {
mdiChevronLeft
@@ -150,7 +150,7 @@ const { tt } = useI18n();
const rootStore = useRootStore();
const version = `v${getVersion()}`;
const version = `${getClientDisplayVersion()}`;
const passwordInput = useTemplateRef<VTextField>('passwordInput');
const confirmPasswordInput = useTemplateRef<VTextField>('confirmPasswordInput');
+2 -2
View File
@@ -110,7 +110,7 @@ import { APPLICATION_LOGO_PATH } from '@/consts/asset.ts';
import { ThemeType } from '@/core/theme.ts';
import { isUserVerifyEmailEnabled } from '@/lib/server_settings.ts';
import { isUserLogined } from '@/lib/userstate.ts';
import { getVersion } from '@/lib/version.ts';
import { getClientDisplayVersion } from '@/lib/version.ts';
import {
mdiChevronLeft
@@ -132,7 +132,7 @@ const { tt, te } = useI18n();
const rootStore = useRootStore();
const version = `v${getVersion()}`;
const version = `${getClientDisplayVersion()}`;
const confirmDialog = useTemplateRef<ConfirmDialogType>('confirmDialog');
const snackbar = useTemplateRef<SnackBarType>('snackbar');
+48 -6
View File
@@ -1,11 +1,19 @@
<template>
<f7-page>
<f7-navbar :title="tt('About')" :back-link="tt('Back')"></f7-navbar>
<f7-navbar>
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
<f7-nav-title :title="tt('About')"></f7-nav-title>
<f7-nav-right>
<f7-link icon-f7="" v-if="clientVersionMatchServerVersion && !forceShowRefreshBrowserCacheMenu"/>
<f7-link icon-f7="ellipsis" @click="showRefreshBrowserCacheSheet = true"
v-else-if="!clientVersionMatchServerVersion || forceShowRefreshBrowserCacheMenu"></f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block-title class="margin-top">{{ tt('global.app.title') }}</f7-block-title>
<f7-list strong inset dividers>
<f7-list-item :title="tt('Version')" :after="version"></f7-list-item>
<f7-list-item :title="tt('Build Time')" :after="buildTime" v-if="buildTime"></f7-list-item>
<f7-list-item :title="tt('Version')" :after="clientVersion" @click="showVersion"></f7-list-item>
<f7-list-item :title="tt('Build Time')" :after="clientBuildTime" v-if="clientBuildTime"></f7-list-item>
<f7-list-item external :title="tt('Official Website')" link="https://github.com/mayswind/ezbookkeeping" target="_blank"></f7-list-item>
<f7-list-item external :title="tt('Report Issue')" link="https://github.com/mayswind/ezbookkeeping/issues" target="_blank"></f7-list-item>
<f7-list-item external :title="tt('Getting help')" link="https://ezbookkeeping.mayswind.net" target="_blank"></f7-list-item>
@@ -54,24 +62,58 @@
</f7-block>
</f7-page>
</f7-popup>
<f7-actions close-by-outside-click close-on-escape :opened="showRefreshBrowserCacheSheet" @actions:closed="showRefreshBrowserCacheSheet = false">
<f7-actions-group>
<f7-actions-button @click="refreshBrowserCache">{{ tt('Refresh Browser Cache') }}</f7-actions-button>
</f7-actions-group>
<f7-actions-group>
<f7-actions-button bold close>{{ tt('Cancel') }}</f7-actions-button>
</f7-actions-group>
</f7-actions>
</f7-page>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
import { useAboutPageBase } from '@/views/base/AboutPageBase.ts';
const { tt } = useI18n();
const { showAlert } = useI18nUIComponents();
const {
version,
buildTime,
clientVersion,
clientVersionMatchServerVersion,
serverDisplayVersion,
clientBuildTime,
exchangeRatesData,
isUserCustomExchangeRates,
mapProviderName,
mapProviderWebsite,
licenseLines,
thirdPartyLicenses
thirdPartyLicenses,
refreshBrowserCache,
init
} = useAboutPageBase();
const showRefreshBrowserCacheSheet = ref<boolean>(false);
const versionClickCount = ref<number>(0);
const forceShowRefreshBrowserCacheMenu = computed<boolean>(() => versionClickCount.value >= 5);
function showVersion(): void {
let versionMessage = `${tt('Frontend Version')}: ${clientVersion}`;
if (serverDisplayVersion.value) {
versionMessage += `<br/>${tt('Backend Version')}: ${serverDisplayVersion.value}`;
}
versionClickCount.value++;
showAlert(versionMessage);
}
init();
</script>
<style>
+2 -2
View File
@@ -101,7 +101,7 @@ import { useUserStore } from '@/stores/user.ts';
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import { findNameByValue } from '@/lib/common.ts';
import { getVersion, getDesktopVersionPath } from '@/lib/version.ts';
import { getClientDisplayVersion, getDesktopVersionPath } from '@/lib/version.ts';
import { isUserScheduledTransactionEnabled } from '@/lib/server_settings.ts';
import { setExpenseAndIncomeAmountColor } from '@/lib/ui/common.ts';
@@ -118,7 +118,7 @@ const settingsStore = useSettingsStore();
const userStore = useUserStore();
const exchangeRatesStore = useExchangeRatesStore();
const version = `v${getVersion()}`;
const version = `${getClientDisplayVersion()}`;
const logouting = ref<boolean>(false);
const showThemePopup = ref<boolean>(false);