fix: use selected proxy after profile changed
This commit is contained in:
parent
311358544e
commit
819c5207d2
@ -1,7 +1,6 @@
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useRecoilValue } from "recoil";
|
|
||||||
import { atomCurrentProfile } from "@/services/states";
|
|
||||||
import { ProxySortType } from "./use-filter-sort";
|
import { ProxySortType } from "./use-filter-sort";
|
||||||
|
import { useProfiles } from "@/hooks/use-profiles";
|
||||||
|
|
||||||
export interface HeadState {
|
export interface HeadState {
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
@ -25,7 +24,8 @@ export const DEFAULT_STATE: HeadState = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function useHeadStateNew() {
|
export function useHeadStateNew() {
|
||||||
const current = useRecoilValue(atomCurrentProfile);
|
const { profiles } = useProfiles();
|
||||||
|
const current = profiles?.current || "";
|
||||||
|
|
||||||
const [state, setState] = useState<Record<string, HeadState>>({});
|
const [state, setState] = useState<Record<string, HeadState>>({});
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import useSWR from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import {
|
import {
|
||||||
getProfiles,
|
getProfiles,
|
||||||
patchProfile,
|
patchProfile,
|
||||||
patchProfilesConfig,
|
patchProfilesConfig,
|
||||||
} from "@/services/cmds";
|
} from "@/services/cmds";
|
||||||
|
import { getProxies, updateProxy } from "@/services/api";
|
||||||
|
|
||||||
export const useProfiles = () => {
|
export const useProfiles = () => {
|
||||||
const { data: profiles, mutate: mutateProfiles } = useSWR(
|
const { data: profiles, mutate: mutateProfiles } = useSWR(
|
||||||
@ -23,9 +24,54 @@ export const useProfiles = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 根据selected的节点选择
|
||||||
|
const activateSelected = async () => {
|
||||||
|
const proxiesData = await getProxies();
|
||||||
|
const profileData = await getProfiles();
|
||||||
|
|
||||||
|
if (!profileData || !proxiesData) return;
|
||||||
|
|
||||||
|
const current = profileData.items?.find(
|
||||||
|
(e) => e.uid === profileData.current
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!current) return;
|
||||||
|
|
||||||
|
// init selected array
|
||||||
|
const { selected = [] } = current;
|
||||||
|
const selectedMap = Object.fromEntries(
|
||||||
|
selected.map((each) => [each.name!, each.now!])
|
||||||
|
);
|
||||||
|
|
||||||
|
let hasChange = false;
|
||||||
|
|
||||||
|
const newSelected: typeof selected = [];
|
||||||
|
const { global, groups } = proxiesData;
|
||||||
|
|
||||||
|
[global, ...groups].forEach(({ type, name, now }) => {
|
||||||
|
if (!now || (type !== "Selector" && type !== "Fallback")) return;
|
||||||
|
if (selectedMap[name] != null && selectedMap[name] !== now) {
|
||||||
|
hasChange = true;
|
||||||
|
updateProxy(name, selectedMap[name]);
|
||||||
|
console.log({
|
||||||
|
name,
|
||||||
|
now,
|
||||||
|
select: selectedMap[name],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
newSelected.push({ name, now: selectedMap[name] });
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasChange) {
|
||||||
|
patchProfile(profileData.current!, { selected: newSelected });
|
||||||
|
mutate("getProxies", getProxies());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
profiles,
|
profiles,
|
||||||
current: profiles?.items?.find((p) => p.uid === profiles.current),
|
current: profiles?.items?.find((p) => p.uid === profiles.current),
|
||||||
|
activateSelected,
|
||||||
patchProfiles,
|
patchProfiles,
|
||||||
patchCurrent,
|
patchCurrent,
|
||||||
mutateProfiles,
|
mutateProfiles,
|
||||||
|
@ -3,7 +3,6 @@ import i18next from "i18next";
|
|||||||
import relativeTime from "dayjs/plugin/relativeTime";
|
import relativeTime from "dayjs/plugin/relativeTime";
|
||||||
import { SWRConfig, mutate } from "swr";
|
import { SWRConfig, mutate } from "swr";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useSetRecoilState } from "recoil";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Route, Routes } from "react-router-dom";
|
import { Route, Routes } from "react-router-dom";
|
||||||
import { alpha, List, Paper, ThemeProvider } from "@mui/material";
|
import { alpha, List, Paper, ThemeProvider } from "@mui/material";
|
||||||
@ -11,8 +10,6 @@ import { listen } from "@tauri-apps/api/event";
|
|||||||
import { appWindow } from "@tauri-apps/api/window";
|
import { appWindow } from "@tauri-apps/api/window";
|
||||||
import { routers } from "./_routers";
|
import { routers } from "./_routers";
|
||||||
import { getAxios } from "@/services/api";
|
import { getAxios } from "@/services/api";
|
||||||
import { atomCurrentProfile } from "@/services/states";
|
|
||||||
import { getProfiles } from "@/services/cmds";
|
|
||||||
import { useVerge } from "@/hooks/use-verge";
|
import { useVerge } from "@/hooks/use-verge";
|
||||||
import { ReactComponent as LogoSvg } from "@/assets/image/logo.svg";
|
import { ReactComponent as LogoSvg } from "@/assets/image/logo.svg";
|
||||||
import { BaseErrorBoundary, Notice } from "@/components/base";
|
import { BaseErrorBoundary, Notice } from "@/components/base";
|
||||||
@ -36,8 +33,6 @@ const Layout = () => {
|
|||||||
const { verge } = useVerge();
|
const { verge } = useVerge();
|
||||||
const { theme_blur, language } = verge || {};
|
const { theme_blur, language } = verge || {};
|
||||||
|
|
||||||
const setCurrentProfile = useSetRecoilState(atomCurrentProfile);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener("keydown", (e) => {
|
window.addEventListener("keydown", (e) => {
|
||||||
if (e.key === "Escape") {
|
if (e.key === "Escape") {
|
||||||
@ -71,9 +66,6 @@ const Layout = () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// set current profile uid
|
|
||||||
getProfiles().then((data) => setCurrentProfile(data.current ?? ""));
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
import { useLockFn } from "ahooks";
|
import { useLockFn } from "ahooks";
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useMemo, useRef, useState } from "react";
|
||||||
import { useSetRecoilState } from "recoil";
|
|
||||||
import { Box, Button, Grid, IconButton, Stack, TextField } from "@mui/material";
|
import { Box, Button, Grid, IconButton, Stack, TextField } from "@mui/material";
|
||||||
import { CachedRounded } from "@mui/icons-material";
|
import { CachedRounded } from "@mui/icons-material";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
getProfiles,
|
getProfiles,
|
||||||
patchProfile,
|
|
||||||
importProfile,
|
importProfile,
|
||||||
enhanceProfiles,
|
enhanceProfiles,
|
||||||
getRuntimeLogs,
|
getRuntimeLogs,
|
||||||
deleteProfile,
|
deleteProfile,
|
||||||
} from "@/services/cmds";
|
} from "@/services/cmds";
|
||||||
import { closeAllConnections, getProxies, updateProxy } from "@/services/api";
|
import { closeAllConnections } from "@/services/api";
|
||||||
import { atomCurrentProfile } from "@/services/states";
|
|
||||||
import { BasePage, Notice } from "@/components/base";
|
import { BasePage, Notice } from "@/components/base";
|
||||||
import {
|
import {
|
||||||
ProfileViewer,
|
ProfileViewer,
|
||||||
@ -30,9 +27,12 @@ const ProfilePage = () => {
|
|||||||
const [url, setUrl] = useState("");
|
const [url, setUrl] = useState("");
|
||||||
const [disabled, setDisabled] = useState(false);
|
const [disabled, setDisabled] = useState(false);
|
||||||
|
|
||||||
const setCurrentProfile = useSetRecoilState(atomCurrentProfile);
|
const {
|
||||||
|
profiles = {},
|
||||||
const { profiles = {}, patchProfiles, mutateProfiles } = useProfiles();
|
activateSelected,
|
||||||
|
patchProfiles,
|
||||||
|
mutateProfiles,
|
||||||
|
} = useProfiles();
|
||||||
|
|
||||||
const { data: chainLogs = {}, mutate: mutateLogs } = useSWR(
|
const { data: chainLogs = {}, mutate: mutateLogs } = useSWR(
|
||||||
"getRuntimeLogs",
|
"getRuntimeLogs",
|
||||||
@ -60,48 +60,6 @@ const ProfilePage = () => {
|
|||||||
return { regularItems, enhanceItems };
|
return { regularItems, enhanceItems };
|
||||||
}, [profiles]);
|
}, [profiles]);
|
||||||
|
|
||||||
// sync selected proxy
|
|
||||||
useEffect(() => {
|
|
||||||
if (profiles.current == null) return;
|
|
||||||
|
|
||||||
const current = profiles.current;
|
|
||||||
const profile = regularItems.find((p) => p.uid === current);
|
|
||||||
|
|
||||||
setCurrentProfile(current);
|
|
||||||
|
|
||||||
if (!profile) return;
|
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
const proxiesData = await getProxies();
|
|
||||||
mutate("getProxies", proxiesData);
|
|
||||||
|
|
||||||
// init selected array
|
|
||||||
const { selected = [] } = profile;
|
|
||||||
const selectedMap = Object.fromEntries(
|
|
||||||
selected.map((each) => [each.name!, each.now!])
|
|
||||||
);
|
|
||||||
|
|
||||||
let hasChange = false;
|
|
||||||
|
|
||||||
const newSelected: typeof selected = [];
|
|
||||||
const { global, groups } = proxiesData;
|
|
||||||
|
|
||||||
[global, ...groups].forEach(({ type, name, now }) => {
|
|
||||||
if (!now || (type !== "Selector" && type !== "Fallback")) return;
|
|
||||||
if (selectedMap[name] != null && selectedMap[name] !== now) {
|
|
||||||
hasChange = true;
|
|
||||||
updateProxy(name, selectedMap[name]);
|
|
||||||
}
|
|
||||||
newSelected.push({ name, now });
|
|
||||||
});
|
|
||||||
|
|
||||||
// update profile selected list
|
|
||||||
patchProfile(current!, { selected: newSelected });
|
|
||||||
// update proxies cache
|
|
||||||
if (hasChange) mutate("getProxies", getProxies());
|
|
||||||
}, 100);
|
|
||||||
}, [profiles, regularItems]);
|
|
||||||
|
|
||||||
const onImport = async () => {
|
const onImport = async () => {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
setUrl("");
|
setUrl("");
|
||||||
@ -119,6 +77,7 @@ const ProfilePage = () => {
|
|||||||
const current = remoteItem.uid;
|
const current = remoteItem.uid;
|
||||||
patchProfiles({ current });
|
patchProfiles({ current });
|
||||||
mutateLogs();
|
mutateLogs();
|
||||||
|
setTimeout(() => activateSelected(), 2000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@ -132,9 +91,9 @@ const ProfilePage = () => {
|
|||||||
if (!force && current === profiles.current) return;
|
if (!force && current === profiles.current) return;
|
||||||
try {
|
try {
|
||||||
await patchProfiles({ current });
|
await patchProfiles({ current });
|
||||||
setCurrentProfile(current);
|
|
||||||
mutateLogs();
|
mutateLogs();
|
||||||
closeAllConnections();
|
closeAllConnections();
|
||||||
|
setTimeout(() => activateSelected(), 2000);
|
||||||
Notice.success("Refresh clash config", 1000);
|
Notice.success("Refresh clash config", 1000);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
Notice.error(err?.message || err.toString(), 4000);
|
Notice.error(err?.message || err.toString(), 4000);
|
||||||
|
@ -71,9 +71,3 @@ export const atomUpdateState = atom<boolean>({
|
|||||||
key: "atomUpdateState",
|
key: "atomUpdateState",
|
||||||
default: false,
|
default: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// current profile uid
|
|
||||||
export const atomCurrentProfile = atom<string>({
|
|
||||||
key: "atomCurrentProfile",
|
|
||||||
default: "",
|
|
||||||
});
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user