({
messages,
isUserCollapsing,
}: UseChatUIOptions)
| 45 | } |
| 46 | |
| 47 | export function useChatUI({ |
| 48 | messages, |
| 49 | isUserCollapsing, |
| 50 | }: UseChatUIOptions): UseChatUIReturn { |
| 51 | const scrollRef = useRef<ScrollBoxRenderable | null>(null) |
| 52 | const [hasOverflow, setHasOverflow] = useState(false) |
| 53 | const hasOverflowRef = useRef(false) |
| 54 | |
| 55 | // Terminal dimensions |
| 56 | const { separatorWidth, terminalWidth, terminalHeight } = |
| 57 | useTerminalDimensions() |
| 58 | const { height: heightLayout, width: widthLayout } = useTerminalLayout() |
| 59 | const isCompactHeight = heightLayout.is('xs') |
| 60 | const isNarrowWidth = widthLayout.is('xs') |
| 61 | const messageAvailableWidth = separatorWidth |
| 62 | |
| 63 | // Theme |
| 64 | const theme = useTheme() |
| 65 | const markdownPalette = useMemo(() => createMarkdownPalette(theme), [theme]) |
| 66 | |
| 67 | // Scroll management |
| 68 | const { scrollToLatest, scrollUp, scrollDown, scrollboxProps, isAtBottom } = |
| 69 | useChatScrollbox(scrollRef, messages, isUserCollapsing) |
| 70 | |
| 71 | // Check if content has overflowed and needs scrolling |
| 72 | useEffect(() => { |
| 73 | const scrollbox = scrollRef.current |
| 74 | if (!scrollbox) return |
| 75 | |
| 76 | const checkOverflow = () => { |
| 77 | const contentHeight = scrollbox.scrollHeight |
| 78 | const viewportHeight = scrollbox.viewport.height |
| 79 | const isOverflowing = contentHeight > viewportHeight |
| 80 | |
| 81 | if (hasOverflowRef.current !== isOverflowing) { |
| 82 | hasOverflowRef.current = isOverflowing |
| 83 | setHasOverflow(isOverflowing) |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | checkOverflow() |
| 88 | scrollbox.verticalScrollBar.on('change', checkOverflow) |
| 89 | |
| 90 | return () => { |
| 91 | scrollbox.verticalScrollBar.off('change', checkOverflow) |
| 92 | } |
| 93 | }, []) |
| 94 | |
| 95 | // Inertial scroll acceleration |
| 96 | const inertialScrollAcceleration = useMemo( |
| 97 | () => createChatScrollAcceleration(), |
| 98 | [], |
| 99 | ) |
| 100 | |
| 101 | const appliedScrollboxProps = useMemo( |
| 102 | () => |
| 103 | inertialScrollAcceleration |
| 104 | ? { ...scrollboxProps, scrollAcceleration: inertialScrollAcceleration } |
no test coverage detected