Browse Source

Refacto: move `displayEmojiReactions` to `ActionListState.Target.Success`

pull/2115/head
Benoit Marty 9 months ago
parent
commit
29d23cbeee
  1. 18
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt
  2. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListState.kt
  3. 12
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt
  4. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt
  5. 1
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt
  6. 82
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt

18
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt

@ -19,7 +19,6 @@ package io.element.android.features.messages.impl.actionlist
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -53,13 +52,6 @@ class ActionListPresenter @Inject constructor(
val isDeveloperModeEnabled by preferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false) val isDeveloperModeEnabled by preferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false)
val displayEmojiReactions by remember {
derivedStateOf {
val event = (target.value as? ActionListState.Target.Success)?.event
event?.isRemote == true && event.content.canReact()
}
}
fun handleEvents(event: ActionListEvents) { fun handleEvents(event: ActionListEvents) {
when (event) { when (event) {
ActionListEvents.Clear -> target.value = ActionListState.Target.None ActionListEvents.Clear -> target.value = ActionListState.Target.None
@ -75,7 +67,6 @@ class ActionListPresenter @Inject constructor(
return ActionListState( return ActionListState(
target = target.value, target = target.value,
displayEmojiReactions = displayEmojiReactions,
eventSink = { handleEvents(it) } eventSink = { handleEvents(it) }
) )
} }
@ -178,8 +169,13 @@ class ActionListPresenter @Inject constructor(
} }
} }
} }
if (actions.isNotEmpty()) { val displayEmojiReactions = timelineItem.isRemote && timelineItem.content.canReact()
target.value = ActionListState.Target.Success(timelineItem, actions.toImmutableList()) if (actions.isNotEmpty() || displayEmojiReactions) {
target.value = ActionListState.Target.Success(
event = timelineItem,
displayEmojiReactions = displayEmojiReactions,
actions = actions.toImmutableList()
)
} else { } else {
target.value = ActionListState.Target.None target.value = ActionListState.Target.None
} }

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListState.kt

@ -24,7 +24,6 @@ import kotlinx.collections.immutable.ImmutableList
@Immutable @Immutable
data class ActionListState( data class ActionListState(
val target: Target, val target: Target,
val displayEmojiReactions: Boolean,
val eventSink: (ActionListEvents) -> Unit, val eventSink: (ActionListEvents) -> Unit,
) { ) {
sealed interface Target { sealed interface Target {
@ -32,6 +31,7 @@ data class ActionListState(
data class Loading(val event: TimelineItem.Event) : Target data class Loading(val event: TimelineItem.Event) : Target
data class Success( data class Success(
val event: TimelineItem.Event, val event: TimelineItem.Event,
val displayEmojiReactions: Boolean,
val actions: ImmutableList<TimelineItemAction>, val actions: ImmutableList<TimelineItemAction>,
) : Target ) : Target
} }

12
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt

@ -42,6 +42,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent().copy( event = aTimelineItemEvent().copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -50,6 +51,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemImageContent()).copy( event = aTimelineItemEvent(content = aTimelineItemImageContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -58,6 +60,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemVideoContent()).copy( event = aTimelineItemEvent(content = aTimelineItemVideoContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -66,6 +69,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemFileContent()).copy( event = aTimelineItemEvent(content = aTimelineItemFileContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -74,6 +78,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy( event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -82,6 +87,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy( event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -90,6 +96,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy( event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = true,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
) )
), ),
@ -98,18 +105,18 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy( event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = false,
actions = aTimelineItemActionList(), actions = aTimelineItemActionList(),
), ),
displayEmojiReactions = false,
), ),
anActionListState().copy( anActionListState().copy(
target = ActionListState.Target.Success( target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemPollContent()).copy( event = aTimelineItemEvent(content = aTimelineItemPollContent()).copy(
reactionsState = reactionsState reactionsState = reactionsState
), ),
displayEmojiReactions = false,
actions = aTimelineItemPollActionList(), actions = aTimelineItemPollActionList(),
), ),
displayEmojiReactions = false,
), ),
) )
} }
@ -117,7 +124,6 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
fun anActionListState() = ActionListState( fun anActionListState() = ActionListState(
target = ActionListState.Target.None, target = ActionListState.Target.None,
displayEmojiReactions = true,
eventSink = {} eventSink = {}
) )

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt

