knock request : simplify executing action

This commit is contained in:
ganfra 2024-12-17 15:35:44 +01:00
parent 1cc21c2d1c
commit 23cf3b1d4e

View file

@ -9,11 +9,12 @@ package io.element.android.features.knockrequests.impl.list
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import io.element.android.features.knockrequests.impl.data.KnockRequestsService import io.element.android.features.knockrequests.impl.data.KnockRequestsService
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
@ -23,6 +24,8 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.ui.room.canBanAsState import io.element.android.libraries.matrix.ui.room.canBanAsState
import io.element.android.libraries.matrix.ui.room.canInviteAsState import io.element.android.libraries.matrix.ui.room.canInviteAsState
import io.element.android.libraries.matrix.ui.room.canKickAsState import io.element.android.libraries.matrix.ui.room.canKickAsState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class KnockRequestsListPresenter @Inject constructor( class KnockRequestsListPresenter @Inject constructor(
@ -33,8 +36,6 @@ class KnockRequestsListPresenter @Inject constructor(
override fun present(): KnockRequestsListState { override fun present(): KnockRequestsListState {
val asyncAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) } val asyncAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
var actionTarget by remember { mutableStateOf<KnockRequestsActionTarget>(KnockRequestsActionTarget.None) } var actionTarget by remember { mutableStateOf<KnockRequestsActionTarget>(KnockRequestsActionTarget.None) }
var targetActionConfirmed by remember { mutableStateOf(false) }
var retryCount by remember { mutableIntStateOf(0) }
val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
val canBan by room.canBanAsState(syncUpdateFlow.value) val canBan by room.canBanAsState(syncUpdateFlow.value)
@ -43,6 +44,8 @@ class KnockRequestsListPresenter @Inject constructor(
val knockRequests by knockRequestsService.knockRequestsFlow.collectAsState() val knockRequests by knockRequestsService.knockRequestsFlow.collectAsState()
val coroutineScope = rememberCoroutineScope()
fun handleEvents(event: KnockRequestsListEvents) { fun handleEvents(event: KnockRequestsListEvents) {
when (event) { when (event) {
KnockRequestsListEvents.AcceptAll -> { KnockRequestsListEvents.AcceptAll -> {
@ -60,53 +63,17 @@ class KnockRequestsListPresenter @Inject constructor(
KnockRequestsListEvents.ResetCurrentAction -> { KnockRequestsListEvents.ResetCurrentAction -> {
asyncAction.value = AsyncAction.Uninitialized asyncAction.value = AsyncAction.Uninitialized
actionTarget = KnockRequestsActionTarget.None actionTarget = KnockRequestsActionTarget.None
targetActionConfirmed = false
} }
KnockRequestsListEvents.RetryCurrentAction -> { KnockRequestsListEvents.RetryCurrentAction -> {
retryCount++ coroutineScope.executeAction(actionTarget, asyncAction, isActionConfirmed = true)
} }
KnockRequestsListEvents.ConfirmCurrentAction -> { KnockRequestsListEvents.ConfirmCurrentAction -> {
targetActionConfirmed = true coroutineScope.executeAction(actionTarget, asyncAction, isActionConfirmed = true)
} }
} }
} }
LaunchedEffect(actionTarget) {
LaunchedEffect(actionTarget, targetActionConfirmed, retryCount) { executeAction(actionTarget, asyncAction, isActionConfirmed = false)
when (val action = actionTarget) {
is KnockRequestsActionTarget.Accept -> {
runUpdatingState(asyncAction) {
knockRequestsService.acceptKnockRequest(action.knockRequest)
}
}
is KnockRequestsActionTarget.Decline -> {
if (targetActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.declineKnockRequest(action.knockRequest)
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
is KnockRequestsActionTarget.DeclineAndBan -> {
if (targetActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.declineAndBanKnockRequest(action.knockRequest)
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
is KnockRequestsActionTarget.AcceptAll -> {
if (targetActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.acceptAllKnockRequests()
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
KnockRequestsActionTarget.None -> Unit
}
} }
return KnockRequestsListState( return KnockRequestsListState(
@ -119,4 +86,46 @@ class KnockRequestsListPresenter @Inject constructor(
eventSink = ::handleEvents eventSink = ::handleEvents
) )
} }
private fun CoroutineScope.executeAction(
actionTarget: KnockRequestsActionTarget,
asyncAction: MutableState<AsyncAction<Unit>>,
isActionConfirmed: Boolean,
) = launch {
when (actionTarget) {
is KnockRequestsActionTarget.Accept -> {
runUpdatingState(asyncAction) {
knockRequestsService.acceptKnockRequest(actionTarget.knockRequest)
}
}
is KnockRequestsActionTarget.Decline -> {
if (isActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.declineKnockRequest(actionTarget.knockRequest)
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
is KnockRequestsActionTarget.DeclineAndBan -> {
if (isActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.declineAndBanKnockRequest(actionTarget.knockRequest)
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
is KnockRequestsActionTarget.AcceptAll -> {
if (isActionConfirmed) {
runUpdatingState(asyncAction) {
knockRequestsService.acceptAllKnockRequests()
}
} else {
asyncAction.value = AsyncAction.ConfirmingNoParams
}
}
KnockRequestsActionTarget.None -> Unit
}
}
} }