feat(config): check for frontend version update

This commit is contained in:
kunish 2024-10-10 23:42:40 +08:00
parent 7c310e7c66
commit 657c180e05
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
3 changed files with 67 additions and 47 deletions

View File

@ -248,37 +248,42 @@ export const updateRuleProviderAPI = (providerName: string) => {
}
type ReleaseAPIResponse = {
tag_name: string
assets: { name: string }[]
}
export const isUpdateAvailableAPI = async (versionResponse: string) => {
export const isFrontendUpdateAvailableAPI = async (currentVersion: string) => {
const repositoryURL = 'https://api.github.com/repos/MetaCubeX/metacubexd'
const { tag_name } = await ky
.get(`${repositoryURL}/releases/latest`)
.json<ReleaseAPIResponse>()
return tag_name !== currentVersion
}
export const isBackendUpdateAvailableAPI = async (currentVersion: string) => {
const repositoryURL = 'https://api.github.com/repos/MetaCubeX/mihomo'
const match = /(alpha|beta|meta)-?(\w+)/.exec(versionResponse)
const match = /(alpha|beta|meta)-?(\w+)/.exec(currentVersion)
if (!match) return false
const check = async (url: string) => {
const { assets } = await ky
.get(`${repositoryURL}${url}`)
.json<ReleaseAPIResponse>()
const alreadyLatest = assets.some(({ name }) => name.includes(version))
return !alreadyLatest
}
const channel = match[1],
version = match[2]
if (channel === 'meta') {
const { assets } = await ky
.get(`${repositoryURL}/releases/latest`)
.json<ReleaseAPIResponse>()
if (channel === 'meta') return await check('/releases/latest')
const alreadyLatest = assets.some(({ name }) => name.includes(version))
return !alreadyLatest
}
if (channel === 'alpha') {
const { assets } = await ky
.get(`${repositoryURL}/releases/tags/Prerelease-Alpha`)
.json<ReleaseAPIResponse>()
const alreadyLatest = assets.some(({ name }) => name.includes(version))
return !alreadyLatest
}
if (channel === 'alpha') return await check('/releases/tags/Prerelease-Alpha')
return false
}

View File

@ -8,7 +8,8 @@ import {
fetchBackendVersionAPI,
flushFakeIPDataAPI,
flushingFakeIPData,
isUpdateAvailableAPI,
isBackendUpdateAvailableAPI,
isFrontendUpdateAvailableAPI,
reloadConfigFileAPI,
reloadingConfigFile,
restartBackendAPI,
@ -494,29 +495,37 @@ const ConfigForXd = () => {
)
}
const Versions: Component<{ backendVersion: Accessor<string> }> = ({
backendVersion,
}) => {
const [isUpdateAvailable, setIsUpdateAvailable] = createSignal(false)
const Versions: Component<{
frontendVersion: string
backendVersion: Accessor<string>
}> = ({ frontendVersion, backendVersion }) => {
const [isFrontendUpdateAvailable] = createResource(() =>
isFrontendUpdateAvailableAPI(frontendVersion),
)
const [isBackendUpdateAvailable] = createResource(() =>
isBackendUpdateAvailableAPI(backendVersion()),
)
createEffect(async () => {
const version = backendVersion()
if (!version) return
setIsUpdateAvailable(await isUpdateAvailableAPI(version))
})
return (
<div class="grid grid-cols-2 gap-4">
<kbd class="kbd">{import.meta.env.APP_VERSION}</kbd>
<div class="relative">
<Show when={isUpdateAvailable()}>
const UpdateAvailableIndicator = () => (
<span class="absolute -right-1 -top-1 flex h-3 w-3">
<span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-info opacity-75" />
<span class="inline-flex h-3 w-3 rounded-full bg-info" />
</span>
)
return (
<div class="grid grid-cols-2 gap-4">
<div class="relative">
<Show when={isFrontendUpdateAvailable()}>
<UpdateAvailableIndicator />
</Show>
<kbd class="kbd w-full">{import.meta.env.APP_VERSION}</kbd>
</div>
<div class="relative">
<Show when={isBackendUpdateAvailable()}>
<UpdateAvailableIndicator />
</Show>
<kbd class="kbd w-full">{backendVersion()}</kbd>
@ -536,13 +545,15 @@ export default () => {
const [t] = useI18n()
const [backendVersion, setBackendVersion] = createSignal('')
const isSingBox = createMemo(() => backendVersion().includes('sing-box'))
onMount(() => {
fetchBackendVersionAPI().then(setBackendVersion)
const frontendVersion = `v${import.meta.env.APP_VERSION}`
const [backendVersion] = createResource(fetchBackendVersionAPI, {
initialValue: '',
})
const isSingBox = createMemo(
() => backendVersion()?.includes('sing-box') || false,
)
return (
<>
<DocumentTitle>{t('config')}</DocumentTitle>
@ -564,7 +575,12 @@ export default () => {
<ConfigTitle withDivider>{t('version')}</ConfigTitle>
<Versions backendVersion={backendVersion} />
<Show when={!backendVersion.loading}>
<Versions
frontendVersion={frontendVersion}
backendVersion={backendVersion}
/>
</Show>
</div>
</>
)

View File

@ -2,6 +2,7 @@ import AutoImport from 'unplugin-auto-import/vite'
import { defineConfig } from 'vite'
import { VitePWA } from 'vite-plugin-pwa'
import solidPlugin from 'vite-plugin-solid'
import { version } from './package.json'
export default defineConfig({
base: './',
@ -9,9 +10,7 @@ export default defineConfig({
resolve: { alias: { '~': '/src' } },
define: {
'import.meta.env.APP_VERSION': JSON.stringify(
process.env.npm_package_version,
),
'import.meta.env.APP_VERSION': JSON.stringify(version),
},
plugins: [