docs: mark P3-5, P3-9, P5-19, P5-23, P5-26 complete in TODO and README
CI / Build & Quality Checks (push) Successful in 10m31s
CI / Build & Quality Checks (push) Successful in 10m31s
Inline GIF preview, policy list viewer, collapsible long messages, message send animation, and right-click room context menu improvements documented and checked off. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+15
-5
@@ -789,7 +789,7 @@ curl -s https://matrix.lotusguild.org/_matrix/client/unstable/org.matrix.msc4140
|
||||
|
||||
---
|
||||
|
||||
### [ ] P3-5 · Inline GIF Preview for Giphy/Tenor Links
|
||||
### [x] P3-5 · Inline GIF Preview for Giphy/Tenor Links
|
||||
|
||||
**[AUDIT REQUIRED — DO THIS FIRST]** — Before any implementation, verify the current behavior:
|
||||
|
||||
@@ -800,6 +800,8 @@ curl -s https://matrix.lotusguild.org/_matrix/client/unstable/org.matrix.msc4140
|
||||
**If not:** Detect Giphy/Tenor URL patterns in the URL preview renderer and fetch the GIF via the homeserver's `/_matrix/media/v3/preview_url` proxy. If the proxy returns a direct media URL, render it as an `<img>` tag with `loading="lazy"`.
|
||||
**Complexity:** Low-Medium (after audit).
|
||||
|
||||
**COMPLETED June 2026.** Giphy and Tenor share URLs are detected by pattern matching in the URL preview renderer. Matching links bypass the generic OG-card layout and render directly as an `<img loading="lazy">` tag, so animated GIFs play inline in the message timeline. Fetched via the homeserver's `/_matrix/media/v3/preview_url` proxy — no direct Giphy/Tenor origin contact from the client. Respects the existing URL preview enabled/disabled setting.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P3-6 · Configurable Composer Toolbar
|
||||
@@ -851,7 +853,7 @@ Features:
|
||||
|
||||
---
|
||||
|
||||
### [ ] P3-9 · Policy List / Ban List Subscription UI
|
||||
### [x] P3-9 · Policy List / Ban List Subscription UI
|
||||
|
||||
**Spec:** CS-API §13.16 (stable), `m.policy.*` events.
|
||||
**Note:** User already has Draupnir bot running in all space rooms — this UI complements rather than replaces it.
|
||||
@@ -864,6 +866,8 @@ Features:
|
||||
**[AUDIT REQUIRED]** — Understand how Draupnir reads policy lists on this homeserver. Confirm whether a client-side subscription UI would conflict with or duplicate Draupnir's configuration. May be more useful as a read-only viewer than a write UI.
|
||||
**Complexity:** High.
|
||||
|
||||
**COMPLETED June 2026.** "Policy Lists" tab added to Room/Space Settings (visible to admins only, gated by power level). Reads all rooms the local user has joined whose `m.room.create` type or name matches the policy list convention (`m.policy.rule.*`). Displays subscribed list rooms with their contents: banned users (`m.policy.rule.user`), banned rooms (`m.policy.rule.room`), and banned servers (`m.policy.rule.server`), each showing the entity, reason, and recommendation field. Subscribe (join the policy room) and Unsubscribe (leave) actions provided. Read-only viewer — Draupnir remains solely responsible for enforcement.
|
||||
|
||||
---
|
||||
|
||||
## PRIORITY 4 — Specialized, high complexity, or very low priority
|
||||
@@ -1106,12 +1110,14 @@ Themes:
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-19 · Collapsible Long Messages ('Read more')
|
||||
### [x] P5-19 · Collapsible Long Messages ('Read more')
|
||||
|
||||
**What:** Messages >~20 lines auto-collapsed with "Read more ↓" button. Click to expand inline. Collapse threshold configurable in settings.
|
||||
**[AUDIT REQUIRED]** Determine whether CSS `max-height` + `overflow:hidden` or a line-count approach is more appropriate for the current message renderer. Check edge cases with code blocks and media embeds.
|
||||
**Complexity:** Medium.
|
||||
|
||||
**COMPLETED June 2026.** CSS `max-height` + `overflow: hidden` approach used on the message body container — avoids costly DOM line-count measurement and works correctly with code blocks and embedded media. Default threshold: 20 lines (~320px). A "Read more ↓" button fades in at the bottom when the message is clamped; clicking it expands inline and replaces the button with "Collapse ↑". Threshold (in lines) is configurable via Settings → Appearance. Respects `prefers-reduced-motion` — the expand/collapse transition is disabled when the media query matches.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-20 · Quick Reply from Browser Notification
|
||||
@@ -1137,11 +1143,13 @@ Themes:
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-23 · Message Send Animation
|
||||
### [x] P5-23 · Message Send Animation
|
||||
|
||||
**What:** Own sent messages fade+scale into the timeline (0.15s ease-out: scale 0.97→1.0, opacity 0.4→1.0). Incoming messages unaffected. Respects `prefers-reduced-motion`.
|
||||
**Complexity:** Low.
|
||||
|
||||
**COMPLETED June 2026.** CSS keyframe `@keyframes msgSendIn` (`scale(0.97) opacity(0.4)` → `scale(1) opacity(1)`, 0.15s ease-out) defined in `Animations.css.ts`. Applied via a vanilla-extract `style` to own-message containers (`EventStatus !== null` — i.e. local-echo messages that have not yet received a server timestamp). Incoming messages and server-confirmed events are unaffected. `@media (prefers-reduced-motion: reduce)` block sets `animation: none`.
|
||||
|
||||
---
|
||||
|
||||
### [x] P5-24 · Hotkey Push-to-Deafen
|
||||
@@ -1161,12 +1169,14 @@ Themes:
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-26 · Right-Click Room Context Menu Improvements
|
||||
### [x] P5-26 · Right-Click Room Context Menu Improvements
|
||||
|
||||
**What:** Consolidated right-click menu: Mute with duration submenu (15min/1hr/8hr/24hr/Indefinite), Copy room link, Mark as read, Leave room, Room settings.
|
||||
**[AUDIT REQUIRED]** Audit current right-click menu to avoid duplicating existing actions.
|
||||
**Complexity:** Low-Medium.
|
||||
|
||||
**COMPLETED June 2026.** `RoomNavItem.tsx` context menu expanded. **Mute** item replaced with a duration submenu (via nested `PopOut`): 15 min / 1 hr / 8 hr / 24 hr / Indefinite — each calls `mx.setRoomTag(roomId, 'm.push.mute', { ...})` / push rule disable with a matching `setTimeout` to auto-restore after the selected duration (stored in `localStorage` for persistence across reloads). **Copy Room Link** copies the `matrix.to` URL to clipboard with a "Copied!" flash. **Mark as Read** calls `mx.setRoomReadMarkers()` to the latest event. **Leave Room** opens the existing leave-room confirmation dialog. **Room Settings** navigates to the room settings panel. Existing items (Rename for me, Favorites, local-name pencil) preserved.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P5-27 · Notification Profile Presets (Gaming / Work / Sleep)
|
||||
|
||||
@@ -70,11 +70,13 @@ A full custom theme engine layered on top of Cinny's vanilla-extract theming:
|
||||
### Moderation
|
||||
|
||||
- **Report Room**: A "Report Room" option in the room header menu (⋮) allows users to report a room to homeserver admins with a reason and abuse category (Spam / Harassment / Inappropriate Content / Other). Calls `POST /_matrix/client/v3/rooms/{roomId}/report` (MSC4151, confirmed supported on matrix.lotusguild.org). Implemented in `ReportRoomModal.tsx` with loading/success/error states.
|
||||
- **Policy List / Ban List Viewer (MSC2313)**: A "Policy Lists" tab in Room / Space Settings (admin-only, power-level gated) shows all subscribed `m.policy.rule.*` rooms and their contents — banned users, banned rooms, and banned servers — each with entity, reason, and recommendation fields. Subscribe (join the policy room) and Unsubscribe (leave) actions are provided. Enforcement remains solely with the Draupnir bot; this UI is a read-only complement.
|
||||
|
||||
### Messaging Enhancements
|
||||
|
||||
- **Rich room topics**: Room topics that contain formatted text (bold, links, italic) are now rendered with full HTML formatting. Falls back to plain text if no `formatted_body` is present. Activates when any room admin sets a formatted topic.
|
||||
- **Edit history viewer**: Clicking the "edited" label on any edited message opens a modal showing every prior version with timestamps. Fetches all `m.replace` relations for the event and displays them oldest-to-newest. Previously the "edited" label was visible but unclickable.
|
||||
- **Inline GIF preview**: Giphy and Tenor share links sent as plain text auto-embed as animated GIFs inline in the timeline. URL patterns are detected client-side; the image is fetched via the homeserver's `/_matrix/media/v3/preview_url` proxy (no direct contact with Giphy/Tenor from the client). Rendered as `<img loading="lazy">` — respects the existing URL preview enabled/disabled setting.
|
||||
- **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.
|
||||
- **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.
|
||||
@@ -148,6 +150,9 @@ Emoji reaction buttons styled for terminal mode via `button[data-reaction-key]`
|
||||
### UX & Composer
|
||||
|
||||
- **Message length counter**: A muted character counter appears just left of the send button while typing, disappearing when the composer is empty. Resets on room switch.
|
||||
- **Collapsible long messages**: Messages exceeding ~20 lines are auto-collapsed with a "Read more ↓" button. Click to expand inline; a "Collapse ↑" button re-folds. Threshold (in lines) configurable in Settings → Appearance. Uses CSS `max-height` + `overflow: hidden` — works correctly with code blocks and embedded media. Respects `prefers-reduced-motion`.
|
||||
- **Message send animation**: Own sent messages fade and scale into the timeline (0.15 s ease-out: `scale(0.97)→scale(1)`, `opacity 0.4→1`). Incoming messages are unaffected. Respects `prefers-reduced-motion`.
|
||||
- **Right-click room context menu**: Expanded sidebar room context menu — **Mute** now opens a duration submenu (15 min / 1 hr / 8 hr / 24 hr / Indefinite) with auto-restore after the selected window; **Copy Room Link** copies the `matrix.to` URL with a "Copied!" flash; **Mark as Read** marks the room read to the latest event; plus Leave Room and Room Settings shortcuts.
|
||||
- **Unverified device warning**: `warnOnUnverifiedDevices` setting (default off). When enabled via Settings → General → Privacy, a warning banner appears above the composer in encrypted rooms that contain unverified devices, showing the count. Sending is never blocked — the banner is informational only. Uses the existing `useUnverifiedDeviceCount()` hook.
|
||||
- **Sidebar room filter**: A search-icon input at the top of the Home and DMs sidebar tabs filters rooms by display name in real time. Clears on tab switch. Styled to match the members-drawer search bar (`size="400"`, search prefix icon).
|
||||
- **DM last message preview**: Each DM row in the sidebar shows a truncated message body (48 chars) and relative timestamp (`Xm`, `Xhr`, `Yesterday`, `D MMM`) below the room name, sourced reactively from `useRoomLatestRenderedEvent`. Encrypted rooms show "Encrypted message" only on actual decryption failure.
|
||||
|
||||
Reference in New Issue
Block a user