mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
Merge pull request #6676 from bxdxnn/misc/reactions-pinned-messages
Show reactions in the pinned messages list
This commit is contained in:
+2
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-5
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -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 {
|
||||||
|
|||||||
+8
@@ -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,
|
||||||
|
|||||||
+39
-5
@@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -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,
|
||||||
|
|||||||
+2
@@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user