From 02eaa882ac06dedd99a2003d4ece094e606eedde Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 6 Aug 2026 17:49:37 +0000 Subject: [PATCH] fix the docs the API merge invalidated, and use the async listUsers Merging keepActiveUser into apiCreateActiveUser changed a signature that two Kotlin docs quote. spec/api.md still described the old parameters and said the command sets the profile as active, full stop; product/flows/onboarding.md quoted the old signature one step above the line this branch had already updated to mention the flag. The iOS spec table was fixed in the previous commit and these were missed - the same drift on the other platform. Both iOS call sites now use listUsersAsync, which is what changeActiveUserAsync_ uses a few lines later; the synchronous listUsers blocks whatever executor the Task is on, and SwiftUI infers that as the main actor. Not compiled: the Kotlin changes here are markdown only, and the Swift ones cannot be built on this machine. --- .../Views/Chat/ComposeMessage/ContextProfilePickerView.swift | 3 +-- apps/ios/Shared/Views/NewChat/NewChatView.swift | 2 +- apps/multiplatform/product/flows/onboarding.md | 2 +- apps/multiplatform/spec/api.md | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift index c21ef9b2f7..691607fade 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift @@ -261,7 +261,7 @@ struct ContextProfilePickerView: View { defer { Task { @MainActor in creatingProfile = false } } let profile = Profile(displayName: displayName, fullName: "", shortDescr: shortDescr, image: image) let newUser = try apiCreateActiveUser(profile, keepActiveUser: true) - let updatedUsers = try? listUsers() + let updatedUsers = try? await listUsersAsync() await MainActor.run { if let updatedUsers = updatedUsers { chatModel.users = updatedUsers @@ -274,7 +274,6 @@ struct ContextProfilePickerView: View { // An older remote host ignored keepActiveUser and activated it, so the // reassignment would fail. Resync to what the host did and report it - not // rethrown, or the form reports it as a failure to create the profile. - // let, not var: MainActor.run's body is @Sendable and cannot capture a mutable local let switched: Bool do { try await changeActiveUserAsync_(newUser.userId, viewPwd: nil) diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index e7807e9efb..de7d386fa2 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -611,7 +611,7 @@ private struct ActiveProfilePicker: View { defer { Task { @MainActor in creatingProfile = false } } let profile = Profile(displayName: displayName, fullName: "", shortDescr: shortDescr, image: image) let newUser = try apiCreateActiveUser(profile, keepActiveUser: true) - let updatedUsers = try? listUsers() + let updatedUsers = try? await listUsersAsync() await MainActor.run { if let updatedUsers = updatedUsers { chatModel.users = updatedUsers } profiles = chatModel.users.map { $0.user } diff --git a/apps/multiplatform/product/flows/onboarding.md b/apps/multiplatform/product/flows/onboarding.md index f922fa28a5..d95ee62e7e 100644 --- a/apps/multiplatform/product/flows/onboarding.md +++ b/apps/multiplatform/product/flows/onboarding.md @@ -114,7 +114,7 @@ enum class OnboardingStage { 2. User enters a display name (validated via `chatValidName` JNI) and optional full name. 3. On submit, `ChatController.apiCreateActiveUser(rh, profile)` is called: ```kotlin - suspend fun apiCreateActiveUser(rh: Long?, p: Profile?, pastTimestamp: Boolean = false, ctrl: ChatCtrl? = null): User? + suspend fun apiCreateActiveUser(rh: Long?, p: Profile?, pastTimestamp: Boolean = false, keepActiveUser: Boolean = false, ctrl: ChatCtrl? = null): User? ``` 4. The core command `CC.CreateActiveUser(p, pastTimestamp, keepActiveUser)` creates the user in the database (onboarding always passes `keepActiveUser = false`, so the new profile becomes active). 5. On success, `CR.ActiveUser` returns the new `User` object. diff --git a/apps/multiplatform/spec/api.md b/apps/multiplatform/spec/api.md index 4114e9de4f..fdc072f080 100644 --- a/apps/multiplatform/spec/api.md +++ b/apps/multiplatform/spec/api.md @@ -90,7 +90,7 @@ All functions below are `suspend fun` members of `ChatController` ([SimpleXAPI.k | Command | Parameters | Description | Line | |---------|-----------|-------------|------| | `apiGetActiveUser` | `rh: Long?, ctrl: ChatCtrl?` | Fetch the currently active user profile | [L841](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L841) | -| `apiCreateActiveUser` | `rh: Long?, p: Profile?, pastTimestamp: Boolean, ctrl: ChatCtrl?` | Create a new user profile and set it as active | [L851](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L851) | +| `apiCreateActiveUser` | `rh: Long?, p: Profile?, pastTimestamp: Boolean, keepActiveUser: Boolean, ctrl: ChatCtrl?` | Create a new user profile and set it as active, unless `keepActiveUser` | [L851](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L851) | | `listUsers` | `rh: Long?` | List all user profiles sorted by display name | [L871](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L871) | | `apiSetActiveUser` | `rh: Long?, userId: Long, viewPwd: String?` | Switch the active user to a different profile | [L881](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L881) | | `apiSetAllContactReceipts` | `rh: Long?, enable: Boolean` | Enable/disable delivery receipts for all contacts globally | [L888](../common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt#L888) |