Send state: show if null and is last message.
Read receipt: Also show the send state even if the flag for read receipt is set to false.
This commit is contained in:
parent
476373731f
commit
3b88e030c6
5 changed files with 54 additions and 42 deletions
|
|
@ -128,6 +128,8 @@ fun TimelineView(
|
||||||
TimelineItemRow(
|
TimelineItemRow(
|
||||||
timelineItem = timelineItem,
|
timelineItem = timelineItem,
|
||||||
showReadReceipts = state.showReadReceipts,
|
showReadReceipts = state.showReadReceipts,
|
||||||
|
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true
|
||||||
|
&& state.timelineItems.first().identifier() == timelineItem.identifier(),
|
||||||
highlightedItem = state.highlightedEventId?.value,
|
highlightedItem = state.highlightedEventId?.value,
|
||||||
userHasPermissionToSendMessage = state.userHasPermissionToSendMessage,
|
userHasPermissionToSendMessage = state.userHasPermissionToSendMessage,
|
||||||
onClick = onMessageClicked,
|
onClick = onMessageClicked,
|
||||||
|
|
@ -173,6 +175,7 @@ fun TimelineView(
|
||||||
private fun TimelineItemRow(
|
private fun TimelineItemRow(
|
||||||
timelineItem: TimelineItem,
|
timelineItem: TimelineItem,
|
||||||
showReadReceipts: Boolean,
|
showReadReceipts: Boolean,
|
||||||
|
isLastOutgoingMessage: Boolean,
|
||||||
highlightedItem: String?,
|
highlightedItem: String?,
|
||||||
userHasPermissionToSendMessage: Boolean,
|
userHasPermissionToSendMessage: Boolean,
|
||||||
sessionState: SessionState,
|
sessionState: SessionState,
|
||||||
|
|
@ -211,6 +214,7 @@ private fun TimelineItemRow(
|
||||||
TimelineItemEventRow(
|
TimelineItemEventRow(
|
||||||
event = timelineItem,
|
event = timelineItem,
|
||||||
showReadReceipts = showReadReceipts,
|
showReadReceipts = showReadReceipts,
|
||||||
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
isHighlighted = highlightedItem == timelineItem.identifier(),
|
isHighlighted = highlightedItem == timelineItem.identifier(),
|
||||||
canReply = userHasPermissionToSendMessage && timelineItem.content.canBeRepliedTo(),
|
canReply = userHasPermissionToSendMessage && timelineItem.content.canBeRepliedTo(),
|
||||||
onClick = { onClick(timelineItem) },
|
onClick = { onClick(timelineItem) },
|
||||||
|
|
@ -252,6 +256,7 @@ private fun TimelineItemRow(
|
||||||
TimelineItemRow(
|
TimelineItemRow(
|
||||||
timelineItem = subGroupEvent,
|
timelineItem = subGroupEvent,
|
||||||
showReadReceipts = showReadReceipts,
|
showReadReceipts = showReadReceipts,
|
||||||
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
highlightedItem = highlightedItem,
|
highlightedItem = highlightedItem,
|
||||||
sessionState = sessionState,
|
sessionState = sessionState,
|
||||||
userHasPermissionToSendMessage = false,
|
userHasPermissionToSendMessage = false,
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ import kotlin.math.roundToInt
|
||||||
fun TimelineItemEventRow(
|
fun TimelineItemEventRow(
|
||||||
event: TimelineItem.Event,
|
event: TimelineItem.Event,
|
||||||
showReadReceipts: Boolean,
|
showReadReceipts: Boolean,
|
||||||
|
isLastOutgoingMessage: Boolean,
|
||||||
isHighlighted: Boolean,
|
isHighlighted: Boolean,
|
||||||
canReply: Boolean,
|
canReply: Boolean,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
|
@ -178,6 +179,7 @@ fun TimelineItemEventRow(
|
||||||
),
|
),
|
||||||
event = event,
|
event = event,
|
||||||
showReadReceipts = showReadReceipts,
|
showReadReceipts = showReadReceipts,
|
||||||
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
isHighlighted = isHighlighted,
|
isHighlighted = isHighlighted,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|
@ -197,6 +199,7 @@ fun TimelineItemEventRow(
|
||||||
TimelineItemEventRowContent(
|
TimelineItemEventRowContent(
|
||||||
event = event,
|
event = event,
|
||||||
showReadReceipts = showReadReceipts,
|
showReadReceipts = showReadReceipts,
|
||||||
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
isHighlighted = isHighlighted,
|
isHighlighted = isHighlighted,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
|
|
@ -241,6 +244,7 @@ private fun SwipeSensitivity(
|
||||||
private fun TimelineItemEventRowContent(
|
private fun TimelineItemEventRowContent(
|
||||||
event: TimelineItem.Event,
|
event: TimelineItem.Event,
|
||||||
showReadReceipts: Boolean,
|
showReadReceipts: Boolean,
|
||||||
|
isLastOutgoingMessage: Boolean,
|
||||||
isHighlighted: Boolean,
|
isHighlighted: Boolean,
|
||||||
interactionSource: MutableInteractionSource,
|
interactionSource: MutableInteractionSource,
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
|
@ -339,23 +343,23 @@ private fun TimelineItemEventRowContent(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read receipts / Send state
|
// Read receipts / Send state
|
||||||
if (showReadReceipts) {
|
TimelineItemReadReceiptView(
|
||||||
TimelineItemReadReceiptView(
|
state = ReadReceiptViewState(
|
||||||
state = ReadReceiptViewState(
|
sendState = event.localSendState,
|
||||||
sendState = event.localSendState,
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
receipts = event.readReceiptState.receipts,
|
receipts = event.readReceiptState.receipts,
|
||||||
),
|
),
|
||||||
onReadReceiptsClicked = onReadReceiptsClicked,
|
showReadReceipts = showReadReceipts,
|
||||||
modifier = Modifier
|
onReadReceiptsClicked = onReadReceiptsClicked,
|
||||||
.constrainAs(readReceipts) {
|
modifier = Modifier
|
||||||
if (event.reactionsState.reactions.isNotEmpty()) {
|
.constrainAs(readReceipts) {
|
||||||
top.linkTo(reactions.bottom, margin = 4.dp)
|
if (event.reactionsState.reactions.isNotEmpty()) {
|
||||||
} else {
|
top.linkTo(reactions.bottom, margin = 4.dp)
|
||||||
top.linkTo(message.bottom, margin = 4.dp)
|
} else {
|
||||||
}
|
top.linkTo(message.bottom, margin = 4.dp)
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -685,6 +689,7 @@ internal fun TimelineItemEventRowPreview() = ElementPreview {
|
||||||
groupPosition = TimelineItemGroupPosition.First,
|
groupPosition = TimelineItemGroupPosition.First,
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -708,6 +713,7 @@ internal fun TimelineItemEventRowPreview() = ElementPreview {
|
||||||
groupPosition = TimelineItemGroupPosition.Last,
|
groupPosition = TimelineItemGroupPosition.Last,
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -749,6 +755,7 @@ internal fun TimelineItemEventRowWithReplyPreview() = ElementPreview {
|
||||||
groupPosition = TimelineItemGroupPosition.First,
|
groupPosition = TimelineItemGroupPosition.First,
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -774,6 +781,7 @@ internal fun TimelineItemEventRowWithReplyPreview() = ElementPreview {
|
||||||
groupPosition = TimelineItemGroupPosition.Last,
|
groupPosition = TimelineItemGroupPosition.Last,
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -827,6 +835,7 @@ internal fun TimelineItemEventRowTimestampPreview(
|
||||||
senderDisplayName = if (useDocument) "Document case" else "Text case",
|
senderDisplayName = if (useDocument) "Document case" else "Text case",
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -861,6 +870,7 @@ internal fun TimelineItemEventRowWithManyReactionsPreview() = ElementPreview {
|
||||||
timelineItemReactions = aTimelineItemReactions(count = 20),
|
timelineItemReactions = aTimelineItemReactions(count = 20),
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -888,6 +898,7 @@ internal fun TimelineItemEventRowLongSenderNamePreview() = ElementPreviewLight {
|
||||||
senderDisplayName = "a long sender display name to test single line and ellipsis at the end of the line",
|
senderDisplayName = "a long sender display name to test single line and ellipsis at the end of the line",
|
||||||
),
|
),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
@ -911,6 +922,7 @@ internal fun TimelineItemEventTimestampBelowPreview() = ElementPreviewLight {
|
||||||
TimelineItemEventRow(
|
TimelineItemEventRow(
|
||||||
event = aTimelineItemEvent(content = aTimelineItemPollContent()),
|
event = aTimelineItemEvent(content = aTimelineItemPollContent()),
|
||||||
showReadReceipts = false,
|
showReadReceipts = false,
|
||||||
|
isLastOutgoingMessage = false,
|
||||||
isHighlighted = false,
|
isHighlighted = false,
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,6 @@ import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
||||||
data class ReadReceiptViewState(
|
data class ReadReceiptViewState(
|
||||||
val sendState: LocalEventSendState?,
|
val sendState: LocalEventSendState?,
|
||||||
|
val isLastOutgoingMessage: Boolean,
|
||||||
val receipts: ImmutableList<ReadReceiptData>,
|
val receipts: ImmutableList<ReadReceiptData>,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,11 @@ class ReadReceiptViewStateProvider : PreviewParameterProvider<ReadReceiptViewSta
|
||||||
|
|
||||||
private fun aReadReceiptViewState(
|
private fun aReadReceiptViewState(
|
||||||
sendState: LocalEventSendState? = null,
|
sendState: LocalEventSendState? = null,
|
||||||
|
isLastOutgoingMessage: Boolean = true,
|
||||||
receipts: List<ReadReceiptData> = emptyList(),
|
receipts: List<ReadReceiptData> = emptyList(),
|
||||||
) = ReadReceiptViewState(
|
) = ReadReceiptViewState(
|
||||||
sendState = sendState,
|
sendState = sendState,
|
||||||
|
isLastOutgoingMessage = isLastOutgoingMessage,
|
||||||
receipts = receipts.toImmutableList(),
|
receipts = receipts.toImmutableList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,23 @@ import kotlinx.collections.immutable.ImmutableList
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineItemReadReceiptView(
|
fun TimelineItemReadReceiptView(
|
||||||
state: ReadReceiptViewState,
|
state: ReadReceiptViewState,
|
||||||
|
showReadReceipts: Boolean,
|
||||||
onReadReceiptsClicked: () -> Unit,
|
onReadReceiptsClicked: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
when (state.sendState) {
|
if (state.receipts.isNotEmpty()) {
|
||||||
LocalEventSendState.Canceled -> Unit
|
if (showReadReceipts) {
|
||||||
|
ReadReceiptsRow(modifier = modifier) {
|
||||||
|
ReadReceiptsAvatars(
|
||||||
|
receipts = state.receipts,
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(4.dp))
|
||||||
|
.clickable { onReadReceiptsClicked() }
|
||||||
|
.padding(2.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else when (state.sendState) {
|
||||||
LocalEventSendState.NotSentYet -> {
|
LocalEventSendState.NotSentYet -> {
|
||||||
ReadReceiptsRow(modifier) {
|
ReadReceiptsRow(modifier) {
|
||||||
Icon(
|
Icon(
|
||||||
|
|
@ -73,11 +85,13 @@ fun TimelineItemReadReceiptView(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LocalEventSendState.Canceled -> Unit
|
||||||
is LocalEventSendState.SendingFailed -> {
|
is LocalEventSendState.SendingFailed -> {
|
||||||
// Error? The timestamp is already displayed in red
|
// Error? The timestamp is already displayed in red
|
||||||
}
|
}
|
||||||
|
null,
|
||||||
is LocalEventSendState.Sent -> {
|
is LocalEventSendState.Sent -> {
|
||||||
if (state.receipts.isEmpty()) {
|
if (state.isLastOutgoingMessage) {
|
||||||
ReadReceiptsRow(modifier = modifier) {
|
ReadReceiptsRow(modifier = modifier) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.padding(2.dp),
|
modifier = Modifier.padding(2.dp),
|
||||||
|
|
@ -86,29 +100,6 @@ fun TimelineItemReadReceiptView(
|
||||||
tint = ElementTheme.colors.iconSecondary
|
tint = ElementTheme.colors.iconSecondary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ReadReceiptsRow(modifier = modifier) {
|
|
||||||
ReadReceiptsAvatars(
|
|
||||||
receipts = state.receipts,
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
.clickable { onReadReceiptsClicked() }
|
|
||||||
.padding(2.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
null -> {
|
|
||||||
if (state.receipts.isNotEmpty()) {
|
|
||||||
ReadReceiptsRow(modifier = modifier) {
|
|
||||||
ReadReceiptsAvatars(
|
|
||||||
receipts = state.receipts,
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(RoundedCornerShape(4.dp))
|
|
||||||
.clickable { onReadReceiptsClicked() }
|
|
||||||
.padding(2.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,6 +205,7 @@ internal fun TimelineItemReactionsViewPreview(
|
||||||
) = ElementPreview {
|
) = ElementPreview {
|
||||||
TimelineItemReadReceiptView(
|
TimelineItemReadReceiptView(
|
||||||
state = state,
|
state = state,
|
||||||
|
showReadReceipts = true,
|
||||||
onReadReceiptsClicked = {},
|
onReadReceiptsClicked = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue