From 14bda4f3a5515aecabc26a9680946d9bc6e54008 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Tue, 28 Dec 2021 01:47:43 +0800
Subject: [PATCH] feat: record selected proxy

---
 src/components/proxy-group.tsx | 20 ++++++++++++++
 src/pages/profile.tsx          | 49 +++++++++++++++++++++++++++++++---
 src/pages/proxy.tsx            |  4 +--
 src/services/cmds.ts           |  7 ++---
 4 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/src/components/proxy-group.tsx b/src/components/proxy-group.tsx
index e20441c..b9f1fa2 100644
--- a/src/components/proxy-group.tsx
+++ b/src/components/proxy-group.tsx
@@ -22,6 +22,8 @@ import {
 } from "@mui/icons-material";
 import { updateProxy } from "../services/api";
 import { ApiType } from "../services/types";
+import { getProfiles, setProfiles } from "../services/cmds";
+import noop from "../utils/noop";
 
 interface ItemProps {
   proxy: ApiType.ProxyItem;
@@ -86,6 +88,24 @@ const ProxyGroup = ({ group }: Props) => {
     try {
       setNow(name);
       await updateProxy(group.name, name);
+
+      const profiles = await getProfiles().catch(console.error);
+      if (!profiles) return;
+      const profile = profiles.items![profiles.current!]!;
+      if (!profile) return;
+      if (!profile.selected) profile.selected = [];
+
+      const index = profile.selected.findIndex(
+        (item) => item.name === group.name
+      );
+
+      if (index < 0) {
+        profile.selected.push({ name: group.name, now: name });
+      } else {
+        profile.selected[index] = { name: group.name, now: name };
+      }
+
+      setProfiles(profiles.current!, profile).catch(console.error);
     } catch {
       setNow(oldValue);
       // Todo
diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx
index 16be950..0b74302 100644
--- a/src/pages/profile.tsx
+++ b/src/pages/profile.tsx
@@ -1,8 +1,13 @@
-import { useRef, useState } from "react";
+import { useEffect, useRef, useState } from "react";
 import useSWR, { useSWRConfig } from "swr";
 import { Box, Button, Grid, TextField, Typography } from "@mui/material";
-import { getProfiles, importProfile, putProfiles } from "../services/cmds";
-import { getProxies } from "../services/api";
+import {
+  getProfiles,
+  putProfiles,
+  setProfiles,
+  importProfile,
+} from "../services/cmds";
+import { getProxies, updateProxy } from "../services/api";
 import ProfileItemComp from "../components/profile-item";
 import useNotice from "../utils/use-notice";
 import noop from "../utils/noop";
@@ -15,6 +20,43 @@ const ProfilePage = () => {
   const { mutate } = useSWRConfig();
   const { data: profiles = {} } = useSWR("getProfiles", getProfiles);
 
+  useEffect(() => {
+    if (profiles.current == null) return;
+
+    const profile = profiles.items![profiles.current];
+    if (!profile) return;
+
+    getProxies().then((proxiesData) => {
+      mutate("getProxies", proxiesData);
+      // init selected array
+      const { selected = [] } = profile;
+      const selectedMap = Object.fromEntries(
+        selected.map((each) => [each.name!, each.now!])
+      );
+      // todo: enhance error handle
+      let hasChange = false;
+      proxiesData.groups.forEach((group) => {
+        const { name, now } = group;
+
+        if (!now || selectedMap[name] === now) return;
+        if (selectedMap[name] == null) {
+          selectedMap[name] = now!;
+        } else {
+          hasChange = true;
+          updateProxy(name, selectedMap[name]);
+        }
+      });
+      // update profile selected list
+      profile.selected = Object.entries(selectedMap).map(([name, now]) => ({
+        name,
+        now,
+      }));
+      setProfiles(profiles.current!, profile).catch(console.error);
+      // update proxies cache
+      if (hasChange) mutate("getProxies", getProxies());
+    });
+  }, [profiles]);
+
   const onImport = async () => {
     if (!url) return;
     setUrl("");
@@ -39,7 +81,6 @@ const ProfilePage = () => {
     putProfiles(index)
       .then(() => {
         mutate("getProfiles", { ...profiles, current: index }, true);
-        mutate("getProxies", getProxies());
       })
       .catch((err) => {
         console.error(err);
diff --git a/src/pages/proxy.tsx b/src/pages/proxy.tsx
index 98a236f..e4a1e2d 100644
--- a/src/pages/proxy.tsx
+++ b/src/pages/proxy.tsx
@@ -4,8 +4,8 @@ import { getProxies } from "../services/api";
 import ProxyGroup from "../components/proxy-group";
 
 const ProxyPage = () => {
-  const { data } = useSWR("getProxies", getProxies);
-  const { groups = [] } = data ?? {};
+  const { data: proxiesData } = useSWR("getProxies", getProxies);
+  const { groups = [] } = proxiesData ?? {};
 
   return (
     <Box sx={{ width: 0.9, maxWidth: "850px", mx: "auto", mb: 2 }}>
diff --git a/src/services/cmds.ts b/src/services/cmds.ts
index 4ca2495..8100092 100644
--- a/src/services/cmds.ts
+++ b/src/services/cmds.ts
@@ -25,11 +25,8 @@ export async function getProfiles() {
   return (await invoke<CmdType.ProfilesConfig>("get_profiles")) ?? {};
 }
 
-export async function setProfiles(
-  current: number,
-  profile: CmdType.ProfileItem
-) {
-  return invoke<void>("set_profiles", { current, profile });
+export async function setProfiles(index: number, profile: CmdType.ProfileItem) {
+  return invoke<void>("set_profiles", { index, profile });
 }
 
 export async function putProfiles(current: number) {
-- 
GitLab