CustomReactionEvents -> CustomReactionEvent

This commit is contained in:
Benoit Marty 2026-01-27 10:01:38 +01:00
parent 60b261cd61
commit cca2fa5ccc
8 changed files with 24 additions and 24 deletions

View file

@ -28,7 +28,7 @@ import io.element.android.features.messages.impl.pinned.banner.aLoadedPinnedMess
import io.element.android.features.messages.impl.timeline.TimelineState import io.element.android.features.messages.impl.timeline.TimelineState
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.aTimelineState import io.element.android.features.messages.impl.timeline.aTimelineState
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvent
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState
@ -196,7 +196,7 @@ fun aReactionSummaryState(
fun aCustomReactionState( fun aCustomReactionState(
target: CustomReactionState.Target = CustomReactionState.Target.None, target: CustomReactionState.Target = CustomReactionState.Target.None,
recentEmojis: ImmutableList<String> = persistentListOf(), recentEmojis: ImmutableList<String> = persistentListOf(),
eventSink: (CustomReactionEvents) -> Unit = {}, eventSink: (CustomReactionEvent) -> Unit = {},
) = CustomReactionState( ) = CustomReactionState(
target = target, target = target,
recentEmojis = recentEmojis, recentEmojis = recentEmojis,

View file

@ -75,7 +75,7 @@ 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.aTimelineState import io.element.android.features.messages.impl.timeline.aTimelineState
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionBottomSheet import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionBottomSheet
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvent
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryView import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryView
import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheet import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheet
@ -191,7 +191,7 @@ fun MessagesView(
} }
fun onMoreReactionsClick(event: TimelineItem.Event) { fun onMoreReactionsClick(event: TimelineItem.Event) {
state.customReactionState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) state.customReactionState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
} }
val expandableState = rememberExpandableBottomSheetLayoutState() val expandableState = rememberExpandableBottomSheetLayoutState()
@ -367,7 +367,7 @@ fun MessagesView(
} }
}, },
onCustomReactionClick = { event -> onCustomReactionClick = { event ->
state.customReactionState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) state.customReactionState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
}, },
onEmojiReactionClick = ::onEmojiReactionClick, onEmojiReactionClick = ::onEmojiReactionClick,
onVerifiedUserSendFailureClick = { event -> onVerifiedUserSendFailureClick = { event ->

View file

@ -35,13 +35,13 @@ fun CustomReactionBottomSheet(
val target = state.target as? CustomReactionState.Target.Success val target = state.target as? CustomReactionState.Target.Success
fun onDismiss() { fun onDismiss() {
state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
} }
fun onEmojiSelectedDismiss(emoji: Emoji) { fun onEmojiSelectedDismiss(emoji: Emoji) {
if (target?.event == null) return if (target?.event == null) return
sheetState.hide(coroutineScope) { sheetState.hide(coroutineScope) {
state.eventSink(CustomReactionEvents.DismissCustomReactionSheet) state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
onSelectEmoji(target.event.eventOrTransactionId, emoji) onSelectEmoji(target.event.eventOrTransactionId, emoji)
} }
} }

View file

@ -10,7 +10,7 @@ package io.element.android.features.messages.impl.timeline.components.customreac
import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.TimelineItem
sealed interface CustomReactionEvents { sealed interface CustomReactionEvent {
data class ShowCustomReactionSheet(val event: TimelineItem.Event) : CustomReactionEvents data class ShowCustomReactionSheet(val event: TimelineItem.Event) : CustomReactionEvent
data object DismissCustomReactionSheet : CustomReactionEvents data object DismissCustomReactionSheet : CustomReactionEvent
} }

View file

@ -54,10 +54,10 @@ class CustomReactionPresenter(
target.value = CustomReactionState.Target.None target.value = CustomReactionState.Target.None
} }
fun handleEvent(event: CustomReactionEvents) { fun handleEvent(event: CustomReactionEvent) {
when (event) { when (event) {
is CustomReactionEvents.ShowCustomReactionSheet -> handleShowCustomReactionSheet(event.event) is CustomReactionEvent.ShowCustomReactionSheet -> handleShowCustomReactionSheet(event.event)
is CustomReactionEvents.DismissCustomReactionSheet -> handleDismissCustomReactionSheet() is CustomReactionEvent.DismissCustomReactionSheet -> handleDismissCustomReactionSheet()
} }
} }
val event = (target.value as? CustomReactionState.Target.Success)?.event val event = (target.value as? CustomReactionState.Target.Success)?.event

View file

@ -17,7 +17,7 @@ data class CustomReactionState(
val target: Target, val target: Target,
val selectedEmoji: ImmutableSet<String>, val selectedEmoji: ImmutableSet<String>,
val recentEmojis: ImmutableList<String>, val recentEmojis: ImmutableList<String>,
val eventSink: (CustomReactionEvents) -> Unit, val eventSink: (CustomReactionEvent) -> Unit,
) { ) {
sealed interface Target { sealed interface Target {
data object None : Target data object None : Target

View file

@ -46,7 +46,7 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemList
import io.element.android.features.messages.impl.timeline.aTimelineItemReadReceipts import io.element.android.features.messages.impl.timeline.aTimelineItemReadReceipts
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.aTimelineState import io.element.android.features.messages.impl.timeline.aTimelineState
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvents import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionEvent
import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState
import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents
import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData
@ -429,7 +429,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on more reaction emits the expected Event`() { fun `clicking on more reaction emits the expected Event`() {
val eventsRecorder = EventsRecorder<CustomReactionEvents>() val eventsRecorder = EventsRecorder<CustomReactionEvent>()
val state = aMessagesState( val state = aMessagesState(
timelineState = aTimelineState( timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()), timelineItems = aTimelineItemList(aTimelineItemTextContent()),
@ -444,12 +444,12 @@ class MessagesViewTest {
) )
val moreReactionContentDescription = rule.activity.getString(R.string.screen_room_timeline_add_reaction) val moreReactionContentDescription = rule.activity.getString(R.string.screen_room_timeline_add_reaction)
rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick() rule.onAllNodesWithContentDescription(moreReactionContentDescription).onFirst().performClick()
eventsRecorder.assertSingle(CustomReactionEvents.ShowCustomReactionSheet(timelineItem)) eventsRecorder.assertSingle(CustomReactionEvent.ShowCustomReactionSheet(timelineItem))
} }
@Test @Test
fun `clicking on more reaction from action list emits the expected Event`() { fun `clicking on more reaction from action list emits the expected Event`() {
val eventsRecorder = EventsRecorder<CustomReactionEvents>() val eventsRecorder = EventsRecorder<CustomReactionEvent>()
val state = aMessagesState( val state = aMessagesState(
timelineState = aTimelineState( timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()), timelineItems = aTimelineItemList(aTimelineItemTextContent()),
@ -478,7 +478,7 @@ class MessagesViewTest {
rule.onNodeWithContentDescription(moreReactionContentDescription).performClick() rule.onNodeWithContentDescription(moreReactionContentDescription).performClick()
// Give time for the close animation to complete // Give time for the close animation to complete
rule.mainClock.advanceTimeBy(milliseconds = 1_000) rule.mainClock.advanceTimeBy(milliseconds = 1_000)
eventsRecorder.assertSingle(CustomReactionEvents.ShowCustomReactionSheet(timelineItem)) eventsRecorder.assertSingle(CustomReactionEvent.ShowCustomReactionSheet(timelineItem))
} }
@Test @Test
@ -512,7 +512,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on a custom emoji emits the expected Events`() { fun `clicking on a custom emoji emits the expected Events`() {
val aUnicode = "🙈" val aUnicode = "🙈"
val customReactionStateEventsRecorder = EventsRecorder<CustomReactionEvents>() val customReactionStateEventsRecorder = EventsRecorder<CustomReactionEvent>()
val eventsRecorder = EventsRecorder<MessagesEvent>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -546,7 +546,7 @@ class MessagesViewTest {
rule.onNodeWithText(aUnicode, useUnmergedTree = true).performClick() rule.onNodeWithText(aUnicode, useUnmergedTree = true).performClick()
// Give time for the close animation to complete // Give time for the close animation to complete
rule.mainClock.advanceTimeBy(milliseconds = 1_000) rule.mainClock.advanceTimeBy(milliseconds = 1_000)
customReactionStateEventsRecorder.assertSingle(CustomReactionEvents.DismissCustomReactionSheet) customReactionStateEventsRecorder.assertSingle(CustomReactionEvent.DismissCustomReactionSheet)
eventsRecorder.assertSingle(MessagesEvent.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId)) eventsRecorder.assertSingle(MessagesEvent.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId))
} }

View file

@ -40,14 +40,14 @@ class CustomReactionPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None) assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None)
initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event)) assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event))
val eventId = (awaitItem().target as? CustomReactionState.Target.Success)?.event?.eventId val eventId = (awaitItem().target as? CustomReactionState.Target.Success)?.event?.eventId
assertThat(eventId).isEqualTo(AN_EVENT_ID) assertThat(eventId).isEqualTo(AN_EVENT_ID)
initialState.eventSink(CustomReactionEvents.DismissCustomReactionSheet) initialState.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.None) assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.None)
} }
} }
@ -63,7 +63,7 @@ class CustomReactionPresenterTest {
assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None) assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None)
val key = reactions.reactions.first().key val key = reactions.reactions.first().key
initialState.eventSink(CustomReactionEvents.ShowCustomReactionSheet(event)) initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event)) assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event))