diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt index 069107a11c..3451c1590c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt @@ -36,8 +36,7 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.model.TimelineItem -import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent -import io.element.android.libraries.core.bool.orFalse +import io.element.android.features.messages.impl.timeline.model.event.isEdited import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon @@ -55,7 +54,7 @@ fun TimelineEventTimestampView( ) { val formattedTime = event.sentTime val hasMessageSendingFailed = event.localSendState is LocalEventSendState.SendingFailed - val isMessageEdited = (event.content as? TimelineItemTextBasedContent)?.isEdited.orFalse() + val isMessageEdited = event.content.isEdited() val tint = if (hasMessageSendingFailed) MaterialTheme.colorScheme.error else null val clickModifier = if (hasMessageSendingFailed) { Modifier.combinedClickable( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowWithReplyPreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowWithReplyPreview.kt index 8812f9ca8f..33e97a4428 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowWithReplyPreview.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRowWithReplyPreview.kt @@ -131,7 +131,8 @@ class InReplyToDetailsProvider : PreviewParameterProvider { maxSelections = 1u, answers = persistentListOf(), votes = persistentMapOf(), - endTime = null + endTime = null, + isEdited = false, ), ).map { aInReplyToDetails( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactory.kt index 04551f7086..3242e97d61 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactory.kt @@ -76,6 +76,7 @@ class TimelineItemContentPollFactory @Inject constructor( answerItems = answerItems, pollKind = content.kind, isEnded = isEndedPoll, + isEdited = content.isEdited, ) } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index 8678ae8826..feb3246e54 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -63,3 +63,13 @@ fun TimelineItemEventContent.canReact(): Boolean = is TimelineItemRedactedContent, TimelineItemUnknownContent -> false } + +/** + * Whether the event content has been edited. + */ +fun TimelineItemEventContent.isEdited(): Boolean = + when (this) { + is TimelineItemTextBasedContent -> isEdited + is TimelineItemPollContent -> isEdited + else -> false + } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt index dc47c12a86..2f60d96fb6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt @@ -26,6 +26,7 @@ data class TimelineItemPollContent( val answerItems: List, val pollKind: PollKind, val isEnded: Boolean, + val isEdited: Boolean ) : TimelineItemEventContent { override val type: String = "TimelineItemPollContent" } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContentProvider.kt index d20f9fa856..d32d361373 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContentProvider.kt @@ -35,6 +35,7 @@ fun aTimelineItemPollContent( question: String = aPollQuestion(), answerItems: List = aPollAnswerItemList(), isEnded: Boolean = false, + isEdited: Boolean = false, ): TimelineItemPollContent { return TimelineItemPollContent( eventId = EventId("\$anEventId"), @@ -42,5 +43,6 @@ fun aTimelineItemPollContent( question = question, answerItems = answerItems, isEnded = isEnded, + isEdited = isEdited, ) } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactoryTest.kt index 2d1f7766c9..5318b85ae0 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactoryTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentPollFactoryTest.kt @@ -235,6 +235,7 @@ internal class TimelineItemContentPollFactoryTest { answers = persistentListOf(A_POLL_ANSWER_1, A_POLL_ANSWER_2, A_POLL_ANSWER_3, A_POLL_ANSWER_4), votes = votes, endTime = endTime, + isEdited = false, ) private fun aTimelineItemPollContent( @@ -253,6 +254,7 @@ internal class TimelineItemContentPollFactoryTest { answerItems = answerItems, pollKind = pollKind, isEnded = isEnded, + isEdited = false, ) private fun aPollAnswerItem( diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt index 8a8d087e8f..5dcfd88016 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt @@ -49,7 +49,8 @@ data class PollContent( val maxSelections: ULong, val answers: ImmutableList, val votes: ImmutableMap>, - val endTime: ULong? + val endTime: ULong?, + val isEdited: Boolean, ) : EventContent data class UnableToDecryptContent( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index 7bad7a34d2..ee28b18d08 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -113,6 +113,7 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap vote.value.map { userId -> UserId(userId) }.toImmutableList() }.toImmutableMap(), endTime = kind.endTime, + isEdited = kind.hasBeenEdited, ) } is TimelineItemContentKind.UnableToDecrypt -> { diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index 2ff8ef1745..4dde81813d 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -191,5 +191,6 @@ fun aPollContent( maxSelections = 1u, answers = answers, votes = persistentMapOf(), - endTime = null + endTime = null, + isEdited = false, )