knock requests : add permissions check
This commit is contained in:
parent
1978c9dbdb
commit
20ed6bb0d2
5 changed files with 150 additions and 39 deletions
|
|
@ -12,6 +12,7 @@ import io.element.android.features.knockrequests.impl.KnockRequest
|
|||
sealed interface KnockRequestsListEvents {
|
||||
data class Accept(val knockRequest: KnockRequest) : KnockRequestsListEvents
|
||||
data class Decline(val knockRequest: KnockRequest) : KnockRequestsListEvents
|
||||
data class DeclineAndBan(val knockRequest: KnockRequest) : KnockRequestsListEvents
|
||||
data object AcceptAll : KnockRequestsListEvents
|
||||
data object DismissCurrentAction : KnockRequestsListEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,35 +8,77 @@
|
|||
package io.element.android.features.knockrequests.impl.list
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
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.canInviteAsState
|
||||
import io.element.android.libraries.matrix.ui.room.canKickAsState
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import javax.inject.Inject
|
||||
|
||||
class KnockRequestsListPresenter @Inject constructor() : Presenter<KnockRequestsListState> {
|
||||
class KnockRequestsListPresenter @Inject constructor(
|
||||
private val room: MatrixRoom,
|
||||
) : Presenter<KnockRequestsListState> {
|
||||
|
||||
@Composable
|
||||
override fun present(): KnockRequestsListState {
|
||||
val actions = remember {
|
||||
mutableStateOf<KnockRequestsCurrentAction>(KnockRequestsCurrentAction.None)
|
||||
}
|
||||
val currentAction = remember { mutableStateOf<KnockRequestsCurrentAction>(KnockRequestsCurrentAction.None) }
|
||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
val canBan by room.canBanAsState(syncUpdateFlow.value)
|
||||
val canDecline by room.canKickAsState(syncUpdateFlow.value)
|
||||
val canAccept by room.canInviteAsState(syncUpdateFlow.value)
|
||||
|
||||
fun handleEvents(event: KnockRequestsListEvents) {
|
||||
when (event) {
|
||||
KnockRequestsListEvents.AcceptAll -> Unit
|
||||
is KnockRequestsListEvents.Accept -> Unit
|
||||
is KnockRequestsListEvents.Decline -> Unit
|
||||
KnockRequestsListEvents.DismissCurrentAction -> {
|
||||
actions.value = KnockRequestsCurrentAction.None
|
||||
KnockRequestsListEvents.AcceptAll -> {
|
||||
currentAction.value = KnockRequestsCurrentAction.AcceptAll(AsyncAction.Uninitialized)
|
||||
}
|
||||
is KnockRequestsListEvents.Accept -> {
|
||||
currentAction.value = KnockRequestsCurrentAction.Accept(event.knockRequest, AsyncAction.Uninitialized)
|
||||
}
|
||||
is KnockRequestsListEvents.Decline -> {
|
||||
currentAction.value = KnockRequestsCurrentAction.Decline(event.knockRequest, AsyncAction.Uninitialized)
|
||||
}
|
||||
is KnockRequestsListEvents.DeclineAndBan -> {
|
||||
currentAction.value = KnockRequestsCurrentAction.DeclineAndBan(event.knockRequest, AsyncAction.Uninitialized)
|
||||
}
|
||||
KnockRequestsListEvents.DismissCurrentAction -> {
|
||||
currentAction.value = KnockRequestsCurrentAction.None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(currentAction) {
|
||||
when (val action = currentAction.value) {
|
||||
is KnockRequestsCurrentAction.Accept -> {
|
||||
// Accept the knock request
|
||||
}
|
||||
is KnockRequestsCurrentAction.Decline -> {
|
||||
// Decline the knock request
|
||||
}
|
||||
is KnockRequestsCurrentAction.DeclineAndBan -> {
|
||||
// Decline and ban the user
|
||||
}
|
||||
is KnockRequestsCurrentAction.AcceptAll -> {
|
||||
// Accept all knock requests
|
||||
}
|
||||
KnockRequestsCurrentAction.None -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
return KnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(persistentListOf()),
|
||||
currentAction = actions.value,
|
||||
currentAction = currentAction.value,
|
||||
canAccept = canAccept,
|
||||
canDecline = canDecline,
|
||||
canBan = canBan,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
data class KnockRequestsListState(
|
||||
val knockRequests: AsyncData<ImmutableList<KnockRequest>>,
|
||||
val currentAction: KnockRequestsCurrentAction,
|
||||
val canAccept: Boolean,
|
||||
val canDecline: Boolean,
|
||||
val canBan: Boolean,
|
||||
val eventSink: (KnockRequestsListEvents) -> Unit,
|
||||
) {
|
||||
val canAcceptAll = knockRequests is AsyncData.Success && knockRequests.data.size > 1
|
||||
|
|
@ -22,7 +25,8 @@ data class KnockRequestsListState(
|
|||
|
||||
sealed interface KnockRequestsCurrentAction {
|
||||
data object None : KnockRequestsCurrentAction
|
||||
data class Accept(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
data class Decline(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
data class Accept(val knockRequest: KnockRequest, val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
data class Decline(val knockRequest: KnockRequest, val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
data class DeclineAndBan(val knockRequest: KnockRequest, val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
data class AcceptAll(val async: AsyncAction<Unit>) : KnockRequestsCurrentAction
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,40 @@ open class KnockRequestsListStateProvider : PreviewParameterProvider<KnockReques
|
|||
aKnockRequest()
|
||||
)
|
||||
),
|
||||
actions = KnockRequestsCurrentAction.AcceptAll(AsyncAction.Loading),
|
||||
currentAction = KnockRequestsCurrentAction.AcceptAll(AsyncAction.Loading),
|
||||
),
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(
|
||||
persistentListOf(
|
||||
aKnockRequest()
|
||||
)
|
||||
),
|
||||
canAccept = false,
|
||||
),
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(
|
||||
persistentListOf(
|
||||
aKnockRequest()
|
||||
)
|
||||
),
|
||||
canDecline = false,
|
||||
),
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(
|
||||
persistentListOf(
|
||||
aKnockRequest()
|
||||
)
|
||||
),
|
||||
canAccept = false,
|
||||
canDecline = false,
|
||||
),
|
||||
aKnockRequestsListState(
|
||||
knockRequests = AsyncData.Success(
|
||||
persistentListOf(
|
||||
aKnockRequest()
|
||||
)
|
||||
),
|
||||
canBan = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -71,10 +104,16 @@ fun aKnockRequest(
|
|||
|
||||
fun aKnockRequestsListState(
|
||||
knockRequests: AsyncData<ImmutableList<KnockRequest>> = AsyncData.Success(persistentListOf()),
|
||||
actions: KnockRequestsCurrentAction = KnockRequestsCurrentAction.None,
|
||||
currentAction: KnockRequestsCurrentAction = KnockRequestsCurrentAction.None,
|
||||
canAccept: Boolean = true,
|
||||
canDecline: Boolean = true,
|
||||
canBan: Boolean = true,
|
||||
eventSink: (KnockRequestsListEvents) -> Unit = {},
|
||||
) = KnockRequestsListState(
|
||||
knockRequests = knockRequests,
|
||||
currentAction = actions,
|
||||
currentAction = currentAction,
|
||||
canAccept = canAccept,
|
||||
canDecline = canDecline,
|
||||
canBan = canBan,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ private fun KnockRequestsListContent(state: KnockRequestsListState, modifier: Mo
|
|||
} else {
|
||||
KnockRequestsList(
|
||||
knockRequests = knockRequests,
|
||||
canAccept = state.canAccept,
|
||||
canDecline = state.canDecline,
|
||||
canBan = state.canBan,
|
||||
onAcceptClick = ::onAcceptClick,
|
||||
onDeclineClick = ::onDeclineClick,
|
||||
)
|
||||
|
|
@ -154,6 +157,13 @@ private fun KnockRequestsActionsView(
|
|||
onErrorDismiss = onDismiss,
|
||||
)
|
||||
}
|
||||
is KnockRequestsCurrentAction.DeclineAndBan -> {
|
||||
AsyncActionView(
|
||||
async = actions.async,
|
||||
onSuccess = {},
|
||||
onErrorDismiss = onDismiss,
|
||||
)
|
||||
}
|
||||
KnockRequestsCurrentAction.None -> Unit
|
||||
}
|
||||
}
|
||||
|
|
@ -162,6 +172,9 @@ private fun KnockRequestsActionsView(
|
|||
@Composable
|
||||
private fun KnockRequestsList(
|
||||
knockRequests: ImmutableList<KnockRequest>,
|
||||
canAccept: Boolean,
|
||||
canDecline: Boolean,
|
||||
canBan: Boolean,
|
||||
onAcceptClick: (KnockRequest) -> Unit,
|
||||
onDeclineClick: (KnockRequest) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -171,6 +184,9 @@ private fun KnockRequestsList(
|
|||
KnockRequestItem(
|
||||
knockRequest = knockRequest,
|
||||
onAcceptClick = onAcceptClick,
|
||||
canBan = canBan,
|
||||
canDecline = canDecline,
|
||||
canAccept = canAccept,
|
||||
onDeclineClick = onDeclineClick,
|
||||
)
|
||||
if (index != knockRequests.size - 1) {
|
||||
|
|
@ -183,6 +199,9 @@ private fun KnockRequestsList(
|
|||
@Composable
|
||||
private fun KnockRequestItem(
|
||||
knockRequest: KnockRequest,
|
||||
canAccept: Boolean,
|
||||
canDecline: Boolean,
|
||||
canBan: Boolean,
|
||||
onAcceptClick: (KnockRequest) -> Unit,
|
||||
onDeclineClick: (KnockRequest) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -194,7 +213,7 @@ private fun KnockRequestItem(
|
|||
) {
|
||||
Avatar(knockRequest.getAvatarData(AvatarSize.KnockRequestItem))
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column(modifier = Modifier) {
|
||||
Column {
|
||||
// Name
|
||||
Text(
|
||||
modifier = Modifier.clipToBounds(),
|
||||
|
|
@ -222,37 +241,43 @@ private fun KnockRequestItem(
|
|||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
}
|
||||
// Actions
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
OutlinedButton(
|
||||
text = stringResource(CommonStrings.action_decline),
|
||||
onClick = {
|
||||
onDeclineClick(knockRequest)
|
||||
},
|
||||
size = ButtonSize.MediumLowPadding,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_accept),
|
||||
if (canDecline) {
|
||||
OutlinedButton(
|
||||
text = stringResource(CommonStrings.action_decline),
|
||||
onClick = {
|
||||
onDeclineClick(knockRequest)
|
||||
},
|
||||
size = ButtonSize.MediumLowPadding,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
if (canAccept) {
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_accept),
|
||||
onClick = {
|
||||
onAcceptClick(knockRequest)
|
||||
},
|
||||
size = ButtonSize.MediumLowPadding,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
}
|
||||
}
|
||||
if (canBan) {
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
TextButton(
|
||||
text = stringResource(CommonStrings.screen_knock_requests_list_decline_and_ban_action_title),
|
||||
onClick = {
|
||||
onAcceptClick(knockRequest)
|
||||
},
|
||||
size = ButtonSize.MediumLowPadding,
|
||||
modifier = Modifier.weight(1f),
|
||||
destructive = true,
|
||||
size = ButtonSize.Small,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
TextButton(
|
||||
text = stringResource(CommonStrings.screen_knock_requests_list_decline_and_ban_action_title),
|
||||
onClick = {
|
||||
onAcceptClick(knockRequest)
|
||||
},
|
||||
destructive = true,
|
||||
size = ButtonSize.Small,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue