diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferViewModel.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferViewModel.kt index c56d4994f..6e9487077 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferViewModel.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferViewModel.kt @@ -59,8 +59,9 @@ class NewTransferViewModel @Inject constructor( private val _failedFiles = MutableSharedFlow() val failedFiles: SharedFlow = _failedFiles - private val filesToImport: CountChannel = CountChannel() + private val filesToImport: TransferCountChannel = TransferCountChannel() val filesToImportCount: StateFlow = filesToImport.count + val currentSessionTotalUploadedFiles: StateFlow = filesToImport.currentSessionTotalUploadedFiles private val filesMutationMutex = Mutex() @@ -181,23 +182,34 @@ class NewTransferViewModel @Inject constructor( _failedFiles.emit(file) } - private class CountChannel { - private val channel = Channel(capacity = Channel.UNLIMITED) + private class TransferCountChannel { + private val channel = Channel(capacity = Channel.UNLIMITED) private val _count = MutableStateFlow(0) val count: StateFlow = _count + // Session resets when reaching 0 files in the queue + private val _currentSessionTotalUploadedFiles = MutableStateFlow(0) + val currentSessionTotalUploadedFiles: StateFlow = _currentSessionTotalUploadedFiles + private val countMutex = Mutex() - suspend fun send(element: T) { - countMutex.withLock { _count.value += 1 } + suspend fun send(element: PickedFile) { + countMutex.withLock { + _count.value += 1 + _currentSessionTotalUploadedFiles.value += 1 + } channel.send(element) } - suspend fun consume(process: suspend (T) -> Unit) { + suspend fun consume(process: suspend (PickedFile) -> Unit) { for (element in channel) { process(element) - countMutex.withLock { _count.value -= 1 } + countMutex.withLock { + val newValue = _count.value - 1 + _count.value = newValue + if (newValue == 0) _currentSessionTotalUploadedFiles.value = 0 + } } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt index 680cf9e03..4bcec948a 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/importfiles/ImportFilesScreen.kt @@ -47,9 +47,11 @@ fun ImportFilesScreen( ) { val files by newTransferViewModel.filesDebounced.collectAsStateWithLifecycle() val filesToImportCount by newTransferViewModel.filesToImportCount.collectAsStateWithLifecycle() + val currentSessionTotalUploadedFiles by newTransferViewModel.currentSessionTotalUploadedFiles.collectAsStateWithLifecycle() ImportFilesScreen( files = { files }, filesToImportCount = { filesToImportCount }, + currentSessionTotalUploadedFiles = { currentSessionTotalUploadedFiles }, removeFileByUid = newTransferViewModel::removeFileByUid, addFiles = newTransferViewModel::addFiles, closeActivity = closeActivity @@ -60,6 +62,7 @@ fun ImportFilesScreen( private fun ImportFilesScreen( files: () -> List, filesToImportCount: () -> Int, + currentSessionTotalUploadedFiles: () -> Int, removeFileByUid: (uid: String) -> Unit, addFiles: (List) -> Unit, closeActivity: () -> Unit, @@ -73,7 +76,9 @@ private fun ImportFilesScreen( val spaceLeft = (TOTAL_FILE_SIZE - usedSpace).coerceAtLeast(0) getHumanReadableSize(context, spaceLeft) } - val isSendButtonEnabled by remember { derivedStateOf { importedFiles.isNotEmpty() && filesToImportCount() == 0 } } + val isSendButtonEnabled by remember { derivedStateOf { importedFiles.isNotEmpty() } } + val isImporting by remember { derivedStateOf { filesToImportCount() > 0 } } + val importProgress by remember { derivedStateOf { 1 - (filesToImportCount().toFloat() / currentSessionTotalUploadedFiles()) } } val filePickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.OpenMultipleDocuments() @@ -90,11 +95,18 @@ private fun ImportFilesScreen( ) }, topButton = { modifier -> + val progress: (() -> Float)? = if (isImporting) { + { importProgress } + } else { + null + } + LargeButton( modifier = modifier, titleRes = R.string.transferSendButton, style = ButtonType.PRIMARY, enabled = { isSendButtonEnabled }, + determinateProgress = progress, onClick = { /*TODO*/ }, ) }, @@ -120,6 +132,13 @@ private fun ImportFilesScreen( @Composable private fun ImportFilesScreenPreview(@PreviewParameter(FileUiListPreviewParameter::class) files: List) { SwissTransferTheme { - ImportFilesScreen({ files }, { 0 }, {}, {}, closeActivity = {}) + ImportFilesScreen( + files = { files }, + filesToImportCount = { 0 }, + currentSessionTotalUploadedFiles = { 0 }, + removeFileByUid = {}, + addFiles = {}, + closeActivity = {} + ) } }