feat(ui): user profile hovercard on username hover (LC-298) #327

Merged
longjacksonle merged 1 commit from feat/lc-298-profile-hovercard into main 2026-06-14 22:34:20 +02:00

Summary

Hovering a message author's name shows a small profile hovercard: avatar, display name + @username, bot badge, live status + custom status, bio, and a Message action.

Changes

  • server/src/routes/users.rs: GET /users/{id}/hovercard (auth-gated). Loads the target; bio shown only for public profiles or to self/admin; the Message link (to /dm/{id}) shown only when a DM is permitted (not self; target public or an existing DM exists, via find_dm_room), mirroring routes::dm.
  • server/src/views/hovercard.rs + server/templates/partials/hovercard.html (new): the card fragment (reuses avatar.html at a larger size).
  • server/src/routes/mod.rs, server/src/views/mod.rs: register route + module.
  • server/templates/room/message.html: data-lc-hovercard="{user_id}" on the User-actor author link.
  • server/templates/layout.html: one delegated hover controller (mouseover/mouseout, 350ms open delay, body-appended #lc-hovercard, position + flip/clamp, keep-open-over-card, dismiss on leave/Esc/scroll, no cache).
  • server/locales/{en,es}/partials.ftl: hovercard-message.

Other surfaces (mention chips, sidebar peers) can opt in later by adding the data-lc-hovercard attribute.

Testing

  • just check, just fmt, just test, just test-saas all pass.
  • New server/tests/routes_hovercard.rs (6 tests): public card shows name/username/bio + Message link; private bio hidden from another member but shown to admin; self card has no Message link; unknown id 404; unauth 303.

Not operator-visible (no env/config/contract change).

## Summary Hovering a message author's name shows a small profile hovercard: avatar, display name + @username, bot badge, live status + custom status, bio, and a Message action. ## Changes - `server/src/routes/users.rs`: `GET /users/{id}/hovercard` (auth-gated). Loads the target; bio shown only for public profiles or to self/admin; the Message link (to `/dm/{id}`) shown only when a DM is permitted (not self; target public or an existing DM exists, via `find_dm_room`), mirroring `routes::dm`. - `server/src/views/hovercard.rs` + `server/templates/partials/hovercard.html` (new): the card fragment (reuses `avatar.html` at a larger size). - `server/src/routes/mod.rs`, `server/src/views/mod.rs`: register route + module. - `server/templates/room/message.html`: `data-lc-hovercard="{user_id}"` on the User-actor author link. - `server/templates/layout.html`: one delegated hover controller (mouseover/mouseout, 350ms open delay, body-appended `#lc-hovercard`, position + flip/clamp, keep-open-over-card, dismiss on leave/Esc/scroll, no cache). - `server/locales/{en,es}/partials.ftl`: `hovercard-message`. Other surfaces (mention chips, sidebar peers) can opt in later by adding the `data-lc-hovercard` attribute. ## Testing - `just check`, `just fmt`, `just test`, `just test-saas` all pass. - New `server/tests/routes_hovercard.rs` (6 tests): public card shows name/username/bio + Message link; private bio hidden from another member but shown to admin; self card has no Message link; unknown id 404; unauth 303. Not operator-visible (no env/config/contract change).
feat(ui): user profile hovercard on username hover (LC-298)
All checks were successful
check-secrets / Nosey parker (push) Successful in 3s
check-secrets / TruffleHog (push) Successful in 5s
check-secrets / Kingfisher (push) Successful in 6s
check-secrets / Nosey parker (pull_request) Successful in 7s
check-secrets / Kingfisher (pull_request) Successful in 10s
check-secrets / TruffleHog (pull_request) Successful in 11s
Check / clippy + fmt + tests (pull_request) Successful in 4m57s
Create release / Create release from merged PR (pull_request) Has been skipped
c08f3faad7
Hovering a message author's name now shows a small profile popover: avatar, display name + @username, a bot badge when applicable, live status + custom status, bio, and a Message action.

A new GET /users/{id}/hovercard endpoint (auth-gated) renders the card. Bio is shown only for public profiles, or to the user themselves, or to an admin (matching the search_users privacy posture). The Message link (to /dm/{id}) appears only when a DM is actually permitted: not self, and the target is public or an existing DM already exists, mirroring what routes::dm allows so the button never leads to a rejection.

The trigger is one delegated controller in layout.html (same pattern as the code-copy / spoiler IIFEs): mouseover/mouseout on [data-lc-hovercard], a 350ms open delay, a single body-appended #lc-hovercard popover positioned near the trigger and flipped/clamped to stay on-screen, kept open while the pointer is over the card, dismissed on leave / Esc / scroll. No caching, so status stays fresh. The message-row author link carries the attribute; other surfaces can opt in later by adding it.

#LC-298
#LC-299

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/lc-298-profile-hovercard 2026-06-14 22:34:20 +02:00
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!327
No description provided.