From efd5dee1895fe5792007a165e1f301905f621d8b Mon Sep 17 00:00:00 2001 From: Paul Hitt Date: Sat, 29 Aug 2026 09:34:10 -0400 Subject: [PATCH] Avatars merge instead of replacing on refresh Same rule as iOS: the live refresh replaced the whole map, so a refresh while the buddy list was briefly empty produced an empty map that blanked every picture. Merge, and ignore an empty result. Co-Authored-By: Claude Opus 4.8 --- .../io/flamenet/messenger/app/MessengerViewModel.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/io/flamenet/messenger/app/MessengerViewModel.kt b/app/src/main/kotlin/io/flamenet/messenger/app/MessengerViewModel.kt index 341ce01..6e3517e 100644 --- a/app/src/main/kotlin/io/flamenet/messenger/app/MessengerViewModel.kt +++ b/app/src/main/kotlin/io/flamenet/messenger/app/MessengerViewModel.kt @@ -1750,7 +1750,17 @@ class MessengerViewModel(app: Application) : AndroidViewModel(app) { current.avatars(signedIn()?.buddies?.map { it.userId }.orEmpty()) }.getOrNull() } - fresh?.let { live -> update { it.copy(avatars = live) } } + // 🔴 **Merge, never replace.** A refresh made while the + // buddy list was momentarily empty — a roster fetch in + // flight, or the list loading from the vault — produced + // an empty map that wiped every picture from the UI at + // once. The avatars were in the vault the whole time, + // which is why "the profile pictures are gone" looked + // like data loss rather than a render bug. Absent means + // "not loaded yet", never "deleted". + fresh?.takeIf { it.isNotEmpty() }?.let { live -> + update { it.copy(avatars = it.avatars + live) } + } } if (threads.isNotEmpty()) { // Whoever just wrote may not be on the list at all —