From 9c90308fe584c23001198d9584e5ca7bfb53334c Mon Sep 17 00:00:00 2001 From: spacedandy-agents-simplex <342056592+spacedandy-agents-simplex@users.noreply.github.com> Date: Wed, 21 Oct 2026 08:58:13 +0000 Subject: [PATCH] ios, android, desktop: Open on a directory result shows the "Open channel?" alert when the link has a signature result or another name Open went straight to the prepared chat whatever the plan said, so a signature check's result and the button for the name's other chat would be shown nowhere. Open now skips the alert only when the plan has neither, which is every Open today: it plans a link, without a signature. Run: 012-search-followup, slice 1 --- apps/ios/Shared/Views/NewChat/NewChatView.swift | 3 ++- apps/ios/product/views/chat-list.md | 2 +- apps/ios/spec/client/chat-list.md | 2 +- apps/ios/spec/client/navigation.md | 2 +- .../kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt | 3 ++- apps/multiplatform/product/views/chat-list.md | 2 +- apps/multiplatform/spec/client/chat-list.md | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index d2fd9706c5..246df8f668 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -1548,7 +1548,8 @@ func planAndConnect( if let groupSLinkData = groupSLinkData_ { logger.debug("planAndConnect, .groupLink, .ok, short link data present") await MainActor.run { - switch prepareGroup { + let mode: PrepareGroupMode = ownerVerification == nil && connectOtherLink == nil ? prepareGroup : .confirm + switch mode { case .confirm: showPrepareGroupAlert( connectionLink: connectionLink, diff --git a/apps/ios/product/views/chat-list.md b/apps/ios/product/views/chat-list.md index 384a664e86..9cc3ee47ef 100644 --- a/apps/ios/product/views/chat-list.md +++ b/apps/ios/product/views/chat-list.md @@ -48,7 +48,7 @@ Searching beyond the user's own chats happens only when the user asks, and the r | "Directory search" switch | In Settings › Privacy › Chats, after "Send link previews"; off by default | | "Enable Directory search?" alert | Every search asks while the switch is off: search text is sent to SimpleX Directory, each search separately and without the user's profile, so it can't build a search history. Cancel sends nothing; Enable turns the switch on and searches. Once it is on, searches don't ask | | Results | One list without headers below the local chats. First your chats among the results that the list above doesn't show (for example because the name doesn't match the typed text), as their regular chat rows; then the other results, with the same avatar size as chat rows: avatar, `#` name, the directory's SimpleX name, description, then the member or subscriber count and "Open" on the right. A join still in progress without a chat shows "Already joining" in place of the count and no "Open" | -| Open | Tapping a result (or its "Open") loads the group's or channel's profile, with the spinner in the search field, and opens the chat straight away, with its Join button and no "Open channel?" question; a channel's banner shows its subscriber count. The user joins from there. A result that is already joining shows the same sheet or alert as pasting its link would | +| Open | Tapping a result (or its "Open") loads the group's or channel's profile, with the spinner in the search field, and opens the chat straight away, with its Join button and no "Open channel?" question; a channel's banner shows its subscriber count. The user joins from there. If the link's signature was checked or its name also leads to another chat, the question shows first, as for a pasted link, with the signature result or the other chat's button. A result that is already joining shows the same sheet or alert as pasting its link would | | Long press | On iOS 16 and later, a long press on a result shows a menu with Open, previewing the row; iOS 15 has no menu | | Load row | The last row of the results: "Load more · N left" when the directory says how many matches are left, "Load more" otherwise; greyed while a page loads. A failed request turns it into "Search failed, tap to retry". Nothing loads more pages automatically | | Page note | When every result of the last page loaded is a chat already in the list, "All results on this page are already in your chats" (secondary colour), followed by the load row when there are more pages | diff --git a/apps/ios/spec/client/chat-list.md b/apps/ios/spec/client/chat-list.md index 0081997bb7..eec5b72b90 100644 --- a/apps/ios/spec/client/chat-list.md +++ b/apps/ios/spec/client/chat-list.md @@ -433,7 +433,7 @@ A result tap first sets `searchFocussed = false`. Text from the directory is ren ### Opening a result -[`openDirectoryResult(_:theme:dismiss:cleanup:)`](../../Shared/Views/ChatList/DirectorySearchView.swift#L337) calls [`planAndConnect`](../../Shared/Views/NewChat/NewChatView.swift#L1342) with the result's link and `prepareGroup: .open`, or `.confirm` (the default) for `.joining`. `planAndConnect` makes the online plan, with the spinner in the field. [`PrepareGroupMode`](../../Shared/Views/NewChat/NewChatView.swift#L1337) is read only in the `.groupLink(.ok)` branch with link data ([L1551](../../Shared/Views/NewChat/NewChatView.swift#L1551)): `.confirm` shows the "Open channel?" / "Open group?" alert ([`showPrepareGroupAlert`](../../Shared/Views/NewChat/NewChatView.swift#L1167)), as for a pasted link, and `.open` calls [`prepareAndOpenGroup`](../../Shared/Views/NewChat/NewChatView.swift#L1217) at once, the function the alert's confirm also calls: `apiPrepareGroup`, the channel's relay hostnames, `addChat`, then `openKnownChat`. So Open goes straight to the prepared chat with its Join button. Every other plan shows what a pasted link shows: the "Open group" alert for a known group, the repeat-join sheet or the connecting alert for a pending join, and the no-relays and update-required alerts. A `.joining` result keeps the default mode, so whatever its online plan turns out to be, it shows what a pasted link would. +[`openDirectoryResult(_:theme:dismiss:cleanup:)`](../../Shared/Views/ChatList/DirectorySearchView.swift#L337) calls [`planAndConnect`](../../Shared/Views/NewChat/NewChatView.swift#L1342) with the result's link and `prepareGroup: .open`, or `.confirm` (the default) for `.joining`. `planAndConnect` makes the online plan, with the spinner in the field. [`PrepareGroupMode`](../../Shared/Views/NewChat/NewChatView.swift#L1337) is read only in the `.groupLink(.ok)` branch with link data ([L1551](../../Shared/Views/NewChat/NewChatView.swift#L1551)): `.confirm` shows the "Open channel?" / "Open group?" alert ([`showPrepareGroupAlert`](../../Shared/Views/NewChat/NewChatView.swift#L1167)), as for a pasted link, and `.open` calls [`prepareAndOpenGroup`](../../Shared/Views/NewChat/NewChatView.swift#L1217) at once, the function the alert's confirm also calls: `apiPrepareGroup`, the channel's relay hostnames, `addChat`, then `openKnownChat`. `.open` applies only when the plan has no `ownerVerification` (verified or failed) and no other name (`connectOtherLink`); with either, the branch shows the alert as `.confirm` does, because only the alert shows the signature line and the other name's button. Open plans a link, not a name, without a signature, so its plan has neither, and Open goes straight to the prepared chat with its Join button. Every other plan shows what a pasted link shows: the "Open group" alert for a known group, the repeat-join sheet or the connecting alert for a pending join, and the no-relays and update-required alerts. A `.joining` result keeps the default mode, so whatever its online plan turns out to be, it shows what a pasted link would. The chat banner of a prepared channel (`nextConnectPrepared && useRelays`) shows its subscriber count, `subscriberCountStr(groupSummary.publicMemberCount)` from the link data, after the full name ([ChatView.swift L1030](../../Shared/Views/Chat/ChatView.swift#L1030)), in `.subheadline` and the secondary colour. diff --git a/apps/ios/spec/client/navigation.md b/apps/ios/spec/client/navigation.md index 93c434186a..bcb788b279 100644 --- a/apps/ios/spec/client/navigation.md +++ b/apps/ios/spec/client/navigation.md @@ -351,7 +351,7 @@ When `groupShortLinkInfo?.direct == false` (channel relay link), the prepare ale - `apiPrepareGroup` call passes `directLink: false` - Stores `groupShortLinkInfo.groupRelays` in `ChatModel.shared.channelRelayHostnames` -The alert's confirm calls `prepareAndOpenGroup`, which prepares the group, stores the relays, adds the chat and opens it. `planAndConnect(…, prepareGroup: .open)`, which the online search's Open uses, calls `prepareAndOpenGroup` without the alert (see [Chat List, Opening a result](chat-list.md#opening-a-result)); the default `.confirm` keeps the alert. +The alert's confirm calls `prepareAndOpenGroup`, which prepares the group, stores the relays, adds the chat and opens it. `planAndConnect(…, prepareGroup: .open)`, which the online search's Open uses, calls `prepareAndOpenGroup` without the alert when the plan has no owner verification and no other name (see [Chat List, Opening a result](chat-list.md#opening-a-result)); with either, and with the default `.confirm`, the alert shows. ### Own Link Confirmation (`showOwnGroupLinkConfirmConnectSheet`) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt index e4e2753a88..e6e855c83d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt @@ -255,7 +255,8 @@ private suspend fun planAndConnectTask( is GroupLinkPlan.Ok -> if (connectionPlan.groupLinkPlan.groupSLinkData_ != null) { Log.d(TAG, "planAndConnect, .GroupLink, .Ok, short link data present") - when (prepareGroup) { + val mode = if (connectionPlan.groupLinkPlan.ownerVerification == null && connectOtherLink == null) prepareGroup else PrepareGroupMode.Confirm + when (mode) { PrepareGroupMode.Confirm -> showPrepareGroupAlert( rhId, diff --git a/apps/multiplatform/product/views/chat-list.md b/apps/multiplatform/product/views/chat-list.md index 0c644cab27..86b4bd4f9e 100644 --- a/apps/multiplatform/product/views/chat-list.md +++ b/apps/multiplatform/product/views/chat-list.md @@ -66,7 +66,7 @@ Searching beyond the user's own chats happens only when the user asks, and the r | "Directory search" switch | In Settings › Privacy › Chats, after "Send link previews"; off by default | | "Enable Directory search?" alert | Every search asks while the switch is off: search text is sent to SimpleX Directory, each search separately and without the user's profile, so it can't build a search history. Enable turns the switch on and searches; Cancel sends nothing. Once it is on, searches don't ask | | Results | One list without headers below the local chats. First your chats among the results that the list above doesn't show (for example because the name doesn't match the typed text), as their regular chat rows; then the other results, laid out as chat rows with the same avatar size: avatar, `#` name, the directory's SimpleX name, description, then the member or subscriber count and "Open" on the right. A join still in progress without a chat shows "Already joining" in place of the count and no "Open" | -| Open | Tapping a result loads the group's or channel's profile and opens the chat straight away, with its Join button and no "Open channel?" question; a channel's banner shows its subscriber count. The user joins from there. A result that is already joining shows the same alert as pasting its link would | +| Open | Tapping a result loads the group's or channel's profile and opens the chat straight away, with its Join button and no "Open channel?" question; a channel's banner shows its subscriber count. The user joins from there. If the link's signature was checked or its name also leads to another chat, the question shows first, as for a pasted link, with the signature result or the other chat's button. A result that is already joining shows the same alert as pasting its link would | | Result menu | A long press (or a right click on desktop) on a result shows a menu with Open | | Load row | The last row of the results: "Load more · N left" when the directory says how many matches are left, "Load more" otherwise; greyed while a page loads. A failed request turns it into "Search failed, tap to retry". Nothing loads more pages automatically | | Page note | When every result of the last page loaded is a chat already in the list, "All results on this page are already in your chats" (secondary colour), followed by the load row when there are more pages | diff --git a/apps/multiplatform/spec/client/chat-list.md b/apps/multiplatform/spec/client/chat-list.md index 195af885a8..4db28de284 100644 --- a/apps/multiplatform/spec/client/chat-list.md +++ b/apps/multiplatform/spec/client/chat-list.md @@ -493,6 +493,6 @@ A result's menu is `ChatListNavLinkLayout`'s dropdown, opened by a long press, o ### Opening a result -[`openDirectoryResult(result, close, cleanup)`](../../common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/DirectorySearchView.kt#L345-L348) runs `withBGApi { planAndConnect(rhId, result.entry.link, close, cleanup, prepareGroup = …) }` with `PrepareGroupMode.Open`, or `Confirm` (the default) for `Joining`. `planAndConnect` makes the online plan with the "Loading profile…" progress. [`PrepareGroupMode`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L24-L26) is passed on to `planAndConnectTask` and read only in the `GroupLinkPlan.Ok` branch with link data ([source](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L258-L281)): `Confirm` shows the "Open channel?" / "Open group?" alert ([`showPrepareGroupAlert`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L768)), as for a pasted link, and `Open` calls [`prepareAndOpenGroup`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L808-L835) at once, the function the alert's confirm also calls: `apiPrepareGroup`, the channel's relay hostnames, `addChat`, `openChat_`, then `cleanup`. So Open goes straight to the prepared chat with its Join button. Every other plan shows what a pasted link shows: the "Open group" alert for a known group, the reconnect and connecting alerts for a pending join, and the no-relays and update-required alerts. A `Joining` result keeps the default mode, so whatever its online plan turns out to be, it shows what a pasted link would. +[`openDirectoryResult(result, close, cleanup)`](../../common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/DirectorySearchView.kt#L345-L348) runs `withBGApi { planAndConnect(rhId, result.entry.link, close, cleanup, prepareGroup = …) }` with `PrepareGroupMode.Open`, or `Confirm` (the default) for `Joining`. `planAndConnect` makes the online plan with the "Loading profile…" progress. [`PrepareGroupMode`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L24-L26) is passed on to `planAndConnectTask` and read only in the `GroupLinkPlan.Ok` branch with link data ([source](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L258-L282)): `Confirm` shows the "Open channel?" / "Open group?" alert ([`showPrepareGroupAlert`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L769)), as for a pasted link, and `Open` calls [`prepareAndOpenGroup`](../../common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ConnectPlan.kt#L809-L836) at once, the function the alert's confirm also calls: `apiPrepareGroup`, the channel's relay hostnames, `addChat`, `openChat_`, then `cleanup`. `Open` applies only when the plan has no `ownerVerification` (verified or failed) and no other name (`connectOtherLink`); with either, the branch shows the alert as `Confirm` does, because only the alert shows the signature line and the other name's button. Open plans a link, not a name, without a signature, so its plan has neither, and Open goes straight to the prepared chat with its Join button. Every other plan shows what a pasted link shows: the "Open group" alert for a known group, the reconnect and connecting alerts for a pending join, and the no-relays and update-required alerts. A `Joining` result keeps the default mode, so whatever its online plan turns out to be, it shows what a pasted link would. The chat banner of a prepared channel (`nextConnectPrepared && useRelays`) shows its subscriber count, `subscriberCountStr(groupSummary.publicMemberCount)` from the link data, after the full name ([ChatView.kt](../../common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt#L2355-L2364)), in `body2`, the secondary colour, centred.