feat: seasonal theme overlays + improved animated chat backgrounds
Adds 11 CSS-only seasonal overlays (Halloween, Christmas, New Year, Autumn, April Fool's, Lunar New Year, Valentine's Day, St. Patrick's Day, Earth Day, Deep Space, Retro Arcade) with date-based auto-detection and a manual override dropdown in Settings → Appearance → Seasonal Theme. All themes respect prefers-reduced-motion. SeasonalEffect mounts at z-index 9997 in App.tsx. Also rewrites all 5 animated chat background keyframes for smoother, more organic motion: Digital Rain gains a phosphor glow flicker; Star Drift now loops each layer by exactly its own tile size (no more seam); Grid Pulse adds an independent brightness oscillation at a prime period; Aurora Flow drives all four gradient layers through distinct paths; Fireflies adds glow-pulse and opacity-blink animations at prime periods for unsynchronised bioluminescence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+76
-47
@@ -1,69 +1,98 @@
|
||||
# Lotus Chat — Bug Report & Technical Audit
|
||||
|
||||
**Date:** June 2026
|
||||
|
||||
This document tracks identified bugs, edge cases, and architectural discrepancies.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Resolved Issues (Recently Fixed)
|
||||
## 🛡️ Critical Security & Privacy Regressions
|
||||
|
||||
- **GIF Sending Bypasses E2EE**: Fixed in `RoomInput.tsx`.
|
||||
- **Scheduled Messages Bypass E2EE**: Fixed in `scheduledMessages.ts`.
|
||||
- **Drag-and-Drop Overlay Persistence**: Fixed in `useFileDrop.ts`.
|
||||
- **Stale Member List in Verification Banner**: Fixed in `useDeviceVerificationStatus.ts`.
|
||||
- **Incomplete Python Comment Highlighting**: Fixed in `syntaxHighlight.ts`.
|
||||
- **Search Button Hidden in E2EE Rooms**: Fixed in `RoomViewHeader.tsx`.
|
||||
- **TDS Design Law Violations (Hardcoded Hex)**: Fixed in `GifPicker.tsx` and `VoiceMessageRecorder.tsx`.
|
||||
- **Recent Emoji Sort Order**: Fixed in `recent-emoji.ts` (recency order, not frequency).
|
||||
- **Encrypted Search Misses Historic Events**: Fixed in `useLocalMessageSearch.ts`.
|
||||
- **Presence Updater Base URL Hack**: Fixed in `usePresenceUpdater.ts`.
|
||||
- **Presence Badge Accessibility**: Fixed in `Presence.tsx` (`aria-label` on badge).
|
||||
- **Presence Updater Wipes Custom Status**: Fixed in `usePresenceUpdater.ts` (removed `status_msg: ''`).
|
||||
- **Manifest Main Icon Paths 404**: Fixed in `public/manifest.json` (`./public/android/` → `./res/android/`). Shortcut icon was already correct.
|
||||
### 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.
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Critical Security & Logic
|
||||
## 🚩 Functional & Logic Bugs
|
||||
|
||||
### 1. Edit History Broken for E2EE
|
||||
### 1. Presence Updater Reverts Status Updates
|
||||
**File:** `src/app/hooks/usePresenceUpdater.ts` (Line 20)
|
||||
**Status:** High Priority
|
||||
|
||||
**File:** `src/app/features/room/message/EditHistoryModal.tsx`
|
||||
**Status:** **FIXED**
|
||||
* **Issue:** The `storedStatus` variable is captured once when the `useEffect` starts.
|
||||
* **Impact:** If a user updates their status message in the Profile settings, the presence updater hook continues to use the *old* status message from its closure. Every time the user moves their mouse/activity, the hook sends `setOnline` with the stale status, reverting the user's change.
|
||||
* **Recommended Fix:**
|
||||
1. Read the status from `localStorage` inside the `setOnline`/`setUnavailable` functions rather than at the top of the effect.
|
||||
|
||||
- **Issue:** The modal fetches edit history via raw `fetch`. Edit events not found in the room cache were constructed from raw encrypted content and never decrypted.
|
||||
- **Fix:** Each newly constructed `MatrixEvent` is now passed through `mx.decryptEventIfNeeded()` before rendering when `evt.isEncrypted()` is true.
|
||||
### 2. Audio Playback Rate Reset
|
||||
**File:** `src/app/components/message/content/AudioContent.tsx` (Line 97)
|
||||
**Status:** UX Bug
|
||||
|
||||
### 2. Service Worker Ephemeral Sessions
|
||||
* **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.
|
||||
|
||||
**File:** `src/sw.ts`
|
||||
**Status:** **NOT A BUG — by design**
|
||||
### 3. Room Insights are Static (No Live Updates)
|
||||
**File:** `src/app/features/room-settings/RoomInsights.tsx` (Line 60)
|
||||
**Status:** Medium Priority
|
||||
|
||||
- The `sessions` Map is intentionally in-memory. The main window re-posts the session to the SW via `postMessage` on every load. Persisting access tokens in SW IndexedDB would duplicate credential storage unnecessarily and is not required for the current feature set.
|
||||
|
||||
---
|
||||
|
||||
## 📱 PWA & Mobile Issues
|
||||
|
||||
### 1. No PWA Precaching (Offline Mode Broken)
|
||||
|
||||
**File:** `src/sw.ts`, `vite.config.js`
|
||||
**Status:** **DEFERRED — out of scope**
|
||||
|
||||
- Full offline Matrix requires persisting sync state, E2EE keys, and an event send queue. The SW exists for authenticated media and notifications, which it handles correctly. Adding Workbox precaching is a multi-sprint project with limited benefit for a Matrix client.
|
||||
|
||||
### 2. PiP Resize Impossible on Mobile
|
||||
* **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:** **FIXED**
|
||||
**Status:** Logic Bug
|
||||
|
||||
- **Issue:** Resize corner `onMouseDown` handlers did not fire on touch devices.
|
||||
- **Fix:** Added `handleResizeTouchStart` using touch events with the same geometry math extracted into a shared `applyResize` helper. `onTouchStart` is now wired to all four resize corners.
|
||||
* **Issue:** Joining a static voice room (Public Space channel) triggers the "Incoming Call" ringing animation and sound. This should only occur for "StartedByUser" intents (DMs and Private Group Calls).
|
||||
* **Root Cause:** The ringing logic does not distinguish between persistent voice rooms and user-initiated calls.
|
||||
* **Recommended Fix:** Check `room.getJoinRule()` or check for the `m.space.parent` event. If the room is a public voice channel, suppress the ringing animation.
|
||||
|
||||
### 3. Double Background Animation (GPU Waste)
|
||||
---
|
||||
|
||||
**File:** `src/app/pages/client/SidebarNav.tsx`, `src/app/features/room/RoomView.tsx`
|
||||
**Status:** **FIXED**
|
||||
## 🎨 UI/UX & Visual Consistency
|
||||
|
||||
- **Issue:** When Glassmorphism is enabled, the chat background was rendered on both `document.body` and `RoomView`, running the same CSS animation twice.
|
||||
- **Fix:** `RoomView` now reads the `glassmorphismSidebar` setting and skips applying `chatBgStyle` when it is active, relying entirely on the `document.body` background that `SidebarNav` already mirrors.
|
||||
### 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:** UI Consistency
|
||||
|
||||
* **Issue:** The dropdowns for "Join & Leave Sounds" and "UI Font" use raw HTML `<select>` elements, which look different from the custom-styled `Menu` used elsewhere.
|
||||
* **Recommended Fix:** Replace raw selects with the `Menu` + `PopOut` pattern used in the "Message Layout" setting.
|
||||
|
||||
### 4. No Camera Focus During Screenshare
|
||||
**File:** `src/app/features/call/CallControls.tsx`
|
||||
**Status:** UX Bug
|
||||
|
||||
* **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.
|
||||
* **Recommended Fix:** Implement a "Pin/Focus" toggle on participant tiles that overrides the automatic screenshare spotlight.
|
||||
|
||||
Reference in New Issue
Block a user