mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-11-23 09:25:35 +08:00
feat(config): check for frontend version update
This commit is contained in:
parent
7c310e7c66
commit
657c180e05
@ -248,37 +248,42 @@ export const updateRuleProviderAPI = (providerName: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ReleaseAPIResponse = {
|
type ReleaseAPIResponse = {
|
||||||
|
tag_name: string
|
||||||
assets: { 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 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
|
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],
|
const channel = match[1],
|
||||||
version = match[2]
|
version = match[2]
|
||||||
|
|
||||||
if (channel === 'meta') {
|
if (channel === 'meta') return await check('/releases/latest')
|
||||||
const { assets } = await ky
|
|
||||||
.get(`${repositoryURL}/releases/latest`)
|
|
||||||
.json<ReleaseAPIResponse>()
|
|
||||||
|
|
||||||
const alreadyLatest = assets.some(({ name }) => name.includes(version))
|
if (channel === 'alpha') return await check('/releases/tags/Prerelease-Alpha')
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@ import {
|
|||||||
fetchBackendVersionAPI,
|
fetchBackendVersionAPI,
|
||||||
flushFakeIPDataAPI,
|
flushFakeIPDataAPI,
|
||||||
flushingFakeIPData,
|
flushingFakeIPData,
|
||||||
isUpdateAvailableAPI,
|
isBackendUpdateAvailableAPI,
|
||||||
|
isFrontendUpdateAvailableAPI,
|
||||||
reloadConfigFileAPI,
|
reloadConfigFileAPI,
|
||||||
reloadingConfigFile,
|
reloadingConfigFile,
|
||||||
restartBackendAPI,
|
restartBackendAPI,
|
||||||
@ -494,29 +495,37 @@ const ConfigForXd = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Versions: Component<{ backendVersion: Accessor<string> }> = ({
|
const Versions: Component<{
|
||||||
backendVersion,
|
frontendVersion: string
|
||||||
}) => {
|
backendVersion: Accessor<string>
|
||||||
const [isUpdateAvailable, setIsUpdateAvailable] = createSignal(false)
|
}> = ({ frontendVersion, backendVersion }) => {
|
||||||
|
const [isFrontendUpdateAvailable] = createResource(() =>
|
||||||
|
isFrontendUpdateAvailableAPI(frontendVersion),
|
||||||
|
)
|
||||||
|
const [isBackendUpdateAvailable] = createResource(() =>
|
||||||
|
isBackendUpdateAvailableAPI(backendVersion()),
|
||||||
|
)
|
||||||
|
|
||||||
createEffect(async () => {
|
const UpdateAvailableIndicator = () => (
|
||||||
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()}>
|
|
||||||
<span class="absolute -right-1 -top-1 flex h-3 w-3">
|
<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="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 class="inline-flex h-3 w-3 rounded-full bg-info" />
|
||||||
</span>
|
</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>
|
</Show>
|
||||||
|
|
||||||
<kbd class="kbd w-full">{backendVersion()}</kbd>
|
<kbd class="kbd w-full">{backendVersion()}</kbd>
|
||||||
@ -536,13 +545,15 @@ export default () => {
|
|||||||
|
|
||||||
const [t] = useI18n()
|
const [t] = useI18n()
|
||||||
|
|
||||||
const [backendVersion, setBackendVersion] = createSignal('')
|
const frontendVersion = `v${import.meta.env.APP_VERSION}`
|
||||||
const isSingBox = createMemo(() => backendVersion().includes('sing-box'))
|
const [backendVersion] = createResource(fetchBackendVersionAPI, {
|
||||||
|
initialValue: '',
|
||||||
onMount(() => {
|
|
||||||
fetchBackendVersionAPI().then(setBackendVersion)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isSingBox = createMemo(
|
||||||
|
() => backendVersion()?.includes('sing-box') || false,
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DocumentTitle>{t('config')}</DocumentTitle>
|
<DocumentTitle>{t('config')}</DocumentTitle>
|
||||||
@ -564,7 +575,12 @@ export default () => {
|
|||||||
|
|
||||||
<ConfigTitle withDivider>{t('version')}</ConfigTitle>
|
<ConfigTitle withDivider>{t('version')}</ConfigTitle>
|
||||||
|
|
||||||
<Versions backendVersion={backendVersion} />
|
<Show when={!backendVersion.loading}>
|
||||||
|
<Versions
|
||||||
|
frontendVersion={frontendVersion}
|
||||||
|
backendVersion={backendVersion}
|
||||||
|
/>
|
||||||
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ import AutoImport from 'unplugin-auto-import/vite'
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
import solidPlugin from 'vite-plugin-solid'
|
import solidPlugin from 'vite-plugin-solid'
|
||||||
|
import { version } from './package.json'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: './',
|
base: './',
|
||||||
@ -9,9 +10,7 @@ export default defineConfig({
|
|||||||
resolve: { alias: { '~': '/src' } },
|
resolve: { alias: { '~': '/src' } },
|
||||||
|
|
||||||
define: {
|
define: {
|
||||||
'import.meta.env.APP_VERSION': JSON.stringify(
|
'import.meta.env.APP_VERSION': JSON.stringify(version),
|
||||||
process.env.npm_package_version,
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
|
Loading…
Reference in New Issue
Block a user