|
@@ -0,0 +1,57 @@
|
|
|
+import useSWRSubscription from "swr/subscription";
|
|
|
+import { useEnableLog } from "../services/states";
|
|
|
+import { createSockette } from "../utils/websocket";
|
|
|
+import { useClashInfo } from "./use-clash";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import { getClashLogs } from "../services/cmds";
|
|
|
+
|
|
|
+const MAX_LOG_NUM = 1000;
|
|
|
+
|
|
|
+export const useLogData = () => {
|
|
|
+ const { clashInfo } = useClashInfo();
|
|
|
+
|
|
|
+ const [enableLog] = useEnableLog();
|
|
|
+ !enableLog || !clashInfo;
|
|
|
+
|
|
|
+ return useSWRSubscription<ILogItem[], any, "getClashLog" | null>(
|
|
|
+ enableLog && clashInfo ? "getClashLog" : null,
|
|
|
+ (_key, { next }) => {
|
|
|
+ const { server = "", secret = "" } = clashInfo!;
|
|
|
+
|
|
|
+ // populate the initial logs
|
|
|
+ getClashLogs().then(
|
|
|
+ (logs) => next(null, logs),
|
|
|
+ (err) => next(err)
|
|
|
+ );
|
|
|
+
|
|
|
+ const s = createSockette(
|
|
|
+ `ws://${server}/logs?token=${encodeURIComponent(secret)}`,
|
|
|
+ {
|
|
|
+ onmessage(event) {
|
|
|
+ const data = JSON.parse(event.data) as ILogItem;
|
|
|
+
|
|
|
+ // append new log item on socket message
|
|
|
+ next(null, (l = []) => {
|
|
|
+ const time = dayjs().format("MM-DD HH:mm:ss");
|
|
|
+
|
|
|
+ if (l.length >= MAX_LOG_NUM) l.shift();
|
|
|
+ return [...l, { ...data, time }];
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onerror(event) {
|
|
|
+ this.close();
|
|
|
+ next(event);
|
|
|
+ },
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ s.close();
|
|
|
+ };
|
|
|
+ },
|
|
|
+ {
|
|
|
+ fallbackData: { up: 0, down: 0 },
|
|
|
+ keepPreviousData: true,
|
|
|
+ }
|
|
|
+ );
|
|
|
+};
|