fix(state): correct invite re-notify, status clear sync, soundboard resync (DP2/DP3/DP5)

- Invites: seed the notify baseline with the invite count at mount instead
  of 0, so a warm reload (allInvitesAtom populates synchronously from cache
  while SYNCING) no longer re-fires the toast+sound for pre-existing invites.
  Only a genuine increase notifies.
- Status: the cross-device sync effect gated on a truthy presence.status, so
  a remote CLEAR never reset the input or localStorage[STATUS_MSG_KEY] and
  usePresenceUpdater.readStatus() re-sent the stale status. Now mirror an
  empty status as a clear (skipping offline/invisible, which carries an empty
  status_msg by design).
- Soundboard: useState initializers ran once and never recomputed when the
  room/rooms arg changed. Add a resync effect keyed on the arg while keeping
  the live state-event update path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 22:29:47 -04:00
parent 8eb961b682
commit db86432644
3 changed files with 44 additions and 8 deletions
+6 -1
View File
@@ -134,7 +134,12 @@ function FaviconUpdater() {
function InviteNotifications() {
const audioRef = useRef<HTMLAudioElement>(null);
const invites = useAtomValue(allInvitesAtom);
const perviousInviteLen = usePreviousValue(invites.length, 0);
// Seed the baseline with the invite count present at mount, NOT 0. allInvitesAtom
// populates synchronously from cache on a warm reload while sync is already
// SYNCING, so a 0 seed made every pre-existing invite look "new" and re-fired the
// toast+sound on each reload. Starting from the current length means only a
// genuine INCREASE (a newly-arrived invite) notifies.
const perviousInviteLen = usePreviousValue(invites.length, invites.length);
const mx = useMatrixClient();
const navigate = useNavigate();