diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/NavigationDestination.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/NavigationDestination.kt index fd56edace..2d7b2132f 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/NavigationDestination.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/navigation/NavigationDestination.kt @@ -96,22 +96,30 @@ sealed class NewTransferNavigation : NavigationDestination() { @Serializable data object ImportFilesDestination : NewTransferNavigation() + @Serializable data object ValidateUserEmailDestination : NewTransferNavigation() + @Serializable data class UploadProgressDestination( val transferType: TransferTypeUi, val totalSize: Long, val recipients: List, ) : NewTransferNavigation() + @Serializable data class UploadSuccessDestination( val transferType: TransferTypeUi, val transferUrl: String, val recipients: List, ) : NewTransferNavigation() + @Serializable - data object UploadErrorDestination : NewTransferNavigation() + data class UploadErrorDestination( + val transferType: TransferTypeUi, + val totalSize: Long, + val recipients: List, + ) : NewTransferNavigation() companion object { val startDestination = ImportFilesDestination diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportFilesViewModel.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportFilesViewModel.kt index efc68d79e..12dce4603 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportFilesViewModel.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/ImportFilesViewModel.kt @@ -113,9 +113,16 @@ class ImportFilesViewModel @Inject constructor( viewModelScope.launch(ioDispatcher) { if (isFirstViewModelCreation) { isFirstViewModelCreation = false - // Remove old imported files in case it would've crashed or similar to start with a clean slate. This is required - // for already imported files restoration to not pick up old files in some extreme cases. + + // Remove old imported files in case it would've crashed (or similar) to start with a clean slate. + // This is required for already imported files restoration to not pick up old files in some extreme cases. removeOldData() + + // Set default values to advanced transfer options. This need to be done here in the `init`, + // because we only want to do it once. If we come back from a cancelled or edited transfer, + // we don't want to erase user's choices about advanced transfer options. + initTransferOptionsValues() + } else { importationFilesManager.restoreAlreadyImportedFiles() } @@ -233,7 +240,7 @@ class ImportFilesViewModel @Inject constructor( ) } - fun initTransferOptionsValues() { + private fun initTransferOptionsValues() { viewModelScope.launch(ioDispatcher) { appSettingsManager.getAppSettings()?.let { selectTransferValidityPeriod(it.validityPeriod.toTransferOption()) diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferNavHost.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferNavHost.kt index 764a77020..d3de353f3 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferNavHost.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/NewTransferNavHost.kt @@ -29,6 +29,8 @@ import com.infomaniak.swisstransfer.ui.screen.newtransfer.importfiles.ValidateUs import com.infomaniak.swisstransfer.ui.screen.newtransfer.upload.UploadErrorScreen import com.infomaniak.swisstransfer.ui.screen.newtransfer.upload.UploadProgressScreen import com.infomaniak.swisstransfer.ui.screen.newtransfer.upload.UploadSuccessScreen +import io.sentry.Sentry +import io.sentry.SentryLevel @Composable fun NewTransferNavHost(navController: NavHostController, closeActivity: () -> Unit) { @@ -52,7 +54,11 @@ fun NewTransferNavHost(navController: NavHostController, closeActivity: () -> Un navigateToUploadSuccess = { transferUrl -> navController.navigate(UploadSuccessDestination(args.transferType, transferUrl, args.recipients)) }, - navigateToUploadError = { navController.navigate(UploadErrorDestination) }, + navigateToUploadError = { + navController.navigate( + UploadErrorDestination(args.transferType, args.totalSize, args.recipients), + ) + }, navigateBackToImportFiles = { navController.popBackStack(route = ImportFilesDestination, inclusive = false) }, ) } @@ -66,7 +72,29 @@ fun NewTransferNavHost(navController: NavHostController, closeActivity: () -> Un ) } composable { - UploadErrorScreen(navigateToImportFiles = { navController.navigate(ImportFilesDestination) }) + val args = it.toRoute() + UploadErrorScreen( + navigateBackToUploadProgress = { + val hasPoppedBack = navController.popBackStack( + route = UploadProgressDestination(args.transferType, args.totalSize, args.recipients), + inclusive = false, + ) + if (!hasPoppedBack) { + navController.navigate(UploadProgressDestination(args.transferType, args.totalSize, args.recipients)) + Sentry.captureMessage( + "PopBackStack to retry transfer after error has failed", + SentryLevel.ERROR, + ) { scope -> + scope.setExtra("transferType", args.transferType.toString()) + scope.setExtra("totalSize", args.totalSize.toString()) + scope.setExtra("recipients.count", args.recipients.count().toString()) + } + } + }, + navigateBackToImportFiles = { + navController.popBackStack(route = ImportFilesDestination, inclusive = false) + }, + ) } } } 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 dd2bafa10..959beab45 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 @@ -93,8 +93,6 @@ fun ImportFilesScreen( resetSendActionResult = importFilesViewModel::resetSendActionResult, ) - LaunchedEffect(Unit) { importFilesViewModel.initTransferOptionsValues() } - val transferOptionsCallbacks = importFilesViewModel.getTransferOptionsCallbacks( transferOptionsStates = { buildList { diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadErrorScreen.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadErrorScreen.kt index bc22273aa..7c7ef2f66 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadErrorScreen.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadErrorScreen.kt @@ -20,11 +20,9 @@ package com.infomaniak.swisstransfer.ui.screen.newtransfer.upload import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource +import androidx.hilt.navigation.compose.hiltViewModel import com.infomaniak.swisstransfer.R -import com.infomaniak.swisstransfer.ui.components.BottomStickyButtonScaffold -import com.infomaniak.swisstransfer.ui.components.BrandTopAppBar -import com.infomaniak.swisstransfer.ui.components.EmptyState -import com.infomaniak.swisstransfer.ui.components.LargeButton +import com.infomaniak.swisstransfer.ui.components.* import com.infomaniak.swisstransfer.ui.images.AppImages.AppIllus import com.infomaniak.swisstransfer.ui.images.illus.uploadError.GhostMagnifyingGlassQuestionMark import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme @@ -32,14 +30,26 @@ import com.infomaniak.swisstransfer.ui.utils.PreviewAllWindows import com.infomaniak.core2.R as RCore2 @Composable -fun UploadErrorScreen(navigateToImportFiles: () -> Unit) { +fun UploadErrorScreen( + navigateBackToUploadProgress: () -> Unit, + navigateBackToImportFiles: () -> Unit, + uploadProgressViewModel: UploadProgressViewModel = hiltViewModel(), +) { BottomStickyButtonScaffold( topBar = { BrandTopAppBar() }, - bottomButton = { + topButton = { LargeButton( modifier = it, title = stringResource(RCore2.string.buttonRetry), - onClick = navigateToImportFiles, + onClick = { uploadProgressViewModel.resendLastTransfer(onCompletion = navigateBackToUploadProgress) }, + ) + }, + bottomButton = { + LargeButton( + modifier = it, + title = stringResource(R.string.buttonEditTransfer), + style = ButtonType.SECONDARY, + onClick = { uploadProgressViewModel.removeAllUploadSession(onCompletion = navigateBackToImportFiles) }, ) } ) { @@ -56,7 +66,7 @@ fun UploadErrorScreen(navigateToImportFiles: () -> Unit) { private fun UploadErrorScreenPreview() { SwissTransferTheme { Surface { - UploadErrorScreen({}) + UploadErrorScreen({}, {}) } } } diff --git a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadProgressViewModel.kt b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadProgressViewModel.kt index 10b8669f9..f8c029f60 100644 --- a/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadProgressViewModel.kt +++ b/app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/upload/UploadProgressViewModel.kt @@ -24,6 +24,8 @@ import com.infomaniak.multiplatform_swisstransfer.managers.UploadManager import com.infomaniak.network.NetworkAvailability import com.infomaniak.sentry.SentryLog import com.infomaniak.swisstransfer.di.IoDispatcher +import com.infomaniak.swisstransfer.di.MainDispatcher +import com.infomaniak.swisstransfer.ui.screen.newtransfer.TransferSendManager import com.infomaniak.swisstransfer.workers.UploadWorker import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext @@ -31,6 +33,7 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -38,7 +41,9 @@ class UploadProgressViewModel @Inject constructor( @ApplicationContext private val appContext: Context, private val uploadWorkerScheduler: UploadWorker.Scheduler, private val uploadManager: UploadManager, + private val transferSendManager: TransferSendManager, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, + @MainDispatcher private val mainDispatcher: CoroutineDispatcher, ) : ViewModel() { val isNetworkAvailable = NetworkAvailability(appContext).isNetworkAvailable @@ -91,6 +96,20 @@ class UploadProgressViewModel @Inject constructor( } } + fun removeAllUploadSession(onCompletion: () -> Unit) { + viewModelScope.launch(ioDispatcher) { + uploadManager.removeAllUploadSession() + withContext(mainDispatcher) { onCompletion() } + } + } + + fun resendLastTransfer(onCompletion: () -> Unit) { + viewModelScope.launch(ioDispatcher) { + transferSendManager.resendLastTransfer() + withContext(mainDispatcher) { onCompletion() } + } + } + companion object { private val TAG = UploadProgressViewModel::class.java.simpleName } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c86889d03..5067e4314 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -22,6 +22,7 @@ Link kopieren Download Auswahl herunterladen + Meine Übertragung bearbeiten Beenden Teilen Starten diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1f579232a..d1a9bed43 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -22,6 +22,7 @@ Copiar enlace Descargar Descargar la selección + Editar mi transferencia Acabado Compartir Inicio diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index dd187c5b7..ae746c4b5 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -22,6 +22,7 @@ Copier le lien Télécharger Télécharger la sélection + Modifier mon transfert Terminer Partager Démarrer diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index d173c83ae..ccd469d63 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -22,6 +22,7 @@ Copia link Scaricare Scarica la selezione + Modifica mio trasferimento Finisci Condividi Inizio diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 159564baf..72ea7c43e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -26,6 +26,7 @@ Copy link Download Download selection + Edit my transfer Finish Share Start