Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9a3edc142 | |||
| ee17f6257e |
+130
-38
@@ -7,17 +7,84 @@
|
|||||||
This file is the single source of truth for all planned, in-progress, and backlog features.
|
This file is the single source of truth for all planned, in-progress, and backlog features.
|
||||||
Update it as features are completed or reprioritized.
|
Update it as features are completed or reprioritized.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ TDS DESIGN LAW — READ BEFORE TOUCHING ANY UI
|
||||||
|
|
||||||
|
> **ALL Lotus Terminal Design System (TDS) styling — colors, animations, glows, borders, fonts, spacing — MUST come exclusively from `/root/code/web_template/base.css` CSS variables.**
|
||||||
|
> Do NOT hardcode hex values. Do NOT invent new variable names. Do NOT deviate from the design tokens defined in that file.
|
||||||
|
> The canonical variable reference: `--lt-accent-orange`, `--lt-accent-cyan`, `--lt-accent-green`, `--lt-glow-orange`, `--lt-box-glow-*`, `--lt-border-color`, etc.
|
||||||
|
> Reference implementation for code patterns: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)
|
||||||
|
> This rule applies to EVERY task in this file without exception.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
- `[AUDIT REQUIRED]` — at least one assumption in the description needs code/server verification before implementing
|
- `[AUDIT REQUIRED]` — at least one assumption needs code/server verification before implementing
|
||||||
- `[UPSTREAM CHECK]` — may already be in upstream Cinny mainline; confirm before building
|
- `[SERVER CHECK]` — depends on a Synapse feature or MSC; verify on `matrix.lotusguild.org`
|
||||||
- `[SERVER CHECK]` — depends on a Synapse feature or MSC that may not be enabled on `matrix.lotusguild.org`
|
- `[LOW PRIORITY]` — implement after all higher-priority items
|
||||||
- `[LOW PRIORITY]` — agreed to add but deprioritized; implement after everything else
|
- `[EXTREME COMPLEXITY]` — multi-sprint, plan separately before touching
|
||||||
- `[EXTREME COMPLEXITY]` — multi-sprint, architectural; plan separately before touching
|
- `[BLOCKED]` — cannot build until a server upgrade, upstream MSC, or dependency resolves
|
||||||
|
- `[IMPROVE]` — feature exists in upstream Cinny; this task enhances it for Lotus Chat
|
||||||
|
|
||||||
Status: `[ ]` pending · `[~]` in progress · `[x]` completed
|
Status: `[ ]` pending · `[~]` in progress · `[x]` completed
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## AUDIT RESULTS — completed June 2026
|
||||||
|
|
||||||
|
### Server Status
|
||||||
|
- **Synapse version:** `1.153.0` (released 2026-05-19) — **FULLY UP TO DATE**, no upgrade needed
|
||||||
|
- **Matrix spec reported:** up to `v1.12` formally, but newer MSC features available via `unstable_features`
|
||||||
|
- **MSC feature flags confirmed ON:** `msc4140` (delayed messages) · `msc3771` (thread receipts) · `msc3440.stable` (threading) · `msc4133.stable` (extended profiles) · `simplified_msc3575` (sliding sync)
|
||||||
|
- **MSC feature flags confirmed OFF:** `msc4306` (thread subscriptions — BLOCKED) · `msc3882` · `msc3912` · `msc4155`
|
||||||
|
- **MSC3266** (room summary, v1.15): endpoint returned 404 — NOT available on this server
|
||||||
|
- **MSC3765** (rich room topics, v1.15): NOT available as stable, but client-side rendering is still worth doing
|
||||||
|
- **MSC3892** (relation redaction): not listed in flags — NOT supported, feature BLOCKED
|
||||||
|
- **MSC4260** (report user, v1.14): server at v1.12 formally — NOT available as spec endpoint; **however** report user already exists upstream in Cinny (message reporting via `reportEvent`)
|
||||||
|
- **MSC4151** (report room, v1.12): merged at exactly v1.12 — should be available ✅
|
||||||
|
|
||||||
|
### Upstream Cinny Features Confirmed (exist in upstream — only improve, don't re-implement)
|
||||||
|
| Feature | Location in upstream | Lotus improvement task |
|
||||||
|
|---|---|---|
|
||||||
|
| "Jump to Latest" button | `RoomTimeline.tsx:2180-2192` | #104 — add unread count + animation |
|
||||||
|
| Mark rooms as read (per section) | `Home.tsx:73-102`, `DirectTab.tsx:29-61` | None needed |
|
||||||
|
| Room upgrade / tombstone banner | `RoomTombstone.tsx`, `RoomUpgrade.tsx` | None needed |
|
||||||
|
| Visual speaking indicator | `useCallSpeakers.ts:8-60`, `MemberSpeaking.tsx:1-78` | #107 — TDS animated ring |
|
||||||
|
| Image + video spoilers (blur/reveal) | `ImageContent.tsx`, `VideoContent.tsx` | #105 — smooth CSS transition |
|
||||||
|
| Report message per event | `Message.tsx:588-709` — `mx.reportEvent()` | #106 — add category selector |
|
||||||
|
| Drag-and-drop file upload | `useFileDrop.ts` — works but overlay bug | #73 — fix overlay dismiss |
|
||||||
|
| Typing indicator (animated dots) | `TypingIndicator.tsx`, `TypingIndicator.css.ts` | #108 — TDS orange dots |
|
||||||
|
| Pinned messages count badge | Confirmed in upstream header icon | None needed |
|
||||||
|
|
||||||
|
### Upstream Cinny Features Confirmed MISSING (we should build these)
|
||||||
|
Quick Switcher, Sidebar filter, Favorite rooms, Invite link generator, Edit history modal,
|
||||||
|
Export history, Room preview before joining, Suggested rooms display, Server notices styling,
|
||||||
|
DM last-message preview, Media gallery, Knock-to-join full UX
|
||||||
|
|
||||||
|
### Code Architecture Facts (relevant to implementation)
|
||||||
|
| Finding | Impact |
|
||||||
|
|---|---|
|
||||||
|
| `folds AvatarImage` does NOT accept children | Avatar overlays/frames must wrap the Avatar component externally, not nest inside it |
|
||||||
|
| Sidebar `SidebarItem` has `translateX` on hover | CSS `backdrop-filter` won't work on sidebar items directly — apply to parent wrapper instead |
|
||||||
|
| Element Call bridge has NO join/leave participant events | Join/leave sounds (#89) must use `m.call.member` Matrix room state events instead |
|
||||||
|
| Element Call bridge has NO audio level events | Speaking indicator uses CSS polling of EC iframe DOM — no direct event bridge |
|
||||||
|
| No in-app toast system exists anywhere | Toast redesign (#80) must build a full `ToastProvider` + queue system from scratch |
|
||||||
|
| Voice message player: `AudioContent.tsx:44-223` | Speed control (#8): add `playbackRate` on the hidden `<audio>` element at line 217 |
|
||||||
|
| Notification sounds: 2 hardcoded `.ogg` files | Custom sounds (#22): replace file path with settingsAtom value |
|
||||||
|
| Chat backgrounds: `chatBackground.ts`, applied to `<Page>` in `RoomView.tsx` | Animated wallpapers (#77): add new entries returning CSS animation keyframe strings |
|
||||||
|
| Push rule UI: mode switcher only, no custom rule creation | Full push rule editor (#61) is a significant build from scratch |
|
||||||
|
| URL preview: `urlPreview: true` default, `encUrlPreview: false` default | Task #49: only need to change `encUrlPreview` default to `true` + add warning text |
|
||||||
|
| Private read receipts: `ReceiptType.ReadPrivate` already in SDK | Task #34: very simple — `markAsRead()` in `notifications.ts` already has `privateReceipt` param |
|
||||||
|
| Right-click room menu: 6 items (Mark read, Notifications, Invite, Copy Link, Settings, Leave) | Task #102: add Mute-with-duration submenu and consolidate |
|
||||||
|
| Glassmorphism: sidebar uses `translateX` transform | Must apply `backdrop-filter` to a parent div, not the sidebar element itself |
|
||||||
|
| JetBrains Mono: NOT bundled, relies on system fonts | Font selector (#98): must bundle fonts as `public/font/*.woff2` files |
|
||||||
|
| GIF links (Giphy/Tenor): render as generic OG preview cards, NOT auto-embedded | Task #42: inline GIF embed needs to be built |
|
||||||
|
| Composer toolbar buttons (in order): Formatting, Emoji/Sticker, GIF, Location, Voice, Send | Task #43: configurable toolbar is straightforward — buttons are a sequential array |
|
||||||
|
| Message hover toolbar: quick reactions row already exists inside Menu component | Task #92: quick reaction bar is already partially there via `MessageQuickReactions` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## COMPLETED
|
## COMPLETED
|
||||||
|
|
||||||
- [x] Audit & document: who reacted hover tooltip — README + landing page
|
- [x] Audit & document: who reacted hover tooltip — README + landing page
|
||||||
@@ -65,25 +132,20 @@ Cache the response in component state; no repeated fetches.
|
|||||||
|
|
||||||
### [ ] P0-3 · Server notices distinct rendering (m.server_notice)
|
### [ ] P0-3 · Server notices distinct rendering (m.server_notice)
|
||||||
**Spec:** CS-API §13.17, stable.
|
**Spec:** CS-API §13.17, stable.
|
||||||
**Confirmed:** Currently server notices arrive as plain DMs — indistinguishable from real messages.
|
**Audit result:** CONFIRMED MISSING. Only `M_CANNOT_LEAVE_SERVER_NOTICE_ROOM` error code exists in `src/app/cs-errorcode.ts` — no rendering differentiation. Server notices currently arrive as plain DMs.
|
||||||
**What:** Detect the `m.server_notice` event type in the timeline renderer. Render with:
|
**What:** The `m.server_notice` room type is set in `m.room.create` content (`type: 'm.server_notice'`). Detect it via `room.getType() === 'm.server_notice'`. Render with:
|
||||||
- A distinct "Server Notice" header badge (server icon + label)
|
- A distinct "Server Notice" header badge (server icon + label) in `RoomViewHeader.tsx`
|
||||||
- Slightly different background color (use `color.Warning` or neutral surface)
|
- Slightly different background color (use `color.Warning` or neutral surface)
|
||||||
- Composer disabled / read-only state in the server notice DM room
|
- Composer hidden/disabled in server notice rooms (check room type in `RoomInput.tsx`)
|
||||||
- Do NOT show "Send message" input in these rooms
|
**Where:** `src/app/features/room/RoomViewHeader.tsx` (badge), `src/app/features/room/RoomInput.tsx` (hide composer when `room.getType() === 'm.server_notice'`).
|
||||||
**Where:** `src/app/features/room/RoomTimeline.tsx` (event renderer), `src/app/features/room/RoomInput.tsx` (hide/disable composer).
|
|
||||||
**[AUDIT REQUIRED]** — Verify how matrix-js-sdk exposes `m.server_notice` — check if it's a room type (`m.server_notice` in `m.room.create`) or per-event content field.
|
|
||||||
**Complexity:** Low.
|
**Complexity:** Low.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### [ ] P0-4 · Reaction / relation redaction (MSC3892)
|
### [BLOCKED] P0-4 · Reaction / relation redaction (MSC3892)
|
||||||
**Spec:** MSC3892, in Final Comment Period.
|
**Spec:** MSC3892, in Final Comment Period.
|
||||||
**What:** When a user removes their reaction (un-reacts), currently a full `m.room.redaction` is sent targeting the reaction event. MSC3892 adds a cleaner relation-scoped redaction. Use the MSC3892 endpoint if the server supports it; fall back to standard redaction otherwise.
|
**Server check result:** `org.matrix.msc3892` is NOT in the server's unstable_features list — **NOT supported**. Current full-event redaction behavior is correct and should not be changed. This task is BLOCKED until the homeserver adds MSC3892 support. No action needed now.
|
||||||
Check server capability: `GET /_matrix/client/v1/capabilities` for `m.room.redaction` capability or probe `/_matrix/client/unstable/org.matrix.msc3892/`.
|
**Complexity:** N/A — blocked.
|
||||||
**[SERVER CHECK]** — Verify `matrix.lotusguild.org` supports MSC3892. If not, no change is needed (current behavior is fine); if yes, use the cleaner endpoint.
|
|
||||||
**Where:** Wherever `onReactionToggle` sends the redaction — likely `src/app/features/room/RoomTimeline.tsx` or a hook.
|
|
||||||
**Complexity:** Low — conditional API call swap.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -173,12 +235,11 @@ If any step is broken, fix it. If all working correctly, close this task with no
|
|||||||
---
|
---
|
||||||
|
|
||||||
### [ ] P0-12 · URL Preview default settings + security warning
|
### [ ] P0-12 · URL Preview default settings + security warning
|
||||||
**What:** In Settings → Privacy (or Messaging), the URL preview toggle should default to ON for both regular and encrypted rooms. Next to the encrypted-room toggle, add a one-sentence security note:
|
**Audit result:** `settings.ts` line 103: `urlPreview: true` (already on by default) · line 104: `encUrlPreview: false` (encrypted rooms OFF by default).
|
||||||
> "URL previews in encrypted rooms are fetched by your homeserver, which sees the URL but not the message context."
|
**What:** Change `encUrlPreview` default to `true` in `src/app/state/settings.ts`. Add a one-sentence security note next to the encrypted-room toggle in the settings UI:
|
||||||
This matches Element's approach of informed consent rather than silent disabling.
|
> "URL previews in encrypted rooms are fetched by your homeserver, which sees the URL but not the message content."
|
||||||
**[AUDIT REQUIRED]** — Find where URL preview settings are stored in `settingsAtom`. Find the settings UI for URL previews. Confirm current defaults (may already be on by default for non-encrypted rooms).
|
**Where:** `src/app/state/settings.ts` line 104 (change default), settings UI file for URL preview toggles (find via grep for `encUrlPreview`).
|
||||||
**Where:** `src/app/state/settings.ts` (default values), `src/app/features/settings/` privacy/messaging panel.
|
**Complexity:** Very Low — one default value change + one sentence of UI text.
|
||||||
**Complexity:** Low — wording + default value change.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -933,31 +994,62 @@ All toggleable manually in Settings → Appearance regardless of date. Respects
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## BLOCKED FEATURES (waiting on server/MSC support)
|
||||||
|
|
||||||
|
These features are confirmed desirable but cannot be built until the listed dependency is resolved.
|
||||||
|
Check back after each Synapse upgrade — re-run `/matrix/client/versions` and `unstable_features` to see if they've become available.
|
||||||
|
|
||||||
|
### [BLOCKED] · Reaction / Relation Redaction (MSC3892)
|
||||||
|
**Blocked by:** `org.matrix.msc3892` = false on `matrix.lotusguild.org`
|
||||||
|
**What it would do:** Cleanly remove a reaction without redacting the parent message.
|
||||||
|
**Current behavior:** Full event redaction — acceptable fallback, no user-facing issue.
|
||||||
|
**Action when unblocked:** Find `onReactionToggle` redaction call site; swap in MSC3892 endpoint with fallback.
|
||||||
|
|
||||||
|
### [BLOCKED] · Room Preview Before Joining (MSC3266)
|
||||||
|
**Blocked by:** `GET /v1/rooms/{id}/summary` returns 404 — endpoint not available on this server
|
||||||
|
**What it would do:** Show room name, topic, avatar, member count before joining.
|
||||||
|
**Action when unblocked:** Build pre-join preview card; trigger on unjoined room navigation.
|
||||||
|
|
||||||
|
### [BLOCKED] · Thread Subscriptions (MSC4306)
|
||||||
|
**Blocked by:** `org.matrix.msc4306` = false on `matrix.lotusguild.org`
|
||||||
|
**What it would do:** Follow a thread without posting; get notifications for replies.
|
||||||
|
**Action when unblocked:** Add "Follow thread" button in the thread panel header (depends on #11 Thread Panel).
|
||||||
|
|
||||||
|
### [BLOCKED] · Report User (MSC4260)
|
||||||
|
**Blocked by:** Server declares only spec v1.12; MSC4260 merged in v1.14 — endpoint may not exist
|
||||||
|
**What it would do:** Report a specific user to homeserver admins (separate from reporting a message).
|
||||||
|
**Note:** Report Message already exists in upstream Cinny. This would add Report User to the profile panel.
|
||||||
|
**Action when unblocked:** Test `POST /_matrix/client/v3/users/{userId}/report`; if 200, add button to user profile.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## AUDITS PENDING
|
## AUDITS PENDING
|
||||||
|
|
||||||
Tasks that require investigation before any implementation:
|
### [x] Audit-1 · Suggested rooms in Space Lobby — CONFIRMED MISSING (build task #51 created)
|
||||||
|
|
||||||
### [ ] Audit-1 · Suggested rooms in Space Lobby (may be upstream)
|
### [x] Audit-2 · Room upgrade / tombstone UX — CONFIRMED EXISTS in upstream (RoomTombstone.tsx, RoomUpgrade.tsx)
|
||||||
Check `src/app/pages/client/space/` and space room list components for `m.space.child` `suggested: true` handling. If upstream Cinny already shows suggested rooms, close this task.
|
|
||||||
|
|
||||||
### [ ] Audit-2 · Room upgrade / tombstone UX (may be upstream)
|
|
||||||
Search `RoomTimeline.tsx` and event renderers for `m.room.tombstone` handling. If upstream Cinny already shows a "room upgraded" banner and disables the composer, close this task.
|
|
||||||
|
|
||||||
### [ ] Audit-3 · Profile banner image — Matrix protocol support
|
### [ ] Audit-3 · Profile banner image — Matrix protocol support
|
||||||
Research whether Matrix spec or MSC4133 (v1.16) defines a standard profile banner field. If no cross-client standard exists, do not implement. Report findings.
|
Research whether Matrix spec or MSC4133 (v1.16) defines a standard profile banner field. `uk.tcpip.msc4133.stable = true` on our server — check if a `banner_url` or similar field is defined. If no cross-client standard exists, do not implement.
|
||||||
|
|
||||||
### [ ] Audit-4 · Visual speaking indicator in voice calls
|
### [x] Audit-4 · Visual speaking indicator — CONFIRMED EXISTS (useCallSpeakers.ts, MemberSpeaking.tsx). TDS improvement task #107 created.
|
||||||
Check Element Call participant UI and Cinny call view for existing speaking indicator. If present, determine if TDS styling is needed. If absent, implement animated speaking ring.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## IMPLEMENTATION NOTES
|
## IMPLEMENTATION NOTES
|
||||||
|
|
||||||
### Design Rules (non-negotiable)
|
### ⚠️ TDS DESIGN LAW (repeated here for emphasis)
|
||||||
- All TDS (Lotus Terminal theme) styling must come from `/root/code/web_template/base.css` CSS variables and token classes — do NOT invent new colors or patterns
|
> Every TDS color, animation, glow, border, shadow, and font value MUST come from `/root/code/web_template/base.css`.
|
||||||
- All new components must respect both TDS dark and TDS light modes
|
> Never hardcode hex values. Never invent CSS variable names.
|
||||||
- Code syntax highlighting token classes: `.tok-kw .tok-str .tok-num .tok-cmt .tok-fn` (see web_template)
|
> Key variables: `--lt-accent-orange` · `--lt-accent-cyan` · `--lt-accent-green` · `--lt-glow-*` · `--lt-box-glow-*` · `--lt-border-color` · `--lt-font-mono`
|
||||||
- Reference implementation for patterns: `/root/code/tinker_tickets/`
|
> Reference implementation: `/root/code/tinker_tickets/` (markdown.js, base.js, ticket.css)
|
||||||
|
> This applies without exception to every task marked `[IMPROVE]`, `[Build]`, or any UI change.
|
||||||
|
|
||||||
|
### Design Rules
|
||||||
|
- All new components must respect both TDS dark (`LotusTerminalTheme`) and TDS light (`LotusTerminalLightTheme`) modes
|
||||||
|
- Non-TDS theme work (custom accent color, theme presets) uses vanilla-extract theme files — match the pattern in `src/lotus-terminal.css.ts`
|
||||||
|
- Code syntax highlighting token classes: `.tok-kw .tok-str .tok-num .tok-cmt .tok-fn` (defined in `web_template/base.css`)
|
||||||
|
- `folds AvatarImage` does NOT accept children — wrap Avatar components externally for overlays/frames/borders
|
||||||
|
|
||||||
### CI/CD Pipeline
|
### CI/CD Pipeline
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user