Merge pull request #6676 from bxdxnn/misc/reactions-pinned-messages

Show reactions in the pinned messages list
This commit is contained in:
Benoit Marty
2026-08-24 09:37:51 +02:00
committed by GitHub
8 changed files with 89 additions and 10 deletions
@@ -11,8 +11,10 @@ package io.element.android.features.messages.impl.pinned.list
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
sealed interface PinnedMessagesListEvent { sealed interface PinnedMessagesListEvent {
data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : PinnedMessagesListEvent data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : PinnedMessagesListEvent
data class OpenThread(val threadRootId: ThreadId) : PinnedMessagesListEvent data class OpenThread(val threadRootId: ThreadId) : PinnedMessagesListEvent
data class ToggleReaction(val emoji: String, val eventOrTransactionId: EventOrTransactionId) : PinnedMessagesListEvent
} }
@@ -30,6 +30,7 @@ import io.element.android.libraries.androidutils.system.copyToClipboard
import io.element.android.libraries.androidutils.system.openUrlInExternalApp import io.element.android.libraries.androidutils.system.openUrlInExternalApp
import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.callback
import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.emoji.api.picker.EmojiPickerRenderer
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
@@ -50,6 +51,7 @@ class PinnedMessagesListNode(
actionListPresenterFactory: ActionListPresenter.Factory, actionListPresenterFactory: ActionListPresenter.Factory,
private val timelineItemPresenterFactories: TimelineItemPresenterFactories, private val timelineItemPresenterFactories: TimelineItemPresenterFactories,
private val permalinkParser: PermalinkParser, private val permalinkParser: PermalinkParser,
private val emojiPickerRenderer: EmojiPickerRenderer,
) : Node(buildContext, plugins = plugins), PinnedMessagesListNavigator { ) : Node(buildContext, plugins = plugins), PinnedMessagesListNavigator {
interface Callback : Plugin { interface Callback : Plugin {
fun handleEventClick(event: TimelineItem.Event, canUseOverlay: Boolean) fun handleEventClick(event: TimelineItem.Event, canUseOverlay: Boolean)
@@ -134,6 +136,7 @@ class PinnedMessagesListNode(
toastMessage = toastMessage, toastMessage = toastMessage,
) )
}, },
emojiPickerRenderer = emojiPickerRenderer,
modifier = modifier modifier = modifier
) )
} }
@@ -30,6 +30,8 @@ import io.element.android.features.messages.impl.link.LinkState
import io.element.android.features.messages.impl.pinned.DefaultPinnedEventsTimelineProvider import io.element.android.features.messages.impl.pinned.DefaultPinnedEventsTimelineProvider
import io.element.android.features.messages.impl.pinned.keepDisplayablePinnedEvents import io.element.android.features.messages.impl.pinned.keepDisplayablePinnedEvents
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactoryConfig import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactoryConfig
import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem
@@ -47,6 +49,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState import io.element.android.libraries.matrix.api.room.powerlevels.permissionsAsState
import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.room.roomMembers
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import io.element.android.services.analyticsproviders.api.trackers.captureInteraction
@@ -71,6 +74,8 @@ class PinnedMessagesListPresenter(
private val linkPresenter: Presenter<LinkState>, private val linkPresenter: Presenter<LinkState>,
private val snackbarDispatcher: SnackbarDispatcher, private val snackbarDispatcher: SnackbarDispatcher,
@Assisted private val actionListPresenter: Presenter<ActionListState>, @Assisted private val actionListPresenter: Presenter<ActionListState>,
private val customReactionPresenter: Presenter<CustomReactionState>,
private val reactionSummaryPresenter: Presenter<ReactionSummaryState>,
@SessionCoroutineScope @SessionCoroutineScope
private val sessionCoroutineScope: CoroutineScope, private val sessionCoroutineScope: CoroutineScope,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
@@ -88,7 +93,7 @@ class PinnedMessagesListPresenter(
private val timelineItemsFactory: TimelineItemsFactory = timelineItemsFactoryCreator.create( private val timelineItemsFactory: TimelineItemsFactory = timelineItemsFactoryCreator.create(
config = TimelineItemsFactoryConfig( config = TimelineItemsFactoryConfig(
computeReadReceipts = false, computeReadReceipts = false,
computeReactions = false, computeReactions = true,
) )
) )
@@ -96,6 +101,9 @@ class PinnedMessagesListPresenter(
override fun present(): PinnedMessagesListState { override fun present(): PinnedMessagesListState {
htmlConverterProvider.Update() htmlConverterProvider.Update()
val roomInfo by room.roomInfoFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState()
val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms ->
perms.userEventPermissions()
}
val timelineRoomInfo by remember { val timelineRoomInfo by remember {
derivedStateOf { derivedStateOf {
TimelineRoomInfo( TimelineRoomInfo(
@@ -103,7 +111,7 @@ class PinnedMessagesListPresenter(
name = roomInfo.name, name = roomInfo.name,
// We don't need to compute those values // We don't need to compute those values
userHasPermissionToSendMessage = false, userHasPermissionToSendMessage = false,
userHasPermissionToSendReaction = false, userHasPermissionToSendReaction = userEventPermissions.canSendReaction,
// We do not care about the call state here. // We do not care about the call state here.
roomCallState = aStandByCallState(), roomCallState = aStandByCallState(),
// don't compute this value or the pin icon will be shown // don't compute this value or the pin icon will be shown
@@ -119,9 +127,8 @@ class PinnedMessagesListPresenter(
} }
val timelineProtectionState = timelineProtectionPresenter.present() val timelineProtectionState = timelineProtectionPresenter.present()
val linkState = linkPresenter.present() val linkState = linkPresenter.present()
val userEventPermissions by room.permissionsAsState(UserEventPermissions.DEFAULT) { perms -> val customReactionState = customReactionPresenter.present()
perms.userEventPermissions() val reactionSummaryState = reactionSummaryPresenter.present()
}
val displayThreadSummaries by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Threads).collectAsState(false) val displayThreadSummaries by featureFlagService.isFeatureEnabledFlow(FeatureFlags.Threads).collectAsState(false)
@@ -138,6 +145,7 @@ class PinnedMessagesListPresenter(
when (event) { when (event) {
is PinnedMessagesListEvent.HandleAction -> sessionCoroutineScope.handleTimelineAction(event.action, event.event) is PinnedMessagesListEvent.HandleAction -> sessionCoroutineScope.handleTimelineAction(event.action, event.event)
is PinnedMessagesListEvent.OpenThread -> navigator.navigateToThread(event.threadRootId) is PinnedMessagesListEvent.OpenThread -> navigator.navigateToThread(event.threadRootId)
is PinnedMessagesListEvent.ToggleReaction -> sessionCoroutineScope.toggleReaction(event.emoji, event.eventOrTransactionId)
} }
} }
@@ -148,10 +156,20 @@ class PinnedMessagesListPresenter(
displayThreadSummaries = displayThreadSummaries, displayThreadSummaries = displayThreadSummaries,
userEventPermissions = userEventPermissions, userEventPermissions = userEventPermissions,
timelineItems = pinnedMessageItems, timelineItems = pinnedMessageItems,
customReactionState = customReactionState,
reactionSummaryState = reactionSummaryState,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }
private fun CoroutineScope.toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId) {
launch {
timelineProvider.invokeOnTimeline {
toggleReaction(emoji, eventOrTransactionId)
}
}
}
private fun CoroutineScope.handleTimelineAction( private fun CoroutineScope.handleTimelineAction(
action: TimelineItemAction, action: TimelineItemAction,
targetEvent: TimelineItem.Event, targetEvent: TimelineItem.Event,
@@ -234,6 +252,8 @@ class PinnedMessagesListPresenter(
linkState: LinkState, linkState: LinkState,
userEventPermissions: UserEventPermissions, userEventPermissions: UserEventPermissions,
timelineItems: AsyncData<ImmutableList<TimelineItem>>, timelineItems: AsyncData<ImmutableList<TimelineItem>>,
customReactionState: CustomReactionState,
reactionSummaryState: ReactionSummaryState,
eventSink: (PinnedMessagesListEvent) -> Unit eventSink: (PinnedMessagesListEvent) -> Unit
): PinnedMessagesListState { ): PinnedMessagesListState {
return when (timelineItems) { return when (timelineItems) {
@@ -252,6 +272,8 @@ class PinnedMessagesListPresenter(
userEventPermissions = userEventPermissions, userEventPermissions = userEventPermissions,
timelineItems = timelineItems.data, timelineItems = timelineItems.data,
actionListState = actionListState, actionListState = actionListState,
customReactionState = customReactionState,
reactionSummaryState = reactionSummaryState,
eventSink = eventSink eventSink = eventSink
) )
} }
@@ -16,6 +16,8 @@ import io.element.android.features.messages.impl.UserEventPermissions
import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.ActionListState
import io.element.android.features.messages.impl.link.LinkState import io.element.android.features.messages.impl.link.LinkState
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
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.protection.TimelineProtectionState import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
import io.element.android.libraries.ui.strings.CommonPlurals import io.element.android.libraries.ui.strings.CommonPlurals
@@ -34,6 +36,8 @@ sealed interface PinnedMessagesListState {
val timelineItems: ImmutableList<TimelineItem>, val timelineItems: ImmutableList<TimelineItem>,
val actionListState: ActionListState, val actionListState: ActionListState,
val linkState: LinkState, val linkState: LinkState,
val customReactionState: CustomReactionState,
val reactionSummaryState: ReactionSummaryState,
val displayThreadSummaries: Boolean, val displayThreadSummaries: Boolean,
val eventSink: (PinnedMessagesListEvent) -> Unit, val eventSink: (PinnedMessagesListEvent) -> Unit,
) : PinnedMessagesListState { ) : PinnedMessagesListState {
@@ -10,6 +10,8 @@ package io.element.android.features.messages.impl.pinned.list
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.messages.impl.UserEventPermissions import io.element.android.features.messages.impl.UserEventPermissions
import io.element.android.features.messages.impl.aCustomReactionState
import io.element.android.features.messages.impl.aReactionSummaryState
import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.ActionListState
import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.actionlist.anActionListState
import io.element.android.features.messages.impl.link.LinkState import io.element.android.features.messages.impl.link.LinkState
@@ -19,6 +21,8 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemDaySepara
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.aTimelineItemReactions import io.element.android.features.messages.impl.timeline.aTimelineItemReactions
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
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.TimelineItemGroupPosition import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemAudioContent
@@ -92,6 +96,8 @@ fun aLoadedPinnedMessagesListState(
linkState: LinkState = aLinkState(), linkState: LinkState = aLinkState(),
timelineItems: List<TimelineItem> = emptyList(), timelineItems: List<TimelineItem> = emptyList(),
actionListState: ActionListState = anActionListState(), actionListState: ActionListState = anActionListState(),
customReactionState: CustomReactionState = aCustomReactionState(),
reactionSummaryState: ReactionSummaryState = aReactionSummaryState(),
aUserEventPermissions: UserEventPermissions = UserEventPermissions.DEFAULT, aUserEventPermissions: UserEventPermissions = UserEventPermissions.DEFAULT,
displayThreadSummaries: Boolean = false, displayThreadSummaries: Boolean = false,
eventSink: (PinnedMessagesListEvent) -> Unit = {} eventSink: (PinnedMessagesListEvent) -> Unit = {}
@@ -101,6 +107,8 @@ fun aLoadedPinnedMessagesListState(
linkState = linkState, linkState = linkState,
timelineItems = timelineItems.toImmutableList(), timelineItems = timelineItems.toImmutableList(),
actionListState = actionListState, actionListState = actionListState,
customReactionState = customReactionState,
reactionSummaryState = reactionSummaryState,
userEventPermissions = aUserEventPermissions, userEventPermissions = aUserEventPermissions,
displayThreadSummaries = displayThreadSummaries, displayThreadSummaries = displayThreadSummaries,
eventSink = eventSink, eventSink = eventSink,
@@ -33,8 +33,12 @@ import io.element.android.features.messages.impl.link.LinkEvent
import io.element.android.features.messages.impl.link.LinkView import io.element.android.features.messages.impl.link.LinkView
import io.element.android.features.messages.impl.timeline.TimelineEvent import io.element.android.features.messages.impl.timeline.TimelineEvent
import io.element.android.features.messages.impl.timeline.components.TimelineItemRow import io.element.android.features.messages.impl.timeline.components.TimelineItemRow
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionBottomSheet
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvent
import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView
import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvent
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryView
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.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
@@ -50,6 +54,8 @@ import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.utils.lazyColumnContentPadding import io.element.android.libraries.designsystem.utils.lazyColumnContentPadding
import io.element.android.libraries.designsystem.utils.scaffoldScrollableContentInsets import io.element.android.libraries.designsystem.utils.scaffoldScrollableContentInsets
import io.element.android.libraries.emoji.api.picker.EmojiPickerRenderer
import io.element.android.libraries.emoji.api.picker.NoOpEmojiPickerRenderer
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
@@ -66,6 +72,7 @@ fun PinnedMessagesListView(
onUserDataClick: (MatrixUser) -> Unit, onUserDataClick: (MatrixUser) -> Unit,
onLinkClick: (Link) -> Unit, onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit, onLinkLongClick: (Link) -> Unit,
emojiPickerRenderer: EmojiPickerRenderer,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Scaffold( Scaffold(
@@ -89,6 +96,7 @@ fun PinnedMessagesListView(
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onLinkLongClick = onLinkLongClick, onLinkLongClick = onLinkLongClick,
onErrorDismiss = onBackClick, onErrorDismiss = onBackClick,
emojiPickerRenderer = emojiPickerRenderer,
modifier = Modifier modifier = Modifier
.padding(padding) .padding(padding)
.consumeWindowInsets(padding), .consumeWindowInsets(padding),
@@ -121,6 +129,7 @@ private fun PinnedMessagesListContent(
onLinkClick: (Link) -> Unit, onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit, onLinkLongClick: (Link) -> Unit,
onErrorDismiss: () -> Unit, onErrorDismiss: () -> Unit,
emojiPickerRenderer: EmojiPickerRenderer,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Box(modifier.fillMaxSize()) { Box(modifier.fillMaxSize()) {
@@ -141,6 +150,7 @@ private fun PinnedMessagesListContent(
onUserDataClick = onUserDataClick, onUserDataClick = onUserDataClick,
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onLinkLongClick = onLinkLongClick, onLinkLongClick = onLinkLongClick,
emojiPickerRenderer = emojiPickerRenderer,
) )
PinnedMessagesListState.Loading -> { PinnedMessagesListState.Loading -> {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
@@ -180,6 +190,7 @@ private fun PinnedMessagesListLoaded(
onUserDataClick: (MatrixUser) -> Unit, onUserDataClick: (MatrixUser) -> Unit,
onLinkClick: (Link) -> Unit, onLinkClick: (Link) -> Unit,
onLinkLongClick: (Link) -> Unit, onLinkLongClick: (Link) -> Unit,
emojiPickerRenderer: EmojiPickerRenderer,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
fun onActionSelected(timelineItemAction: TimelineItemAction, event: TimelineItem.Event) { fun onActionSelected(timelineItemAction: TimelineItemAction, event: TimelineItem.Event) {
@@ -203,11 +214,25 @@ private fun PinnedMessagesListLoaded(
) )
} }
fun onReactionClick(emoji: String, event: TimelineItem.Event) {
state.eventSink(PinnedMessagesListEvent.ToggleReaction(emoji, event.eventOrTransactionId))
}
fun onReactionLongClick(emoji: String, event: TimelineItem.Event) {
event.eventId?.let { eventId ->
state.reactionSummaryState.eventSink(ReactionSummaryEvent.ShowReactionSummary(eventId, event.reactionsState.reactions, emoji))
}
}
fun onMoreReactionsClick(event: TimelineItem.Event) {
state.customReactionState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
}
ActionListView( ActionListView(
state = state.actionListState, state = state.actionListState,
onSelectAction = ::onActionSelected, onSelectAction = ::onActionSelected,
onCustomReactionClick = {}, onCustomReactionClick = ::onMoreReactionsClick,
onEmojiReactionClick = { _, _ -> }, onEmojiReactionClick = ::onReactionClick,
onVerifiedUserSendFailureClick = {} onVerifiedUserSendFailureClick = {}
) )
@@ -239,9 +264,9 @@ private fun PinnedMessagesListLoaded(
onLongClick = ::onMessageLongClick, onLongClick = ::onMessageLongClick,
displayThreadSummaries = displayThreadSummaries, displayThreadSummaries = displayThreadSummaries,
inReplyToClick = {}, inReplyToClick = {},
onReactionClick = { _, _ -> }, onReactionClick = ::onReactionClick,
onReactionLongClick = { _, _ -> }, onReactionLongClick = ::onReactionLongClick,
onMoreReactionsClick = {}, onMoreReactionsClick = ::onMoreReactionsClick,
onReadReceiptClick = {}, onReadReceiptClick = {},
onSwipeToReply = {}, onSwipeToReply = {},
onJoinCallClick = {}, onJoinCallClick = {},
@@ -273,6 +298,14 @@ private fun PinnedMessagesListLoaded(
state.linkState, state.linkState,
onLinkValid = onLinkClick, onLinkValid = onLinkClick,
) )
CustomReactionBottomSheet(
state = state.customReactionState,
onSelectEmoji = { eventOrTransactionId, emoji ->
state.eventSink(PinnedMessagesListEvent.ToggleReaction(emoji.unicode, eventOrTransactionId))
},
emojiPickerRenderer = emojiPickerRenderer,
)
ReactionSummaryView(state = state.reactionSummaryState)
} }
@Composable @Composable
@@ -322,5 +355,6 @@ internal fun PinnedMessagesListViewPreview(@PreviewParameter(PinnedMessagesListS
onUserDataClick = {}, onUserDataClick = {},
onLinkClick = {}, onLinkClick = {},
onLinkLongClick = {}, onLinkLongClick = {},
emojiPickerRenderer = NoOpEmojiPickerRenderer,
) )
} }
@@ -10,6 +10,8 @@ package io.element.android.features.messages.impl.pinned.list
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import im.vector.app.features.analytics.plan.PinUnpinAction import im.vector.app.features.analytics.plan.PinUnpinAction
import io.element.android.features.messages.impl.aCustomReactionState
import io.element.android.features.messages.impl.aReactionSummaryState
import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.actionlist.anActionListState
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
import io.element.android.features.messages.impl.fixtures.aTimelineItemsFactoryCreator import io.element.android.features.messages.impl.fixtures.aTimelineItemsFactoryCreator
@@ -400,6 +402,8 @@ class PinnedMessagesListPresenterTest {
snackbarDispatcher = SnackbarDispatcher(), snackbarDispatcher = SnackbarDispatcher(),
actionListPresenter = { anActionListState() }, actionListPresenter = { anActionListState() },
linkPresenter = { aLinkState() }, linkPresenter = { aLinkState() },
customReactionPresenter = { aCustomReactionState() },
reactionSummaryPresenter = { aReactionSummaryState() },
analyticsService = analyticsService, analyticsService = analyticsService,
featureFlagService = featureFlagService, featureFlagService = featureFlagService,
sessionCoroutineScope = this, sessionCoroutineScope = this,
@@ -24,6 +24,7 @@ import io.element.android.features.messages.impl.actionlist.anActionListState
import io.element.android.features.messages.impl.timeline.aTimelineItemList import io.element.android.features.messages.impl.timeline.aTimelineItemList
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.aTimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemFileContent
import io.element.android.libraries.emoji.api.picker.NoOpEmojiPickerRenderer
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EnsureNeverCalled
import io.element.android.tests.testutils.EnsureNeverCalledWithParam import io.element.android.tests.testutils.EnsureNeverCalledWithParam
@@ -111,6 +112,7 @@ private fun AndroidComposeUiTest<ComponentActivity>.setPinnedMessagesListView(
onUserDataClick = onUserDataClick, onUserDataClick = onUserDataClick,
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onLinkLongClick = onLinkLongClick, onLinkLongClick = onLinkLongClick,
emojiPickerRenderer = NoOpEmojiPickerRenderer,
) )
} }
} }