From d872b282d8ada974b5b6ca28e1dbe7b4dc71e3cf Mon Sep 17 00:00:00 2001 From: "Jan C. Borchardt" <925062+jancborchardt@users.noreply.github.com> Date: Tue, 28 Jul 2026 17:36:32 +0200 Subject: [PATCH] fix(chat): keep reply reference when restoring a message draft Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Jan C. Borchardt <925062+jancborchardt@users.noreply.github.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 22 +++++++---- .../talk/chat/ResolveReplyToMessageIdTest.kt | 38 +++++++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 app/src/test/java/com/nextcloud/talk/chat/ResolveReplyToMessageIdTest.kt 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 fa07b43ab8..2710b73b47 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -2398,13 +2398,12 @@ class ChatActivity : cursor?.close() } - fun getReplyToMessageId(): Int { - var replyMessageId = messageInputViewModel.getReplyChatMessage.value?.jsonMessageId - if (replyMessageId == null || replyMessageId == 0) { - replyMessageId = conversationThreadInfo?.thread?.id ?: 0 - } - return replyMessageId - } + fun getReplyToMessageId(): Int = + resolveReplyToMessageId( + messageInputViewModel.getReplyChatMessage.value?.jsonMessageId, + chatViewModel.messageDraft.quotedJsonId, + conversationThreadInfo?.thread?.id + ) @Throws(IllegalStateException::class) private fun onPickCameraResult(intent: Intent?) { @@ -4035,3 +4034,12 @@ class ChatActivity : private const val SEARCH_CENTER_STABILIZE_DELAY_MS = 200L } } + +/** + * The reply is only kept in the view model, so it is gone when the activity was recreated. + * The saved draft still holds it, so use it as fallback before falling back to the thread. + */ +internal fun resolveReplyToMessageId(replyMessageId: Int?, draftQuotedJsonId: Int?, threadId: Int?): Int { + val replyId = replyMessageId?.takeIf { it != 0 } ?: draftQuotedJsonId?.takeIf { it != 0 } + return replyId ?: threadId ?: 0 +} diff --git a/app/src/test/java/com/nextcloud/talk/chat/ResolveReplyToMessageIdTest.kt b/app/src/test/java/com/nextcloud/talk/chat/ResolveReplyToMessageIdTest.kt new file mode 100644 index 0000000000..8d77647ca3 --- /dev/null +++ b/app/src/test/java/com/nextcloud/talk/chat/ResolveReplyToMessageIdTest.kt @@ -0,0 +1,38 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package com.nextcloud.talk.chat + +import org.junit.Assert +import org.junit.Test + +class ResolveReplyToMessageIdTest { + + @Test + fun replyFromViewModelIsUsed() { + Assert.assertEquals(7, resolveReplyToMessageId(7, null, 42)) + } + + @Test + fun replyFromDraftIsUsedWhenViewModelIsEmpty() { + Assert.assertEquals(7, resolveReplyToMessageId(null, 7, 42)) + } + + @Test + fun replyFromDraftIsUsedWhenViewModelIsZero() { + Assert.assertEquals(7, resolveReplyToMessageId(0, 7, 42)) + } + + @Test + fun threadIsUsedWithoutReply() { + Assert.assertEquals(42, resolveReplyToMessageId(null, null, 42)) + } + + @Test + fun zeroWithoutReplyAndThread() { + Assert.assertEquals(0, resolveReplyToMessageId(null, 0, null)) + } +}