Skip to content

Commit

Permalink
refactor(PublicShareViewModel): Refactor executeDownloadAction with l…
Browse files Browse the repository at this point in the history
…iveData
  • Loading branch information
FabianDevel committed Sep 19, 2024
1 parent 9fb3f79 commit 7ed34e9
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@
*/
package com.infomaniak.drive.ui.publicShare

import android.content.Intent
import androidx.annotation.StringRes
import androidx.core.content.FileProvider
import androidx.lifecycle.LifecycleOwner
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

interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListener {

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

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

override fun openWith() = fetchCacheFileForAction(DownloadAction.OPEN_WITH)

override fun shareFile() = executeActionAndClose(DownloadAction.SEND_COPY)
override fun shareFile() = fetchCacheFileForAction(DownloadAction.SEND_COPY)

override fun saveToKDrive() = executeActionAndClose(DownloadAction.SAVE_TO_DRIVE)
override fun saveToKDrive() = fetchCacheFileForAction(DownloadAction.SAVE_TO_DRIVE)

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

private suspend fun navigateToDownloadDialog() = withContext(Dispatchers.Main) {
private fun fetchCacheFileForAction(action: DownloadAction) {
ownerFragment?.viewLifecycleOwner?.let { lifecycleOwner ->
publicShareViewModel.fetchCacheFileForAction(
file = currentFile,
navigateToDownloadDialog = ::navigateToDownloadDialog,
).observe(lifecycleOwner) { cacheFile ->
cacheFile?.let { file -> executeDownloadAction(action, file) } ?: onDownloadError(getErrorMessage(action))
}
}
}

private suspend fun navigateToDownloadDialog() = Dispatchers.Main {
currentFile?.let { file ->
ownerFragment?.safeNavigate(
resId = R.id.previewDownloadProgressDialog,
Expand All @@ -70,15 +91,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,6 +24,7 @@ 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.navigation.fragment.findNavController
Expand All @@ -36,7 +37,6 @@ import com.infomaniak.drive.ui.SaveExternalFilesActivity
import com.infomaniak.drive.ui.SaveExternalFilesActivity.Companion.DESTINATION_DRIVE_ID_KEY
import com.infomaniak.drive.ui.SaveExternalFilesActivity.Companion.DESTINATION_FOLDER_ID_KEY
import com.infomaniak.drive.ui.SaveExternalFilesActivityArgs
import com.infomaniak.drive.ui.fileList.BaseDownloadProgressDialog.DownloadAction
import com.infomaniak.drive.ui.fileList.FileListFragment
import com.infomaniak.drive.ui.fileList.multiSelect.MultiSelectActionsBottomSheetDialog
import com.infomaniak.drive.ui.fileList.preview.PreviewDownloadProgressDialogArgs
Expand All @@ -45,13 +45,15 @@ 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 com.infomaniak.lib.core.R as RCore

class PublicShareListFragment : FileListFragment() {
Expand Down Expand Up @@ -215,24 +217,27 @@ class PublicShareListFragment : FileListFragment() {
}

private fun openBookmark(file: File) {
publicShareViewModel.executeDownloadAction(
activityContext = requireActivity(),
downloadAction = DownloadAction.OPEN_BOOKMARK,
publicShareViewModel.fetchCacheFileForAction(
file = file,
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(),
)
},
).observe(viewLifecycleOwner, ::executeOpenBookmarkAction)
}

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,9 @@
*/
package com.infomaniak.drive.ui.publicShare

import android.content.Context
import android.content.Intent
import androidx.core.content.FileProvider
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.infomaniak.drive.R
import android.app.Application
import androidx.lifecycle.*
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 +29,22 @@ 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.*

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 = SingleLiveEvent<Pair<IOFile?, DownloadAction>>()
val initPublicShareResult = SingleLiveEvent<Pair<ApiError?, ShareLink?>>()
val submitPasswordResult = SingleLiveEvent<Boolean?>()
var hasBeenAuthenticated = false
Expand Down Expand Up @@ -160,38 +154,19 @@ 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) {
fun fetchCacheFileForAction(file: File?, navigateToDownloadDialog: suspend () -> Unit) = liveData(Dispatchers.IO) {
runCatching {
val cacheFile = file!!.convertToIOFile(
context = activityContext,
onProgress = downloadProgressLiveData::postValue,
navigateToDownloadDialog = navigateToDownloadDialog,
emit(
file!!.convertToIOFile(
context = appContext,
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)
}

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

Expand Down

0 comments on commit 7ed34e9

Please sign in to comment.