mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-06-16 13:34:04 +08:00
fix(import): refresh all providers immediately after SQL import
- Remove setTimeout delay that could be cancelled on component unmount - Invalidate all providers cache (not just current app) since import affects all apps - Call onImportSuccess before sync to ensure UI refresh even if sync fails - Update i18n: "Data refreshed" (past tense, reflecting immediate action)
This commit is contained in:
+16
-1
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
Plus,
|
||||
Settings,
|
||||
@@ -45,6 +46,7 @@ type View = "providers" | "settings" | "prompts" | "skills" | "mcp" | "agents";
|
||||
|
||||
function App() {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [activeApp, setActiveApp] = useState<AppId>("claude");
|
||||
const [currentView, setCurrentView] = useState<View>("providers");
|
||||
@@ -258,7 +260,20 @@ function App() {
|
||||
|
||||
// 导入配置成功后刷新
|
||||
const handleImportSuccess = async () => {
|
||||
await refetch();
|
||||
try {
|
||||
// 导入会影响所有应用的供应商数据:刷新所有 providers 缓存
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ["providers"],
|
||||
refetchType: "all",
|
||||
});
|
||||
await queryClient.refetchQueries({
|
||||
queryKey: ["providers"],
|
||||
type: "all",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("[App] Failed to refresh providers after import", error);
|
||||
await refetch();
|
||||
}
|
||||
try {
|
||||
await providersApi.updateTrayMenu();
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { settingsApi } from "@/lib/api";
|
||||
@@ -39,15 +39,6 @@ export function useImportExport(
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [backupId, setBackupId] = useState<string | null>(null);
|
||||
const [isImporting, setIsImporting] = useState(false);
|
||||
const successTimerRef = useRef<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (successTimerRef.current) {
|
||||
window.clearTimeout(successTimerRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const clearSelection = useCallback(() => {
|
||||
setSelectedFile("");
|
||||
@@ -105,6 +96,10 @@ export function useImportExport(
|
||||
}
|
||||
|
||||
setBackupId(result.backupId ?? null);
|
||||
// 导入成功后立即触发外部刷新(与 live 同步结果解耦)
|
||||
// - 避免 sync 失败时 UI 不刷新
|
||||
// - 避免依赖 setTimeout(组件卸载会取消)
|
||||
void onImportSuccess?.();
|
||||
|
||||
const syncResult = await syncCurrentProvidersLiveSafe();
|
||||
if (syncResult.ok) {
|
||||
@@ -114,10 +109,6 @@ export function useImportExport(
|
||||
defaultValue: "配置导入成功",
|
||||
}),
|
||||
);
|
||||
|
||||
successTimerRef.current = window.setTimeout(() => {
|
||||
void onImportSuccess?.();
|
||||
}, 1500);
|
||||
} else {
|
||||
console.error(
|
||||
"[useImportExport] Failed to sync live config",
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
"selectFileFailed": "Please choose a valid SQL backup file",
|
||||
"configCorrupted": "SQL file may be corrupted or invalid",
|
||||
"backupId": "Backup ID",
|
||||
"autoReload": "Data will refresh automatically in 2 seconds...",
|
||||
"autoReload": "Data refreshed",
|
||||
"languageOptionChinese": "中文",
|
||||
"languageOptionEnglish": "English",
|
||||
"languageOptionJapanese": "日本語",
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
"selectFileFailed": "有効な SQL バックアップファイルを選択してください",
|
||||
"configCorrupted": "SQL ファイルが壊れているか形式が無効な可能性があります",
|
||||
"backupId": "バックアップ ID",
|
||||
"autoReload": "2 秒後に自動で再読み込みします...",
|
||||
"autoReload": "データを更新しました",
|
||||
"languageOptionChinese": "中文",
|
||||
"languageOptionEnglish": "English",
|
||||
"languageOptionJapanese": "日本語",
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
"selectFileFailed": "请选择有效的 SQL 备份文件",
|
||||
"configCorrupted": "SQL 文件可能已损坏或格式不正确",
|
||||
"backupId": "备份ID",
|
||||
"autoReload": "数据将在2秒后自动刷新...",
|
||||
"autoReload": "数据已刷新",
|
||||
"languageOptionChinese": "中文",
|
||||
"languageOptionEnglish": "English",
|
||||
"languageOptionJapanese": "日本語",
|
||||
|
||||
@@ -110,12 +110,6 @@ describe("useImportExport Hook", () => {
|
||||
expect(result.current.status).toBe("success");
|
||||
expect(result.current.backupId).toBe("backup-123");
|
||||
expect(toastSuccessMock).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Skip delay to execute callback
|
||||
await act(async () => {
|
||||
vi.runOnlyPendingTimers();
|
||||
});
|
||||
|
||||
expect(onImportSuccess).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user