Merge pull request #1897 from element-hq/jonny/timeline-poll-edited

Display edited indicator for polls in the timeline
This commit is contained in:
ganfra 2023-12-14 08:13:11 +01:00 committed by GitHub
commit b94f446fc1
10 changed files with 25 additions and 6 deletions

View file

@ -36,8 +36,7 @@ import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons 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.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent import io.element.android.features.messages.impl.timeline.model.event.isEdited
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
@ -55,7 +54,7 @@ fun TimelineEventTimestampView(
) { ) {
val formattedTime = event.sentTime val formattedTime = event.sentTime
val hasMessageSendingFailed = event.localSendState is LocalEventSendState.SendingFailed 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 tint = if (hasMessageSendingFailed) MaterialTheme.colorScheme.error else null
val clickModifier = if (hasMessageSendingFailed) { val clickModifier = if (hasMessageSendingFailed) {
Modifier.combinedClickable( Modifier.combinedClickable(

View file

@ -131,7 +131,8 @@ class InReplyToDetailsProvider : PreviewParameterProvider<InReplyToDetails> {
maxSelections = 1u, maxSelections = 1u,
answers = persistentListOf(), answers = persistentListOf(),
votes = persistentMapOf(), votes = persistentMapOf(),
endTime = null endTime = null,
isEdited = false,
), ),
).map { ).map {
aInReplyToDetails( aInReplyToDetails(

View file

@ -76,6 +76,7 @@ class TimelineItemContentPollFactory @Inject constructor(
answerItems = answerItems, answerItems = answerItems,
pollKind = content.kind, pollKind = content.kind,
isEnded = isEndedPoll, isEnded = isEndedPoll,
isEdited = content.isEdited,
) )
} }
} }

View file

@ -63,3 +63,13 @@ fun TimelineItemEventContent.canReact(): Boolean =
is TimelineItemRedactedContent, is TimelineItemRedactedContent,
TimelineItemUnknownContent -> false TimelineItemUnknownContent -> false
} }
/**
* Whether the event content has been edited.
*/
fun TimelineItemEventContent.isEdited(): Boolean =
when (this) {
is TimelineItemTextBasedContent -> isEdited
is TimelineItemPollContent -> isEdited
else -> false
}

View file

@ -26,6 +26,7 @@ data class TimelineItemPollContent(
val answerItems: List<PollAnswerItem>, val answerItems: List<PollAnswerItem>,
val pollKind: PollKind, val pollKind: PollKind,
val isEnded: Boolean, val isEnded: Boolean,
val isEdited: Boolean
) : TimelineItemEventContent { ) : TimelineItemEventContent {
override val type: String = "TimelineItemPollContent" override val type: String = "TimelineItemPollContent"
} }

View file

@ -35,6 +35,7 @@ fun aTimelineItemPollContent(
question: String = aPollQuestion(), question: String = aPollQuestion(),
answerItems: List<PollAnswerItem> = aPollAnswerItemList(), answerItems: List<PollAnswerItem> = aPollAnswerItemList(),
isEnded: Boolean = false, isEnded: Boolean = false,
isEdited: Boolean = false,
): TimelineItemPollContent { ): TimelineItemPollContent {
return TimelineItemPollContent( return TimelineItemPollContent(
eventId = EventId("\$anEventId"), eventId = EventId("\$anEventId"),
@ -42,5 +43,6 @@ fun aTimelineItemPollContent(
question = question, question = question,
answerItems = answerItems, answerItems = answerItems,
isEnded = isEnded, isEnded = isEnded,
isEdited = isEdited,
) )
} }

View file

@ -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), answers = persistentListOf(A_POLL_ANSWER_1, A_POLL_ANSWER_2, A_POLL_ANSWER_3, A_POLL_ANSWER_4),
votes = votes, votes = votes,
endTime = endTime, endTime = endTime,
isEdited = false,
) )
private fun aTimelineItemPollContent( private fun aTimelineItemPollContent(
@ -253,6 +254,7 @@ internal class TimelineItemContentPollFactoryTest {
answerItems = answerItems, answerItems = answerItems,
pollKind = pollKind, pollKind = pollKind,
isEnded = isEnded, isEnded = isEnded,
isEdited = false,
) )
private fun aPollAnswerItem( private fun aPollAnswerItem(

View file

@ -49,7 +49,8 @@ data class PollContent(
val maxSelections: ULong, val maxSelections: ULong,
val answers: ImmutableList<PollAnswer>, val answers: ImmutableList<PollAnswer>,
val votes: ImmutableMap<String, ImmutableList<UserId>>, val votes: ImmutableMap<String, ImmutableList<UserId>>,
val endTime: ULong? val endTime: ULong?,
val isEdited: Boolean,
) : EventContent ) : EventContent
data class UnableToDecryptContent( data class UnableToDecryptContent(

View file

@ -113,6 +113,7 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap
vote.value.map { userId -> UserId(userId) }.toImmutableList() vote.value.map { userId -> UserId(userId) }.toImmutableList()
}.toImmutableMap(), }.toImmutableMap(),
endTime = kind.endTime, endTime = kind.endTime,
isEdited = kind.hasBeenEdited,
) )
} }
is TimelineItemContentKind.UnableToDecrypt -> { is TimelineItemContentKind.UnableToDecrypt -> {

View file

@ -191,5 +191,6 @@ fun aPollContent(
maxSelections = 1u, maxSelections = 1u,
answers = answers, answers = answers,
votes = persistentMapOf(), votes = persistentMapOf(),
endTime = null endTime = null,
isEdited = false,
) )