- LOTUS_FEATURES.md: full reference of every custom Lotus feature with implementation details, file paths, and API notes - LOTUS_BUGS.md: audit of confirmed bugs with root causes and fixes - LOTUS_TODO_REFERENCE.md: technical implementation notes for backlog items - LOTUS_TODO.md: trim completed audit results section, link to FEATURES doc - README.md: rewrite to marketing-friendly feature list format; fix incorrect claim that screenshare auto-reverts view to grid (removed) Fix: auto-revert spotlight on screenshare was removed (600ms grid-click caused fullscreen to show avatars); corrected in LOTUS_FEATURES.md and removed from README.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8.4 KiB
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 & UI Bugs
1. Drag-and-Drop Overlay Persistence
File: src/app/hooks/useFileDrop.ts
Status: Confirmed (Backlog item #!BUG)
- Issue: The file drop overlay remains visible if a user drags a file over the browser window and then moves the mouse out of the window without dropping.
- Root Cause: The
dragleaveevent does not reliably decrement the internaldragCounterwhen the mouse leaves the browser viewport entirely. - Recommended Fix: Update the
handleDragLeavefunction to detect when the mouse has left the window by checking ifevt.relatedTargetis null.
2. Stale Member List in Verification Banner
File: src/app/hooks/useDeviceVerificationStatus.ts
Status: High Priority
- Issue: The "Unverified Device Warning" banner may fail to appear for users who join a room after it has already been opened in the client.
- Root Cause: The
memberIdsarray is memoized only onroom.roomId. New members joining the room do not trigger a recalculation of the list, meaning their devices are never checked. - Recommended Fix: Add the room's joined member count to the memoization dependencies.
3. Night Light Overlay Coverage (Portal Issue)
File: src/app/pages/App.tsx
Status: UI Consistency
- Issue: The Night Light (blue light filter) overlay is rendered inside the
#rootdiv. However, Cinny's modals, tooltips, and popouts are rendered inside a sibling#portalContainer. - Impact: Modals and tooltips will appear at full brightness, bypassing the filter.
- Recommended Fix: Move the
NightLightOverlaycomponent to the end ofdocument.bodyor utilize a Portal to render it inside#portalContainerwith a high z-index (e.g., 9999).
4. Decrypted Media Memory Leak (Gallery & Lightbox)
File: src/app/features/room/MediaGallery.tsx
Status: Performance / Memory
- Issue: Every image in the gallery history is decrypted and converted to a Blob URL simultaneously.
- Impact: Scrolling through long room histories can consume gigabytes of RAM, as Blob URLs are not revoked until the gallery is closed.
- Recommended Fix: Implement virtualization for the gallery grid. Only decrypt and create URLs for items currently in or near the viewport.
🎨 UI/UX & Visual Consistency
1. Search Button Hidden in E2EE Rooms
File: src/app/features/room/RoomViewHeader.tsx
Status: Major UX Regression
- Issue: The message search icon is hidden in encrypted rooms.
- Impact: Users cannot access the "Encrypted Room Search" feature (local cache scan) from the room header, even though the feature is implemented and functional in the search page.
- Recommended Fix: Remove the
!encryptedRoomcondition from the Search button renderer in the header.
2. TDS Design Law Violations (Hardcoded Hex)
Files: src/app/components/GifPicker.tsx, src/app/components/VoiceMessageRecorder.tsx
Status: Styling Integrity
- Issue: Multiple custom components use hardcoded hex values (e.g.,
#FF6B00,#060c14) instead of the CSS variables defined inlotus-terminal.css.ts. - Impact: These components will not adapt if theme tokens are updated in the central TDS file, and they bypass the "Design Law" established in the backlog.
- Recommended Fix: Replace all hardcoded hex values with
var(--lt-accent-orange),var(--lt-bg-secondary), etc.
3. Missing CSS Variable --bg-surface-variant
Files: src/app/features/message-search/MessageSearch.tsx, src/app/components/VoiceMessageRecorder.tsx
Status: UI Bug
- Issue: Components use
var(--bg-surface-variant), which is not defined in eitherindex.cssorlotus-terminal.css.ts. - Impact: Backgrounds for the voice recorder and search cache panels appear transparent or fall back to browser defaults.
- Recommended Fix: Define
--bg-surface-variantin both global themes and the TDS theme, or switch to using--bg-surface-low.
4. Recent vs. Top Emoji Logic Discrepancy
File: src/app/plugins/recent-emoji.ts
Status: Logic Inconsistency
- Issue: The "Quick Reactions" hover bar is described as showing the "3 most recently used emojis." However, the implementation sorts by
usage count, meaning it actually shows the "most frequently used" emojis. - Impact: If a user uses a new emoji, it will not appear in the quick reactions until its total usage count exceeds the current top 3. This contradicts user expectations for a "recently used" list.
- Recommended Fix: Update
getRecentEmojisto sort by the order in the array (which is unshifted inaddRecentEmoji) or add a timestamp to each emoji entry in the account data to allow true chronological sorting.
🔍 Technical Refinements
1. Incomplete Python Comment Highlighting
File: src/app/utils/syntaxHighlight.ts
Status: Medium Priority
- Issue: Python comments (
#) are only highlighted if they appear at the very start of a line. Inline comments likeprint("hello") # commentare treated as plain text. - Recommended Fix: Update the detection logic to allow
#after whitespace or tabs.
// Recommended
(i === 0 || code[i - 1] === '\n' || code[i - 1] === ' ' || code[i - 1] === '\t')
2. Duplicate Bookmarking Race Condition
File: src/app/hooks/useBookmarks.ts
Status: Data Integrity
- Issue: Rapidly clicking the bookmark button can trigger multiple
setAccountDatacalls that read from the same stale local cache, potentially overwriting each other. - Recommended Fix: Implement a queue or locking mechanism for account data updates to ensure atomicity.
3. Presence Updater Matrix Base URL Access
File: src/app/hooks/usePresenceUpdater.ts
Status: Best Practice
- Issue: The code uses a hacky cast:
(mx as unknown as { baseUrl: string }).baseUrl. - Recommended Fix: Use the standard SDK method
mx.getHomeserverUrl().
4. Encrypted Search Misses Historic Events
File: src/app/features/message-search/useLocalMessageSearch.ts
Status: Functional Limitation
- Issue: The search only scans
room.getLiveTimeline().getEvents(). - Impact: If a user has scrolled back and loaded historic messages into linked timelines, those messages will be ignored by the search.
- Recommended Fix: Iterate through all timelines in the room's primary
TimelineSetusingroom.getUnfilteredTimelineSet().getTimelines().
5. useAccountDataCallback Memoization Risk
File: src/app/hooks/useAccountDataCallback.ts
Status: Maintenance Risk
- Issue: The hook attaches/detaches a Matrix event listener every time the
onAccountDatacallback changes. If a component using this hook does not memoize the callback (viauseCallback), the listener will be churned on every render. - Impact: Potential performance degradation and subtle event-handling bugs if listeners are added/removed multiple times per second.
- Recommended Fix: Add a JSDoc warning to the hook file instructing developers to always wrap the callback in
useCallback.
📝 Documentation & Accessibility
1. Documentation Discrepancy (EC Spotlight)
Files: LOTUS_FEATURES.md vs matrix/README.md
- Issue:
LOTUS_FEATURES.mdclaims there is an "Auto-revert spotlight on screenshare" feature.matrix/README.mdcorrectly states this was removed as it broke fullscreen views. - Action: Update
LOTUS_FEATURES.mdto remove the mention.
2. Presence Badge Accessibility
File: src/app/components/presence/Presence.tsx
Status: Accessibility
- Issue:
aria-labelledbyrefers to a Tooltip ID that may not be in the DOM when the badge is first read by a screen reader. - Recommended Fix: Add a descriptive
aria-labeldirectly to theBadgecomponent (e.g.,aria-label="Status: Online").
3. Missing Status Tooltip on Text
File: src/app/features/room/MembersDrawer.tsx
Status: UX Improvement
- Issue: In the members drawer, the status message text is truncated but does not have a tooltip. The tooltip only exists on the small presence dot.
- Recommended Fix: Wrap the status text in a
TooltipProviderto allow users to read long status messages.