fix(desktop): hydrate Focus Assist on mount; thread-aware toast quick reply
CI / Build & Quality Checks (push) Canceled after 0s
CI / Trigger Desktop Build (push) Canceled after 0s
CI / Secret scan (gitleaks) (push) Canceled after 0s
CI / Docker image build & smoke test (push) Canceled after 0s
CI / Playwright smoke (e2e) (push) Canceled after 0s

- useTauriFocusAssist queries the new `get_focus_assist` command on mount.
  The native poll's first reading is emitted during app setup, before the
  page listens, and the atom resets on every reload — so with Focus Assist
  already on, notifications leaked until the OS state flipped
  (cinny-desktop #15).
- The toast quick reply takes the real `threadId` from the notification
  data and replies inside the thread (cinny-desktop #17).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
Lotus CI
2026-09-23 19:32:42 -04:00
co-authored by Claude Opus 5.5
parent f5ee3c0d0e
commit 3b6de2fdac
2 changed files with 20 additions and 3 deletions
+14 -1
View File
@@ -1,6 +1,7 @@
import { useEffect } from 'react';
import { useSetAtom } from 'jotai';
import { focusAssistActiveAtom } from '../state/focusAssist';
import { useTauriEvent } from './useTauri';
import { tauriInvoke, useTauriEvent } from './useTauri';
/** Detail shape of the `focus-assist-changed` event emitted by the native side. */
type FocusAssistChangedDetail = {
@@ -21,4 +22,16 @@ export function useTauriFocusAssist(): void {
useTauriEvent<FocusAssistChangedDetail>('focus-assist-changed', ({ active }) =>
setFocusAssist(active),
);
// Hydrate on mount. The native poll only emits on a transition, and its first
// reading lands during app setup before this page is listening — so with Focus
// Assist already on at launch (or after a reload) notifications leaked until
// the OS state next flipped (cinny-desktop #15). `null` = no reading yet.
useEffect(() => {
tauriInvoke()?.('get_focus_assist')
.then((active) => {
if (typeof active === 'boolean') setFocusAssist(active);
})
.catch(() => undefined);
}, [setFocusAssist]);
}