package com.aiosman.riderpro.ui import ChangePasswordScreen import ImageViewer import ModificationListScreen import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionLayout import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import com.aiosman.riderpro.LocalAnimatedContentScope import com.aiosman.riderpro.LocalNavController import com.aiosman.riderpro.LocalSharedTransitionScope import com.aiosman.riderpro.ui.account.AccountEditScreen import com.aiosman.riderpro.ui.comment.CommentsScreen import com.aiosman.riderpro.ui.favourite.FavouriteScreen import com.aiosman.riderpro.ui.follower.FollowerScreen import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen import com.aiosman.riderpro.ui.gallery.OfficialPhotographerScreen import com.aiosman.riderpro.ui.gallery.ProfileTimelineScreen import com.aiosman.riderpro.ui.index.IndexScreen import com.aiosman.riderpro.ui.like.LikeScreen import com.aiosman.riderpro.ui.location.LocationDetailScreen import com.aiosman.riderpro.ui.login.EmailSignupScreen import com.aiosman.riderpro.ui.login.LoginPage import com.aiosman.riderpro.ui.login.SignupScreen import com.aiosman.riderpro.ui.login.UserAuthScreen import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen import com.aiosman.riderpro.ui.modification.EditModificationScreen import com.aiosman.riderpro.ui.post.NewPostImageGridScreen import com.aiosman.riderpro.ui.post.NewPostScreen import com.aiosman.riderpro.ui.post.PostScreen import com.aiosman.riderpro.ui.profile.AccountProfile sealed class NavigationRoute( val route: String, ) { data object Index : NavigationRoute("Index") data object ProfileTimeline : NavigationRoute("ProfileTimeline") data object LocationDetail : NavigationRoute("LocationDetail/{x}/{y}") data object OfficialPhoto : NavigationRoute("OfficialPhoto") data object OfficialPhotographer : NavigationRoute("OfficialPhotographer") data object Post : NavigationRoute("Post/{id}") data object ModificationList : NavigationRoute("ModificationList") data object MyMessage : NavigationRoute("MyMessage") data object Comments : NavigationRoute("Comments") data object Likes : NavigationRoute("Likes") data object Followers : NavigationRoute("Followers") data object NewPost : NavigationRoute("NewPost") data object EditModification : NavigationRoute("EditModification") data object Login : NavigationRoute("Login") data object AccountProfile : NavigationRoute("AccountProfile/{id}") data object SignUp : NavigationRoute("SignUp") data object UserAuth : NavigationRoute("UserAuth") data object EmailSignUp : NavigationRoute("EmailSignUp") data object AccountEdit : NavigationRoute("AccountEditScreen") data object ImageViewer : NavigationRoute("ImageViewer") data object ChangePasswordScreen : NavigationRoute("ChangePasswordScreen") data object FavouritesScreen : NavigationRoute("FavouritesScreen") data object NewPostImageGrid : NavigationRoute("NewPostImageGrid") data object Search : NavigationRoute("Search") } @Composable fun NavigationController( navController: NavHostController, startDestination: String = NavigationRoute.Login.route ) { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } NavHost( navController = navController, startDestination = startDestination, ) { composable(route = NavigationRoute.Index.route) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { IndexScreen() } } composable(route = NavigationRoute.ProfileTimeline.route) { ProfileTimelineScreen() } composable( route = NavigationRoute.LocationDetail.route, arguments = listOf( navArgument("x") { type = NavType.FloatType }, navArgument("y") { type = NavType.FloatType } ) ) { Box( modifier = Modifier.padding(bottom = navigationBarHeight) ) { val x = it.arguments?.getFloat("x") ?: 0f val y = it.arguments?.getFloat("y") ?: 0f LocationDetailScreen( x, y ) } } composable(route = NavigationRoute.OfficialPhoto.route) { OfficialGalleryScreen() } composable(route = NavigationRoute.OfficialPhotographer.route) { OfficialPhotographerScreen() } composable( route = NavigationRoute.Post.route, arguments = listOf(navArgument("id") { type = NavType.StringType }), enterTransition = { fadeIn(animationSpec = tween(durationMillis = 100)) }, exitTransition = { fadeOut(animationSpec = tween(durationMillis = 100)) } ) { backStackEntry -> CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { val id = backStackEntry.arguments?.getString("id") PostScreen( id!! ) } } composable(route = NavigationRoute.ModificationList.route) { ModificationListScreen() } composable(route = NavigationRoute.MyMessage.route) { NotificationsScreen() } composable(route = NavigationRoute.Comments.route) { CommentsScreen() } composable(route = NavigationRoute.Likes.route) { LikeScreen() } composable(route = NavigationRoute.Followers.route) { FollowerScreen() } composable( route = NavigationRoute.NewPost.route, enterTransition = { fadeIn(animationSpec = tween(durationMillis = 100)) }, exitTransition = { fadeOut(animationSpec = tween(durationMillis = 100)) } ) { NewPostScreen() } composable(route = NavigationRoute.EditModification.route) { Box( modifier = Modifier.padding(top = 64.dp) ) { EditModificationScreen() } } composable(route = NavigationRoute.Login.route) { LoginPage() } composable( route = NavigationRoute.AccountProfile.route, arguments = listOf(navArgument("id") { type = NavType.StringType }) ) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { AccountProfile(it.arguments?.getString("id")!!) } } composable(route = NavigationRoute.SignUp.route) { SignupScreen() } composable(route = NavigationRoute.UserAuth.route) { UserAuthScreen() } composable(route = NavigationRoute.EmailSignUp.route) { EmailSignupScreen() } composable(route = NavigationRoute.AccountEdit.route) { AccountEditScreen() } composable(route = NavigationRoute.ImageViewer.route) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { ImageViewer() } } composable(route = NavigationRoute.ChangePasswordScreen.route) { ChangePasswordScreen() } composable(route = NavigationRoute.FavouritesScreen.route) { FavouriteScreen() } composable(route = NavigationRoute.NewPostImageGrid.route) { NewPostImageGridScreen() } composable(route = NavigationRoute.Search.route) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { SearchScreen() } } } } @OptIn(ExperimentalSharedTransitionApi::class) @Composable fun Navigation(startDestination: String = NavigationRoute.Login.route) { val navController = rememberNavController() SharedTransitionLayout { CompositionLocalProvider( LocalNavController provides navController, LocalSharedTransitionScope provides this@SharedTransitionLayout, ) { Box { NavigationController( navController = navController, startDestination = startDestination ) } } } }