mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 21:32:34 +00:00
Migrate EmojiPickerPresenter to assisted-factory pattern with EmptyGetRecentEmojis
This commit is contained in:
-2
@@ -37,7 +37,6 @@ fun CustomReactionBottomSheet(
|
|||||||
CustomReactionState.Target.None,
|
CustomReactionState.Target.None,
|
||||||
is CustomReactionState.Target.Loading -> Unit
|
is CustomReactionState.Target.Loading -> Unit
|
||||||
is CustomReactionState.Target.Success -> {
|
is CustomReactionState.Target.Success -> {
|
||||||
|
|
||||||
fun onEmojiSelectedDismiss(emoji: Emoji) {
|
fun onEmojiSelectedDismiss(emoji: Emoji) {
|
||||||
sheetState.hide(coroutineScope) {
|
sheetState.hide(coroutineScope) {
|
||||||
state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
|
state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
|
||||||
@@ -49,7 +48,6 @@ fun CustomReactionBottomSheet(
|
|||||||
state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
|
state.eventSink(CustomReactionEvent.DismissCustomReactionSheet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ModalBottomSheet(
|
ModalBottomSheet(
|
||||||
onDismissRequest = ::onDismiss,
|
onDismissRequest = ::onDismiss,
|
||||||
sheetState = sheetState,
|
sheetState = sheetState,
|
||||||
|
|||||||
+4
-1
@@ -17,12 +17,15 @@ import dev.zacsweers.metro.Inject
|
|||||||
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.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.emoji.api.picker.EmojiPickerPresenter
|
import io.element.android.libraries.emoji.api.picker.EmojiPickerPresenter
|
||||||
|
import io.element.android.libraries.emoji.api.recentemojis.GetRecentEmojis
|
||||||
import kotlinx.collections.immutable.toImmutableSet
|
import kotlinx.collections.immutable.toImmutableSet
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
class CustomReactionPresenter(
|
class CustomReactionPresenter(
|
||||||
private val emojiPickerPresenter: EmojiPickerPresenter,
|
emojiPickerPresenterFactory: EmojiPickerPresenter.Factory,
|
||||||
|
getRecentEmojis: GetRecentEmojis,
|
||||||
) : Presenter<CustomReactionState> {
|
) : Presenter<CustomReactionState> {
|
||||||
|
private val emojiPickerPresenter = emojiPickerPresenterFactory.create(getRecentEmojis)
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): CustomReactionState {
|
override fun present(): CustomReactionState {
|
||||||
var internalTarget by remember { mutableStateOf<InternalTarget>(InternalTarget.None) }
|
var internalTarget by remember { mutableStateOf<InternalTarget>(InternalTarget.None) }
|
||||||
|
|||||||
+4
-5
@@ -11,6 +11,8 @@ package io.element.android.features.messages.impl.timeline.components.customreac
|
|||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
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.libraries.emoji.api.picker.EmojiPickerPresenter
|
||||||
|
import io.element.android.libraries.emoji.api.recentemojis.EmptyGetRecentEmojis
|
||||||
import io.element.android.libraries.emoji.impl.picker.anEmojiPickerState
|
import io.element.android.libraries.emoji.impl.picker.anEmojiPickerState
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
@@ -24,7 +26,8 @@ class CustomReactionPresenterTest {
|
|||||||
val warmUpRule = WarmUpRule()
|
val warmUpRule = WarmUpRule()
|
||||||
|
|
||||||
private val presenter = CustomReactionPresenter(
|
private val presenter = CustomReactionPresenter(
|
||||||
emojiPickerPresenter = { anEmojiPickerState() },
|
emojiPickerPresenterFactory = EmojiPickerPresenter.Factory { EmojiPickerPresenter { anEmojiPickerState() } },
|
||||||
|
getRecentEmojis = EmptyGetRecentEmojis,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -36,8 +39,6 @@ class CustomReactionPresenterTest {
|
|||||||
|
|
||||||
initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
|
initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(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)
|
||||||
|
|
||||||
@@ -57,8 +58,6 @@ class CustomReactionPresenterTest {
|
|||||||
val key = reactions.reactions.first().key
|
val key = reactions.reactions.first().key
|
||||||
initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
|
initialState.eventSink(CustomReactionEvent.ShowCustomReactionSheet(event))
|
||||||
|
|
||||||
assertThat(awaitItem().target).isEqualTo(CustomReactionState.Target.Loading(event))
|
|
||||||
|
|
||||||
val stateWithSelectedEmojis = awaitItem()
|
val stateWithSelectedEmojis = awaitItem()
|
||||||
val eventId = (stateWithSelectedEmojis.target as? CustomReactionState.Target.Success)?.event?.eventId
|
val eventId = (stateWithSelectedEmojis.target as? CustomReactionState.Target.Success)?.event?.eventId
|
||||||
assertThat(eventId).isEqualTo(AN_EVENT_ID)
|
assertThat(eventId).isEqualTo(AN_EVENT_ID)
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ dependencies {
|
|||||||
implementation(projects.libraries.matrix.api)
|
implementation(projects.libraries.matrix.api)
|
||||||
|
|
||||||
implementation(libs.kotlinx.collections.immutable)
|
implementation(libs.kotlinx.collections.immutable)
|
||||||
implementation(libs.matrix.emojibase.bindings)
|
api(libs.matrix.emojibase.bindings)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -8,5 +8,10 @@
|
|||||||
package io.element.android.libraries.emoji.api.picker
|
package io.element.android.libraries.emoji.api.picker
|
||||||
|
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
import io.element.android.libraries.emoji.api.recentemojis.GetRecentEmojis
|
||||||
|
|
||||||
fun interface EmojiPickerPresenter : Presenter<EmojiPickerState>
|
fun interface EmojiPickerPresenter : Presenter<EmojiPickerState> {
|
||||||
|
fun interface Factory {
|
||||||
|
fun create(getRecentEmojis: GetRecentEmojis): EmojiPickerPresenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+9
@@ -9,6 +9,7 @@
|
|||||||
package io.element.android.libraries.emoji.api.recentemojis
|
package io.element.android.libraries.emoji.api.recentemojis
|
||||||
|
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of recently used emojis for reactions.
|
* Returns the list of recently used emojis for reactions.
|
||||||
@@ -16,3 +17,11 @@ import kotlinx.collections.immutable.ImmutableList
|
|||||||
fun interface GetRecentEmojis {
|
fun interface GetRecentEmojis {
|
||||||
suspend operator fun invoke(): Result<ImmutableList<String>>
|
suspend operator fun invoke(): Result<ImmutableList<String>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [GetRecentEmojis] that never returns any recent emojis. Handy for pickers that don't want
|
||||||
|
* a "Recent" tab (e.g. the user-status picker).
|
||||||
|
*/
|
||||||
|
object EmptyGetRecentEmojis : GetRecentEmojis {
|
||||||
|
override suspend fun invoke(): Result<ImmutableList<String>> = Result.success(persistentListOf())
|
||||||
|
}
|
||||||
|
|||||||
+14
-5
@@ -17,8 +17,10 @@ import androidx.compose.runtime.produceState
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalInspectionMode
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
|
import dev.zacsweers.metro.Assisted
|
||||||
|
import dev.zacsweers.metro.AssistedFactory
|
||||||
|
import dev.zacsweers.metro.AssistedInject
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
|
||||||
import io.element.android.emojibasebindings.Emoji
|
import io.element.android.emojibasebindings.Emoji
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.designsystem.theme.components.IconSource
|
import io.element.android.libraries.designsystem.theme.components.IconSource
|
||||||
@@ -37,13 +39,18 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
@Inject
|
@AssistedInject
|
||||||
@ContributesBinding(SessionScope::class)
|
|
||||||
class DefaultEmojiPickerPresenter(
|
class DefaultEmojiPickerPresenter(
|
||||||
private val emojibaseProvider: EmojibaseProvider,
|
private val emojibaseProvider: EmojibaseProvider,
|
||||||
private val getRecentEmojis: GetRecentEmojis,
|
@Assisted private val getRecentEmojis: GetRecentEmojis,
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
) : EmojiPickerPresenter {
|
) : EmojiPickerPresenter {
|
||||||
|
@AssistedFactory
|
||||||
|
@ContributesBinding(SessionScope::class)
|
||||||
|
interface Factory : EmojiPickerPresenter.Factory {
|
||||||
|
override fun create(getRecentEmojis: GetRecentEmojis): DefaultEmojiPickerPresenter
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): EmojiPickerState {
|
override fun present(): EmojiPickerState {
|
||||||
val queryState = rememberTextFieldState()
|
val queryState = rememberTextFieldState()
|
||||||
@@ -86,7 +93,9 @@ class DefaultEmojiPickerPresenter(
|
|||||||
val searchQuery = queryState.text.toString()
|
val searchQuery = queryState.text.toString()
|
||||||
LaunchedEffect(searchQuery, data) {
|
LaunchedEffect(searchQuery, data) {
|
||||||
if (searchQuery.isEmpty() || data.allEmojis.isEmpty()) {
|
if (searchQuery.isEmpty() || data.allEmojis.isEmpty()) {
|
||||||
emojiResults = SearchBarResultState.Initial()
|
if (emojiResults !is SearchBarResultState.Initial) {
|
||||||
|
emojiResults = SearchBarResultState.Initial()
|
||||||
|
}
|
||||||
return@LaunchedEffect
|
return@LaunchedEffect
|
||||||
}
|
}
|
||||||
delay(100.milliseconds)
|
delay(100.milliseconds)
|
||||||
|
|||||||
Reference in New Issue
Block a user