From af27dfbe9e891494ead7f3e22115de56efc797bc Mon Sep 17 00:00:00 2001 From: Fabian Devel Date: Tue, 1 Oct 2024 14:57:51 +0200 Subject: [PATCH] refactor(PublicShareViewModel): Use a flow to avoid observing several time --- .../OnPublicShareItemClickListener.kt | 19 ++++++---- .../ui/publicShare/PublicShareListFragment.kt | 12 +++++- .../ui/publicShare/PublicShareViewModel.kt | 38 ++++++++++++------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/infomaniak/drive/ui/publicShare/OnPublicShareItemClickListener.kt b/app/src/main/java/com/infomaniak/drive/ui/publicShare/OnPublicShareItemClickListener.kt index f3fe5f711e..e9b4cd3a74 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/publicShare/OnPublicShareItemClickListener.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/publicShare/OnPublicShareItemClickListener.kt @@ -21,6 +21,7 @@ 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 @@ -34,6 +35,7 @@ import com.infomaniak.drive.views.FileInfoActionsView.OnItemClickListener.Compan import com.infomaniak.lib.core.utils.safeNavigate import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.invoke +import kotlinx.coroutines.launch interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListener { @@ -46,8 +48,10 @@ interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListen fun onDownloadError(@StringRes errorMessage: Int) fun observeCacheFileForAction(viewLifecycleOwner: LifecycleOwner) { - publicShareViewModel.fetchCacheFileForActionResult.observe(viewLifecycleOwner) { (cacheFile, action) -> - cacheFile?.let { file -> executeDownloadAction(action, file) } ?: onDownloadError(getErrorMessage(action)) + viewLifecycleOwner.lifecycleScope.launch { + publicShareViewModel.fetchCacheFileForActionResult.collect { (cacheFile, action) -> + executeAction(cacheFile, action) + } } } @@ -72,16 +76,15 @@ interface OnPublicShareItemClickListener : FileInfoActionsView.OnItemClickListen } private fun startAction(action: DownloadAction) { - val cacheFileResult = publicShareViewModel.fetchCacheFileForAction( + publicShareViewModel.fetchCacheFileForAction( file = currentFile, + action = action, navigateToDownloadDialog = ::navigateToDownloadDialog, ) + } - ownerFragment?.viewLifecycleOwner?.let { lifecycleOwner -> - cacheFileResult.observe(lifecycleOwner) { cacheFile -> - cacheFile?.let { file -> executeDownloadAction(action, file) } ?: onDownloadError(getErrorMessage(action)) - } - } + fun executeAction(cacheFile: IOFile?, action: DownloadAction) { + cacheFile?.let { file -> executeDownloadAction(action, file) } ?: onDownloadError(getErrorMessage(action)) } private suspend fun navigateToDownloadDialog() = Dispatchers.Main { diff --git a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareListFragment.kt b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareListFragment.kt index bb96b4fcd1..3fddbcf3a8 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareListFragment.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareListFragment.kt @@ -27,6 +27,7 @@ import androidx.activity.result.contract.ActivityResultContracts.StartActivityFo 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 @@ -37,6 +38,7 @@ 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 @@ -54,6 +56,7 @@ import com.infomaniak.lib.core.utils.safeNavigate import com.infomaniak.lib.core.utils.whenResultIsOk import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.invoke +import kotlinx.coroutines.launch import com.infomaniak.lib.core.R as RCore class PublicShareListFragment : FileListFragment() { @@ -121,6 +124,12 @@ class PublicShareListFragment : FileListFragment() { observeRootFile() observeFiles() + + viewLifecycleOwner.lifecycleScope.launch { + publicShareViewModel.fetchCacheFileForActionResult.collect { (cacheFile, action) -> + if (action == DownloadAction.OPEN_BOOKMARK) executeOpenBookmarkAction(cacheFile) + } + } } private fun initFileAdapter() { @@ -219,6 +228,7 @@ class PublicShareListFragment : FileListFragment() { private fun openBookmark(file: File) { publicShareViewModel.fetchCacheFileForAction( file = file, + action = DownloadAction.OPEN_BOOKMARK, navigateToDownloadDialog = { Dispatchers.Main { safeNavigate( @@ -227,7 +237,7 @@ class PublicShareListFragment : FileListFragment() { ) } }, - ).observe(viewLifecycleOwner, ::executeOpenBookmarkAction) + ) } private fun executeOpenBookmarkAction(cacheFile: IOFile?) = runCatching { diff --git a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareViewModel.kt b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareViewModel.kt index c73329c492..5a562a54e6 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareViewModel.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicShareViewModel.kt @@ -18,7 +18,10 @@ package com.infomaniak.drive.ui.publicShare import android.app.Application -import androidx.lifecycle.* +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewModelScope import com.infomaniak.drive.MainApplication import com.infomaniak.drive.data.api.ApiRepository import com.infomaniak.drive.data.api.CursorApiResponse @@ -34,6 +37,8 @@ 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(application: Application, val savedStateHandle: SavedStateHandle) : AndroidViewModel(application) { @@ -44,7 +49,10 @@ class PublicShareViewModel(application: Application, val savedStateHandle: Saved var fileClicked: File? = null val downloadProgressLiveData = MutableLiveData(0) val buildArchiveResult = SingleLiveEvent>() - val fetchCacheFileForActionResult = SingleLiveEvent>() + val fetchCacheFileForActionResult = MutableSharedFlow>( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) val initPublicShareResult = SingleLiveEvent>() val submitPasswordResult = SingleLiveEvent() var hasBeenAuthenticated = false @@ -159,19 +167,21 @@ class PublicShareViewModel(application: Application, val savedStateHandle: Saved buildArchiveResult.postValue(result) } - fun fetchCacheFileForAction(file: File?, navigateToDownloadDialog: suspend () -> Unit) = liveData(Dispatchers.IO) { - runCatching { - emit( - file!!.convertToIOFile( - context = appContext, - onProgress = downloadProgressLiveData::postValue, - navigateToDownloadDialog = navigateToDownloadDialog, + 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 -> - emit(null) - downloadProgressLiveData.postValue(null) - exception.printStackTrace() + }.onFailure { exception -> + fetchCacheFileForActionResult.emit(null to action) + downloadProgressLiveData.postValue(null) + exception.printStackTrace() + } } }