Force last owner of a room to pass ownership when leaving (#5094)

* Move `ChangeRoles*` classes to their own module so they can be shared

* Hook the change roles screen to the leave room action, add confirmation dialogs

* Use enum instead of sealed interface for `ChangeRoomMemberRolesListType`

* Try to improve communications between nodes

* refactor (leave room) : makes sure to expose only necessary code from api module

* Add `:libraries:previewutils` module to share some test fixtures used for UI previews

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: ganfra <francoisg@matrix.org>
This commit is contained in:
Jorge Martin Espinosa
2025-08-05 17:24:14 +02:00
committed by GitHub
parent a87bbdd91c
commit 955263bee1
112 changed files with 1337 additions and 513 deletions

View File

@@ -56,15 +56,11 @@ class AcceptDeclineInvitePresenter @Inject constructor(
)
}
}
is InternalAcceptDeclineInviteEvents.CancelDeclineInvite -> {
declinedAction.value = AsyncAction.Uninitialized
}
is InternalAcceptDeclineInviteEvents.DismissAcceptError -> {
is InternalAcceptDeclineInviteEvents.ClearAcceptActionState -> {
acceptedAction.value = AsyncAction.Uninitialized
}
is InternalAcceptDeclineInviteEvents.DismissDeclineError -> {
is InternalAcceptDeclineInviteEvents.ClearDeclineActionState -> {
declinedAction.value = AsyncAction.Uninitialized
}
}

View File

@@ -35,9 +35,12 @@ fun AcceptDeclineInviteView(
Box(modifier = modifier) {
AsyncActionView(
async = state.acceptAction,
onSuccess = onAcceptInviteSuccess,
onSuccess = { roomId ->
state.eventSink(InternalAcceptDeclineInviteEvents.ClearAcceptActionState)
onAcceptInviteSuccess(roomId)
},
onErrorDismiss = {
state.eventSink(InternalAcceptDeclineInviteEvents.DismissAcceptError)
state.eventSink(InternalAcceptDeclineInviteEvents.ClearAcceptActionState)
},
errorTitle = {
stringResource(CommonStrings.common_something_went_wrong)
@@ -52,9 +55,12 @@ fun AcceptDeclineInviteView(
)
AsyncActionView(
async = state.declineAction,
onSuccess = onDeclineInviteSuccess,
onSuccess = { roomId ->
state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
onDeclineInviteSuccess(roomId)
},
onErrorDismiss = {
state.eventSink(InternalAcceptDeclineInviteEvents.DismissDeclineError)
state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
},
errorTitle = {
stringResource(CommonStrings.common_something_went_wrong)
@@ -78,7 +84,7 @@ fun AcceptDeclineInviteView(
)
},
onDismissClick = {
state.eventSink(InternalAcceptDeclineInviteEvents.CancelDeclineInvite)
state.eventSink(InternalAcceptDeclineInviteEvents.ClearDeclineActionState)
}
)
}

View File

@@ -10,7 +10,6 @@ package io.element.android.features.invite.impl.acceptdecline
import io.element.android.features.invite.api.acceptdecline.AcceptDeclineInviteEvents
sealed interface InternalAcceptDeclineInviteEvents : AcceptDeclineInviteEvents {
data object CancelDeclineInvite : InternalAcceptDeclineInviteEvents
data object DismissAcceptError : InternalAcceptDeclineInviteEvents
data object DismissDeclineError : InternalAcceptDeclineInviteEvents
data object ClearAcceptActionState : InternalAcceptDeclineInviteEvents
data object ClearDeclineActionState : InternalAcceptDeclineInviteEvents
}

View File

@@ -56,7 +56,7 @@ class AcceptDeclineInvitePresenterTest {
awaitItem().also { state ->
assertThat(state.declineAction).isEqualTo(ConfirmingDeclineInvite(inviteData, false))
state.eventSink(
InternalAcceptDeclineInviteEvents.CancelDeclineInvite
InternalAcceptDeclineInviteEvents.ClearDeclineActionState
)
}
awaitItem().also { state ->
@@ -90,7 +90,7 @@ class AcceptDeclineInvitePresenterTest {
awaitItem().also { state ->
assertThat(state.declineAction).isInstanceOf(AsyncAction.Failure::class.java)
state.eventSink(
InternalAcceptDeclineInviteEvents.DismissDeclineError
InternalAcceptDeclineInviteEvents.ClearDeclineActionState
)
}
awaitItem().also { state ->
@@ -154,7 +154,7 @@ class AcceptDeclineInvitePresenterTest {
awaitItem().also { state ->
assertThat(state.acceptAction).isInstanceOf(AsyncAction.Failure::class.java)
state.eventSink(
InternalAcceptDeclineInviteEvents.DismissAcceptError
InternalAcceptDeclineInviteEvents.ClearAcceptActionState
)
}
awaitItem().also { state ->