From 819c5207d28daa7bfdf4ba64d1a204130039fb18 Mon Sep 17 00:00:00 2001 From: GyDi Date: Sun, 15 Jan 2023 21:33:03 +0800 Subject: [PATCH] fix: use selected proxy after profile changed --- src/components/proxy/use-head-state.ts | 6 +-- src/hooks/use-profiles.ts | 48 +++++++++++++++++++- src/pages/_layout.tsx | 8 ---- src/pages/profiles.tsx | 61 +++++--------------------- src/services/states.ts | 6 --- 5 files changed, 60 insertions(+), 69 deletions(-) diff --git a/src/components/proxy/use-head-state.ts b/src/components/proxy/use-head-state.ts index daba79b..d1bce2f 100644 --- a/src/components/proxy/use-head-state.ts +++ b/src/components/proxy/use-head-state.ts @@ -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>({}); diff --git a/src/hooks/use-profiles.ts b/src/hooks/use-profiles.ts index 9b6c5fe..9b49df2 100644 --- a/src/hooks/use-profiles.ts +++ b/src/hooks/use-profiles.ts @@ -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, diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index 4b52ace..1027ecc 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -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(() => { diff --git a/src/pages/profiles.tsx b/src/pages/profiles.tsx index b023aca..ec423f1 100644 --- a/src/pages/profiles.tsx +++ b/src/pages/profiles.tsx @@ -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); diff --git a/src/services/states.ts b/src/services/states.ts index 399eb3e..6ac6edc 100644 --- a/src/services/states.ts +++ b/src/services/states.ts @@ -71,9 +71,3 @@ export const atomUpdateState = atom({ key: "atomUpdateState", default: false, }); - -// current profile uid -export const atomCurrentProfile = atom({ - key: "atomCurrentProfile", - default: "", -});