mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-13 05:20:28 +08:00
Compare commits
4 Commits
c8f89d1d59
...
b5853fa4aa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5853fa4aa | ||
|
|
56291d3d91 | ||
|
|
7a06a5a069 | ||
|
|
99bbd7ee5a |
@ -60,7 +60,7 @@
|
||||
"dayjs": "1.11.20",
|
||||
"foxact": "^0.3.0",
|
||||
"foxts": "^5.3.0",
|
||||
"i18next": "^25.10.4",
|
||||
"i18next": "^26.0.0",
|
||||
"js-yaml": "^4.1.1",
|
||||
"lodash-es": "^4.17.23",
|
||||
"meta-json-schema": "^1.19.21",
|
||||
@ -71,7 +71,7 @@
|
||||
"react-dom": "19.2.4",
|
||||
"react-error-boundary": "6.1.1",
|
||||
"react-hook-form": "^7.72.0",
|
||||
"react-i18next": "16.6.6",
|
||||
"react-i18next": "17.0.1",
|
||||
"react-markdown": "10.1.0",
|
||||
"react-router": "^7.13.1",
|
||||
"react-virtuoso": "^4.18.3",
|
||||
@ -120,7 +120,7 @@
|
||||
"typescript": "^6.0.0",
|
||||
"typescript-eslint": "^8.57.1",
|
||||
"vite": "^8.0.1",
|
||||
"vite-plugin-svgr": "^4.5.0"
|
||||
"vite-plugin-svgr": "^5.0.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx}": [
|
||||
|
||||
38
pnpm-lock.yaml
generated
38
pnpm-lock.yaml
generated
@ -87,8 +87,8 @@ importers:
|
||||
specifier: ^5.3.0
|
||||
version: 5.3.0
|
||||
i18next:
|
||||
specifier: ^25.10.4
|
||||
version: 25.10.4(typescript@6.0.2)
|
||||
specifier: ^26.0.0
|
||||
version: 26.0.2(typescript@6.0.2)
|
||||
js-yaml:
|
||||
specifier: ^4.1.1
|
||||
version: 4.1.1
|
||||
@ -120,8 +120,8 @@ importers:
|
||||
specifier: ^7.72.0
|
||||
version: 7.72.0(react@19.2.4)
|
||||
react-i18next:
|
||||
specifier: 16.6.6
|
||||
version: 16.6.6(i18next@25.10.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)
|
||||
specifier: 17.0.1
|
||||
version: 17.0.1(i18next@26.0.2(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2)
|
||||
react-markdown:
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0(@types/react@19.2.14)(react@19.2.4)
|
||||
@ -262,8 +262,8 @@ importers:
|
||||
specifier: ^8.0.1
|
||||
version: 8.0.1(@types/node@24.12.0)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3)
|
||||
vite-plugin-svgr:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0(typescript@6.0.2)(vite@8.0.1(@types/node@24.12.0)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3))
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0(typescript@6.0.2)(vite@8.0.1(@types/node@24.12.0)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3))
|
||||
|
||||
packages:
|
||||
|
||||
@ -2491,10 +2491,10 @@ packages:
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
i18next@25.10.4:
|
||||
resolution: {integrity: sha512-XsE/6eawy090meuFU0BTY9BtmWr1m9NSwLr0NK7/A04LA58wdAvDsi9WNOJ40Qb1E9NIPbvnVLZEN2fWDd3/3Q==}
|
||||
i18next@26.0.2:
|
||||
resolution: {integrity: sha512-WsK0SdP+7tGzsxpT+Us1s2nvOyx657DatBodaNZe4KcPTPYzkVfRKUygN69mB+sCbbnifRuKz+Ya5JRzd8DNHw==}
|
||||
peerDependencies:
|
||||
typescript: ^5
|
||||
typescript: ^5 || ^6
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
@ -3055,10 +3055,10 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18 || ^19
|
||||
|
||||
react-i18next@16.6.6:
|
||||
resolution: {integrity: sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==}
|
||||
react-i18next@17.0.1:
|
||||
resolution: {integrity: sha512-iG65FGnFHcYyHNuT01ukffYWCOBFTWSdVD8EZd/dCVWgtjFPObcSsvYYNwcsokO/rDcTb5d6D8Acv8MrOdm6Hw==}
|
||||
peerDependencies:
|
||||
i18next: '>= 25.10.9'
|
||||
i18next: '>= 26.0.1'
|
||||
react: '>= 16.8.0'
|
||||
react-dom: '*'
|
||||
react-native: '*'
|
||||
@ -3434,10 +3434,10 @@ packages:
|
||||
vfile@6.0.3:
|
||||
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
||||
|
||||
vite-plugin-svgr@4.5.0:
|
||||
resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==}
|
||||
vite-plugin-svgr@5.0.0:
|
||||
resolution: {integrity: sha512-CZFWDtbWSLnF6C+uv8u7E5Ao6UVQYBpJrS6212XsEod/Lm4ErhOoFc01/po4ie5hqvMCr5KYrlMrSGQQEtMtBg==}
|
||||
peerDependencies:
|
||||
vite: '>=2.6.0'
|
||||
vite: '>=3.0.0'
|
||||
|
||||
vite@8.0.1:
|
||||
resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==}
|
||||
@ -6016,7 +6016,7 @@ snapshots:
|
||||
|
||||
husky@9.1.7: {}
|
||||
|
||||
i18next@25.10.4(typescript@6.0.2):
|
||||
i18next@26.0.2(typescript@6.0.2):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.2
|
||||
optionalDependencies:
|
||||
@ -6656,11 +6656,11 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
|
||||
react-i18next@16.6.6(i18next@25.10.4(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2):
|
||||
react-i18next@17.0.1(i18next@26.0.2(typescript@6.0.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.2):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.2
|
||||
html-parse-stringify: 3.0.1
|
||||
i18next: 25.10.4(typescript@6.0.2)
|
||||
i18next: 26.0.2(typescript@6.0.2)
|
||||
react: 19.2.4
|
||||
use-sync-external-store: 1.6.0(react@19.2.4)
|
||||
optionalDependencies:
|
||||
@ -7078,7 +7078,7 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.3
|
||||
|
||||
vite-plugin-svgr@4.5.0(typescript@6.0.2)(vite@8.0.1(@types/node@24.12.0)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3)):
|
||||
vite-plugin-svgr@5.0.0(typescript@6.0.2)(vite@8.0.1(@types/node@24.12.0)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(yaml@2.8.3)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0
|
||||
'@svgr/core': 8.1.0(typescript@6.0.2)
|
||||
|
||||
@ -100,8 +100,7 @@ async function resolveUpdater() {
|
||||
|
||||
Object.entries(updateDataNew.platforms).forEach(([key, value]) => {
|
||||
if (value.url) {
|
||||
updateDataNew.platforms[key].url =
|
||||
'https://download.clashverge.dev/' + value.url
|
||||
updateDataNew.platforms[key].url = 'https://update.hwdns.net/' + value.url
|
||||
} else {
|
||||
console.log(`[Error]: updateDataNew.platforms.${key} is null`)
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ async function processRelease(github, options, tag, isAlpha) {
|
||||
Object.entries(updateDataNew.platforms).forEach(([key, value]) => {
|
||||
if (value.url) {
|
||||
updateDataNew.platforms[key].url =
|
||||
'https://download.clashverge.dev/' + value.url
|
||||
'https://update.hwdns.net/' + value.url
|
||||
} else {
|
||||
console.log(`[Error]: updateDataNew.platforms.${key} is null`)
|
||||
}
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK",
|
||||
"endpoints": [
|
||||
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
|
||||
"https://gh-proxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
|
||||
"https://update.hwdns.net/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
|
||||
"https://gh-proxy.org/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-proxy.json",
|
||||
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update.json"
|
||||
],
|
||||
"windows": {
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
"active": true,
|
||||
"dialog": false,
|
||||
"endpoints": [
|
||||
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://update.hwdns.net/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json"
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
"active": true,
|
||||
"dialog": false,
|
||||
"endpoints": [
|
||||
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://update.hwdns.net/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json"
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
"active": true,
|
||||
"dialog": false,
|
||||
"endpoints": [
|
||||
"https://download.clashverge.dev/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://update.hwdns.net/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json",
|
||||
"https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json"
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
|
||||
@ -7,13 +7,17 @@ import {
|
||||
} from '@mui/icons-material'
|
||||
import { Typography, Stack, Divider, Chip, IconButton } from '@mui/material'
|
||||
import { useLockFn } from 'ahooks'
|
||||
import { useCallback, useEffect, useMemo, useReducer } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { useServiceInstaller } from '@/hooks/use-service-installer'
|
||||
import { useSystemState } from '@/hooks/use-system-state'
|
||||
import { useUpdate } from '@/hooks/use-update'
|
||||
import {
|
||||
useUpdate,
|
||||
updateLastCheckTime,
|
||||
readLastCheckTime,
|
||||
} from '@/hooks/use-update'
|
||||
import { useVerge } from '@/hooks/use-verge'
|
||||
import { getSystemInfo } from '@/services/cmds'
|
||||
import { showNotice } from '@/services/notice-service'
|
||||
@ -21,29 +25,6 @@ import { version as appVersion } from '@root/package.json'
|
||||
|
||||
import { EnhancedCard } from './enhanced-card'
|
||||
|
||||
interface SystemState {
|
||||
osInfo: string
|
||||
lastCheckUpdate: string
|
||||
}
|
||||
|
||||
type SystemStateAction =
|
||||
| { type: 'set-os-info'; payload: string }
|
||||
| { type: 'set-last-check-update'; payload: string }
|
||||
|
||||
const systemStateReducer = (
|
||||
state: SystemState,
|
||||
action: SystemStateAction,
|
||||
): SystemState => {
|
||||
switch (action.type) {
|
||||
case 'set-os-info':
|
||||
return { ...state, osInfo: action.payload }
|
||||
case 'set-last-check-update':
|
||||
return { ...state, lastCheckUpdate: action.payload }
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
||||
|
||||
export const SystemInfoCard = () => {
|
||||
const { t } = useTranslation()
|
||||
const { verge, patchVerge } = useVerge()
|
||||
@ -51,28 +32,18 @@ export const SystemInfoCard = () => {
|
||||
const { isAdminMode, isSidecarMode } = useSystemState()
|
||||
const { installServiceAndRestartCore } = useServiceInstaller()
|
||||
|
||||
// 自动检查更新逻辑
|
||||
const { checkUpdate: triggerCheckUpdate } = useUpdate(true, {
|
||||
onSuccess: () => {
|
||||
const now = Date.now()
|
||||
localStorage.setItem('last_check_update', now.toString())
|
||||
dispatchSystemState({
|
||||
type: 'set-last-check-update',
|
||||
payload: new Date(now).toLocaleString(),
|
||||
})
|
||||
},
|
||||
})
|
||||
// 自动检查更新逻辑(lastCheckUpdate 由 useUpdate 统一管理)
|
||||
const { checkUpdate: triggerCheckUpdate, lastCheckUpdate } = useUpdate(true)
|
||||
|
||||
// 系统信息状态
|
||||
const [systemState, dispatchSystemState] = useReducer(systemStateReducer, {
|
||||
osInfo: '',
|
||||
lastCheckUpdate: '-',
|
||||
})
|
||||
const [osInfo, setOsInfo] = useState('')
|
||||
|
||||
const lastCheckUpdateText = useMemo(
|
||||
() => (lastCheckUpdate ? new Date(lastCheckUpdate).toLocaleString() : '-'),
|
||||
[lastCheckUpdate],
|
||||
)
|
||||
|
||||
// 初始化系统信息
|
||||
useEffect(() => {
|
||||
let timeoutId: number | undefined
|
||||
|
||||
getSystemInfo()
|
||||
.then((info) => {
|
||||
const lines = info.split('\n')
|
||||
@ -87,49 +58,23 @@ export const SystemInfoCard = () => {
|
||||
sysVersion = sysVersion.substring(sysName.length).trim()
|
||||
}
|
||||
|
||||
dispatchSystemState({
|
||||
type: 'set-os-info',
|
||||
payload: `${sysName} ${sysVersion}`,
|
||||
})
|
||||
setOsInfo(`${sysName} ${sysVersion}`)
|
||||
}
|
||||
})
|
||||
.catch(console.error)
|
||||
}, [])
|
||||
|
||||
// 获取最后检查更新时间
|
||||
const lastCheck = localStorage.getItem('last_check_update')
|
||||
if (lastCheck) {
|
||||
try {
|
||||
const timestamp = parseInt(lastCheck, 10)
|
||||
if (!isNaN(timestamp)) {
|
||||
dispatchSystemState({
|
||||
type: 'set-last-check-update',
|
||||
payload: new Date(timestamp).toLocaleString(),
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error parsing last check update time', e)
|
||||
}
|
||||
} else if (verge?.auto_check_update) {
|
||||
// 如果启用了自动检查更新但没有记录,设置当前时间并延迟检查
|
||||
const now = Date.now()
|
||||
localStorage.setItem('last_check_update', now.toString())
|
||||
dispatchSystemState({
|
||||
type: 'set-last-check-update',
|
||||
payload: new Date(now).toLocaleString(),
|
||||
})
|
||||
// 如果启用了自动检查更新但没有记录,设置当前时间并延迟检查
|
||||
useEffect(() => {
|
||||
if (!verge?.auto_check_update) return
|
||||
if (readLastCheckTime() !== null) return
|
||||
|
||||
timeoutId = window.setTimeout(() => {
|
||||
if (verge?.auto_check_update) {
|
||||
triggerCheckUpdate().catch(console.error)
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
return () => {
|
||||
if (timeoutId !== undefined) {
|
||||
window.clearTimeout(timeoutId)
|
||||
}
|
||||
}
|
||||
}, [verge?.auto_check_update, dispatchSystemState, triggerCheckUpdate])
|
||||
updateLastCheckTime()
|
||||
const timeoutId = window.setTimeout(() => {
|
||||
triggerCheckUpdate().catch(console.error)
|
||||
}, 5000)
|
||||
return () => window.clearTimeout(timeoutId)
|
||||
}, [verge?.auto_check_update, triggerCheckUpdate])
|
||||
|
||||
// 导航到设置页面
|
||||
const goToSettings = useCallback(() => {
|
||||
@ -157,12 +102,6 @@ export const SystemInfoCard = () => {
|
||||
const onCheckUpdate = useLockFn(async () => {
|
||||
try {
|
||||
const info = await triggerCheckUpdate()
|
||||
const now = Date.now()
|
||||
localStorage.setItem('last_check_update', now.toString())
|
||||
dispatchSystemState({
|
||||
type: 'set-last-check-update',
|
||||
payload: new Date(now).toLocaleString(),
|
||||
})
|
||||
if (!info?.available) {
|
||||
showNotice.success(
|
||||
'settings.components.verge.advanced.notifications.latestVersion',
|
||||
@ -280,7 +219,7 @@ export const SystemInfoCard = () => {
|
||||
{t('home.components.systemInfo.fields.osInfo')}
|
||||
</Typography>
|
||||
<Typography variant="body2" fontWeight="medium">
|
||||
{systemState.osInfo}
|
||||
{osInfo}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Divider />
|
||||
@ -341,7 +280,7 @@ export const SystemInfoCard = () => {
|
||||
'&:hover': { opacity: 0.7 },
|
||||
}}
|
||||
>
|
||||
{systemState.lastCheckUpdate}
|
||||
{lastCheckUpdateText}
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Divider />
|
||||
|
||||
@ -78,7 +78,6 @@ const SettingClash = ({ onError }: Props) => {
|
||||
const handleDnsToggle = useLockFn(async (enable: boolean) => {
|
||||
try {
|
||||
setDnsSettingsEnabled(enable)
|
||||
localStorage.setItem('dns_settings_enabled', String(enable))
|
||||
await patchVerge({ enable_dns_settings: enable })
|
||||
await invoke('apply_dns_config', { apply: enable })
|
||||
setTimeout(() => {
|
||||
@ -86,7 +85,6 @@ const SettingClash = ({ onError }: Props) => {
|
||||
}, 500)
|
||||
} catch (err: any) {
|
||||
setDnsSettingsEnabled(!enable)
|
||||
localStorage.setItem('dns_settings_enabled', String(!enable))
|
||||
showNotice.error(err)
|
||||
await patchVerge({ enable_dns_settings: !enable }).catch(() => {})
|
||||
throw err
|
||||
|
||||
@ -4,6 +4,7 @@ import { useCallback, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { DialogRef, TooltipIcon } from '@/components/base'
|
||||
import { updateLastCheckTime } from '@/hooks/use-update'
|
||||
import {
|
||||
exitApp,
|
||||
exportDiagnosticInfo,
|
||||
@ -45,6 +46,7 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
|
||||
const onCheckUpdate = async () => {
|
||||
try {
|
||||
const info = await checkUpdate()
|
||||
updateLastCheckTime()
|
||||
if (!info?.available) {
|
||||
showNotice.success(
|
||||
'settings.components.verge.advanced.notifications.latestVersion',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import useSWR, { SWRConfiguration } from 'swr'
|
||||
import useSWR, { mutate as globalMutate, SWRConfiguration } from 'swr'
|
||||
|
||||
import { checkUpdateSafe } from '@/services/update'
|
||||
|
||||
@ -12,6 +12,26 @@ export interface UpdateInfo {
|
||||
downloadAndInstall: (onEvent?: any) => Promise<void>
|
||||
}
|
||||
|
||||
// --- Last check timestamp (shared via SWR + localStorage) ---
|
||||
|
||||
const LAST_CHECK_KEY = 'last_check_update'
|
||||
|
||||
export const readLastCheckTime = (): number | null => {
|
||||
const stored = localStorage.getItem(LAST_CHECK_KEY)
|
||||
if (!stored) return null
|
||||
const ts = parseInt(stored, 10)
|
||||
return isNaN(ts) ? null : ts
|
||||
}
|
||||
|
||||
export const updateLastCheckTime = (timestamp?: number): number => {
|
||||
const now = timestamp ?? Date.now()
|
||||
localStorage.setItem(LAST_CHECK_KEY, now.toString())
|
||||
globalMutate(LAST_CHECK_KEY, now, false)
|
||||
return now
|
||||
}
|
||||
|
||||
// --- useUpdate hook ---
|
||||
|
||||
export const useUpdate = (
|
||||
enabled: boolean = true,
|
||||
options?: SWRConfiguration,
|
||||
@ -36,11 +56,22 @@ export const useUpdate = (
|
||||
refreshInterval: 24 * 60 * 60 * 1000, // 24 hours
|
||||
dedupingInterval: 60 * 60 * 1000, // 1 hour
|
||||
...options,
|
||||
onSuccess: (...args) => {
|
||||
updateLastCheckTime()
|
||||
options?.onSuccess?.(...args)
|
||||
},
|
||||
})
|
||||
|
||||
// Shared last check timestamp
|
||||
const { data: lastCheckUpdate } = useSWR(LAST_CHECK_KEY, readLastCheckTime, {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
})
|
||||
|
||||
return {
|
||||
updateInfo,
|
||||
checkUpdate,
|
||||
loading: isValidating,
|
||||
lastCheckUpdate: lastCheckUpdate ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user