fix(app): the hand-over is announced, so the window that held the pen lets go

This commit is contained in:
2026-10-10 17:58:48 +07:00
parent cb9e96dd8d
commit af5f94e94e
+8 -1
View File
@@ -55,6 +55,11 @@ export interface SingleWindow {
export function useSingleWindow(active: boolean): SingleWindow { export function useSingleWindow(active: boolean): SingleWindow {
const id = useRef(Math.random().toString(36).slice(2)); const id = useRef(Math.random().toString(36).slice(2));
const owner = useRef(false); 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<BroadcastChannel | null>(null);
const [held, setHeld] = useState<boolean | null>(null); const [held, setHeld] = useState<boolean | null>(null);
const [taken, setTaken] = useState(false); const [taken, setTaken] = useState(false);
@@ -80,6 +85,7 @@ export function useSingleWindow(active: boolean): SingleWindow {
} catch { } catch {
bus = null; bus = null;
} }
channel.current = bus;
let answered = false; let answered = false;
const onMessage = (e: MessageEvent) => { const onMessage = (e: MessageEvent) => {
@@ -146,11 +152,12 @@ export function useSingleWindow(active: boolean): SingleWindow {
window.removeEventListener('pagehide', leave); window.removeEventListener('pagehide', leave);
bus?.removeEventListener('message', onMessage as EventListener); bus?.removeEventListener('message', onMessage as EventListener);
bus?.close(); bus?.close();
channel.current = null;
}; };
}, [active, claim]); }, [active, claim]);
const take = useCallback(() => { const take = useCallback(() => {
claim(null); claim(channel.current);
setTaken(false); setTaken(false);
setHeld(false); setHeld(false);
}, [claim]); }, [claim]);