diff --git a/app/src/main/java/ru/fromchat/ui/App.kt b/app/src/main/java/ru/fromchat/ui/App.kt index cc1d1fb..85703b7 100644 --- a/app/src/main/java/ru/fromchat/ui/App.kt +++ b/app/src/main/java/ru/fromchat/ui/App.kt @@ -4,13 +4,19 @@ import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection. import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.Start import androidx.compose.animation.core.tween import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.unit.IntOffset +import androidx.navigation.NavController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import ru.fromchat.ui.auth.LoginScreen import ru.fromchat.ui.auth.RegisterScreen import ru.fromchat.ui.chat.ChatScreen +import ru.fromchat.ui.chat.PublicChatScreen + +val LocalNavController = compositionLocalOf { error("") } @Composable fun App() { @@ -18,48 +24,56 @@ fun App() { val navController = rememberNavController() val animationSpec = tween(400) - NavHost( - navController = navController, - startDestination = "login", - enterTransition = { - slideIntoContainer( - Start, - animationSpec = animationSpec - ) - }, - exitTransition = { - slideOutOfContainer( - Start, - animationSpec = animationSpec - ) - }, - popEnterTransition = { - slideIntoContainer( - End, - animationSpec = animationSpec - ) - }, - popExitTransition = { - slideOutOfContainer( - End, - animationSpec = animationSpec - ) - } + CompositionLocalProvider( + LocalNavController provides navController ) { - composable("login") { - LoginScreen( - onLoginSuccess = { navController.navigate("chat") }, - onNavigateToRegister = { navController.navigate("register") } - ) - } + NavHost( + navController = navController, + startDestination = "login", + enterTransition = { + slideIntoContainer( + Start, + animationSpec = animationSpec + ) + }, + exitTransition = { + slideOutOfContainer( + Start, + animationSpec = animationSpec + ) + }, + popEnterTransition = { + slideIntoContainer( + End, + animationSpec = animationSpec + ) + }, + popExitTransition = { + slideOutOfContainer( + End, + animationSpec = animationSpec + ) + } + ) { + composable("login") { + LoginScreen( + onLoginSuccess = { navController.navigate("chat") }, + onNavigateToRegister = { navController.navigate("register") } + ) + } - composable("register") { - RegisterScreen( - onRegistered = { navController.navigate("login") } - ) - } + composable("register") { + RegisterScreen( + onRegistered = { navController.navigate("login") } + ) + } - composable("chat") { ChatScreen() } + composable("chat") { ChatScreen() } + + composable("chats/publicChat") { + PublicChatScreen() + } + } } } } \ No newline at end of file diff --git a/app/src/main/java/ru/fromchat/ui/chat/ChatScreen.kt b/app/src/main/java/ru/fromchat/ui/chat/ChatScreen.kt index 1707d11..e18fd8d 100644 --- a/app/src/main/java/ru/fromchat/ui/chat/ChatScreen.kt +++ b/app/src/main/java/ru/fromchat/ui/chat/ChatScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.material.icons.automirrored.filled.Chat import androidx.compose.material.icons.filled.Contacts import androidx.compose.material.icons.filled.Mail import androidx.compose.material3.Icon +import androidx.compose.material3.ListItem import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.Scaffold @@ -20,13 +21,14 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import ru.fromchat.ui.LocalNavController enum class ChatTab { CHATS, CONTACTS, DMS } @Composable fun ChatScreen() { var selectedTab by remember { mutableStateOf(ChatTab.CHATS) } - var activeChat by remember { mutableStateOf(null) } + val navController = LocalNavController.current Scaffold( bottomBar = { @@ -51,16 +53,17 @@ fun ChatScreen() { ) } } - ) { paddingValues -> - Column(modifier = Modifier.fillMaxSize().padding(paddingValues).padding(12.dp)) { + ) { innerPadding -> + Column(modifier = Modifier.fillMaxSize().padding(innerPadding).padding(12.dp)) { when (selectedTab) { ChatTab.CHATS -> { - if (activeChat == null) { - Text("Общий чат", modifier = Modifier.clickable { activeChat = "Общий чат" }.padding(8.dp)) - Text("Общий чат 2", modifier = Modifier.clickable { activeChat = "Общий чат 2" }.padding(8.dp)) - } else { - BaseChat(chatTitle = activeChat!!) - } + ListItem( + headlineContent = { Text("Public chat") }, + supportingContent = { Text("You: last message") }, + modifier = Modifier.clickable { + navController.navigate("chats/publicChat") + } + ) } ChatTab.CONTACTS -> { Text("Скоро будет...") diff --git a/app/src/main/java/ru/fromchat/ui/chat/PublicChatScreen.kt b/app/src/main/java/ru/fromchat/ui/chat/PublicChatScreen.kt new file mode 100644 index 0000000..6e1b890 --- /dev/null +++ b/app/src/main/java/ru/fromchat/ui/chat/PublicChatScreen.kt @@ -0,0 +1,141 @@ +package ru.fromchat.ui.chat + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.DoneAll +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import ru.fromchat.ui.LocalNavController + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun PublicChatScreen() { + val navController = LocalNavController.current + + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = "Public Chat", + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + navigationIcon = { + IconButton( + onClick = { + navController.navigateUp() + } + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back" + ) + } + } + ) + } + ) { innerPadding -> + Column( + Modifier + .padding(innerPadding) + .verticalScroll(rememberScrollState()) + ) { + @Composable + fun Message( + text: String, + isAuthor: Boolean, + isRead: Boolean, + timestamp: String + ) { + Row( + modifier = Modifier + .padding(horizontal = 16.dp, vertical = 4.dp) + .fillMaxWidth(), + horizontalArrangement = if (isAuthor) Arrangement.End else Arrangement.Start + ) { + val background = + if (isAuthor) + MaterialTheme.colorScheme.primaryContainer + else MaterialTheme.colorScheme.surfaceContainer + + Column( + Modifier + .clip( + RoundedCornerShape( + if (isAuthor) 16.dp else 5.dp, + 16.dp, + if (isAuthor) 5.dp else 16.dp, + 16.dp + ) + ) + .background(background) + .padding(10.dp) + .width(IntrinsicSize.Max) + ) { + Text(text) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(0.dp, Alignment.End), + modifier = Modifier.fillMaxWidth() + ) { + Spacer(Modifier.weight(1f)) + Text( + text = timestamp, + fontSize = 14.sp + ) + if (isRead) { + Icon( + imageVector = Icons.Filled.DoneAll, + contentDescription = "Read", + modifier = Modifier.size(17.dp) + ) + } + } + } + } + } + + repeat(100) { + Message( + text = "test", + isAuthor = true, + isRead = true, + timestamp = "9:41" + ) + Message( + text = "test2", + isAuthor = false, + isRead = true, + timestamp = "9:41" + ) + } + } + } +} \ No newline at end of file