Merge branch 'develop' into feature/dla/emojibase_integration
This commit is contained in:
commit
d2e4cda28c
27 changed files with 259 additions and 50 deletions
|
|
@ -22,4 +22,8 @@ sealed interface TimelineEvents {
|
|||
data object LoadMore : TimelineEvents
|
||||
data class SetHighlightedEvent(val eventId: EventId?) : TimelineEvents
|
||||
data class OnScrollFinished(val firstIndex: Int) : TimelineEvents
|
||||
data class PollAnswerSelected(
|
||||
val pollStartId: EventId,
|
||||
val answerId: String
|
||||
) : TimelineEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,13 @@ class TimelinePresenter @Inject constructor(
|
|||
lastReadReceiptId = lastReadReceiptId
|
||||
)
|
||||
}
|
||||
is TimelineEvents.PollAnswerSelected -> appScope.launch {
|
||||
room.sendPollResponse(
|
||||
pollStartId = event.pollStartId,
|
||||
answers = listOf(event.answerId),
|
||||
)
|
||||
// TODO Polls: Send poll vote analytic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ fun TimelineView(
|
|||
// TODO implement this logic once we have support to 'jump to event X' in sliding sync
|
||||
}
|
||||
|
||||
fun onPollAnswerSelected(pollStartId: EventId, answerId: String) {
|
||||
state.eventSink(TimelineEvents.PollAnswerSelected(pollStartId, answerId))
|
||||
}
|
||||
|
||||
Box(modifier = modifier) {
|
||||
LazyColumn(
|
||||
|
|
@ -125,6 +128,7 @@ fun TimelineView(
|
|||
onReactionLongClick = onReactionLongClicked,
|
||||
onMoreReactionsClick = onMoreReactionsClicked,
|
||||
onTimestampClicked = onTimestampClicked,
|
||||
onPollAnswerSelected = ::onPollAnswerSelected,
|
||||
onSwipeToReply = onSwipeToReply,
|
||||
)
|
||||
}
|
||||
|
|
@ -162,6 +166,7 @@ fun TimelineItemRow(
|
|||
onMoreReactionsClick: (TimelineItem.Event) -> Unit,
|
||||
onTimestampClicked: (TimelineItem.Event) -> Unit,
|
||||
onSwipeToReply: (TimelineItem.Event) -> Unit,
|
||||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
when (timelineItem) {
|
||||
|
|
@ -194,6 +199,7 @@ fun TimelineItemRow(
|
|||
onMoreReactionsClick = onMoreReactionsClick,
|
||||
onTimestampClicked = onTimestampClicked,
|
||||
onSwipeToReply = { onSwipeToReply(timelineItem) },
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -231,6 +237,7 @@ fun TimelineItemRow(
|
|||
onReactionClick = onReactionClick,
|
||||
onReactionLongClick = onReactionLongClick,
|
||||
onMoreReactionsClick = onMoreReactionsClick,
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
onSwipeToReply = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ fun TimelineItemEventRow(
|
|||
onReactionLongClick: (emoji: String, eventId: TimelineItem.Event) -> Unit,
|
||||
onMoreReactionsClick: (eventId: TimelineItem.Event) -> Unit,
|
||||
onSwipeToReply: () -> Unit,
|
||||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
|
@ -175,6 +176,7 @@ fun TimelineItemEventRow(
|
|||
onReactionClicked = { emoji -> onReactionClick(emoji, event) },
|
||||
onReactionLongClicked = { emoji -> onReactionLongClick(emoji, event) },
|
||||
onMoreReactionsClicked = { onMoreReactionsClick(event) },
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -191,6 +193,7 @@ fun TimelineItemEventRow(
|
|||
onReactionClicked = { emoji -> onReactionClick(emoji, event) },
|
||||
onReactionLongClicked = { emoji -> onReactionLongClick(emoji, event) },
|
||||
onMoreReactionsClicked = { onMoreReactionsClick(event) },
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -232,6 +235,7 @@ private fun TimelineItemEventRowContent(
|
|||
onReactionClicked: (emoji: String) -> Unit,
|
||||
onReactionLongClicked: (emoji: String) -> Unit,
|
||||
onMoreReactionsClicked: (event: TimelineItem.Event) -> Unit,
|
||||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun ConstrainScope.linkStartOrEnd(event: TimelineItem.Event) = if (event.isMine) {
|
||||
|
|
@ -289,7 +293,8 @@ private fun TimelineItemEventRowContent(
|
|||
inReplyToClick = inReplyToClicked,
|
||||
onTimestampClicked = {
|
||||
onTimestampClicked(event)
|
||||
}
|
||||
},
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -360,6 +365,7 @@ private fun MessageEventBubbleContent(
|
|||
onMessageLongClick: () -> Unit,
|
||||
inReplyToClick: () -> Unit,
|
||||
onTimestampClicked: () -> Unit,
|
||||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
@SuppressLint("ModifierParameter") bubbleModifier: Modifier = Modifier, // need to rename this modifier to distinguish it from the following ones
|
||||
) {
|
||||
val timestampPosition = when (event.content) {
|
||||
|
|
@ -385,6 +391,7 @@ private fun MessageEventBubbleContent(
|
|||
onClick = onMessageClick,
|
||||
onLongClick = onMessageLongClick,
|
||||
extraPadding = event.toExtraPadding(),
|
||||
onPollAnswerSelected = onPollAnswerSelected,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -607,6 +614,7 @@ private fun ContentToPreview() {
|
|||
onMoreReactionsClick = {},
|
||||
onTimestampClicked = {},
|
||||
onSwipeToReply = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
TimelineItemEventRow(
|
||||
event = aTimelineItemEvent(
|
||||
|
|
@ -627,6 +635,7 @@ private fun ContentToPreview() {
|
|||
onMoreReactionsClick = {},
|
||||
onTimestampClicked = {},
|
||||
onSwipeToReply = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -674,6 +683,7 @@ private fun ContentToPreviewWithReply() {
|
|||
onMoreReactionsClick = {},
|
||||
onTimestampClicked = {},
|
||||
onSwipeToReply = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
TimelineItemEventRow(
|
||||
event = aTimelineItemEvent(
|
||||
|
|
@ -695,6 +705,7 @@ private fun ContentToPreviewWithReply() {
|
|||
onMoreReactionsClick = {},
|
||||
onTimestampClicked = {},
|
||||
onSwipeToReply = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -752,6 +763,7 @@ private fun ContentTimestampToPreview(event: TimelineItem.Event) {
|
|||
onMoreReactionsClick = {},
|
||||
onTimestampClicked = {},
|
||||
onSwipeToReply = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -792,6 +804,7 @@ private fun ContentWithManyReactionsToPreview() {
|
|||
onMoreReactionsClick = {},
|
||||
onSwipeToReply = {},
|
||||
onTimestampClicked = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -816,6 +829,7 @@ internal fun TimelineItemEventRowLongSenderNamePreview() = ElementPreviewLight {
|
|||
onMoreReactionsClick = {},
|
||||
onSwipeToReply = {},
|
||||
onTimestampClicked = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -836,5 +850,6 @@ internal fun TimelineItemEventTimestampBelowPreview() = ElementPreviewLight {
|
|||
onMoreReactionsClick = {},
|
||||
onSwipeToReply = {},
|
||||
onTimestampClicked = {},
|
||||
onPollAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ fun TimelineItemStateEventRow(
|
|||
onClick = onClick,
|
||||
onLongClick = onLongClick,
|
||||
extraPadding = noExtraPadding,
|
||||
onPollAnswerSelected = { _, _ -> error("Polls are not supported in state events") },
|
||||
modifier = Modifier.defaultTimelineContentPadding()
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
|
||||
@Composable
|
||||
fun TimelineItemEventContentView(
|
||||
|
|
@ -39,6 +40,7 @@ fun TimelineItemEventContentView(
|
|||
extraPadding: ExtraPadding,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
when (content) {
|
||||
|
|
@ -93,7 +95,7 @@ fun TimelineItemEventContentView(
|
|||
)
|
||||
is TimelineItemPollContent -> TimelineItemPollView(
|
||||
content = content,
|
||||
onAnswerSelected = {},
|
||||
onAnswerSelected = onPollAnswerSelected,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,16 +24,17 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.poll.api.PollContentView
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.matrix.api.poll.PollAnswer
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Composable
|
||||
fun TimelineItemPollView(
|
||||
content: TimelineItemPollContent,
|
||||
onAnswerSelected: (PollAnswer) -> Unit,
|
||||
onAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
PollContentView(
|
||||
eventId = content.eventId,
|
||||
question = content.question,
|
||||
answerItems = content.answerItems.toImmutableList(),
|
||||
pollKind = content.pollKind,
|
||||
|
|
@ -49,6 +50,6 @@ internal fun TimelineItemPollViewPreview(@PreviewParameter(TimelineItemPollConte
|
|||
ElementPreview {
|
||||
TimelineItemPollView(
|
||||
content = content,
|
||||
onAnswerSelected = {},
|
||||
onAnswerSelected = { _, _ -> },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class TimelineItemContentFactory @Inject constructor(
|
|||
is RoomMembershipContent -> roomMembershipFactory.create(eventTimelineItem)
|
||||
is StateContent -> stateFactory.create(eventTimelineItem)
|
||||
is StickerContent -> stickerFactory.create(itemContent)
|
||||
is PollContent -> pollFactory.create(itemContent)
|
||||
is PollContent -> pollFactory.create(itemContent, eventTimelineItem.eventId)
|
||||
is UnableToDecryptContent -> utdFactory.create(itemContent)
|
||||
is UnknownContent -> TimelineItemUnknownContent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import io.element.android.features.poll.api.PollAnswerItem
|
|||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.poll.isDisclosed
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
import javax.inject.Inject
|
||||
|
|
@ -32,7 +33,10 @@ class TimelineItemContentPollFactory @Inject constructor(
|
|||
private val featureFlagService: FeatureFlagService,
|
||||
) {
|
||||
|
||||
suspend fun create(content: PollContent): TimelineItemEventContent {
|
||||
suspend fun create(
|
||||
content: PollContent,
|
||||
eventId: EventId?
|
||||
): TimelineItemEventContent {
|
||||
if (!featureFlagService.isFeatureEnabled(FeatureFlags.Polls)) return TimelineItemUnknownContent
|
||||
|
||||
// Todo Move this computation to the matrix rust sdk
|
||||
|
|
@ -67,6 +71,7 @@ class TimelineItemContentPollFactory @Inject constructor(
|
|||
}
|
||||
|
||||
return TimelineItemPollContent(
|
||||
eventId = eventId,
|
||||
question = content.question,
|
||||
answerItems = answerItems,
|
||||
pollKind = content.kind,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@
|
|||
package io.element.android.features.messages.impl.timeline.model.event
|
||||
|
||||
import io.element.android.features.poll.api.PollAnswerItem
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||
|
||||
data class TimelineItemPollContent(
|
||||
val eventId: EventId?,
|
||||
val question: String,
|
||||
val answerItems: List<PollAnswerItem>,
|
||||
val pollKind: PollKind,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.messages.impl.timeline.model.event
|
|||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.poll.api.aPollAnswerItemList
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||
|
||||
open class TimelineItemPollContentProvider : PreviewParameterProvider<TimelineItemPollContent> {
|
||||
|
|
@ -30,6 +31,7 @@ open class TimelineItemPollContentProvider : PreviewParameterProvider<TimelineIt
|
|||
|
||||
fun aTimelineItemPollContent(): TimelineItemPollContent {
|
||||
return TimelineItemPollContent(
|
||||
eventId = EventId("\$anEventId"),
|
||||
pollKind = PollKind.Disclosed,
|
||||
question = "What type of food should we have at the party?",
|
||||
answerItems = aPollAnswerItemList(),
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class MessageSummaryFormatterImpl @Inject constructor(
|
|||
is TimelineItemLocationContent -> context.getString(CommonStrings.common_shared_location)
|
||||
is TimelineItemEncryptedContent -> context.getString(CommonStrings.common_unable_to_decrypt)
|
||||
is TimelineItemRedactedContent -> context.getString(CommonStrings.common_message_removed)
|
||||
is TimelineItemPollContent, // Todo Polls: handle summary
|
||||
is TimelineItemPollContent -> event.content.question
|
||||
is TimelineItemUnknownContent -> context.getString(CommonStrings.common_unsupported_event)
|
||||
is TimelineItemImageContent -> context.getString(CommonStrings.common_image)
|
||||
is TimelineItemVideoContent -> context.getString(CommonStrings.common_video)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue