-
Notifications
You must be signed in to change notification settings - Fork 0
Studio: Fix empty chat threads on navigation and stabilize new chat flow #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7f9bbe7
e379b51
ec74cbc
f977819
74e74f5
cb41fc0
3a4c26d
ce90347
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,6 +22,7 @@ import { | |||||||||||||||||||||||||||||||||||||
| } from "@hugeicons/core-free-icons"; | ||||||||||||||||||||||||||||||||||||||
| import { HugeiconsIcon } from "@hugeicons/react"; | ||||||||||||||||||||||||||||||||||||||
| import { db, useLiveQuery } from "./db"; | ||||||||||||||||||||||||||||||||||||||
| import { useChatRuntimeStore } from "./stores/chat-runtime-store"; | ||||||||||||||||||||||||||||||||||||||
| import type { ChatView, ThreadRecord } from "./types"; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| interface SidebarItem { | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -76,12 +77,17 @@ export function ThreadSidebar({ | |||||||||||||||||||||||||||||||||||||
| onNewCompare: () => void; | ||||||||||||||||||||||||||||||||||||||
| showCompare: boolean; | ||||||||||||||||||||||||||||||||||||||
| }) { | ||||||||||||||||||||||||||||||||||||||
| const allThreads = useLiveQuery( | ||||||||||||||||||||||||||||||||||||||
| () => db.threads.orderBy("createdAt").reverse().toArray(), | ||||||||||||||||||||||||||||||||||||||
| [], | ||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||
| const allThreads = useLiveQuery(async () => { | ||||||||||||||||||||||||||||||||||||||
| const threadIdsWithMessage = new Set( | ||||||||||||||||||||||||||||||||||||||
| (await db.messages.orderBy("threadId").uniqueKeys()) as string[], | ||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||
| const rows = await db.threads.orderBy("createdAt").reverse().toArray(); | ||||||||||||||||||||||||||||||||||||||
| return rows.filter((t) => !t.archived && threadIdsWithMessage.has(t.id)); | ||||||||||||||||||||||||||||||||||||||
| }, []); | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+80
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Consider adding a
Comment on lines
+80
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation of
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| const items = groupThreads(allThreads ?? []); | ||||||||||||||||||||||||||||||||||||||
| const activeId = view.mode === "single" ? view.threadId : view.pairId; | ||||||||||||||||||||||||||||||||||||||
| const storeThreadId = useChatRuntimeStore((s) => s.activeThreadId); | ||||||||||||||||||||||||||||||||||||||
| const activeId = | ||||||||||||||||||||||||||||||||||||||
| view.mode === "single" ? (view.threadId ?? storeThreadId) : view.pairId; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| function viewForItem(item: SidebarItem): ChatView { | ||||||||||||||||||||||||||||||||||||||
| return item.type === "single" | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -101,7 +107,11 @@ export function ThreadSidebar({ | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| if (activeId === item.id) { | ||||||||||||||||||||||||||||||||||||||
| onSelect({ mode: "single" }); | ||||||||||||||||||||||||||||||||||||||
| // Directly set a new view with a nonce rather than going through | ||||||||||||||||||||||||||||||||||||||
| // onNewThread(), which may return early if the guard sees no | ||||||||||||||||||||||||||||||||||||||
| // threadId and no activeThreadId (after we just cleared it). | ||||||||||||||||||||||||||||||||||||||
| useChatRuntimeStore.getState().setActiveThreadId(null); | ||||||||||||||||||||||||||||||||||||||
| onSelect({ mode: "single", newThreadNonce: crypto.randomUUID() }); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The guard added to
handleNewThreadprevents the "New Chat" action from resetting the composer state if the user is already on an unsaved draft (i.e., no messages sent yet). This means clicking "New Chat" won't clear any typed text or attachments in the current draft, which is a regression in user experience.Since new threads are no longer persisted until the first message is sent (as per the changes in
runtime-provider.tsx), there is no risk of cluttering the database with empty threads by allowing the state to reset. Removing this guard ensures that the "New Chat" button always provides a fresh start as expected.