From f940796aaabcc1e2dc21f769d91590efd8b75869 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 6 Aug 2026 18:22:56 +0000 Subject: [PATCH] android, desktop: make the form's submit callback optional, as iOS already does CreateProfile took a required onSubmit, so both existing call sites had to change and a createProfileFromForm helper existed only to give them somewhere to delegate. The iOS port of the same change made the callback optional and touched no existing call site; this does the same. UserPicker and UserProfilesView drop out of the diff, the helper goes, and the branch the form always had stays where it was, behind a null check. The trade is that chatModel and close stay parameters even though the invitation path uses neither, and the callback is nullable. That is the price of not touching two unrelated files, and it is the shape iOS already ships. Easy to reverse if the cleaner signature is preferred. --- .../chat/simplex/common/views/WelcomeView.kt | 29 ++++++++++--------- .../common/views/chatlist/UserPicker.kt | 5 +--- .../views/usersettings/UserProfilesView.kt | 5 +--- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt index d5bc150bbd..70c5135233 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt @@ -57,8 +57,12 @@ fun bioFitsLimit(bio: String): Boolean { return chatJsonLength(bio) <= MAX_BIO_LENGTH_BYTES } +/** [onSubmit] replaces the default create-and-activate action, so the same form can be + * used to create a profile for an invitation - which must not switch the active user + * until the invitation has been moved onto it. Optional, so the existing call sites are + * untouched. */ @Composable -fun CreateProfile(submitting: Boolean = false, onSubmit: (displayName: String, shortDescr: String, image: String?) -> Unit) { +fun CreateProfile(chatModel: ChatModel, close: () -> Unit, submitting: Boolean = false, onSubmit: ((displayName: String, shortDescr: String, image: String?) -> Unit)? = null) { val scope = rememberCoroutineScope() val scrollState = rememberScrollState() val keyboardState by getKeyboardState() @@ -160,7 +164,15 @@ fun CreateProfile(submitting: Boolean = false, onSubmit: (displayName: String, s disabled = submitting || !canCreateProfile(displayName.value) || !bioFitsLimit(shortDescr.value), textColor = MaterialTheme.colors.primary, iconColor = MaterialTheme.colors.primary, - click = { onSubmit(displayName.value, shortDescr.value, profileImage.value) }, + click = { + if (onSubmit != null) { + onSubmit(displayName.value, shortDescr.value, profileImage.value) + } else if (chatModel.localUserCreated.value == true) { + createProfileInProfiles(chatModel, displayName.value, shortDescr.value, profileImage.value, close) + } else { + createProfileInNoProfileSetup(displayName.value, profileImage.value, close) + } + }, ) SectionTextFooter(generalGetString(MR.strings.your_profile_is_stored_on_your_device)) SectionTextFooter(generalGetString(MR.strings.profile_is_only_shared_with_your_contacts)) @@ -359,7 +371,7 @@ fun createProfileForInvitation(rhId: Long?, onCreated: suspend (User) -> Unit) { val modalManager = ModalManager.fullscreen if (modalManager.isLastModalOpenNotClosing(ModalViewId.CONTEXT_USER_PICKER_NEW_PROFILE)) return modalManager.showModalCloseable(id = ModalViewId.CONTEXT_USER_PICKER_NEW_PROFILE) { close -> - CreateProfile(submitting = chatModel.creatingProfileForInvitation.value) { displayName, shortDescr, image -> + CreateProfile(chatModel, close, submitting = chatModel.creatingProfileForInvitation.value) { displayName, shortDescr, image -> if (chatModel.creatingProfileForInvitation.value) return@CreateProfile chatModel.creatingProfileForInvitation.value = true // On Main, like the pickers' own handlers: every call here suspends into IO, and the @@ -408,17 +420,6 @@ fun createProfileForInvitation(rhId: Long?, onCreated: suspend (User) -> Unit) { } } -// The two ordinary "add a profile" paths, where the new profile becomes the active -// one. Creating one for an invitation takes neither, which is why the form itself -// no longer chooses. -fun createProfileFromForm(chatModel: ChatModel, displayName: String, shortDescr: String, image: String?, close: () -> Unit) { - if (chatModel.localUserCreated.value == true) { - createProfileInProfiles(chatModel, displayName, shortDescr, image, close) - } else { - createProfileInNoProfileSetup(displayName, image, close) - } -} - fun createProfileInNoProfileSetup(displayName: String, image: String? = null, close: () -> Unit) { withBGApi { val user = controller.apiCreateActiveUser(null, Profile(displayName.trim(), "", null, image = image)) ?: return@withBGApi diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt index 45cbdf78cf..81a6b31323 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/UserPicker.kt @@ -30,7 +30,6 @@ import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.platform.* import chat.simplex.common.views.CreateProfile -import chat.simplex.common.views.createProfileFromForm import chat.simplex.common.views.localauth.VerticalDivider import chat.simplex.common.views.remote.* import chat.simplex.common.views.usersettings.* @@ -260,9 +259,7 @@ fun UserPicker( LaunchedEffect(Unit) { userPickerState.value = AnimatedViewState.HIDING } - CreateProfile { displayName, shortDescr, image -> - createProfileFromForm(chat.simplex.common.platform.chatModel, displayName, shortDescr, image, close) - } + CreateProfile(chat.simplex.common.platform.chatModel, close) } } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt index 38974d2b0e..ac21fb6b23 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt @@ -28,7 +28,6 @@ import chat.simplex.common.views.chatlist.UserProfilePickerItem import chat.simplex.common.views.chatlist.UserProfileRow import chat.simplex.common.views.helpers.* import chat.simplex.common.views.CreateProfile -import chat.simplex.common.views.createProfileFromForm import chat.simplex.common.views.database.* import chat.simplex.common.views.onboarding.OnboardingStage import chat.simplex.res.MR @@ -50,9 +49,7 @@ fun UserProfilesView(m: ChatModel, search: MutableState, profileHidden: addUser = { withAuth { ModalManager.center.showModalCloseable { close -> - CreateProfile { displayName, shortDescr, image -> - createProfileFromForm(m, displayName, shortDescr, image, close) - } + CreateProfile(m, close) } } },