From 205fbe3b0de45356bca7ebf6931ebe8a0a8278f5 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Wed, 3 Jun 2026 10:36:53 -0400 Subject: [PATCH] docs: mark all P1 features complete in TODO; update README and landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LOTUS_TODO.md: - P1-1: marked UPSTREAM REMOVED (Ctrl+K already exists as full room switcher) - P1-2 through P1-11: all marked [x] with implementation notes README.md: - New sections: UX & Composer, Settings (Appearance), Calls (Extended) - Documents: media gallery, sidebar filter, DM previews, favorites, poll creation, voice speed, invite QR, private receipts, knock-to-join, syntax highlighting, night light, push-to-deafen, typing dots, char counter - Key Custom Files table updated with 4 new entries landing/index.html (matrix repo): - Polls row: "display & vote" → "create, vote & display" - Voice messages: add speed control note - 4 new UX table rows: Media Gallery, Sidebar filter, Favorite rooms, Invite link+QR - also-available paragraph updated with all P1 additions - Comparison date updated Co-Authored-By: Claude Sonnet 4.6 --- LOTUS_TODO.md | 109 +++++++++++++++++--------------------------------- README.md | 27 +++++++++++++ 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/LOTUS_TODO.md b/LOTUS_TODO.md index 0be6840ae..4bac5d099 100644 --- a/LOTUS_TODO.md +++ b/LOTUS_TODO.md @@ -327,28 +327,14 @@ Core features that meaningfully expand what users can do every day. --- -### [ ] P1-1 · Quick Room Switcher (Ctrl+K / Cmd+K) +### [UPSTREAM — REMOVED] P1-1 · Quick Room Switcher (Ctrl+K / Cmd+K) -**What:** Global keyboard shortcut opens a floating search modal above all content. Features: - -- Fuzzy-search across ALL rooms and DMs by display name in real time -- Keyboard navigable: `↑`/`↓` to move, `Enter` to open room, `Esc` to close -- Shows unread badge count inline next to each result -- Pressing Ctrl+K again while open closes it -- Recent rooms shown immediately before typing - **Architecture:** -- New component: `src/app/components/QuickSwitcher.tsx` -- Register global hotkey via `useEffect` + `window.addEventListener('keydown')` in `src/app/pages/client/ClientRoot.tsx` -- Use the existing `OverlayContainerProvider` portal (from `App.tsx`) so the modal floats above everything -- Room data: `allRoomsAtom` + `mDirectAtom` from `src/app/state/roomList.ts` -- Style with `folds` `Menu`, `Box`, `Input` components matching existing patterns -- Use `is-hotkey` library (already in the project) for the keybind - **[AUDIT REQUIRED]** — Confirm upstream Cinny does NOT already have a quick switcher. Check for any existing Ctrl+K handler in `ClientRoot.tsx` or `App.tsx`. - **Complexity:** Medium. +**Audit result:** CONFIRMED UPSTREAM. `SearchModalRenderer` (Ctrl+K) in `src/app/features/search/Search.tsx` is already a full room/DM switcher with avatars, unread badges, fuzzy search across all rooms and DMs, and keyboard navigation. It is more polished than anything we would build. A custom `QuickSwitcher.tsx` was built and then deleted — Ctrl+K was left to the existing upstream implementation. +**No action needed.** --- -### [ ] P1-2 · Media Gallery +### [x] P1-2 · Media Gallery **What:** A scrollable grid of all shared images, videos, and files in a room. Accessible via a new icon in the room header (picture/grid icon). Features: @@ -358,60 +344,36 @@ Core features that meaningfully expand what users can do every day. - Click file → download - Shows sender + timestamp tooltip on hover - TDS-aware grid styling - **Architecture:** -- New component: `src/app/features/room/media-gallery/MediaGallery.tsx` -- Renders as a right-side drawer (similar to the members drawer pattern) -- Add icon button to `src/app/features/room/RoomViewHeader.tsx` -- Paginate backwards from latest event using `/messages?dir=b` - **[AUDIT REQUIRED]** — Confirm upstream Cinny has no existing media gallery or file browser. Check room header icons and room settings panels. - **Complexity:** Medium. + **Complexity:** Medium. + **COMPLETED June 2026.** `MediaGallery.tsx` renders as a fixed right-side drawer (320px). Three tabs: Images | Videos | Files. Reads already-decrypted events from `room.getLiveTimeline().getEvents()` (required for E2EE rooms — raw API returns undecryptable blobs). For encrypted images, shows a lock icon + filename placeholder (server can't thumbnail encrypted content). Unencrypted thumbnails use `mxcUrlToHttp(mx, url, false, 120, 120, 'crop')` — `useAuthentication=false` avoids the v1 authenticated endpoint that adds `allow_redirect=true`, which Synapse rejects with 400. Load More uses `mx.paginateEventTimeline()`. Gallery icon added to room header (Desktop only). --- -### [ ] P1-3 · Sidebar Room Filter / Search +### [x] P1-3 · Sidebar Room Filter / Search **What:** A text input at the top of each room list tab (Home, DMs, Spaces) that filters visible rooms in real time by display name. Ephemeral — clears when you switch tabs. No server calls — pure client-side filter over the loaded room list. -**Architecture:** - -- Add filter `useState('')` to each tab component -- Filter the room array before rendering: `rooms.filter(id => displayName(id).toLowerCase().includes(filter))` -- Show a small `×` clear button when filter is non-empty -- TDS: mono font, dim border input matching the design system - **Where:** `src/app/pages/client/home/Home.tsx` (Home tab), DMs equivalent, Space room list. - **[AUDIT REQUIRED]** — Confirm upstream Cinny does NOT already have a filter input in room lists. - **Complexity:** Low-Medium. +**Complexity:** Low-Medium. +**COMPLETED June 2026.** Filter inputs added to `Home.tsx` (rooms) and `Direct.tsx` (DMs). Styled with `size="400"`, `radii="400"`, search icon prefix — matches the members-drawer search bar style. Clear `×` button appears when non-empty. Filtering respects local room name overrides (`getLocalRoomNamesContent`). Favorites section always shows unfiltered; only the main "Rooms" list is filtered. Input fills full panel width (`grow="Yes"` on container Box). --- -### [ ] P1-4 · Enhanced DM List (last message preview + timestamp) +### [x] P1-4 · Enhanced DM List (last message preview + timestamp) **What:** Show the last message text and relative timestamp ("2 min ago", "Yesterday") next to each DM in the sidebar, like iMessage or WhatsApp. Currently only the room name and unread badge are shown. -**Architecture:** - -- For each DM room: get `room.getLastActiveTimestamp()` and `room.timeline[room.timeline.length - 1]` for the last event -- Render the event body (truncated to ~60 chars), stripping any HTML -- Format timestamp: "just now" / "X min ago" / "Yesterday" / date -- Falls back gracefully if the room has no messages yet - **[AUDIT REQUIRED]** — Check if upstream Cinny already shows message previews in DM list. Check `src/app/pages/client/direct-messages/` or `DirectTab.tsx` for existing DM list item rendering. - **Complexity:** Medium — need to extract last event body safely across encrypted/non-encrypted rooms. +**Complexity:** Medium. +**COMPLETED June 2026.** Implemented in `RoomNavItem.tsx` via `useRoomLatestRenderedEvent(room)` hook (reactive — re-renders on new events). When `direct=true`: shows truncated body (48 chars) + relative timestamp below the room name. Handles: encrypted events (shows "Encrypted message" only on actual decryption failure — `isDecryptionFailure()` not `isEncrypted()`), stickers ("Sticker"), membership events (skipped entirely), missing timestamps. Timestamp formatting: `Xm` / `Xhr` / `Yesterday` / `D MMM`. --- -### [ ] P1-5 · Voice Message Playback Speed Control +### [x] P1-5 · Voice Message Playback Speed Control **What:** Add a speed toggle to the voice message audio player in the room timeline: `0.75×` → `1×` → `1.5×` → `2×`. Clicking the current speed label cycles to the next. Uses the HTML `