From 0a3c59450b9d6650492c27637c77ddfd72a889ff Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Sat, 11 Dec 2021 20:52:06 +0800
Subject: [PATCH] feat(traffic): api support & adjust

---
 src/components/traffic.tsx | 37 ++++++++++++++++++++-----------------
 src/services/base.ts       | 11 +++++++++++
 src/services/index.ts      |  5 +++++
 src/services/traffic.ts    | 29 +++++++++++++++++++++++++++++
 4 files changed, 65 insertions(+), 17 deletions(-)
 create mode 100644 src/services/base.ts
 create mode 100644 src/services/index.ts
 create mode 100644 src/services/traffic.ts

diff --git a/src/components/traffic.tsx b/src/components/traffic.tsx
index 26b8f55..51c1b83 100644
--- a/src/components/traffic.tsx
+++ b/src/components/traffic.tsx
@@ -1,29 +1,32 @@
-import axios from "axios";
+import { CancelTokenSource } from "axios";
 import { useEffect, useState } from "react";
+import { Box, Typography } from "@mui/material";
 import { ArrowDownward, ArrowUpward } from "@mui/icons-material";
 import parseTraffic from "../utils/parse-traffic";
-import { Typography } from "@mui/material";
-import { Box } from "@mui/system";
+import services from "../services";
 
 const Traffic = () => {
   const [traffic, setTraffic] = useState({ up: 0, down: 0 });
 
   useEffect(() => {
-    const onTraffic = () => {
-      axios({
-        url: `http://127.0.0.1:9090/traffic`,
-        method: "GET",
-        onDownloadProgress: (progressEvent) => {
-          const data = progressEvent.currentTarget.response || "";
-          const lastData = data.slice(data.trim().lastIndexOf("\n") + 1);
-          try {
-            if (lastData) setTraffic(JSON.parse(lastData));
-          } catch {}
-        },
-      }).catch(() => setTimeout(onTraffic, 500));
-    };
+    let timer: any = null;
+    let source: CancelTokenSource | null = null;
+
+    async function onTraffic() {
+      timer = null;
+      try {
+        source = await services.getTraffic(setTraffic);
+      } catch {
+        timer = setTimeout(onTraffic, 500);
+      }
+    }
 
     onTraffic();
+
+    return () => {
+      if (timer) clearTimeout(timer);
+      source?.cancel();
+    };
   }, []);
 
   const [up, upUnit] = parseTraffic(traffic.up);
@@ -45,7 +48,7 @@ const Traffic = () => {
 
   return (
     <Box width="110px">
-      <Box mb={2} display="flex" alignItems="center" whiteSpace="nowrap">
+      <Box mb={1.5} display="flex" alignItems="center" whiteSpace="nowrap">
         <ArrowUpward
           fontSize="small"
           color={+up > 0 ? "primary" : "disabled"}
diff --git a/src/services/base.ts b/src/services/base.ts
new file mode 100644
index 0000000..23b2d38
--- /dev/null
+++ b/src/services/base.ts
@@ -0,0 +1,11 @@
+import axios from "axios";
+
+const axiosIns = axios.create({
+  baseURL: "http://127.0.0.1:9090",
+});
+
+axiosIns.interceptors.response.use((respone) => {
+  return respone.data;
+});
+
+export default axiosIns;
diff --git a/src/services/index.ts b/src/services/index.ts
new file mode 100644
index 0000000..a15cef0
--- /dev/null
+++ b/src/services/index.ts
@@ -0,0 +1,5 @@
+import * as traffic from "./traffic";
+
+export default {
+  ...traffic,
+};
diff --git a/src/services/traffic.ts b/src/services/traffic.ts
new file mode 100644
index 0000000..09e0e34
--- /dev/null
+++ b/src/services/traffic.ts
@@ -0,0 +1,29 @@
+import axios from "axios";
+import axiosIns from "./base";
+
+export interface TrafficData {
+  up: number;
+  down: number;
+}
+
+/// Get the traffic stream
+export async function getTraffic(callback: (data: TrafficData) => void) {
+  const source = axios.CancelToken.source();
+
+  axiosIns.get("/traffic", {
+    cancelToken: source.token,
+    onDownloadProgress: (progressEvent) => {
+      const data = progressEvent.currentTarget.response || "";
+      const lastData = data.slice(data.trim().lastIndexOf("\n") + 1);
+
+      if (!lastData) callback({ up: 0, down: 0 });
+      try {
+        callback(JSON.parse(lastData) as TrafficData);
+      } catch {
+        callback({ up: 0, down: 0 });
+      }
+    },
+  });
+
+  return source;
+}
-- 
GitLab