mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
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.
This commit is contained in:
committed by
N. Taylor Mullen
parent
33743d347b
commit
9c46acc793
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user