show message time
This commit is contained in:
@@ -48,6 +48,7 @@ import org.jetbrains.compose.resources.painterResource
|
|||||||
import rust.nostr.sdk.Event
|
import rust.nostr.sdk.Event
|
||||||
import su.reya.coop.LocalNostrViewModel
|
import su.reya.coop.LocalNostrViewModel
|
||||||
import su.reya.coop.LocalSnackbarHostState
|
import su.reya.coop.LocalSnackbarHostState
|
||||||
|
import su.reya.coop.humanReadable
|
||||||
import su.reya.coop.shared.displayNameFlow
|
import su.reya.coop.shared.displayNameFlow
|
||||||
import su.reya.coop.shared.pictureFlow
|
import su.reya.coop.shared.pictureFlow
|
||||||
|
|
||||||
@@ -177,9 +178,9 @@ fun ChatMessage(
|
|||||||
RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp, bottomStart = 4.dp, bottomEnd = 20.dp)
|
RoundedCornerShape(topStart = 20.dp, topEnd = 20.dp, bottomStart = 4.dp, bottomEnd = 20.dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
val alignment = if (isMine) Alignment.CenterEnd else Alignment.CenterStart
|
|
||||||
val containerColor =
|
val containerColor =
|
||||||
if (isMine) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.secondaryContainer
|
if (isMine) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.secondaryContainer
|
||||||
|
|
||||||
val contentColor =
|
val contentColor =
|
||||||
if (isMine) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSecondaryContainer
|
if (isMine) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSecondaryContainer
|
||||||
|
|
||||||
@@ -187,19 +188,26 @@ fun ChatMessage(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 4.dp),
|
.padding(vertical = 4.dp),
|
||||||
contentAlignment = alignment
|
contentAlignment = if (isMine) Alignment.CenterEnd else Alignment.CenterStart
|
||||||
) {
|
) {
|
||||||
Surface(
|
Column {
|
||||||
color = containerColor,
|
|
||||||
contentColor = contentColor,
|
|
||||||
shape = bubbleShape,
|
|
||||||
modifier = Modifier.widthIn(max = 280.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
Text(
|
||||||
text = event.content(),
|
text = event.createdAt().humanReadable(),
|
||||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
style = MaterialTheme.typography.labelSmall,
|
||||||
style = MaterialTheme.typography.bodyMedium
|
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.size(4.dp))
|
||||||
|
Surface(
|
||||||
|
color = containerColor,
|
||||||
|
contentColor = contentColor,
|
||||||
|
shape = bubbleShape,
|
||||||
|
modifier = Modifier.widthIn(max = 280.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = event.content(),
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||||
|
style = MaterialTheme.typography.bodyMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -56,6 +57,7 @@ import org.jetbrains.compose.resources.painterResource
|
|||||||
import su.reya.coop.LocalNostrViewModel
|
import su.reya.coop.LocalNostrViewModel
|
||||||
import su.reya.coop.LocalSnackbarHostState
|
import su.reya.coop.LocalSnackbarHostState
|
||||||
import su.reya.coop.Room
|
import su.reya.coop.Room
|
||||||
|
import su.reya.coop.ago
|
||||||
import su.reya.coop.shared.displayNameFlow
|
import su.reya.coop.shared.displayNameFlow
|
||||||
import su.reya.coop.shared.pictureFlow
|
import su.reya.coop.shared.pictureFlow
|
||||||
import su.reya.coop.short
|
import su.reya.coop.short
|
||||||
@@ -265,10 +267,21 @@ fun ChatRoom(room: Room, onClick: () -> Unit) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Row(
|
||||||
text = displayName ?: "Unknown",
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.titleMediumEmphasized
|
verticalAlignment = Alignment.CenterVertically
|
||||||
)
|
) {
|
||||||
|
Text(
|
||||||
|
text = displayName,
|
||||||
|
style = MaterialTheme.typography.titleMediumEmphasized,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = room.createdAt.ago(),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
supportingContent = {
|
supportingContent = {
|
||||||
if (!room.lastMessage.isNullOrBlank()) {
|
if (!room.lastMessage.isNullOrBlank()) {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package su.reya.coop
|
package su.reya.coop
|
||||||
|
|
||||||
|
import kotlinx.datetime.DateTimeUnit
|
||||||
import kotlinx.datetime.TimeZone
|
import kotlinx.datetime.TimeZone
|
||||||
|
import kotlinx.datetime.minus
|
||||||
|
import kotlinx.datetime.number
|
||||||
import kotlinx.datetime.toLocalDateTime
|
import kotlinx.datetime.toLocalDateTime
|
||||||
import rust.nostr.sdk.Event
|
import rust.nostr.sdk.Event
|
||||||
import rust.nostr.sdk.PublicKey
|
import rust.nostr.sdk.PublicKey
|
||||||
@@ -117,3 +120,35 @@ fun Timestamp.ago(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Timestamp.humanReadable(): String {
|
||||||
|
val timeZone = TimeZone.currentSystemDefault()
|
||||||
|
val inputInstant = Instant.fromEpochSeconds(this.asSecs().toLong())
|
||||||
|
val inputDateTime = inputInstant.toLocalDateTime(timeZone)
|
||||||
|
val inputDate = inputDateTime.date
|
||||||
|
|
||||||
|
val now = Clock.System.now()
|
||||||
|
val today = now.toLocalDateTime(timeZone).date
|
||||||
|
val yesterday = today.minus(1, DateTimeUnit.DAY)
|
||||||
|
|
||||||
|
val hour = inputDateTime.hour
|
||||||
|
val minute = inputDateTime.minute.toString().padStart(2, '0')
|
||||||
|
val amPm = if (hour < 12) "AM" else "PM"
|
||||||
|
val hour12 = when {
|
||||||
|
hour == 0 -> 12
|
||||||
|
hour > 12 -> hour - 12
|
||||||
|
else -> hour
|
||||||
|
}
|
||||||
|
val timeFormat = "$hour12:$minute $amPm"
|
||||||
|
|
||||||
|
return when (inputDate) {
|
||||||
|
today -> "Today at $timeFormat"
|
||||||
|
yesterday -> "Yesterday at $timeFormat"
|
||||||
|
else -> {
|
||||||
|
val day = inputDateTime.day.toString().padStart(2, '0')
|
||||||
|
val month = inputDateTime.month.number.toString().padStart(2, '0')
|
||||||
|
val year = inputDateTime.year.toString().takeLast(2)
|
||||||
|
"$day/$month/$year, $timeFormat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user