From 4a254560c0cc0d763db0c9dab5b3d5f8ee95aa03 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> Date: Fri, 24 Nov 2023 16:51:31 +0000 Subject: [PATCH] desktop: fix user address changes on connected mobile (#3452) * desktop: fix user address changes on connected mobile * close user-specific views when remote host changes --- .../chat/simplex/common/model/SimpleXAPI.kt | 4 ++-- .../common/views/newchat/CreateLinkView.kt | 2 +- .../common/views/usersettings/Preferences.kt | 5 +++- .../common/views/usersettings/SettingsView.kt | 2 +- .../views/usersettings/UserAddressView.kt | 24 ++++++++++--------- .../views/usersettings/UserProfileView.kt | 6 ++++- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 5b44312cc3..df70ceaf2e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -991,7 +991,7 @@ object ChatController { val userId = try { currentUserId("apiSetProfileAddress") } catch (e: Exception) { return null } return when (val r = sendCmd(rh, CC.ApiSetProfileAddress(userId, on))) { is CR.UserProfileNoChange -> null - is CR.UserProfileUpdated -> r.user + is CR.UserProfileUpdated -> r.user.updateRemoteHostId(rh) else -> throw Exception("failed to set profile address: ${r.responseType} ${r.details}") } } @@ -1034,7 +1034,7 @@ object ChatController { suspend fun apiDeleteUserAddress(rh: Long?): User? { val userId = try { currentUserId("apiDeleteUserAddress") } catch (e: Exception) { return null } val r = sendCmd(rh, CC.ApiDeleteMyAddress(userId)) - if (r is CR.UserContactLinkDeleted) return r.user + if (r is CR.UserContactLinkDeleted) return r.user.updateRemoteHostId(rh) Log.e(TAG, "apiDeleteUserAddress bad response: ${r.responseType} ${r.details}") return null } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/CreateLinkView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/CreateLinkView.kt index 0a23ed743d..a162752716 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/CreateLinkView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/CreateLinkView.kt @@ -67,7 +67,7 @@ fun CreateLinkView(m: ChatModel, rh: RemoteHostInfo?, initialSelection: CreateLi AddContactView(m, rh,connReqInvitation.value ?: "", contactConnection) } CreateLinkTab.LONG_TERM -> { - UserAddressView(m, rh?.remoteHostId, viaCreateLinkView = true, close = {}) + UserAddressView(m, viaCreateLinkView = true, close = {}) } } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt index e94c53f644..c375fc5459 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt @@ -21,7 +21,10 @@ import chat.simplex.res.MR fun PreferencesView(m: ChatModel, user: User, close: () -> Unit,) { var preferences by rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(user.fullPreferences) } var currentPreferences by rememberSaveable(stateSaver = serializableSaver()) { mutableStateOf(preferences) } - + val u = remember { m.currentUser } + KeyChangeEffect(u.value?.remoteHostId, u.value?.userId) { + close() + } fun savePrefs(afterSave: () -> Unit = {}) { withApi { val newProfile = user.profile.toProfile().copy(preferences = preferences.toPreferences()) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt index 4e86d33a4e..dfe3581521 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt @@ -155,7 +155,7 @@ fun SettingsLayout( } val profileHidden = rememberSaveable { mutableStateOf(false) } SettingsActionItem(painterResource(MR.images.ic_manage_accounts), stringResource(MR.strings.your_chat_profiles), { withAuth(generalGetString(MR.strings.auth_open_chat_profiles), generalGetString(MR.strings.auth_log_in_using_credential)) { showSettingsModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden) } } }, disabled = stopped, extraPadding = true) - SettingsActionItem(painterResource(MR.images.ic_qr_code), stringResource(MR.strings.your_simplex_contact_address), showCustomModal { it, close -> UserAddressView(it, it.currentUser.value?.remoteHostId, shareViaProfile = it.currentUser.value!!.addressShared, close = close) }, disabled = stopped, extraPadding = true) + SettingsActionItem(painterResource(MR.images.ic_qr_code), stringResource(MR.strings.your_simplex_contact_address), showCustomModal { it, close -> UserAddressView(it, shareViaProfile = it.currentUser.value!!.addressShared, close = close) }, disabled = stopped, extraPadding = true) ChatPreferencesItem(showCustomModal, stopped = stopped) if (appPlatform.isDesktop) { SettingsActionItem(painterResource(MR.images.ic_smartphone), stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles), showModal { ConnectMobileView() }, disabled = stopped, extraPadding = true) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt index d248241086..915120d81d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt @@ -33,7 +33,6 @@ import chat.simplex.res.MR @Composable fun UserAddressView( chatModel: ChatModel, - rhId: Long?, viaCreateLinkView: Boolean = false, shareViaProfile: Boolean = false, close: () -> Unit @@ -42,12 +41,15 @@ fun UserAddressView( val shareViaProfile = remember { mutableStateOf(shareViaProfile) } var progressIndicator by remember { mutableStateOf(false) } val onCloseHandler: MutableState<(close: () -> Unit) -> Unit> = remember { mutableStateOf({ _ -> }) } - + val user = remember { chatModel.currentUser } + KeyChangeEffect(user.value?.remoteHostId, user.value?.userId) { + close() + } fun setProfileAddress(on: Boolean) { progressIndicator = true withBGApi { try { - val u = chatModel.controller.apiSetProfileAddress(rhId, on) + val u = chatModel.controller.apiSetProfileAddress(user?.value?.remoteHostId, on) if (u != null) { chatModel.updateUser(u) } @@ -63,14 +65,14 @@ fun UserAddressView( val uriHandler = LocalUriHandler.current val showLayout = @Composable { UserAddressLayout( + user = user.value, userAddress = userAddress.value, shareViaProfile, - rhId, onCloseHandler, createAddress = { withApi { progressIndicator = true - val connReqContact = chatModel.controller.apiCreateUserAddress(rhId) + val connReqContact = chatModel.controller.apiCreateUserAddress(user?.value?.remoteHostId) if (connReqContact != null) { chatModel.userAddress.value = UserContactLinkRec(connReqContact) @@ -115,7 +117,7 @@ fun UserAddressView( onConfirm = { progressIndicator = true withApi { - val u = chatModel.controller.apiDeleteUserAddress(rhId) + val u = chatModel.controller.apiDeleteUserAddress(user?.value?.remoteHostId) if (u != null) { chatModel.userAddress.value = null chatModel.updateUser(u) @@ -129,7 +131,7 @@ fun UserAddressView( }, saveAas = { aas: AutoAcceptState, savedAAS: MutableState -> withBGApi { - val address = chatModel.controller.userAddressAutoAccept(rhId, aas.autoAccept) + val address = chatModel.controller.userAddressAutoAccept(user?.value?.remoteHostId, aas.autoAccept) if (address != null) { chatModel.userAddress.value = address savedAAS.value = aas @@ -168,9 +170,9 @@ fun UserAddressView( @Composable private fun UserAddressLayout( + user: User?, userAddress: UserContactLinkRec?, shareViaProfile: MutableState, - rhId: Long?, onCloseHandler: MutableState<(close: () -> Unit) -> Unit>, createAddress: () -> Unit, learnMore: () -> Unit, @@ -183,7 +185,7 @@ private fun UserAddressLayout( Column( Modifier.verticalScroll(rememberScrollState()), ) { - AppBarTitle(stringResource(MR.strings.simplex_address), hostDevice(rhId), withPadding = false) + AppBarTitle(stringResource(MR.strings.simplex_address), hostDevice(user?.remoteHostId), withPadding = false) Column( Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF), horizontalAlignment = Alignment.CenterHorizontally, @@ -432,6 +434,7 @@ private fun SaveAASButton(disabled: Boolean, onClick: () -> Unit) { fun PreviewUserAddressLayoutNoAddress() { SimpleXTheme { UserAddressLayout( + user = User.sampleData, userAddress = null, createAddress = {}, share = { _ -> }, @@ -440,7 +443,6 @@ fun PreviewUserAddressLayoutNoAddress() { setProfileAddress = { _ -> }, learnMore = {}, shareViaProfile = remember { mutableStateOf(false) }, - rhId = null, onCloseHandler = remember { mutableStateOf({}) }, sendEmail = {}, ) @@ -466,6 +468,7 @@ private fun showUnsavedChangesAlert(save: () -> Unit, revert: () -> Unit) { fun PreviewUserAddressLayoutAddressCreated() { SimpleXTheme { UserAddressLayout( + user = User.sampleData, userAddress = UserContactLinkRec("https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D"), createAddress = {}, share = { _ -> }, @@ -474,7 +477,6 @@ fun PreviewUserAddressLayoutAddressCreated() { setProfileAddress = { _ -> }, learnMore = {}, shareViaProfile = remember { mutableStateOf(false) }, - rhId = null, onCloseHandler = remember { mutableStateOf({}) }, sendEmail = {}, ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt index 4bc2d92410..bf7c4ac802 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt @@ -29,7 +29,11 @@ import java.net.URI @Composable fun UserProfileView(chatModel: ChatModel, close: () -> Unit) { - val user = chatModel.currentUser.value + val u = remember {chatModel.currentUser} + val user = u.value + KeyChangeEffect(u.value?.remoteHostId, u.value?.userId) { + close() + } if (user != null) { var profile by remember { mutableStateOf(user.profile.toProfile()) } UserProfileLayout(