summaryrefslogtreecommitdiff
path: root/src/modules/logs
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/logs')
-rw-r--r--src/modules/logs/hooks.ts28
-rw-r--r--src/modules/logs/utils.ts4
2 files changed, 21 insertions, 11 deletions
diff --git a/src/modules/logs/hooks.ts b/src/modules/logs/hooks.ts
index bbb3f7f..0620569 100644
--- a/src/modules/logs/hooks.ts
+++ b/src/modules/logs/hooks.ts
@@ -1,25 +1,33 @@
+import { useAtom, useSetAtom } from 'jotai';
import * as React from 'react';
import { fetchLogs, reconnect as reconnectLogs, stop as stopLogs } from '~/api/logs';
-import { appendLog } from '~/store/logs';
-import { DispatchFn, Log } from '~/store/types';
-import { ClashAPIConfig } from '~/types';
+import { appendLogAtom, logFilterText } from '~/store/logs';
+import { ClashAPIConfig, Log } from '~/types';
import { LOGS_SCROLL_BOTTOM_THRESHOLD } from './utils';
-const { useCallback, useEffect, useRef, useState } = React;
+const { useCallback, useEffect, useMemo, useRef, useState } = React;
type UpdateAppConfigFn = (name: string, value: unknown) => void;
+/** 搜索词是防抖过的,过滤结果缓存住,免得每条新日志进来都重扫一遍 */
+export function useFilteredLogs(logs: Log[]) {
+ const [filterText] = useAtom(logFilterText);
+ return useMemo(() => {
+ if (filterText === '') return logs;
+ const f = filterText.toLowerCase();
+ return logs.filter((log) => log.payload.toLowerCase().indexOf(f) >= 0);
+ }, [logs, filterText]);
+}
+
export function useLogsPage({
- dispatch,
logLevel,
apiConfig,
logs,
logStreamingPaused,
updateAppConfig,
}: {
- dispatch: DispatchFn;
logLevel: string;
apiConfig: ClashAPIConfig;
logs: Log[];
@@ -31,14 +39,15 @@ export function useLogsPage({
updateAppConfig('logStreamingPaused', !logStreamingPaused);
}, [apiConfig, logLevel, logStreamingPaused, updateAppConfig]);
- const appendLogInternal = useCallback((log) => dispatch(appendLog(log)), [dispatch]);
+ // useSetAtom 返回的 setter 引用稳定,可以直接当 effect 依赖
+ const appendLog = useSetAtom(appendLogAtom);
useEffect(() => {
- const unsubscribe = fetchLogs({ ...apiConfig, logLevel }, appendLogInternal);
+ const unsubscribe = fetchLogs({ ...apiConfig, logLevel }, appendLog);
return () => {
unsubscribe?.();
};
- }, [apiConfig, logLevel, appendLogInternal]);
+ }, [apiConfig, logLevel, appendLog]);
const scrollRef = useRef<HTMLDivElement>(null);
const [isAtBottom, setIsAtBottom] = useState(true);
@@ -49,6 +58,7 @@ export function useLogsPage({
}
}, []);
+ // 贴着底看的时候才自动跟随,用户往回翻了就别抢滚动位置
useEffect(() => {
if (isAtBottom) {
scrollToBottom();
diff --git a/src/modules/logs/utils.ts b/src/modules/logs/utils.ts
index cb0d7c6..34a716f 100644
--- a/src/modules/logs/utils.ts
+++ b/src/modules/logs/utils.ts
@@ -5,5 +5,5 @@ export const LOG_TYPES: Record<string, string> = {
error: 'error',
};
-export const LOGS_HEIGHT_RATIO = 0.8;
-export const LOGS_SCROLL_BOTTOM_THRESHOLD = 50; \ No newline at end of file
+/** 距底部多少像素以内算「贴着底」,自动跟随新日志 */
+export const LOGS_SCROLL_BOTTOM_THRESHOLD = 50;