Files
fluffytrix/.claude/agent-memory/MEMORY.md
2026-03-02 16:30:40 +00:00

4.3 KiB

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.sizehashCode() 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