mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-15 04:20:57 -07:00
feat(ui): implement true sticky topic header in app layouts
- Relocated TopicStickyHeader from chat history to global AppLayouts (Default and ScreenReader) for permanent viewport stickiness. - Fixed duplication issues by removing complex history injection logic in MainContent.tsx. - Restored natural rendering of topic updates in chat history to ensure consistent scrollback context. - Added persistent styling (background and separator) to TopicStickyHeader for better visual hierarchy. - Simplified MainContent.tsx logic by removing redundant overlay and virtualization hacks. - Updated unit tests and snapshots to align with the new stable layout architecture.
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
||||
type VirtualizedListRef,
|
||||
} from './shared/VirtualizedList.js';
|
||||
import { ScrollableList } from './shared/ScrollableList.js';
|
||||
import { useMemo, memo, useCallback, useEffect, useRef } from 'react';
|
||||
import { useMemo, memo, useEffect, useRef } from 'react';
|
||||
import { MAX_GEMINI_MESSAGE_LINES } from '../constants.js';
|
||||
import { useConfirmingTool } from '../hooks/useConfirmingTool.js';
|
||||
import { ToolConfirmationQueue } from './ToolConfirmationQueue.js';
|
||||
@@ -147,16 +147,6 @@ export const MainContent = () => {
|
||||
],
|
||||
);
|
||||
|
||||
const staticHistoryItems = useMemo(
|
||||
() => historyItems.slice(0, lastUserPromptIndex + 1),
|
||||
[historyItems, lastUserPromptIndex],
|
||||
);
|
||||
|
||||
const lastResponseHistoryItems = useMemo(
|
||||
() => historyItems.slice(lastUserPromptIndex + 1),
|
||||
[historyItems, lastUserPromptIndex],
|
||||
);
|
||||
|
||||
const pendingItems = useMemo(
|
||||
() => (
|
||||
<Box flexDirection="column" key="pending-items-group">
|
||||
@@ -209,31 +199,17 @@ export const MainContent = () => {
|
||||
],
|
||||
);
|
||||
|
||||
const virtualizedData = useMemo(
|
||||
() => [
|
||||
...augmentedHistory.map(
|
||||
({
|
||||
item,
|
||||
isExpandable,
|
||||
isFirstThinking,
|
||||
isFirstAfterThinking,
|
||||
suppressNarration,
|
||||
}) => ({
|
||||
type: 'history' as const,
|
||||
item,
|
||||
isExpandable,
|
||||
isFirstThinking,
|
||||
isFirstAfterThinking,
|
||||
suppressNarration,
|
||||
}),
|
||||
),
|
||||
if (isAlternateBuffer) {
|
||||
const virtualizedData = [
|
||||
...augmentedHistory.map((ah) => ({ type: 'history' as const, ...ah })),
|
||||
{ type: 'pending' as const },
|
||||
],
|
||||
[augmentedHistory],
|
||||
);
|
||||
];
|
||||
|
||||
const renderItem = useCallback(
|
||||
({ item }: { item: (typeof virtualizedData)[number] }) => {
|
||||
const renderItem = ({
|
||||
item,
|
||||
}: {
|
||||
item: (typeof virtualizedData)[number];
|
||||
}) => {
|
||||
if (item.type === 'history') {
|
||||
return (
|
||||
<MemoizedHistoryItemDisplay
|
||||
@@ -257,11 +233,8 @@ export const MainContent = () => {
|
||||
} else {
|
||||
return pendingItems;
|
||||
}
|
||||
},
|
||||
[mainAreaWidth, uiState.slashCommands, pendingItems, uiState.constrainHeight, staticAreaMaxItemHeight]
|
||||
);
|
||||
};
|
||||
|
||||
if (isAlternateBuffer) {
|
||||
return (
|
||||
<ScrollableList
|
||||
ref={scrollableListRef}
|
||||
@@ -280,6 +253,9 @@ export const MainContent = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const staticHistoryItems = historyItems.slice(0, lastUserPromptIndex + 1);
|
||||
const lastResponseHistoryItems = historyItems.slice(lastUserPromptIndex + 1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Static
|
||||
|
||||
Reference in New Issue
Block a user