From 819c5207d28daa7bfdf4ba64d1a204130039fb18 Mon Sep 17 00:00:00 2001
From: GyDi <zzzgydi@gmail.com>
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<Record<string, HeadState>>({});
 
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<boolean>({
   key: "atomUpdateState",
   default: false,
 });
-
-// current profile uid
-export const atomCurrentProfile = atom<string>({
-  key: "atomCurrentProfile",
-  default: "",
-});
-- 
GitLab