From 9d4bb218806d88e5d472ad15362e9989a4e836f6 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Sat, 11 Jul 2026 15:09:34 +0000 Subject: [PATCH] android, desktop: save draft when switching to chat where user cannot send messages On desktop, chat and chatId change in the same recomposition when another chat is opened from the always-visible chat list. The effect clearing compose state of a non-sendable chat (observer, channel subscriber, review by admins) was composed before the draft-saving KeyChangeEffect and ran first, wiping the live compose state before it could be saved and then clearing the previously saved draft via clearPrevDraft. Effects launch in composition order, so the clearing effect is moved after KeyChangeEffect: the previous chat's draft is saved first, and clearCurrentDraft is a no-op for it because draftChatId no longer matches the opened chat. Clearing the opened chat's own draft when it cannot send is preserved, as is clearing when the open chat itself becomes non-sendable (only the sendMsgEnabled key changes). --- .../chat/simplex/common/views/chat/ComposeView.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt index fb00603166..c05bf39a9b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt @@ -1307,13 +1307,6 @@ fun ComposeView( } } - LaunchedEffect(rememberUpdatedState(chat.chatInfo.sendMsgEnabled).value) { - if (!chat.chatInfo.sendMsgEnabled) { - clearCurrentDraft() - clearState() - } - } - KeyChangeEffect(chatModel.chatId.value) { prevChatId -> val cs = composeState.value if (cs.liveMessage != null && (cs.message.text.isNotEmpty() || cs.liveMessage.sent)) { @@ -1344,6 +1337,14 @@ fun ComposeView( chatModel.removeLiveDummy() CIFile.cachedRemoteFileRequests.clear() } + // Must be composed after KeyChangeEffect above (effects run in composition order), + // so that on chat switch the previous chat's draft is saved before it is cleared here. + LaunchedEffect(rememberUpdatedState(chat.chatInfo.sendMsgEnabled).value) { + if (!chat.chatInfo.sendMsgEnabled) { + clearCurrentDraft() + clearState() + } + } // keep the attach size limit in sync with the chat: the user's active badge raises it, but not in incognito chats where no badge is presented LaunchedEffect(chat.chatInfo) { val incognito = if (chat.chatInfo.profileChangeProhibited) chat.chatInfo.incognito else chatModel.controller.appPrefs.incognito.get()