mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
perf: remove system-level unlock test timeout notice
This commit is contained in:
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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": "检测超时或失败"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user