fix: correct address display error caused by async system proxy retrieval

This commit is contained in:
wonfen
2025-06-22 23:19:11 +08:00
parent bdfc383a18
commit fee08f3826
3 changed files with 113 additions and 31 deletions

View File

@@ -17,7 +17,7 @@ const formatUptime = (uptimeMs: number) => {
export const ClashInfoCard = () => { export const ClashInfoCard = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { version: clashVersion } = useClash(); const { version: clashVersion } = useClash();
const { clashConfig, sysproxy, rules, uptime } = useAppData(); const { clashConfig, rules, uptime, systemProxyAddress } = useAppData();
// 使用useMemo缓存格式化后的uptime避免频繁计算 // 使用useMemo缓存格式化后的uptime避免频繁计算
const formattedUptime = useMemo(() => formatUptime(uptime), [uptime]); const formattedUptime = useMemo(() => formatUptime(uptime), [uptime]);
@@ -42,7 +42,7 @@ export const ClashInfoCard = () => {
{t("System Proxy Address")} {t("System Proxy Address")}
</Typography> </Typography>
<Typography variant="body2" fontWeight="medium"> <Typography variant="body2" fontWeight="medium">
{sysproxy?.server || "-"} {systemProxyAddress}
</Typography> </Typography>
</Stack> </Stack>
<Divider /> <Divider />
@@ -74,7 +74,14 @@ export const ClashInfoCard = () => {
</Stack> </Stack>
</Stack> </Stack>
); );
}, [clashConfig, clashVersion, t, formattedUptime, rules.length, sysproxy]); }, [
clashConfig,
clashVersion,
t,
formattedUptime,
rules.length,
systemProxyAddress,
]);
return ( return (
<EnhancedCard <EnhancedCard

View File

@@ -3,6 +3,7 @@ import { BaseFieldset } from "@/components/base/base-fieldset";
import { TooltipIcon } from "@/components/base/base-tooltip-icon"; import { TooltipIcon } from "@/components/base/base-tooltip-icon";
import { EditorViewer } from "@/components/profile/editor-viewer"; import { EditorViewer } from "@/components/profile/editor-viewer";
import { useVerge } from "@/hooks/use-verge"; import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-provider";
import { getClashConfig } from "@/services/api"; import { getClashConfig } from "@/services/api";
import { import {
getAutotemProxy, getAutotemProxy,
@@ -172,6 +173,35 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
} }
}; };
const { systemProxyAddress } = useAppData();
// 为当前状态计算系统代理地址
const getSystemProxyAddress = useMemo(() => {
if (!clashConfig) return "-";
const isPacMode = value.pac ?? false;
if (isPacMode) {
const host = value.proxy_host || "127.0.0.1";
const port = verge?.verge_mixed_port || clashConfig["mixed-port"] || 7897;
return `${host}:${port}`;
} else {
return systemProxyAddress;
}
}, [
value.pac,
value.proxy_host,
verge?.verge_mixed_port,
clashConfig,
systemProxyAddress,
]);
const getCurrentPacUrl = useMemo(() => {
const host = value.proxy_host || "127.0.0.1";
// 根据环境判断PAC端口
const port = import.meta.env.DEV ? 11233 : 33331;
return `http://${host}:${port}/commands/pac`;
}, [value.proxy_host]);
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
open: () => { open: () => {
setOpen(true); setOpen(true);
@@ -417,7 +447,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
<FlexBox> <FlexBox>
<Typography className="label">{t("Server Addr")}</Typography> <Typography className="label">{t("Server Addr")}</Typography>
<Typography className="value"> <Typography className="value">
{sysproxy?.server ? sysproxy.server : t("Not available")} {getSystemProxyAddress}
</Typography> </Typography>
</FlexBox> </FlexBox>
</> </>
@@ -425,7 +455,9 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{value.pac && ( {value.pac && (
<FlexBox> <FlexBox>
<Typography className="label">{t("PAC URL")}</Typography> <Typography className="label">{t("PAC URL")}</Typography>
<Typography className="value">{autoproxy?.url || "-"}</Typography> <Typography className="value">
{getCurrentPacUrl || "-"}
</Typography>
</FlexBox> </FlexBox>
)} )}
</BaseFieldset> </BaseFieldset>

View File

@@ -1,5 +1,12 @@
import { createContext, useContext, useMemo, useEffect } from "react"; import React, {
import useSWR from "swr"; createContext,
useContext,
useEffect,
useMemo,
useState,
} from "react";
import { useVerge } from "@/hooks/use-verge";
import useSWR, { mutate } from "swr";
import useSWRSubscription from "swr/subscription"; import useSWRSubscription from "swr/subscription";
import { import {
getProxies, getProxies,
@@ -37,6 +44,8 @@ interface AppDataContextType {
}; };
traffic: { up: number; down: number }; traffic: { up: number; down: number };
memory: { inuse: number }; memory: { inuse: number };
systemProxyAddress: string;
refreshProxy: () => Promise<any>; refreshProxy: () => Promise<any>;
refreshClashConfig: () => Promise<any>; refreshClashConfig: () => Promise<any>;
refreshRules: () => Promise<any>; refreshRules: () => Promise<any>;
@@ -55,8 +64,9 @@ export const AppDataProvider = ({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) => { }) => {
const { clashInfo } = useClashInfo();
const pageVisible = useVisibility(); const pageVisible = useVisibility();
const { clashInfo } = useClashInfo();
const { verge } = useVerge();
// 基础数据 - 中频率更新 (5秒) // 基础数据 - 中频率更新 (5秒)
const { data: proxiesData, mutate: refreshProxy } = useSWR( const { data: proxiesData, mutate: refreshProxy } = useSWR(
@@ -508,8 +518,39 @@ export const AppDataProvider = ({
}; };
// 聚合所有数据 // 聚合所有数据
const value = useMemo( const value = useMemo(() => {
() => ({ // 计算系统代理地址
const calculateSystemProxyAddress = () => {
if (!verge || !clashConfig) return "-";
const isPacMode = verge.proxy_auto_config ?? false;
if (isPacMode) {
// PAC模式显示我们期望设置的代理地址
const proxyHost = verge.proxy_host || "127.0.0.1";
const proxyPort =
verge.verge_mixed_port || clashConfig["mixed-port"] || 7897;
return `${proxyHost}:${proxyPort}`;
} else {
// HTTP代理模式优先使用系统地址但如果格式不正确则使用期望地址
const systemServer = sysproxy?.server;
if (
systemServer &&
systemServer !== "-" &&
!systemServer.startsWith(":")
) {
return systemServer;
} else {
// 系统地址无效,返回期望的代理地址
const proxyHost = verge.proxy_host || "127.0.0.1";
const proxyPort =
verge.verge_mixed_port || clashConfig["mixed-port"] || 7897;
return `${proxyHost}:${proxyPort}`;
}
}
};
return {
// 数据 // 数据
proxies: proxiesData, proxies: proxiesData,
clashConfig, clashConfig,
@@ -534,6 +575,8 @@ export const AppDataProvider = ({
traffic: trafficData, traffic: trafficData,
memory: memoryData, memory: memoryData,
systemProxyAddress: calculateSystemProxyAddress(),
// 刷新方法 // 刷新方法
refreshProxy, refreshProxy,
refreshClashConfig, refreshClashConfig,
@@ -542,27 +585,27 @@ export const AppDataProvider = ({
refreshProxyProviders, refreshProxyProviders,
refreshRuleProviders, refreshRuleProviders,
refreshAll, refreshAll,
}), };
[ }, [
proxiesData, proxiesData,
clashConfig, clashConfig,
rulesData, rulesData,
sysproxy, sysproxy,
runningMode, runningMode,
uptimeData, uptimeData,
connectionsData, connectionsData,
trafficData, trafficData,
memoryData, memoryData,
proxyProviders, proxyProviders,
ruleProviders, ruleProviders,
refreshProxy, verge,
refreshClashConfig, refreshProxy,
refreshRules, refreshClashConfig,
refreshSysproxy, refreshRules,
refreshProxyProviders, refreshSysproxy,
refreshRuleProviders, refreshProxyProviders,
], refreshRuleProviders,
); ]);
return ( return (
<AppDataContext.Provider value={value}>{children}</AppDataContext.Provider> <AppDataContext.Provider value={value}>{children}</AppDataContext.Provider>