211 lines
9.3 KiB
Kotlin
211 lines
9.3 KiB
Kotlin
package navigation
|
|
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material3.Scaffold
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.collectAsState
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.hilt.navigation.compose.hiltViewModel
|
|
import androidx.navigation.NavHostController
|
|
import androidx.navigation.NavType
|
|
import androidx.navigation.compose.NavHost
|
|
import androidx.navigation.compose.composable
|
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
import androidx.navigation.compose.rememberNavController
|
|
import androidx.navigation.navArgument
|
|
import auth.presentation.LoginScreen
|
|
import auth.presentation.RegisterScreen
|
|
import auth.presentation.AuthViewModel
|
|
import core.presentation.settings.SettingsScreen
|
|
import core.presentation.settings.SettingsViewModel
|
|
import chats.presentation.chat_list.ChatListScreen
|
|
import chats.presentation.chat_list.ChatListViewModel
|
|
import chats.presentation.chat_detail.ChatDetailScreen
|
|
import chats.presentation.chat_detail.ChatDetailViewModel
|
|
import contacts.presentation.ContactListScreen
|
|
import contacts.presentation.ContactListViewModel
|
|
import core.presentation.components.GlassNavigationBar
|
|
import profiles.presentation.ProfileScreen
|
|
import profiles.presentation.EditProfileScreen
|
|
import profiles.presentation.viewmodel.ProfileViewModel
|
|
import stories.presentation.StoryViewModel
|
|
|
|
sealed class Screen(val route: String) {
|
|
object Login : Screen("login")
|
|
object Register : Screen("register")
|
|
object ChatList : Screen("chat_list")
|
|
object ChatDetail : Screen("chat_detail/{chatId}/{chatName}") {
|
|
fun createRoute(chatId: String, chatName: String) = "chat_detail/$chatId/$chatName"
|
|
}
|
|
object Profile : Screen("profile?profileId={profileId}") {
|
|
fun createRoute(profileId: String? = null) = if (profileId != null) "profile?profileId=$profileId" else "profile"
|
|
}
|
|
object EditProfile : Screen("edit_profile")
|
|
object Settings : Screen("settings")
|
|
object Contacts : Screen("contacts")
|
|
}
|
|
|
|
@Composable
|
|
fun AppNavigation(
|
|
navController: NavHostController = rememberNavController()
|
|
) {
|
|
val authViewModel: AuthViewModel = hiltViewModel()
|
|
val authState by authViewModel.state.collectAsState()
|
|
val startDestination = if (authState.isAuthenticated) Screen.ChatList.route else Screen.Login.route
|
|
|
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
val currentRoute = navBackStackEntry?.destination?.route
|
|
|
|
// Определяем, нужно ли показывать нижнюю панель
|
|
val showBottomBar = currentRoute in listOf(
|
|
Screen.ChatList.route,
|
|
Screen.Contacts.route,
|
|
Screen.Settings.route,
|
|
Screen.Profile.route
|
|
)
|
|
|
|
Scaffold(
|
|
bottomBar = {
|
|
if (showBottomBar) {
|
|
GlassNavigationBar(
|
|
currentRoute = currentRoute ?: "",
|
|
onNavigate = { route ->
|
|
navController.navigate(route) {
|
|
popUpTo(Screen.ChatList.route) { saveState = true }
|
|
launchSingleTop = true
|
|
restoreState = true
|
|
}
|
|
},
|
|
userAvatarUrl = null,
|
|
username = "Me"
|
|
)
|
|
}
|
|
}
|
|
) { paddingValues ->
|
|
Box(modifier = Modifier.padding(if (showBottomBar) paddingValues else PaddingValues(0.dp))) {
|
|
NavHost(
|
|
navController = navController,
|
|
startDestination = startDestination
|
|
) {
|
|
composable(Screen.Login.route) {
|
|
val viewModel: AuthViewModel = hiltViewModel()
|
|
LoginScreen(
|
|
viewModel = viewModel,
|
|
onNavigateToRegister = { navController.navigate(Screen.Register.route) },
|
|
onNavigateToSettings = { navController.navigate(Screen.Settings.route) },
|
|
onLoginSuccess = {
|
|
navController.navigate(Screen.ChatList.route) {
|
|
popUpTo(Screen.Login.route) { inclusive = true }
|
|
}
|
|
}
|
|
)
|
|
}
|
|
composable(Screen.Register.route) {
|
|
val viewModel: AuthViewModel = hiltViewModel()
|
|
RegisterScreen(
|
|
viewModel = viewModel,
|
|
onNavigateToLogin = { navController.popBackStack() },
|
|
onRegisterSuccess = {
|
|
navController.navigate(Screen.ChatList.route) {
|
|
popUpTo(Screen.Login.route) { inclusive = true }
|
|
}
|
|
}
|
|
)
|
|
}
|
|
composable(Screen.ChatList.route) {
|
|
val viewModel: ChatListViewModel = hiltViewModel()
|
|
val storyViewModel: StoryViewModel = hiltViewModel()
|
|
ChatListScreen(
|
|
viewModel = viewModel,
|
|
storyViewModel = storyViewModel,
|
|
onChatClick = { chatId ->
|
|
navController.navigate(Screen.ChatDetail.createRoute(chatId, "Chat"))
|
|
},
|
|
onStoryClick = { /* Story click logic */ }
|
|
)
|
|
}
|
|
composable(
|
|
route = Screen.ChatDetail.route,
|
|
arguments = listOf(
|
|
navArgument("chatId") { type = NavType.StringType },
|
|
navArgument("chatName") { type = NavType.StringType }
|
|
)
|
|
) { backStackEntry ->
|
|
val chatId = backStackEntry.arguments?.getString("chatId") ?: ""
|
|
val chatName = backStackEntry.arguments?.getString("chatName") ?: "Chat"
|
|
val viewModel: ChatDetailViewModel = hiltViewModel()
|
|
|
|
ChatDetailScreen(
|
|
chatId = chatId,
|
|
chatName = chatName,
|
|
viewModel = viewModel,
|
|
onBack = { navController.popBackStack() }
|
|
)
|
|
}
|
|
composable(Screen.Contacts.route) {
|
|
val viewModel: ContactListViewModel = hiltViewModel()
|
|
val state by viewModel.state.collectAsState()
|
|
ContactListScreen(
|
|
contacts = state.contacts,
|
|
isLoading = state.isLoading,
|
|
onContactClick = { id -> navController.navigate(Screen.Profile.createRoute(id)) },
|
|
onSearchChange = { viewModel.onSearchChange(it) }
|
|
)
|
|
}
|
|
composable(
|
|
route = Screen.Profile.route,
|
|
arguments = listOf(
|
|
navArgument("profileId") {
|
|
type = NavType.StringType
|
|
nullable = true
|
|
}
|
|
)
|
|
) { backStackEntry ->
|
|
val profileId = backStackEntry.arguments?.getString("profileId")
|
|
val viewModel: ProfileViewModel = hiltViewModel()
|
|
|
|
ProfileScreen(
|
|
profileId = profileId,
|
|
viewModel = viewModel,
|
|
onEditProfile = { navController.navigate(Screen.EditProfile.route) },
|
|
onBack = { navController.popBackStack() },
|
|
onSendMessage = { id -> navController.navigate(Screen.ChatDetail.createRoute(id, "Chat")) }
|
|
)
|
|
}
|
|
composable(Screen.EditProfile.route) {
|
|
val viewModel: ProfileViewModel = hiltViewModel()
|
|
val state by viewModel.state.collectAsState()
|
|
|
|
EditProfileScreen(
|
|
currentDisplayName = state.profile?.displayName,
|
|
currentUsername = state.profile?.username ?: "",
|
|
currentBio = state.profile?.bio,
|
|
currentAvatarUrl = state.profile?.avatarUrl,
|
|
onSave = { name, bio, uri ->
|
|
viewModel.updateProfile(name, bio, uri)
|
|
navController.popBackStack()
|
|
},
|
|
onBack = { navController.popBackStack() }
|
|
)
|
|
}
|
|
composable(Screen.Settings.route) {
|
|
val viewModel: SettingsViewModel = hiltViewModel()
|
|
SettingsScreen(
|
|
viewModel = viewModel,
|
|
onBack = { navController.popBackStack() },
|
|
onLogout = {
|
|
navController.navigate(Screen.Login.route) {
|
|
popUpTo(0) { inclusive = true }
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|