Simplify ForwardMessagesState by using AsyncAction.

This commit is contained in:
Benoit Marty 2024-05-30 12:22:20 +02:00 committed by Benoit Marty
parent e6fab7eee2
commit 130bce178a
6 changed files with 42 additions and 83 deletions

View file

@ -36,7 +36,6 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.roomselect.api.RoomSelectEntryPoint
import io.element.android.libraries.roomselect.api.RoomSelectMode
import kotlinx.collections.immutable.ImmutableList
import kotlinx.parcelize.Parcelize
@ContributesNode(RoomScope::class)
@ -99,7 +98,7 @@ class ForwardMessagesNode @AssistedInject constructor(
}
}
private fun onForwardSuccess(roomIds: ImmutableList<RoomId>) {
private fun onForwardSuccess(roomIds: List<RoomId>) {
navigateUp()
if (roomIds.size == 1) {
val targetRoomId = roomIds.first()

View file

@ -18,15 +18,13 @@ package io.element.android.features.messages.impl.forward
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.timeline.TimelineProvider
@ -38,7 +36,7 @@ import kotlinx.coroutines.launch
class ForwardMessagesPresenter @AssistedInject constructor(
@Assisted eventId: String,
private val matrixCoroutineScope: CoroutineScope,
private val appCoroutineScope: CoroutineScope,
private val timelineProvider: TimelineProvider,
) : Presenter<ForwardMessagesState> {
private val eventId: EventId = EventId(eventId)
@ -48,28 +46,22 @@ class ForwardMessagesPresenter @AssistedInject constructor(
fun create(eventId: String): ForwardMessagesPresenter
}
private val forwardingActionState: MutableState<AsyncData<ImmutableList<RoomId>>> = mutableStateOf(AsyncData.Uninitialized)
private val forwardingActionState: MutableState<AsyncAction<List<RoomId>>> = mutableStateOf(AsyncAction.Uninitialized)
fun onRoomSelected(roomIds: List<RoomId>) {
matrixCoroutineScope.forwardEvent(eventId, roomIds.toPersistentList(), forwardingActionState)
appCoroutineScope.forwardEvent(eventId, roomIds.toPersistentList(), forwardingActionState)
}
@Composable
override fun present(): ForwardMessagesState {
val forwardingSucceeded by remember {
derivedStateOf { forwardingActionState.value.dataOrNull() }
}
fun handleEvents(event: ForwardMessagesEvents) {
when (event) {
ForwardMessagesEvents.ClearError -> forwardingActionState.value = AsyncData.Uninitialized
ForwardMessagesEvents.ClearError -> forwardingActionState.value = AsyncAction.Uninitialized
}
}
return ForwardMessagesState(
isForwarding = forwardingActionState.value.isLoading(),
error = (forwardingActionState.value as? AsyncData.Failure)?.error,
forwardingSucceeded = forwardingSucceeded,
forwardAction = forwardingActionState.value,
eventSink = { handleEvents(it) }
)
}
@ -77,12 +69,11 @@ class ForwardMessagesPresenter @AssistedInject constructor(
private fun CoroutineScope.forwardEvent(
eventId: EventId,
roomIds: ImmutableList<RoomId>,
isForwardMessagesState: MutableState<AsyncData<ImmutableList<RoomId>>>,
isForwardMessagesState: MutableState<AsyncAction<List<RoomId>>>,
) = launch {
isForwardMessagesState.value = AsyncData.Loading()
timelineProvider.getActiveTimeline().forwardEvent(eventId, roomIds).fold(
{ isForwardMessagesState.value = AsyncData.Success(roomIds) },
{ isForwardMessagesState.value = AsyncData.Failure(it) }
)
suspend {
timelineProvider.getActiveTimeline().forwardEvent(eventId, roomIds).getOrThrow()
roomIds
}.runCatchingUpdatingState(isForwardMessagesState)
}
}

View file

@ -16,13 +16,10 @@
package io.element.android.features.messages.impl.forward
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
data class ForwardMessagesState(
// TODO Migrate to an Async
val isForwarding: Boolean,
val error: Throwable?,
val forwardingSucceeded: ImmutableList<RoomId>?,
val forwardAction: AsyncAction<List<RoomId>>,
val eventSink: (ForwardMessagesEvents) -> Unit
)

View file

@ -17,34 +17,30 @@
package io.element.android.features.messages.impl.forward
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
open class ForwardMessagesStateProvider : PreviewParameterProvider<ForwardMessagesState> {
override val values: Sequence<ForwardMessagesState>
get() = sequenceOf(
aForwardMessagesState(),
aForwardMessagesState(
isForwarding = true,
forwardAction = AsyncAction.Loading,
),
aForwardMessagesState(
forwardingSucceeded = persistentListOf(RoomId("!room2:domain")),
forwardAction = AsyncAction.Success(
listOf(RoomId("!room2:domain")),
)
),
aForwardMessagesState(
error = Throwable("error"),
forwardAction = AsyncAction.Failure(Throwable("error")),
),
// Add other states here
)
}
fun aForwardMessagesState(
isForwarding: Boolean = false,
error: Throwable? = null,
forwardingSucceeded: ImmutableList<RoomId>? = null,
forwardAction: AsyncAction<List<RoomId>> = AsyncAction.Uninitialized,
) = ForwardMessagesState(
isForwarding = isForwarding,
error = error,
forwardingSucceeded = forwardingSucceeded,
forwardAction = forwardAction,
eventSink = {}
)

View file

@ -17,45 +17,25 @@
package io.element.android.features.messages.impl.forward
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogDefaults
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
@Composable
fun ForwardMessagesView(
state: ForwardMessagesState,
onForwardSuccess: (ImmutableList<RoomId>) -> Unit,
modifier: Modifier = Modifier,
onForwardSuccess: (List<RoomId>) -> Unit,
) {
if (state.forwardingSucceeded != null) {
onForwardSuccess(state.forwardingSucceeded)
return
}
if (state.isForwarding) {
ProgressDialog(modifier)
}
if (state.error != null) {
ForwardingErrorDialog(
modifier = modifier,
onDismiss = { state.eventSink(ForwardMessagesEvents.ClearError) },
)
}
}
@Composable
private fun ForwardingErrorDialog(onDismiss: () -> Unit, modifier: Modifier = Modifier) {
ErrorDialog(
content = ErrorDialogDefaults.title,
onDismiss = onDismiss,
modifier = modifier,
AsyncActionView(
async = state.forwardAction,
onSuccess = {
onForwardSuccess(it)
},
onErrorDismiss = {
state.eventSink(ForwardMessagesEvents.ClearError)
},
)
}