feat(proxy-groups, current-proxy-card): auto-refresh delay sorting

- proxy-groups: recalculate active group head and reapply delay sort after tests so list reorders automatically when "按延迟排序" is active.
- current-proxy-card: add delaySortRefresh trigger after auto/manual latency checks to immediately refresh selector and proxy list ordering.
- current-proxy-card: listen for delaySortRefresh to keep displayed delay chips and option ordering aligned with latest measurements.
This commit is contained in:
Slinetrac
2025-10-14 20:13:04 +08:00
parent 7c71d07ad2
commit 2e3174baa7
3 changed files with 60 additions and 40 deletions

View File

@@ -124,6 +124,7 @@ export const CurrentProxyCard = () => {
const savedSortType = localStorage.getItem(STORAGE_KEY_SORT_TYPE);
return savedSortType ? (Number(savedSortType) as ProxySortType) : 0;
});
const [delaySortRefresh, setDelaySortRefresh] = useState(0);
// 定义状态类型
type ProxyState = {
@@ -443,12 +444,17 @@ export const CurrentProxyCard = () => {
} finally {
autoCheckInProgressRef.current = false;
refreshProxy();
if (sortType === 1) {
setDelaySortRefresh((prev) => prev + 1);
}
}
}, [
isDirectMode,
refreshProxy,
state.selection.group,
state.selection.proxy,
sortType,
setDelaySortRefresh,
]);
useEffect(() => {
@@ -487,28 +493,25 @@ export const CurrentProxyCard = () => {
]);
// 自定义渲染选择框中的值
const renderProxyValue = useCallback(
(selected: string) => {
if (!selected || !state.proxyData.records[selected]) return selected;
const renderProxyValue = (selected: string) => {
if (!selected || !state.proxyData.records[selected]) return selected;
const delayValue = delayManager.getDelayFix(
state.proxyData.records[selected],
state.selection.group,
);
const delayValue = delayManager.getDelayFix(
state.proxyData.records[selected],
state.selection.group,
);
return (
<Box sx={{ display: "flex", justifyContent: "space-between" }}>
<Typography noWrap>{selected}</Typography>
<Chip
size="small"
label={delayManager.formatDelay(delayValue)}
color={convertDelayColor(delayValue)}
/>
</Box>
);
},
[state.proxyData.records, state.selection.group],
);
return (
<Box sx={{ display: "flex", justifyContent: "space-between" }}>
<Typography noWrap>{selected}</Typography>
<Chip
size="small"
label={delayManager.formatDelay(delayValue)}
color={convertDelayColor(delayValue)}
/>
</Box>
);
};
// 排序类型变更
const handleSortTypeChange = useCallback(() => {
@@ -594,24 +597,28 @@ export const CurrentProxyCard = () => {
}
refreshProxy();
if (sortType === 1) {
setDelaySortRefresh((prev) => prev + 1);
}
});
// 排序代理函数(增加非空校验)
const sortProxies = useCallback(
(proxies: ProxyOption[]) => {
if (!proxies || sortType === 0) return proxies;
// 计算要显示的代理选项(增加非空校验)
const proxyOptions = useMemo(() => {
const sortWithLatency = (proxiesToSort: ProxyOption[]) => {
if (!proxiesToSort || sortType === 0) return proxiesToSort;
// 确保数据存在
if (!state.proxyData.records || !state.selection.group) return proxies;
if (!state.proxyData.records || !state.selection.group) {
return proxiesToSort;
}
const list = [...proxies];
const list = [...proxiesToSort];
if (sortType === 1) {
const refreshTick = delaySortRefresh;
list.sort((a, b) => {
const recordA = state.proxyData.records[a.name];
const recordB = state.proxyData.records[b.name];
// 处理 record 不存在的情况
if (!recordA) return 1;
if (!recordB) return -1;
@@ -621,19 +628,16 @@ export const CurrentProxyCard = () => {
if (ad === -1 || ad === -2) return 1;
if (bd === -1 || bd === -2) return -1;
return ad - bd;
if (ad !== bd) return ad - bd;
return refreshTick >= 0 ? a.name.localeCompare(b.name) : 0;
});
} else {
list.sort((a, b) => a.name.localeCompare(b.name));
}
return list;
},
[sortType, state.proxyData.records, state.selection.group],
);
};
// 计算要显示的代理选项(增加非空校验)
const proxyOptions = useMemo(() => {
if (isDirectMode) {
return [{ name: "DIRECT" }];
}
@@ -647,7 +651,7 @@ export const CurrentProxyCard = () => {
name: typeof p === "string" ? p : p.name,
}));
return sortProxies(options);
return sortWithLatency(options);
}
// 规则模式
@@ -657,7 +661,7 @@ export const CurrentProxyCard = () => {
if (group) {
const options = group.all.map((name) => ({ name }));
return sortProxies(options);
return sortWithLatency(options);
}
return [];
@@ -667,7 +671,8 @@ export const CurrentProxyCard = () => {
proxies,
state.proxyData,
state.selection.group,
sortProxies,
sortType,
delaySortRefresh,
]);
// 获取排序图标