feat: persist scroll position per conversation tab

- Added scrollPosition to Conversation interface
- Save scroll position when switching away from a tab
- Restore exact scroll position when switching back
- Uses -1 to indicate auto-scroll mode (scroll to bottom)
- Prevents interference between scroll restore and auto-scroll
This commit is contained in:
2026-01-23 14:57:06 -08:00
committed by Naomi Carrigan
parent 371e4efde3
commit c088dc0096
3 changed files with 59 additions and 3 deletions
+20
View File
@@ -21,6 +21,7 @@ export interface Conversation {
grantedTools: Set<string>;
pendingPermission: PermissionRequest | null;
pendingQuestion: UserQuestionEvent | null;
scrollPosition: number;
createdAt: Date;
lastActivityAt: Date;
}
@@ -55,6 +56,7 @@ function createConversationsStore() {
grantedTools: new Set(),
pendingPermission: null,
pendingQuestion: null,
scrollPosition: -1, // -1 means "scroll to bottom" (auto-scroll)
createdAt: new Date(),
lastActivityAt: new Date(),
};
@@ -106,6 +108,7 @@ function createConversationsStore() {
($conv) => $conv?.pendingPermission || null
);
const pendingQuestion = derived(activeConversation, ($conv) => $conv?.pendingQuestion || null);
const scrollPosition = derived(activeConversation, ($conv) => $conv?.scrollPosition ?? -1);
return {
// Expose derived stores for compatibility
@@ -118,6 +121,7 @@ function createConversationsStore() {
isProcessing: { subscribe: isProcessing.subscribe },
grantedTools: { subscribe: grantedTools.subscribe },
pendingRetryMessage: { subscribe: pendingRetryMessage.subscribe },
scrollPosition: { subscribe: scrollPosition.subscribe },
// New conversation-specific stores
conversations: { subscribe: conversations.subscribe },
@@ -325,6 +329,22 @@ function createConversationsStore() {
});
},
saveScrollPosition: (id: string, position: number) => {
conversations.update((convs) => {
const conv = convs.get(id);
if (conv) {
conv.scrollPosition = position;
}
return convs;
});
},
getScrollPosition: (id: string): number => {
const convs = get(conversations);
const conv = convs.get(id);
return conv?.scrollPosition ?? -1;
},
// Methods that operate on the active conversation
setSessionId: (id: string | null) => {
ensureInitialized();