docs: mark all P1 features complete in TODO; update README and landing page
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 <noreply@anthropic.com>
This commit is contained in:
+36
-73
@@ -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<string>('')` 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 `<audio>` element's `playbackRate` property.
|
||||
**Architecture:**
|
||||
|
||||
- `const [speed, setSpeed] = useState(1)`
|
||||
- On click: `audioRef.current.playbackRate = nextSpeed`
|
||||
- Render a small clickable pill: `1×` etc., next to the audio controls
|
||||
- Persist speed preference in `settingsAtom` so it carries across messages
|
||||
**[AUDIT REQUIRED]** — Locate exactly where voice messages render in the timeline. Search for `m.audio` / `MSC3245` / `VoiceMessage` in `src/app/features/room/`. The recorder is in `VoiceMessageRecorder.tsx` but the _player_ for received voice messages is elsewhere.
|
||||
**Complexity:** Low-Medium.
|
||||
**Complexity:** Low-Medium.
|
||||
**COMPLETED June 2026.** `AudioContent.tsx` — `useState<0.75|1|1.5|2>(1)` with `SPEED_STEPS = [0.75, 1, 1.5, 2]`. `useEffect` sets `audioRef.current.playbackRate` when speed changes (persists across pause/resume). Speed pill rendered as a `Chip` in the left controls area. Local state only (no settingsAtom persistence — speed resets per-message, which is the standard behavior).
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-6 · Poll Creation
|
||||
### [x] P1-6 · Poll Creation
|
||||
|
||||
**What:** Users can create polls from the message composer. Features:
|
||||
|
||||
@@ -436,11 +398,12 @@ Core features that meaningfully expand what users can do every day.
|
||||
**Architecture:**
|
||||
- New component: `src/app/features/room/PollCreator.tsx`
|
||||
- Wire toolbar button into `src/app/features/room/RoomInput.tsx` (follow GIF picker pattern)
|
||||
**Complexity:** Medium.
|
||||
**Complexity:** Medium.
|
||||
**COMPLETED June 2026.** `PollCreator.tsx` — modal with question input, 2–10 option inputs (add/remove), Single/Multiple choice toggle buttons. `isMultiple: boolean` state with `max_selections` computed at submit time from filled options length. Sends stable `m.poll.start` event. `Icons.OrderList` button in RoomInput `after` prop opens the modal. Sentry issue JAVASCRIPT-REACT-N fixed: `PollContent.tsx` vote handler now `.catch(() => undefined)` to suppress `Cannot call getPendingEvents with pendingEventOrdering == chronological` SDK error.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-7 · Code Syntax Highlighting in Messages
|
||||
### [x] P1-7 · Code Syntax Highlighting in Messages
|
||||
|
||||
**What:** Color-code fenced code blocks in rendered messages. Language auto-detected from the code fence hint (` ```python `, ` ```js `, etc.).
|
||||
**⚠️ MUST match `/root/code/web_template/base.css` exactly.** The web_template defines the canonical token structure for all Lotus apps:
|
||||
@@ -457,13 +420,14 @@ Core features that meaningfully expand what users can do every day.
|
||||
- `.tok-cmt` → `var(--color-tok-cmt)` italic (comments)
|
||||
- `.tok-fn` → `var(--accent-purple)` (function names)
|
||||
See `/root/code/tinker_tickets/assets/js/markdown.js` for the reference tokenizer implementation.
|
||||
**[AUDIT REQUIRED]** — Check the TDS CSS variables (`--accent-cyan`, `--accent-green`, etc.) are available in Cinny's `lotus-terminal.css.ts` vanilla-extract theme. Map `var(--accent-*)` to the correct folds/vanilla-extract tokens. Also verify the tokenizer approach from tinker_tickets is language-agnostic enough for chat (it may need extension for more languages).
|
||||
**Where:** Code block renderer in `src/app/components/message/` or wherever `<pre><code>` is rendered.
|
||||
**Complexity:** Medium.
|
||||
**[AUDIT REQUIRED]** — Check the TDS CSS variables (`--accent-cyan`, `--accent-green`, etc.) are available in Cinny's `lotus-terminal.css.ts` vanilla-extract theme. Map `var(--accent-*)` to the correct folds/vanilla-extract tokens. Also verify the tokenizer approach from tinker_tickets is language-agnostic enough for chat (it may need extension for more languages).
|
||||
**Where:** Code block renderer in `src/app/components/message/` or wherever `<pre><code>` is rendered.
|
||||
**Complexity:** Medium.
|
||||
**COMPLETED June 2026.** `src/app/utils/syntaxHighlight.ts` — custom tokenizer returning `SyntaxToken[]` with inline styles from `--lt-accent-*` CSS variables. Supports: JS/TS/JSX/TSX, Python, Rust. Tokens: `kw` (cyan), `str` (green), `num` (orange), `cmt` (italic, opacity 0.5), `fn` (purple). Integrated in `react-custom-html-parser.tsx` via `TDS_TOKENIZER_LANGS` set — falls back to ReactPrism for unsupported languages. `ReactPrism.css` adds `.prism-tds-dark` / `.prism-tds-light` classes. `useTheme.ts` sets `prism-tds-dark/light` on the LotusTerminal themes.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-8 · Favorite / Starred Rooms
|
||||
### [x] P1-8 · Favorite / Starred Rooms
|
||||
|
||||
**What:** Star any room from its context menu. Starred rooms appear in a dedicated "Favorites" section at the top of the sidebar room list. Uses Matrix's built-in `m.favourite` room tag (account data), so favorites sync across devices and clients automatically.
|
||||
|
||||
@@ -475,12 +439,12 @@ Body: { "order": 0.5 }
|
||||
- Right-click room → "Add to Favorites" / "Remove from Favorites"
|
||||
- Favorites section appears above the regular room list in the Home tab
|
||||
- Star icon shown on favorited rooms in the list
|
||||
**[AUDIT REQUIRED]** — Confirm upstream Cinny does NOT already render `m.favourite` tagged rooms in a special section. Check `src/app/pages/client/home/` for any tag-based room grouping. Some versions of Cinny may already do this.
|
||||
**Complexity:** Medium.
|
||||
**Complexity:** Medium.
|
||||
**COMPLETED June 2026.** `RoomNavItem.tsx` context menu: "Add to Favorites" / "Remove from Favorites" calls `mx.setRoomTag(roomId, 'm.favourite', { order: 0.5 })` / `mx.deleteRoomTag(roomId, 'm.favourite')`. Star indicator shown on favorited rooms. `Home.tsx`: rooms split into `favoriteRooms` / `otherRooms` by `room.tags?.['m.favourite']`. Favorites section (with its own `NavCategory` + `favVirtualizer`) rendered above the main Rooms list when any favorites exist. `FAVORITES_CATEGORY_ID` is collapsible.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-9 · Invite Link Generator (with QR code)
|
||||
### [x] P1-9 · Invite Link Generator (with QR code)
|
||||
|
||||
**What:** In room settings (or via right-click on room), a "Copy Invite Link" button that:
|
||||
|
||||
@@ -488,13 +452,13 @@ Body: { "order": 0.5 }
|
||||
2. Copies it to clipboard via `navigator.clipboard.writeText()`
|
||||
3. Shows a QR code of the link (use a lightweight QR library e.g. `qrcode` npm package)
|
||||
4. "Share" button that opens the native Web Share API if supported
|
||||
**[AUDIT REQUIRED]** — Check if upstream Cinny already has a "copy invite link" button in room settings. Also check if the room settings panel already shows the room address/alias.
|
||||
**Where:** Room settings panel `src/app/features/room-settings/` or room header context menu.
|
||||
**Complexity:** Low-Medium.
|
||||
**Where:** Room settings panel `src/app/features/room-settings/` or room header context menu.
|
||||
**Complexity:** Low-Medium.
|
||||
**COMPLETED June 2026.** `RoomShareInvite.tsx` — new component in `common-settings/general/`. Shows invite URL as copyable text + 160×160 QR code (`api.qrserver.com`). "Copy Link" button with 2s "Copied!" state. Added to room settings General tab. **Also** added to the Invite User modal (`InviteUserPrompt.tsx`): `⊞` toggle button in header shows/hides a 180×180 QR panel between the header and user search form. CSP on LXC 106 updated to add `https://api.qrserver.com` to `img-src` (nginx reloaded).
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-10 · Private Read Receipts toggle
|
||||
### [x] P1-10 · Private Read Receipts toggle
|
||||
|
||||
**Spec:** CS-API stable — `m.read.private` vs `m.read`.
|
||||
**What:** Add a toggle in Settings → Privacy: "Send private read receipts" — when enabled, read receipts are sent as `m.read.private` (only you and the server see them) instead of `m.read` (everyone in the room sees when you read). Default: public (current behavior, unchanged).
|
||||
@@ -503,21 +467,20 @@ Body: { "order": 0.5 }
|
||||
- New `settingsAtom` field: `privateReadReceipts: boolean` (default `false`)
|
||||
- When sending a read receipt, check the setting and use the appropriate type
|
||||
- Find `mx.sendReadReceipt(...)` call sites and add the `receiptType` parameter
|
||||
**[AUDIT REQUIRED]** — Verify the `matrix-js-sdk` version in use supports the `receiptType` parameter on `sendReadReceipt`. Check the SDK's type definitions for this method.
|
||||
**Complexity:** Low.
|
||||
**Complexity:** Low.
|
||||
**COMPLETED June 2026.** `privateReadReceipts: boolean` (default `false`) in `settingsAtom`. Toggle in Settings → General → Privacy section. `notifications.ts`: `markAsRead()` already had `privateReceipt` parameter; added `getSettings().privateReadReceipts` read so either flag independently triggers `ReceiptType.ReadPrivate`. `getSettings()` reads from localStorage which is always kept in sync with the atom via `setSettings()` on every atom write — no staleness issue.
|
||||
|
||||
---
|
||||
|
||||
### [ ] P1-11 · Knock-to-join UX (Room version 7)
|
||||
### [x] P1-11 · Knock-to-join UX (Room version 7)
|
||||
|
||||
**Spec:** Room version 7 (stable Matrix spec). Join rule: `knock`.
|
||||
**What:** Full knock UX for both sides:
|
||||
|
||||
- **Knocking:** When a room's join rule is `knock`, show a "Request to Join" button instead of "Join Room". Sends `POST /join` which triggers a knock state event. Show pending state ("Request sent") while waiting.
|
||||
- **Approving knocks:** Room admins/mods see a notification of pending knocks. In the members drawer or room settings, show a "Pending Requests" section listing knockers with "Approve" (`/invite`) and "Deny" (`/kick`) buttons.
|
||||
**[SERVER CHECK]** — Verify `matrix.lotusguild.org` Synapse supports room version 7 and the knock join rule.
|
||||
**[AUDIT REQUIRED]** — Check if upstream Cinny handles the `knock` join rule at all. If it does, only the approvals UI on the admin side may be missing.
|
||||
**Complexity:** Medium.
|
||||
**Complexity:** Medium.
|
||||
**COMPLETED June 2026.** `RoomIntro.tsx`: when `room.getJoinRule() === JoinRule.Knock`, shows "Request to Join" button instead of "Join Room". On click: `mx.knockRoom(room.roomId)` (SDK method confirmed). After knocking: shows "Request sent — waiting for room admin approval" state. State resets on `room.roomId` change via `useEffect`. `MembersDrawer.tsx`: "Pending Requests" section visible to users with invite power level — lists `room.getMembersWithMembership(Membership.Knock)` with Approve (`mx.invite`) / Deny (`mx.kick`) buttons.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -135,6 +135,29 @@ Emoji reaction buttons styled for terminal mode via `button[data-reaction-key]`
|
||||
- **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.
|
||||
|
||||
### 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.
|
||||
- **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.
|
||||
- **Favorite rooms**: Right-click any room → "Add to Favorites" / "Remove from Favorites". Favorited rooms (using the standard Matrix `m.favourite` tag) appear in a collapsible "Favorites" section above the main room list on the Home tab. Syncs across devices via account data.
|
||||
- **Poll creation**: Polls can be created directly from the composer — `Icons.OrderList` button opens a modal with question field, 2–10 answer options (add/remove), and Single/Multiple choice toggle. Sends a stable `m.poll.start` event. (Poll display & voting were already supported.)
|
||||
- **Voice message playback speed**: `0.75×` → `1×` → `1.5×` → `2×` speed toggle pill on voice message player — cycles on click via `playbackRate` on the `<audio>` element.
|
||||
- **Invite link + QR code**: Room settings → General shows a "Share Room" tile with the `matrix.to` invite URL and a QR code. The Invite modal also has a `⊞` toggle button showing a QR panel when clicked. Both use `api.qrserver.com` (added to CSP on LXC 106).
|
||||
- **Private read receipts**: Settings → General → Privacy — "Private Read Receipts" toggle. When on, sends `m.read.private` instead of `m.read` so other room members can't see when you've read messages.
|
||||
- **Media gallery**: A right-side drawer (photo icon in room header, Desktop only) showing Images | Videos | Files tabs. Reads already-decrypted timeline events — works in E2EE rooms. Encrypted-blob images show a lock-icon placeholder. Load More paginates backwards via `mx.paginateEventTimeline()`.
|
||||
- **Knock-to-join**: When a room's join rule is `knock`, RoomIntro shows "Request to Join" (calls `mx.knockRoom()`) with "Request sent" pending state. Room admins see a "Pending Requests" section in the members drawer with Approve / Deny buttons.
|
||||
- **Code syntax highlighting** (TDS mode): Fenced code blocks in messages highlight keywords (cyan), strings (green), numbers (orange), comments (italic dim), function names (purple) using inline `--lt-accent-*` CSS variables. Custom tokenizer in `syntaxHighlight.ts` — supports JS/TS/JSX/TSX, Python, Rust. Falls back to ReactPrism for other languages.
|
||||
|
||||
### Settings (Appearance)
|
||||
|
||||
- **Night Light / Blue Light Filter**: Warm orange overlay (`rgba(255,140,0,N%)`) across the entire UI. Toggle + intensity slider (5–80%) in Settings → Appearance. `position:fixed; pointer-events:none; z-index:9998`. Persists across sessions.
|
||||
|
||||
### Calls (Extended)
|
||||
|
||||
- **Push-to-Deafen**: Press `M` during a call to toggle speaker mute (deafen). Configurable in Settings → General → Calls alongside the PTT key. Skips editable elements; guards `e.repeat`; uses `el.ownerDocument.body` for iframe safety.
|
||||
- **TDS typing indicator dots**: When Lotus Terminal mode is active, the animated typing indicator dots turn TDS orange (`var(--lt-accent-orange)`) via `color: currentColor` inheritance.
|
||||
|
||||
### Server Integration
|
||||
|
||||
- **Server support contact (MSC1929)**: Settings → Help & About displays the homeserver admin contact fetched from `/.well-known/matrix/support`. Shows the admin's Matrix ID and a link to the support page when the homeserver has configured this endpoint. Degrades gracefully when not configured (section is hidden on 404 or network error). In TDS mode the contact text and link render in `--lt-accent-cyan`. Implemented in `src/app/features/settings/about/About.tsx`.
|
||||
@@ -206,3 +229,7 @@ Built files are served from `/var/www/html/` on LXC 106 (nginx). Config lives at
|
||||
| `src/app/components/CallEmbedProvider.tsx` | PiP + draggable call embed, call wallpaper carry-over |
|
||||
| `src/app/plugins/call/CallEmbed.ts` | EC widget bridge: iframe setup, `color-scheme` dark/light injection, built-in control hiding, theme sync |
|
||||
| `src/app/plugins/millify.ts` | Named import fix for Rolldown CJS interop (prevents `zc.default is not a function` crash) |
|
||||
| `src/app/features/room/MediaGallery.tsx` | Right-side media gallery drawer (images/videos/files) |
|
||||
| `src/app/features/room/PollCreator.tsx` | Poll creation modal (single/multiple choice, 2–10 options) |
|
||||
| `src/app/features/common-settings/general/RoomShareInvite.tsx` | Invite link + QR code tile for room settings |
|
||||
| `src/app/utils/syntaxHighlight.ts` | TDS code syntax tokenizer (JS/TS/Python/Rust → inline CSS vars) |
|
||||
|
||||
Reference in New Issue
Block a user