import styles from "./log-list.module.scss"; import { useVirtualizer } from '@tanstack/react-virtual'; import { observer } from 'mobx-react'; import React, { useEffect, useRef } from 'react'; import type { LogTabViewModel } from './logs-view-model'; import { LogRow } from "./log-row"; export interface LogListProps { model: LogTabViewModel; } export const LogList = observer(({ model }: LogListProps) => { const [toBottomVisible, setToBottomVisible] = React.useState(false); const [lastLineVisible, setLastLineVisible] = React.useState(true); const { visibleLogs } = model; const parentRef = useRef(null) const rowVirtualizer = useVirtualizer({ count: visibleLogs.get().length, getScrollElement: () => parentRef.current, estimateSize: () => 38, overscan: 5, scrollPaddingEnd: 0, scrollPaddingStart: 0, }); const onScroll = (event: React.UIEvent) => { if (!parentRef.current) return; setToBottomVisibility(); setLastLineVisibility(); onScrollToTop(); } // TODO: Move to its own hook const setToBottomVisibility = () => { const { scrollTop, scrollHeight } = parentRef.current as HTMLDivElement; // console.log("scrolling", scrollHeight, scrollTop, rowVirtualizer.getTotalSize()) if (scrollHeight - scrollTop > 4000) { setToBottomVisible(true); } else { setToBottomVisible(false); } } const setLastLineVisibility = () => { const { scrollTop, scrollHeight } = parentRef.current as HTMLDivElement; if (scrollHeight - scrollTop < 4000) { setLastLineVisible(true); } else { setLastLineVisible(false); } } /** * Check if user scrolled to top and new logs should be loaded */ const onScrollToTop = async () => { const { scrollTop } = parentRef.current as HTMLDivElement; if (scrollTop === 0) { const logs = model.logs.get(); const firstLog = logs[0]; await model.loadLogs(); const scrollToIndex = model.logs.get().findIndex(log => log === firstLog); rowVirtualizer.scrollToIndex(scrollToIndex, { align: 'start', smoothScroll: false }); } }; useEffect(() => { setTimeout(() => { // Initial scroll to bottom rowVirtualizer.scrollToIndex(visibleLogs.get().length - 1, { align: 'end', smoothScroll: false }); }, 200) }, [model.logTabData.get()?.selectedPodId]) useEffect(() => { rowVirtualizer.scrollToIndex(visibleLogs.get().length - 1, { align: 'end', smoothScroll: false }); }, [model.logTabData.get()]); return (
{rowVirtualizer.getVirtualItems().map((virtualRow) => (
))}
) });