From 437fef1c30e71877efbb2d82ade8e415ab623ff7 Mon Sep 17 00:00:00 2001
From: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon, 6 Apr 2026 02:14:33 +0800
Subject: [PATCH] fix: eliminate error flash on startup by distinguishing
loading from error state
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Change TQ_MIHOMO retryDelay from fixed 2000ms to exponential backoff
(200ms → 400ms → 800ms, cap 3s) so core-dependent queries retry faster
- Expose isCoreDataPending from AppDataProvider to distinguish between
data still loading vs actual errors
- ClashModeCard: show placeholder instead of "communication error" while
core data is pending
- CurrentProxyCard: show empty space instead of "no active node" while
core data is pending
---
src/components/home/clash-mode-card.tsx | 7 +++++--
src/components/home/current-proxy-card.tsx | 7 +++++--
src/providers/app-data-context.ts | 1 +
src/providers/app-data-provider.tsx | 19 ++++++++++++++++---
4 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/src/components/home/clash-mode-card.tsx b/src/components/home/clash-mode-card.tsx
index 4e55c67b2..d346a1421 100644
--- a/src/components/home/clash-mode-card.tsx
+++ b/src/components/home/clash-mode-card.tsx
@@ -41,7 +41,7 @@ const MODE_META: Record<
export const ClashModeCard = () => {
const { t } = useTranslation()
const { verge } = useVerge()
- const { clashConfig, refreshClashConfig } = useAppData()
+ const { clashConfig, isCoreDataPending, refreshClashConfig } = useAppData()
// 支持的模式列表
const modeList = CLASH_MODES
@@ -57,8 +57,11 @@ export const ClashModeCard = () => {
if (currentModeKey) {
return t(MODE_META[currentModeKey].description)
}
+ if (isCoreDataPending) {
+ return '\u00A0'
+ }
return t('home.components.clashMode.errors.communication')
- }, [currentModeKey, t])
+ }, [currentModeKey, isCoreDataPending, t])
// 模式图标映射
const modeIcons = useMemo(
diff --git a/src/components/home/current-proxy-card.tsx b/src/components/home/current-proxy-card.tsx
index d02ce36de..a9428ae9e 100644
--- a/src/components/home/current-proxy-card.tsx
+++ b/src/components/home/current-proxy-card.tsx
@@ -105,7 +105,8 @@ export const CurrentProxyCard = () => {
const { t } = useTranslation()
const navigate = useNavigate()
const theme = useTheme()
- const { proxies, clashConfig, refreshProxy, rules } = useAppData()
+ const { proxies, clashConfig, isCoreDataPending, refreshProxy, rules } =
+ useAppData()
const { verge } = useVerge()
const { current: currentProfile } = useProfiles()
const autoDelayEnabled = verge?.enable_auto_delay_detection ?? false
@@ -911,7 +912,9 @@ export const CurrentProxyCard = () => {
}
>
- {currentProxy ? (
+ {isCoreDataPending ? (
+
+ ) : currentProxy ? (
{/* 代理节点信息显示 */}
ruleProviders: Record
systemProxyAddress: string
+ isCoreDataPending: boolean
refreshProxy: () => Promise
refreshClashConfig: () => Promise
diff --git a/src/providers/app-data-provider.tsx b/src/providers/app-data-provider.tsx
index 9c2d15ebd..c6b7565cc 100644
--- a/src/providers/app-data-provider.tsx
+++ b/src/providers/app-data-provider.tsx
@@ -23,7 +23,7 @@ const TQ_MIHOMO = {
refetchOnReconnect: false,
staleTime: 1500,
retry: 3,
- retryDelay: 2000,
+ retryDelay: (attempt: number) => Math.min(200 * 2 ** attempt, 3000),
} as const
const TQ_DEFAULTS = {
@@ -41,13 +41,21 @@ export const AppDataProvider = ({
}) => {
const { verge } = useVerge()
- const { data: proxiesData, refetch: refreshProxy } = useQuery({
+ const {
+ data: proxiesData,
+ isPending: isProxiesPending,
+ refetch: refreshProxy,
+ } = useQuery({
queryKey: ['getProxies'],
queryFn: calcuProxies,
...TQ_MIHOMO,
})
- const { data: clashConfig, refetch: refreshClashConfig } = useQuery({
+ const {
+ data: clashConfig,
+ isPending: isClashConfigPending,
+ refetch: refreshClashConfig,
+ } = useQuery({
queryKey: ['getClashConfig'],
queryFn: getBaseConfig,
...TQ_MIHOMO,
@@ -323,6 +331,9 @@ export const AppDataProvider = ({
systemProxyAddress: calculateSystemProxyAddress(),
+ // core 数据加载状态
+ isCoreDataPending: isProxiesPending || isClashConfigPending,
+
// 刷新方法
refreshProxy,
refreshClashConfig,
@@ -335,6 +346,8 @@ export const AppDataProvider = ({
}, [
proxiesData,
clashConfig,
+ isProxiesPending,
+ isClashConfigPending,
rulesData,
sysproxy,
runningMode,