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

* refactor(app-data): split monolithic context into focused SWR hooks

* refactor(swr): unify polling and consolidate proxy/config/provider data flow
This commit is contained in:
Sline
2025-11-24 16:18:31 +08:00
committed by GitHub
parent 871881c460
commit 8e8182f707
17 changed files with 432 additions and 295 deletions
+5 -4
View File
@@ -22,7 +22,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next";
import { updateProxyProvider } from "tauri-plugin-mihomo-api";
import { useAppData } from "@/providers/app-data-context";
import { useProxiesData, useProxyProvidersData } from "@/hooks/app-data";
import { showNotice } from "@/services/noticeService";
import parseTraffic from "@/utils/parse-traffic";
@@ -48,7 +48,8 @@ const parseExpire = (expire?: number) => {
export const ProviderButton = () => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const { proxyProviders, refreshProxy, refreshProxyProviders } = useAppData();
const { proxyProviders, refreshProxyProviders } = useProxyProvidersData();
const { refreshProxy } = useProxiesData();
const [updating, setUpdating] = useState<Record<string, boolean>>({});
// 检查是否有提供者
@@ -175,8 +176,8 @@ export const ProviderButton = () => {
<List sx={{ py: 0, minHeight: 250 }}>
{Object.entries(proxyProviders || {})
.sort()
.map(([key, item]) => {
const provider = item;
.map(([key, provider]) => {
if (!provider) return null;
const time = dayjs(provider.updatedAt);
const isUpdating = updating[key];
+2 -2
View File
@@ -39,7 +39,7 @@ import {
selectNodeForGroup,
} from "tauri-plugin-mihomo-api";
import { useAppData } from "@/providers/app-data-context";
import { useProxiesData } from "@/hooks/app-data";
import { calcuProxies, updateProxyChainConfigInRuntime } from "@/services/cmds";
interface ProxyChainItem {
@@ -199,7 +199,7 @@ export const ProxyChain = ({
}: ProxyChainProps) => {
const theme = useTheme();
const { t } = useTranslation();
const { proxies } = useAppData();
const { proxies } = useProxiesData();
const [isConnecting, setIsConnecting] = useState(false);
const markUnsavedChanges = useCallback(() => {
onMarkUnsavedChanges?.();
+2 -2
View File
@@ -15,9 +15,9 @@ import { useTranslation } from "react-i18next";
import { Virtuoso, type VirtuosoHandle } from "react-virtuoso";
import { delayGroup, healthcheckProxyProvider } from "tauri-plugin-mihomo-api";
import { useProxiesData } from "@/hooks/app-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";
@@ -61,7 +61,7 @@ export const ProxyGroups = (props: Props) => {
}>({ open: false, message: "" });
const { verge } = useVerge();
const { proxies: proxiesData } = useAppData();
const { proxies: proxiesData } = useProxiesData();
const groups = proxiesData?.groups;
const availableGroups = useMemo(() => groups ?? [], [groups]);
+4 -20
View File
@@ -1,8 +1,8 @@
import { useEffect, useMemo } from "react";
import useSWR from "swr";
import { useProxiesData } from "@/hooks/app-data";
import { useVerge } from "@/hooks/use-verge";
import { useAppData } from "@/providers/app-data-context";
import { getRuntimeConfig } from "@/services/cmds";
import delayManager from "@/services/delay";
@@ -33,24 +33,8 @@ interface IProxyItem {
}
// 代理组类型
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;
type ProxyGroup = IProxyGroupItem & {
now?: string;
};
export interface IRenderItem {
@@ -99,7 +83,7 @@ export const useRenderList = (
selectedGroup?: string | null,
) => {
// 使用全局数据提供者
const { proxies: proxiesData, refreshProxy } = useAppData();
const { proxies: proxiesData, refreshProxy } = useProxiesData();
const { verge } = useVerge();
const { width } = useWindowWidth();
const [headStates, setHeadState] = useHeadStateNew();