diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt index 9470803fb..97c5bbbcf 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt @@ -88,11 +88,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.DataPacket import com.geeksville.mesh.R import com.geeksville.mesh.android.Logging +import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.database.entity.QuickChatAction import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.model.getChannel -import com.geeksville.mesh.ui.message.components.MessageList import com.geeksville.mesh.ui.components.NodeKeyStatusIcon +import com.geeksville.mesh.ui.components.NodeMenuAction +import com.geeksville.mesh.ui.message.components.MessageList +import com.geeksville.mesh.ui.navigateToNavGraph import com.geeksville.mesh.ui.theme.AppTheme import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -111,6 +114,19 @@ internal fun FragmentManager.navigateToMessages(contactKey: String, message: Str class MessagesFragment : Fragment(), Logging { private val model: UIViewModel by activityViewModels() + private fun navigateToMessages(node: NodeEntity) = node.user.let { user -> + val hasPKC = model.ourNodeInfo.value?.hasPKC == true && node.hasPKC // TODO use meta.hasPKC + val channel = if (hasPKC) DataPacket.PKC_CHANNEL_INDEX else node.channel + val contactKey = "$channel${user.id}" + info("calling MessagesFragment filter: $contactKey") + parentFragmentManager.navigateToMessages(contactKey) + } + + private fun navigateToNodeDetails(nodeNum: Int) { + info("calling NodeDetails --> destNum: $nodeNum") + parentFragmentManager.navigateToNavGraph(nodeNum, "NodeDetails") + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -128,6 +144,8 @@ class MessagesFragment : Fragment(), Logging { contactKey = contactKey, message = message, viewModel = model, + navigateToMessages = ::navigateToMessages, + navigateToNodeDetails = ::navigateToNodeDetails, ) { parentFragmentManager.popBackStack() } } } @@ -148,6 +166,8 @@ internal fun MessageScreen( contactKey: String, message: String, viewModel: UIViewModel = hiltViewModel(), + navigateToMessages: (NodeEntity) -> Unit, + navigateToNodeDetails: (Int) -> Unit, onNavigateBack: () -> Unit ) { val coroutineScope = rememberCoroutineScope() @@ -255,8 +275,16 @@ internal fun MessageScreen( onUnreadChanged = { viewModel.clearUnreadCount(contactKey, it) }, contentPadding = innerPadding, onSendReaction = { emoji, id -> viewModel.sendReaction(emoji, id, contactKey) }, - ) { - // TODO onCLick() + ) { action -> + when (action) { + is NodeMenuAction.Remove -> viewModel.removeNode(action.node.num) + is NodeMenuAction.Ignore -> viewModel.ignoreNode(action.node) + is NodeMenuAction.DirectMessage -> navigateToMessages(action.node) + is NodeMenuAction.RequestUserInfo -> viewModel.requestUserInfo(action.node.num) + is NodeMenuAction.RequestPosition -> viewModel.requestPosition(action.node.num) + is NodeMenuAction.TraceRoute -> viewModel.requestTraceroute(action.node.num) + is NodeMenuAction.MoreDetails -> navigateToNodeDetails(action.node.num) + } } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageList.kt b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageList.kt index 3d8ae96a7..21ad8525a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageList.kt @@ -17,8 +17,10 @@ package com.geeksville.mesh.ui.message.components +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items @@ -32,17 +34,21 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment 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 +import com.geeksville.mesh.ui.components.NodeMenu +import com.geeksville.mesh.ui.components.NodeMenuAction import com.geeksville.mesh.ui.components.SimpleAlertDialog import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce +@Suppress("LongMethod") @Composable internal fun MessageList( messages: List, @@ -50,7 +56,7 @@ internal fun MessageList( onUnreadChanged: (Long) -> Unit, contentPadding: PaddingValues, onSendReaction: (String, Int) -> Unit, - onClick: (Message) -> Unit = {} + onNodeMenuAction: (NodeMenuAction) -> Unit = {} ) { val haptics = LocalHapticFeedback.current val inSelectionMode by remember { derivedStateOf { selectedIds.value.isNotEmpty() } } @@ -90,21 +96,35 @@ internal fun MessageList( val selected by remember { derivedStateOf { selectedIds.value.contains(msg.uuid) } } ReactionRow(fromLocal, msg.emojis) { showReactionDialog = msg.emojis } - MessageItem( - node = msg.node, - messageText = msg.text, - messageTime = msg.time, - messageStatus = msg.status, - selected = selected, - 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) }, - ) + Box(Modifier.wrapContentSize(Alignment.TopStart)) { + var expandedNodeMenu by remember { mutableStateOf(false) } + MessageItem( + node = msg.node, + messageText = msg.text, + messageTime = msg.time, + messageStatus = msg.status, + selected = selected, + onClick = { if (inSelectionMode) selectedIds.toggle(msg.uuid) }, + onLongClick = { + selectedIds.toggle(msg.uuid) + haptics.performHapticFeedback(HapticFeedbackType.LongPress) + }, + onChipClick = { + if (msg.node.num != 0) { + expandedNodeMenu = true + } + }, + onStatusClick = { showStatusDialog = msg }, + onSendReaction = { onSendReaction(it, msg.packetId) }, + ) + NodeMenu( + node = msg.node, + showFullMenu = true, + onDismissRequest = { expandedNodeMenu = false }, + expanded = expandedNodeMenu, + onAction = onNodeMenuAction + ) + } } } }