Composer drafts are lost on page reload (only written on unmount) #37

Closed
opened 2026-09-12 01:51:06 -04:00 by jared · 0 comments
Owner

Severity: medium · Type: bug · Confidence: high

Location: src/app/features/room/RoomInput.tsx:412-425 (unmount-only persist), src/app/hooks/useHydrateMsgDrafts.ts, LOTUS_FEATURES.md:736-741

Problem

The only writer of draft-msg-<key> is the effect cleanup, which React runs on unmount / draftKey change. There is no pagehide/beforeunload/debounced save anywhere in the app (grep for beforeunload returns nothing). So a draft typed in the currently-open room and never navigated away from is lost on refresh, tab close, or crash — even though useHydrateMsgDrafts exists specifically to rehydrate drafts "after a reload". The composer's own DraftIndicator also stays hidden for the open room for the same reason (the atom is only written on leave), so the "Draft saved" affordance never appears while you are actually typing.

How to trigger

Type a message in a room, press F5 without switching rooms — the draft is gone.

Suggested fix

Add a debounced (or pagehide/visibilitychange-triggered) write of editor.children to the atom + localStorage while typing, reusing the existing cleanup serialization.


Filed from the September 2026 client audit (branch lotus @ 4bea4895).

**Severity:** medium · **Type:** bug · **Confidence:** high **Location:** `src/app/features/room/RoomInput.tsx:412-425` (unmount-only persist), `src/app/hooks/useHydrateMsgDrafts.ts`, `LOTUS_FEATURES.md:736-741` ### Problem The only writer of `draft-msg-<key>` is the effect **cleanup**, which React runs on unmount / `draftKey` change. There is no `pagehide`/`beforeunload`/debounced save anywhere in the app (grep for `beforeunload` returns nothing). So a draft typed in the currently-open room and never navigated away from is lost on refresh, tab close, or crash — even though `useHydrateMsgDrafts` exists specifically to rehydrate drafts "after a reload". The composer's own `DraftIndicator` also stays hidden for the open room for the same reason (the atom is only written on leave), so the "Draft saved" affordance never appears while you are actually typing. ### How to trigger Type a message in a room, press F5 without switching rooms — the draft is gone. ### Suggested fix Add a debounced (or `pagehide`/`visibilitychange`-triggered) write of `editor.children` to the atom + localStorage while typing, reusing the existing cleanup serialization. --- _Filed from the September 2026 client audit (branch `lotus` @ 4bea4895)._
jared added this to the Audit 2026-09 · Medium & Low milestone 2026-09-12 01:51:06 -04:00
jared added the bugpriority: mediumarea: messaging labels 2026-09-12 01:51:06 -04:00
jared self-assigned this 2026-09-12 01:51:06 -04:00
jared closed this issue 2026-09-15 21:32:09 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
2026-11-14
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#37