The tray only knew what this browser had scheduled (localStorage), but
Synapse lists every pending one via MSC4140 GET /delayed_events. Load it
when the tray mounts and on window focus (localStorage stays as a first-
paint cache), keeping only non-state m.room.message events. Logout now
says "N scheduled messages still send after you log out" and offers to
cancel them.
Fixes#322
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
- scheduledMessages.test.ts (9): pins the MSC4140 request shape (PUT to the room
send endpoint with the org.matrix.msc4140.delay query, POST cancel/restart to
/delayed_events with the unstable prefix), the delay-floor math (Math.max(1000,
round(sendAt-now)) — "now"/past targets still yield a valid >=1000ms delay),
rounding, and url-encoding.
- lotusDenoiseUtils.test.ts (9): model-catalog data integrity + isMLDenoiseSupported
feature detection across AudioContext/webkit/getUserMedia.
- Bug found + fixed: isMLDenoiseSupported used `!!AudioWorkletNode`, a bare global
reference that throws ReferenceError (not returns false) on a browser with
AudioContext but no AudioWorkletNode binding. Switched to `typeof` so the
detection helper reports unsupported instead of throwing. Regression test proven
to fail on the old code.
Suite now 545 tests (4th real bug caught by the prevention work).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>