diff --git a/app/src/main/java/com/flamyoad/filemanager/ui/FileManagerNavHost.kt b/app/src/main/java/com/flamyoad/filemanager/ui/FileManagerNavHost.kt index 9ad5065..3179cd7 100644 --- a/app/src/main/java/com/flamyoad/filemanager/ui/FileManagerNavHost.kt +++ b/app/src/main/java/com/flamyoad/filemanager/ui/FileManagerNavHost.kt @@ -1,11 +1,17 @@ package com.flamyoad.filemanager.ui +import androidx.compose.animation.AnimatedContentTransitionScope import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition +import androidx.compose.animation.core.tween import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.dropUnlessResumed +import androidx.navigation.NavController import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost +import com.flamyoad.common.Route import com.flamyoad.explorer_impl.FileListRoute import com.flamyoad.explorer_impl.HomePageRoute import com.flamyoad.explorer_impl.fileListRoute @@ -20,20 +26,49 @@ fun FileManagerNavHost( NavHost( navController = navController, startDestination = HomePageRoute, - enterTransition = { EnterTransition.None }, - exitTransition = { ExitTransition.None }, + enterTransition = { + slideIntoContainer( + AnimatedContentTransitionScope.SlideDirection.Start, + tween(500) + ) + }, + exitTransition = { + slideOutOfContainer( + AnimatedContentTransitionScope.SlideDirection.Start, + tween(500) + ) + }, modifier = modifier ) { homePageRoute( onNavigateToFileList = { directory -> - navController.navigate(FileListRoute(directory)) + navController.navigateSafely(FileListRoute(directory)) } ) fileListRoute( onNavigateToFileList = { directory -> - navController.navigate(FileListRoute(directory)) + navController.navigateSafely(FileListRoute(directory)) } ) imageViewerRoute() } +} + +// dropUnlessResumed is used to avoid navigating multiple times to the same destination or +// popping the backstack when the destination is already on top. +// https://github.com/seve-andre/jetpack-compose-template/pull/37 +//@Composable +//fun NavController.navigateTo( +// route: Route, +//): () -> Unit = dropUnlessResumed { this.navigate(route) } + + +// https://slack-chats.kotlinlang.org/t/18829110/hey-guys-i-m-trying-to-wrap-my-head-around-the-new-dropunles +// https://github.com/HedvigInsurance/android/blob/develop/app%2Fapp%2Fsrc%2Fmain%2Fkotlin%2Fcom%2Fhedvig%2Fandroid%2Fapp%2Fnavigation%2FRememberNavigator.kt#L20-L28 +// Pros: Doesn't require @Composable context +fun NavController.navigateSafely(route: Route) { + val currentBackStackEntry = this.currentBackStackEntry ?: return + if (currentBackStackEntry.lifecycle.currentState == Lifecycle.State.RESUMED) { + this.navigate(route) + } } \ No newline at end of file diff --git a/common-ui/src/main/java/com/flamyoad/common_ui/BaseViewModel.kt b/common-ui/src/main/java/com/flamyoad/common_ui/BaseViewModel.kt index 402cf02..ff132c4 100644 --- a/common-ui/src/main/java/com/flamyoad/common_ui/BaseViewModel.kt +++ b/common-ui/src/main/java/com/flamyoad/common_ui/BaseViewModel.kt @@ -11,11 +11,11 @@ abstract class BaseViewModel: ViewModel() { fun Flow.toStateFlow( initialState: T, - stopTimeoutMillis: Long = 500L + started: SharingStarted = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000L), ): StateFlow { return stateIn( scope = this@BaseViewModel.viewModelScope, - started = SharingStarted.WhileSubscribed(stopTimeoutMillis = stopTimeoutMillis), + started = started, initialValue = initialState, ) } diff --git a/explorer-impl/src/main/java/com/flamyoad/explorer_impl/ui/filelist/FileListViewModel.kt b/explorer-impl/src/main/java/com/flamyoad/explorer_impl/ui/filelist/FileListViewModel.kt index 5df6c90..30db7a0 100644 --- a/explorer-impl/src/main/java/com/flamyoad/explorer_impl/ui/filelist/FileListViewModel.kt +++ b/explorer-impl/src/main/java/com/flamyoad/explorer_impl/ui/filelist/FileListViewModel.kt @@ -8,6 +8,7 @@ import com.flamyoad.file_scanner.DirectoryProvider import com.flamyoad.file_scanner.FileHandle import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filterNotNull @@ -33,7 +34,7 @@ internal class FileListViewModel @Inject constructor( .flatMapLatest { directoryProvider.observeDir(it) } .map, UiState>> { UiState.Success(it) } // oh no...we shoul;dnt have to .catch { emit(UiState.Error(it)) } - .toStateFlow(initialState = UiState.Loading) + .toStateFlow(initialState = UiState.Loading, started = SharingStarted.Lazily) fun initPath(path: File) { currentPath.update { path }