Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

15 Refactor executeDownloadActions #1427

Merged
merged 4 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading