From 36d8fa7de4d26d4ddd61067d3ced2b5538185e52 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Sat, 25 Dec 2021 23:20:59 +0800
Subject: [PATCH] fix: api loading delay

---
 src/components/traffic.tsx | 14 ++++++++-----
 src/pages/_layout.tsx      |  9 +-------
 src/pages/connections.tsx  | 16 +++++++++------
 src/pages/log.tsx          | 18 +++++++++-------
 src/services/api.ts        | 42 +++++++++++++++++++++++++-------------
 5 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/src/components/traffic.tsx b/src/components/traffic.tsx
index caee800..e0e7d91 100644
--- a/src/components/traffic.tsx
+++ b/src/components/traffic.tsx
@@ -9,14 +9,18 @@ const Traffic = () => {
   const [traffic, setTraffic] = useState({ up: 0, down: 0 });
 
   useEffect(() => {
-    const { server, secret } = getInfomation();
-    const ws = new WebSocket(`ws://${server}/traffic?token=${secret}`);
+    let ws: WebSocket | null = null;
 
-    ws.addEventListener("message", (event) => {
-      setTraffic(JSON.parse(event.data) as ApiType.TrafficItem);
+    getInfomation().then((result) => {
+      const { server = "", secret = "" } = result;
+      ws = new WebSocket(`ws://${server}/traffic?token=${secret}`);
+
+      ws.addEventListener("message", (event) => {
+        setTraffic(JSON.parse(event.data) as ApiType.TrafficItem);
+      });
     });
 
-    return () => ws.close();
+    return () => ws?.close();
   }, []);
 
   const [up, upUnit] = parseTraffic(traffic.up);
diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx
index 1939610..3680322 100644
--- a/src/pages/_layout.tsx
+++ b/src/pages/_layout.tsx
@@ -4,8 +4,7 @@ import { Route, Routes } from "react-router-dom";
 import { useRecoilState } from "recoil";
 import { createTheme, List, Paper, ThemeProvider } from "@mui/material";
 import { atomPaletteMode } from "../states/setting";
-import { getClashInfo, getVergeConfig } from "../services/cmds";
-import { initAxios } from "../services/api";
+import { getVergeConfig } from "../services/cmds";
 import LogoSvg from "../assets/image/logo.svg";
 import LogPage from "./log";
 import HomePage from "./home";
@@ -43,12 +42,6 @@ const Layout = () => {
   const [mode, setMode] = useRecoilState(atomPaletteMode);
   const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig);
 
-  useEffect(() => {
-    getClashInfo()
-      .then((result) => initAxios(result?.controller ?? {}))
-      .catch(() => console.error("can not initialize clash verge"));
-  }, []);
-
   useEffect(() => {
     setMode(vergeConfig?.theme_mode ?? "light");
   }, [vergeConfig?.theme_mode]);
diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx
index 8a7b534..c848c08 100644
--- a/src/pages/connections.tsx
+++ b/src/pages/connections.tsx
@@ -10,15 +10,19 @@ const ConnectionsPage = () => {
   const [conn, setConn] = useState<ApiType.Connections>(initConn);
 
   useEffect(() => {
-    const { server, secret } = getInfomation();
-    const ws = new WebSocket(`ws://${server}/connections?token=${secret}`);
+    let ws: WebSocket | null = null;
 
-    ws.addEventListener("message", (event) => {
-      const data = JSON.parse(event.data) as ApiType.Connections;
-      setConn(data);
+    getInfomation().then((result) => {
+      const { server = "", secret = "" } = result;
+      ws = new WebSocket(`ws://${server}/connections?token=${secret}`);
+
+      ws.addEventListener("message", (event) => {
+        const data = JSON.parse(event.data) as ApiType.Connections;
+        setConn(data);
+      });
     });
 
-    return () => ws.close();
+    return () => ws?.close();
   }, []);
 
   return (
diff --git a/src/pages/log.tsx b/src/pages/log.tsx
index f10a58c..1a32e6a 100644
--- a/src/pages/log.tsx
+++ b/src/pages/log.tsx
@@ -12,16 +12,20 @@ const LogPage = () => {
   const [logData, setLogData] = useState(logCache);
 
   useEffect(() => {
-    const info = getInfomation();
-    const ws = new WebSocket(`ws://${info.server}/logs?token=${info.secret}`);
+    let ws: WebSocket | null = null;
 
-    ws.addEventListener("message", (event) => {
-      const data = JSON.parse(event.data) as ApiType.LogItem;
-      const time = dayjs().format("MM-DD HH:mm:ss");
-      setLogData((l) => (logCache = [...l, { ...data, time }]));
+    getInfomation().then((result) => {
+      const { server = "", secret = "" } = result;
+      ws = new WebSocket(`ws://${server}/logs?token=${secret}`);
+
+      ws.addEventListener("message", (event) => {
+        const data = JSON.parse(event.data) as ApiType.LogItem;
+        const time = dayjs().format("MM-DD HH:mm:ss");
+        setLogData((l) => (logCache = [...l, { ...data, time }]));
+      });
     });
 
-    return () => ws.close();
+    return () => ws?.close();
   }, []);
 
   return (
diff --git a/src/services/api.ts b/src/services/api.ts
index f4cdb5c..52d4cb1 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -1,32 +1,41 @@
 import axios, { AxiosInstance } from "axios";
+import { getClashInfo } from "./cmds";
 import { ApiType } from "./types";
 
 let axiosIns: AxiosInstance = null!;
-let server = "127.0.0.1:9090";
+let server = "";
 let secret = "";
 
-type Callback<T> = (data: T) => void;
-
 /// initialize some infomation
-export function initAxios(info: { server?: string; secret?: string }) {
-  if (info.server) server = info.server;
-  if (info.secret) secret = info.secret;
+export async function getAxios() {
+  if (axiosIns) return axiosIns;
+
+  try {
+    const info = await getClashInfo();
+
+    if (info?.controller?.server) server = info?.controller?.server;
+    if (info?.controller?.secret) secret = info?.controller?.secret;
+  } catch {}
 
   axiosIns = axios.create({
     baseURL: `http://${server}`,
     headers: secret ? { Authorization: `Bearer ${secret}` } : {},
   });
   axiosIns.interceptors.response.use((r) => r.data);
+  return axiosIns;
 }
 
 /// get infomation
-export function getInfomation() {
-  return { server, secret };
+export async function getInfomation() {
+  if (server) return { server, secret };
+  const info = await getClashInfo();
+  return info?.controller!;
 }
 
 /// Get Version
 export async function getVersion() {
-  return axiosIns.get("/version") as Promise<{
+  const instance = await getAxios();
+  return instance.get("/version") as Promise<{
     premium: boolean;
     version: string;
   }>;
@@ -34,27 +43,32 @@ export async function getVersion() {
 
 /// Get current base configs
 export async function getClashConfig() {
-  return axiosIns.get("/configs") as Promise<ApiType.ConfigData>;
+  const instance = await getAxios();
+  return instance.get("/configs") as Promise<ApiType.ConfigData>;
 }
 
 /// Update current configs
 export async function updateConfigs(config: Partial<ApiType.ConfigData>) {
-  return axiosIns.patch("/configs", config);
+  const instance = await getAxios();
+  return instance.patch("/configs", config);
 }
 
 /// Get current rules
 export async function getRules() {
-  return axiosIns.get("/rules") as Promise<ApiType.RuleItem[]>;
+  const instance = await getAxios();
+  return instance.get("/rules") as Promise<ApiType.RuleItem[]>;
 }
 
 /// Update the Proxy Choose
 export async function updateProxy(group: string, proxy: string) {
-  return axiosIns.put(`/proxies/${group}`, { name: proxy });
+  const instance = await getAxios();
+  return instance.put(`/proxies/${group}`, { name: proxy });
 }
 
 /// Get the Proxy infomation
 export async function getProxies() {
-  const response = await axiosIns.get<any, any>("/proxies");
+  const instance = await getAxios();
+  const response = await instance.get<any, any>("/proxies");
   const proxies = (response?.proxies ?? {}) as Record<
     string,
     ApiType.ProxyItem
-- 
GitLab