Skip to content

Commit

Permalink
Merge pull request #1427 from Infomaniak/15-refactor-executeDownloadA…
Browse files Browse the repository at this point in the history
…ctions

15 Refactor executeDownloadActions
  • Loading branch information
sirambd authored Oct 1, 2024
2 parents d538d7b + f2c1e24 commit 21f0316
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@
*/
package com.infomaniak.drive.ui.publicShare

import android.content.Intent
import androidx.annotation.StringRes
import androidx.core.content.FileProvider
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.infomaniak.drive.R
import com.infomaniak.drive.data.models.File
import com.infomaniak.drive.ui.fileList.BaseDownloadProgressDialog.DownloadAction
import com.infomaniak.drive.ui.fileList.preview.PreviewDownloadProgressDialogArgs
import com.infomaniak.drive.ui.fileList.preview.PreviewPDFHandler
import com.infomaniak.drive.utils.DrivePermissions
import com.infomaniak.drive.utils.IOFile
import com.infomaniak.drive.utils.*
import com.infomaniak.drive.utils.FilePresenter.openBookmarkIntent
import com.infomaniak.drive.utils.Utils.openWith
import com.infomaniak.drive.views.FileInfoActionsView
import com.infomaniak.drive.views.FileInfoActionsView.OnItemClickListener.Companion.downloadFile
import com.infomaniak.lib.core.utils.safeNavigate
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch

interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListener {

Expand All @@ -41,11 +47,19 @@ interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListen
fun onDownloadSuccess()
fun onDownloadError(@StringRes errorMessage: Int)

override fun openWith() = executeActionAndClose(DownloadAction.OPEN_WITH)
fun observeCacheFileForAction(viewLifecycleOwner: LifecycleOwner) {
viewLifecycleOwner.lifecycleScope.launch {
publicShareViewModel.fetchCacheFileForActionResult.collect { (cacheFile, action) ->
cacheFile?.let { file -> executeDownloadAction(action, file) } ?: onDownloadError(getErrorMessage(action))
}
}
}

override fun shareFile() = executeActionAndClose(DownloadAction.SEND_COPY)
override fun openWith() = startAction(DownloadAction.OPEN_WITH)

override fun saveToKDrive() = executeActionAndClose(DownloadAction.SAVE_TO_DRIVE)
override fun shareFile() = startAction(DownloadAction.SEND_COPY)

override fun saveToKDrive() = startAction(DownloadAction.SAVE_TO_DRIVE)

override fun downloadFileClicked() {
super.downloadFileClicked()
Expand All @@ -56,12 +70,20 @@ interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListen
super.printClicked()
previewPDFHandler?.printClicked(
context = currentContext,
onDefaultCase = { executeActionAndClose(DownloadAction.PRINT_PDF, R.string.errorFileNotFound) },
onDefaultCase = { startAction(DownloadAction.PRINT_PDF) },
onError = { onDownloadError(R.string.errorFileNotFound) },
)
}

private suspend fun navigateToDownloadDialog() = withContext(Dispatchers.Main) {
private fun startAction(action: DownloadAction) {
publicShareViewModel.fetchCacheFileForAction(
file = currentFile,
action = action,
navigateToDownloadDialog = ::navigateToDownloadDialog,
)
}

private suspend fun navigateToDownloadDialog() = Dispatchers.Main {
currentFile?.let { file ->
ownerFragment?.safeNavigate(
resId = R.id.previewDownloadProgressDialog,
Expand All @@ -70,15 +92,27 @@ interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListen
}
}

private fun executeActionAndClose(action: DownloadAction, @StringRes errorMessageId: Int = R.string.errorDownload) {
publicShareViewModel.executeDownloadAction(
activityContext = currentContext,
downloadAction = action,
file = currentFile,
navigateToDownloadDialog = ::navigateToDownloadDialog,
onDownloadSuccess = ::onDownloadSuccess,
onDownloadError = { onDownloadError(errorMessageId) },
)
private fun executeDownloadAction(downloadAction: DownloadAction, cacheFile: IOFile) = runCatching {
val uri = FileProvider.getUriForFile(currentContext, currentContext.getString(R.string.FILE_AUTHORITY), cacheFile)

when (downloadAction) {
DownloadAction.OPEN_WITH -> {
currentContext.openWith(uri, currentFile?.getMimeType(), Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
DownloadAction.SEND_COPY -> currentContext.shareFile { uri }
DownloadAction.SAVE_TO_DRIVE -> currentContext.saveToKDrive(uri)
DownloadAction.OPEN_BOOKMARK -> currentContext.openBookmarkIntent(cacheFile.name, uri)
DownloadAction.PRINT_PDF -> currentContext.printPdf(cacheFile)
}

onDownloadSuccess()
}.onFailure { exception ->
exception.printStackTrace()
onDownloadError(getErrorMessage(downloadAction))
}

private fun getErrorMessage(downloadAction: DownloadAction): Int {
return if (downloadAction == DownloadAction.PRINT_PDF) R.string.errorFileNotFound else R.string.errorDownload
}

override fun displayInfoClicked() = Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class PublicShareFileActionsBottomSheetDialog : BottomSheetDialogFragment(), OnP
drivePermissions.registerPermissions(this@PublicShareFileActionsBottomSheetDialog) { authorized ->
if (authorized) downloadFileClicked()
}

observeCacheFileForAction(viewLifecycleOwner)
}

private fun initBottomSheet() = with(binding.publicShareFileActionsView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.core.content.FileProvider
import androidx.core.view.isGone
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
Expand All @@ -45,13 +47,16 @@ import com.infomaniak.drive.ui.publicShare.PublicShareViewModel.Companion.ROOT_S
import com.infomaniak.drive.utils.AccountUtils
import com.infomaniak.drive.utils.DrivePermissions
import com.infomaniak.drive.utils.FilePresenter.displayFile
import com.infomaniak.drive.utils.FilePresenter.openBookmarkIntent
import com.infomaniak.drive.utils.FilePresenter.openFolder
import com.infomaniak.drive.utils.IOFile
import com.infomaniak.drive.views.FileInfoActionsView.OnItemClickListener.Companion.downloadFile
import com.infomaniak.lib.core.utils.SnackbarUtils.showSnackbar
import com.infomaniak.lib.core.utils.safeNavigate
import com.infomaniak.lib.core.utils.whenResultIsOk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch
import com.infomaniak.lib.core.R as RCore

class PublicShareListFragment : FileListFragment() {
Expand Down Expand Up @@ -119,6 +124,7 @@ class PublicShareListFragment : FileListFragment() {

observeRootFile()
observeFiles()
observeBookmarkAction()
}

private fun initFileAdapter() {
Expand Down Expand Up @@ -204,6 +210,14 @@ class PublicShareListFragment : FileListFragment() {
}
}

private fun observeBookmarkAction() {
viewLifecycleOwner.lifecycleScope.launch {
publicShareViewModel.fetchCacheFileForActionResult.collect { (cacheFile, action) ->
if (action == DownloadAction.OPEN_BOOKMARK) executeOpenBookmarkAction(cacheFile)
}
}
}

private fun openFolder(folder: File) {
openFolder(
file = folder,
Expand All @@ -215,24 +229,28 @@ class PublicShareListFragment : FileListFragment() {
}

private fun openBookmark(file: File) {
publicShareViewModel.executeDownloadAction(
activityContext = requireActivity(),
downloadAction = DownloadAction.OPEN_BOOKMARK,
publicShareViewModel.fetchCacheFileForAction(
file = file,
action = DownloadAction.OPEN_BOOKMARK,
navigateToDownloadDialog = {
withContext(Dispatchers.Main) {
Dispatchers.Main {
safeNavigate(
resId = R.id.previewDownloadProgressDialog,
args = PreviewDownloadProgressDialogArgs(file.name).toBundle(),
)
}
},
onDownloadError = {
showSnackbar(
title = R.string.errorGetBookmarkURL,
anchor = (requireActivity() as? PublicShareActivity)?.getMainButton(),
)
},
)
}

private fun executeOpenBookmarkAction(cacheFile: IOFile?) = runCatching {
val uri = FileProvider.getUriForFile(requireContext(), getString(R.string.FILE_AUTHORITY), cacheFile!!)
requireContext().openBookmarkIntent(cacheFile.name, uri)
}.onFailure { exception ->
exception.printStackTrace()
showSnackbar(
title = R.string.errorGetBookmarkURL,
anchor = (requireActivity() as? PublicShareActivity)?.getMainButton(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class PublicSharePreviewSliderFragment : BasePreviewSliderFragment(), OnPublicSh
super.onViewCreated(view, savedInstanceState)

initBottomSheet()
observeCacheFileForAction(viewLifecycleOwner)
}

private fun initBottomSheet() = with(bottomSheetView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
*/
package com.infomaniak.drive.ui.publicShare

import android.content.Context
import android.content.Intent
import androidx.core.content.FileProvider
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.infomaniak.drive.R
import com.infomaniak.drive.MainApplication
import com.infomaniak.drive.data.api.ApiRepository
import com.infomaniak.drive.data.api.CursorApiResponse
import com.infomaniak.drive.data.cache.FolderFilesProvider.FolderFilesProviderArgs
Expand All @@ -34,23 +32,27 @@ import com.infomaniak.drive.data.models.File
import com.infomaniak.drive.data.models.File.SortType
import com.infomaniak.drive.data.models.ShareLink
import com.infomaniak.drive.ui.fileList.BaseDownloadProgressDialog.DownloadAction
import com.infomaniak.drive.utils.FilePresenter.openBookmarkIntent
import com.infomaniak.drive.utils.Utils.openWith
import com.infomaniak.drive.utils.printPdf
import com.infomaniak.drive.utils.saveToKDrive
import com.infomaniak.drive.utils.shareFile
import com.infomaniak.drive.utils.IOFile
import com.infomaniak.lib.core.models.ApiError
import com.infomaniak.lib.core.utils.SentryLog
import com.infomaniak.lib.core.utils.SingleLiveEvent
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow

class PublicShareViewModel(val savedStateHandle: SavedStateHandle) : ViewModel() {
class PublicShareViewModel(application: Application, val savedStateHandle: SavedStateHandle) : AndroidViewModel(application) {

private val appContext = getApplication<MainApplication>()

var rootSharedFile = SingleLiveEvent<File?>()
val childrenLiveData = SingleLiveEvent<Pair<List<File>, Boolean>>()
var fileClicked: File? = null
val downloadProgressLiveData = MutableLiveData(0)
val buildArchiveResult = SingleLiveEvent<Pair<Int?, ArchiveUUID?>>()
val fetchCacheFileForActionResult = MutableSharedFlow<Pair<IOFile?, DownloadAction>>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)
val initPublicShareResult = SingleLiveEvent<Pair<ApiError?, ShareLink?>>()
val submitPasswordResult = SingleLiveEvent<Boolean?>()
var hasBeenAuthenticated = false
Expand Down Expand Up @@ -165,38 +167,21 @@ class PublicShareViewModel(val savedStateHandle: SavedStateHandle) : ViewModel()
buildArchiveResult.postValue(result)
}

fun executeDownloadAction(
activityContext: Context,
downloadAction: DownloadAction,
file: File?,
navigateToDownloadDialog: suspend () -> Unit,
onDownloadSuccess: (() -> Unit)? = null,
onDownloadError: () -> Unit,
) = viewModelScope.launch(Dispatchers.IO) {
runCatching {
val cacheFile = file!!.convertToIOFile(
context = activityContext,
onProgress = downloadProgressLiveData::postValue,
navigateToDownloadDialog = navigateToDownloadDialog,
)

val uri = FileProvider.getUriForFile(activityContext, activityContext.getString(R.string.FILE_AUTHORITY), cacheFile)

when (downloadAction) {
DownloadAction.OPEN_WITH -> {
activityContext.openWith(uri, file.getMimeType(), Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
DownloadAction.SEND_COPY -> activityContext.shareFile { uri }
DownloadAction.SAVE_TO_DRIVE -> activityContext.saveToKDrive(uri)
DownloadAction.OPEN_BOOKMARK -> activityContext.openBookmarkIntent(file.name, uri)
DownloadAction.PRINT_PDF -> activityContext.printPdf(cacheFile)
fun fetchCacheFileForAction(file: File?, action: DownloadAction, navigateToDownloadDialog: suspend () -> Unit) {
viewModelScope.launch(Dispatchers.IO) {
runCatching {
fetchCacheFileForActionResult.emit(
file!!.convertToIOFile(
context = appContext,
onProgress = downloadProgressLiveData::postValue,
navigateToDownloadDialog = navigateToDownloadDialog,
) to action
)
}.onFailure { exception ->
fetchCacheFileForActionResult.emit(null to action)
downloadProgressLiveData.postValue(null)
exception.printStackTrace()
}

Dispatchers.Main { onDownloadSuccess?.invoke() }
}.onFailure { exception ->
downloadProgressLiveData.postValue(null)
exception.printStackTrace()
Dispatchers.Main { onDownloadError() }
}
}

Expand Down

0 comments on commit 21f0316

Please sign in to comment.