From 44334364168545cdef5e145294efa3bb5034b323 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 28 Oct 2020 18:09:16 +0100 Subject: [PATCH] Room member profile: Add action to create (or open) a DM (#2310) --- CHANGES.md | 1 + .../android/sdk/common/CryptoTestHelper.kt | 9 +-------- .../android/sdk/api/session/room/RoomService.kt | 16 ++++++++++++++++ .../VerificationBottomSheetViewModel.kt | 10 +--------- .../home/room/detail/RoomDetailAction.kt | 1 + .../home/room/detail/RoomDetailFragment.kt | 7 +++++++ .../home/room/detail/RoomDetailPendingAction.kt | 1 + .../home/room/detail/RoomDetailViewEvents.kt | 2 ++ .../home/room/detail/RoomDetailViewModel.kt | 16 ++++++++++++++++ .../RoomMemberProfileController.kt | 9 +++++++++ .../RoomMemberProfileFragment.kt | 5 +++++ vector/src/main/res/values/strings.xml | 1 + 12 files changed, 61 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8261412b4c..5cf2e7f53b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Improvements 🙌: - Use Hardware keyboard enter to send message (use shift-enter for new line) (#1881, #1440) - Edit and remove icons are now visible on image attachment preview screen (#2294) - Room profile: BigImageViewerActivity now only display the image. Use the room setting to change or delete the room Avatar + - Room member profile: Add action to create (or open) a DM (#2310) Bugfix 🐛: - Messages encrypted with no way to decrypt after SDK update from 0.18 to 1.0.0 (#2252) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 370b416f54..ec2b28a4da 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -285,14 +285,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) { fun createDM(alice: Session, bob: Session): String { val roomId = mTestHelper.doSync { - alice.createRoom( - CreateRoomParams().apply { - invitedUserIds.add(bob.myUserId) - setDirectMessage() - enableEncryptionIfInvitedUsersSupportIt = true - }, - it - ) + alice.createDirectRoom(bob.myUserId, it) } mTestHelper.waitWithLatch { latch -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index 965e7e23bb..9bd7738af4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -35,6 +35,22 @@ interface RoomService { fun createRoom(createRoomParams: CreateRoomParams, callback: MatrixCallback): Cancelable + /** + * Create a direct room asynchronously. This is a facility method to create a direct room with the necessary parameters + */ + fun createDirectRoom(otherUserId: String, + callback: MatrixCallback): Cancelable { + return createRoom( + CreateRoomParams() + .apply { + invitedUserIds.add(otherUserId) + setDirectMessage() + enableEncryptionIfInvitedUsersSupportIt = true + }, + callback + ) + } + /** * Join a room by id * @param roomIdOrAlias the roomId or the room alias of the room to join diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 2720c20fb0..22711108f8 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -49,7 +49,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.events.model.LocalEcho -import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 @@ -245,14 +244,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( pendingRequest = Loading() ) } - val roomParams = CreateRoomParams() - .apply { - invitedUserIds.add(otherUserId) - setDirectMessage() - enableEncryptionIfInvitedUsersSupportIt = true - } - - session.createRoom(roomParams, object : MatrixCallback { + session.createDirectRoom(otherUserId, object : MatrixCallback { override fun onSuccess(data: String) { setState { copy( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index 912967138b..99adc0bf83 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -88,5 +88,6 @@ sealed class RoomDetailAction : VectorViewModelAction { val userJustAccepted: Boolean, val grantedEvents: RoomDetailViewEvents) : RoomDetailAction() + data class OpenOrCreateDm(val userId: String) : RoomDetailAction() data class JumpToReadReceipt(val userId: String) : RoomDetailAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 24f3cabe12..9c6c473a7f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -363,6 +363,7 @@ class RoomDetailFragment @Inject constructor( RoomDetailViewEvents.ShowWaitingView -> vectorBaseActivity.showWaitingView() RoomDetailViewEvents.HideWaitingView -> vectorBaseActivity.hideWaitingView() is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it) + is RoomDetailViewEvents.OpenRoom -> handleOpenRoom(it) }.exhaustive } @@ -371,6 +372,10 @@ class RoomDetailFragment @Inject constructor( } } + private fun handleOpenRoom(openRoom: RoomDetailViewEvents.OpenRoom) { + navigator.openRoom(requireContext(), openRoom.roomId, null) + } + private fun requestNativeWidgetPermission(it: RoomDetailViewEvents.RequestNativeWidgetPermission) { val tag = RoomWidgetPermissionBottomSheet::class.java.name val dFrag = childFragmentManager.findFragmentByTag(tag) as? RoomWidgetPermissionBottomSheet @@ -886,6 +891,8 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.handle(RoomDetailAction.JumpToReadReceipt(roomDetailPendingAction.userId)) is RoomDetailPendingAction.MentionUser -> insertUserDisplayNameInTextEditor(roomDetailPendingAction.userId) + is RoomDetailPendingAction.OpenOrCreateDm -> + roomDetailViewModel.handle(RoomDetailAction.OpenOrCreateDm(roomDetailPendingAction.userId)) }.exhaustive } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailPendingAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailPendingAction.kt index 394d46ef8d..598ab9d056 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailPendingAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailPendingAction.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.detail sealed class RoomDetailPendingAction { + data class OpenOrCreateDm(val userId: String) : RoomDetailPendingAction() data class JumpToReadReceipt(val userId: String) : RoomDetailPendingAction() data class MentionUser(val userId: String) : RoomDetailPendingAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index ee2d193473..b9e3e6b31d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -38,6 +38,8 @@ sealed class RoomDetailViewEvents : VectorViewEvents { data class ShowInfoOkDialog(val message: String) : RoomDetailViewEvents() data class ShowE2EErrorMessage(val withHeldCode: WithHeldCode?) : RoomDetailViewEvents() + data class OpenRoom(val roomId: String) : RoomDetailViewEvents() + data class NavigateToEvent(val eventId: String) : RoomDetailViewEvents() data class JoinJitsiConference(val widget: Widget, val withVideo: Boolean) : RoomDetailViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index e721e0948d..ca387db1f6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -273,10 +273,26 @@ class RoomDetailViewModel @AssistedInject constructor( is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId) is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action) is RoomDetailAction.CancelSend -> handleCancel(action) + is RoomDetailAction.OpenOrCreateDm -> handleOpenOrCreateDm(action) is RoomDetailAction.JumpToReadReceipt -> handleJumpToReadReceipt(action) }.exhaustive } + private fun handleOpenOrCreateDm(action: RoomDetailAction.OpenOrCreateDm) { + val existingDm = session.getExistingDirectRoomWithUser(action.userId) + if (existingDm == null) { + // First create a direct room + viewModelScope.launch(Dispatchers.IO) { + val roomId = awaitCallback { + session.createDirectRoom(action.userId, it) + } + _viewEvents.post(RoomDetailViewEvents.OpenRoom(roomId)) + } + } else { + _viewEvents.post(RoomDetailViewEvents.OpenRoom(existingDm.roomId)) + } + } + private fun handleJumpToReadReceipt(action: RoomDetailAction.JumpToReadReceipt) { room.getUserReadReceipt(action.userId) ?.let { handleNavigateToEvent(RoomDetailAction.NavigateToEvent(it, true)) } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt index a3ffd80ade..2e91091443 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt @@ -45,6 +45,7 @@ class RoomMemberProfileController @Inject constructor( fun onTapVerify() fun onShowDeviceList() fun onShowDeviceListNoCrossSigning() + fun onOpenDmClicked() fun onJumpToReadReceiptClicked() fun onMentionClicked() fun onEditPowerLevel(currentRole: Role) @@ -173,6 +174,14 @@ class RoomMemberProfileController @Inject constructor( buildProfileSection(stringProvider.getString(R.string.room_profile_section_more)) + buildProfileAction( + id = "direct", + editable = false, + title = stringProvider.getString(R.string.room_member_open_or_create_dm), + dividerColor = dividerColor, + action = { callback?.onOpenDmClicked() } + ) + if (state.hasReadReceipt) { buildProfileAction( id = "read_receipt", diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index 2f5b2d5387..d60b5580fa 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -278,6 +278,11 @@ class RoomMemberProfileFragment @Inject constructor( DeviceListBottomSheet.newInstance(it.userId).show(parentFragmentManager, "DEV_LIST") } + override fun onOpenDmClicked() { + roomDetailPendingActionStore.data = RoomDetailPendingAction.OpenOrCreateDm(fragmentArgs.userId) + vectorBaseActivity.finish() + } + override fun onJumpToReadReceiptClicked() { roomDetailPendingActionStore.data = RoomDetailPendingAction.JumpToReadReceipt(fragmentArgs.userId) vectorBaseActivity.finish() diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index dd461123cc..16ebca5f20 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2167,6 +2167,7 @@ Default in %1$s Custom (%1$d) in %2$s + Direct message Jump to read receipt "Element does not handle events of type '%1$s'"