mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
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:
committed by
GitHub
parent
dff295eadf
commit
1a335698c0
@@ -14,7 +14,5 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation(projects.libraries.architecture)
|
||||
implementation(projects.libraries.designsystem)
|
||||
implementation(projects.libraries.uiStrings)
|
||||
implementation(projects.libraries.matrix.api)
|
||||
}
|
||||
|
||||
+2
-5
@@ -9,9 +9,6 @@ package io.element.android.features.leaveroom.api
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
sealed interface LeaveRoomEvent {
|
||||
data class ShowConfirmation(val roomId: RoomId) : LeaveRoomEvent
|
||||
data object HideConfirmation : LeaveRoomEvent
|
||||
data class LeaveRoom(val roomId: RoomId) : LeaveRoomEvent
|
||||
data object HideError : LeaveRoomEvent
|
||||
interface LeaveRoomEvent {
|
||||
data class LeaveRoom(val roomId: RoomId, val needsConfirmation: Boolean) : LeaveRoomEvent
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.leaveroom.api
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
interface LeaveRoomRenderer {
|
||||
@Composable
|
||||
fun Render(
|
||||
state: LeaveRoomState,
|
||||
onSelectNewOwners: (RoomId) -> Unit,
|
||||
modifier: Modifier,
|
||||
)
|
||||
}
|
||||
+2
-25
@@ -7,29 +7,6 @@
|
||||
|
||||
package io.element.android.features.leaveroom.api
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
data class LeaveRoomState(
|
||||
val confirmation: Confirmation,
|
||||
val progress: Progress,
|
||||
val error: Error,
|
||||
val eventSink: (LeaveRoomEvent) -> Unit,
|
||||
) {
|
||||
sealed interface Confirmation {
|
||||
data object Hidden : Confirmation
|
||||
data class Dm(val roomId: RoomId) : Confirmation
|
||||
data class Generic(val roomId: RoomId) : Confirmation
|
||||
data class PrivateRoom(val roomId: RoomId) : Confirmation
|
||||
data class LastUserInRoom(val roomId: RoomId) : Confirmation
|
||||
}
|
||||
|
||||
sealed interface Progress {
|
||||
data object Hidden : Progress
|
||||
data object Shown : Progress
|
||||
}
|
||||
|
||||
sealed interface Error {
|
||||
data object Hidden : Error
|
||||
data object Shown : Error
|
||||
}
|
||||
interface LeaveRoomState {
|
||||
val eventSink: (LeaveRoomEvent) -> Unit
|
||||
}
|
||||
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023, 2024 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.leaveroom.api
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
class LeaveRoomStateProvider : PreviewParameterProvider<LeaveRoomState> {
|
||||
override val values: Sequence<LeaveRoomState>
|
||||
get() = sequenceOf(
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Hidden,
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Generic(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.PrivateRoom(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.LastUserInRoom(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Hidden,
|
||||
progress = LeaveRoomState.Progress.Shown,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Hidden,
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Shown,
|
||||
),
|
||||
aLeaveRoomState(
|
||||
confirmation = LeaveRoomState.Confirmation.Dm(roomId = A_ROOM_ID),
|
||||
progress = LeaveRoomState.Progress.Hidden,
|
||||
error = LeaveRoomState.Error.Hidden,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private val A_ROOM_ID = RoomId("!aRoomId:aDomain")
|
||||
|
||||
fun aLeaveRoomState(
|
||||
confirmation: LeaveRoomState.Confirmation = LeaveRoomState.Confirmation.Hidden,
|
||||
progress: LeaveRoomState.Progress = LeaveRoomState.Progress.Hidden,
|
||||
error: LeaveRoomState.Error = LeaveRoomState.Error.Hidden,
|
||||
eventSink: (LeaveRoomEvent) -> Unit = {},
|
||||
) = LeaveRoomState(
|
||||
confirmation = confirmation,
|
||||
progress = progress,
|
||||
error = error,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023, 2024 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.leaveroom.api
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
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 io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun LeaveRoomView(
|
||||
state: LeaveRoomState
|
||||
) {
|
||||
LeaveRoomConfirmationDialog(state)
|
||||
LeaveRoomProgressDialog(state)
|
||||
LeaveRoomErrorDialog(state)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LeaveRoomConfirmationDialog(
|
||||
state: LeaveRoomState,
|
||||
) {
|
||||
when (state.confirmation) {
|
||||
is LeaveRoomState.Confirmation.Hidden -> {}
|
||||
|
||||
is LeaveRoomState.Confirmation.Dm -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_private_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.PrivateRoom -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_private_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.LastUserInRoom -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_empty_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
|
||||
is LeaveRoomState.Confirmation.Generic -> LeaveRoomConfirmationDialog(
|
||||
text = R.string.leave_room_alert_subtitle,
|
||||
roomId = state.confirmation.roomId,
|
||||
isDm = false,
|
||||
eventSink = state.eventSink,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LeaveRoomConfirmationDialog(
|
||||
@StringRes text: Int,
|
||||
roomId: RoomId,
|
||||
isDm: Boolean,
|
||||
eventSink: (LeaveRoomEvent) -> Unit,
|
||||
) {
|
||||
ConfirmationDialog(
|
||||
title = stringResource(if (isDm) CommonStrings.action_leave_conversation else CommonStrings.action_leave_room),
|
||||
content = stringResource(text),
|
||||
submitText = stringResource(CommonStrings.action_leave),
|
||||
onSubmitClick = { eventSink(LeaveRoomEvent.LeaveRoom(roomId)) },
|
||||
onDismiss = { eventSink(LeaveRoomEvent.HideConfirmation) },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LeaveRoomProgressDialog(
|
||||
state: LeaveRoomState,
|
||||
) {
|
||||
when (state.progress) {
|
||||
is LeaveRoomState.Progress.Hidden -> {}
|
||||
is LeaveRoomState.Progress.Shown -> ProgressDialog(
|
||||
text = stringResource(CommonStrings.common_leaving_room),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LeaveRoomErrorDialog(
|
||||
state: LeaveRoomState,
|
||||
) {
|
||||
when (state.error) {
|
||||
is LeaveRoomState.Error.Hidden -> {}
|
||||
is LeaveRoomState.Error.Shown -> ErrorDialog(
|
||||
content = stringResource(CommonStrings.error_unknown),
|
||||
onSubmit = { state.eventSink(LeaveRoomEvent.HideError) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun LeaveRoomViewPreview(
|
||||
@PreviewParameter(LeaveRoomStateProvider::class) state: LeaveRoomState
|
||||
) = ElementPreview {
|
||||
Box(
|
||||
modifier = Modifier.size(300.dp, 300.dp),
|
||||
propagateMinConstraints = true,
|
||||
) {
|
||||
LeaveRoomView(state = state)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user