@ -179,7 +179,7 @@ private fun SheetContent(
HorizontalDivider() HorizontalDivider()
} }
} }
if (state.displayEmojiReactions) { if (target.displayEmojiReactions) {
item { item {
EmojiReactionsRow( EmojiReactionsRow(
highlightedEmojis = target.event.reactionsState.highlightedKeys, highlightedEmojis = target.event.reactionsState.highlightedKeys,

1
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt

@ -47,6 +47,7 @@ fun TimelineItemEventContent.canBeRepliedTo(): Boolean =
/** /**
* Return true if user can react (i.e. send a reaction) on the event content. * Return true if user can react (i.e. send a reaction) on the event content.
* This does not take into account the power level of the user.
*/ */
fun TimelineItemEventContent.canReact(): Boolean = fun TimelineItemEventContent.canReact(): Boolean =
when (this) { when (this) {

82
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt

@ -68,8 +68,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = false,
actions = persistentListOf(
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
) )
) )
@ -93,8 +94,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = false,
actions = persistentListOf(
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
) )
) )
@ -121,8 +123,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Copy, TimelineItemAction.Copy,
@ -153,8 +156,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Copy, TimelineItemAction.Copy,
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
@ -182,8 +186,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Copy, TimelineItemAction.Copy,
@ -215,8 +220,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Edit, TimelineItemAction.Edit,
@ -248,8 +254,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
@ -279,8 +286,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
stateEvent, event = stateEvent,
persistentListOf( displayEmojiReactions = false,
actions = persistentListOf(
TimelineItemAction.Copy, TimelineItemAction.Copy,
TimelineItemAction.ViewSource, TimelineItemAction.ViewSource,
) )
@ -308,8 +316,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
stateEvent, event = stateEvent,
persistentListOf( displayEmojiReactions = false,
actions = persistentListOf(
TimelineItemAction.Copy, TimelineItemAction.Copy,
) )
) )
@ -336,8 +345,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Edit, TimelineItemAction.Edit,
@ -373,7 +383,6 @@ class ActionListPresenterTest {
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, canRedact = false, canSendMessage = true)) initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, canRedact = false, canSendMessage = true))
awaitItem().run { awaitItem().run {
assertThat(target).isEqualTo(ActionListState.Target.None) assertThat(target).isEqualTo(ActionListState.Target.None)
assertThat(displayEmojiReactions).isFalse()
} }
} }
} }
@ -395,15 +404,15 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = false,
actions = persistentListOf(
TimelineItemAction.Edit, TimelineItemAction.Edit,
TimelineItemAction.Copy, TimelineItemAction.Copy,
TimelineItemAction.Redact, TimelineItemAction.Redact,
) )
) )
) )
assertThat(successState.displayEmojiReactions).isFalse()
} }
} }
@ -423,8 +432,9 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Edit, TimelineItemAction.Edit,
TimelineItemAction.EndPoll, TimelineItemAction.EndPoll,
@ -432,9 +442,9 @@ class ActionListPresenterTest {
) )
) )
) )
assertThat(successState.displayEmojiReactions).isTrue()
} }
} }
@Test @Test
fun `present - compute for non-editable poll message`() = runTest { fun `present - compute for non-editable poll message`() = runTest {
val presenter = createActionListPresenter(isDeveloperModeEnabled = false) val presenter = createActionListPresenter(isDeveloperModeEnabled = false)
@ -451,15 +461,15 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.EndPoll, TimelineItemAction.EndPoll,
TimelineItemAction.Redact, TimelineItemAction.Redact,
) )
) )
) )
assertThat(successState.displayEmojiReactions).isTrue()
} }
} }
@ -479,14 +489,14 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Redact, TimelineItemAction.Redact,
) )
) )
) )
assertThat(successState.displayEmojiReactions).isTrue()
} }
} }
@ -505,15 +515,15 @@ class ActionListPresenterTest {
val successState = awaitItem() val successState = awaitItem()
assertThat(successState.target).isEqualTo( assertThat(successState.target).isEqualTo(
ActionListState.Target.Success( ActionListState.Target.Success(
messageEvent, event = messageEvent,
persistentListOf( displayEmojiReactions = true,
actions = persistentListOf(
TimelineItemAction.Reply, TimelineItemAction.Reply,
TimelineItemAction.Forward, TimelineItemAction.Forward,
TimelineItemAction.Redact, TimelineItemAction.Redact,
) )
) )
) )
assertThat(successState.displayEmojiReactions).isTrue()
} }
} }
} }

Loading…
Cancel
Save