Files
2026-03-02 16:30:40 +00:00

51 lines
4.3 KiB
Markdown

# Fluffytrix Android Bug Hunter Memory
## Architecture
- Messages stored descending (newest at index 0) for `reverseLayout = true` LazyColumn
- Thread replies filtered from main timeline into `threadMessageCache[roomId][threadRootEventId]`
- Thread detection: parse `content.m.relates_to.rel_type == "m.thread"` from raw JSON via `eventItem.lazyProvider.debugInfo().originalJson` (must be in try/catch)
- Space hierarchy: top-level spaces → child spaces → rooms. Orphan rooms = rooms not in any space
- Static channel ordering enforced via `_channelOrderMap` (DataStore-persisted)
- `MainViewModel` uses `ProcessLifecycleOwner` observer to pause/resume sync on app background/foreground
- `AuthRepository` holds `matrixClient` and `syncService` as plain `var` (not thread-safe, accessed from IO threads)
## Recurring Bug Patterns
### Threading / Coroutines
- `loadMoreMessages()` launches on `Dispatchers.Default` (omits dispatcher), so `timeline.paginateBackwards()` runs on main thread — SDK calls must use `Dispatchers.IO`
- `TimelineListener.onUpdate` launches `viewModelScope.launch(Dispatchers.Default)` — fine for CPU work, but the mutex-protected list manipulation inside is correct
- `processRooms` uses `withContext(Dispatchers.Default)` for CPU-heavy room processing — correct pattern
- `rebuildThreadList` and `updateThreadMessagesView` called from within `Dispatchers.Default` coroutine (inside `onUpdate`) — these write to `_roomThreads` and `_threadMessages` StateFlows, which is safe from any thread
### Memory Leaks
- `messageCache`, `messageIds`, `memberCache`, `threadMessageCache` are plain `mutableMapOf` on ViewModel — accessed from multiple coroutines without synchronization (race condition potential)
- `senderAvatarCache` and `senderNameCache` similarly unsynchronized
- `activeTimeline` is written from `Dispatchers.IO` coroutine and read from `Dispatchers.Default` in the listener — not volatile/synchronized
### Compose
- `rememberLazyListState()` in `MessageTimeline` is recreated on channel/thread switch — loses scroll position. Should be keyed per channel or held in ViewModel
- `collectAsState()` without `repeatOnLifecycle` in `MainScreen` — acceptable since `collectAsState` internally uses `repeatOnLifecycle(STARTED)` in Compose lifecycle-runtime
- Thread items in `ChannelList` rendered with `for` loop inside `LazyColumn` items block — not using `item(key=)` for thread rows, causing missed optimizations but not a correctness bug
### Visual
- `senderColors` array contains hardcoded hex colors — violates Material You convention but is intentional Discord-style sender coloring (acceptable)
- `Color.White` used directly in `VideoContent` play button and fullscreen viewers — minor Material You violation but acceptable for media overlays
### Data Correctness
- `colorForSender`: `name.hashCode().ushr(1) % senderColors.size``hashCode()` can be negative; `ushr(1)` makes it non-negative, so modulo is safe. Correct.
- Binary search in `processEventItem` for descending insert: comparator is `msg.timestamp.compareTo(it.timestamp)` — this inserts newer messages at lower indices (ascending by timestamp reversed). For `reverseLayout` this is correct.
- Thread binary search uses same comparator — threads stored ascending by timestamp, which for `reverseLayout` is correct (newest at index 0 visually).
- `sendThreadMessage` sends as plain message without thread relation — documented known limitation/TODO in code
### Build
- `isMinifyEnabled = true` in debug build — unusual, slows debug builds and can make debugging harder, but not a bug per se
- `kotlin = "2.2.10"` in version catalog — check that this is a valid release (2.2.0 is latest as of mid-2025; 2.2.10 may be typo for 2.2.0 or future patch)
## Key File Paths
- ViewModel: `app/src/main/java/com/example/fluffytrix/ui/screens/main/MainViewModel.kt`
- Main screen: `app/src/main/java/com/example/fluffytrix/ui/screens/main/MainScreen.kt`
- Message timeline: `app/src/main/java/com/example/fluffytrix/ui/screens/main/components/MessageTimeline.kt`
- Channel list: `app/src/main/java/com/example/fluffytrix/ui/screens/main/components/ChannelList.kt`
- Auth repo: `app/src/main/java/com/example/fluffytrix/data/repository/AuthRepository.kt`
- Preferences: `app/src/main/java/com/example/fluffytrix/data/local/PreferencesManager.kt`