Skip to content

Commit

Permalink
refactor: replace user with node in Message model
Browse files Browse the repository at this point in the history
  • Loading branch information
andrekir committed Dec 5, 2024
1 parent 746f155 commit 4a1319a
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 29 deletions.
2 changes: 1 addition & 1 deletion app/src/main/java/com/geeksville/mesh/DataPacket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ data class DataPacket(
const val PKC_CHANNEL_INDEX = 8

fun nodeNumToDefaultId(n: Int): String = "!%08x".format(n)
fun idToDefaultNodeNum(id: String?): Int? = id?.toLong(16)?.toInt()
fun idToDefaultNodeNum(id: String?): Int? = runCatching { id?.toLong(16)?.toInt() }.getOrNull()

override fun createFromParcel(parcel: Parcel): DataPacket {
return DataPacket(parcel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ class NodeRepository @Inject constructor(
.conflate()
.stateIn(processLifecycle.coroutineScope, SharingStarted.Eagerly, emptyMap())

fun getNode(userId: String): NodeEntity = nodeDBbyNum.value.values.find { it.user.id == userId }
?: NodeEntity(
num = DataPacket.idToDefaultNodeNum(userId) ?: 0,
user = getUser(userId),
)

fun getUser(nodeNum: Int): MeshProtos.User = getUser(DataPacket.nodeNumToDefaultId(nodeNum))

fun getUser(userId: String): MeshProtos.User =
Expand Down
14 changes: 7 additions & 7 deletions app/src/main/java/com/geeksville/mesh/database/entity/Packet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ data class PacketEntity(
@Relation(entity = ReactionEntity::class, parentColumn = "packet_id", entityColumn = "reply_id")
val reactions: List<ReactionEntity> = emptyList(),
) {
suspend fun toMessage(getUser: suspend (userId: String?) -> User) = with(packet) {
suspend fun toMessage(getNode: suspend (userId: String?) -> NodeEntity) = with(packet) {
Message(
uuid = uuid,
receivedTime = received_time,
user = getUser(data.from),
node = getNode(data.from),
text = data.text.orEmpty(),
time = getShortDateTime(data.time),
read = read,
status = data.status,
routingError = routingError,
packetId = packetId,
emojis = reactions.toReaction(getUser),
emojis = reactions.toReaction(getNode),
)
}
}
Expand Down Expand Up @@ -101,14 +101,14 @@ data class ReactionEntity(
)

private suspend fun ReactionEntity.toReaction(
getUser: suspend (userId: String?) -> User
getNode: suspend (userId: String?) -> NodeEntity
) = Reaction(
replyId = replyId,
user = getUser(userId),
user = getNode(userId).user,
emoji = emoji,
timestamp = timestamp,
)

private suspend fun List<ReactionEntity>.toReaction(
getUser: suspend (userId: String?) -> User
) = this.map { it.toReaction(getUser) }
getNode: suspend (userId: String?) -> NodeEntity
) = this.map { it.toReaction(getNode) }
4 changes: 2 additions & 2 deletions app/src/main/java/com/geeksville/mesh/model/Message.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
package com.geeksville.mesh.model

import com.geeksville.mesh.MeshProtos.Routing
import com.geeksville.mesh.MeshProtos.User
import com.geeksville.mesh.MessageStatus
import com.geeksville.mesh.R
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.database.entity.Reaction

val Routing.Error.stringRes: Int
Expand All @@ -47,7 +47,7 @@ val Routing.Error.stringRes: Int
data class Message(
val uuid: Long,
val receivedTime: Long,
val user: User,
val node: NodeEntity,
val text: String,
val time: String,
val read: Boolean,
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/com/geeksville/mesh/model/UIState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class UIViewModel @Inject constructor(
get() = preferences.getInt(MAP_STYLE_ID, 0)
set(value) = preferences.edit { putInt(MAP_STYLE_ID, value) }

fun getNode(userId: String?) = nodeDB.getNode(userId ?: DataPacket.ID_BROADCAST)
fun getUser(userId: String?) = nodeDB.getUser(userId ?: DataPacket.ID_BROADCAST)

private val _snackbarText = MutableLiveData<Any?>(null)
Expand Down Expand Up @@ -330,7 +331,7 @@ class UIViewModel @Inject constructor(

@OptIn(ExperimentalCoroutinesApi::class)
fun getMessagesFrom(contactKey: String) = packetRepository.getMessagesFrom(contactKey)
.mapLatest { list -> list.map { it.toMessage(::getUser) } }
.mapLatest { list -> list.map { it.toMessage(::getNode) } }

@OptIn(ExperimentalCoroutinesApi::class)
val waypoints = packetRepository.getWaypoints().mapLatest { list ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.Chip
import androidx.compose.material.ChipDefaults
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
Expand All @@ -55,16 +56,19 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.MessageStatus
import com.geeksville.mesh.R
import com.geeksville.mesh.database.entity.NodeEntity
import com.geeksville.mesh.ui.components.AutoLinkText
import com.geeksville.mesh.ui.preview.NodeEntityPreviewParameterProvider
import com.geeksville.mesh.ui.theme.AppTheme

@Suppress("LongMethod")
@OptIn(ExperimentalMaterialApi::class, ExperimentalFoundationApi::class)
@Composable
internal fun MessageItem(
shortName: String?,
node: NodeEntity,
messageText: String?,
messageTime: String,
messageStatus: MessageStatus?,
Expand All @@ -81,7 +85,7 @@ internal fun MessageItem(
.background(color = if (selected) Color.Gray else MaterialTheme.colors.background),
verticalAlignment = Alignment.CenterVertically,
) {
val fromLocal = shortName == null
val fromLocal = node.user.id == DataPacket.ID_LOCAL
val messageColor = if (fromLocal) R.color.colorMyMsg else R.color.colorMsg
val (topStart, topEnd) = if (fromLocal) 12.dp to 4.dp else 4.dp to 12.dp
val messageModifier = if (fromLocal) {
Expand Down Expand Up @@ -110,15 +114,19 @@ internal fun MessageItem(
.padding(horizontal = 8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
if (shortName != null) {
if (!fromLocal) {
Chip(
onClick = onChipClick,
modifier = Modifier
.padding(end = 8.dp)
.width(72.dp),
colors = ChipDefaults.chipColors(
backgroundColor = Color(node.colors.second),
contentColor = Color(node.colors.first),
),
) {
Text(
text = shortName,
text = node.user.shortName,
modifier = Modifier.fillMaxWidth(),
fontSize = MaterialTheme.typography.button.fontSize,
fontWeight = FontWeight.Normal,
Expand All @@ -129,11 +137,14 @@ internal fun MessageItem(
Column(
modifier = Modifier.padding(top = 8.dp),
) {
// Text(
// text = longName ?: stringResource(id = R.string.unknown_username),
// color = MaterialTheme.colors.onSurface,
// fontSize = MaterialTheme.typography.button.fontSize,
// )
// if (!fromLocal) {
// Text(
// text = with(node.user) { "$longName ($id)" },
// modifier = Modifier.padding(bottom = 4.dp),
// color = MaterialTheme.colors.onSurface,
// fontSize = MaterialTheme.typography.caption.fontSize,
// )
// }
AutoLinkText(
text = messageText.orEmpty(),
style = LocalTextStyle.current.copy(
Expand Down Expand Up @@ -181,8 +192,7 @@ internal fun MessageItem(
private fun MessageItemPreview() {
AppTheme {
MessageItem(
shortName = stringResource(R.string.some_username),
// longName = stringResource(R.string.unknown_username),
node = NodeEntityPreviewParameterProvider().values.first(),
messageText = stringResource(R.string.sample_message),
messageTime = "10:00",
messageStatus = MessageStatus.DELIVERED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import com.geeksville.mesh.DataPacket
import com.geeksville.mesh.database.entity.Reaction
import com.geeksville.mesh.model.Message
Expand All @@ -50,6 +52,7 @@ internal fun MessageList(
onSendReaction: (String, Int) -> Unit,
onClick: (Message) -> Unit = {}
) {
val haptics = LocalHapticFeedback.current
val inSelectionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } }
val listState = rememberLazyListState(
initialFirstVisibleItemIndex = messages.indexOfLast { !it.read }.coerceAtLeast(0)
Expand All @@ -70,10 +73,10 @@ internal fun MessageList(
ReactionDialog(reactions) { showReactionDialog = null }
}

fun toggle(uuid: Long) = if (selectedIds.value.contains(uuid)) {
selectedIds.value -= uuid
fun MutableState<Set<Long>>.toggle(uuid: Long) = if (value.contains(uuid)) {
value -= uuid
} else {
selectedIds.value += uuid
value += uuid
}

LazyColumn(
Expand All @@ -83,18 +86,21 @@ internal fun MessageList(
contentPadding = contentPadding
) {
items(messages, key = { it.uuid }) { msg ->
val fromLocal = msg.user.id == DataPacket.ID_LOCAL
val fromLocal = msg.node.user.id == DataPacket.ID_LOCAL
val selected by remember { derivedStateOf { selectedIds.value.contains(msg.uuid) } }

ReactionRow(fromLocal, msg.emojis) { showReactionDialog = msg.emojis }
MessageItem(
shortName = msg.user.shortName.takeIf { !fromLocal },
node = msg.node,
messageText = msg.text,
messageTime = msg.time,
messageStatus = msg.status,
selected = selected,
onClick = { if (inSelectionMode) toggle(msg.uuid) },
onLongClick = { toggle(msg.uuid) },
onClick = { if (inSelectionMode) selectedIds.toggle(msg.uuid) },
onLongClick = {
selectedIds.toggle(msg.uuid)
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
},
onChipClick = { onClick(msg) },
onStatusClick = { showStatusDialog = msg },
onSendReaction = { onSendReaction(it, msg.packetId) },
Expand Down

0 comments on commit 4a1319a

Please sign in to comment.