fix: restore ArrowUp caret movement and clean up virtual list lints
ArrowUp in chat input now moves caret instead of recalling history when the field has text Removed manual cache-busting workaround and eslint-disable in favor of idiomatic onChange state sync
This commit is contained in:
@@ -2335,12 +2335,11 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle ArrowUp/ArrowDown for message history navigation
|
// Handle ArrowUp/ArrowDown for message history navigation
|
||||||
// ArrowUp: only when cursor at start (position 0) or input is empty
|
// ArrowUp: only when input is empty (so pressing Up at start of text just moves cursor)
|
||||||
// ArrowDown: also works when cursor at end (to cycle forward through history)
|
// ArrowDown: also works when cursor at end (to cycle forward through history)
|
||||||
const isAnyAutocompleteOpen = showCommandAutocomplete || showSkillAutocomplete || showSnippetAutocomplete || showFileMention;
|
const isAnyAutocompleteOpen = showCommandAutocomplete || showSkillAutocomplete || showSnippetAutocomplete || showFileMention;
|
||||||
const cursorAtStart = textareaRef.current?.selectionStart === 0 && textareaRef.current?.selectionEnd === 0;
|
|
||||||
const cursorAtEnd = textareaRef.current?.selectionStart === message.length && textareaRef.current?.selectionEnd === message.length;
|
const cursorAtEnd = textareaRef.current?.selectionStart === message.length && textareaRef.current?.selectionEnd === message.length;
|
||||||
const canNavigateHistoryUp = !isAnyAutocompleteOpen && (message.length === 0 || cursorAtStart);
|
const canNavigateHistoryUp = !isAnyAutocompleteOpen && message.length === 0;
|
||||||
const canNavigateHistoryDown = !isAnyAutocompleteOpen && (message.length === 0 || cursorAtEnd);
|
const canNavigateHistoryDown = !isAnyAutocompleteOpen && (message.length === 0 || cursorAtEnd);
|
||||||
|
|
||||||
// Markdown-aware auto-pairing (source mode), normal input only.
|
// Markdown-aware auto-pairing (source mode), normal input only.
|
||||||
|
|||||||
@@ -1372,7 +1372,7 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
|
|||||||
scrollEl.scrollTop += prependedHeight;
|
scrollEl.scrollTop += prependedHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
const [virtualVersion, bumpVirtualVersion] = React.useReducer((v: number) => v + 1, 0);
|
const [historyVirtualRows, setHistoryVirtualRows] = React.useState<VirtualItem[]>(EMPTY_VIRTUAL_ROWS);
|
||||||
|
|
||||||
const historyVirtualizer = useVirtualizer({
|
const historyVirtualizer = useVirtualizer({
|
||||||
count: historyEntries.length,
|
count: historyEntries.length,
|
||||||
@@ -1383,7 +1383,9 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
|
|||||||
useAnimationFrameWithResizeObserver: true,
|
useAnimationFrameWithResizeObserver: true,
|
||||||
overscan: MESSAGE_LIST_OVERSCAN,
|
overscan: MESSAGE_LIST_OVERSCAN,
|
||||||
enabled: shouldVirtualizeHistory,
|
enabled: shouldVirtualizeHistory,
|
||||||
onChange: bumpVirtualVersion,
|
onChange: () => {
|
||||||
|
setHistoryVirtualRows(historyVirtualizer.getVirtualItems());
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
React.useLayoutEffect(() => {
|
React.useLayoutEffect(() => {
|
||||||
@@ -1438,10 +1440,13 @@ const MessageList = React.forwardRef<MessageListHandle, MessageListProps>(({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const historyVirtualRows = React.useMemo(
|
// Sync virtual rows on initial mount and when virtualization toggles.
|
||||||
() => (shouldVirtualizeHistory ? historyVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ROWS),
|
// Ongoing updates are handled by the virtualizer's onChange callback.
|
||||||
[historyVirtualizer, shouldVirtualizeHistory, virtualVersion],
|
React.useLayoutEffect(() => {
|
||||||
);
|
setHistoryVirtualRows(
|
||||||
|
shouldVirtualizeHistory ? historyVirtualizer.getVirtualItems() : EMPTY_VIRTUAL_ROWS,
|
||||||
|
);
|
||||||
|
}, [shouldVirtualizeHistory, historyVirtualizer]);
|
||||||
|
|
||||||
const allEntries = React.useMemo(() => {
|
const allEntries = React.useMemo(() => {
|
||||||
return trailingStreamingEntry ? [...historyEntries, trailingStreamingEntry] : historyEntries;
|
return trailingStreamingEntry ? [...historyEntries, trailingStreamingEntry] : historyEntries;
|
||||||
|
|||||||
Reference in New Issue
Block a user