Private
Public Access
1
0

MessageListScreen: Add time annotations/max width

This commit is contained in:
2024-03-19 00:15:36 -07:00
parent 1c78ecc93d
commit 3d3abc1813
2 changed files with 70 additions and 26 deletions

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinScriptingSettings">
<scriptDefinition className="org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate" definitionName="KotlinSettingsScript">
<order>2147483647</order>
<autoReloadConfigurations>true</autoReloadConfigurations>
</scriptDefinition>
</component>
</project>

View File

@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@@ -39,9 +40,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
@@ -49,6 +52,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import net.buzzert.kordophone.backend.model.GUID import net.buzzert.kordophone.backend.model.GUID
import net.buzzert.kordophone.backend.model.Message import net.buzzert.kordophone.backend.model.Message
import net.buzzert.kordophonedroid.ui.theme.KordophoneTopAppBar import net.buzzert.kordophonedroid.ui.theme.KordophoneTopAppBar
import java.text.SimpleDateFormat
import java.time.Duration
import java.time.Instant
import java.time.LocalDate
import java.time.Period
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Date
private val IncomingChatBubbleShape = RoundedCornerShape(4.dp, 20.dp, 20.dp, 20.dp) private val IncomingChatBubbleShape = RoundedCornerShape(4.dp, 20.dp, 20.dp, 20.dp)
private val OutgoingChatBubbleShape = RoundedCornerShape(20.dp, 4.dp, 20.dp, 20.dp) private val OutgoingChatBubbleShape = RoundedCornerShape(20.dp, 4.dp, 20.dp, 20.dp)
@@ -56,6 +67,7 @@ private val OutgoingChatBubbleShape = RoundedCornerShape(20.dp, 4.dp, 20.dp, 20.
data class MessageListViewItem( data class MessageListViewItem(
val text: String, val text: String,
val fromMe: Boolean, val fromMe: Boolean,
val date: Date,
val delivered: Boolean = true, val delivered: Boolean = true,
) )
@@ -79,6 +91,7 @@ fun MessageListScreen(
MessageListViewItem( MessageListViewItem(
text = it.text, text = it.text,
fromMe = it.sender == null, fromMe = it.sender == null,
date = it.date,
delivered = !viewModel.isPendingMessage(it) delivered = !viewModel.isPendingMessage(it)
) )
} }
@@ -140,14 +153,48 @@ fun Messages(
.fillMaxSize() .fillMaxSize()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
) { ) {
var lastDate: Date? = null
val dateFormatter = SimpleDateFormat.getDateTimeInstance()
for (index in messages.indices) { for (index in messages.indices) {
val content = messages[index] val content = messages[index]
if (lastDate == null) {
lastDate = content.date
}
val duration = Duration.between(content.date.toInstant(), lastDate.toInstant())
lastDate = content.date
Log.d("MessageListScreen", "period: $duration")
// Remember: This is upside down.
item { item {
MessageBubble( MessageBubble(
text = content.text, text = content.text,
mine = content.fromMe, mine = content.fromMe,
modifier = Modifier.alpha(if (!content.delivered) 0.5F else 1.0f) modifier = Modifier
.alpha(if (!content.delivered) 0.5F else 1.0f)
) )
// Greater than 30 minutes: show date:
if (duration.toMinutes() > 30) {
val formattedDate = dateFormatter.format(content.date)
Text(
text = formattedDate,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.caption.copy(
color = MaterialTheme.colors.onSurface.copy(alpha = 0.4f)
),
modifier = Modifier
.fillMaxWidth()
.padding(18.dp),
)
}
// Greater than five minutes: add a bit of space.
else if (duration.toMinutes() > 5) {
Spacer(modifier = Modifier.height(12.dp))
}
} }
} }
} }
@@ -163,21 +210,27 @@ fun MessageBubble(
val backgroundBubbleColor = if (mine) MaterialTheme.colors.primary else MaterialTheme.colors.secondary val backgroundBubbleColor = if (mine) MaterialTheme.colors.primary else MaterialTheme.colors.secondary
Column() { Column() {
Row( Row(modifier = modifier.fillMaxWidth()) {
modifier = modifier.fillMaxWidth(), if (mine) { Spacer(modifier = Modifier.weight(1f)) }
horizontalArrangement = if (mine) Arrangement.End else Arrangement.Start,
) { Row(
Surface( modifier = Modifier.fillMaxWidth(0.8f),
color = backgroundBubbleColor, horizontalArrangement = if (mine) Arrangement.End else Arrangement.Start,
shape = if (mine) OutgoingChatBubbleShape else IncomingChatBubbleShape,
) { ) {
Text( Surface(
text = text, color = backgroundBubbleColor,
style = MaterialTheme.typography.body1, shape = if (mine) OutgoingChatBubbleShape else IncomingChatBubbleShape,
modifier = Modifier ) {
.padding(16.dp) Text(
) text = text,
style = MaterialTheme.typography.body1,
modifier = Modifier
.padding(16.dp)
)
}
} }
if (!mine) { Spacer(modifier = Modifier.weight(1f)) }
} }
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
@@ -190,9 +243,9 @@ fun MessageBubble(
@Composable @Composable
private fun MessageListScreenPreview() { private fun MessageListScreenPreview() {
val messages = listOf<MessageListViewItem>( val messages = listOf<MessageListViewItem>(
MessageListViewItem(text = "Hello", fromMe = false), MessageListViewItem(text = "Hello", fromMe = false, date = Date()),
MessageListViewItem(text = "Hey there", fromMe = true), MessageListViewItem(text = "Hey there, this is a longer text message that might wrap to another line", fromMe = true, date = Date()),
MessageListViewItem(text = "How's it going", fromMe = true, delivered = false) MessageListViewItem(text = "How's it going", fromMe = true, delivered = false, date = Date())
).reversed() ).reversed()
Scaffold() { Scaffold() {