From c1eb539a5ce8553e3dda2916fe55985e7ba694b9 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Sun, 13 Mar 2022 01:37:41 +0800
Subject: [PATCH] feat: event emit when clash config update

---
 src-tauri/src/core/clash.rs              | 13 +++++++++---
 src-tauri/src/main.rs                    |  9 ++------
 src/components/layout/layout-traffic.tsx | 11 ++++++----
 src/components/layout/use-log-setup.ts   | 26 +++++++++---------------
 src/pages/_layout.tsx                    |  6 ++----
 5 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/src-tauri/src/core/clash.rs b/src-tauri/src/core/clash.rs
index 4eae910..8d72711 100644
--- a/src-tauri/src/core/clash.rs
+++ b/src-tauri/src/core/clash.rs
@@ -264,7 +264,7 @@ impl Clash {
   /// activate the profile
   /// generate a new profile to the temp_dir
   /// then put the path to the clash core
-  fn _activate(info: ClashInfo, config: Mapping) -> Result<()> {
+  fn _activate(info: ClashInfo, config: Mapping, window: Option<Window>) -> Result<()> {
     let temp_path = dirs::profiles_temp_path();
     config::save_yaml(temp_path.clone(), &config, Some("# Clash Verge Temp File"))?;
 
@@ -294,6 +294,12 @@ impl Clash {
                 if resp.status() != 204 {
                   log::error!("failed to activate clash for status \"{}\"", resp.status());
                 }
+
+                // emit the window to update something
+                if let Some(window) = window {
+                  window.emit("verge://refresh-clash-config", "yes").unwrap();
+                }
+
                 // do not retry
                 break;
               }
@@ -325,6 +331,7 @@ impl Clash {
 
     // generate the payload
     let payload = profiles.gen_enhanced(event_name.clone())?;
+    let window = self.window.clone();
 
     win.once(&event_name, move |event| {
       if let Some(result) = event.payload() {
@@ -359,7 +366,7 @@ impl Clash {
 
           log::info!("profile enhanced status {}", result.status);
 
-          Self::_activate(info, config).unwrap();
+          Self::_activate(info, config, window).unwrap();
         }
 
         if let Some(error) = result.error {
@@ -390,7 +397,7 @@ impl Clash {
       config.insert(key, value);
     }
 
-    Self::_activate(info, config)?;
+    Self::_activate(info, config, self.window.clone())?;
     self.activate_enhanced(profiles, delay)
   }
 }
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 5cbcd4f..de62bfa 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -45,13 +45,8 @@ fn main() -> std::io::Result<()> {
           let profiles_state = app_handle.state::<states::ProfilesState>();
           let mut clash = clash_state.0.lock().unwrap();
           let mut profiles = profiles_state.0.lock().unwrap();
-          match clash.restart_sidecar(&mut profiles) {
-            Ok(_) => {
-              let window = app_handle.get_window("main").unwrap();
-              window.emit("restart_clash", "yes").unwrap();
-            }
-            Err(err) => log::error!("{}", err),
-          }
+
+          crate::log_if_err!(clash.restart_sidecar(&mut profiles));
         }
         "quit" => {
           resolve::resolve_reset(app_handle);
diff --git a/src/components/layout/layout-traffic.tsx b/src/components/layout/layout-traffic.tsx
index 19db259..1938a66 100644
--- a/src/components/layout/layout-traffic.tsx
+++ b/src/components/layout/layout-traffic.tsx
@@ -12,6 +12,7 @@ import useLogSetup from "./use-log-setup";
 import useTrafficGraph from "./use-traffic-graph";
 import parseTraffic from "../../utils/parse-traffic";
 
+// setup the traffic
 const LayoutTraffic = () => {
   const portValue = useRecoilValue(atomClashPort);
   const [traffic, setTraffic] = useState({ up: 0, down: 0 });
@@ -26,12 +27,14 @@ const LayoutTraffic = () => {
   useLogSetup();
 
   useEffect(() => {
-    let unlisten: () => void = null!;
-
     // should reconnect the traffic ws
-    listen("restart_clash", () => setRefresh({})).then((fn) => (unlisten = fn));
+    const unlisten = listen("verge://refresh-clash-config", () =>
+      setRefresh({})
+    );
 
-    return () => unlisten?.();
+    return () => {
+      unlisten.then((fn) => fn());
+    };
   }, []);
 
   useEffect(() => {
diff --git a/src/components/layout/use-log-setup.ts b/src/components/layout/use-log-setup.ts
index 6d34304..ff095f1 100644
--- a/src/components/layout/use-log-setup.ts
+++ b/src/components/layout/use-log-setup.ts
@@ -1,5 +1,5 @@
 import dayjs from "dayjs";
-import { useEffect } from "react";
+import { useEffect, useState } from "react";
 import { useSetRecoilState } from "recoil";
 import { listen } from "@tauri-apps/api/event";
 import { ApiType } from "../../services/types";
@@ -10,11 +10,11 @@ const MAX_LOG_NUM = 1000;
 
 // setup the log websocket
 export default function useLogSetup() {
+  const [refresh, setRefresh] = useState({});
   const setLogData = useSetRecoilState(atomLogData);
 
   useEffect(() => {
     let ws: WebSocket = null!;
-    let unlisten: () => void = null!;
 
     const handler = (event: MessageEvent<any>) => {
       const data = JSON.parse(event.data) as ApiType.LogItem;
@@ -25,25 +25,19 @@ export default function useLogSetup() {
       });
     };
 
-    (async () => {
-      const { server = "", secret = "" } = await getInfomation();
-
+    getInfomation().then((info) => {
+      const { server = "", secret = "" } = info;
       ws = new WebSocket(`ws://${server}/logs?token=${secret}`);
       ws.addEventListener("message", handler);
+    });
 
-      // reconnect the websocket
-      unlisten = await listen("restart_clash", async () => {
-        const { server = "", secret = "" } = await getInfomation();
-
-        ws?.close();
-        ws = new WebSocket(`ws://${server}/logs?token=${secret}`);
-        ws.addEventListener("message", handler);
-      });
-    })();
+    const unlisten = listen("verge://refresh-clash-config", () =>
+      setRefresh({})
+    );
 
     return () => {
       ws?.close();
-      unlisten?.();
+      unlisten?.then((fn) => fn());
     };
-  }, []);
+  }, [refresh]);
 }
diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx
index 46d3a9d..df1736c 100644
--- a/src/pages/_layout.tsx
+++ b/src/pages/_layout.tsx
@@ -30,12 +30,10 @@ const Layout = () => {
       if (e.key === "Escape") appWindow.hide();
     });
 
-    listen("restart_clash", async () => {
+    listen("verge://refresh-clash-config", async () => {
       // the clash info may be updated
       await getAxios(true);
-      // make sure that the clash is ok
-      setTimeout(() => mutate("getProxies"), 1000);
-      setTimeout(() => mutate("getProxies"), 2000);
+      mutate("getProxies");
       mutate("getClashConfig");
     });
   }, []);
-- 
GitLab