From ecd547b86c35b36fa12bd902dd47edacbd29ddda Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 13 Feb 2020 17:59:16 +0100 Subject: [PATCH] Auto close the room picker and open the first room when data are shared in case of multi selection --- .../home/room/detail/RoomDetailFragment.kt | 2 +- .../features/navigation/DefaultNavigator.kt | 8 ++-- .../riotx/features/navigation/Navigator.kt | 6 ++- .../features/share/IncomingShareFragment.kt | 38 ++++++++++++------- .../features/share/IncomingShareViewEvents.kt | 6 ++- .../features/share/IncomingShareViewModel.kt | 36 ++++++++++++------ 6 files changed, 63 insertions(+), 33 deletions(-) diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 7d45db2aae..7a64953986 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -1352,7 +1352,7 @@ class RoomDetailFragment @Inject constructor( override fun onContentAttachmentsReady(attachments: List) { val grouped = attachments.toGroupedContentAttachmentData() if (grouped.notPreviewables.isNotEmpty()) { - // Send the non previewable attachment right now (?) + // Send the not previewable attachment right now (?) roomDetailViewModel.handle(RoomDetailAction.SendMedia(grouped.notPreviewables, false)) } if (grouped.previewables.isNotEmpty()) { diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt index ecc806c798..1d0bf23e84 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/DefaultNavigator.kt @@ -64,15 +64,15 @@ class DefaultNavigator @Inject constructor( startActivity(context, intent, buildTask) } - override fun performDeviceVerification(context: Context, otherUserId: String, sasTransationId: String) { + override fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) { val session = sessionHolder.getSafeActiveSession() ?: return - val tx = session.getVerificationService().getExistingTransaction(otherUserId, sasTransationId) ?: return + val tx = session.getVerificationService().getExistingTransaction(otherUserId, sasTransactionId) ?: return (tx as? IncomingSasVerificationTransaction)?.performAccept() if (context is VectorBaseActivity) { VerificationBottomSheet.withArgs( roomId = null, otherUserId = otherUserId, - transactionId = sasTransationId + transactionId = sasTransactionId ).show(context.supportFragmentManager, "REQPOP") } } @@ -126,7 +126,7 @@ class DefaultNavigator @Inject constructor( startActivity(context, intent, buildTask) } - override fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData) { + override fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) { val args = RoomDetailArgs(roomId, null, sharedData) val intent = RoomDetailActivity.newIntent(activity, args) activity.startActivity(intent) diff --git a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt index 0f368362e8..89eab73af1 100644 --- a/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/riotx/features/navigation/Navigator.kt @@ -26,11 +26,13 @@ interface Navigator { fun openRoom(context: Context, roomId: String, eventId: String? = null, buildTask: Boolean = false) - fun performDeviceVerification(context: Context, otherUserId: String, sasTransationId: String) + fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) + fun requestSessionVerification(context: Context) + fun waitSessionVerification(context: Context) - fun openRoomForSharing(activity: Activity, roomId: String, sharedData: SharedData) + fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) fun openNotJoinedRoom(context: Context, roomIdOrAlias: String?, eventId: String? = null, buildTask: Boolean = false) diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareFragment.kt index 81ae6e2fd9..1ba00ad50c 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareFragment.kt @@ -48,6 +48,10 @@ import im.vector.riotx.features.login.LoginActivity import kotlinx.android.synthetic.main.fragment_incoming_share.* import javax.inject.Inject +/** + * Display the list of rooms + * The user can select multiple rooms to send the data to + */ class IncomingShareFragment @Inject constructor( val incomingShareViewModelFactory: IncomingShareViewModel.Factory, private val incomingShareController: IncomingShareController, @@ -55,7 +59,7 @@ class IncomingShareFragment @Inject constructor( ) : VectorBaseFragment(), AttachmentsHelper.Callback, IncomingShareController.Callback { private lateinit var attachmentsHelper: AttachmentsHelper - private val incomingShareViewModel: IncomingShareViewModel by fragmentViewModel() + private val viewModel: IncomingShareViewModel by fragmentViewModel() override fun getLayoutResId() = R.layout.fragment_incoming_share @@ -92,21 +96,29 @@ class IncomingShareFragment @Inject constructor( } override fun onQueryTextChange(newText: String): Boolean { - incomingShareViewModel.handle(IncomingShareAction.FilterWith(newText)) + viewModel.handle(IncomingShareAction.FilterWith(newText)) return true } }) sendShareButton.setOnClickListener { _ -> handleSendShare() } - incomingShareViewModel.observeViewEvents { + viewModel.observeViewEvents { when (it) { is IncomingShareViewEvents.ShareToRoom -> handleShareToRoom(it) is IncomingShareViewEvents.EditMediaBeforeSending -> handleEditMediaBeforeSending(it) + is IncomingShareViewEvents.MultipleRoomsShareDone -> handleMultipleRoomsShareDone(it) }.exhaustive } } + private fun handleMultipleRoomsShareDone(viewEvent: IncomingShareViewEvents.MultipleRoomsShareDone) { + requireActivity().let { + navigator.openRoom(it, viewEvent.roomId) + it.finish() + } + } + private fun handleEditMediaBeforeSending(event: IncomingShareViewEvents.EditMediaBeforeSending) { val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(event.contentAttachmentData)) startActivityForResult(intent, AttachmentsPreviewActivity.REQUEST_CODE) @@ -119,8 +131,8 @@ class IncomingShareFragment @Inject constructor( AttachmentsPreviewActivity.REQUEST_CODE -> { val sendData = AttachmentsPreviewActivity.getOutput(data) val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data) - incomingShareViewModel.handle(IncomingShareAction.UpdateSharedData(SharedData.Attachments(sendData))) - incomingShareViewModel.handle(IncomingShareAction.ShareMedia(keepOriginalSize)) + viewModel.handle(IncomingShareAction.UpdateSharedData(SharedData.Attachments(sendData))) + viewModel.handle(IncomingShareAction.ShareMedia(keepOriginalSize)) } } } @@ -146,12 +158,12 @@ class IncomingShareFragment @Inject constructor( if (event.showAlert) { showConfirmationDialog(event.roomSummary, event.sharedData) } else { - navigator.openRoomForSharing(requireActivity(), event.roomSummary.roomId, event.sharedData) + navigator.openRoomForSharingAndFinish(requireActivity(), event.roomSummary.roomId, event.sharedData) } } private fun handleSendShare() { - incomingShareViewModel.handle(IncomingShareAction.ShareToSelectedRooms) + viewModel.handle(IncomingShareAction.ShareToSelectedRooms) } override fun onDestroyView() { @@ -167,7 +179,7 @@ class IncomingShareFragment @Inject constructor( override fun onContentAttachmentsReady(attachments: List) { val sharedData = SharedData.Attachments(attachments) - incomingShareViewModel.handle(IncomingShareAction.UpdateSharedData(sharedData)) + viewModel.handle(IncomingShareAction.UpdateSharedData(sharedData)) } override fun onAttachmentsProcessFailed() { @@ -186,7 +198,7 @@ class IncomingShareFragment @Inject constructor( false } else { val sharedData = SharedData.Text(sharedText) - incomingShareViewModel.handle(IncomingShareAction.UpdateSharedData(sharedData)) + viewModel.handle(IncomingShareAction.UpdateSharedData(sharedData)) true } } @@ -198,7 +210,7 @@ class IncomingShareFragment @Inject constructor( .setTitle(R.string.send_attachment) .setMessage(getString(R.string.share_confirm_room, roomSummary.displayName)) .setPositiveButton(R.string.send) { _, _ -> - navigator.openRoomForSharing(requireActivity(), roomSummary.roomId, sharedData) + navigator.openRoomForSharingAndFinish(requireActivity(), roomSummary.roomId, sharedData) } .setNegativeButton(R.string.cancel, null) .show() @@ -211,17 +223,17 @@ class IncomingShareFragment @Inject constructor( requireActivity().finish() } - override fun invalidate() = withState(incomingShareViewModel) { + override fun invalidate() = withState(viewModel) { sendShareButton.isVisible = it.isInMultiSelectionMode incomingShareController.setData(it) } override fun onRoomClicked(roomSummary: RoomSummary) { - incomingShareViewModel.handle(IncomingShareAction.SelectRoom(roomSummary, false)) + viewModel.handle(IncomingShareAction.SelectRoom(roomSummary, false)) } override fun onRoomLongClicked(roomSummary: RoomSummary): Boolean { - incomingShareViewModel.handle(IncomingShareAction.SelectRoom(roomSummary, true)) + viewModel.handle(IncomingShareAction.SelectRoom(roomSummary, true)) return true } } diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewEvents.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewEvents.kt index 6195e21753..2940a1e750 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewEvents.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewEvents.kt @@ -21,6 +21,10 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.core.platform.VectorViewEvents sealed class IncomingShareViewEvents : VectorViewEvents { - data class ShareToRoom(val roomSummary: RoomSummary, val sharedData: SharedData, val showAlert: Boolean) : IncomingShareViewEvents() + data class ShareToRoom(val roomSummary: RoomSummary, + val sharedData: SharedData, + val showAlert: Boolean) : IncomingShareViewEvents() + data class EditMediaBeforeSending(val contentAttachmentData: List) : IncomingShareViewEvents() + data class MultipleRoomsShareDone(val roomId: String) : IncomingShareViewEvents() } diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt index e4cd47f624..d78ebcae31 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareViewModel.kt @@ -129,16 +129,17 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: } } + private fun handleShareMediaToSelectedRooms(action: IncomingShareAction.ShareMedia) = withState { state -> + (state.sharedData as? SharedData.Attachments)?.let { + shareAttachments(it.attachmentData, state.selectedRoomIds, proposeMediaEdition = false, compressMediaBeforeSending = !action.keepOriginalSize) + } + } + private fun shareAttachments(attachmentData: List, selectedRoomIds: Set, proposeMediaEdition: Boolean, compressMediaBeforeSending: Boolean) { - if (!proposeMediaEdition) { - // Pick the first room to send the media - selectedRoomIds.firstOrNull() - ?.let { roomId -> session.getRoom(roomId) } - ?.sendMedias(attachmentData, compressMediaBeforeSending, selectedRoomIds) - } else { + if (proposeMediaEdition) { val grouped = attachmentData.toGroupedContentAttachmentData() if (grouped.notPreviewables.isNotEmpty()) { // Send the not previewable attachment right now (?) @@ -146,17 +147,28 @@ class IncomingShareViewModel @AssistedInject constructor(@Assisted initialState: selectedRoomIds.firstOrNull() ?.let { roomId -> session.getRoom(roomId) } ?.sendMedias(grouped.notPreviewables, compressMediaBeforeSending, selectedRoomIds) + + // Ensure they will not be sent twice + setState { + copy( + sharedData = SharedData.Attachments(grouped.previewables) + ) + } } if (grouped.previewables.isNotEmpty()) { // In case of multiple share of media, edit them first _viewEvents.post(IncomingShareViewEvents.EditMediaBeforeSending(grouped.previewables)) + } else { + // This is it, pass the first roomId to let the screen open it + _viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(selectedRoomIds.first())) } - } - } - - private fun handleShareMediaToSelectedRooms(action: IncomingShareAction.ShareMedia) = withState { state -> - (state.sharedData as? SharedData.Attachments)?.let { - shareAttachments(it.attachmentData, state.selectedRoomIds, proposeMediaEdition = false, compressMediaBeforeSending = !action.keepOriginalSize) + } else { + // Pick the first room to send the media + selectedRoomIds.firstOrNull() + ?.let { roomId -> session.getRoom(roomId) } + ?.sendMedias(attachmentData, compressMediaBeforeSending, selectedRoomIds) + // This is it, pass the first roomId to let the screen open it + _viewEvents.post(IncomingShareViewEvents.MultipleRoomsShareDone(selectedRoomIds.first())) } }