feat: message editing and typing indicators (Phase 7 & 8) #6

Merged
longjacksonle merged 21 commits from long-branch into main 2026-04-13 03:36:06 +02:00

Summary

  • Phase 7 — Message Editing: Users can edit their own messages after sending.
    Admins and moderators can edit any message. An (edited) label appears on modified
    messages, and edits propagate in real time over WebSocket.
  • Phase 8 — Typing Indicators: Shows "Alice is typing…" above the composer when
    another user is actively composing a message in the same room or DM. Purely
    ephemeral — no database writes.

Changes

Phase 7 — Message Editing

  • DB migration: adds edited_at TEXT column to messages
  • New edit_message server function — validates ownership (or mod/admin role),
    enforces max_message_length, writes to DB, broadcasts ChatEvent::MessageEdited
    over WebSocket
  • Message model gains edited_at: Option
  • Room view and DM view: inline edit UI on hover (textarea + Save/Cancel),
    (edited) label, WS event handler to refresh on remote edits
  • Integration tests: owner can edit, non-owner is rejected, soft-deleted message
    is rejected, empty/oversized body is rejected

Phase 8 — Typing Indicators

  • New ChatEvent::UserTyping and ChatEvent::UserStoppedTyping server→client events
  • New ClientControl::Typing client→server frame
  • Hub: stores (room_id, user_id) → Instant typing state; broadcasts UserTyping on
    the first keystroke of a new session; spawns a 5s eviction task that sends
    UserStoppedTyping on silence; excludes the sender from their own broadcast
  • WsHandle gains send_typing(room_id)
  • Room view and DM view: debounced typing frame (at most once/sec on oninput),
    Signal<Vec<(user_id, username)>> for currently-typing users, "Alice is typing…"
    label above the composer

Test plan

  • Build passes: just dev-web
  • Edit a message you sent — inline editor appears, save updates in place with
    (edited) label
  • Attempt to edit another user's message — edit button should not appear
  • Open two sessions in different browsers, join the same room — typing in one
    shows indicator in the other; stops after 5s of silence
  • Test typing indicator in a DM conversation
  • Run integration tests: just test
--- Summary - Phase 7 — Message Editing: Users can edit their own messages after sending. Admins and moderators can edit any message. An (edited) label appears on modified messages, and edits propagate in real time over WebSocket. - Phase 8 — Typing Indicators: Shows "Alice is typing…" above the composer when another user is actively composing a message in the same room or DM. Purely ephemeral — no database writes. Changes Phase 7 — Message Editing - DB migration: adds edited_at TEXT column to messages - New edit_message server function — validates ownership (or mod/admin role), enforces max_message_length, writes to DB, broadcasts ChatEvent::MessageEdited over WebSocket - Message model gains edited_at: Option<String> - Room view and DM view: inline edit UI on hover (textarea + Save/Cancel), (edited) label, WS event handler to refresh on remote edits - Integration tests: owner can edit, non-owner is rejected, soft-deleted message is rejected, empty/oversized body is rejected Phase 8 — Typing Indicators - New ChatEvent::UserTyping and ChatEvent::UserStoppedTyping server→client events - New ClientControl::Typing client→server frame - Hub: stores (room_id, user_id) → Instant typing state; broadcasts UserTyping on the first keystroke of a new session; spawns a 5s eviction task that sends UserStoppedTyping on silence; excludes the sender from their own broadcast - WsHandle gains send_typing(room_id) - Room view and DM view: debounced typing frame (at most once/sec on oninput), Signal<Vec<(user_id, username)>> for currently-typing users, "Alice is typing…" label above the composer Test plan - Build passes: just dev-web - Edit a message you sent — inline editor appears, save updates in place with (edited) label - Attempt to edit another user's message — edit button should not appear - Open two sessions in different browsers, join the same room — typing in one shows indicator in the other; stops after 5s of silence - Test typing indicator in a DM conversation - Run integration tests: just test
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!6
No description provided.