From c64d7f315ea3d1898837d30fee817679df79d721 Mon Sep 17 00:00:00 2001 From: claude code agent 227 Date: Fri, 26 Jun 2026 17:17:17 +0300 Subject: [PATCH] fix(ai-chat): open chat window before resolving the bound chat (#191) Address PR #209 review. - use-open-ai-chat.ts: call setWindowOpen(true) before awaiting getBoundChat so the header button feels instant on slow connections; the chat switch (setActiveChatId/setDraft/setSelectedRoleId) is applied after the round-trip resolves. Also drop the redundant no-op setWindowOpen(true) in the already-open branch (bare early return). - CHANGELOG.md: document the header AI-chat button auto-opening the latest chat bound to the current document under [Unreleased]/Added. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 7 +++++++ .../features/ai-chat/hooks/use-open-ai-chat.ts | 16 +++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f154a7..0917bdd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,6 +97,13 @@ per-workspace rolling-day token budget. applies it through the existing `/pages/update` route — reflecting it in the title field and broadcasting to other clients. Gated by the `settings.ai.generative` flag and throttled per user. (#199) +- **AI chat: header button auto-opens the chat bound to the current document.** + Clicking the AI-chat button in the header while viewing a page now reopens the + latest chat tied to that document instead of whatever chat was last active, + reusing the existing `ai_chats.page_id` provenance (no migration). The newest + chat you created on the page wins; with no bound chat — or off a page, or if + the lookup fails — it falls soft to a fresh chat and keeps the current + selection otherwise. (#191) ### Changed diff --git a/apps/client/src/features/ai-chat/hooks/use-open-ai-chat.ts b/apps/client/src/features/ai-chat/hooks/use-open-ai-chat.ts index 2592194b..604299c5 100644 --- a/apps/client/src/features/ai-chat/hooks/use-open-ai-chat.ts +++ b/apps/client/src/features/ai-chat/hooks/use-open-ai-chat.ts @@ -32,11 +32,13 @@ export function useOpenAiChatForCurrentPage() { return useCallback(async () => { // Re-clicks while the window is already open (incl. minimized) must NOT // re-resolve and yank the user to another chat: resolve only on a genuine - // closed -> open transition. - if (windowOpen) { - setWindowOpen(true); - return; - } + // closed -> open transition. (`windowOpen` is already true here, so there + // is nothing to set — just bail.) + if (windowOpen) return; + // Open the window FIRST so the control feels instant: the bound-chat + // round-trip below must never gate the window appearing, or on a slow + // connection the first click reads as a hung control until the POST returns. + setWindowOpen(true); let resolved: string | null = activeChatId; // off-a-page: keep current if (pageId) { try { @@ -46,13 +48,13 @@ export function useOpenAiChatForCurrentPage() { } } // Clear the composer draft / picked role ONLY on an actual switch, so - // reopening the same chat does not wipe an in-progress draft. + // reopening the same chat does not wipe an in-progress draft. Applied after + // the resolve so the window is already visible while the switch settles. if (resolved !== activeChatId) { setActiveChatId(resolved); setDraft(""); setSelectedRoleId(null); } - setWindowOpen(true); }, [ windowOpen, activeChatId,