# 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`