docs: comprehensive audit pass — all 5 agent findings integrated into TODO
CI / Build & Quality Checks (push) Failing after 5m42s

Key findings:
- Jump to Date (task #7): DELETED — JumpToTime.tsx fully implemented upstream,
  wired in RoomViewHeader.tsx:215
- useUnverifiedDeviceCount() hook EXISTS (useDeviceVerificationStatus.ts:65) —
  task #65 is trivial
- useCallMembersChange() hook (useCall.ts:37-52) handles join/leave sounds
  via MatrixRTCSessionEvent.MembershipsChanged — correct approach for #89
- MessageQuickReactions already in hover toolbar (Message.tsx:146-184) — #92
  simpler than expected
- knockSupported() utility exists (matrix.ts:376) — #58 only needs RoomIntro button
- StateEventEditor in DevTools can already edit m.room.server_acl — #69 is a UX wrapper
- getMatrixToRoom() in matrix-to.ts already generates invite URLs — #24 just needs QR
- Glassmorphism: sidebar container safe for backdrop-filter (translateX only on items)
- Animated backgrounds: must use ::before pseudo-element, not backgroundImage
- matrix-js-sdk has no arbitrary profile field setters — #62 needs raw HTTP
- Toast system: build from scratch, insert at App.tsx:65 after OverlayContainerProvider
- JetBrains Mono already loaded via Google Fonts CDN in index.html:33
- MSC4151 report room endpoint confirmed live (405 on GET = POST-only endpoint exists)
- /.well-known/matrix/support not configured — needs server file creation + client reads

Full file reference table added with 30+ key file paths for all planned features.
Corrected 5 previously wrong architecture assumptions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 13:34:34 -04:00
parent c9a3edc142
commit 22e7252de8
+69 -18
View File
@@ -62,26 +62,77 @@ Quick Switcher, Sidebar filter, Favorite rooms, Invite link generator, Edit hist
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)
### Code Architecture Facts — Full Audit Results
#### Corrected facts (previous version had errors)
| Old assumption | Correct finding |
|---|---|
| ~~Join/leave sounds need m.call.member state events~~ | **Use `useCallMembersChange()` hook** at `src/app/hooks/useCall.ts:37-52` — subscribes to `MatrixRTCSessionEvent.MembershipsChanged`, receives old/new membership arrays |
| ~~Glassmorphism needs parent wrapper (translateX blocks filter)~~ | **SAFE to apply directly to sidebar container**`translateX` only on `SidebarItem` hover, not the sidebar container. Apply backdrop-filter to `Sidebar.css.ts:6-17` |
| ~~Avatar frames must wrap externally~~ | **Modify `UserAvatar` internally** — add optional `frameName?: string` prop; renders overlay inside component. Avoids 3 different wrapper implementations |
| ~~JetBrains Mono not bundled~~ | **Already loaded via Google Fonts CDN** in `index.html:33-35`. Other fonts: use `@fontsource` npm packages |
| ~~Animated backgrounds: add to backgroundImage~~ | **backgroundImage can't have @keyframes** — use CSS `::before` pseudo-element on `<Page>` component with `position:absolute, inset:0, z-index:-1` |
#### Confirmed facts
| 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` |
| `folds AvatarImage` does NOT accept children | Add frame/overlay inside `UserAvatar.tsx` component itself (see correction above) |
| No in-app toast system exists | Toast redesign (#80): build `ToastProvider` + Jotai atom queue; insert after `OverlayContainerProvider` at `App.tsx:65`; use `portalContainer` div from `index.html:101` |
| `useUnverifiedDeviceCount()` hook EXISTS | Task #65 is trivial: `src/app/hooks/useDeviceVerificationStatus.ts:65-106` — call it in `RoomInput.tsx` |
| Voice player: `AudioContent.tsx:44-223` | Task #8: `playbackRate` on hidden `<audio>` at line 217 |
| Notification sounds: 2 hardcoded `.ogg` files in `ClientNonUIFeatures.tsx` | Task #22: replace hardcoded paths with `settingsAtom` value |
| Chat backgrounds: `chatBackground.ts`, applied to `<Page>` in `RoomView.tsx:106` | Task #77: animated backgrounds need CSS class + `::before` pseudo-element approach |
| `KeywordMessages.tsx` already implements custom keyword push rules | Task #61: only non-keyword rule types need new UI |
| `StateEventEditor.tsx` in Developer Tools can already edit any state event | Task #69: build user-friendly ACL UI in Permissions tab, not from scratch |
| URL preview: `urlPreview: true`, `encUrlPreview: false` in settings.ts | Task #49: one-line default change + warning string |
| Private read receipts: `ReceiptType.ReadPrivate` in SDK, `markAsRead()` has param | Task #34: trivially simple |
| Right-click room menu: 6 items in `RoomNavItem.tsx:70-220` | Task #102: add Mute-duration submenu using `PopOut` same as Notifications item |
| GIF links render as generic OG preview cards | Task #42: inline GIF embed needs explicit URL pattern detection + `<img>` render |
| Toolbar buttons (in order): Attach, Formatting, Emoji/Sticker, GIF, Location, Voice, Send | Task #43: sequential array in `RoomInput.tsx` after/before props |
| `MessageQuickReactions` already in hover toolbar (4 recent emojis) | Task #92: increase limit, adjust layout position |
| `knockSupported()` utility EXISTS at `matrix.ts:376-391` | Task #58: just need "Request to Join" button in `RoomIntro.tsx:25-119` |
| `CallControl.setMicrophone(bool)` at `CallControl.ts:206-212` | Task #84: call this directly for AFK auto-mute |
| matrix-js-sdk has NO arbitrary profile field methods | Task #62: use `mx.http.authedRequest()` for MSC4133 raw HTTP calls |
| `JumpToTime.tsx` FULLY IMPLEMENTED and wired in `RoomViewHeader.tsx:215` | Task #7: DELETED — already upstream |
| Poll voting already implemented in `PollContent.tsx:189-213` | Task #9: only CREATE UI needed |
| `useRecentEmoji(mx, 4)` provides the quick reaction data | Task #92: same source as full emoji board |
| `getMatrixToRoom()` in `matrix-to.ts` already generates invite URLs | Task #24: just add QR code display to room settings |
| `/.well-known/matrix/support` not configured on server | Task #67: client reads gracefully if present; Jared must CREATE the file server-side |
| MSC4151 report room endpoint returned HTTP 405 on GET → POST-only → EXISTS | Task #59: endpoint is live, just needs POST with JSON body |
| `/timestamp_to_event` returned 401 (needs auth) → EXISTS | Jump to Date already works — task deleted as upstream |
| `useCallSpeakers.ts` uses CSS MutationObserver polling on EC iframe DOM | Task #107: can augment with TDS ring animation on top of existing data |
#### Key file quick reference
| What you need | File | Lines |
|---|---|---|
| Global keydown hook | `src/app/hooks/useKeyDown.ts` | whole file |
| Room navigation | `src/app/hooks/useRoomNavigate.ts` | 19-72 |
| All room IDs atom | `src/app/state/room-list/roomList.ts` | `allRoomsAtom` |
| Room unread counts | `src/app/state/room/roomToUnread.ts` | `roomToUnreadAtom` |
| Overlay portal provider | `src/app/pages/App.tsx` | 65 |
| Portal container div | `index.html` | 101 |
| Room settings tabs | `src/app/features/room-settings/RoomSettings.tsx` | 27-56 |
| State event read/write pattern | `src/app/features/common-settings/general/RoomEncryption.tsx` | 42-52 |
| Power level checker | `src/app/hooks/usePowerLevels.ts` | whole file |
| Slash command registration | `src/app/hooks/useCommands.ts` | 140-537 |
| Chat background picker | `src/app/features/settings/general/General.tsx` | 945-981 |
| Chat backgrounds definition | `src/app/features/lotus/chatBackground.ts` | whole file |
| Matrix.to URL builder | `src/app/plugins/matrix-to.ts` | `getMatrixToRoom()` |
| Media event content types | `src/app/types/matrix/common.ts` | 46-91 |
| Media URL conversion | `src/app/utils/matrix.ts` | `mxcUrlToHttp()` |
| Message pagination (search) | `src/app/features/message-search/useMessageSearch.ts` | 74-121 |
| Infinite pagination pattern | `src/app/features/message-search/MessageSearch.tsx` | 234-365 |
| Poll event format | `src/app/components/message/content/PollContent.tsx` | 1-320 |
| Theme class application | `src/app/hooks/useTheme.ts` | 25-60 |
| Animations file | `src/app/styles/Animations.css.ts` | whole file |
| Message status (EventStatus) | `src/app/features/room/message/Message.tsx` | 84-142 |
| Call member change events | `src/app/hooks/useCall.ts` | 37-52 |
| Mic control in calls | `src/app/plugins/call/CallControl.ts` | 206-212 |
| Device verification hook | `src/app/hooks/useDeviceVerificationStatus.ts` | 65-106 |
| Knock room support check | `src/app/utils/matrix.ts` | 376-391 |
| Room join button location | `src/app/components/room-intro/RoomIntro.tsx` | 25-119 |
| Notification mute via push rules | `src/app/hooks/useRoomsNotificationPreferences.ts` | 110-150 |
| Message text body CSS | `src/app/components/message/layout/layout.css.ts` | 182-205 |
---