feat: automatically check version updates
This commit is contained in:
1
app.vue
1
app.vue
@ -3,6 +3,7 @@
|
|||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
<AutoUpdateToast />
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
65
components/AutoUpdateToast.vue
Normal file
65
components/AutoUpdateToast.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useIntervalFn } from '@vueuse/core'
|
||||||
|
// @ts-expect-error
|
||||||
|
import semverGt from 'semver/functions/gt'
|
||||||
|
import type VersionMeta from '~/public/version.json'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
const toast = useToast()
|
||||||
|
const runtimeConfig = useRuntimeConfig()
|
||||||
|
|
||||||
|
const interval = 5 * 60 * 1000
|
||||||
|
let lastCheck: Date | undefined
|
||||||
|
|
||||||
|
const checkUpdate = async () => {
|
||||||
|
if (lastCheck && new Date().getTime() - lastCheck.getTime() < interval) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastCheck = new Date()
|
||||||
|
try {
|
||||||
|
const response = (await $fetch(
|
||||||
|
'https://deep-research.ataw.top/version.json',
|
||||||
|
)) as typeof VersionMeta
|
||||||
|
if (semverGt(response.version, runtimeConfig.public.version)) {
|
||||||
|
toast.add({
|
||||||
|
title: t('autoUpdate.newVersionTitle', [response.version]),
|
||||||
|
description: t('autoUpdate.newVersionDescription'),
|
||||||
|
color: 'info',
|
||||||
|
duration: 10_000,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: t('autoUpdate.refresh'),
|
||||||
|
onClick: () => {
|
||||||
|
window.location.reload()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查更新失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每 3 分钟检查一次更新
|
||||||
|
const { pause, resume } = useIntervalFn(checkUpdate, interval, {
|
||||||
|
immediate: true,
|
||||||
|
immediateCallback: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 当页面不可见时暂停检查
|
||||||
|
const visibility = useDocumentVisibility()
|
||||||
|
const focus = useWindowFocus()
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[visibility, focus],
|
||||||
|
([visible, focused]) => {
|
||||||
|
if (visible === 'visible' && focused) {
|
||||||
|
resume()
|
||||||
|
} else {
|
||||||
|
pause()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
)
|
||||||
|
</script>
|
@ -85,5 +85,10 @@
|
|||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"requestBlockedByCORS": "The current API provider may not allow cross-origin requests. Please try a different service provider or contact the provider for support."
|
"requestBlockedByCORS": "The current API provider may not allow cross-origin requests. Please try a different service provider or contact the provider for support."
|
||||||
|
},
|
||||||
|
"autoUpdate": {
|
||||||
|
"newVersionTitle": "New version available: {0}",
|
||||||
|
"newVersionDescription": "Please refresh the page to get the latest version.",
|
||||||
|
"refresh": "Refresh"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -85,5 +85,10 @@
|
|||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"requestBlockedByCORS": "当前 API 服务可能不允许接口跨域,请换一个服务试试,或者向服务方反馈。"
|
"requestBlockedByCORS": "当前 API 服务可能不允许接口跨域,请换一个服务试试,或者向服务方反馈。"
|
||||||
|
},
|
||||||
|
"autoUpdate": {
|
||||||
|
"newVersionTitle": "发现新版本:{0}",
|
||||||
|
"newVersionDescription": "请刷新页面以获取最新版本。",
|
||||||
|
"refresh": "刷新"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import { version as projVersion } from './public/version.json'
|
||||||
|
|
||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
modules: [
|
modules: [
|
||||||
@ -8,8 +10,16 @@ export default defineNuxtConfig({
|
|||||||
'@nuxtjs/i18n',
|
'@nuxtjs/i18n',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
runtimeConfig: {
|
||||||
|
public: {
|
||||||
|
version: projVersion,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
routeRules: {
|
routeRules: {
|
||||||
'/version.json': { cors: true },
|
'/version.json': {
|
||||||
|
cors: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
i18n: {
|
i18n: {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"nuxt": "^3.15.4",
|
"nuxt": "^3.15.4",
|
||||||
"p-limit": "^6.2.0",
|
"p-limit": "^6.2.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
|
"semver": "^7.7.1",
|
||||||
"tailwindcss": "^4.0.5",
|
"tailwindcss": "^4.0.5",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
"vue-router": "latest",
|
"vue-router": "latest",
|
||||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -62,6 +62,9 @@ importers:
|
|||||||
pinia:
|
pinia:
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
version: 3.0.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||||
|
semver:
|
||||||
|
specifier: ^7.7.1
|
||||||
|
version: 7.7.1
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^4.0.5
|
specifier: ^4.0.5
|
||||||
version: 4.0.6
|
version: 4.0.6
|
||||||
|
Reference in New Issue
Block a user