From ac8ed1478ebd2f6ff3cb1733b47ef339a359be8a Mon Sep 17 00:00:00 2001 From: alexfront Date: Thu, 8 Sep 2022 14:14:35 +0300 Subject: [PATCH] Scroll list to bottom when new logs arrived Signed-off-by: alexfront --- .../components/dock/logs/log-list.module.scss | 2 +- .../components/dock/logs/log-list.tsx | 30 +++++++++---------- src/renderer/hooks/useIntersectionObserver.ts | 6 ++-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/renderer/components/dock/logs/log-list.module.scss b/src/renderer/components/dock/logs/log-list.module.scss index 32ebc636a3..459262ba41 100644 --- a/src/renderer/components/dock/logs/log-list.module.scss +++ b/src/renderer/components/dock/logs/log-list.module.scss @@ -33,6 +33,6 @@ width: 100%; height: 1px; bottom: 0; - background-color: red; + background-color: var(--logsBackground); position: absolute; } \ No newline at end of file diff --git a/src/renderer/components/dock/logs/log-list.tsx b/src/renderer/components/dock/logs/log-list.tsx index c966c76211..3bf75b7371 100644 --- a/src/renderer/components/dock/logs/log-list.tsx +++ b/src/renderer/components/dock/logs/log-list.tsx @@ -16,18 +16,20 @@ import { v4 as getRandomId } from "uuid"; import { useJumpToBottomButton } from "./use-scroll-to-bottom"; import { useInitialScrollToBottom } from "./use-initial-scroll-to-bottom"; import { ToBottom } from "./to-bottom"; +import useIntersectionObserver from "../../../hooks/useIntersectionObserver"; export interface LogListProps { model: LogTabViewModel; } export const LogList = observer(({ model }: LogListProps) => { - // const [lastLineVisible, setLastLineVisible] = React.useState(true); - const [rowKeySuffix, setRowKeySuffix] = React.useState(getRandomId()); - const { visibleLogs } = model; - const parentRef = useRef(null) + const parentRef = useRef(null); + const lastLineRef = useRef(null); + const [rowKeySuffix, setRowKeySuffix] = React.useState(getRandomId()); const [toBottomVisible, setButtonVisibility] = useJumpToBottomButton(parentRef.current); + const entry = useIntersectionObserver(lastLineRef.current, {}); + const rowVirtualizer = useVirtualizer({ count: visibleLogs.get().length, getScrollElement: () => parentRef.current, @@ -47,20 +49,9 @@ export const LogList = observer(({ model }: LogListProps) => { if (!parentRef.current) return; setButtonVisibility(); - setLastLineVisibility(); onScrollToTop(); }, 1_000, { trailing: true, leading: true }); - const setLastLineVisibility = () => { - // const { scrollTop, scrollHeight } = parentRef.current as HTMLDivElement; - - // if (scrollHeight - scrollTop < 4000) { - // setLastLineVisible(true); - // } else { - // setLastLineVisible(false); - // } - } - /** * Loads new logs if user scrolled to the top */ @@ -83,6 +74,7 @@ export const LogList = observer(({ model }: LogListProps) => { useEffect(() => { // rowVirtualizer.scrollToIndex(visibleLogs.get().length - 1, { align: 'end', smoothScroll: false }); + // Refresh list setRowKeySuffix(getRandomId()); }, [model.logTabData.get()]); @@ -92,6 +84,12 @@ export const LogList = observer(({ model }: LogListProps) => { scrollTo(model.searchStore.occurrences[model.searchStore.activeOverlayIndex]); }, [model.searchStore.searchQuery, model.searchStore.activeOverlayIndex]) + useEffect(() => { + if (entry?.isIntersecting) { + scrollToBottom(); + } + }, [model.visibleLogs.get().length]); + return (
{
))} -
+
{toBottomVisible && ( diff --git a/src/renderer/hooks/useIntersectionObserver.ts b/src/renderer/hooks/useIntersectionObserver.ts index fff4aa3662..03faa47948 100644 --- a/src/renderer/hooks/useIntersectionObserver.ts +++ b/src/renderer/hooks/useIntersectionObserver.ts @@ -14,7 +14,7 @@ interface IntersectionObserverOptions { * disconnect the IntersectionObserver instance after * intersection. */ - triggerOnce: boolean; + triggerOnce?: boolean; /** * Number from 0 to 1 representing the percentage @@ -22,7 +22,7 @@ interface IntersectionObserverOptions { * considered as visible. Can also be an array of * thresholds. */ - threshold: number | number[]; + threshold?: number | number[]; /** * Element that is used as the viewport for checking visibility @@ -38,7 +38,7 @@ interface IntersectionObserverOptions { } function useIntersectionObserver( - element: Element, + element: Element | null, { threshold = 0, rootMargin = "0%",