android: voice messages + attachments architecture plan, build fixes
This commit is contained in:
1 parent
f8d7c21a79
commit
e751e6ee69
17 files changed
+299
-329
No files matched your search
+3
-1
@@ -9,6 +9,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -19,6 +20,7 @@ fun MessageBubble(message: Message) {
|
||||
val bgColor = if (message.isOutgoing) Color(0xFF4A90D9) else Color(0xFFE8E8E8)
|
||||
val textColor = if (message.isOutgoing) Color.White else Color.Black
|
||||
val alignment = if (message.isOutgoing) Arrangement.End else Arrangement.Start
|
||||
val minBubbleWidth = (LocalConfiguration.current.screenWidthDp / 3).dp
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 2.dp),
|
||||
@@ -26,7 +28,7 @@ fun MessageBubble(message: Message) {
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.widthIn(max = 300.dp)
|
||||
.widthIn(min = minBubbleWidth, max = 300.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(bgColor)
|
||||
.padding(12.dp)
|
||||
|
||||
+42
-17
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.QrCode
|
||||
@@ -15,8 +16,10 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.utun.chat.data.Channel
|
||||
@@ -72,26 +75,48 @@ fun ChannelListScreen(
|
||||
} else {
|
||||
LazyColumn {
|
||||
items(channels) { ch ->
|
||||
val barColor = if (ch.peersOnline > 0) Color(0xFF4CAF50) else Color(0xFF9E9E9E)
|
||||
val badgeText = when {
|
||||
ch.peersOnline > 99 -> "99+"
|
||||
ch.peersOnline > 0 -> ch.peersOnline.toString()
|
||||
else -> ""
|
||||
}
|
||||
|
||||
Surface(modifier = Modifier.clickable { onSelectChannel(ch) }) {
|
||||
Row(Modifier.fillMaxWidth().padding(16.dp)) {
|
||||
Box(Modifier.size(48.dp), contentAlignment = androidx.compose.ui.Alignment.Center) {
|
||||
Surface(shape = MaterialTheme.shapes.small) {
|
||||
Text("#", fontSize = 24.sp, modifier = Modifier.padding(8.dp))
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column {
|
||||
Row {
|
||||
Text(ch.name, fontWeight = FontWeight.Bold, fontSize = 16.sp)
|
||||
if (ch.peersOnline > 0) {
|
||||
Text(" (${ch.peersOnline})",
|
||||
fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.padding(start = 4.dp))
|
||||
Row(Modifier.fillMaxWidth().height(IntrinsicSize.Min)) {
|
||||
Box(Modifier.width(4.dp).fillMaxHeight().background(barColor))
|
||||
Row(Modifier.fillMaxWidth().padding(12.dp)) {
|
||||
Box(Modifier.size(44.dp), contentAlignment = Alignment.Center) {
|
||||
Surface(shape = MaterialTheme.shapes.small) {
|
||||
Text("#", fontSize = 22.sp, modifier = Modifier.padding(8.dp))
|
||||
}
|
||||
if (badgeText.isNotEmpty()) {
|
||||
val badgeSize = 18.dp
|
||||
Box(
|
||||
Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.offset(x = (-4).dp, y = (-6).dp)
|
||||
.size(badgeSize)
|
||||
.clip(CircleShape)
|
||||
.background(Color(0xFF4CAF50)),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
badgeText, fontSize = 9.sp, color = Color.White,
|
||||
fontWeight = FontWeight.Bold, textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ch.lastMsg.isNotEmpty())
|
||||
Text(ch.lastMsg, fontSize = 13.sp, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
Column {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(ch.name, fontWeight = FontWeight.Bold, fontSize = 16.sp)
|
||||
}
|
||||
if (ch.lastMsg.isNotEmpty())
|
||||
Text(ch.lastMsg, fontSize = 13.sp,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -31,30 +31,17 @@ fun ChatScreen(
|
||||
if (messages.isNotEmpty()) listState.animateScrollToItem(messages.size - 1)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(channel.name) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) { Icon(Icons.Default.ArrowBack, "Back") }
|
||||
}
|
||||
)
|
||||
},
|
||||
bottomBar = {
|
||||
InputBar(
|
||||
text = text,
|
||||
onTextChange = { text = it },
|
||||
onSend = {
|
||||
onSendMessage(text)
|
||||
text = ""
|
||||
},
|
||||
enabled = true,
|
||||
modifier = Modifier.navigationBarsPadding()
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().imePadding()
|
||||
) {
|
||||
TopAppBar(
|
||||
title = { Text(channel.name) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back") }
|
||||
}
|
||||
)
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize().padding(padding).imePadding(),
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
state = listState
|
||||
) {
|
||||
items(messages.size) { idx ->
|
||||
@@ -62,5 +49,15 @@ fun ChatScreen(
|
||||
}
|
||||
item { Spacer(Modifier.height(8.dp)) }
|
||||
}
|
||||
InputBar(
|
||||
text = text,
|
||||
onTextChange = { text = it },
|
||||
onSend = {
|
||||
onSendMessage(text)
|
||||
text = ""
|
||||
},
|
||||
enabled = true,
|
||||
modifier = Modifier.navigationBarsPadding()
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user