From 32b2ab927ac154ffd7ffbcdedbb4734d6139312a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 17:14:29 +0000 Subject: [PATCH 1/2] fix(chat): don't freeze the author-info flag at first composition The chat list content read ChatUiState.isOneToOneConversation - which, despite its name, carries "show author avatars and names", i.e. the negation of the conversation being one-to-one - through remember { mutableStateOf(...) } without a key. That snapshots the field at the very first composition and never updates it again, so the value only ends up correct when the conversation emission from the database happens to win the race against the ComposeView's initial composition. Since the room list, chat opening and message prefetching moved onto local database flows, a chat opens straight from the cache and the first composition reliably runs before the conversation state lands. The flag then stays frozen at its default false and group chats render every incoming message without the author's avatar and display name. Read the flag directly from the collected uiState instead, so the message list recomposes with the real value once the conversation arrives. Also drop the debug log that would otherwise print on every recomposition. Assisted-by: Claude Code:claude-fable-5 Signed-off-by: Andy Scherzinger --- app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 5eeb4e7c7d..9e1b0aa482 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -889,8 +889,7 @@ class ChatActivity : LocalUploadProgressProvider provides { refId -> uploadProgressMap[refId] }, LocalUploadedLocalPreviewProvider provides { refId -> uploadedLocalPreviewMap[refId] } ) { - val isOneToOneConversation by remember { mutableStateOf(uiState.isOneToOneConversation) } - Log.d(TAG, "isOneToOneConversation=" + isOneToOneConversation) + val isOneToOneConversation = uiState.isOneToOneConversation // list of the file ids of messages being downloaded val downloadingFileState = remember { mutableStateOf(listOf()) } From 66f55fa89f71875838e30d38bff8daadbd6a65c5 Mon Sep 17 00:00:00 2001 From: Andy Scherzinger Date: Sun, 23 Aug 2026 20:33:22 +0200 Subject: [PATCH 2/2] fix(mentions): show a user placeholder instead of a plain accent circle Mention chips fell back to R.drawable.accent_circle whenever the avatar request was still in flight or failed. That drawable is a bare oval filled with colorPrimary, so a user chip - for example the actor in a "{user} left the conversation" system message - rendered as a featureless blue circle rather than a recognizable avatar placeholder. The chip's own loadImage() uses the fallback for both .placeholder() and .error(), so the circle showed up in both cases. Add ic_circular_user, a gray circle with a white person glyph built the same way as the existing ic_circular_group_mentions, icon_circular_team and icon_circular_phone chip icons, and use it as the fallback for user, guest and email chips. All chip fallbacks are now one visual family. Applies to both chip renderers, since the Compose chip and the MentionChipSpan in MarkdownText share resolveMentionFallbackIcon, and to the legacy composer chips in DisplayUtils so the chip shown while typing matches the one in the sent message. Self-mentions keep mention_chip, whose dark circle is the deliberate contrast against the primary-colored self chip. Assisted-by: Claude Code:claude-opus-5 Signed-off-by: Andy Scherzinger --- .../com/nextcloud/talk/ui/chat/MentionChip.kt | 2 +- .../com/nextcloud/talk/utils/DisplayUtils.kt | 2 +- .../main/res/drawable/ic_circular_user.xml | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 app/src/main/res/drawable/ic_circular_user.xml diff --git a/app/src/main/java/com/nextcloud/talk/ui/chat/MentionChip.kt b/app/src/main/java/com/nextcloud/talk/ui/chat/MentionChip.kt index 67c337d793..93906c3978 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/chat/MentionChip.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/chat/MentionChip.kt @@ -160,7 +160,7 @@ fun resolveMentionFallbackIcon(mention: MentionChipModel): Int = mention.type == "user-group" -> R.drawable.ic_circular_group_mentions mention.type == "circle" -> R.drawable.icon_circular_team mention.isSelfMention -> R.drawable.mention_chip - else -> R.drawable.accent_circle + else -> R.drawable.ic_circular_user } fun estimateMentionChipWidthInEm(label: String, fontSizeSp: Float): Float { diff --git a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt index 75dd8c27d9..dcd778ff83 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/DisplayUtils.kt @@ -182,7 +182,7 @@ object DisplayUtils { drawable = if (chipResource == R.xml.chip_you) { R.drawable.mention_chip } else { - R.drawable.accent_circle + R.drawable.ic_circular_user } chip.setChipIconResource(drawable) } else { diff --git a/app/src/main/res/drawable/ic_circular_user.xml b/app/src/main/res/drawable/ic_circular_user.xml new file mode 100644 index 0000000000..2dacd5fe71 --- /dev/null +++ b/app/src/main/res/drawable/ic_circular_user.xml @@ -0,0 +1,27 @@ + + + + + + + + + +