From f64268efdb13f90314c2b1fa605de4566c9b0286 Mon Sep 17 00:00:00 2001 From: Maxime Naturel Date: Wed, 23 Feb 2022 16:27:18 +0100 Subject: [PATCH] Adding download media use case --- .../home/room/detail/TimelineFragment.kt | 1 + .../action/MessageActionsViewModel.kt | 4 +- .../media/VectorAttachmentViewerActivity.kt | 7 +++ .../domain/usecase/DownloadMediaUseCase.kt | 51 +++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/media/domain/usecase/DownloadMediaUseCase.kt diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 1a40018526..9ca2e28646 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -2111,6 +2111,7 @@ class TimelineFragment @Inject constructor( } } + // TODO mutualize permission checking creating activity extension or delegation interface? private fun onSaveActionClicked(action: EventSharedAction.Save) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && !checkPermissions(PERMISSIONS_FOR_WRITING_FILES, requireActivity(), saveActionActivityResultLauncher)) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 13ae8098c3..6acaedfd3c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -251,7 +251,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted val msgType = messageContent?.msgType return arrayListOf().apply { - // TODO need to check all possible items and confirm order + // TODO need to check all possible items and confirm order changes to apply when { timelineEvent.root.sendState.hasFailed() -> { addActionsForFailedState(timelineEvent, actionPermissions, messageContent, msgType) @@ -569,7 +569,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } - // TODO need to add this into Viewer screen to check if it is saveable? => create extension on MessageType? + // TODO need to add this into Viewer screen to check if it is saveable? => create extension on MessageType or useCase? private fun canSave(msgType: String?): Boolean { return when (msgType) { MessageType.MSGTYPE_IMAGE, diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index 3e8f48df98..61110e9d81 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -271,6 +271,13 @@ class VectorAttachmentViewerActivity : AttachmentViewerActivity(), AttachmentInt } } + // TODO create suspendable usecase: downloadMediaUseCase + // create interface for base use case + // create ViewModel with action downloadAction, events downloading, downloaded, error + // call usecase using viewModel + // launch coroutine in Activity using repeatOnLifeCycle extension + // add unit tests for usecase? + /* ========================================================================================== * COMPANION * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/app/features/media/domain/usecase/DownloadMediaUseCase.kt b/vector/src/main/java/im/vector/app/features/media/domain/usecase/DownloadMediaUseCase.kt new file mode 100644 index 0000000000..e7b7d02f01 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/media/domain/usecase/DownloadMediaUseCase.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.media.domain.usecase + +import android.content.Context +import androidx.core.net.toUri +import dagger.hilt.android.qualifiers.ApplicationContext +import im.vector.app.core.intent.getMimeTypeFromUri +import im.vector.app.core.utils.saveMedia +import im.vector.app.features.notifications.NotificationUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import java.io.File +import javax.inject.Inject + +class DownloadMediaUseCase @Inject constructor( + @ApplicationContext private val appContext: Context, + private val notificationUtils: NotificationUtils +) { + + /* ========================================================================================== + * Public API + * ========================================================================================== */ + + // TODO find a way to provide Dispatchers via Interface to be able to unit tests + suspend fun execute(file: File): Result = withContext(Dispatchers.IO) { + runCatching { + saveMedia( + context = appContext, + file = file, + title = file.name, + mediaMimeType = getMimeTypeFromUri(appContext, file.toUri()), + notificationUtils = notificationUtils + ) + } + } +}