diff options
| author | Taylor Mullen <[email protected]> | 2025-05-15 22:56:03 -0700 |
|---|---|---|
| committer | N. Taylor Mullen <[email protected]> | 2025-05-15 22:57:28 -0700 |
| commit | 9c46acc793df3573e6fbcf53ac3e46663494e410 (patch) | |
| tree | 82c40d365c60f5e578a7548c65a15cb6e4838ccd /packages/cli/src/ui/App.tsx | |
| parent | 33743d347b6721f8eec537d01ad9f6a95b4c6683 (diff) | |
Refactor: Improve UI rendering and address code review comments
This commit addresses several code review comments primarily focused on improving the rendering and stability of the CLI UI.
Key changes include:
- Passing `isPending` and `availableTerminalHeight` props to `MarkdownDisplay` to enable more intelligent rendering of content, especially for pending messages and code blocks.
- Adjusting height calculations in `ToolGroupMessage` and `ToolMessage` to more accurately reflect available space.
- Refining the logic in `App.tsx` for measuring and utilizing terminal height, including renaming `footerRef` to `mainControlsRef` for clarity.
- Ensuring consistent prop drilling for `isPending` and `availableTerminalHeight` through `HistoryItemDisplay`, `GeminiMessage`, and `GeminiMessageContent`.
- In `MarkdownDisplay`, when `isPending` is true and content exceeds `availableTerminalHeight`, the code block will now be truncated with a "... generating more ..." message. If there's insufficient space even for the
message, a simpler "... code is being written ..." will be shown.
Diffstat (limited to 'packages/cli/src/ui/App.tsx')
| -rw-r--r-- | packages/cli/src/ui/App.tsx | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx index b6275491..e607955a 100644 --- a/packages/cli/src/ui/App.tsx +++ b/packages/cli/src/ui/App.tsx @@ -5,8 +5,9 @@ */ import { useCallback, useEffect, useMemo, useState, useRef } from 'react'; -import { Box, DOMElement, measureElement, Static, Text, useStdout } from 'ink'; +import { Box, DOMElement, measureElement, Static, Text } from 'ink'; import { StreamingState, type HistoryItem } from './types.js'; +import { useTerminalSize } from './hooks/useTerminalSize.js'; import { useGeminiStream } from './hooks/useGeminiStream.js'; import { useLoadingIndicator } from './hooks/useLoadingIndicator.js'; import { useThemeCommand } from './hooks/useThemeCommand.js'; @@ -56,8 +57,7 @@ export const App = ({ const [debugMessage, setDebugMessage] = useState<string>(''); const [showHelp, setShowHelp] = useState<boolean>(false); const [themeError, setThemeError] = useState<string | null>(null); - const [availableTerminalHeight, setAvailableTerminalHeight] = - useState<number>(0); + const [footerHeight, setFooterHeight] = useState<number>(0); const { isThemeDialogOpen, openThemeDialog, @@ -195,26 +195,24 @@ export const App = ({ // --- Render Logic --- - // Get terminal dimensions - - const { stdout } = useStdout(); - const terminalWidth = stdout?.columns ?? 80; - const terminalHeight = stdout?.rows ?? 24; - const footerRef = useRef<DOMElement>(null); + const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize(); + const mainControlsRef = useRef<DOMElement>(null); const pendingHistoryItemRef = useRef<DOMElement>(null); // Calculate width for suggestions, leave some padding const suggestionsWidth = Math.max(60, Math.floor(terminalWidth * 0.8)); useEffect(() => { - const staticExtraHeight = /* margins and padding */ 3; - const fullFooterMeasurement = measureElement(footerRef.current!); - const fullFooterHeight = fullFooterMeasurement.height; + if (mainControlsRef.current) { + const fullFooterMeasurement = measureElement(mainControlsRef.current); + setFooterHeight(fullFooterMeasurement.height); + } + }, [terminalHeight]); // Re-calculate if terminalHeight changes, as it might affect footer's rendered height. - setAvailableTerminalHeight( - terminalHeight - fullFooterHeight - staticExtraHeight, - ); - }, [terminalHeight]); + const availableTerminalHeight = useMemo(() => { + const staticExtraHeight = /* margins and padding */ 3; + return terminalHeight - footerHeight - staticExtraHeight; + }, [terminalHeight, footerHeight]); useEffect(() => { if (!pendingHistoryItem) { @@ -260,7 +258,14 @@ export const App = ({ <Header /> <Tips /> </Box>, - ...history.map((h) => <HistoryItemDisplay availableTerminalHeight={availableTerminalHeight} key={h.id} item={h} />), + ...history.map((h) => ( + <HistoryItemDisplay + availableTerminalHeight={availableTerminalHeight} + key={h.id} + item={h} + isPending={false} + /> + )), ]} > {(item) => item} @@ -272,12 +277,13 @@ export const App = ({ // TODO(taehykim): It seems like references to ids aren't necessary in // HistoryItemDisplay. Refactor later. Use a fake id for now. item={{ ...pendingHistoryItem, id: 0 }} + isPending={true} /> </Box> )} {showHelp && <Help commands={slashCommands} />} - <Box flexDirection="column" ref={footerRef}> + <Box flexDirection="column" ref={mainControlsRef}> {startupWarnings.length > 0 && ( <Box borderStyle="round" |
