feat(ui): enable TimelineDialog with full-text search across all message roles in one session (#1104)

* feat: register open_timeline_dialog shortcut (mod+t)

* feat: enhance TimelineDialog with full-text search across all roles

* feat: add open_timeline_dialog shortcut labels to all locales

* feat: wire TimelineDialog into ChatContainer

* fix: add setTimelineDialogOpen to hook dependency array

* fix: tighten timeline dialog interactions

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
jwcrystal
2026-05-05 11:21:06 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 495b9d56d2
commit 63b4a5b996
18 changed files with 175 additions and 35 deletions
@@ -14,6 +14,7 @@ import ScrollToBottomButton from './components/ScrollToBottomButton';
import { ScrollShadow } from '@/components/ui/ScrollShadow';
import { useChatScrollManager, type AnimationHandlers, type ContentChangeReason } from '@/hooks/useChatScrollManager';
import { useChatTimelineController } from './hooks/useChatTimelineController';
import { TimelineDialog } from './TimelineDialog';
import { useChatTurnNavigation } from './hooks/useChatTurnNavigation';
import { useDeviceInfo } from '@/lib/device';
import { Button } from '@/components/ui/button';
@@ -342,6 +343,8 @@ export const ChatContainer: React.FC = () => {
const isExpandedInput = useUIStore((state) => state.isExpandedInput);
const stickyUserHeader = useUIStore((state) => state.stickyUserHeader);
const chatRenderMode = useUIStore((state) => state.chatRenderMode);
const isTimelineDialogOpen = useUIStore((s) => s.isTimelineDialogOpen);
const setTimelineDialogOpen = useUIStore((s) => s.setTimelineDialogOpen);
// Streaming state
const streamingMessageId = useStreamingStore(
@@ -958,19 +961,27 @@ export const ChatContainer: React.FC = () => {
<div
className={cn(
'relative z-10',
isDesktopExpandedInput
? 'flex-1 min-h-0 bg-background'
: 'bg-background'
)}
>
{!isDesktopExpandedInput && sessionMessages.length > 0 && (
<ScrollToBottomButton
isDesktopExpandedInput
? 'flex-1 min-h-0 bg-background'
: 'bg-background'
)}
>
{!isDesktopExpandedInput && sessionMessages.length > 0 && (
<ScrollToBottomButton
visible={timelineController.showScrollToBottom}
onClick={navigation.resumeToLatest}
/>
)}
<ChatInput scrollToBottom={resumeToLatestInstant} />
</div>
<TimelineDialog
open={isTimelineDialogOpen}
onOpenChange={setTimelineDialogOpen}
onScrollToMessage={timelineController.scrollToMessage}
onScrollByTurnOffset={navigation.scrollByTurnOffset}
onResumeToLatest={resumeToLatestInstant}
/>
</div>
);
};