MessagesEvents -> MessagesEvent

This commit is contained in:
Benoit Marty 2026-01-27 09:38:45 +01:00
parent f184562d8f
commit a1e5afcdd5
8 changed files with 79 additions and 79 deletions

View file

@ -13,12 +13,12 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
sealed interface MessagesEvents { sealed interface MessagesEvent {
data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : MessagesEvents data class HandleAction(val action: TimelineItemAction, val event: TimelineItem.Event) : MessagesEvent
data class ToggleReaction(val emoji: String, val eventOrTransactionId: EventOrTransactionId) : MessagesEvents data class ToggleReaction(val emoji: String, val eventOrTransactionId: EventOrTransactionId) : MessagesEvent
data class InviteDialogDismissed(val action: InviteDialogAction) : MessagesEvents data class InviteDialogDismissed(val action: InviteDialogAction) : MessagesEvent
data class OnUserClicked(val user: MatrixUser) : MessagesEvents data class OnUserClicked(val user: MatrixUser) : MessagesEvent
data object MarkAsFullyReadAndExit : MessagesEvents data object MarkAsFullyReadAndExit : MessagesEvent
} }
enum class InviteDialogAction { enum class InviteDialogAction {

View file

@ -242,7 +242,7 @@ class MessagesNode(
val state = presenter.present() val state = presenter.present()
BackHandler { BackHandler {
state.eventSink(MessagesEvents.MarkAsFullyReadAndExit) state.eventSink(MessagesEvent.MarkAsFullyReadAndExit)
} }
OnLifecycleEvent { _, event -> OnLifecycleEvent { _, event ->
@ -253,7 +253,7 @@ class MessagesNode(
} }
MessagesView( MessagesView(
state = state, state = state,
onBackClick = { state.eventSink(MessagesEvents.MarkAsFullyReadAndExit) }, onBackClick = { state.eventSink(MessagesEvent.MarkAsFullyReadAndExit) },
onRoomDetailsClick = callback::navigateToRoomDetails, onRoomDetailsClick = callback::navigateToRoomDetails,
onEventContentClick = { isLive, event -> onEventContentClick = { isLive, event ->
if (isLive) { if (isLive) {

View file

@ -220,9 +220,9 @@ class MessagesPresenter(
onPauseOrDispose {} onPauseOrDispose {}
} }
fun handleEvent(event: MessagesEvents) { fun handleEvent(event: MessagesEvent) {
when (event) { when (event) {
is MessagesEvents.HandleAction -> { is MessagesEvent.HandleAction -> {
localCoroutineScope.handleTimelineAction( localCoroutineScope.handleTimelineAction(
action = event.action, action = event.action,
targetEvent = event.event, targetEvent = event.event,
@ -232,20 +232,20 @@ class MessagesPresenter(
timelineProtectionState = timelineProtectionState, timelineProtectionState = timelineProtectionState,
) )
} }
is MessagesEvents.ToggleReaction -> { is MessagesEvent.ToggleReaction -> {
localCoroutineScope.toggleReaction(event.emoji, event.eventOrTransactionId) localCoroutineScope.toggleReaction(event.emoji, event.eventOrTransactionId)
} }
is MessagesEvents.InviteDialogDismissed -> { is MessagesEvent.InviteDialogDismissed -> {
hasDismissedInviteDialog = true hasDismissedInviteDialog = true
if (event.action == InviteDialogAction.Invite) { if (event.action == InviteDialogAction.Invite) {
localCoroutineScope.reinviteOtherUser(inviteProgress) localCoroutineScope.reinviteOtherUser(inviteProgress)
} }
} }
is MessagesEvents.OnUserClicked -> { is MessagesEvent.OnUserClicked -> {
roomMemberModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.user)) roomMemberModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.user))
} }
is MessagesEvents.MarkAsFullyReadAndExit -> coroutineScope.launch { is MessagesEvent.MarkAsFullyReadAndExit -> coroutineScope.launch {
if (!markingAsReadAndExiting.getAndSet(true)) { if (!markingAsReadAndExiting.getAndSet(true)) {
val latestEventId = room.liveTimeline.getLatestEventId().getOrElse { val latestEventId = room.liveTimeline.getLatestEventId().getOrElse {
Timber.w(it, "Failed to get latest event id to mark as fully read") Timber.w(it, "Failed to get latest event id to mark as fully read")

View file

@ -57,7 +57,7 @@ data class MessagesState(
val dmUserVerificationState: IdentityState?, val dmUserVerificationState: IdentityState?,
val roomMemberModerationState: RoomMemberModerationState, val roomMemberModerationState: RoomMemberModerationState,
val successorRoom: SuccessorRoom?, val successorRoom: SuccessorRoom?,
val eventSink: (MessagesEvents) -> Unit val eventSink: (MessagesEvent) -> Unit
) { ) {
val isTombstoned = successorRoom != null val isTombstoned = successorRoom != null
} }

View file

@ -133,7 +133,7 @@ fun aMessagesState(
dmUserVerificationState: IdentityState? = null, dmUserVerificationState: IdentityState? = null,
roomMemberModerationState: RoomMemberModerationState = aRoomMemberModerationState(), roomMemberModerationState: RoomMemberModerationState = aRoomMemberModerationState(),
successorRoom: SuccessorRoom? = null, successorRoom: SuccessorRoom? = null,
eventSink: (MessagesEvents) -> Unit = {}, eventSink: (MessagesEvent) -> Unit = {},
) = MessagesState( ) = MessagesState(
roomId = RoomId("!id:domain"), roomId = RoomId("!id:domain"),
roomName = roomName, roomName = roomName,

View file

@ -178,11 +178,11 @@ fun MessagesView(
} }
fun onActionSelected(action: TimelineItemAction, event: TimelineItem.Event) { fun onActionSelected(action: TimelineItemAction, event: TimelineItem.Event) {
state.eventSink(MessagesEvents.HandleAction(action, event)) state.eventSink(MessagesEvent.HandleAction(action, event))
} }
fun onEmojiReactionClick(emoji: String, event: TimelineItem.Event) { fun onEmojiReactionClick(emoji: String, event: TimelineItem.Event) {
state.eventSink(MessagesEvents.ToggleReaction(emoji, event.eventOrTransactionId)) state.eventSink(MessagesEvent.ToggleReaction(emoji, event.eventOrTransactionId))
} }
fun onEmojiReactionLongClick(emoji: String, event: TimelineItem.Event) { fun onEmojiReactionLongClick(emoji: String, event: TimelineItem.Event) {
@ -244,7 +244,7 @@ fun MessagesView(
onMessageLongClick = ::onMessageLongClick, onMessageLongClick = ::onMessageLongClick,
onUserDataClick = { onUserDataClick = {
hidingKeyboard { hidingKeyboard {
state.eventSink(MessagesEvents.OnUserClicked(it)) state.eventSink(MessagesEvent.OnUserClicked(it))
} }
}, },
onLinkClick = { link, customTab -> onLinkClick = { link, customTab ->
@ -264,7 +264,7 @@ fun MessagesView(
onSendLocationClick = onSendLocationClick, onSendLocationClick = onSendLocationClick,
onCreatePollClick = onCreatePollClick, onCreatePollClick = onCreatePollClick,
onSwipeToReply = { targetEvent -> onSwipeToReply = { targetEvent ->
state.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, targetEvent)) state.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, targetEvent))
}, },
forceJumpToBottomVisibility = forceJumpToBottomVisibility, forceJumpToBottomVisibility = forceJumpToBottomVisibility,
onJoinCallClick = onJoinCallClick, onJoinCallClick = onJoinCallClick,
@ -378,7 +378,7 @@ fun MessagesView(
CustomReactionBottomSheet( CustomReactionBottomSheet(
state = state.customReactionState, state = state.customReactionState,
onSelectEmoji = { uniqueId, emoji -> onSelectEmoji = { uniqueId, emoji ->
state.eventSink(MessagesEvents.ToggleReaction(emoji.unicode, uniqueId)) state.eventSink(MessagesEvent.ToggleReaction(emoji.unicode, uniqueId))
} }
) )
@ -404,8 +404,8 @@ private fun ReinviteDialog(state: MessagesState) {
content = stringResource(id = R.string.screen_room_invite_again_alert_message), content = stringResource(id = R.string.screen_room_invite_again_alert_message),
cancelText = stringResource(id = CommonStrings.action_cancel), cancelText = stringResource(id = CommonStrings.action_cancel),
submitText = stringResource(id = CommonStrings.action_invite), submitText = stringResource(id = CommonStrings.action_invite),
onSubmitClick = { state.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) }, onSubmitClick = { state.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Invite)) },
onDismiss = { state.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Cancel)) } onDismiss = { state.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Cancel)) }
) )
} }
} }

View file

@ -185,14 +185,14 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
skipItems(1) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId())) initialState.eventSink(MessagesEvent.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle() advanceUntilIdle()
assert(toggleReactionSuccess) assert(toggleReactionSuccess)
.isCalledOnce() .isCalledOnce()
.with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId())) .with(value("👍"), value(AN_EVENT_ID.toEventOrTransactionId()))
// No crashes when sending a reaction failed // No crashes when sending a reaction failed
timeline.toggleReactionLambda = toggleReactionFailure timeline.toggleReactionLambda = toggleReactionFailure
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId())) initialState.eventSink(MessagesEvent.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle() advanceUntilIdle()
assert(toggleReactionFailure) assert(toggleReactionFailure)
.isCalledOnce() .isCalledOnce()
@ -230,8 +230,8 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId())) initialState.eventSink(MessagesEvent.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
initialState.eventSink(MessagesEvents.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId())) initialState.eventSink(MessagesEvent.ToggleReaction("👍", AN_EVENT_ID.toEventOrTransactionId()))
advanceUntilIdle() advanceUntilIdle()
assert(toggleReactionSuccess) assert(toggleReactionSuccess)
.isCalledExactly(2) .isCalledExactly(2)
@ -253,7 +253,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Forward, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
} }
@ -266,7 +266,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(clipboardHelper = clipboardHelper) val presenter = createMessagesPresenter(clipboardHelper = clipboardHelper)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.CopyText, event)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.CopyText, event))
skipItems(2) skipItems(2)
assertThat(clipboardHelper.clipboardContents).isEqualTo((event.content as TimelineItemTextContent).body) assertThat(clipboardHelper.clipboardContents).isEqualTo((event.content as TimelineItemTextContent).body)
} }
@ -289,7 +289,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.CopyLink, event)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.CopyLink, event))
skipItems(2) skipItems(2)
assertThat(clipboardHelper.clipboardContents).isEqualTo("a link") assertThat(clipboardHelper.clipboardContents).isEqualTo("a link")
} }
@ -303,7 +303,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, aMessageEvent()))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -321,7 +321,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter() val presenter = createMessagesPresenter()
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, aMessageEvent(eventId = null))) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, aMessageEvent(eventId = null)))
skipItems(1) skipItems(1)
} }
} }
@ -354,7 +354,7 @@ class MessagesPresenterTest {
formattedFileSize = "4MB" formattedFileSize = "4MB"
) )
) )
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, mediaMessage))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -396,7 +396,7 @@ class MessagesPresenterTest {
formattedFileSize = "50MB" formattedFileSize = "50MB"
) )
) )
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, mediaMessage))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -431,7 +431,7 @@ class MessagesPresenterTest {
fileExtension = "pdf", fileExtension = "pdf",
) )
) )
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, mediaMessage)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, mediaMessage))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -452,7 +452,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Edit, aMessageEvent()))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -474,7 +474,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EditPoll, aMessageEvent(content = aTimelineItemPollContent()))) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.EditPoll, aMessageEvent(content = aTimelineItemPollContent())))
awaitItem() awaitItem()
onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
} }
@ -486,7 +486,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(timelineEventSink = timelineEventSink) val presenter = createMessagesPresenter(timelineEventSink = timelineEventSink)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EndPoll, aMessageEvent(content = aTimelineItemPollContent()))) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.EndPoll, aMessageEvent(content = aTimelineItemPollContent())))
delay(1) delay(1)
timelineEventSink.assertSingle(TimelineEvents.EndPoll(AN_EVENT_ID)) timelineEventSink.assertSingle(TimelineEvents.EndPoll(AN_EVENT_ID))
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
@ -516,7 +516,7 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
val messageEvent = aMessageEvent() val messageEvent = aMessageEvent()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Redact, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Redact, messageEvent))
awaitItem() awaitItem()
assert(redactEventLambda) assert(redactEventLambda)
.isCalledOnce() .isCalledOnce()
@ -533,7 +533,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.ReportContent, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
onReportContentClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(A_USER_ID)) onReportContentClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(A_USER_ID))
} }
@ -548,7 +548,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(navigator = navigator) val presenter = createMessagesPresenter(navigator = navigator)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewSource, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.ViewSource, aMessageEvent()))
assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None)
onShowEventDebugInfoClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(aTimelineItemDebugInfo())) onShowEventDebugInfoClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(aTimelineItemDebugInfo()))
} }
@ -576,7 +576,7 @@ class MessagesPresenterTest {
val focusedState = awaitItem() val focusedState = awaitItem()
assertThat(focusedState.showReinvitePrompt).isTrue() assertThat(focusedState.showReinvitePrompt).isTrue()
// If it's dismissed then we stop showing the alert // If it's dismissed then we stop showing the alert
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Cancel)) initialState.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Cancel))
skipItems(1) skipItems(1)
val dismissedState = awaitItem() val dismissedState = awaitItem()
assertThat(dismissedState.showReinvitePrompt).isFalse() assertThat(dismissedState.showReinvitePrompt).isFalse()
@ -648,7 +648,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(joinedRoom = room) val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last() val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) initialState.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Invite))
skipItems(1) skipItems(1)
val loadingState = awaitItem() val loadingState = awaitItem()
assertThat(loadingState.inviteProgress.isLoading()).isTrue() assertThat(loadingState.inviteProgress.isLoading()).isTrue()
@ -680,7 +680,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(joinedRoom = room) val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last() val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) initialState.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Invite))
skipItems(1) skipItems(1)
val loadingState = consumeItemsUntilPredicate { state -> val loadingState = consumeItemsUntilPredicate { state ->
state.inviteProgress.isLoading() state.inviteProgress.isLoading()
@ -704,7 +704,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(joinedRoom = room) val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last() val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) initialState.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Invite))
skipItems(1) skipItems(1)
val loadingState = awaitItem() val loadingState = awaitItem()
assertThat(loadingState.inviteProgress.isLoading()).isTrue() assertThat(loadingState.inviteProgress.isLoading()).isTrue()
@ -733,7 +733,7 @@ class MessagesPresenterTest {
val presenter = createMessagesPresenter(joinedRoom = room) val presenter = createMessagesPresenter(joinedRoom = room)
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = consumeItemsUntilTimeout().last() val initialState = consumeItemsUntilTimeout().last()
initialState.eventSink(MessagesEvents.InviteDialogDismissed(InviteDialogAction.Invite)) initialState.eventSink(MessagesEvent.InviteDialogDismissed(InviteDialogAction.Invite))
val loadingState = consumeItemsUntilPredicate { state -> val loadingState = consumeItemsUntilPredicate { state ->
state.inviteProgress.isLoading() state.inviteProgress.isLoading()
@ -830,7 +830,7 @@ class MessagesPresenterTest {
val poll = aMessageEvent( val poll = aMessageEvent(
content = aTimelineItemPollContent() content = aTimelineItemPollContent()
) )
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Reply, poll)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Reply, poll))
skipItems(1) skipItems(1)
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -868,11 +868,11 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
timeline.pinEventLambda = successPinEventLambda timeline.pinEventLambda = successPinEventLambda
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Pin, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Pin, messageEvent))
assert(successPinEventLambda).isCalledOnce().with(value(messageEvent.eventId)) assert(successPinEventLambda).isCalledOnce().with(value(messageEvent.eventId))
timeline.pinEventLambda = failurePinEventLambda timeline.pinEventLambda = failurePinEventLambda
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Pin, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Pin, messageEvent))
assert(failurePinEventLambda).isCalledOnce().with(value(messageEvent.eventId)) assert(failurePinEventLambda).isCalledOnce().with(value(messageEvent.eventId))
skipItems(1) skipItems(1)
assertThat(awaitItem().snackbarMessage).isNotNull() assertThat(awaitItem().snackbarMessage).isNotNull()
@ -908,11 +908,11 @@ class MessagesPresenterTest {
val initialState = awaitItem() val initialState = awaitItem()
timeline.unpinEventLambda = successUnpinEventLambda timeline.unpinEventLambda = successUnpinEventLambda
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Unpin, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Unpin, messageEvent))
assert(successUnpinEventLambda).isCalledOnce().with(value(messageEvent.eventId)) assert(successUnpinEventLambda).isCalledOnce().with(value(messageEvent.eventId))
timeline.unpinEventLambda = failureUnpinEventLambda timeline.unpinEventLambda = failureUnpinEventLambda
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Unpin, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.Unpin, messageEvent))
assert(failureUnpinEventLambda).isCalledOnce().with(value(messageEvent.eventId)) assert(failureUnpinEventLambda).isCalledOnce().with(value(messageEvent.eventId))
skipItems(1) skipItems(1)
assertThat(awaitItem().snackbarMessage).isNotNull() assertThat(awaitItem().snackbarMessage).isNotNull()
@ -936,7 +936,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EditCaption, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.EditCaption, messageEvent))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -962,7 +962,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.AddCaption, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.AddCaption, messageEvent))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -1000,7 +1000,7 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
skipItems(1) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.RemoveCaption, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.RemoveCaption, messageEvent))
editCaptionLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID.toEventOrTransactionId()), value(null), value(null)) editCaptionLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID.toEventOrTransactionId()), value(null), value(null))
} }
} }
@ -1014,7 +1014,7 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
skipItems(1) skipItems(1)
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewInTimeline, messageEvent)) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.ViewInTimeline, messageEvent))
// No op! // No op!
} }
} }
@ -1108,7 +1108,7 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink( initialState.eventSink(
MessagesEvents.HandleAction( MessagesEvent.HandleAction(
action = TimelineItemAction.ReplyInThread, action = TimelineItemAction.ReplyInThread,
event = aMessageEvent(threadInfo = TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID)) event = aMessageEvent(threadInfo = TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
) )
@ -1130,7 +1130,7 @@ class MessagesPresenterTest {
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink( initialState.eventSink(
MessagesEvents.HandleAction( MessagesEvent.HandleAction(
action = TimelineItemAction.ReplyInThread, action = TimelineItemAction.ReplyInThread,
event = aMessageEvent( event = aMessageEvent(
// The event id will be used as the thread id instead // The event id will be used as the thread id instead
@ -1155,7 +1155,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ReplyInThread, aMessageEvent())) initialState.eventSink(MessagesEvent.HandleAction(TimelineItemAction.ReplyInThread, aMessageEvent()))
awaitItem() awaitItem()
composerRecorder.assertSingle( composerRecorder.assertSingle(
MessageComposerEvent.SetMode( MessageComposerEvent.SetMode(
@ -1182,7 +1182,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.MarkAsFullyReadAndExit) initialState.eventSink(MessagesEvent.MarkAsFullyReadAndExit)
runCurrent() runCurrent()
@ -1206,7 +1206,7 @@ class MessagesPresenterTest {
) )
presenter.testWithLifecycleOwner { presenter.testWithLifecycleOwner {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(MessagesEvents.MarkAsFullyReadAndExit) initialState.eventSink(MessagesEvent.MarkAsFullyReadAndExit)
runCurrent() runCurrent()

View file

@ -88,7 +88,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on back invoke expected callback`() { fun `clicking on back invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder eventSink = eventsRecorder
) )
@ -103,7 +103,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on room name invoke expected callback`() { fun `clicking on room name invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder eventSink = eventsRecorder
) )
@ -118,7 +118,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on join call invoke expected callback`() { fun `clicking on join call invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder eventSink = eventsRecorder
) )
@ -134,7 +134,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on an Event invoke expected callback`() { fun `clicking on an Event invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
timelineState = aTimelineState( timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()), timelineItems = aTimelineItemList(aTimelineItemTextContent()),
@ -253,7 +253,7 @@ class MessagesViewTest {
} }
private fun swipeTest(userHasPermissionToSendMessage: Boolean) { private fun swipeTest(userHasPermissionToSendMessage: Boolean) {
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val canBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = true) val canBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = true)
val cannotBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = false) val cannotBeRepliedEvent = aTimelineItemEvent(canBeRepliedTo = false)
val state = aMessagesState( val state = aMessagesState(
@ -273,7 +273,7 @@ class MessagesViewTest {
onLast().performTouchInput { swipeRight(endX = 200f) } onLast().performTouchInput { swipeRight(endX = 200f) }
} }
if (userHasPermissionToSendMessage) { if (userHasPermissionToSendMessage) {
eventsRecorder.assertSingle(MessagesEvents.HandleAction(TimelineItemAction.Reply, canBeRepliedEvent)) eventsRecorder.assertSingle(MessagesEvent.HandleAction(TimelineItemAction.Reply, canBeRepliedEvent))
} else { } else {
eventsRecorder.assertEmpty() eventsRecorder.assertEmpty()
} }
@ -281,7 +281,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on send location invoke expected callback`() { fun `clicking on send location invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
composerState = aMessageComposerState( composerState = aMessageComposerState(
showAttachmentSourcePicker = true showAttachmentSourcePicker = true
@ -299,7 +299,7 @@ class MessagesViewTest {
@Test @Test
fun `clicking on create poll invoke expected callback`() { fun `clicking on create poll invoke expected callback`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
composerState = aMessageComposerState( composerState = aMessageComposerState(
showAttachmentSourcePicker = true showAttachmentSourcePicker = true
@ -319,7 +319,7 @@ class MessagesViewTest {
@Test @Test
@Config(qualifiers = "h1024dp") @Config(qualifiers = "h1024dp")
fun `clicking on the avatar of the sender of an Event emits the expected event`() { fun `clicking on the avatar of the sender of an Event emits the expected event`() {
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder eventSink = eventsRecorder
) )
@ -327,7 +327,7 @@ class MessagesViewTest {
rule.setMessagesView(state = state) rule.setMessagesView(state = state)
rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick() rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
eventsRecorder.assertSingle( eventsRecorder.assertSingle(
MessagesEvents.OnUserClicked( MessagesEvent.OnUserClicked(
MatrixUser( MatrixUser(
userId = timelineEvent.senderId, userId = timelineEvent.senderId,
displayName = timelineEvent.senderProfile.getDisplayName(), displayName = timelineEvent.senderProfile.getDisplayName(),
@ -340,13 +340,13 @@ class MessagesViewTest {
@Test @Test
@Config(qualifiers = "h1024dp") @Config(qualifiers = "h1024dp")
fun `clicking on the display name of the sender of an Event emits expected event`() { fun `clicking on the display name of the sender of an Event emits expected event`() {
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState(eventSink = eventsRecorder) val state = aMessagesState(eventSink = eventsRecorder)
val timelineEvent = state.timelineState.timelineItems.filterIsInstance<TimelineItem.Event>().first() val timelineEvent = state.timelineState.timelineItems.filterIsInstance<TimelineItem.Event>().first()
rule.setMessagesView(state = state) rule.setMessagesView(state = state)
rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick() rule.onNodeWithTag(TestTags.timelineItemSenderAvatar.value, useUnmergedTree = true).performClick()
eventsRecorder.assertSingle( eventsRecorder.assertSingle(
MessagesEvents.OnUserClicked( MessagesEvent.OnUserClicked(
MatrixUser( MatrixUser(
userId = timelineEvent.senderId, userId = timelineEvent.senderId,
displayName = timelineEvent.senderProfile.getDisplayName(), displayName = timelineEvent.senderProfile.getDisplayName(),
@ -358,7 +358,7 @@ class MessagesViewTest {
@Test @Test
fun `selecting a action on a message emits the expected Event`() { fun `selecting a action on a message emits the expected Event`() {
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder eventSink = eventsRecorder
) )
@ -381,12 +381,12 @@ class MessagesViewTest {
rule.clickOn(CommonStrings.action_edit) rule.clickOn(CommonStrings.action_edit)
// 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(MessagesEvents.HandleAction(TimelineItemAction.Edit, timelineItem)) eventsRecorder.assertSingle(MessagesEvent.HandleAction(TimelineItemAction.Edit, timelineItem))
} }
@Test @Test
fun `clicking on a reaction emits the expected Event`() { fun `clicking on a reaction emits the expected Event`() {
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState( val state = aMessagesState(
timelineState = aTimelineState( timelineState = aTimelineState(
timelineItems = aTimelineItemList(aTimelineItemTextContent()), timelineItems = aTimelineItemList(aTimelineItemTextContent()),
@ -401,7 +401,7 @@ class MessagesViewTest {
text = "👍️", text = "👍️",
useUnmergedTree = true, useUnmergedTree = true,
).onFirst().performClick() ).onFirst().performClick()
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction("👍️", timelineItem.eventOrTransactionId)) eventsRecorder.assertSingle(MessagesEvent.ToggleReaction("👍️", timelineItem.eventOrTransactionId))
} }
@Test @Test
@ -513,7 +513,7 @@ class MessagesViewTest {
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<CustomReactionEvents>()
val eventsRecorder = EventsRecorder<MessagesEvents>() val eventsRecorder = EventsRecorder<MessagesEvent>()
val state = aMessagesState( val state = aMessagesState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
) )
@ -547,7 +547,7 @@ class MessagesViewTest {
// 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(CustomReactionEvents.DismissCustomReactionSheet)
eventsRecorder.assertSingle(MessagesEvents.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId)) eventsRecorder.assertSingle(MessagesEvent.ToggleReaction(aUnicode, timelineItem.eventOrTransactionId))
} }
@Test @Test
@ -589,7 +589,7 @@ class MessagesViewTest {
@Test @Test
fun `no banner shown when there is no successor room`() { fun `no banner shown when there is no successor room`() {
val eventsRecorder = EventsRecorder<MessagesEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<MessagesEvent>(expectEvents = false)
val state = aMessagesState( val state = aMessagesState(
successorRoom = null, successorRoom = null,
eventSink = eventsRecorder eventSink = eventsRecorder