Add public chat screen

Signed-off-by: denis0001-dev <denis0001.dev@ya.ru>
This commit is contained in:
2025-09-09 17:25:57 +03:00
Unverified
parent 7e9448c883
commit 63b5bdba7b
3 changed files with 206 additions and 48 deletions
+14
View File
@@ -4,13 +4,19 @@ import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.
import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.Start import androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion.Start
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController import androidx.navigation.compose.rememberNavController
import ru.fromchat.ui.auth.LoginScreen import ru.fromchat.ui.auth.LoginScreen
import ru.fromchat.ui.auth.RegisterScreen import ru.fromchat.ui.auth.RegisterScreen
import ru.fromchat.ui.chat.ChatScreen import ru.fromchat.ui.chat.ChatScreen
import ru.fromchat.ui.chat.PublicChatScreen
val LocalNavController = compositionLocalOf<NavController> { error("") }
@Composable @Composable
fun App() { fun App() {
@@ -18,6 +24,9 @@ fun App() {
val navController = rememberNavController() val navController = rememberNavController()
val animationSpec = tween<IntOffset>(400) val animationSpec = tween<IntOffset>(400)
CompositionLocalProvider(
LocalNavController provides navController
) {
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = "login", startDestination = "login",
@@ -60,6 +69,11 @@ fun App() {
} }
composable("chat") { ChatScreen() } composable("chat") { ChatScreen() }
composable("chats/publicChat") {
PublicChatScreen()
}
}
} }
} }
} }
@@ -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.Contacts
import androidx.compose.material.icons.filled.Mail import androidx.compose.material.icons.filled.Mail
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem
import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@@ -20,13 +21,14 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ru.fromchat.ui.LocalNavController
enum class ChatTab { CHATS, CONTACTS, DMS } enum class ChatTab { CHATS, CONTACTS, DMS }
@Composable @Composable
fun ChatScreen() { fun ChatScreen() {
var selectedTab by remember { mutableStateOf(ChatTab.CHATS) } var selectedTab by remember { mutableStateOf(ChatTab.CHATS) }
var activeChat by remember { mutableStateOf<String?>(null) } val navController = LocalNavController.current
Scaffold( Scaffold(
bottomBar = { bottomBar = {
@@ -51,16 +53,17 @@ fun ChatScreen() {
) )
} }
} }
) { paddingValues -> ) { innerPadding ->
Column(modifier = Modifier.fillMaxSize().padding(paddingValues).padding(12.dp)) { Column(modifier = Modifier.fillMaxSize().padding(innerPadding).padding(12.dp)) {
when (selectedTab) { when (selectedTab) {
ChatTab.CHATS -> { ChatTab.CHATS -> {
if (activeChat == null) { ListItem(
Text("Общий чат", modifier = Modifier.clickable { activeChat = "Общий чат" }.padding(8.dp)) headlineContent = { Text("Public chat") },
Text("Общий чат 2", modifier = Modifier.clickable { activeChat = "Общий чат 2" }.padding(8.dp)) supportingContent = { Text("You: last message") },
} else { modifier = Modifier.clickable {
BaseChat(chatTitle = activeChat!!) navController.navigate("chats/publicChat")
} }
)
} }
ChatTab.CONTACTS -> { ChatTab.CONTACTS -> {
Text("Скоро будет...") Text("Скоро будет...")
@@ -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"
)
}
}
}
}