mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-10-26 01:34:51 +08:00
fix(providers): stop flashing the previous app's list when switching apps
useProvidersQuery used keepPreviousData, but its key only varies by app, so the placeholder was always another app's providers: the first switch to Codex briefly showed Claude's cards, Gemini showed OpenCode's empty state. Drop the placeholder and instead prefetch every visible app's list once settings load, keeping the small lists cached so later switches render the right data on the first frame.
This commit is contained in:
1 parent
c57d64f4de
commit
98d163237a
2 files changed
+53
-29
No files matched your search
+18
-1
@@ -8,7 +8,12 @@ import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import type { Provider, VisibleApps } from "@/types";
|
||||
import { KNOWN_APP_TYPES, type AppTypeFilter } from "@/types/usage";
|
||||
import type { EnvConflict } from "@/types/env";
|
||||
import { proxyKeys, useProvidersQuery, useSettingsQuery } from "@/lib/query";
|
||||
import {
|
||||
providersQueryOptions,
|
||||
proxyKeys,
|
||||
useProvidersQuery,
|
||||
useSettingsQuery,
|
||||
} from "@/lib/query";
|
||||
import {
|
||||
piApi,
|
||||
providersApi,
|
||||
@@ -185,6 +190,18 @@ function App() {
|
||||
}
|
||||
}, [visibleApps, activeApp]);
|
||||
|
||||
// 启动后把其他可见应用的供应商列表预取进缓存:第一次切过去直接有数据,不先画骨架
|
||||
const providersPrefetchedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (!settingsData || providersPrefetchedRef.current) return;
|
||||
providersPrefetchedRef.current = true;
|
||||
for (const app of APP_IDS) {
|
||||
if (app !== activeApp && visibleApps[app]) {
|
||||
void queryClient.prefetchQuery(providersQueryOptions(app));
|
||||
}
|
||||
}
|
||||
}, [settingsData, visibleApps, activeApp, queryClient]);
|
||||
|
||||
// 「启动时检查应用更新」(默认关):打开了才在后台查一次,查到新版本侧栏「应用」上出现圆点
|
||||
const checkToolUpdatesOnStartup =
|
||||
settingsData?.checkToolUpdatesOnStartup ?? false;
|
||||
|
||||
+35
-28
@@ -1,9 +1,5 @@
|
||||
import { useRef } from "react";
|
||||
import {
|
||||
useQuery,
|
||||
type UseQueryResult,
|
||||
keepPreviousData,
|
||||
} from "@tanstack/react-query";
|
||||
import { useQuery, type UseQueryResult } from "@tanstack/react-query";
|
||||
import {
|
||||
providersApi,
|
||||
settingsApi,
|
||||
@@ -47,39 +43,50 @@ export interface UseProvidersQueryOptions {
|
||||
isProxyRunning?: boolean; // 代理服务是否运行中
|
||||
}
|
||||
|
||||
/**
|
||||
* 供应商列表的查询键与读取函数。App 启动后用它把其他应用的列表预取进缓存,
|
||||
* 第一次切过去时直接有数据,不用先画骨架。
|
||||
*/
|
||||
export const providersQueryOptions = (appId: AppId) => ({
|
||||
queryKey: ["providers", appId] as const,
|
||||
// 列表很小:没人订阅时也一直留在缓存里,过了默认的 5 分钟再切过去也不画骨架
|
||||
gcTime: Infinity,
|
||||
queryFn: async (): Promise<ProvidersQueryData> => {
|
||||
let providers: Record<string, Provider> = {};
|
||||
let currentProviderId = "";
|
||||
|
||||
try {
|
||||
providers = await providersApi.getAll(appId);
|
||||
} catch (error) {
|
||||
console.error("获取供应商列表失败:", error);
|
||||
}
|
||||
|
||||
try {
|
||||
currentProviderId = await providersApi.getCurrent(appId);
|
||||
} catch (error) {
|
||||
console.error("获取当前供应商失败:", error);
|
||||
}
|
||||
|
||||
return {
|
||||
providers: sortProviders(providers),
|
||||
currentProviderId,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const useProvidersQuery = (
|
||||
appId: AppId,
|
||||
options?: UseProvidersQueryOptions,
|
||||
): UseQueryResult<ProvidersQueryData> => {
|
||||
const { isProxyRunning = false } = options || {};
|
||||
|
||||
// 不设 keepPreviousData:键只随应用变化,占位数据就是上一个应用的列表,
|
||||
// 切应用时会先闪一下别家的卡片
|
||||
return useQuery({
|
||||
queryKey: ["providers", appId],
|
||||
placeholderData: keepPreviousData,
|
||||
...providersQueryOptions(appId),
|
||||
// 当代理服务运行时,每 10 秒刷新一次供应商列表
|
||||
// 这样可以自动反映后端熔断器自动禁用代理目标的变更
|
||||
refetchInterval: isProxyRunning ? 10000 : false,
|
||||
queryFn: async () => {
|
||||
let providers: Record<string, Provider> = {};
|
||||
let currentProviderId = "";
|
||||
|
||||
try {
|
||||
providers = await providersApi.getAll(appId);
|
||||
} catch (error) {
|
||||
console.error("获取供应商列表失败:", error);
|
||||
}
|
||||
|
||||
try {
|
||||
currentProviderId = await providersApi.getCurrent(appId);
|
||||
} catch (error) {
|
||||
console.error("获取当前供应商失败:", error);
|
||||
}
|
||||
|
||||
return {
|
||||
providers: sortProviders(providers),
|
||||
currentProviderId,
|
||||
};
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user