Fix flicker issues by ensuring all actively changing content fits in the viewport (#1217)

This commit is contained in:
Jacob Richman
2025-06-19 20:17:23 +00:00
committed by GitHub
parent 10a83a6395
commit b0bc7c3d99
22 changed files with 1353 additions and 248 deletions

View File

@@ -115,6 +115,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
const ctrlCTimerRef = useRef<NodeJS.Timeout | null>(null);
const [ctrlDPressedOnce, setCtrlDPressedOnce] = useState(false);
const ctrlDTimerRef = useRef<NodeJS.Timeout | null>(null);
const [constrainHeight, setConstrainHeight] = useState<boolean>(true);
const errorCount = useMemo(
() => consoleMessages.filter((msg) => msg.type === 'error').length,
@@ -217,7 +218,7 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
const widthFraction = 0.9;
const inputWidth = Math.max(
20,
Math.round(terminalWidth * widthFraction) - 3,
Math.floor(terminalWidth * widthFraction) - 3,
);
const suggestionsWidth = Math.max(60, Math.floor(terminalWidth * 0.8));
@@ -279,6 +280,8 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
return;
}
handleExit(ctrlDPressedOnce, setCtrlDPressedOnce, ctrlDTimerRef);
} else if (key.ctrl && input === 's') {
setConstrainHeight((prev) => !prev);
}
});
@@ -393,10 +396,11 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
}
}, [terminalHeight, consoleMessages, showErrorDetails]);
const availableTerminalHeight = useMemo(() => {
const staticExtraHeight = /* margins and padding */ 3;
return terminalHeight - footerHeight - staticExtraHeight;
}, [terminalHeight, footerHeight]);
const staticExtraHeight = /* margins and padding */ 3;
const availableTerminalHeight = useMemo(
() => terminalHeight - footerHeight - staticExtraHeight,
[terminalHeight, footerHeight],
);
useEffect(() => {
if (!pendingHistoryItems.length) {
@@ -445,7 +449,10 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
{quittingMessages.map((item) => (
<HistoryItemDisplay
key={item.id}
availableTerminalHeight={availableTerminalHeight}
availableTerminalHeight={
constrainHeight ? availableTerminalHeight : undefined
}
terminalWidth={terminalWidth}
item={item}
isPending={false}
config={config}
@@ -454,7 +461,11 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
</Box>
);
}
const mainAreaWidth = Math.floor(terminalWidth * 0.9);
const debugConsoleMaxHeight = Math.max(terminalHeight * 0.2, 5);
// Arbitrary threshold to ensure that items in the static area are large
// enough but not too large to make the terminal hard to use.
const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
return (
<StreamingContext.Provider value={streamingState}>
<Box flexDirection="column" marginBottom={1} width="90%">
@@ -479,7 +490,8 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
</Box>,
...history.map((h) => (
<HistoryItemDisplay
availableTerminalHeight={availableTerminalHeight}
terminalWidth={mainAreaWidth}
availableTerminalHeight={staticAreaMaxItemHeight}
key={h.id}
item={h}
isPending={false}
@@ -494,7 +506,10 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
{pendingHistoryItems.map((item, i) => (
<HistoryItemDisplay
key={i}
availableTerminalHeight={availableTerminalHeight}
availableTerminalHeight={
constrainHeight ? availableTerminalHeight : undefined
}
terminalWidth={mainAreaWidth}
// TODO(taehykim): It seems like references to ids aren't necessary in
// HistoryItemDisplay. Refactor later. Use a fake id for now.
item={{ ...item, id: 0 }}
@@ -534,6 +549,12 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
onSelect={handleThemeSelect}
onHighlight={handleThemeHighlight}
settings={settings}
availableTerminalHeight={
constrainHeight
? terminalHeight - staticExtraHeight
: undefined
}
terminalWidth={mainAreaWidth}
/>
</Box>
) : isEditorDialogOpen ? (
@@ -604,7 +625,13 @@ const App = ({ config, settings, startupWarnings = [] }: AppProps) => {
</Box>
{showErrorDetails && (
<DetailedMessagesDisplay messages={filteredConsoleMessages} />
<DetailedMessagesDisplay
messages={filteredConsoleMessages}
maxHeight={
constrainHeight ? debugConsoleMaxHeight : undefined
}
width={inputWidth}
/>
)}
{isInputActive && (