From e40f5606af62aed8aaec3a6c523f582038559589 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:36:17 +0000 Subject: [PATCH 1/4] Update dependency org.matrix.rustcomponents:sdk-android to v0.2.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2e11cc2f52..d5b5171cea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -152,7 +152,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:1.3.2" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.2" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.3" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } From f171dc94da46226aa9e44ab39adb3273b8f66c4e Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 19 Feb 2024 21:35:31 +0100 Subject: [PATCH 2/4] rust sdk : fix api changes --- .../libraries/eventformatter/impl/StateContentFormatter.kt | 2 +- .../libraries/matrix/api/timeline/item/event/OtherState.kt | 2 +- .../matrix/impl/auth/RustMatrixAuthenticationService.kt | 1 + .../impl/timeline/item/event/TimelineEventContentMapper.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/StateContentFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/StateContentFormatter.kt index 678e0f1d53..857bc0b89e 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/StateContentFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/StateContentFormatter.kt @@ -170,7 +170,7 @@ class StateContentFormatter @Inject constructor( "RoomPinnedEvents" } } - OtherState.RoomPowerLevels -> when (renderingMode) { + is OtherState.RoomPowerLevels -> when (renderingMode) { RenderingMode.RoomList -> { Timber.v("Filtering timeline item for room state change: $content") null diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/OtherState.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/OtherState.kt index 6960b3565d..90b30cc1f9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/OtherState.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/OtherState.kt @@ -33,7 +33,7 @@ sealed interface OtherState { data object RoomJoinRules : OtherState data class RoomName(val name: String?) : OtherState data object RoomPinnedEvents : OtherState - data object RoomPowerLevels : OtherState + data class RoomPowerLevels(val users: Map) : OtherState data object RoomServerAcl : OtherState data class RoomThirdPartyInvite(val displayName: String?) : OtherState data object RoomTombstone : OtherState diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index b777988783..c27ace88f6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -65,6 +65,7 @@ class RustMatrixAuthenticationService @Inject constructor( basePath = baseDirectory.absolutePath, passphrase = pendingPassphrase, userAgent = userAgentProvider.provide(), + additionalRootCertificates = emptyList(), oidcConfiguration = oidcConfiguration, customSlidingSyncProxy = null, sessionDelegate = null, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt index 67afb3907c..0bef1744cc 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt @@ -163,7 +163,7 @@ private fun RustOtherState.map(): OtherState { RustOtherState.RoomJoinRules -> OtherState.RoomJoinRules is RustOtherState.RoomName -> OtherState.RoomName(name) RustOtherState.RoomPinnedEvents -> OtherState.RoomPinnedEvents - RustOtherState.RoomPowerLevels -> OtherState.RoomPowerLevels + is RustOtherState.RoomPowerLevels -> OtherState.RoomPowerLevels(users) RustOtherState.RoomServerAcl -> OtherState.RoomServerAcl is RustOtherState.RoomThirdPartyInvite -> OtherState.RoomThirdPartyInvite(displayName) RustOtherState.RoomTombstone -> OtherState.RoomTombstone From d6c81c207cd2fc17280f19f681034fa50d3e7310 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 19 Feb 2024 21:52:19 +0100 Subject: [PATCH 3/4] rust sdk : should fix test --- .../DefaultRoomLastMessageFormatterTest.kt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt index c75fb9ed4b..5165e5dadf 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt @@ -641,9 +641,21 @@ class DefaultRoomLastMessageFormatterTest { @Config(qualifiers = "en") fun `Room state change - others must return null`() { val otherStates = arrayOf( - OtherState.PolicyRuleRoom, OtherState.PolicyRuleServer, OtherState.PolicyRuleUser, OtherState.RoomAliases, OtherState.RoomCanonicalAlias, - OtherState.RoomGuestAccess, OtherState.RoomHistoryVisibility, OtherState.RoomJoinRules, OtherState.RoomPinnedEvents, OtherState.RoomPowerLevels, - OtherState.RoomServerAcl, OtherState.RoomTombstone, OtherState.SpaceChild, OtherState.SpaceParent, OtherState.Custom("custom_event_type") + OtherState.PolicyRuleRoom, + OtherState.PolicyRuleServer, + OtherState.PolicyRuleUser, + OtherState.RoomAliases, + OtherState.RoomCanonicalAlias, + OtherState.RoomGuestAccess, + OtherState.RoomHistoryVisibility, + OtherState.RoomJoinRules, + OtherState.RoomPinnedEvents, + OtherState.RoomPowerLevels(emptyMap()), + OtherState.RoomServerAcl, + OtherState.RoomTombstone, + OtherState.SpaceChild, + OtherState.SpaceParent, + OtherState.Custom("custom_event_type") ) val results = otherStates.map { state -> From e68139bf4651cc71404abea2f7dfe1f1e129abdb Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 20 Feb 2024 10:07:06 +0100 Subject: [PATCH 4/4] Display banned users in room member list (#2415) * Display banned users in room member list --------- Co-authored-by: ElementBot --- changelog.d/2256.feature | 1 + .../impl/members/RoomMemberListPresenter.kt | 21 +++ .../impl/members/RoomMemberListState.kt | 4 +- .../members/RoomMemberListStateProvider.kt | 14 ++ .../impl/members/RoomMemberListView.kt | 150 ++++++++++++++---- .../impl/src/main/res/values/localazy.xml | 2 + .../impl/src/main/res/values/localazy.xml | 1 + .../libraries/matrix/api/room/MatrixRoom.kt | 2 + .../room/powerlevels/MatrixRoomPowerLevels.kt | 5 + .../matrix/impl/room/RustMatrixRoom.kt | 6 + .../matrix/test/room/FakeMatrixRoom.kt | 9 ++ .../src/main/res/values/localazy.xml | 1 + ...annedList-Day-3_4_null,NEXUS_5,1.0,en].png | 3 + ...nedList-Night-3_5_null,NEXUS_5,1.0,en].png | 3 + ...berList-Day-2_3_null_8,NEXUS_5,1.0,en].png | 3 + ...rList-Night-2_4_null_8,NEXUS_5,1.0,en].png | 3 + ...ttings-Day-5_6_null_0,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_1,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_2,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_3,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_4,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_5,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-5_6_null_6,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_0,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_1,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_2,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_3,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_4,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_5,NEXUS_5,1.0,en].png} | 0 ...ings-Night-5_7_null_6,NEXUS_5,1.0,en].png} | 0 ...cyOption-Day-4_5_null,NEXUS_5,1.0,en].png} | 0 ...Option-Night-4_6_null,NEXUS_5,1.0,en].png} | 0 ...ttings-Day-6_7_null_0,NEXUS_5,1.0,en].png} | 0 ...ings-Night-6_8_null_0,NEXUS_5,1.0,en].png} | 0 34 files changed, 197 insertions(+), 31 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Day-3_4_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Night-3_5_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Day-2_3_null_8,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Night-2_4_null_8,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-3_4_null,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-4_5_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-3_5_null,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-4_6_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-6_7_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-6_8_null_0,NEXUS_5,1.0,en].png} (100%) diff --git a/changelog.d/2256.feature b/changelog.d/2256.feature index e7d33d6d11..98ed9d17cd 100644 --- a/changelog.d/2256.feature +++ b/changelog.d/2256.feature @@ -1,3 +1,4 @@ Add moderation to rooms: - Sort member in room member list by powerlevel, display their roles. +- Display banner users in room member list for users with enough power level to ban/unban. diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 29800f6eac..04c1b50912 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -27,14 +27,18 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.powerlevels.canBan import io.element.android.libraries.matrix.api.room.powerlevels.canInvite import io.element.android.libraries.matrix.api.room.roomMembers import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.withContext import javax.inject.Inject @@ -57,6 +61,20 @@ class RoomMemberListPresenter @Inject constructor( value = room.canInvite().getOrElse { false } } + val canDisplayBannedUsers by produceState(initialValue = false) { + val roomIsNotDmAndUserCanBan = !room.isDm && room.canBan().getOrElse { false } + if (roomIsNotDmAndUserCanBan) { + room.membersStateFlow + .onEach { members -> + val hasBannedUsers = members.roomMembers()?.any { it.membership == RoomMembershipState.BAN }.orFalse() + value = hasBannedUsers + } + .collect() + } else { + value = false + } + } + LaunchedEffect(membersState) { if (membersState is MatrixRoomMembersState.Unknown) { return@LaunchedEffect @@ -69,6 +87,7 @@ class RoomMemberListPresenter @Inject constructor( joined = members.getOrDefault(RoomMembershipState.JOIN, emptyList()) .sortedWith(PowerLevelRoomMemberComparator()) .toImmutableList(), + banned = members.getOrDefault(RoomMembershipState.BAN, emptyList()).sortedBy { it.userId.value }.toImmutableList(), ) ) } @@ -89,6 +108,7 @@ class RoomMemberListPresenter @Inject constructor( joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList()) .sortedWith(PowerLevelRoomMemberComparator()) .toImmutableList(), + banned = results.getOrDefault(RoomMembershipState.BAN, emptyList()).sortedBy { it.userId.value }.toImmutableList(), ) ) } @@ -102,6 +122,7 @@ class RoomMemberListPresenter @Inject constructor( searchResults = searchResults, isSearchActive = isSearchActive, canInvite = canInvite, + canDisplayBannedUsers = canDisplayBannedUsers, eventSink = { event -> when (event) { is RoomMemberListEvents.OnSearchActiveChanged -> isSearchActive = event.active diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index aa2d94cc65..e9bcbffabb 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -27,10 +27,12 @@ data class RoomMemberListState( val searchResults: SearchBarResultState, val isSearchActive: Boolean, val canInvite: Boolean, + val canDisplayBannedUsers: Boolean, val eventSink: (RoomMemberListEvents) -> Unit, ) data class RoomMembers( val invited: ImmutableList, - val joined: ImmutableList + val joined: ImmutableList, + val banned: ImmutableList, ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 9846401323..48c4559697 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -32,6 +32,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider = AsyncData.Uninitialized, searchResults: SearchBarResultState = SearchBarResultState.Initial(), + canDisplayBannedUsers: Boolean = false, ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", searchResults = searchResults, isSearchActive = false, canInvite = false, + canDisplayBannedUsers = canDisplayBannedUsers, eventSink = {} ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 6ad3d7c42f..2bfdbecc74 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -16,6 +16,8 @@ package io.element.android.features.roomdetails.impl.members +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -30,7 +32,12 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.pluralStringResource @@ -49,6 +56,7 @@ import io.element.android.libraries.designsystem.theme.components.CircularProgre import io.element.android.libraries.designsystem.theme.components.Scaffold import io.element.android.libraries.designsystem.theme.components.SearchBar import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.designsystem.theme.components.SegmentedButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar @@ -58,6 +66,12 @@ import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.ui.components.MatrixUserRow import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +private enum class SelectedSection { + MEMBERS, + BANNED +} @Composable fun RoomMemberListView( @@ -66,6 +80,7 @@ fun RoomMemberListView( onInvitePressed: () -> Unit, onMemberSelected: (UserId) -> Unit, modifier: Modifier = Modifier, + initialSelectedSectionIndex: Int = 0, ) { fun onUserSelected(roomMember: RoomMember) { onMemberSelected(roomMember.userId) @@ -83,6 +98,7 @@ fun RoomMemberListView( } } ) { padding -> + var selectedSection by remember { mutableStateOf(SelectedSection.entries[initialSelectedSectionIndex]) } Column( modifier = Modifier .fillMaxWidth() @@ -98,7 +114,8 @@ fun RoomMemberListView( onActiveChanged = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, onTextChanged = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, onUserSelected = ::onUserSelected, - modifier = Modifier.fillMaxWidth() + selectedSection = selectedSection, + modifier = Modifier.fillMaxWidth(), ) if (!state.isSearchActive) { @@ -106,7 +123,10 @@ fun RoomMemberListView( RoomMemberList( roomMembers = state.roomMembers.data, showMembersCount = true, - onUserSelected = ::onUserSelected + canDisplayBannedUsersControls = state.canDisplayBannedUsers, + selectedSection = selectedSection, + onSelectedSectionChanged = { selectedSection = it }, + onUserSelected = ::onUserSelected, ) } else if (state.roomMembers.isLoading()) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { @@ -118,49 +138,90 @@ fun RoomMemberListView( } } +@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) @Composable private fun RoomMemberList( roomMembers: RoomMembers, showMembersCount: Boolean, + selectedSection: SelectedSection, + onSelectedSectionChanged: (SelectedSection) -> Unit, + canDisplayBannedUsersControls: Boolean, onUserSelected: (RoomMember) -> Unit, ) { LazyColumn(modifier = Modifier.fillMaxWidth(), state = rememberLazyListState()) { - if (roomMembers.invited.isNotEmpty()) { - roomMemberListSection( - headerText = { stringResource(id = R.string.screen_room_member_list_pending_header_title) }, - members = roomMembers.invited, - onMemberSelected = { onUserSelected(it) } - ) - } - if (roomMembers.joined.isNotEmpty()) { - roomMemberListSection( - headerText = { - if (showMembersCount) { - val memberCount = roomMembers.joined.count() - pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) - } else { - stringResource(id = R.string.screen_room_member_list_room_members_header_title) + if (canDisplayBannedUsersControls) { + stickyHeader { + val segmentedButtonTitles = persistentListOf( + stringResource(id = R.string.screen_room_member_list_mode_members), + stringResource(id = R.string.screen_room_member_list_mode_banned), + ) + SingleChoiceSegmentedButtonRow( + modifier = Modifier + .background(ElementTheme.colors.bgCanvasDefault) + .fillMaxWidth() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), + ) { + for ((index, title) in segmentedButtonTitles.withIndex()) { + SegmentedButton( + index = index, + count = segmentedButtonTitles.size, + selected = selectedSection.ordinal == index, + onClick = { onSelectedSectionChanged(SelectedSection.entries[index]) }, + text = title, + ) } - }, - members = roomMembers.joined, - onMemberSelected = { onUserSelected(it) } - ) + } + } + } + when (selectedSection) { + SelectedSection.MEMBERS -> { + if (roomMembers.invited.isNotEmpty()) { + roomMemberListSection( + headerText = { stringResource(id = R.string.screen_room_member_list_pending_header_title) }, + members = roomMembers.invited, + onMemberSelected = { onUserSelected(it) } + ) + } + if (roomMembers.joined.isNotEmpty()) { + roomMemberListSection( + headerText = { + if (showMembersCount) { + val memberCount = roomMembers.joined.count() + pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) + } else { + stringResource(id = R.string.screen_room_member_list_room_members_header_title) + } + }, + members = roomMembers.joined, + onMemberSelected = { onUserSelected(it) } + ) + } + } + SelectedSection.BANNED -> { // Banned users + roomMemberListSection( + headerText = null, + members = roomMembers.banned, + onMemberSelected = { onUserSelected(it) } + ) + } } } } private fun LazyListScope.roomMemberListSection( - headerText: @Composable () -> String, + headerText: @Composable (() -> String)?, members: ImmutableList, onMemberSelected: (RoomMember) -> Unit, ) { - item { - Text( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), - text = headerText(), - style = ElementTheme.typography.fontBodyLgRegular, - color = MaterialTheme.colorScheme.secondary, - ) + headerText?.let { + item { + Text( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + text = it(), + style = ElementTheme.typography.fontBodyLgRegular, + color = MaterialTheme.colorScheme.secondary, + ) + } } items(members) { matrixUser -> RoomMemberListItem( @@ -238,6 +299,7 @@ private fun RoomMemberSearchBar( onActiveChanged: (Boolean) -> Unit, onTextChanged: (String) -> Unit, onUserSelected: (RoomMember) -> Unit, + selectedSection: SelectedSection, modifier: Modifier = Modifier, ) { SearchBar( @@ -252,7 +314,10 @@ private fun RoomMemberSearchBar( RoomMemberList( roomMembers = results, showMembersCount = false, - onUserSelected = { onUserSelected(it) } + onUserSelected = { onUserSelected(it) }, + canDisplayBannedUsersControls = false, + selectedSection = selectedSection, + onSelectedSectionChanged = {}, ) }, ) @@ -268,3 +333,28 @@ internal fun RoomMemberListPreview(@PreviewParameter(RoomMemberListStateProvider onInvitePressed = {}, ) } + +@PreviewsDayNight +@Composable +internal fun RoomMemberBannedListPreview() = ElementPreview { + RoomMemberListView( + initialSelectedSectionIndex = 1, + state = aRoomMemberListState( + roomMembers = AsyncData.Success( + RoomMembers( + invited = persistentListOf(), + joined = persistentListOf(), + banned = persistentListOf( + aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice"), + aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob"), + aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie"), + ), + ) + ), + canDisplayBannedUsers = true, + ), + onBackPressed = {}, + onMemberSelected = {}, + onInvitePressed = {}, + ) +} diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index f2d3c16aad..2561083bfd 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -24,6 +24,8 @@ "Notifications" "Share room" "Updating room…" + "Banned" + "Members" "Pending" "Admin" "Moderator" diff --git a/features/verifysession/impl/src/main/res/values/localazy.xml b/features/verifysession/impl/src/main/res/values/localazy.xml index 9b785044d8..b46954f42b 100644 --- a/features/verifysession/impl/src/main/res/values/localazy.xml +++ b/features/verifysession/impl/src/main/res/values/localazy.xml @@ -6,6 +6,7 @@ "Confirm that the numbers below match those shown on your other session." "Compare numbers" "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted." + "Enter recovery key" "Prove it’s you in order to access your encrypted message history." "Open an existing session" "Retry verification" diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 9a25938ee8..fd8f76b6e9 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -129,6 +129,8 @@ interface MatrixRoom : Closeable { suspend fun canUserInvite(userId: UserId): Result + suspend fun canUserBan(userId: UserId): Result + suspend fun canUserRedactOwn(userId: UserId): Result suspend fun canUserRedactOther(userId: UserId): Result diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt index c228a9cb2f..c879991bc0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/powerlevels/MatrixRoomPowerLevels.kt @@ -25,6 +25,11 @@ import io.element.android.libraries.matrix.api.room.StateEventType */ suspend fun MatrixRoom.canInvite(): Result = canUserInvite(sessionId) +/** + * Shortcut for calling [MatrixRoom.canBanUser] with our own user. + */ +suspend fun MatrixRoom.canBan(): Result = canUserBan(sessionId) + /** * Shortcut for calling [MatrixRoom.canUserSendState] with our own user. */ diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 6e1b06ac51..196d5bd715 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -319,6 +319,12 @@ class RustMatrixRoom( } } + override suspend fun canUserBan(userId: UserId): Result { + return runCatching { + innerRoom.canUserBan(userId.value) + } + } + override suspend fun canUserRedactOwn(userId: UserId): Result { return runCatching { innerRoom.canUserRedactOwn(userId.value) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index 4061a9dd9c..5ab6c621a5 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -90,6 +90,7 @@ class FakeMatrixRoom( private var joinRoomResult = Result.success(Unit) private var inviteUserResult = Result.success(Unit) private var canInviteResult = Result.success(true) + private var canBanResult = Result.success(false) private var canRedactOwnResult = Result.success(canRedactOwn) private var canRedactOtherResult = Result.success(canRedactOther) private val canSendStateResults = mutableMapOf>() @@ -280,6 +281,10 @@ class FakeMatrixRoom( inviteUserResult } + override suspend fun canUserBan(userId: UserId): Result { + return canBanResult + } + override suspend fun canUserInvite(userId: UserId): Result { return canInviteResult } @@ -495,6 +500,10 @@ class FakeMatrixRoom( joinRoomResult = result } + fun givenCanBanResult(result: Result) { + canBanResult = result + } + fun givenInviteUserResult(result: Result) { inviteUserResult = result } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 4865698362..77248a2339 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -120,6 +120,7 @@ "Error" "Everyone" "Favourite" + "Favourited" "File" "File saved to Downloads" "Forward message" diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Day-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Day-3_4_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..b98c07dbc1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Day-3_4_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f6ce6e7d31871ff45ca2494fbb12bb1bc6e44a1fb6baee547b001743d1b4702 +size 35078 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Night-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Night-3_5_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..ea9e6614b9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberBannedList_null_RoomMemberBannedList-Night-3_5_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b5bd1bfd3ff184ae96c61ee639b0114b4612125f3284360f547fb2bdf73befb +size 34121 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Day-2_3_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Day-2_3_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9960521ede --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Day-2_3_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:efc266bca406673c57731b4d6a283d217e7199f4b8a9c70c45ed3e00611d165d +size 52344 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Night-2_4_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Night-2_4_null_8,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..4107ebae71 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.members_RoomMemberList_null_RoomMemberList-Night-2_4_null_8,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65dd3de9356356a9bf651cecd725c1be89a0d1b1ba816e4df9b25ce0a76313dd +size 51139 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-4_5_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Day-5_6_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-4_6_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomNotificationSettings_null_RoomNotificationSettings-Night-5_7_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-4_5_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-3_4_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Day-4_5_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-4_6_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-3_5_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_RoomPrivacyOption_null_RoomPrivacyOption-Night-4_6_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-6_7_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-5_6_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Day-6_7_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-6_8_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-5_7_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettings_null_UserDefinedRoomNotificationSettings-Night-6_8_null_0,NEXUS_5,1.0,en].png