change(invites) : add logic to decline invite and block a user
This commit is contained in:
parent
e2116e76f2
commit
82dc29b91c
13 changed files with 145 additions and 63 deletions
|
|
@ -16,6 +16,7 @@ import im.vector.app.features.analytics.plan.JoinedRoom
|
|||
import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents
|
||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteState
|
||||
import io.element.android.features.invite.api.response.ConfirmingDeclineInvite
|
||||
import io.element.android.features.invite.api.response.InviteData
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.architecture.runCatchingUpdatingState
|
||||
|
|
@ -43,15 +44,34 @@ class AcceptDeclineInvitePresenter @Inject constructor(
|
|||
fun handleEvents(event: AcceptDeclineInviteEvents) {
|
||||
when (event) {
|
||||
is AcceptDeclineInviteEvents.AcceptInvite -> {
|
||||
localCoroutineScope.acceptInvite(event.invite.roomId, acceptedAction)
|
||||
val inviteData = event.invite
|
||||
if (inviteData == null) {
|
||||
acceptedAction.value = AsyncAction.Failure(InvalidDataException())
|
||||
} else {
|
||||
localCoroutineScope.acceptInvite(inviteData.roomId, acceptedAction)
|
||||
}
|
||||
}
|
||||
|
||||
is AcceptDeclineInviteEvents.DeclineInvite -> {
|
||||
declinedAction.value = ConfirmingDeclineInvite(event.invite)
|
||||
val inviteData = event.invite
|
||||
if (inviteData == null) {
|
||||
declinedAction.value = AsyncAction.Failure(InvalidDataException())
|
||||
} else {
|
||||
declinedAction.value = ConfirmingDeclineInvite(inviteData, event.blockUser)
|
||||
}
|
||||
}
|
||||
|
||||
is InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite -> {
|
||||
localCoroutineScope.declineInvite(event.roomId, declinedAction)
|
||||
when (val declinedActionValue = declinedAction.value) {
|
||||
is ConfirmingDeclineInvite -> {
|
||||
localCoroutineScope.declineInvite(
|
||||
inviteData = declinedActionValue.inviteData,
|
||||
declinedAction = declinedAction,
|
||||
blockUser = declinedActionValue.blockUser,
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
is InternalAcceptDeclineInviteEvents.CancelDeclineInvite -> {
|
||||
|
|
@ -92,13 +112,21 @@ class AcceptDeclineInvitePresenter @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.declineInvite(roomId: RoomId, declinedAction: MutableState<AsyncAction<RoomId>>) = launch {
|
||||
private fun CoroutineScope.declineInvite(
|
||||
inviteData: InviteData,
|
||||
blockUser: Boolean,
|
||||
declinedAction: MutableState<AsyncAction<RoomId>>,
|
||||
) = launch {
|
||||
suspend {
|
||||
client.getPendingRoom(roomId)?.use {
|
||||
client.getPendingRoom(inviteData.roomId)?.use {
|
||||
it.leave().getOrThrow()
|
||||
notificationCleaner.clearMembershipNotificationForRoom(client.sessionId, roomId)
|
||||
}
|
||||
roomId
|
||||
val senderId = inviteData.senderId
|
||||
if (blockUser && senderId != null) {
|
||||
client.ignoreUser(senderId).getOrThrow()
|
||||
}
|
||||
notificationCleaner.clearMembershipNotificationForRoom(client.sessionId, inviteData.roomId)
|
||||
inviteData.roomId
|
||||
}.runCatchingUpdatingState(declinedAction)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,9 @@ fun AcceptDeclineInviteView(
|
|||
if (confirming is ConfirmingDeclineInvite) {
|
||||
DeclineConfirmationDialog(
|
||||
invite = confirming.inviteData,
|
||||
blockUser = confirming.blockUser,
|
||||
onConfirmClick = {
|
||||
state.eventSink(InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite(confirming.inviteData.roomId))
|
||||
state.eventSink(InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite)
|
||||
},
|
||||
onDismissClick = {
|
||||
state.eventSink(InternalAcceptDeclineInviteEvents.CancelDeclineInvite)
|
||||
|
|
@ -66,29 +67,35 @@ fun AcceptDeclineInviteView(
|
|||
@Composable
|
||||
private fun DeclineConfirmationDialog(
|
||||
invite: InviteData,
|
||||
blockUser: Boolean,
|
||||
onConfirmClick: () -> Unit,
|
||||
onDismissClick: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val contentResource = if (invite.isDm) {
|
||||
R.string.screen_invites_decline_direct_chat_message
|
||||
} else {
|
||||
R.string.screen_invites_decline_chat_message
|
||||
val senderId = invite.senderId.value
|
||||
val content = when {
|
||||
blockUser -> stringResource(R.string.screen_join_room_decline_and_block_alert_message, senderId)
|
||||
invite.isDm -> stringResource(R.string.screen_invites_decline_direct_chat_message, invite.roomName)
|
||||
else -> stringResource(R.string.screen_invites_decline_chat_message, invite.roomName)
|
||||
}
|
||||
|
||||
val titleResource = if (invite.isDm) {
|
||||
R.string.screen_invites_decline_direct_chat_title
|
||||
} else {
|
||||
R.string.screen_invites_decline_chat_title
|
||||
val title = when {
|
||||
blockUser -> stringResource(R.string.screen_join_room_decline_and_block_alert_title)
|
||||
invite.isDm -> stringResource(R.string.screen_invites_decline_direct_chat_title)
|
||||
else -> stringResource(R.string.screen_invites_decline_chat_title)
|
||||
}
|
||||
val submitText = if (blockUser) {
|
||||
stringResource(R.string.screen_join_room_decline_and_block_alert_confirmation)
|
||||
} else {
|
||||
stringResource(CommonStrings.action_decline)
|
||||
}
|
||||
|
||||
ConfirmationDialog(
|
||||
modifier = modifier,
|
||||
content = stringResource(contentResource, invite.roomName),
|
||||
title = stringResource(titleResource),
|
||||
submitText = stringResource(CommonStrings.action_decline),
|
||||
content = content,
|
||||
title = title,
|
||||
submitText = submitText,
|
||||
cancelText = stringResource(CommonStrings.action_cancel),
|
||||
onSubmitClick = onConfirmClick,
|
||||
destructiveSubmit = blockUser,
|
||||
onDismiss = onDismissClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,9 @@
|
|||
package io.element.android.features.invite.impl.response
|
||||
|
||||
import io.element.android.features.invite.api.response.AcceptDeclineInviteEvents
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
sealed interface InternalAcceptDeclineInviteEvents : AcceptDeclineInviteEvents {
|
||||
data class ConfirmDeclineInvite(val roomId: RoomId) : InternalAcceptDeclineInviteEvents
|
||||
data object ConfirmDeclineInvite : InternalAcceptDeclineInviteEvents
|
||||
data object CancelDeclineInvite : InternalAcceptDeclineInviteEvents
|
||||
data object DismissAcceptError : InternalAcceptDeclineInviteEvents
|
||||
data object DismissDeclineError : InternalAcceptDeclineInviteEvents
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.invite.impl.response
|
||||
|
||||
class InvalidDataException : Exception()
|
||||
|
|
@ -17,10 +17,12 @@ import io.element.android.libraries.matrix.api.MatrixClient
|
|||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.room.FakeRoomPreview
|
||||
import io.element.android.libraries.matrix.test.room.join.FakeJoinRoom
|
||||
|
|
@ -93,7 +95,7 @@ class AcceptDeclineInvitePresenterTest {
|
|||
awaitItem().also { state ->
|
||||
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData))
|
||||
state.eventSink(
|
||||
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite(inviteData.roomId)
|
||||
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite()
|
||||
)
|
||||
}
|
||||
assertThat(awaitItem().declineAction.isLoading()).isTrue()
|
||||
|
|
@ -141,7 +143,7 @@ class AcceptDeclineInvitePresenterTest {
|
|||
awaitItem().also { state ->
|
||||
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData))
|
||||
state.eventSink(
|
||||
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite(inviteData.roomId)
|
||||
InternalAcceptDeclineInviteEvents.ConfirmDeclineInvite()
|
||||
)
|
||||
}
|
||||
assertThat(awaitItem().declineAction.isLoading()).isTrue()
|
||||
|
|
@ -237,12 +239,14 @@ class AcceptDeclineInvitePresenterTest {
|
|||
private fun anInviteData(
|
||||
roomId: RoomId = A_ROOM_ID,
|
||||
name: String = A_ROOM_NAME,
|
||||
isDm: Boolean = false
|
||||
isDm: Boolean = false,
|
||||
senderId: UserId = A_USER_ID,
|
||||
): InviteData {
|
||||
return InviteData(
|
||||
roomId = roomId,
|
||||
roomName = name,
|
||||
isDm = isDm
|
||||
isDm = isDm,
|
||||
senderId = senderId,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue