perf: remove system-level unlock test timeout notice

This commit is contained in:
wonfen
2025-09-15 22:16:13 +08:00
parent 0855bd4896
commit c438e916ca
3 changed files with 33 additions and 32 deletions

View File

@@ -677,5 +677,6 @@
"Controller address copied to clipboard": "Controller address copied to clipboard", "Controller address copied to clipboard": "Controller address copied to clipboard",
"Secret copied to clipboard": "Secret copied to clipboard", "Secret copied to clipboard": "Secret copied to clipboard",
"Saving...": "Saving...", "Saving...": "Saving...",
"Proxy node already exists in chain": "Proxy node already exists in chain" "Proxy node already exists in chain": "Proxy node already exists in chain",
"Detection timeout or failed": "Detection timeout or failed"
} }

View File

@@ -677,5 +677,6 @@
"Controller address copied to clipboard": "控制器地址已复制到剪贴板", "Controller address copied to clipboard": "控制器地址已复制到剪贴板",
"Secret copied to clipboard": "访问密钥已复制到剪贴板", "Secret copied to clipboard": "访问密钥已复制到剪贴板",
"Saving...": "保存中...", "Saving...": "保存中...",
"Proxy node already exists in chain": "该节点已在链式代理表中" "Proxy node already exists in chain": "该节点已在链式代理表中",
"Detection timeout or failed": "检测超时或失败"
} }

View File

@@ -26,7 +26,6 @@ import {
} from "@mui/icons-material"; } from "@mui/icons-material";
import { showNotice } from "@/services/noticeService"; import { showNotice } from "@/services/noticeService";
// 定义流媒体检测项类型
interface UnlockItem { interface UnlockItem {
name: string; name: string;
status: string; status: string;
@@ -34,7 +33,6 @@ interface UnlockItem {
check_time?: string | null; check_time?: string | null;
} }
// 用于存储测试结果的本地存储键名
const UNLOCK_RESULTS_STORAGE_KEY = "clash_verge_unlock_results"; const UNLOCK_RESULTS_STORAGE_KEY = "clash_verge_unlock_results";
const UNLOCK_RESULTS_TIME_KEY = "clash_verge_unlock_time"; const UNLOCK_RESULTS_TIME_KEY = "clash_verge_unlock_time";
@@ -42,14 +40,10 @@ const UnlockPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const theme = useTheme(); const theme = useTheme();
// 保存所有流媒体检测项的状态
const [unlockItems, setUnlockItems] = useState<UnlockItem[]>([]); const [unlockItems, setUnlockItems] = useState<UnlockItem[]>([]);
// 是否正在执行全部检测
const [isCheckingAll, setIsCheckingAll] = useState(false); const [isCheckingAll, setIsCheckingAll] = useState(false);
// 记录正在检测中的项目
const [loadingItems, setLoadingItems] = useState<string[]>([]); const [loadingItems, setLoadingItems] = useState<string[]>([]);
// 按首字母排序项目
const sortItemsByName = (items: UnlockItem[]) => { const sortItemsByName = (items: UnlockItem[]) => {
return [...items].sort((a, b) => a.name.localeCompare(b.name)); return [...items].sort((a, b) => a.name.localeCompare(b.name));
}; };
@@ -66,7 +60,6 @@ const UnlockPage = () => {
} }
}; };
// 从本地存储加载测试结果
const loadResultsFromStorage = (): { const loadResultsFromStorage = (): {
items: UnlockItem[] | null; items: UnlockItem[] | null;
time: string | null; time: string | null;
@@ -88,24 +81,17 @@ const UnlockPage = () => {
return { items: null, time: null }; return { items: null, time: null };
}; };
// 页面加载时获取初始检测项列表
useEffect(() => { useEffect(() => {
// 尝试从本地存储加载上次测试结果
const { items: storedItems } = loadResultsFromStorage(); const { items: storedItems } = loadResultsFromStorage();
if (storedItems && storedItems.length > 0) { if (storedItems && storedItems.length > 0) {
// 如果有存储的结果,优先使用
setUnlockItems(storedItems); setUnlockItems(storedItems);
// 后台同时获取最新的初始状态但不更新UI
getUnlockItems(false); getUnlockItems(false);
} else { } else {
// 没有存储的结果,获取初始状态
getUnlockItems(true); getUnlockItems(true);
} }
}, []); }, []);
// 获取所有解锁检测项列表
const getUnlockItems = async (updateUI: boolean = true) => { const getUnlockItems = async (updateUI: boolean = true) => {
try { try {
const items = await invoke<UnlockItem[]>("get_unlock_items"); const items = await invoke<UnlockItem[]>("get_unlock_items");
@@ -119,7 +105,6 @@ const UnlockPage = () => {
} }
}; };
// invoke加超时防止后端卡死
const invokeWithTimeout = async <T,>( const invokeWithTimeout = async <T,>(
cmd: string, cmd: string,
args?: any, args?: any,
@@ -128,7 +113,10 @@ const UnlockPage = () => {
return Promise.race([ return Promise.race([
invoke<T>(cmd, args), invoke<T>(cmd, args),
new Promise<T>((_, reject) => new Promise<T>((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), timeout), setTimeout(
() => reject(new Error(t("Detection timeout or failed"))),
timeout,
),
), ),
]); ]);
}; };
@@ -149,8 +137,10 @@ const UnlockPage = () => {
setIsCheckingAll(false); setIsCheckingAll(false);
} catch (err: any) { } catch (err: any) {
setIsCheckingAll(false); setIsCheckingAll(false);
showNotice("error", err?.message || err?.toString() || "检测超时或失败"); showNotice(
alert("检测超时或失败: " + (err?.message || err)); "error",
err?.message || err?.toString() || t("Detection timeout or failed"),
);
console.error("Failed to check media unlock:", err); console.error("Failed to check media unlock:", err);
} }
}); });
@@ -180,13 +170,17 @@ const UnlockPage = () => {
setLoadingItems((prev) => prev.filter((item) => item !== name)); setLoadingItems((prev) => prev.filter((item) => item !== name));
} catch (err: any) { } catch (err: any) {
setLoadingItems((prev) => prev.filter((item) => item !== name)); setLoadingItems((prev) => prev.filter((item) => item !== name));
showNotice("error", err?.message || err?.toString() || `检测${name}失败`); showNotice(
alert("检测超时或失败: " + (err?.message || err)); "error",
err?.message ||
err?.toString() ||
t("Detection failed for {name}").replace("{name}", name),
);
console.error(`Failed to check ${name}:`, err); console.error(`Failed to check ${name}:`, err);
} }
}); });
// 获取状态对应的颜色 // 状态颜色
const getStatusColor = (status: string) => { const getStatusColor = (status: string) => {
if (status === "Pending") return "default"; if (status === "Pending") return "default";
if (status === "Yes") return "success"; if (status === "Yes") return "success";
@@ -204,7 +198,7 @@ const UnlockPage = () => {
return "default"; return "default";
}; };
// 获取状态对应的图标 // 状态图标
const getStatusIcon = (status: string) => { const getStatusIcon = (status: string) => {
if (status === "Pending") return <PendingOutlined />; if (status === "Pending") return <PendingOutlined />;
if (status === "Yes") return <CheckCircleOutlined />; if (status === "Yes") return <CheckCircleOutlined />;
@@ -214,7 +208,7 @@ const UnlockPage = () => {
return <HelpOutline />; return <HelpOutline />;
}; };
// 获取状态对应的边框色 // 边框色
const getStatusBorderColor = (status: string) => { const getStatusBorderColor = (status: string) => {
if (status === "Yes") return theme.palette.success.main; if (status === "Yes") return theme.palette.success.main;
if (status === "No") return theme.palette.error.main; if (status === "No") return theme.palette.error.main;
@@ -263,7 +257,7 @@ const UnlockPage = () => {
) : ( ) : (
<Grid container spacing={1.5} columns={{ xs: 1, sm: 2, md: 3 }}> <Grid container spacing={1.5} columns={{ xs: 1, sm: 2, md: 3 }}>
{unlockItems.map((item) => ( {unlockItems.map((item) => (
<Grid size={1}> <Grid size={1} key={item.name}>
<Card <Card
variant="outlined" variant="outlined"
sx={{ sx={{
@@ -313,16 +307,21 @@ const UnlockPage = () => {
minWidth: "32px", minWidth: "32px",
width: "32px", width: "32px",
height: "32px", height: "32px",
//p: 0,
borderRadius: "50%", borderRadius: "50%",
}} }}
onClick={() => checkSingleMedia(item.name)} onClick={() => checkSingleMedia(item.name)}
> >
{loadingItems.includes(item.name) ? ( <RefreshRounded
<CircularProgress size={16} /> sx={{
) : ( animation: loadingItems.includes(item.name)
<RefreshRounded fontSize="small" /> ? "spin 1s linear infinite"
)} : "none",
"@keyframes spin": {
"0%": { transform: "rotate(0deg)" },
"100%": { transform: "rotate(360deg)" },
},
}}
/>
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>