fix: use selected proxy after profile changed

This commit is contained in:
GyDi 2023-01-15 21:33:03 +08:00
parent 311358544e
commit 819c5207d2
No known key found for this signature in database
GPG Key ID: 9C3AD40F1F99880A
5 changed files with 60 additions and 69 deletions

View File

@ -1,7 +1,6 @@
import { useCallback, useEffect, useState } from "react";
import { useRecoilValue } from "recoil";
import { atomCurrentProfile } from "@/services/states";
import { ProxySortType } from "./use-filter-sort";
import { useProfiles } from "@/hooks/use-profiles";
export interface HeadState {
open?: boolean;
@ -25,7 +24,8 @@ export const DEFAULT_STATE: HeadState = {
};
export function useHeadStateNew() {
const current = useRecoilValue(atomCurrentProfile);
const { profiles } = useProfiles();
const current = profiles?.current || "";
const [state, setState] = useState<Record<string, HeadState>>({});

View File

@ -1,9 +1,10 @@
import useSWR from "swr";
import useSWR, { mutate } from "swr";
import {
getProfiles,
patchProfile,
patchProfilesConfig,
} from "@/services/cmds";
import { getProxies, updateProxy } from "@/services/api";
export const useProfiles = () => {
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 {
profiles,
current: profiles?.items?.find((p) => p.uid === profiles.current),
activateSelected,
patchProfiles,
patchCurrent,
mutateProfiles,

View File

@ -3,7 +3,6 @@ import i18next from "i18next";
import relativeTime from "dayjs/plugin/relativeTime";
import { SWRConfig, mutate } from "swr";
import { useEffect } from "react";
import { useSetRecoilState } from "recoil";
import { useTranslation } from "react-i18next";
import { Route, Routes } from "react-router-dom";
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 { routers } from "./_routers";
import { getAxios } from "@/services/api";
import { atomCurrentProfile } from "@/services/states";
import { getProfiles } from "@/services/cmds";
import { useVerge } from "@/hooks/use-verge";
import { ReactComponent as LogoSvg } from "@/assets/image/logo.svg";
import { BaseErrorBoundary, Notice } from "@/components/base";
@ -36,8 +33,6 @@ const Layout = () => {
const { verge } = useVerge();
const { theme_blur, language } = verge || {};
const setCurrentProfile = useSetRecoilState(atomCurrentProfile);
useEffect(() => {
window.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
@ -71,9 +66,6 @@ const Layout = () => {
break;
}
});
// set current profile uid
getProfiles().then((data) => setCurrentProfile(data.current ?? ""));
}, []);
useEffect(() => {

View File

@ -1,20 +1,17 @@
import useSWR, { mutate } from "swr";
import { useLockFn } from "ahooks";
import { useEffect, useMemo, useRef, useState } from "react";
import { useSetRecoilState } from "recoil";
import { useMemo, useRef, useState } from "react";
import { Box, Button, Grid, IconButton, Stack, TextField } from "@mui/material";
import { CachedRounded } from "@mui/icons-material";
import { useTranslation } from "react-i18next";
import {
getProfiles,
patchProfile,
importProfile,
enhanceProfiles,
getRuntimeLogs,
deleteProfile,
} from "@/services/cmds";
import { closeAllConnections, getProxies, updateProxy } from "@/services/api";
import { atomCurrentProfile } from "@/services/states";
import { closeAllConnections } from "@/services/api";
import { BasePage, Notice } from "@/components/base";
import {
ProfileViewer,
@ -30,9 +27,12 @@ const ProfilePage = () => {
const [url, setUrl] = useState("");
const [disabled, setDisabled] = useState(false);
const setCurrentProfile = useSetRecoilState(atomCurrentProfile);
const { profiles = {}, patchProfiles, mutateProfiles } = useProfiles();
const {
profiles = {},
activateSelected,
patchProfiles,
mutateProfiles,
} = useProfiles();
const { data: chainLogs = {}, mutate: mutateLogs } = useSWR(
"getRuntimeLogs",
@ -60,48 +60,6 @@ const ProfilePage = () => {
return { regularItems, enhanceItems };
}, [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 () => {
if (!url) return;
setUrl("");
@ -119,6 +77,7 @@ const ProfilePage = () => {
const current = remoteItem.uid;
patchProfiles({ current });
mutateLogs();
setTimeout(() => activateSelected(), 2000);
}
});
} catch (err: any) {
@ -132,9 +91,9 @@ const ProfilePage = () => {
if (!force && current === profiles.current) return;
try {
await patchProfiles({ current });
setCurrentProfile(current);
mutateLogs();
closeAllConnections();
setTimeout(() => activateSelected(), 2000);
Notice.success("Refresh clash config", 1000);
} catch (err: any) {
Notice.error(err?.message || err.toString(), 4000);

View File

@ -71,9 +71,3 @@ export const atomUpdateState = atom<boolean>({
key: "atomUpdateState",
default: false,
});
// current profile uid
export const atomCurrentProfile = atom<string>({
key: "atomCurrentProfile",
default: "",
});