From 24e6882e72e1ca1c589a94553aedfd8528eb7622 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Thu, 4 Jun 2026 20:56:55 -0400 Subject: [PATCH] docs: mark P3-5, P3-9, P5-19, P5-23, P5-26 complete in TODO and README 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 --- LOTUS_TODO.md | 20 +++++++++++++++----- README.md | 5 +++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/LOTUS_TODO.md b/LOTUS_TODO.md index 31423d228..024291013 100644 --- a/LOTUS_TODO.md +++ b/LOTUS_TODO.md @@ -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 `` 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 `` 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) diff --git a/README.md b/README.md index b0d9b803e..e800fa0ab 100644 --- a/README.md +++ b/README.md @@ -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 `` — 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 `