feat(ui): mark a conversation unread from a message (LC-286) #321
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-286-mark-unread"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Adds a "Mark unread" hover action - the inverse of "mark all read" (LC-250) and per-room read (LC-258). It rewinds the room's read watermark to just before the chosen message, so that message and everything after it count as unread again and the sidebar badge reappears. Useful for triage ("I'll deal with this later").
How
upsert_dm_readkeepsMAX(...)), so it cannot rewind. Newdb::chat::rewind_dm_readis an unconditional upsert that can move the watermark backward;set_last_read/ the read paths stay advance-only (mark-read still can't be clobbered by a stale lower value).POST /messages/{id}/unread(routes::read_all::post_message_unread): look up the message (404 if missing),is_room_accessiblegate (403), set the watermark tomax(0, id - 1)soget_unread_count'sid > watermarkre-raises this message and newer; broadcastReadAllChanged(live sidebar refresh across tabs); return the re-rendered sidebar.message.html: a "Mark unread" button in the hover menu (hx-post, targets#sidebar). Strings in en + es.Re-flagging the room's mentions as unread is out of scope for v1 (mentions have their own read state); this rewinds the message watermark. The four LC-77 fixtures are regenerated for the new button (diff is exactly that button, purely additive). No new env. Not operator-visible.
Tests
routes_read_all: marking a read message unread raisesget_unread_count; the access gate 403s a non-member on a private room; a missing message 404s.just testandjust test-saaspass.QA note
Worth a manual pass: in a room you've read, hover an older message and "Mark unread" - the sidebar badge for that room reappears and updates in another open tab; navigate away and back and the room re-clears on open (expected, Slack-style). Confirm it's gated on rooms you can't access.
Adds a "Mark unread" hover action - the inverse of the LC-250/LC-258 read paths. It rewinds the room's read watermark to just before the chosen message, so that message and everything after it count as unread again and the sidebar badge reappears (for later triage). The existing watermark setter only advances (upsert_dm_read keeps MAX), so this adds db::chat::rewind_dm_read, an unconditional upsert that can move the watermark backward; the read paths stay advance-only. POST /messages/{id}/unread (routes::read_all) looks up the message (404), gates on is_room_accessible (403), sets the watermark to max(0, id-1), broadcasts ReadAllChanged (live sidebar refresh across tabs), and returns the re-rendered sidebar. The hover button targets #sidebar. Strings localized in en + es. The four LC-77 fixtures are regenerated for the new button (diff is exactly that button, purely additive). Tests cover the rewind (unread count rises), the access gate (403), and missing message (404). #LC-286 #LC-287 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>