Files
cinny/LOTUS_BUGS.md
T
jared e9a970a75b
CI / Build & Quality Checks (push) Successful in 10m22s
Trigger Desktop Build / trigger (push) Successful in 7s
fix: settings dropdowns, background animations, ringing, avatar decorations
Settings dropdowns (Bug #3):
- Add reusable SettingsSelect component using Menu+PopOut+FocusTrap — exact
  same pattern as Message Layout, so all dropdowns look consistent
- Replace raw <select> for Seasonal Theme, UI Font, AFK Timeout, and
  Join & Leave Sounds with SettingsSelect

Animated chat backgrounds bleeding onto content (Bug #6 / #7):
- Remove filter:brightness() and opacity animations from chatBackground.ts
  (animRainGlowKeyframe, animGridBrightnessKeyframe, animFirefliesGlowKeyframe,
  animFirefliesBlinkKeyframe). These were applied to the Page element which
  caused ALL descendants (messages, composer) to flash in sync.
  Also created a CSS stacking context on Page that pushed SeasonalEffect
  (position:fixed; z-index:9997) behind the animated background layer.
- Only backgroundPosition / backgroundSize animations remain — safe, do not
  affect descendants, and do not create stacking contexts.
- Remove now-unused animation keyframe imports from chatBackground.ts.

Voice ringing in persistent rooms (Bug #5):
- Narrow the ringing condition from (Invite|Knock|Restricted) to only Invite,
  matching exactly the rooms where the call button is visible.
- Add room.isCallRoom() early-exit so m.join_rule:call rooms never ring.

Avatar decoration images not loading (Bug #8):
- Change loading="lazy" → loading="eager" in DecorationPreviewCell.
  Lazy loading does not reliably trigger for images inside nested overflow
  scroll containers (the settings panel scroll area), so images never loaded.

Docs: LOTUS_BUGS.md updated with root cause and resolution for all 5 new bugs.
Docs: LOTUS_TODO.md adds P5-35/P5-36 (deferred desktop notification/jump list).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 12:20:47 -04:00

132 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lotus Chat — Bug Report & Technical Audit
**Date:** June 2026
This document tracks identified bugs, edge cases, and architectural discrepancies found during the audit of the Lotus Chat codebase. Recommended fixes are provided for each item.
---
## 🛡️ Critical Security & Privacy Regressions
### 1. E2EE Bypass in Media Gallery Downloads
**File:** `src/app/features/room/MediaGallery.tsx` (Line 855)
**Status:** **CRITICAL**
* **Issue:** The "Download" button in the Files tab uses `mxcUrlToHttp` directly and clicks an `<a>` link.
* **Impact:** In encrypted rooms, this downloads the encrypted ciphertext rather than the decrypted file. Users cannot open the downloaded files.
* **Recommended Fix:**
1. Check if the event is encrypted.
2. If encrypted, use the `decryptAttachment` logic (similar to `useDecryptedMediaUrl`) to decrypt the file in memory.
3. Use `file-saver` or a Blob URL to trigger the download of the decrypted plaintext.
### 2. Privacy Leak in URL Previews
**File:** `src/app/components/url-preview/UrlPreviewCard.tsx` (Line 1655)
**Status:** **PRIVACY RISK**
* **Issue:** Generic URL preview cards fetch favicons directly from `https://www.google.com/s2/favicons?domain=...`.
* **Impact:** This leaks the user's browsing/chat activity (domains of links they see) to Google. It bypasses the "proxied through Matrix" privacy standard.
* **Recommended Fix:** Use the proxy URL returned by the Matrix `/_matrix/media/v3/preview_url` endpoint instead of contacting Google directly.
---
## 🚩 Functional & Logic Bugs
### 1. Presence Updater Reverts Status Updates
**File:** `src/app/hooks/usePresenceUpdater.ts` (Line 20)
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** The `storedStatus` variable was captured once when the `useEffect` started.
* **Impact:** If a user updated their status message in Profile Settings, the hook would continue broadcasting the old message on every activity event, silently reverting the change.
* **Fix Applied:** Replaced the single `localStorage.getItem` read with a `readStatus()` function called inside every `setOnline` and `setUnavailable` invocation, ensuring the current value is always used.
### 2. Audio Playback Rate Reset
**File:** `src/app/components/message/content/AudioContent.tsx` (Line 97)
**Status:** UX Bug
* **Issue:** The `playbackRate` is set in a `useEffect` that only depends on `[playbackSpeed]`.
* **Impact:** If a user selects a playback speed *before* the audio blob has finished loading, the `<audio>` element may reset its rate to 1.0 once the `<source>` is added.
* **Recommended Fix:** Add `srcState.data` to the `useEffect` dependencies or set the `playbackRate` in an `onCanPlay` handler on the audio element.
### 3. Room Insights are Static (No Live Updates)
**File:** `src/app/features/room-settings/RoomInsights.tsx` (Line 60)
**Status:** Medium Priority
* **Issue:** Stats are calculated in a `useMemo` that only depends on `[room]`.
* **Impact:** If new messages arrive while the Insights page is open, the statistics (message counts, top participants, etc.) do not update.
* **Recommended Fix:** Add a listener for `RoomEvent.Timeline` inside the component to trigger a recalculation when new events are added to the room.
### 4. Incorrect Ringing in Voice Rooms
**File:** `src/app/components/CallEmbedProvider.tsx`
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** Joining a static voice room (Public Space channel) triggered the "Incoming Call" ringing animation and sound.
* **Root Cause:** `getStateEvent(room, StateEvent.SpaceParent)` always returned `undefined` because `m.space.parent` events use the parent space's room ID as the state key, not an empty string. The ringing suppression check silently failed.
* **Fix Applied:** Replaced `getStateEvent` with `getStateEvents` (plural), which returns all events of a given type regardless of state key. A room with any `m.space.parent` event is correctly identified as a space channel and suppresses ringing.
---
## 🎨 UI/UX & Visual Consistency
### 1. Hardcoded Primary Color in Polls
**File:** `src/app/components/message/content/PollContent.tsx` (Line 245)
**Status:** TDS Violation
* **Issue:** Uses `rgba(var(--mx-primary-rgb, 0,132,255), ...)` for selected options and borders.
* **Impact:** Polls look like standard Cinny and ignore the Lotus Terminal Design System (TDS) colors.
* **Recommended Fix:** Use `var(--lt-accent-cyan)` or the primary theme accent color.
### 2. Inaccessible Room Menu on Mobile
**File:** `src/app/features/room-nav/RoomNavItem.tsx` (Line 643)
**Status:** **MOBILE BUG**
* **Issue:** The room menu icon (`VerticalDots`) is hidden on mobile because `hover` is never active.
* **Impact:** Mobile users cannot access room settings, mark as read, or leave rooms from the sidebar.
* **Recommended Fix:** Ensure the menu button is visible on mobile for the active room or provide an alternative trigger.
### 3. Inconsistent Settings Dropdown Styling
**File:** `src/app/features/settings/general/General.tsx`
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** The dropdowns for "Join & Leave Sounds", "UI Font", and "Seasonal Theme" used raw HTML `<select>` elements, which render differently from the custom-styled `Menu`+`PopOut` used for "Message Layout" and other settings.
* **Fix Applied:** All three raw `<select>` elements replaced with a reusable `SettingsSelect` component using the Menu+PopOut+FocusTrap pattern consistent with the rest of the settings UI.
### 4. No Camera Focus During Screenshare
**File:** `src/app/features/call/CallControls.tsx`
**Status:** UX Bug — blocked by Element Call internals
* **Issue:** When someone is screensharing and another participant turns on their camera, there is no way to switch the primary display to the camera or go fullscreen on it.
* **Root Cause:** Element Call's spotlight/layout is controlled internally by EC. Lotus Chat injects the call iframe and cannot easily override EC's participant tile behavior without forking the EC widget.
* **Recommended Fix:** Implement a "Pin/Focus" toggle on participant tiles that overrides the automatic screenshare spotlight — requires EC upstream changes or a custom message bridge.
### 5. Ringing Modal Fires in Persistent Voice Rooms
**File:** `src/app/components/CallEmbedProvider.tsx` (line 337342)
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** Joining a persistent voice room (not a DM or transient group call) showed the incoming call ringing modal and animation.
* **Root Cause:** The `isPrivateGroup` condition included `JoinRule.Restricted` and `JoinRule.Knock` rooms. Lotus Guild voice rooms are `Restricted` join-rule rooms. Their `m.space.parent` state event was being checked but some rooms were set up with only the space-side `m.space.child` relationship, leaving no `m.space.parent` on the room itself — so they passed as `isPrivateGroup` and triggered ringing.
* **Fix Applied:** Narrowed `isPrivateGroup` to only `JoinRule.Invite` to match the exact set of rooms where the call button is shown. Also added `room.isCallRoom()` early-exit so rooms with `m.join_rule.call` type never ring.
### 6. Animated Chat Backgrounds Affect Message Content
**File:** `src/app/features/lotus/chatBackground.ts`
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** Animated backgrounds that use `filter: brightness()` or `opacity` animations (Digital Rain glow, Grid Pulse brightness, Fireflies glow/blink) applied those effects to the entire `<Page>` element, causing all message content and the composer to flash/flicker in sync with the animation.
* **Root Cause:** `filter` and `opacity` CSS properties affect an element AND all its descendants. Applying these as part of the `animation` shorthand on the `Page` container made them "inherited" visually by everything inside the room view.
* **Side Effect:** `filter` animation also created a CSS stacking context on Page, which pushed Seasonal Theme overlays (position:fixed; z-index:9997) behind the Page compositor layer.
* **Fix Applied:** Removed `animRainGlowKeyframe`, `animGridBrightnessKeyframe`, `animFirefliesGlowKeyframe`, and `animFirefliesBlinkKeyframe` from `chatBackground.ts`. Only `backgroundPosition` / `backgroundSize` animations remain — these are safe and do not affect descendants or create stacking contexts.
### 7. Seasonal Themes Display Behind Chat Background
**File:** `src/app/components/seasonal/SeasonalEffect.tsx`
**Status:** ✅ RESOLVED (June 2026) — root cause was Bug #6
* **Issue:** Seasonal theme overlays (position:fixed; z-index:9997) appeared behind animated chat backgrounds.
* **Root Cause:** The `filter` animation on `<Page>` created a CSS stacking context, causing Page's GPU compositing layer to render above the fixed-position seasonal overlay in some browsers. Removing the filter animations (Bug #6 fix) resolves the stacking context issue.
* **Fix Applied:** See Bug #6. No additional changes to SeasonalEffect required.
### 8. Avatar Decoration Images Not Rendering in Settings
**File:** `src/app/features/settings/account/ProfileDecoration.tsx`
**Status:** ✅ RESOLVED (June 2026)
* **Issue:** Under Settings → Account → Avatar Decoration, no decoration images were visible.
* **Root Cause:** The `DecorationPreviewCell` used `loading="lazy"` on decoration images. The browser's lazy-loading algorithm determines image visibility from the viewport, but the decoration grid is inside a nested `overflowY: auto` scroll container inside a settings panel — the browser did not correctly detect these images as near the viewport and never triggered them to load.
* **Fix Applied:** Changed `loading="lazy"` to `loading="eager"` in `DecorationPreviewCell`. The settings panel is user-initiated, so eager loading is appropriate.