From 07e06957ef14f90b47b7009cae42888408eb700f Mon Sep 17 00:00:00 2001 From: Yoan Pintas Date: Mon, 5 Jun 2023 22:02:11 +0200 Subject: [PATCH] Prompt the user when the invited MatrixId is not recognized (#8483) --- changelog.d/8468.bugfix | 1 + .../ui-strings/src/main/res/values/strings.xml | 4 ++++ .../createdirect/CreateDirectRoomActivity.kt | 15 ++++++++++++++- .../features/invite/InviteUsersToRoomActivity.kt | 15 ++++++++++++++- .../features/userdirectory/PendingSelection.kt | 2 +- .../features/userdirectory/UserListViewModel.kt | 4 ++++ .../features/userdirectory/UserListViewState.kt | 1 + 7 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 changelog.d/8468.bugfix diff --git a/changelog.d/8468.bugfix b/changelog.d/8468.bugfix new file mode 100644 index 0000000000..f250d48dc6 --- /dev/null +++ b/changelog.d/8468.bugfix @@ -0,0 +1 @@ +Prompt the user when the invited MatrixId is not recognized diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index ee7d2fea12..9f842a5741 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -1729,6 +1729,8 @@ "Public" "Anyone will be able to join this room" "The room has been created, but some invitations have not been sent for the following reason:\n\n%s" + Unable to find profiles for the Matrix IDs listed below. Would you like to start a chat anyway?\n\n%s + Start chat anyway "An error occurred getting trust info" "An error occurred getting keys backup data" @@ -2744,6 +2746,8 @@ Invitations sent to %1$s and %2$d more We could not invite users. Please check the users you want to invite and try again. + Unable to find profiles for the Matrix IDs listed below. Would you like to invite them anyway?\n\n%s + Invite anyway Scan a QR code Share my code diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index fbddf815c6..faf4374d93 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -48,6 +48,7 @@ import im.vector.app.features.qrcode.QrCodeScannerEvents import im.vector.app.features.qrcode.QrCodeScannerFragment import im.vector.app.features.qrcode.QrCodeScannerViewModel import im.vector.app.features.qrcode.QrScannerArgs +import im.vector.app.features.userdirectory.PendingSelection import im.vector.app.features.userdirectory.UserListFragment import im.vector.app.features.userdirectory.UserListFragmentArgs import im.vector.app.features.userdirectory.UserListSharedAction @@ -160,7 +161,19 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() { } private fun handleOnMenuItemSubmitClick(action: UserListSharedAction.OnMenuItemSubmitClick) { - viewModel.handle(CreateDirectRoomAction.PrepareRoomWithSelectedUsers(action.selections)) + val unknownUsers = action.selections.filter { it is PendingSelection.UserPendingSelection && it.isUnknownUser } + if (unknownUsers.isEmpty()) { + viewModel.handle(CreateDirectRoomAction.PrepareRoomWithSelectedUsers(action.selections)) + } else { + MaterialAlertDialogBuilder(this) + .setTitle(R.string.dialog_title_confirmation) + .setMessage(getString(R.string.create_room_unknown_users_dialog_content, unknownUsers.joinToString("\n • ", " • ") { it.getMxId() })) + .setPositiveButton(R.string.create_room_unknown_users_dialog_submit) { _, _ -> + viewModel.handle(CreateDirectRoomAction.PrepareRoomWithSelectedUsers(action.selections)) + } + .setNegativeButton(R.string.action_cancel, null) + .show() + } } private fun renderCreateAndInviteState(state: Async) { diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 7f514d2ad2..c000efaef2 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -37,6 +37,7 @@ import im.vector.app.core.utils.onPermissionDeniedSnackbar import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.toast import im.vector.app.features.contactsbook.ContactsBookFragment +import im.vector.app.features.userdirectory.PendingSelection import im.vector.app.features.userdirectory.UserListFragment import im.vector.app.features.userdirectory.UserListFragmentArgs import im.vector.app.features.userdirectory.UserListSharedAction @@ -94,7 +95,19 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() { } private fun handleOnMenuItemSubmitClick(action: UserListSharedAction.OnMenuItemSubmitClick) { - viewModel.handle(InviteUsersToRoomAction.InviteSelectedUsers(action.selections)) + val unknownUsers = action.selections.filter { it is PendingSelection.UserPendingSelection && it.isUnknownUser } + if (unknownUsers.isEmpty()) { + viewModel.handle(InviteUsersToRoomAction.InviteSelectedUsers(action.selections)) + } else { + MaterialAlertDialogBuilder(this) + .setTitle(R.string.dialog_title_confirmation) + .setMessage(getString(R.string.invite_unknown_users_dialog_content, unknownUsers.joinToString("\n • ", " • ") { it.getMxId() })) + .setPositiveButton(R.string.invite_unknown_users_dialog_submit) { _, _ -> + viewModel.handle(InviteUsersToRoomAction.InviteSelectedUsers(action.selections)) + } + .setNegativeButton(R.string.action_cancel, null) + .show() + } } private fun openPhoneBook() { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt b/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt index 643aa30995..7838b76452 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/PendingSelection.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.toMatrixItem sealed class PendingSelection { - data class UserPendingSelection(val user: User) : PendingSelection() + data class UserPendingSelection(val user: User, var isUnknownUser: Boolean = false) : PendingSelection() data class ThreePidPendingSelection(val threePid: ThreePid) : PendingSelection() fun getBestName(): String { diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt index ae28ff020d..96875d73a5 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewModel.kt @@ -260,6 +260,7 @@ class UserListViewModel @AssistedInject constructor( .sortedBy { it.toMatrixItem().firstLetterOfDisplayName() } val userProfile = if (MatrixPatterns.isUserId(search)) { val user = tryOrNull { session.profileService().getProfileAsUser(search) } + setState { copy(unknownUserId = search.takeIf { user == null }) } User( userId = search, displayName = user?.displayName, @@ -284,6 +285,9 @@ class UserListViewModel @AssistedInject constructor( (action.pendingSelection is PendingSelection.UserPendingSelection && state.pendingSelections.last() is PendingSelection.UserPendingSelection) if (canSelectUser) { + if (action.pendingSelection is PendingSelection.UserPendingSelection) { + action.pendingSelection.isUnknownUser = action.pendingSelection.getMxId() == state.unknownUserId + } val selections = state.pendingSelections.toggle(action.pendingSelection, singleElement = state.singleSelection) setState { copy(pendingSelections = selections) } } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewState.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewState.kt index ec932a2a57..27fa11bf54 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewState.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewState.kt @@ -30,6 +30,7 @@ data class UserListViewState( val matchingEmail: Async = Uninitialized, val filteredMappedContacts: List = emptyList(), val pendingSelections: Set = emptySet(), + val unknownUserId: String? = null, val searchTerm: String = "", val singleSelection: Boolean, val single3pidSelection: Boolean,