diff --git a/app/src/main/java/chat/revolt/composables/chat/Message.kt b/app/src/main/java/chat/revolt/composables/chat/Message.kt index 4e68651d..0e5bf881 100644 --- a/app/src/main/java/chat/revolt/composables/chat/Message.kt +++ b/app/src/main/java/chat/revolt/composables/chat/Message.kt @@ -196,6 +196,8 @@ fun Message( onAddReaction: () -> Unit = {}, fromWebhook: Boolean = false, webhookName: String? = null, + jumpToMessage: (String) -> Unit = {}, + highlightedMessageId: String? = null, modifier: Modifier = Modifier ) { val author = RevoltAPI.userCache[message.author] ?: return CircularProgressIndicator() @@ -281,16 +283,21 @@ fun Message( } else { Column( modifier = Modifier.then( - if ((message.mentions?.contains(RevoltAPI.selfId) == true) - || mentionsSelfRole - || message.flags has MessageFlag.MentionsOnline - || message.flags has MessageFlag.MentionsEveryone - ) { - Modifier.background( - MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) - ) - } else { - Modifier + when { + highlightedMessageId == message.id -> { + Modifier.background( + MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f) + ) + } + (message.mentions?.contains(RevoltAPI.selfId) == true) + || mentionsSelfRole + || message.flags has MessageFlag.MentionsOnline + || message.flags has MessageFlag.MentionsEveryone -> { + Modifier.background( + MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) + ) + } + else -> Modifier } ) ) { @@ -306,11 +313,8 @@ fun Message( replyMessage.author ) } == true), - ) { - // TODO Add jump to message - if (replyMessage == null) { - Toast.makeText(context, "lmao prankd", Toast.LENGTH_SHORT).show() - } + ) { messageId -> + jumpToMessage(messageId) } } } diff --git a/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt b/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt index 3ba2a7e4..234fb3a3 100644 --- a/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt +++ b/app/src/main/java/chat/revolt/composables/screens/chat/atoms/RegularMessage.kt @@ -70,6 +70,8 @@ fun RegularMessage( showReactBottomSheet: () -> Unit, putTextAtCursorPosition: (String) -> Unit, replyToMessage: suspend (String) -> Unit, + jumpToMessage: (String) -> Unit = {}, + highlightedMessageId: String? = null, scope: CoroutineScope = rememberCoroutineScope() ) { val haptic = LocalHapticFeedback.current @@ -182,6 +184,8 @@ fun RegularMessage( }, fromWebhook = message.webhook != null, webhookName = message.webhook?.name, + jumpToMessage = jumpToMessage, + highlightedMessageId = highlightedMessageId, modifier = Modifier .offset( x = with(LocalDensity.current) { animOffsetX.toDp() } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt index 08e3b1f7..e3c62b4d 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt @@ -677,6 +677,16 @@ fun ChannelScreen( modifier = Modifier.weight(1f), contentAlignment = Alignment.BottomCenter ) { + val jumpToMessage: (String) -> Unit = { messageId -> + viewModel.setHighlightedMessage(messageId) + val messageIndex = viewModel.findMessageIndex(messageId) + if (messageIndex >= 0) { + scope.launch { + lazyListState.animateScrollToItem(messageIndex) + } + } + } + LazyColumn( state = lazyListState, userScrollEnabled = !disableScroll, @@ -748,6 +758,8 @@ fun ChannelScreen( }, putTextAtCursorPosition = viewModel::putAtCursorPosition, replyToMessage = viewModel::addReplyTo, + jumpToMessage = jumpToMessage, + highlightedMessageId = viewModel.highlightedMessageId, scope = scope ) } diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt index 1402e278..dbb0e058 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreenViewModel.kt @@ -106,6 +106,8 @@ class ChannelScreenViewModel @Inject constructor( var ageGateUnlocked by mutableStateOf(null) var showGeoGate by mutableStateOf(false) + var highlightedMessageId by mutableStateOf(null) + init { viewModelScope.launch { keyboardHeight = kvStorage.getInt("keyboardHeight") ?: 900 // reasonable default for now @@ -311,6 +313,27 @@ class ChannelScreenViewModel @Inject constructor( keyboardHeight = height } + fun setHighlightedMessage(messageId: String) { + highlightedMessageId = messageId + + viewModelScope.launch { + delay(3000) // 3 second highlight + if (highlightedMessageId == messageId) { + highlightedMessageId = null + } + } + } + + fun findMessageIndex(messageId: String): Int { + return items.indexOfFirst { item -> + when (item) { + is ChannelScreenItem.RegularMessage -> item.message.id == messageId + is ChannelScreenItem.SystemMessage -> item.message.id == messageId + else -> false + } + } + } + private suspend fun applyMessageEdit() { try { editMessage(