revert: use-app-data (#6088)

* Revert "refactor(app-data): split monolithic context into focused SWR hooks (#5576)"

This reverts commit 8e8182f707.

# Conflicts:
#	src/components/home/clash-info-card.tsx
#	src/components/home/clash-mode-card.tsx
#	src/components/home/current-proxy-card.tsx
#	src/components/home/home-profile-card.tsx
#	src/components/proxy/provider-button.tsx
#	src/components/proxy/proxy-chain.tsx
#	src/components/proxy/proxy-groups.tsx
#	src/components/proxy/use-render-list.ts
#	src/components/rule/provider-button.tsx
#	src/components/setting/mods/sysproxy-viewer.tsx
#	src/hooks/use-clash-data.ts
#	src/hooks/use-current-proxy.ts
#	src/hooks/use-shared-swr-poller.ts
#	src/hooks/use-system-proxy-state.ts
#	src/pages/rules.tsx

* docs: Changelog.md
This commit is contained in:
Sline
2026-01-16 18:32:31 +08:00
committed by GitHub
parent a5f494bda2
commit fd98caccd2
19 changed files with 361 additions and 448 deletions
+2 -15
View File
@@ -4,13 +4,7 @@ import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useClash } from "@/hooks/use-clash";
import {
useAppUptime,
useClashConfig,
useRulesData,
useSystemProxyAddress,
useSystemProxyData,
} from "@/hooks/use-clash-data";
import { useAppData } from "@/providers/app-data-context";
import { EnhancedCard } from "./enhanced-card";
@@ -25,14 +19,7 @@ const formatUptime = (uptimeMs: number) => {
export const ClashInfoCard = () => {
const { t } = useTranslation();
const { version: clashVersion } = useClash();
const { clashConfig } = useClashConfig();
const { sysproxy } = useSystemProxyData();
const { rules } = useRulesData();
const { uptime } = useAppUptime();
const systemProxyAddress = useSystemProxyAddress({
clashConfig,
sysproxy,
});
const { clashConfig, rules, uptime, systemProxyAddress } = useAppData();
// 使用useMemo缓存格式化后的uptime,避免频繁计算
const formattedUptime = useMemo(() => formatUptime(uptime), [uptime]);
+2 -2
View File
@@ -9,8 +9,8 @@ import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { closeAllConnections } from "tauri-plugin-mihomo-api";
import { useClashConfig } from "@/hooks/use-clash-data";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import { patchClashMode } from "@/services/cmds";
import type { TranslationKey } from "@/types/generated/i18n-keys";
@@ -41,7 +41,7 @@ const MODE_META: Record<
export const ClashModeCard = () => {
const { t } = useTranslation();
const { verge } = useVerge();
const { clashConfig, refreshClashConfig } = useClashConfig();
const { clashConfig, refreshClashConfig } = useAppData();
// 支持的模式列表
const modeList = CLASH_MODES;
+2 -8
View File
@@ -34,14 +34,10 @@ import { useNavigate } from "react-router";
import { delayGroup, healthcheckProxyProvider } from "tauri-plugin-mihomo-api";
import { EnhancedCard } from "@/components/home/enhanced-card";
import {
useClashConfig,
useProxiesData,
useRulesData,
} from "@/hooks/use-clash-data";
import { useProfiles } from "@/hooks/use-profiles";
import { useProxySelection } from "@/hooks/use-proxy-selection";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import delayManager from "@/services/delay";
import { debugLog } from "@/utils/debug";
@@ -105,9 +101,7 @@ export const CurrentProxyCard = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const theme = useTheme();
const { proxies, refreshProxy } = useProxiesData();
const { clashConfig } = useClashConfig();
const { rules } = useRulesData();
const { proxies, clashConfig, refreshProxy, rules } = useAppData();
const { verge } = useVerge();
const { current: currentProfile } = useProfiles();
const autoDelayEnabled = verge?.enable_auto_delay_detection ?? false;
+2 -2
View File
@@ -24,7 +24,7 @@ import { useCallback, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router";
import { useRefreshAll } from "@/hooks/use-clash-data";
import { useAppData } from "@/providers/app-data-context";
import { openWebUrl, updateProfile } from "@/services/cmds";
import { showNotice } from "@/services/notice-service";
import parseTraffic from "@/utils/parse-traffic";
@@ -281,7 +281,7 @@ export const HomeProfileCard = ({
}: HomeProfileCardProps) => {
const { t } = useTranslation();
const navigate = useNavigate();
const refreshAll = useRefreshAll();
const { refreshAll } = useAppData();
// 更新当前订阅
const [updating, setUpdating] = useState(false);
+4 -5
View File
@@ -22,7 +22,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { updateProxyProvider } from "tauri-plugin-mihomo-api";
import { useProxiesData, useProxyProvidersData } from "@/hooks/use-clash-data";
import { useAppData } from "@/providers/app-data-context";
import { showNotice } from "@/services/notice-service";
import parseTraffic from "@/utils/parse-traffic";
@@ -48,8 +48,7 @@ const parseExpire = (expire?: number) => {
export const ProviderButton = () => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const { proxyProviders, refreshProxyProviders } = useProxyProvidersData();
const { refreshProxy } = useProxiesData();
const { proxyProviders, refreshProxy, refreshProxyProviders } = useAppData();
const [updating, setUpdating] = useState<Record<string, boolean>>({});
// 检查是否有提供者
@@ -176,8 +175,8 @@ export const ProviderButton = () => {
<List sx={{ py: 0, minHeight: 250 }}>
{Object.entries(proxyProviders || {})
.sort()
.map(([key, provider]) => {
if (!provider) return null;
.map(([key, item]) => {
const provider = item;
const time = dayjs(provider.updatedAt);
const isUpdating = updating[key];
+3 -3
View File
@@ -38,7 +38,7 @@ import {
selectNodeForGroup,
} from "tauri-plugin-mihomo-api";
import { useProxiesData } from "@/hooks/use-clash-data";
import { useAppData } from "@/providers/app-data-context";
import { updateProxyChainConfigInRuntime } from "@/services/cmds";
import { debugLog } from "@/utils/debug";
@@ -199,7 +199,7 @@ export const ProxyChain = ({
}: ProxyChainProps) => {
const theme = useTheme();
const { t } = useTranslation();
const { proxies, refreshProxy } = useProxiesData();
const { proxies, refreshProxy } = useAppData();
const [isConnecting, setIsConnecting] = useState(false);
const markUnsavedChanges = useCallback(() => {
onMarkUnsavedChanges?.();
@@ -221,7 +221,7 @@ export const ProxyChain = ({
}
const proxyChainGroup = proxies.groups.find(
(group) => group.name === selectedGroup,
(group: { name: string }) => group.name === selectedGroup,
);
return proxyChainGroup?.now === lastNode.name;
+2 -2
View File
@@ -16,9 +16,9 @@ import { Virtuoso, type VirtuosoHandle } from "react-virtuoso";
import { delayGroup, healthcheckProxyProvider } from "tauri-plugin-mihomo-api";
import { BaseEmpty } from "@/components/base";
import { useProxiesData } from "@/hooks/use-clash-data";
import { useProxySelection } from "@/hooks/use-proxy-selection";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import { updateProxyChainConfigInRuntime } from "@/services/cmds";
import delayManager from "@/services/delay";
import { debugLog } from "@/utils/debug";
@@ -80,7 +80,7 @@ export const ProxyGroups = (props: Props) => {
}>({ open: false, message: "" });
const { verge } = useVerge();
const { proxies: proxiesData } = useProxiesData();
const { proxies: proxiesData } = useAppData();
const groups = proxiesData?.groups;
const availableGroups = useMemo(() => {
if (!groups) return [];
+20 -4
View File
@@ -1,8 +1,8 @@
import { useEffect, useMemo } from "react";
import useSWR from "swr";
import { useProxiesData } from "@/hooks/use-clash-data";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import { getRuntimeConfig } from "@/services/cmds";
import delayManager from "@/services/delay";
import { debugLog } from "@/utils/debug";
@@ -34,8 +34,24 @@ interface IProxyItem {
}
// 代理组类型
type ProxyGroup = IProxyGroupItem & {
now?: string;
type ProxyGroup = {
name: string;
type: string;
udp: boolean;
xudp: boolean;
tfo: boolean;
mptcp: boolean;
smux: boolean;
history: {
time: string;
delay: number;
}[];
now: string;
all: IProxyItem[];
hidden?: boolean;
icon?: string;
testUrl?: string;
provider?: string;
};
export interface IRenderItem {
@@ -84,7 +100,7 @@ export const useRenderList = (
selectedGroup?: string | null,
) => {
// 使用全局数据提供者
const { proxies: proxiesData, refreshProxy } = useProxiesData();
const { proxies: proxiesData, refreshProxy } = useAppData();
const { verge } = useVerge();
const { width } = useWindowWidth();
const [headStates, setHeadState] = useHeadStateNew();
+5 -20
View File
@@ -21,10 +21,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { updateRuleProvider } from "tauri-plugin-mihomo-api";
import type {
useRuleProvidersData,
useRulesData,
} from "@/hooks/use-clash-data";
import { useAppData } from "@/providers/app-data-context";
import { showNotice } from "@/services/notice-service";
// 辅助组件 - 类型框
@@ -40,22 +37,10 @@ const TypeBox = styled(Box)<{ component?: React.ElementType }>(({ theme }) => ({
lineHeight: 1.25,
}));
type RuleProvidersHook = ReturnType<typeof useRuleProvidersData>;
type RulesHook = ReturnType<typeof useRulesData>;
interface ProviderButtonProps {
ruleProviders: RuleProvidersHook["ruleProviders"];
refreshRuleProviders: RuleProvidersHook["refreshRuleProviders"];
refreshRules: RulesHook["refreshRules"];
}
export const ProviderButton = ({
ruleProviders,
refreshRuleProviders,
refreshRules,
}: ProviderButtonProps) => {
export const ProviderButton = () => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const { ruleProviders, refreshRules, refreshRuleProviders } = useAppData();
const [updating, setUpdating] = useState<Record<string, boolean>>({});
// 检查是否有提供者
@@ -178,8 +163,8 @@ export const ProviderButton = ({
<List sx={{ py: 0, minHeight: 250 }}>
{Object.entries(ruleProviders || {})
.sort()
.map(([key, provider]) => {
if (!provider) return null;
.map(([key, item]) => {
const provider = item;
const time = dayjs(provider.updatedAt);
const isUpdating = updating[key];
+14 -13
View File
@@ -22,7 +22,8 @@ import {
useState,
} from "react";
import { useTranslation } from "react-i18next";
import { mutate } from "swr";
import useSWR, { mutate } from "swr";
import { getBaseConfig } from "tauri-plugin-mihomo-api";
import {
BaseDialog,
@@ -33,12 +34,8 @@ import {
TooltipIcon,
} from "@/components/base";
import { EditorViewer } from "@/components/profile/editor-viewer";
import {
useClashConfig,
useSystemProxyAddress,
useSystemProxyData,
} from "@/hooks/use-clash-data";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import {
getAutotemProxy,
getNetworkInterfacesInfo,
@@ -110,6 +107,9 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
const { verge, patchVerge, mutateVerge } = useVerge();
const [hostOptions, setHostOptions] = useState<string[]>([]);
type SysProxy = Awaited<ReturnType<typeof getSystemProxy>>;
const [sysproxy, setSysproxy] = useState<SysProxy>();
type AutoProxy = Awaited<ReturnType<typeof getAutotemProxy>>;
const [autoproxy, setAutoproxy] = useState<AutoProxy>();
@@ -148,8 +148,12 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
return "127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,localhost,*.local,*.crashlytics.com,<local>";
};
const { clashConfig } = useClashConfig();
const { sysproxy, refreshSysproxy } = useSystemProxyData();
const { data: clashConfig } = useSWR("getClashConfig", getBaseConfig, {
revalidateOnFocus: false,
revalidateIfStale: true,
dedupingInterval: 1000,
errorRetryInterval: 5000,
});
const prevMixedPortRef = useRef(clashConfig?.mixedPort);
@@ -183,10 +187,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
updateProxy();
}, [clashConfig?.mixedPort, value.pac]);
const systemProxyAddress = useSystemProxyAddress({
clashConfig,
sysproxy,
});
const { systemProxyAddress } = useAppData();
// 为当前状态计算系统代理地址
const getSystemProxyAddress = useMemo(() => {
@@ -236,7 +237,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
pac_content: pac_file_content ?? DEFAULT_PAC,
proxy_host: proxy_host ?? "127.0.0.1",
});
void refreshSysproxy();
getSystemProxy().then((p) => setSysproxy(p));
getAutotemProxy().then((p) => setAutoproxy(p));
fetchNetworkInterfaces();
},