From af5f94e94e24c07b131ec75fafcfcfc155fc3af7 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Sat, 10 Oct 2026 17:58:48 +0700 Subject: [PATCH] fix(app): the hand-over is announced, so the window that held the pen lets go --- docker/frontend/src/ui/SingleTab.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docker/frontend/src/ui/SingleTab.tsx b/docker/frontend/src/ui/SingleTab.tsx index 7c2a937..dde368b 100644 --- a/docker/frontend/src/ui/SingleTab.tsx +++ b/docker/frontend/src/ui/SingleTab.tsx @@ -55,6 +55,11 @@ export interface SingleWindow { export function useSingleWindow(active: boolean): SingleWindow { const id = useRef(Math.random().toString(36).slice(2)); const owner = useRef(false); + // The line to the window that held the pen. It is not the effect's own `bus`: + // `take` runs from a press, long after the effect that opened the channel, and a + // hand-over that is not announced leaves the other window still writing the + // record and still believing the library is its own. + const channel = useRef(null); const [held, setHeld] = useState(null); const [taken, setTaken] = useState(false); @@ -80,6 +85,7 @@ export function useSingleWindow(active: boolean): SingleWindow { } catch { bus = null; } + channel.current = bus; let answered = false; const onMessage = (e: MessageEvent) => { @@ -146,11 +152,12 @@ export function useSingleWindow(active: boolean): SingleWindow { window.removeEventListener('pagehide', leave); bus?.removeEventListener('message', onMessage as EventListener); bus?.close(); + channel.current = null; }; }, [active, claim]); const take = useCallback(() => { - claim(null); + claim(channel.current); setTaken(false); setHeld(false); }, [claim]);