From 40974ddf97919106f7cd5ea85bf10e0fcf3675ff Mon Sep 17 00:00:00 2001 From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com> Date: Wed, 22 Apr 2026 18:30:56 +0800 Subject: [PATCH] fix(chat): disable focus button on pages without an anchor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The focus toggle was only disabled when focusMode was already ON *and* the current page had no anchor. Off-state on the same page stayed clickable — clicking turned it on, and the button instantly greyed out, making the missing fourth state visible. Decouple "clickable" from focusMode: the button is disabled whenever the current page has no anchor, regardless of the persisted on/off preference. Both the chip render (context-anchor.tsx:173) and send path (chat-window.tsx:176) already guard on candidate presence, so leaving focusMode=true on an unanchorable page has no side effects — the preference is preserved for the next anchorable page. Tooltip now reads "Nothing to share with Multica on this page" whenever the button is disabled, regardless of focusMode. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../views/chat/components/context-anchor.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/views/chat/components/context-anchor.tsx b/packages/views/chat/components/context-anchor.tsx index a2e289903..27c4f39c9 100644 --- a/packages/views/chat/components/context-anchor.tsx +++ b/packages/views/chat/components/context-anchor.tsx @@ -109,13 +109,13 @@ export function useRouteAnchorCandidate(wsId: string): { } /** - * Focus-mode toggle. Three visual states driven by two dimensions: - * - focusMode (persisted) on | off - * - candidate present yes | no + * Focus-mode toggle. Disabled whenever the current page has no anchor + * (nothing to share) — focusMode persists across such pages, so returning + * to an anchorable page restores the user's prior on/off choice. * - * off → ghost + muted, clickable (→ turns on) + * no candidate → disabled + * off + candidate → ghost + muted, clickable (→ turns on) * on + candidate → secondary (bright), clickable (→ turns off) - * on + no candidate → disabled (can't click until a focus target exists) */ export function ContextAnchorButton() { const wsId = useWorkspaceId(); @@ -124,16 +124,16 @@ export function ContextAnchorButton() { const setFocusMode = useChatStore((s) => s.setFocusMode); const hasAnchor = !!candidate; - const isDisabled = focusMode && !hasAnchor && !isResolving; + const isDisabled = !hasAnchor && !isResolving; const isBright = focusMode && hasAnchor; - const tooltipText = !focusMode - ? "Let Multica know what you're viewing" - : hasAnchor + const tooltipText = isDisabled + ? "Nothing to share with Multica on this page" + : focusMode && candidate ? candidate.type === "issue" ? `Multica knows you're viewing ${candidate.label} · Click to turn off` : `Multica knows you're viewing project "${candidate.label}" · Click to turn off` - : "Nothing to share with Multica on this page"; + : "Let Multica know what you're viewing"; return (