feat: proxy group is always placed at the forefront when sorting proxies (#458)

This commit is contained in:
wzdnzd 2023-12-01 19:16:42 +08:00 committed by GitHub
parent 89ad396bc2
commit a0f80aa62d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 5 deletions

View File

@ -38,12 +38,17 @@ export const sortProxiesByOrderingType = (
proxyNames: string[],
proxyLatencyMap: Record<string, number>,
orderingType: PROXIES_ORDERING_TYPE,
proxyGroupNames: Set<string> | undefined,
) => {
if (orderingType === PROXIES_ORDERING_TYPE.NATURAL) {
return proxyNames
}
return proxyNames.sort((a, b) => {
if (proxyGroupNames?.has(a) && !proxyGroupNames?.has(b)) return -1
if (proxyGroupNames?.has(b) && !proxyGroupNames?.has(a)) return 1
const prevLatency = proxyLatencyMap[a]
const nextLatency = proxyLatencyMap[b]
@ -77,10 +82,13 @@ export const sortProxiesByOrderingType = (
export const filterProxiesByAvailability = (
proxyNames: string[],
proxyLatencyMap: Record<string, number>,
excludes: Set<string>,
enabled?: boolean,
) =>
enabled
? proxyNames.filter(
(name) => proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED,
? proxyNames.filter((name) =>
excludes?.has(name)
? true
: proxyLatencyMap[name] !== latencyQualityMap().NOT_CONNECTED,
)
: proxyNames

View File

@ -41,6 +41,7 @@ export default () => {
proxies,
selectProxyInGroup,
latencyMap,
proxyGroupNames,
proxyProviders,
updateProviderByProviderName,
updateAllProvider,
@ -157,8 +158,10 @@ export default () => {
proxyGroup.all ?? [],
latencyMap(),
proxiesOrderingType(),
proxyGroupNames(),
),
latencyMap(),
proxyGroupNames(),
hideUnAvailableProxies(),
),
)
@ -244,6 +247,7 @@ export default () => {
proxyProvider.proxies.map((i) => i.name) ?? [],
latencyMap(),
proxiesOrderingType(),
undefined,
),
)

View File

@ -52,6 +52,9 @@ const [isAllProviderUpdating, setIsAllProviderUpdating] = createSignal(false)
// these signals should be global state
const [proxies, setProxies] = createSignal<ProxyWithProvider[]>([])
const [proxyGroupNames, setProxyGroupNames] = createSignal<Set<string>>(
new Set(),
)
const [proxyProviders, setProxyProviders] = createSignal<
(ProxyProvider & { proxies: ProxyNodeWithProvider[] })[]
>([])
@ -89,19 +92,46 @@ const setProxiesInfo = (
return proxy.history?.at(-1)?.delay
}
const dependedLatencyProxies = {} as Record<string, Set<string>>
proxies.forEach((proxy) => {
const { udp, xudp, type, now, name, provider = '' } = proxy
newProxyNodeMap[proxy.name] = { udp, xudp, type, now, name, provider }
const latency =
lastDelay(proxy, urlForLatencyTest()) || latencyQualityMap().NOT_CONNECTED
newLatencyMap[proxy.name] = latency
// to solve the problem of the ProxyGroup cannot obtain the latency of the currently used proxy node
// it seems that only clash.core and clash.preminu have issues
if (!now) {
newLatencyMap[proxy.name] =
lastDelay(proxy, urlForLatencyTest()) ||
latencyQualityMap().NOT_CONNECTED
} else if (newLatencyMap[now] !== undefined) {
newLatencyMap[proxy.name] = newLatencyMap[now]
} else {
const dependencies = dependedLatencyProxies[now] ?? new Set()
dependencies.add(proxy.name)
dependedLatencyProxies[now] = dependencies
}
const proxyIPv6Support =
(lastDelay(proxy, urlForIPv6SupportTest(), false) ?? 0) > 0
newProxyIPv6SupportMap[proxy.name] = proxyIPv6Support
})
const independencies = Object.keys(dependedLatencyProxies).filter(
(now) => newLatencyMap[now] !== undefined,
)
// maybe we should use Union-Find to implement this
while (independencies.length > 0) {
const now = independencies.shift()!
const delay = newLatencyMap[now]!
for (const name of dependedLatencyProxies[now]?.values() ?? []) {
newLatencyMap[name] = delay
independencies.push(name)
}
}
batch(() => {
setProxyNodeMap(newProxyNodeMap)
setLatencyMap(newLatencyMap)
@ -142,6 +172,9 @@ export const useProxies = () => {
batch(() => {
setProxies(sortedProxies)
setProxyGroupNames(
new Set(['DIRECT', 'REJECT', ...sortedProxies.map((p) => p.name)]),
)
setProxyProviders(sortedProviders)
setProxiesInfo(allProxies)
})
@ -293,6 +326,7 @@ export const useProxies = () => {
updatingMap,
isAllProviderUpdating,
proxies,
proxyGroupNames,
proxyProviders,
proxyLatencyTest,
proxyGroupLatencyTest,