1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
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 { LOGS_SCROLL_BOTTOM_THRESHOLD } from './utils';
const { useCallback, useEffect, useRef, useState } = React;
type UpdateAppConfigFn = (name: string, value: unknown) => void;
export function useLogsPage({
dispatch,
logLevel,
apiConfig,
logs,
logStreamingPaused,
updateAppConfig,
}: {
dispatch: DispatchFn;
logLevel: string;
apiConfig: ClashAPIConfig;
logs: Log[];
logStreamingPaused: boolean;
updateAppConfig: UpdateAppConfigFn;
}) {
const toggleIsRefreshPaused = useCallback(() => {
logStreamingPaused ? reconnectLogs({ ...apiConfig, logLevel }) : stopLogs();
updateAppConfig('logStreamingPaused', !logStreamingPaused);
}, [apiConfig, logLevel, logStreamingPaused, updateAppConfig]);
const appendLogInternal = useCallback((log) => dispatch(appendLog(log)), [dispatch]);
useEffect(() => {
fetchLogs({ ...apiConfig, logLevel }, appendLogInternal);
return () => {
stopLogs();
};
}, [apiConfig, logLevel, appendLogInternal]);
const scrollRef = useRef<HTMLDivElement>(null);
const [isAtBottom, setIsAtBottom] = useState(true);
const scrollToBottom = useCallback(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, []);
useEffect(() => {
if (isAtBottom) {
scrollToBottom();
}
}, [logs, isAtBottom, scrollToBottom]);
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
const atBottom = scrollHeight - scrollTop - clientHeight < LOGS_SCROLL_BOTTOM_THRESHOLD;
setIsAtBottom(atBottom);
}, []);
return {
toggleIsRefreshPaused,
scrollRef,
isAtBottom,
scrollToBottom,
onScroll,
};
}
|