Files
OneCamera/app/src/main/java/com/example/onecamera/navigation/OneCameraNavGraph.kt
T
2026-10-13 10:17:03 +08:00

123 lines
4.7 KiB
Kotlin

package com.example.onecamera.navigation
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.example.onecamera.data.preferences.UserPreferences
import com.example.onecamera.data.preferences.UserPreferencesRepository
import com.example.onecamera.ui.camera.CameraScreen
import com.example.onecamera.ui.folders.FoldersScreen
import com.example.onecamera.ui.gallery.GalleryScreen
import com.example.onecamera.ui.settings.SettingsScreen
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.serialization.Serializable
@Serializable
object FoldersRoute
@Serializable
data class GalleryRoute(val folderUri: String)
@Serializable
data class CameraRoute(
val targetFolderUri: String,
val showTargetGalleryAfterSave: Boolean = false,
)
@Serializable
object SettingsRoute
@HiltViewModel
class NavGraphViewModel @Inject constructor(
preferencesRepository: UserPreferencesRepository,
) : ViewModel() {
val preferences: StateFlow<UserPreferences> = preferencesRepository.userPreferencesFlow
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), UserPreferences())
}
@Composable
fun OneCameraNavGraph(navController: NavHostController) {
val viewModel: NavGraphViewModel = hiltViewModel()
val preferences by viewModel.preferences.collectAsStateWithLifecycle()
val transitionsEnabled = preferences.screenTransitionsEnabled
androidx.compose.runtime.CompositionLocalProvider(
com.example.onecamera.ui.components.LocalOneCameraAnimationsEnabled provides transitionsEnabled,
) {
NavHost(
navController = navController,
startDestination = FoldersRoute,
enterTransition = { if (transitionsEnabled) fadeIn(tween(250)) else EnterTransition.None },
exitTransition = { if (transitionsEnabled) fadeOut(tween(250)) else ExitTransition.None },
popEnterTransition = { if (transitionsEnabled) fadeIn(tween(250)) else EnterTransition.None },
popExitTransition = { if (transitionsEnabled) fadeOut(tween(250)) else ExitTransition.None },
) {
composable<FoldersRoute> {
FoldersScreen(
onNavigateToGallery = { folderUri ->
navController.navigate(GalleryRoute(folderUri))
},
onNavigateToCamera = { folderUri ->
navController.navigate(
CameraRoute(
targetFolderUri = folderUri,
showTargetGalleryAfterSave = true,
),
)
},
onNavigateToSettings = {
navController.navigate(SettingsRoute)
},
)
}
composable<GalleryRoute> { backStackEntry ->
val route = backStackEntry.toRoute<GalleryRoute>()
GalleryScreen(
folderUri = route.folderUri,
onNavigateToCamera = { folderUri ->
navController.navigate(CameraRoute(folderUri))
},
onNavigateToSubfolder = { folderUri ->
navController.navigate(GalleryRoute(folderUri))
},
onNavigateBack = { navController.popBackStack() },
)
}
composable<CameraRoute> { backStackEntry ->
val route = backStackEntry.toRoute<CameraRoute>()
CameraScreen(
targetFolderUri = route.targetFolderUri,
onNavigateBack = { navController.popBackStack() },
onPhotoSaved = {
navController.popBackStack()
if (route.showTargetGalleryAfterSave) {
navController.navigate(GalleryRoute(route.targetFolderUri))
}
},
)
}
composable<SettingsRoute> {
SettingsScreen(
onNavigateBack = { navController.popBackStack() },
)
}
}
}
}