docs: document who reacted, sticker/emoji panel, pinned messages, custom status

Add proper README entries for four features that were implemented but
undocumented or only mentioned incidentally:
- Emoji & sticker picker in composer (sends m.sticker via mx.sendEvent)
- Pinned messages panel (header icon + context menu pin/unpin)
- Who reacted: hover tooltip + right-click ReactionViewer modal
- Custom status message: emoji picker, auto-clear timer, 64-char limit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 23:06:59 -04:00
parent 8e3acf8d00
commit 5435741d42
+5
View File
@@ -70,6 +70,8 @@ A full custom theme engine layered on top of Cinny's vanilla-extract theming:
### Messaging Enhancements
- **GIF picker**: Giphy-powered GIF search and send. Button appears in the message composer only when `gifApiKey` is set in `config.json`. Sends GIF as `m.image` — fetches blob, uploads via `mx.uploadContent`, sends with `mx.sendMessage`. `FocusTrap` handles click-outside / Escape to close. When TDS is active: dark navy background (`#060c14`), orange dim border, `// GIF_SEARCH` header, CSS overrides for Giphy SDK search bar (dark bg, orange border/focus ring, JetBrains Mono), custom orange scrollbar. All TDS styles live in `lotus-terminal.css.ts` — no runtime `<style>` injection, eliminating flash of unstyled content.
- **Emoji & sticker picker**: The message composer toolbar includes a unified emoji/sticker board (`EmojiBoard`). The emoji tab sends inline emoji or custom emoji from loaded packs. The sticker tab (`EmojiBoardTab.Sticker`) sends `m.sticker` events via `mx.sendEvent(EventType.Sticker, {...})` — fetches the sticker image from the mxc URL, resolves dimensions, and sends with url/info/body. Custom emoji and sticker packs are managed globally or per-room in Settings → Emojis & Stickers. Sticker button auto-hides on narrow viewports (< 500 px) to save space. Implemented in `src/app/features/room/RoomInput.tsx`.
- **Pinned messages**: Each room has a pin icon (📌) in the header that opens a panel listing all currently pinned messages. Any message can be pinned or unpinned via its context menu (updates the `m.room.pinned_events` state event). Implemented in `src/app/features/room/room-pin-menu/`.
- **Message forwarding**: Forward any message to any room from the message context menu.
- **Draft persistence**: Unsent message drafts survive page reload via `localStorage` (`draft-msg-<roomId>`). Jotai in-memory atom is primary; localStorage is used as fallback on reload and cleared on send.
- **Message search date range**: From/To date pickers in the search filter bar. Sends `from_ts`/`to_ts` epoch ms to the Matrix `/search` endpoint. Chip shows active range with X to clear.
@@ -112,6 +114,8 @@ Emoji reaction buttons styled for terminal mode via `button[data-reaction-key]`
- Own reaction (aria-pressed=true): orange tint `rgba(255,107,0,0.12)`, orange border
- Light TDS: equivalent blue/orange variants
**Who reacted**: Hovering any reaction chip shows a `TooltipProvider` tooltip listing the display names of everyone who reacted with that emoji (up to ~3 names, then "and N others"). Right-clicking opens a full `ReactionViewer` modal — a two-panel view with all reaction keys on the left and avatars/names of reactors on the right, keyboard-navigable (↑↓ arrows). Clicking a name in the modal opens their room profile. Implemented in `src/app/features/room/message/Reactions.tsx` and `src/app/features/room/reaction-viewer/ReactionViewer.tsx`.
### DM Call Improvements
@@ -120,6 +124,7 @@ Emoji reaction buttons styled for terminal mode via `button[data-reaction-key]`
### Presence
- **Discord-style presence selector**: Clicking your avatar in the bottom-left sidebar opens a popout with five status options — Online (green), Idle (yellow), Do Not Disturb (red, broadcasts `unavailable` with `status_msg: 'dnd'`), Invisible (grey outline, broadcasts `offline`), and Auto (activity-tracking, the original behaviour). The selected status persists across reloads via the settings atom. A colored badge on the avatar reflects the current status at a glance. `usePresenceUpdater` short-circuits immediately for manual modes; full idle-timer and visibility-change logic only runs in Auto mode. Settings also exposed via `src/app/state/settings.ts` (`presenceStatus` field).
- **Custom status message**: Set a short status text (up to 64 characters) with an emoji picker, shown below your display name in member lists and presence displays. Accessible via Settings → Account → Profile. Includes an **auto-clear timer** (options: 30 minutes, 1 hour, 4 hours, 1 day, 3 days, 7 days) — after the timer expires, the status is automatically cleared by setting `status_msg: ''` via `mx.setPresence`. A character counter (shown when ≥ 56/64 chars) prevents overflow. Implemented in `src/app/features/settings/account/Profile.tsx`.
- **Presence badges on members**: Online/busy/away dots shown next to users in the room members drawer and settings members panel (`PresenceBadge` component from `src/app/components/presence/Presence.tsx`).
- **Document title unread count**: Tab title updates to `(N) Lotus Chat` for mentions, `· Lotus Chat` for unreads, `Lotus Chat` when clear.