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.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.runtime.LaunchedEffect 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.AccountEditScreen2 import com.aiosman.riderpro.ui.comment.CommentsScreen import com.aiosman.riderpro.ui.favourite.FavouriteNoticeScreen import com.aiosman.riderpro.ui.follower.FollowerListScreen import com.aiosman.riderpro.ui.follower.FollowerNoticeScreen import com.aiosman.riderpro.ui.follower.FollowingListScreen 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.index.tabs.message.NotificationsScreen import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen import com.aiosman.riderpro.ui.like.LikeNoticeScreen 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.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") data object FollowerList : NavigationRoute("FollowerList/{id}") data object FollowingList : NavigationRoute("FollowingList/{id}") } @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 = 50)) }, exitTransition = { fadeOut(animationSpec = tween(durationMillis = 50)) } ) { 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) { LikeNoticeScreen() } composable(route = NavigationRoute.Followers.route) { FollowerNoticeScreen() } 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) { AccountEditScreen2() } composable(route = NavigationRoute.ImageViewer.route) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { ImageViewer() } } composable(route = NavigationRoute.ChangePasswordScreen.route) { ChangePasswordScreen() } composable(route = NavigationRoute.FavouritesScreen.route) { FavouriteNoticeScreen() } composable(route = NavigationRoute.NewPostImageGrid.route) { NewPostImageGridScreen() } composable(route = NavigationRoute.Search.route) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { SearchScreen() } } composable( route = NavigationRoute.FollowerList.route, arguments = listOf(navArgument("id") { type = NavType.IntType }) ) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { FollowerListScreen(it.arguments?.getInt("id")!!) } } composable( route = NavigationRoute.FollowingList.route, arguments = listOf(navArgument("id") { type = NavType.IntType }) ) { CompositionLocalProvider( LocalAnimatedContentScope provides this, ) { FollowingListScreen(it.arguments?.getInt("id")!!) } } } } @OptIn(ExperimentalSharedTransitionApi::class) @Composable fun Navigation(startDestination: String = NavigationRoute.Login.route,onLaunch: (navController: NavHostController) -> Unit) { val navController = rememberNavController() LaunchedEffect(Unit) { onLaunch(navController) } SharedTransitionLayout { CompositionLocalProvider( LocalNavController provides navController, LocalSharedTransitionScope provides this@SharedTransitionLayout, ) { Box { NavigationController( navController = navController, startDestination = startDestination ) } } } }