feat/mentions-notifications #52

Merged
longjacksonle merged 9 commits from feat/mentions-notifications into main 2026-05-06 21:27:37 +02:00
No description provided.
Stop tracking .claude/settings.local.json so per-developer Claude Code allowlist tweaks stay local. Also pulls in the regex crate (and updates phf 0.10 -> 0.11) for upcoming server-side pattern matching.
Move the Phase 13 upload plan into docs/superpowers/plans/, mark Phase 13
as done in TODO.md, add the detailed Phase 14 (@mentions + notifications)
implementation plan, and add the regex crate dependency required by the
upcoming mention-token parser.
Add the server-side logic for @mention support across rooms, DMs, and edits:

- Extend all `SELECT` queries for `UserRecord` / `User` to include `notify_browser_enabled` and `notify_sound_enabled`; add `set_notification_prefs` and `list_user_ids` helpers to `db::auth`.
- New `db::mentions` module: `parse_mention_tokens` (regex, deduped), `reconcile_mentions` (diff-based insert/delete preserving `read_at`), `mentions_for_messages` (bulk load with auth cross-pool lookup), `mark_mentions_read_for_room`, `count_unread_mentions_per_room`, and `delete_mentions_for_message`.
- `routes::mentions`: `GET /users/mentions?room_id=&q=` autocomplete endpoint that resolves candidate user IDs from room members, enclave members, or all users depending on room type.
- `routes::room::post_message`: extract tokens, resolve against candidate set, call `reconcile_mentions`, and broadcast `ChatEvent::Mentioned` to each newly-mentioned user; DMs get an implicit mention event without a DB row.
- `routes::room::patch_message`: same reconcile-and-fan-out on edit, plus `ChatEvent::MentionCleared` for users whose mention was removed.
- `routes::room::delete_message`: drop mention rows and broadcast `MentionCleared` before the soft-delete.
- `load_sidebar`: include per-room unread mention counts in `SidebarRoom`.
- `MessageView` gains a `mentions` field populated in every render path (room page, single message, thread panel, DM view).
Add the client-facing half of the mention system:

- `render_body()` replaces `linkify_body()` as the HTML renderer for message bodies. It matches `@username` tokens against resolved `MentionRef` rows (already fetched by the DB layer) and emits styled anchor chips; unresolved tokens and URL linkification are handled by the existing `linkify_body()` fallback.
- `MessageView` gains a `mentions` field populated in all three WS render paths (new message, edited message, thread reply).
- `ChatEvent::Mentioned` and `ChatEvent::MentionCleared` are added to the event enum and routed in the WebSocket handler. Dedicated `render_mentioned` / `render_mention_cleared` fns materialise `MentionedFragment` and `MentionClearedFragment` templates (backed by new Askama structs in `ws_fragments.rs`).
- `SidebarRoom` gains a `mentions` count for the upcoming `@N` badge in the sidebar partial.
- `views/mentions.rs` is added for the autocomplete popover view struct and template binding.
- Settings form gains `notify_browser_enabled` and `notify_sound_enabled` fields, persisted via `db::auth::set_notification_prefs`.
- When the active user is the DM viewer, `render_new_message_or_bump` marks mention rows read for the room.
- Unit tests cover chip rendering, unknown-token pass-through, and email-address non-match.
Wire up the hidden DOM bus (`lc-notify-bus`) so incoming `mentioned` and
`mention_cleared` WS frames drive title-bar counts, favicon dot toggling,
sidebar `@N` badge repaints, browser Notification API pop-ups, and the
notification sound - all without page reloads.

Add a `@username` autocomplete popover in the composer that fires an HTMX
request to `/users/mentions` on every keystroke after `@`, renders the
`mention_popover.html` partial, and supports keyboard navigation (arrows,
Enter/Tab to insert, Escape to dismiss).

Add `notify_browser_enabled` and `notify_sound_enabled` checkboxes to the
settings page, and emit them into `lc-mention-counts` so the notification
script picks up the user's preferences server-side.

Add `mention_badge.html` partial rendered in the sidebar next to the unread
badge, and the `mentioned.html` / `mention_cleared.html` WS partials that
feed the bus via `hx-swap-oob`.
Add the notification_settings auth migration and the mentions chat migration to every test setup function that was missing them, and add a new db_mentions.rs integration test file covering parse, reconcile, watermark, cross-pool username resolution, and delete behaviour.
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!52
No description provided.