- Read states store: smarter hasUnread compares against latest message
- ConversationList: orange dot + bold name for unread DMs
- DMChat: auto-mark-read when viewing conversation
- WS handler: mark DM read on new message while active+focused
The notification bell and settings gear spans had opacity-0 but
pointer-events were still active. Their stopPropagation handlers
prevented the parent button's onClick from firing when clicking
in the icon area. Added pointer-events-none to the container,
re-enabled on group-hover.
Invalid HTML: <button> inside <button> causes the browser to close
the outer button prematurely, so clicking the channel name never
fires setActiveChannel. Changed inner elements to <span role=button>.
- Input field no longer nested inside a button/clickable div
- Snapshot state before clearing editing mode to avoid stale closures
- Log errors instead of silently swallowing them
ContextMenu: reusable hook-based component that positions a menu at
the cursor and auto-closes on outside click or Escape.
ChannelList:
- Right-click channel -> Edit Name, Permissions, Delete Channel
- Right-click group header -> Edit Name, Create Channel Here, Delete Group
- Inline rename: replacing name text with an input, commits on Enter/blur
- CreateChannelModal now accepts defaultGroupId to pre-select a group
ServerBar:
- Right-click server icon -> Server Settings, Invite People, Leave Server
- Leave calls DELETE /servers/{id}/members/me
Backend:
- Added LeaveServer handler (DELETE /servers/{serverID}/members/me)
- Server owner cannot leave; must transfer or delete
Phase 7.1 — Per-channel notification settings
- New notification_settings table (user_id, channel_id, level)
- GET/PUT/DELETE handlers under /channels/{channelID}/notifications
- Push dispatch and @mention loops filtered by notification level
- Frontend: bell icon per channel cycling all/mentions/none
Phase 7.4 — Read receipts
- New read_states table (user_id, channel_id, last_read_message_id)
- PUT /channels/{channelID}/read and GET /users/me/read-states
- Auto-mark-read when messages load in ChatArea
- Unread dot for channels never opened
Also: favicon/icon refresh in index.html
Frontend:
- Settings link in header next to logout
- [+] button to create server (name + optional icon)
- [#] button to join server via invite code
- [+] button to create channel (name, type, category)
- Server name shown instead of UUID in channel list header
- /invites/:code route wired for JoinServer component
Backend:
- Wire role CRUD + member-role assignment routes (MANAGE_SERVER gated)
- Seed @everyone default role on server creation