|
1 | | -import { useEffect } from 'react' |
| 1 | +import { useState, useEffect } from 'react' |
2 | 2 | import { wsSnackbar } from '@postgres.ai/shared/pages/Logs/wsSnackbar' |
3 | 3 |
|
4 | | -export const useWsScroll = () => { |
5 | | - const snackbarTag = document.createElement('div') |
6 | | - const contentElement = document.getElementById( |
7 | | - 'content-container', |
8 | | - ) as HTMLElement |
| 4 | +export const useWsScroll = (isLoading: boolean) => { |
| 5 | + const [isNewData, setIsNewData] = useState(false) |
| 6 | + const [isAtBottom, setIsAtBottom] = useState(true) |
9 | 7 |
|
10 | 8 | useEffect(() => { |
11 | | - const targetNode = document.getElementById('logs-container') as HTMLElement |
12 | | - contentElement?.addEventListener( |
13 | | - 'scroll', |
14 | | - () => { |
15 | | - wsSnackbar(contentElement, targetNode, snackbarTag) |
16 | | - }, |
17 | | - false, |
18 | | - ) |
19 | | - |
20 | | - return () => |
| 9 | + !isLoading && wsSnackbar(isAtBottom, isNewData) |
| 10 | + |
| 11 | + const contentElement = document.getElementById('content-container') |
| 12 | + const targetNode = document.getElementById('logs-container') |
| 13 | + |
| 14 | + const clientAtBottom = (element: HTMLElement) => |
| 15 | + element.scrollHeight - element.scrollTop - 50 < element.clientHeight |
| 16 | + |
| 17 | + const handleScroll = (e: Event) => { |
| 18 | + if (clientAtBottom(e.target as HTMLElement)) { |
| 19 | + setIsAtBottom(true) |
| 20 | + setIsNewData(false) |
| 21 | + } else { |
| 22 | + setIsAtBottom(false) |
| 23 | + } |
| 24 | + } |
| 25 | + |
| 26 | + const handleInsert = (e: Event | any) => { |
| 27 | + if (e.srcElement?.tagName !== 'DIV') { |
| 28 | + isAtBottom && targetNode?.scrollIntoView(false) |
| 29 | + setIsNewData(true) |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + contentElement?.addEventListener('scroll', handleScroll, false) |
| 34 | + contentElement?.addEventListener('DOMNodeInserted', handleInsert, false) |
| 35 | + |
| 36 | + return () => { |
| 37 | + contentElement?.removeEventListener('scroll', handleScroll, false) |
21 | 38 | contentElement?.removeEventListener( |
22 | | - 'scroll', |
23 | | - () => { |
24 | | - wsSnackbar(contentElement, targetNode, snackbarTag) |
25 | | - }, |
| 39 | + 'DOMNodeInserted', |
| 40 | + handleInsert, |
26 | 41 | false, |
27 | 42 | ) |
28 | | - }, []) |
| 43 | + } |
| 44 | + }, [isAtBottom, isNewData, isLoading]) |
29 | 45 | } |
0 commit comments