From ecd547b86c35b36fa12bd902dd47edacbd29ddda Mon Sep 17 00:00:00 2001
From: Benoit Marty <benoitm@matrix.org>
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<ContentAttachmentData>) {
         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<ContentAttachmentData>) {
         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<ContentAttachmentData>) : 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<ContentAttachmentData>,
                                  selectedRoomIds: Set<String>,
                                  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()))
         }
     }