Composer: Edit and reply: highlight selected item.

This commit is contained in:
Benoit Marty 2022-12-01 11:19:54 +01:00 committed by Benoit Marty
parent 232cabcb27
commit a84db0cf92
6 changed files with 48 additions and 12 deletions

View file

@ -25,6 +25,7 @@ class MessageTimelineItemStateMapper(
private val room: MatrixRoom, private val room: MatrixRoom,
private val dispatcher: CoroutineDispatcher, private val dispatcher: CoroutineDispatcher,
) { ) {
var highlightedEventId: String? = null
suspend fun map(timelineItems: List<MatrixTimelineItem>): List<MessagesTimelineItemState> = suspend fun map(timelineItems: List<MatrixTimelineItem>): List<MessagesTimelineItemState> =
withContext(dispatcher) { withContext(dispatcher) {
@ -33,7 +34,12 @@ class MessageTimelineItemStateMapper(
val currentTimelineItem = timelineItems[index] val currentTimelineItem = timelineItems[index]
val timelineItemState = when (currentTimelineItem) { val timelineItemState = when (currentTimelineItem) {
is MatrixTimelineItem.Event -> { is MatrixTimelineItem.Event -> {
buildMessageEvent(currentTimelineItem, index, timelineItems) buildMessageEvent(
currentTimelineItem,
index,
timelineItems,
highlightedEventId
)
} }
is MatrixTimelineItem.Virtual -> MessagesTimelineItemState.Virtual( is MatrixTimelineItem.Virtual -> MessagesTimelineItemState.Virtual(
"virtual_item_$index" "virtual_item_$index"
@ -48,7 +54,8 @@ class MessageTimelineItemStateMapper(
private suspend fun buildMessageEvent( private suspend fun buildMessageEvent(
currentTimelineItem: MatrixTimelineItem.Event, currentTimelineItem: MatrixTimelineItem.Event,
index: Int, index: Int,
timelineItems: List<MatrixTimelineItem> timelineItems: List<MatrixTimelineItem>,
highlightedEventId: String?,
): MessagesTimelineItemState.MessageEvent { ): MessagesTimelineItemState.MessageEvent {
val currentSender = currentTimelineItem.event.sender() val currentSender = currentTimelineItem.event.sender()
val groupPosition = val groupPosition =
@ -68,6 +75,7 @@ class MessageTimelineItemStateMapper(
senderAvatar = senderAvatarData, senderAvatar = senderAvatarData,
content = currentTimelineItem.computeContent(), content = currentTimelineItem.computeContent(),
isMine = currentTimelineItem.event.isOwn(), isMine = currentTimelineItem.event.isOwn(),
isHighlighted = currentTimelineItem.event.eventId().orEmpty() == highlightedEventId,
groupPosition = groupPosition, groupPosition = groupPosition,
reactionsState = currentTimelineItem.computeReactionsState() reactionsState = currentTimelineItem.computeReactionsState()
) )

View file

@ -382,6 +382,7 @@ fun MessageEventRow(
MessageEventBubble( MessageEventBubble(
groupPosition = messageEvent.groupPosition, groupPosition = messageEvent.groupPosition,
isMine = messageEvent.isMine, isMine = messageEvent.isMine,
isHighlighted = messageEvent.isHighlighted,
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
modifier = Modifier modifier = Modifier

View file

@ -18,9 +18,7 @@ import io.element.android.x.matrix.room.MatrixRoom
import io.element.android.x.matrix.timeline.MatrixTimeline import io.element.android.x.matrix.timeline.MatrixTimeline
import io.element.android.x.textcomposer.MessageComposerMode import io.element.android.x.textcomposer.MessageComposerMode
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
@ -191,7 +189,21 @@ class MessagesViewModel(
} }
}.launchIn(viewModelScope) }.launchIn(viewModelScope)
timeline.timelineItems() combine(
timeline.timelineItems(),
stateFlow
.map { it.composerMode }
.distinctUntilChanged()
) { timelineItems, messageComposerMode ->
// Set the highlightedEventId to messageTimelineItemStateMapper, before the mapping occurs
messageTimelineItemStateMapper.highlightedEventId = when (messageComposerMode) {
is MessageComposerMode.Normal -> null
is MessageComposerMode.Edit -> messageComposerMode.eventId
is MessageComposerMode.Quote -> null
is MessageComposerMode.Reply -> messageComposerMode.eventId
}
timelineItems
}
.map(messageTimelineItemStateMapper::map) .map(messageTimelineItemStateMapper::map)
.execute { .execute {
copy(timelineItems = it) copy(timelineItems = it)

View file

@ -24,6 +24,7 @@ private val BUBBLE_RADIUS = 16.dp
fun MessageEventBubble( fun MessageEventBubble(
groupPosition: MessagesItemGroupPosition, groupPosition: MessagesItemGroupPosition,
isMine: Boolean, isMine: Boolean,
isHighlighted: Boolean,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: () -> Unit, onClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
@ -64,17 +65,25 @@ fun MessageEventBubble(
} }
} }
val backgroundBubbleColor = if (isMine) { val backgroundBubbleColor = if (isHighlighted) {
if (LocalIsDarkTheme.current) { if (LocalIsDarkTheme.current) {
SystemGrey5Dark MessageHighlightDark
} else { } else {
SystemGrey5Light MessageHighlightLight
} }
} else { } else {
if (LocalIsDarkTheme.current) { if (isMine) {
SystemGrey6Dark if (LocalIsDarkTheme.current) {
SystemGrey5Dark
} else {
SystemGrey5Light
}
} else { } else {
SystemGrey6Light if (LocalIsDarkTheme.current) {
SystemGrey6Dark
} else {
SystemGrey6Light
}
} }
} }
val bubbleShape = bubbleShape() val bubbleShape = bubbleShape()

View file

@ -16,6 +16,7 @@ sealed interface MessagesTimelineItemState {
val content: MessagesTimelineItemContent, val content: MessagesTimelineItemContent,
val sentTime: String = "", val sentTime: String = "",
val isMine: Boolean = false, val isMine: Boolean = false,
val isHighlighted: Boolean = false,
val groupPosition: MessagesItemGroupPosition = MessagesItemGroupPosition.None, val groupPosition: MessagesItemGroupPosition = MessagesItemGroupPosition.None,
val reactionsState: MessagesItemReactionState val reactionsState: MessagesItemReactionState
) : MessagesTimelineItemState { ) : MessagesTimelineItemState {

View file

@ -34,3 +34,8 @@ val Melon = Color(0xFFFF812D)
val ElementGreen = Color(0xFF0DBD8B) val ElementGreen = Color(0xFF0DBD8B)
val ElementOrange = Color(0xFFD9B072) val ElementOrange = Color(0xFFD9B072)
val Vermilion = Color(0xFFFF5B55) val Vermilion = Color(0xFFFF5B55)
// TODO Update color
val MessageHighlightLight = Azure
// TODO Update color
val MessageHighlightDark = Azure