mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-26 22:22:13 +08:00
* fix(config): prevent cleanup_orphaned_files from deleting active profiles When IProfiles::new() fails to parse profiles.yaml (e.g., corrupt file), it returns Self::default() with items: None. The subsequent cleanup_orphaned_files() call then sees no active files and deletes all profile files in the profiles/ directory except the two hardcoded protected files (Merge.yaml and Script.js). Guard cleanup_orphaned_files() against this by checking if items is None or empty before proceeding. When items is unavailable, skip the cleanup and log a warning instead of blindly deleting user data. Fixes #7577 * fix(home): manual update check not working when auto_check_update disabled When auto_check_update is false, useUpdate() sets enabled=false for the SWR query, which sets the SWR key to null. Calling swr.mutate() on a null key does not execute the queryFn, returning undefined instead. This caused the home page's "last check time" click to instantly show "already up to date" without actually checking for updates. Fix: use revalidateQuery() for the manual checkUpdate function, which uses the global SWR mutate with the actual query key, bypassing the enabled: false state and always triggering a real network request. Fixes #7584 * fix: preserve manual update and profile data --------- Co-authored-by: Evan Gong <evan@users.noreply.github.com> Co-authored-by: wonfen <96291150+wonfen@users.noreply.github.com> Co-authored-by: wonfen <eiwonfen@gmail.com>
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { fetchCacheData, setCacheData, useQuery } from '@/services/query-client'
|
|
import { checkUpdateSafe } from '@/services/update'
|
|
|
|
import { useVerge } from './use-verge'
|
|
|
|
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())
|
|
setCacheData([LAST_CHECK_KEY], now)
|
|
return now
|
|
}
|
|
|
|
// --- useUpdate hook ---
|
|
|
|
export const useUpdate = (enabled: boolean = true) => {
|
|
const { verge } = useVerge()
|
|
const { auto_check_update } = verge || {}
|
|
|
|
// Determine if we should check for updates
|
|
// If enabled is explicitly false, don't check
|
|
// Otherwise, respect the auto_check_update setting (or default to true if null/undefined for manual triggers)
|
|
const shouldCheck = enabled && auto_check_update !== false
|
|
|
|
const fetchUpdate = async () => {
|
|
const result = await checkUpdateSafe()
|
|
updateLastCheckTime()
|
|
return result
|
|
}
|
|
|
|
const { data: updateInfo, isFetching: isValidating } = useQuery({
|
|
queryKey: ['checkUpdate'],
|
|
queryFn: fetchUpdate,
|
|
enabled: shouldCheck,
|
|
retry: 2,
|
|
staleTime: 60 * 60 * 1000,
|
|
refetchInterval: 24 * 60 * 60 * 1000,
|
|
refetchIntervalInBackground: false,
|
|
refetchOnWindowFocus: false,
|
|
})
|
|
|
|
const checkUpdate = async () => {
|
|
const data = await fetchCacheData(['checkUpdate'], fetchUpdate)
|
|
return { data }
|
|
}
|
|
|
|
// Shared last check timestamp
|
|
const { data: lastCheckUpdate } = useQuery({
|
|
queryKey: [LAST_CHECK_KEY],
|
|
queryFn: readLastCheckTime,
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
})
|
|
|
|
return {
|
|
updateInfo,
|
|
checkUpdate,
|
|
loading: isValidating,
|
|
lastCheckUpdate: lastCheckUpdate ?? null,
|
|
}
|
|
}
|