diff --git a/app/src/main/java/com/infomaniak/drive/ui/menu/TrashFragment.kt b/app/src/main/java/com/infomaniak/drive/ui/menu/TrashFragment.kt index dad3e1ae6b..f900ab4fcd 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/menu/TrashFragment.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/menu/TrashFragment.kt @@ -66,6 +66,8 @@ class TrashFragment : FileSubTypeListFragment() { } setupMultiSelectLayout() + observeDriveTrash() + observeTrashedFolderFiles() } private fun initParams() = with(binding) { @@ -155,6 +157,30 @@ class TrashFragment : FileSubTypeListFragment() { binding.noFilesLayout.toggleVisibility(fileAdapter.getFiles().isEmpty()) } + private fun observeDriveTrash() { + trashViewModel.driveTrashResults.observe(viewLifecycleOwner) { result -> + populateFileList( + files = result?.files ?: ArrayList(), + isComplete = result?.isComplete ?: true, + forceClean = result?.isFirstPage == true, + isNewSort = result?.isNewSort ?: false, + ) + } + } + + private fun observeTrashedFolderFiles() { + trashViewModel.trashedFolderFilesResults.observe(viewLifecycleOwner) { + it?.let { result -> + populateFileList( + files = result.files, + isComplete = result.isComplete, + forceClean = result.isFirstPage, + isNewSort = result.isNewSort, + ) + } + } + } + companion object { const val MATOMO_CATEGORY = "trashFileAction" } @@ -187,26 +213,13 @@ class TrashFragment : FileSubTypeListFragment() { fileAdapter.isComplete = false folder?.let { folder -> - trashViewModel.getTrashedFolderFiles(folder, fileListViewModel.sortType).observe(viewLifecycleOwner) { result -> - result?.apply { - populateFileList( - files = result.files, - isComplete = isComplete, - forceClean = result.isFirstPage, - isNewSort = isNewSort, - ) - } - } + trashViewModel.loadTrashedFolderFiles( + file = folder, + order = fileListViewModel.sortType, + isNewSort = isNewSort, + ) } ?: run { - trashViewModel.getDriveTrash(AccountUtils.currentDriveId, fileListViewModel.sortType) - .observe(viewLifecycleOwner) { result -> - populateFileList( - files = result?.files ?: ArrayList(), - isComplete = result?.isComplete ?: true, - forceClean = result?.isFirstPage == true, - isNewSort = isNewSort, - ) - } + trashViewModel.loadDriveTrash(AccountUtils.currentDriveId, fileListViewModel.sortType, isNewSort) } } } diff --git a/app/src/main/java/com/infomaniak/drive/ui/menu/TrashViewModel.kt b/app/src/main/java/com/infomaniak/drive/ui/menu/TrashViewModel.kt index 0aaafd18f6..4ba437c918 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/menu/TrashViewModel.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/menu/TrashViewModel.kt @@ -17,90 +17,98 @@ */ package com.infomaniak.drive.ui.menu -import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.liveData +import androidx.lifecycle.viewModelScope import com.infomaniak.drive.data.api.ApiRepository import com.infomaniak.drive.data.models.File import com.infomaniak.drive.ui.fileList.FileListFragment import com.infomaniak.lib.core.utils.SingleLiveEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job +import kotlinx.coroutines.launch class TrashViewModel : ViewModel() { val selectedFile = MutableLiveData() val removeFileId = SingleLiveEvent() - private var getDeletedFilesJob: Job = Job() + var driveTrashResults = MutableLiveData() + var trashedFolderFilesResults = MutableLiveData() - fun getTrashedFolderFiles(file: File, order: File.SortType): LiveData { - getDeletedFilesJob.cancel() - getDeletedFilesJob = Job() - return liveData(Dispatchers.IO + getDeletedFilesJob) { - suspend fun recursive(page: Int) { - val apiResponse = ApiRepository.getTrashedFolderFiles(file, order, page) - if (apiResponse.isSuccess()) { - val data = apiResponse.data - when { - data == null -> Unit - data.size < ApiRepository.PER_PAGE -> emit( - FileListFragment.FolderFilesResult( - parentFolder = file, - files = ArrayList(data), - isComplete = true, - isFirstPage = page == 1, - ) - ) - else -> { - emit( - FileListFragment.FolderFilesResult( - parentFolder = file, - files = ArrayList(data), - isComplete = false, - isFirstPage = page == 1 - ) - ) - recursive(page + 1) - } - } - } else emit(null) + private var getDeletedFilesJob: Job? = null + + fun loadDriveTrash(driveId: Int, order: File.SortType, isNewSort: Boolean) { + getDeletedFilesJob?.cancel() + getDeletedFilesJob = viewModelScope.launch(Dispatchers.IO) { + driveTrashResults.postValue(getDriveTrash(driveId, order, isNewSort)) + } + } + + fun loadTrashedFolderFiles(file: File, order: File.SortType, isNewSort: Boolean) { + getDeletedFilesJob?.cancel() + getDeletedFilesJob = viewModelScope.launch(Dispatchers.IO) { + trashedFolderFilesResults.postValue(getTrashedFolderFiles(file, order, isNewSort)) + } + } + + private fun getTrashedFolderFiles(file: File, order: File.SortType, isNewSort: Boolean): FileListFragment.FolderFilesResult? { + + tailrec fun recursive(page: Int): FileListFragment.FolderFilesResult? { + val apiResponse = ApiRepository.getTrashedFolderFiles(file, order, page) + val data = apiResponse.data + return when { + data == null -> null + data.size < ApiRepository.PER_PAGE -> + FileListFragment.FolderFilesResult( + parentFolder = file, + files = ArrayList(data), + isComplete = true, + isFirstPage = page == 1, + isNewSort = isNewSort, + ) + else -> { + FileListFragment.FolderFilesResult( + parentFolder = file, + files = ArrayList(data), + isComplete = false, + isFirstPage = page == 1, + isNewSort = isNewSort, + ) + recursive(page + 1) + } } - recursive(1) } + + return recursive(1) } - fun getDriveTrash(driveId: Int, order: File.SortType): LiveData { - getDeletedFilesJob.cancel() - getDeletedFilesJob = Job() - return liveData(Dispatchers.IO + getDeletedFilesJob) { - suspend fun recursive(page: Int) { - val apiResponse = ApiRepository.getDriveTrash(driveId, order, page) - if (apiResponse.isSuccess()) { - when { - apiResponse.data.isNullOrEmpty() -> emit(null) - apiResponse.data!!.size < ApiRepository.PER_PAGE -> emit( - FileListFragment.FolderFilesResult( - files = apiResponse.data!!, - isComplete = true, - isFirstPage = page == 1, - ) - ) - else -> { - emit( - FileListFragment.FolderFilesResult( - files = apiResponse.data!!, - isComplete = false, - isFirstPage = page == 1, - ) - ) - recursive(page + 1) - } - } - } else emit(null) + private fun getDriveTrash(driveId: Int, order: File.SortType, isNewSort: Boolean): FileListFragment.FolderFilesResult? { + + fun recursive(page: Int): FileListFragment.FolderFilesResult? { + val apiResponse = ApiRepository.getDriveTrash(driveId, order, page) + return when { + apiResponse.data.isNullOrEmpty() -> null + apiResponse.data!!.size < ApiRepository.PER_PAGE -> + FileListFragment.FolderFilesResult( + files = apiResponse.data!!, + isComplete = true, + isFirstPage = page == 1, + isNewSort = isNewSort, + ) + else -> { + FileListFragment.FolderFilesResult( + files = apiResponse.data!!, + isComplete = false, + isFirstPage = page == 1, + isNewSort = isNewSort, + ) + recursive(page + 1) + } } - recursive(1) } + + return recursive(1) } fun emptyTrash(driveId: Int) = liveData(Dispatchers.IO) { @@ -108,6 +116,6 @@ class TrashViewModel : ViewModel() { } fun cancelTrashFileJob() { - getDeletedFilesJob.cancel() + getDeletedFilesJob?.cancel() } }