Skip to content

Commit b715c16

Browse files
authored
feat(system_logs): Fixed auto scroll
1 parent 35db939 commit b715c16

File tree

1 file changed

+64
-4
lines changed

1 file changed

+64
-4
lines changed

web-server/src/content/Service/SystemLogs.tsx

+64-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { CircularProgress } from '@mui/material';
1+
import { ExpandCircleDown } from '@mui/icons-material';
2+
import { Button, CircularProgress } from '@mui/material';
23
import { useEffect, useRef } from 'react';
34
import { ErrorBoundary } from 'react-error-boundary';
45

@@ -9,19 +10,55 @@ import { SystemLogsErrorFallback } from '@/components/Service/SystemLog/SystemLo
910
import { SomethingWentWrong } from '@/components/SomethingWentWrong/SomethingWentWrong';
1011
import { Line } from '@/components/Text';
1112
import { ServiceNames } from '@/constants/service';
13+
import { useBoolState } from '@/hooks/useEasyState';
1214
import { useSystemLogs } from '@/hooks/useSystemLogs';
1315
import { parseLogLine } from '@/utils/logFormatter';
1416

17+
import { MotionBox } from '../../components/MotionComponents';
18+
1519
export const SystemLogs = ({ serviceName }: { serviceName?: ServiceNames }) => {
1620
const { services, loading, logs } = useSystemLogs({ serviceName });
17-
21+
const showScrollDownButton = useBoolState(false);
1822
const containerRef = useRef<HTMLDivElement>(null);
1923

24+
const scrollDown = () => {
25+
containerRef.current.scrollIntoView({ behavior: 'smooth' });
26+
};
27+
2028
useEffect(() => {
29+
const observer = new IntersectionObserver(
30+
(entries) => {
31+
entries.forEach((entry) => {
32+
if (entry.isIntersecting) {
33+
showScrollDownButton.false();
34+
} else {
35+
showScrollDownButton.true();
36+
}
37+
});
38+
},
39+
{
40+
threshold: 0
41+
}
42+
);
43+
44+
const containerElement = containerRef.current;
45+
2146
if (containerRef.current) {
22-
containerRef.current.scrollIntoView({ behavior: 'smooth' });
47+
observer.observe(containerElement);
2348
}
24-
}, [logs]);
49+
50+
return () => {
51+
if (containerElement) {
52+
observer.unobserve(containerElement);
53+
}
54+
};
55+
}, [showScrollDownButton]);
56+
57+
useEffect(() => {
58+
if (containerRef.current && !showScrollDownButton.value) {
59+
scrollDown();
60+
}
61+
}, [logs, showScrollDownButton.value]);
2562

2663
if (!serviceName)
2764
return (
@@ -51,6 +88,29 @@ export const SystemLogs = ({ serviceName }: { serviceName?: ServiceNames }) => {
5188
})
5289
)}
5390
<FlexBox ref={containerRef} />
91+
92+
{showScrollDownButton.value && (
93+
<Button
94+
onClick={scrollDown}
95+
component={MotionBox}
96+
initial={{ opacity: 0, scale: 0.7 }}
97+
animate={{ opacity: 1, scale: 1 }}
98+
transition={{
99+
ease: 'easeOut'
100+
}}
101+
bottom={20}
102+
sx={{
103+
position: 'fixed',
104+
marginLeft: `calc(${
105+
containerRef.current
106+
? containerRef.current.clientWidth / 2 - 67
107+
: 0
108+
}px)`
109+
}}
110+
>
111+
<ExpandCircleDown fontSize="large" color="secondary" />
112+
</Button>
113+
)}
54114
</FlexBox>
55115
</ErrorBoundary>
56116
);

0 commit comments

Comments
 (0)