From d948a79de60317600cfb77eea9f27adf42101566 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 20 Aug 2026 16:47:14 +0000 Subject: [PATCH] android, desktop: drop changes that do not serve the fix The connect composer no longer renders in a group's support scope, so no other view offers to join a prepared group and the record it kept was never read. Restores the block order in the member contact view, which is in this change only for the timeout. Records that the contacts list is not covered, on either platform. --- ...seContextGroupDirectInvitationActionsView.kt | 15 ++++++++------- .../simplex/common/views/chat/ComposeView.kt | 17 ++++++----------- plans/2026-08-20-do-not-accept-or-join-twice.md | 12 +++++++++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextGroupDirectInvitationActionsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextGroupDirectInvitationActionsView.kt index 6a2d0f367b..f64965f240 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextGroupDirectInvitationActionsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextGroupDirectInvitationActionsView.kt @@ -29,6 +29,14 @@ fun ComposeContextMemberContactActionsView( ) { val inProgress = rememberSaveable { mutableStateOf(false) } var progressByTimeout by rememberSaveable { mutableStateOf(false) } + + KeyChangeEffect(chatModel.chatId.value) { + if (inProgress.value) { + inProgress.value = false + progressByTimeout = false + } + } + LaunchedEffect(inProgress.value) { progressByTimeout = if (inProgress.value) { delay(500) @@ -38,13 +46,6 @@ fun ComposeContextMemberContactActionsView( } } - KeyChangeEffect(chatModel.chatId.value) { - if (inProgress.value) { - inProgress.value = false - progressByTimeout = false - } - } - Box( Modifier.height(60.dp), contentAlignment = Alignment.Center 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 157d10da36..8f3c72a261 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 @@ -654,17 +654,12 @@ fun ComposeView( val mc = checkLinkPreview() sending() val incognito = if (chat.chatInfo.profileChangeProhibited) chat.chatInfo.incognito else chatModel.controller.appPrefs.incognito.get() - chatModel.joiningGroups.add(chat.chatInfo.apiId) - val result = try { - chatModel.controller.apiConnectPreparedGroup( - rh = chat.remoteHostId, - groupId = chat.chatInfo.apiId, - incognito = incognito, - msg = mc - ) - } finally { - chatModel.joiningGroups.remove(chat.chatInfo.apiId) - } + val result = chatModel.controller.apiConnectPreparedGroup( + rh = chat.remoteHostId, + groupId = chat.chatInfo.apiId, + incognito = incognito, + msg = mc + ) if (result != null) { val (groupInfo, relayResults) = result withContext(Dispatchers.Main) { diff --git a/plans/2026-08-20-do-not-accept-or-join-twice.md b/plans/2026-08-20-do-not-accept-or-join-twice.md index f44f66fdf4..02175466b6 100644 --- a/plans/2026-08-20-do-not-accept-or-join-twice.md +++ b/plans/2026-08-20-do-not-accept-or-join-twice.md @@ -138,9 +138,9 @@ contact request id and group id — not by chat id, because the same request app `ChatInfo.ContactRequest` (`<@N`) in the chat list and under `ChatInfo.Direct` (`@N`) in the chat, and those two views must agree. They are maintained by the shared `acceptContactRequest` and by a new shared `joinGroup`, so every caller participates without changing its call site and a failed -accept re-enables the buttons. Every view derives from the record instead of owning a flag, which -deletes the parameter chain, the per-view flags and the `KeyChangeEffect` that existed only to reset -them on chat change. +accept re-enables the buttons. The views this change covers derive from the record instead of owning +a flag, which deletes the parameter chain, the per-view flags and the `KeyChangeEffect` that existed +only to reset them on chat change. The contacts list is not covered - see "Not covered". The record is taken before the request is sent rather than inside the background coroutine, so a second tap in the same view is blocked too — the previous per-view flags were set synchronously at @@ -204,6 +204,12 @@ change addresses it. **`acceptMemberContact` and `apiAcceptMember`** keep their per-view flags; they are the same shape but were left out of scope. +**The contacts list still offers Accept while an accept is in flight** - `ContactListNavView.kt` +opens `contactRequestAlertDialog` without checking, and `ContactListNavLink.swift` has its own +buttons rather than the ones this change gates. It is the same defect in one more view on each +platform, left out to keep the change small; the outcome is now a clear error from fix 1 rather than +the agent error, and the contacts list is a sheet, so the other views are not tappable behind it. + ## Testing - `connecting to channel twice fails` (`tests/ChatTests/Groups.hs`) and `prepare group and connect