From 03d14087e6693a7384bb8d59d49e0a2d0778a92b Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 13 Jan 2026 14:35:49 +0100 Subject: [PATCH] Create spaces (#5982) * Allow creating a space with `CreateRoomParameters` * Add 'Create space' menu item in the spaces home screen. Also, imports new strings related to spaces. * Link the 'Create space' button with the screen to create the space * Unify room access and visibility for `ConfigureRoom`, use the updated design * Fix `EditRoomDetails` avatar size (68dp) * Replace `EditableAvatarView` and `UnsavedAvatar` copmonents with `AvatarPickerView` * `AvatarDataFetcherFactory`: Make sure we use a fallback image fetcher when the URL is not an MXC one (a local one, i.e.). This removes the previous need for a separate `UnsavedAvatarView` * Use `AvatarPickerView` in all the screens where `EditableAvatarView` was used * Improve naming and previews * Update strings, remove unused ones for `RoomAccessItem` * Make `isSpace` part of the `CreateRoomConfig` * Ensure the content fits in the screenshots for `AvatarPickerSizesPreview` * Add `AvatarDataFetcherFactoryTest` * Add new feature flag for creating spaces * Fix ripple being too large for the `Pick` state * Tweak margins and section titles a bit * Add preview for `HomeTopBar` with the spaces case * Update screenshots --------- Co-authored-by: ElementBot --- .../android/appnav/LoggedInFlowNode.kt | 17 + .../createroom/api/CreateRoomEntryPoint.kt | 1 + .../createroom/impl/CreateRoomFlowNode.kt | 15 +- .../impl/DefaultCreateRoomEntryPoint.kt | 4 +- .../impl/configureroom/ConfigureRoomNode.kt | 15 +- .../configureroom/ConfigureRoomPresenter.kt | 22 +- .../ConfigureRoomStateProvider.kt | 12 + .../impl/configureroom/ConfigureRoomView.kt | 177 +++---- .../impl/configureroom/CreateRoomConfig.kt | 1 + .../configureroom/CreateRoomConfigStore.kt | 10 +- .../impl/configureroom/RoomAccessItem.kt | 18 +- .../impl/configureroom/RoomVisibilityItem.kt | 24 +- .../src/main/res/values-be/translations.xml | 4 - .../src/main/res/values-bg/translations.xml | 4 - .../src/main/res/values-cs/translations.xml | 5 - .../src/main/res/values-cy/translations.xml | 5 - .../src/main/res/values-da/translations.xml | 5 - .../src/main/res/values-de/translations.xml | 5 - .../src/main/res/values-el/translations.xml | 5 - .../src/main/res/values-es/translations.xml | 5 - .../src/main/res/values-et/translations.xml | 5 - .../src/main/res/values-eu/translations.xml | 5 - .../src/main/res/values-fa/translations.xml | 5 - .../src/main/res/values-fi/translations.xml | 5 - .../src/main/res/values-fr/translations.xml | 5 - .../src/main/res/values-hr/translations.xml | 5 - .../src/main/res/values-hu/translations.xml | 5 - .../src/main/res/values-in/translations.xml | 5 - .../src/main/res/values-it/translations.xml | 5 - .../src/main/res/values-ka/translations.xml | 2 - .../src/main/res/values-ko/translations.xml | 5 - .../src/main/res/values-lt/translations.xml | 2 - .../src/main/res/values-nb/translations.xml | 5 - .../src/main/res/values-nl/translations.xml | 5 - .../src/main/res/values-pl/translations.xml | 5 - .../main/res/values-pt-rBR/translations.xml | 5 - .../src/main/res/values-pt/translations.xml | 5 - .../src/main/res/values-ro/translations.xml | 5 - .../src/main/res/values-ru/translations.xml | 5 - .../src/main/res/values-sk/translations.xml | 5 - .../src/main/res/values-sv/translations.xml | 5 - .../src/main/res/values-tr/translations.xml | 5 - .../src/main/res/values-uk/translations.xml | 5 - .../src/main/res/values-ur/translations.xml | 2 - .../src/main/res/values-uz/translations.xml | 5 - .../main/res/values-zh-rTW/translations.xml | 5 - .../src/main/res/values-zh/translations.xml | 5 - .../impl/src/main/res/values/localazy.xml | 30 +- .../impl/DefaultCreateRoomEntryPointTest.kt | 1 + .../ConfigureRoomPresenterTest.kt | 2 + .../api/FakeCreateRoomEntryPoint.kt | 1 + .../features/home/api/HomeEntryPoint.kt | 1 + .../features/home/impl/HomeFlowNode.kt | 1 + .../android/features/home/impl/HomeView.kt | 9 +- .../home/impl/components/HomeTopBar.kt | 186 +++++--- .../home/impl/spaces/HomeSpacesPresenter.kt | 5 + .../home/impl/spaces/HomeSpacesState.kt | 1 + .../impl/spaces/HomeSpacesStateProvider.kt | 9 + .../home/impl/DefaultHomeEntryPointTest.kt | 1 + .../home/impl/roomlist/RoomListViewTest.kt | 2 + .../impl/spaces/HomeSpacesPresenterTest.kt | 10 + .../user/editprofile/EditUserProfileView.kt | 22 +- .../impl/src/main/res/values/localazy.xml | 4 +- .../impl/RoomDetailsEditView.kt | 32 +- .../impl/src/main/res/values/localazy.xml | 2 +- .../startchat/impl/StartChatFlowNode.kt | 1 + .../components/avatar/AvatarSize.kt | 2 +- .../libraries/featureflag/api/FeatureFlags.kt | 7 + .../api/createroom/CreateRoomParameters.kt | 1 + .../libraries/matrix/impl/RustMatrixClient.kt | 1 + .../ui/media/AvatarDataFetcherFactory.kt | 20 +- .../ui/media/AvatarDataFetcherFactoryTest.kt | 78 ++++ .../matrix/ui/components/AvatarPickerView.kt | 436 ++++++++++++++++++ .../ui/components/EditableAvatarView.kt | 157 ------- .../matrix/ui/components/UnsavedAvatar.kt | 93 ---- .../ui/room/address/RoomAddressField.kt | 2 +- .../src/main/res/values/localazy.xml | 6 + .../tests/konsist/KonsistPreviewTest.kt | 4 + ...nfigureroom_ConfigureRoomViewDark_0_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_1_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_2_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_3_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_4_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_5_en.png | 4 +- ...nfigureroom_ConfigureRoomViewDark_6_en.png | 3 + ...figureroom_ConfigureRoomViewLight_0_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_1_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_2_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_3_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_4_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_5_en.png | 4 +- ...figureroom_ConfigureRoomViewLight_6_en.png | 3 + ...l.components_HomeTopBarSpaces_Day_0_en.png | 3 + ...components_HomeTopBarSpaces_Night_0_en.png | 3 + ...me.impl.spaces_HomeSpacesView_Day_2_en.png | 3 + ....impl.spaces_HomeSpacesView_Night_2_en.png | 3 + .../features.home.impl_HomeView_Day_4_en.png | 4 +- ...features.home.impl_HomeView_Night_4_en.png | 4 +- ...itprofile_EditUserProfileView_Day_0_en.png | 4 +- ...itprofile_EditUserProfileView_Day_1_en.png | 4 +- ...itprofile_EditUserProfileView_Day_2_en.png | 4 +- ...profile_EditUserProfileView_Night_0_en.png | 4 +- ...profile_EditUserProfileView_Night_1_en.png | 4 +- ...profile_EditUserProfileView_Night_2_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_0_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_1_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_2_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_3_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_4_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_5_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_6_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_7_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_8_en.png | 4 +- ...edit.impl_RoomDetailsEditView_Day_9_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_0_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_1_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_2_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_3_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_4_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_5_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_6_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_7_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_8_en.png | 4 +- ...it.impl_RoomDetailsEditView_Night_9_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_14_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_15_en.png | 4 +- ....root_SecurityAndPrivacyViewDark_16_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_4_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_5_en.png | 4 +- ...l.root_SecurityAndPrivacyViewDark_6_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_14_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_15_en.png | 4 +- ...root_SecurityAndPrivacyViewLight_16_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_4_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_5_en.png | 4 +- ....root_SecurityAndPrivacyViewLight_6_en.png | 4 +- ....components_AvatarPickerSizes_Day_0_en.png | 3 + ...omponents_AvatarPickerSizes_Night_0_en.png | 3 + ...omponents_AvatarPickerViewRtl_Day_0_en.png | 3 + ...ponents_AvatarPickerViewRtl_Night_0_en.png | 3 + ...i.components_AvatarPickerView_Day_0_en.png | 3 + ...components_AvatarPickerView_Night_0_en.png | 3 + ...components_EditableAvatarView_Day_0_en.png | 3 - ...components_EditableAvatarView_Day_1_en.png | 3 - ...components_EditableAvatarView_Day_2_en.png | 3 - ...mponents_EditableAvatarView_Night_0_en.png | 3 - ...mponents_EditableAvatarView_Night_1_en.png | 3 - ...mponents_EditableAvatarView_Night_2_en.png | 3 - ...x.ui.components_UnsavedAvatar_Day_0_en.png | 3 - ...ui.components_UnsavedAvatar_Night_0_en.png | 3 - 150 files changed, 1097 insertions(+), 778 deletions(-) create mode 100644 libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt create mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt delete mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt delete mode 100644 libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 219566d9db..21bdd99a47 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -47,6 +47,7 @@ import io.element.android.appnav.room.RoomFlowNode import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.compound.colors.SemanticColorsLightDark +import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.enterprise.api.EnterpriseService import io.element.android.features.enterprise.api.SessionEnterpriseService import io.element.android.features.ftue.api.FtueEntryPoint @@ -144,6 +145,7 @@ class LoggedInFlowNode( snackbarDispatcher: SnackbarDispatcher, private val analyticsService: AnalyticsService, private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher, + private val createRoomEntryPoint: CreateRoomEntryPoint, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Placeholder, @@ -287,6 +289,9 @@ class LoggedInFlowNode( @Parcelize data object CreateRoom : NavTarget + @Parcelize + data object CreateSpace : NavTarget + @Parcelize data class SecureBackup( val initialElement: SecureBackupEntryPoint.InitialTarget = SecureBackupEntryPoint.InitialTarget.Root @@ -338,6 +343,10 @@ class LoggedInFlowNode( backstack.push(NavTarget.CreateRoom) } + override fun navigateToCreateSpace() { + backstack.push(NavTarget.CreateSpace) + } + override fun navigateToSetUpRecovery() { backstack.push(NavTarget.SecureBackup(initialElement = SecureBackupEntryPoint.InitialTarget.Root)) } @@ -469,6 +478,14 @@ class LoggedInFlowNode( callback = callback, ) } + is NavTarget.CreateSpace -> { + val callback = object : CreateRoomEntryPoint.Callback { + override fun onRoomCreated(roomId: RoomId) { + backstack.replace(NavTarget.Room(roomIdOrAlias = RoomIdOrAlias.Id(roomId), serverNames = emptyList())) + } + } + createRoomEntryPoint.createNode(isSpace = true, parentNode = this, buildContext = buildContext, callback = callback) + } is NavTarget.SecureBackup -> { secureBackupEntryPoint.createNode( parentNode = this, diff --git a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt index 1c6a9f04db..22757aba06 100644 --- a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt +++ b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/CreateRoomEntryPoint.kt @@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomId interface CreateRoomEntryPoint : FeatureEntryPoint { fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: Callback, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt index 7fea6fc0e5..89dbddd186 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt @@ -24,6 +24,7 @@ import io.element.android.features.createroom.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.SessionScope @@ -37,23 +38,29 @@ class CreateRoomFlowNode( @Assisted plugins: List, ) : BaseFlowNode( backstack = BackStack( - initialElement = NavTarget.ConfigureRoom, + initialElement = NavTarget.ConfigureRoom(isSpace = plugins.filterIsInstance().first().isSpace), savedStateMap = buildContext.savedStateMap, ), buildContext = buildContext, plugins = plugins ) { + @Parcelize + data class Inputs( + val isSpace: Boolean + ) : NodeInputs, Parcelable + private val callback: CreateRoomEntryPoint.Callback = callback() override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { - NavTarget.ConfigureRoom -> { + is NavTarget.ConfigureRoom -> { + val inputs = ConfigureRoomNode.Inputs(isSpace = navTarget.isSpace) val callback = object : ConfigureRoomNode.Callback { override fun onCreateRoomSuccess(roomId: RoomId) { backstack.replace(NavTarget.AddPeople(roomId)) } } - createNode(buildContext, plugins = listOf(callback)) + createNode(buildContext, plugins = listOf(inputs, callback)) } is NavTarget.AddPeople -> { val inputs = AddPeopleNode.Inputs(navTarget.roomId) @@ -74,7 +81,7 @@ class CreateRoomFlowNode( sealed interface NavTarget : Parcelable { @Parcelize - data object ConfigureRoom : NavTarget + data class ConfigureRoom(val isSpace: Boolean) : NavTarget @Parcelize data class AddPeople(val roomId: RoomId) : NavTarget diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt index 2261d294cf..63163e7a28 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPoint.kt @@ -18,10 +18,12 @@ import io.element.android.libraries.di.SessionScope @ContributesBinding(SessionScope::class) class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint { override fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: CreateRoomEntryPoint.Callback, ): Node { - return parentNode.createNode(buildContext, listOf(callback)) + val inputs = CreateRoomFlowNode.Inputs(isSpace) + return parentNode.createNode(buildContext, listOf(inputs, callback)) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt index 43ceee3594..e021a7a0f9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt @@ -8,6 +8,7 @@ package io.element.android.features.createroom.impl.configureroom +import android.os.Parcelable import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.bumble.appyx.core.lifecycle.subscribe @@ -18,23 +19,35 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback +import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.parcelize.Parcelize @ContributesNode(SessionScope::class) @AssistedInject class ConfigureRoomNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, - private val presenter: ConfigureRoomPresenter, + presenterFactory: ConfigureRoomPresenter.Factory, private val analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { fun onCreateRoomSuccess(roomId: RoomId) } + @Parcelize + data class Inputs( + val isSpace: Boolean, + ) : NodeInputs, Parcelable + + private val inputs = inputs() + + private val presenter = presenterFactory.create(inputs.isSpace) + init { lifecycle.subscribe( onResume = { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index dbec30c0c5..aef55c77df 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -19,7 +19,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.core.net.toUri -import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.Assisted +import dev.zacsweers.metro.AssistedFactory +import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.CreatedRoom import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter @@ -49,8 +51,9 @@ import kotlinx.coroutines.launch import timber.log.Timber import kotlin.jvm.optionals.getOrDefault -@Inject +@AssistedInject class ConfigureRoomPresenter( + @Assisted private val isSpace: Boolean, private val dataStore: CreateRoomConfigStore, private val matrixClient: MatrixClient, private val mediaPickerProvider: PickerProvider, @@ -61,13 +64,22 @@ class ConfigureRoomPresenter( private val roomAliasHelper: RoomAliasHelper, private val mediaOptimizationConfigProvider: MediaOptimizationConfigProvider, ) : Presenter { + @AssistedFactory + interface Factory { + fun create(isSpace: Boolean): ConfigureRoomPresenter + } + private val cameraPermissionPresenter: PermissionsPresenter = permissionsPresenterFactory.create(android.Manifest.permission.CAMERA) private var pendingPermissionRequest = false + init { + dataStore.setIsSpace(isSpace) + } + @Composable override fun present(): ConfigureRoomState { val cameraPermissionState = cameraPermissionPresenter.present() - val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState(CreateRoomConfig()) + val createRoomConfig by dataStore.getCreateRoomConfigFlow().collectAsState() val homeserverName = remember { matrixClient.userIdServerName() } val isKnockFeatureEnabled by remember { featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) @@ -171,7 +183,8 @@ class ConfigureRoomPresenter( preset = RoomPreset.PUBLIC_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, - roomAliasName = config.roomVisibility.roomAddress() + roomAliasName = config.roomVisibility.roomAddress(), + isSpace = isSpace, ) } else { CreateRoomParameters( @@ -184,6 +197,7 @@ class ConfigureRoomPresenter( preset = RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, + isSpace = isSpace, ) } matrixClient.createRoom(params) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 7f760b46fb..dc78ed7aab 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -78,6 +78,18 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Unit, modifier: Modifier = Modifier, ) { + val isSpace = state.config.isSpace val focusManager = LocalFocusManager.current val isAvatarActionsSheetVisible = remember { mutableStateOf(false) } @@ -81,6 +87,7 @@ fun ConfigureRoomView( modifier = modifier.clearFocusOnTap(focusManager), topBar = { ConfigureRoomToolbar( + isSpace = isSpace, isNextActionEnabled = state.isValid, onBackClick = onBackClick, onNextClick = { @@ -96,9 +103,10 @@ fun ConfigureRoomView( .imePadding() .verticalScroll(rememberScrollState()) .consumeWindowInsets(padding), - verticalArrangement = Arrangement.spacedBy(24.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), ) { RoomNameWithAvatar( + isSpace = isSpace, modifier = Modifier.padding(horizontal = 16.dp), avatarUri = state.config.avatarUri, roomName = state.config.roomName.orEmpty(), @@ -110,37 +118,35 @@ fun ConfigureRoomView( topic = state.config.topic.orEmpty(), onTopicChange = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) }, ) - RoomVisibilityOptions( + + RoomVisibilityAndAccessOptions( selected = when (state.config.roomVisibility) { is RoomVisibilityState.Private -> RoomVisibilityItem.Private - is RoomVisibilityState.Public -> RoomVisibilityItem.Public + is RoomVisibilityState.Public -> when (state.config.roomVisibility.roomAccess) { + RoomAccess.Knocking -> RoomVisibilityItem.AskToJoin + RoomAccess.Anyone -> RoomVisibilityItem.Public + } }, + isKnockingEnabled = state.isKnockFeatureEnabled, onOptionClick = { focusManager.clearFocus() state.eventSink(ConfigureRoomEvents.RoomVisibilityChanged(it)) }, ) - if (state.config.roomVisibility is RoomVisibilityState.Public && state.isKnockFeatureEnabled) { - RoomAccessOptions( - selected = when (state.config.roomVisibility.roomAccess) { - RoomAccess.Anyone -> RoomAccessItem.Anyone - RoomAccess.Knocking -> RoomAccessItem.AskToJoin - }, - onOptionClick = { - focusManager.clearFocus() - state.eventSink(ConfigureRoomEvents.RoomAccessChanged(it)) - }, - ) - RoomAddressField( - modifier = Modifier.padding(horizontal = 16.dp), - address = state.config.roomVisibility.roomAddress.value, - homeserverName = state.homeserverName, - addressValidity = state.roomAddressValidity, - onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) }, - label = stringResource(R.string.screen_create_room_room_address_section_title), - supportingText = stringResource(R.string.screen_create_room_room_address_section_footer), - ) - Spacer(Modifier) + + if (state.config.roomVisibility !is RoomVisibilityState.Private) { + Column { + ListSectionHeader(title = stringResource(R.string.screen_create_room_room_address_section_title)) + RoomAddressField( + modifier = Modifier.padding(horizontal = 16.dp), + address = state.config.roomVisibility.roomAddress().getOrNull().orEmpty(), + homeserverName = state.homeserverName, + addressValidity = state.roomAddressValidity, + onAddressChange = { state.eventSink(ConfigureRoomEvents.RoomAddressChanged(it)) }, + label = null, + supportingText = stringResource(R.string.screen_create_room_room_address_section_footer), + ) + } } } } @@ -156,11 +162,11 @@ fun ConfigureRoomView( async = state.createRoomAction, progressDialog = { AsyncActionViewDefaults.ProgressDialog( - progressText = stringResource(CommonStrings.common_creating_room), + progressText = stringResource(if (isSpace) CommonStrings.common_creating_space else CommonStrings.common_creating_room), ) }, onSuccess = { onCreateRoomSuccess(it) }, - errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) }, + errorMessage = { stringResource(if (isSpace) R.string.screen_create_room_error_creating_space else R.string.screen_create_room_error_creating_room) }, onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom) }, onErrorDismiss = { state.eventSink(ConfigureRoomEvents.CancelCreateRoom) }, ) @@ -173,12 +179,13 @@ fun ConfigureRoomView( @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ConfigureRoomToolbar( + isSpace: Boolean, isNextActionEnabled: Boolean, onBackClick: () -> Unit, onNextClick: () -> Unit, ) { TopAppBar( - titleStr = stringResource(R.string.screen_create_room_title), + titleStr = stringResource(if (isSpace) R.string.screen_create_room_new_space_title else R.string.screen_create_room_new_room_title), navigationIcon = { BackButton(onClick = onBackClick) }, actions = { TextButton( @@ -192,6 +199,7 @@ private fun ConfigureRoomToolbar( @Composable private fun RoomNameWithAvatar( + isSpace: Boolean, avatarUri: String?, roomName: String, onAvatarClick: () -> Unit, @@ -203,25 +211,33 @@ private fun RoomNameWithAvatar( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically, ) { - val a11yAvatar = stringResource(CommonStrings.a11y_room_avatar) - UnsavedAvatar( - avatarUri = avatarUri, - avatarSize = AvatarSize.EditRoomDetails, - avatarType = AvatarType.Room(), - modifier = Modifier - .clickable( - onClick = onAvatarClick, - onClickLabel = stringResource(CommonStrings.action_open_context_menu), - ) - .clearAndSetSemantics { - contentDescription = a11yAvatar - }, - ) + Box( + modifier = Modifier.padding(end = 8.dp).size(AvatarSize.EditRoomDetails.dp), + contentAlignment = Alignment.Center, + ) { + val avatarState = remember(avatarUri) { + if (avatarUri != null) { + AvatarPickerState.Selected( + avatarData = AvatarData(id = "#", name = null, url = avatarUri, size = AvatarSize.EditRoomDetails), + type = if (isSpace) AvatarType.Space() else AvatarType.Room(), + ) + } else { + val containerSize = 48.dp + val padding = PaddingValues((AvatarSize.EditRoomDetails.dp - containerSize) / 2) + AvatarPickerState.Pick(buttonSize = 48.dp, iconSize = 24.dp, externalPadding = padding) + } + } + AvatarPickerView( + state = avatarState, + onClick = onAvatarClick, + ) + } TextField( - label = stringResource(R.string.screen_create_room_room_name_label), + modifier = Modifier.padding(bottom = 18.dp), + label = stringResource(CommonStrings.common_name), value = roomName, - placeholder = stringResource(CommonStrings.common_room_name_placeholder), + placeholder = stringResource(R.string.screen_create_room_name_placeholder), singleLine = true, onValueChange = onChangeRoomName, ) @@ -240,7 +256,7 @@ private fun RoomTopic( value = topic, onValueChange = onTopicChange, maxLines = 3, - supportingText = stringResource(CommonStrings.common_topic_placeholder), + placeholder = stringResource(R.string.screen_create_room_topic_placeholder), keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.Sentences, ), @@ -256,38 +272,58 @@ private fun ConfigureRoomOptions( Column( modifier = modifier.selectableGroup() ) { - Text( - text = title, - style = ElementTheme.typography.fontBodyLgMedium, - color = ElementTheme.colors.textPrimary, - modifier = Modifier.padding(horizontal = 16.dp), - ) + ListSectionHeader(title = title) content() } } @Composable -private fun RoomVisibilityOptions( +private fun RoomVisibilityAndAccessOptions( selected: RoomVisibilityItem, + isKnockingEnabled: Boolean, onOptionClick: (RoomVisibilityItem) -> Unit, modifier: Modifier = Modifier, ) { ConfigureRoomOptions( - title = stringResource(R.string.screen_create_room_room_visibility_section_title), + title = stringResource(R.string.screen_create_room_room_access_section_title), modifier = modifier, ) { RoomVisibilityItem.entries.forEach { item -> + if (item == RoomVisibilityItem.AskToJoin && !isKnockingEnabled) { + return@forEach + } + val isSelected = item == selected ListItem( leadingContent = ListItemContent.Custom { RoundedIconAtom( size = RoundedIconAtomSize.Big, - resourceId = item.icon, + resourceId = when (item) { + RoomVisibilityItem.Public -> CompoundDrawables.ic_compound_public + RoomVisibilityItem.AskToJoin -> CompoundDrawables.ic_compound_user_add + RoomVisibilityItem.Private -> CompoundDrawables.ic_compound_lock + }, tint = if (isSelected) ElementTheme.colors.iconPrimary else ElementTheme.colors.iconSecondary, + backgroundTint = Color.Transparent, ) }, - headlineContent = { Text(text = stringResource(item.title)) }, - supportingContent = { Text(text = stringResource(item.description)) }, + headlineContent = { + val title = when (item) { + RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_title) + RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_title) + RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_title) + } + Text(text = title) + }, + supportingContent = { + // TODO handle description of items in a certain space/org + val description = when (item) { + RoomVisibilityItem.Public -> stringResource(R.string.screen_create_room_public_option_short_description) + RoomVisibilityItem.AskToJoin -> stringResource(R.string.screen_create_room_room_access_section_knocking_option_description) + RoomVisibilityItem.Private -> stringResource(R.string.screen_create_room_private_option_description) + } + Text(text = description) + }, trailingContent = ListItemContent.RadioButton(selected = isSelected), onClick = { onOptionClick(item) }, ) @@ -295,27 +331,6 @@ private fun RoomVisibilityOptions( } } -@Composable -private fun RoomAccessOptions( - selected: RoomAccessItem, - onOptionClick: (RoomAccessItem) -> Unit, - modifier: Modifier = Modifier, -) { - ConfigureRoomOptions( - title = stringResource(R.string.screen_create_room_room_access_section_header), - modifier = modifier, - ) { - RoomAccessItem.entries.forEach { item -> - ListItem( - headlineContent = { Text(text = stringResource(item.title)) }, - supportingContent = { Text(text = stringResource(item.description)) }, - trailingContent = ListItemContent.RadioButton(selected = item == selected), - onClick = { onOptionClick(item) }, - ) - } - } -} - @PreviewWithLargeHeight @Composable internal fun ConfigureRoomViewLightPreview(@PreviewParameter(ConfigureRoomStateProvider::class) state: ConfigureRoomState) = diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt index b9d05a144f..8355047ddf 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfig.kt @@ -13,6 +13,7 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf data class CreateRoomConfig( + val isSpace: Boolean = false, val roomName: String? = null, val topic: String? = null, val avatarUri: String? = null, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt index 5e8637ddd6..81c9638f0c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/CreateRoomConfigStore.kt @@ -72,11 +72,11 @@ class CreateRoomConfigStore( config.copy( roomVisibility = when (visibility) { RoomVisibilityItem.Private -> RoomVisibilityState.Private - RoomVisibilityItem.Public -> { + RoomVisibilityItem.Public, RoomVisibilityItem.AskToJoin -> { val roomAliasName = roomAliasHelper.roomAliasNameFromRoomDisplayName(config.roomName.orEmpty()) RoomVisibilityState.Public( roomAddress = RoomAddress.AutoFilled(roomAliasName), - roomAccess = RoomAccess.Anyone, + roomAccess = if (visibility == RoomVisibilityItem.AskToJoin) RoomAccess.Knocking else RoomAccess.Anyone, ) } } @@ -114,6 +114,12 @@ class CreateRoomConfigStore( } } + fun setIsSpace(isSpace: Boolean) { + createRoomConfigFlow.getAndUpdate { config -> + config.copy(isSpace = isSpace) + } + } + fun clearCachedData() { cachedAvatarUri = null } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt index 2d37be9103..9d140b952c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccessItem.kt @@ -8,19 +8,7 @@ package io.element.android.features.createroom.impl.configureroom -import androidx.annotation.StringRes -import io.element.android.features.createroom.impl.R - -enum class RoomAccessItem( - @StringRes val title: Int, - @StringRes val description: Int -) { - Anyone( - title = R.string.screen_create_room_room_access_section_anyone_option_title, - description = R.string.screen_create_room_room_access_section_anyone_option_description, - ), - AskToJoin( - title = R.string.screen_create_room_room_access_section_knocking_option_title, - description = R.string.screen_create_room_room_access_section_knocking_option_description, - ), +enum class RoomAccessItem { + Anyone, + AskToJoin, } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt index b92dee4d6e..feff1ee90f 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityItem.kt @@ -8,24 +8,8 @@ package io.element.android.features.createroom.impl.configureroom -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import io.element.android.features.createroom.impl.R -import io.element.android.libraries.designsystem.icons.CompoundDrawables - -enum class RoomVisibilityItem( - @DrawableRes val icon: Int, - @StringRes val title: Int, - @StringRes val description: Int -) { - Private( - icon = CompoundDrawables.ic_compound_lock, - title = R.string.screen_create_room_private_option_title, - description = R.string.screen_create_room_private_option_description, - ), - Public( - icon = CompoundDrawables.ic_compound_public, - title = R.string.screen_create_room_public_option_title, - description = R.string.screen_create_room_public_option_description, - ) +enum class RoomVisibilityItem { + Public, + AskToJoin, + Private } diff --git a/features/createroom/impl/src/main/res/values-be/translations.xml b/features/createroom/impl/src/main/res/values-be/translations.xml index f5d6a234e2..23d70a3b3d 100644 --- a/features/createroom/impl/src/main/res/values-be/translations.xml +++ b/features/createroom/impl/src/main/res/values-be/translations.xml @@ -8,10 +8,6 @@ "Любы можа знайсці гэты пакой. Вы можаце змяніць гэта ў любы час у наладах пакоя." "Публічны пакой" - "Хто заўгодна" - "Доступ у пакой" "Папрасіце далучыцца" - "Назва пакоя" - "Стварыце пакой" "Тэма (неабавязкова)" diff --git a/features/createroom/impl/src/main/res/values-bg/translations.xml b/features/createroom/impl/src/main/res/values-bg/translations.xml index 249058b7af..83fb24e691 100644 --- a/features/createroom/impl/src/main/res/values-bg/translations.xml +++ b/features/createroom/impl/src/main/res/values-bg/translations.xml @@ -8,11 +8,7 @@ "Всеки може да намери тази стая. Можете да промените това по всяко време в настройките на стаята." "Общодостъпна стая" - "Всеки може да се присъедини към тази стая" - "Всеки" "За да бъде тази стая видима в директорията на общодостъпните стаи, ще ви е необходим адрес на стаята." - "Име на стаята" "Видимост на стаята" - "Създаване на стая" "Тема за разговор (незадължително)" diff --git a/features/createroom/impl/src/main/res/values-cs/translations.xml b/features/createroom/impl/src/main/res/values-cs/translations.xml index e19cfbcf91..af95081f1d 100644 --- a/features/createroom/impl/src/main/res/values-cs/translations.xml +++ b/features/createroom/impl/src/main/res/values-cs/translations.xml @@ -8,15 +8,10 @@ "Tuto místnost může najít kdokoli. To můžete kdykoli změnit v nastavení místnosti." "Veřejná místnost" - "Do této místnosti může vstoupit kdokoli" - "Kdokoliv" - "Přístup do místnosti" "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout" "Požádat o připojení" "Aby byla tato místnost viditelná v adresáři veřejných místností, budete potřebovat adresu místnosti." "Adresa místnosti" - "Název místnosti" "Viditelnost místnosti" - "Vytvořit místnost" "Téma (nepovinné)" diff --git a/features/createroom/impl/src/main/res/values-cy/translations.xml b/features/createroom/impl/src/main/res/values-cy/translations.xml index 52168014bf..741022659c 100644 --- a/features/createroom/impl/src/main/res/values-cy/translations.xml +++ b/features/createroom/impl/src/main/res/values-cy/translations.xml @@ -8,15 +8,10 @@ "Gall unrhyw un ddod o hyd i\'r ystafell hon. Gallwch newid hyn unrhyw bryd yng ngosodiadau ystafell." "Ystafell gyhoeddus" - "Gall unrhyw un ymuno â\'r ystafell hon" - "Unrhyw un" - "Mynediad i\'r Ystafell" "Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais" "Gofyn i gael ymuno" "Er mwyn i\'r ystafell hon fod yn weladwy yn y cyfeiriadur ystafelloedd cyhoeddus, bydd angen cyfeiriad ystafell arnoch." "Cyfeiriad yr ystafell" - "Enw\'r ystafell" "Gwelededd yr ystafell" - "Creu ystafell" "Pwnc (dewisol)" diff --git a/features/createroom/impl/src/main/res/values-da/translations.xml b/features/createroom/impl/src/main/res/values-da/translations.xml index 1a69f150fb..45261f2a29 100644 --- a/features/createroom/impl/src/main/res/values-da/translations.xml +++ b/features/createroom/impl/src/main/res/values-da/translations.xml @@ -8,15 +8,10 @@ "Alle kan finde dette rum. Du kan ændre dette når som helst i rummets indstillinger." "Offentligt rum" - "Alle kan deltage i dette rum" - "Enhver" - "Adgang til rummet" "Alle kan bede om at deltage i rummet, men en administrator eller en moderator skal acceptere anmodningen" "Spørg om at deltage" "Hvis dette rum skal være synligt i det offentlige register, skal du bruge en rum-adresse." "Rummets adresse" - "Navn på rum" "Rummets synlighed" - "Opret et rum" "Emne (valgfrit)" diff --git a/features/createroom/impl/src/main/res/values-de/translations.xml b/features/createroom/impl/src/main/res/values-de/translations.xml index 9c48001c92..692a2c921e 100644 --- a/features/createroom/impl/src/main/res/values-de/translations.xml +++ b/features/createroom/impl/src/main/res/values-de/translations.xml @@ -8,15 +8,10 @@ "Jeder kann diesen Chat finden. Du kannst dies jederzeit in den Einstellungen des Chats ändern." "Öffentlicher Chat" - "Jeder darf diesem Chat beitreten" - "Jeder" - "Chat Zugang" "Jeder kann den Beitritt zum Chat erbitten, aber ein Admin oder Moderator muss die Anfrage akzeptieren." "Beitritt beantragen" "Du benötigst eine Chat-Adresse, damit dieser Chat im öffentlichen Verzeichnis sichtbar ist." "Chatroom Adresse" - "Chat-Name" " Sichtbarkeit des Chats" - "Chat erstellen" "Thema (optional)" diff --git a/features/createroom/impl/src/main/res/values-el/translations.xml b/features/createroom/impl/src/main/res/values-el/translations.xml index 37ccd49d0e..a8c500df94 100644 --- a/features/createroom/impl/src/main/res/values-el/translations.xml +++ b/features/createroom/impl/src/main/res/values-el/translations.xml @@ -8,15 +8,10 @@ "Ο καθένας μπορεί να βρει αυτή την αίθουσα. Αυτό μπορείτε να το αλλάξετε ανά πάσα στιγμή στις ρυθμίσεις της αίθουσας." "Δημόσια αίθουσα" - "Οποιοσδήποτε μπορεί να συμμετάσχει σε αυτή την αίθουσα" - "Οποιοσδήποτε" - "Πρόσβαση στην Αίθουσα" "Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή ένας συντονιστής θα πρέπει να αποδεχτεί το αίτημα" "Αίτημα συμμετοχής" "Για να είναι ορατή αυτή η αίθουσα στον δημόσιο κατάλογο αιθουσών, θα χρειαστείτε μια διεύθυνση αίθουσας." "Διεύθυνση δωματίου" - "Όνομα αίθουσας" "Ορατότητα αίθουσας" - "Δημιουργία αίθουσας" "Θέμα (προαιρετικό)" diff --git a/features/createroom/impl/src/main/res/values-es/translations.xml b/features/createroom/impl/src/main/res/values-es/translations.xml index 64806977c0..fcf2996398 100644 --- a/features/createroom/impl/src/main/res/values-es/translations.xml +++ b/features/createroom/impl/src/main/res/values-es/translations.xml @@ -8,14 +8,9 @@ "Cualquiera puede encontrar esta sala. Puedes cambiar esto en cualquier momento en los ajustes de la sala." "Sala pública" - "Cualquiera puede unirse a esta sala" - "Cualquiera" - "Acceso a la sala" "Cualquiera puede solicitar unirse a la sala, pero un administrador o un moderador tendrá que aceptar la solicitud" "Solicitud para unirse" "Para que esta sala sea visible en el directorio de salas públicas, necesitarás una dirección de sala." - "Nombre de la sala" "Visibilidad de la sala" - "Crear una sala" "Tema (opcional)" diff --git a/features/createroom/impl/src/main/res/values-et/translations.xml b/features/createroom/impl/src/main/res/values-et/translations.xml index 98449f4817..c81caebede 100644 --- a/features/createroom/impl/src/main/res/values-et/translations.xml +++ b/features/createroom/impl/src/main/res/values-et/translations.xml @@ -8,15 +8,10 @@ "Kõik saavad seda jututuba leida. Sa võid seda jututoa seadistustest alati muuta." "Avalik jututuba" - "Kõik võivad selle jututoaga liituda" - "Kõik kasutajad" - "Ligipääs jututoale" "Kõik võivad paluda selle jututoaga liitumist, kuid peakasutaja või moderaator peavad selle kinnitama" "Küsi võimalust liitumiseks" "Selleks, et see jututuba oleks nähtav jututubade avalikus kataloogis, sa vajad jututoa aadressi." "Jututoa aadress" - "Jututoa nimi" "Jututoa nähtavus" - "Loo jututuba" "Teema (kui soovid lisada)" diff --git a/features/createroom/impl/src/main/res/values-eu/translations.xml b/features/createroom/impl/src/main/res/values-eu/translations.xml index 537aa495a5..f4b6d405b7 100644 --- a/features/createroom/impl/src/main/res/values-eu/translations.xml +++ b/features/createroom/impl/src/main/res/values-eu/translations.xml @@ -8,12 +8,7 @@ "Edonork aurki dezake gela hau. Gelaren ezarpenetan aldatu dezakezu hobespena." "Gela publikoa" - "Edonor sar daiteke gela honetara" - "Edonork" - "Gelarako sarbidea" "Gelaren helbidea" - "Gelaren izena" "Gelaren ikusgarritasuna" - "Sortu gela" "Mintzagaia (aukerakoa)" diff --git a/features/createroom/impl/src/main/res/values-fa/translations.xml b/features/createroom/impl/src/main/res/values-fa/translations.xml index 09869c76f6..dad5298a0f 100644 --- a/features/createroom/impl/src/main/res/values-fa/translations.xml +++ b/features/createroom/impl/src/main/res/values-fa/translations.xml @@ -8,13 +8,8 @@ "هرکسی می‌تواند اتاق را بیابد. می‌توانید بعداً در تظیمات اتاق عوضش کنید." "اتاق عمومی" - "هرکسی می‌تواند به این اتاق بپیوندد" - "هرکسی" - "دسترسی اتاق" "درخواست دعوت" "نشانی اتاق" - "نام اتاق" "نمایانی اتاق" - "ایجاد اتاق" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-fi/translations.xml b/features/createroom/impl/src/main/res/values-fi/translations.xml index df541d3dee..3b120947cc 100644 --- a/features/createroom/impl/src/main/res/values-fi/translations.xml +++ b/features/createroom/impl/src/main/res/values-fi/translations.xml @@ -8,15 +8,10 @@ "Kuka tahansa voi löytää tämän huoneen. Voit muuttaa tämän milloin tahansa huoneen asetuksista." "Julkinen huone" - "Kuka tahansa voi liittyä tähän huoneeseen" - "Kuka tahansa" - "Huoneeseen Pääsy" "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö" "Pyydä liittymistä" "Jotta tämä huone näkyisi julkisessa huonehakemistossa, tarvitset huoneen osoitteen." "Huoneen osoite" - "Huoneen nimi" "Huoneen näkyvyys" - "Luo huone" "Aihe (valinnainen)" diff --git a/features/createroom/impl/src/main/res/values-fr/translations.xml b/features/createroom/impl/src/main/res/values-fr/translations.xml index afbdc919ba..d500902949 100644 --- a/features/createroom/impl/src/main/res/values-fr/translations.xml +++ b/features/createroom/impl/src/main/res/values-fr/translations.xml @@ -8,15 +8,10 @@ "N’importe qui peut trouver ce salon. Vous pouvez modifier cela à tout moment dans les paramètres du salon." "Salon public" - "Tout le monde peut rejoindre ce salon" - "Tout le monde" - "Accès au salon" "Tout le monde peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande" "Demander à rejoindre" "Pour que ce salon soit visible dans le répertoire des salons publics, vous aurez besoin d’une adresse de salon." "Adresse du salon" - "Nom du salon" "Visibilité du salon" - "Créer un salon" "Sujet (facultatif)" diff --git a/features/createroom/impl/src/main/res/values-hr/translations.xml b/features/createroom/impl/src/main/res/values-hr/translations.xml index 1d6d7e5af7..510bd68659 100644 --- a/features/createroom/impl/src/main/res/values-hr/translations.xml +++ b/features/createroom/impl/src/main/res/values-hr/translations.xml @@ -8,15 +8,10 @@ "Svatko može pronaći ovu sobu. To možete u svakom trenutku promijeniti u postavkama sobe." "Javna soba" - "Svatko se može pridružiti ovoj sobi" - "Svatko" - "Pristup sobi" "Svatko može zatražiti pridruživanje sobi, ali administrator ili moderator morat će prihvatiti zahtjev." "Zatraži pridruživanje" "Da bi ova soba bila vidljiva u javnom direktoriju soba, trebat će vam adresa sobe." "Adresa sobe" - "Naziv sobe" "Vidljivost sobe" - "Stvori sobu" "Tema (neobavezno)" diff --git a/features/createroom/impl/src/main/res/values-hu/translations.xml b/features/createroom/impl/src/main/res/values-hu/translations.xml index 24f71983ce..bfa1205b05 100644 --- a/features/createroom/impl/src/main/res/values-hu/translations.xml +++ b/features/createroom/impl/src/main/res/values-hu/translations.xml @@ -8,15 +8,10 @@ "Bárki megtalálhatja ezt a szobát. Ezt bármikor módosíthatja a szobabeállításokban." "Nyilvános szoba" - "Bárki csatlakozhat ehhez a szobához" - "Bárki" - "Szobahozzáférés" "Bárki kérheti, hogy csatlakozzon a szobához, de egy adminisztrátornak vagy moderátornak el kell fogadnia a kérést" "Csatlakozás kérése" "Ahhoz, hogy ez a szoba látható legyen a nyilvános szobák címtárában, meg kell adnia a szoba címét." "Szoba címe" - "Szoba neve" "Szoba láthatósága" - "Szoba létrehozása" "Téma (nem kötelező)" diff --git a/features/createroom/impl/src/main/res/values-in/translations.xml b/features/createroom/impl/src/main/res/values-in/translations.xml index 219f621068..014fc8a628 100644 --- a/features/createroom/impl/src/main/res/values-in/translations.xml +++ b/features/createroom/impl/src/main/res/values-in/translations.xml @@ -8,15 +8,10 @@ "Siapa pun dapat mencari ruangan ini. Anda dapat mengubah ini kapan pun dalam pengaturan ruangan." "Ruangan publik" - "Siapa pun dapat bergabung dengan ruangan ini" - "Siapa pun" - "Akses Ruangan" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut" "Minta untuk bergabung" "Supaya ruangan ini terlihat di direktori ruangan publik, Anda memerlukan alamat ruangan." "Alamat ruangan" - "Nama ruangan" "Keterlihatan ruangan" - "Buat ruangan" "Topik (opsional)" diff --git a/features/createroom/impl/src/main/res/values-it/translations.xml b/features/createroom/impl/src/main/res/values-it/translations.xml index 741b88b763..980fb5c660 100644 --- a/features/createroom/impl/src/main/res/values-it/translations.xml +++ b/features/createroom/impl/src/main/res/values-it/translations.xml @@ -8,15 +8,10 @@ "Chiunque può trovare questa stanza. Puoi modificarlo in qualsiasi momento nelle impostazioni della stanza." "Stanza pubblica" - "Chiunque può entrare in questa stanza" - "Chiunque" - "Accesso alla stanza" "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta" "Chiedi di entrare" "Affinché questa stanza sia visibile nell\'elenco delle stanze pubbliche, è necessario un indirizzo della stanza." "Indirizzo della stanza" - "Nome stanza" "Visibilità della stanza" - "Crea una stanza" "Argomento (facoltativo)" diff --git a/features/createroom/impl/src/main/res/values-ka/translations.xml b/features/createroom/impl/src/main/res/values-ka/translations.xml index 20c7af40de..de1e33bd68 100644 --- a/features/createroom/impl/src/main/res/values-ka/translations.xml +++ b/features/createroom/impl/src/main/res/values-ka/translations.xml @@ -7,7 +7,5 @@ "კერძო ოთახი" "ყველას ამ ოთახის მოძებნა შეუძლია. თქვენ ნებისმიერ დროს შეგიძლიათ ამის შეცვლა ოთახის პარამეტრებში." - "ოთახის სახელი" - "ოთახის შექმნა" "თემა (სურვილისამებრ)" diff --git a/features/createroom/impl/src/main/res/values-ko/translations.xml b/features/createroom/impl/src/main/res/values-ko/translations.xml index 3dfdc46e7c..e861333e9b 100644 --- a/features/createroom/impl/src/main/res/values-ko/translations.xml +++ b/features/createroom/impl/src/main/res/values-ko/translations.xml @@ -8,14 +8,9 @@ "누구나 이 방을 찾을 수 있습니다. 방 설정에서 언제든지 변경할 수 있습니다." "공개 방" - "누구나 이 방에 참여할 수 있습니다." - "누구나" - "방 액세스" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." "참가 요청" "이 방이 공개 방 디렉토리에 표시되려면 방 주소가 필요합니다." - "방 이름" "방 표시 여부" - "방 만들기" "주제 (선택)" diff --git a/features/createroom/impl/src/main/res/values-lt/translations.xml b/features/createroom/impl/src/main/res/values-lt/translations.xml index 2fb7b3eb5c..e392f57717 100644 --- a/features/createroom/impl/src/main/res/values-lt/translations.xml +++ b/features/createroom/impl/src/main/res/values-lt/translations.xml @@ -7,7 +7,5 @@ "Privatus kambarys" "Bet kas gali rasti šį kambarį. Tai galite bet kada pakeisti kambario nustatymuose." - "Kambario pavadinimas" - "Kurti kambarį" "Tema (nebūtina)" diff --git a/features/createroom/impl/src/main/res/values-nb/translations.xml b/features/createroom/impl/src/main/res/values-nb/translations.xml index e6021cf5ac..14a8c53e52 100644 --- a/features/createroom/impl/src/main/res/values-nb/translations.xml +++ b/features/createroom/impl/src/main/res/values-nb/translations.xml @@ -8,15 +8,10 @@ "Alle kan finne dette rommet. Du kan endre dette når som helst i rominnstillingene." "Offentlig rom" - "Alle kan bli med i dette rommet" - "Alle" - "Tilgang til rom" "Alle kan be om å få bli med i rommet, men en administrator eller moderator må godta forespørselen" "Be om å bli med" "For at dette rommet skal være synlig i den offentlige romkatalogen, trenger du en romadresse." "Romadresse" - "Romnavn" "Romsynlighet" - "Opprett et rom" "Emne (valgfritt)" diff --git a/features/createroom/impl/src/main/res/values-nl/translations.xml b/features/createroom/impl/src/main/res/values-nl/translations.xml index 5142148171..8af8b11621 100644 --- a/features/createroom/impl/src/main/res/values-nl/translations.xml +++ b/features/createroom/impl/src/main/res/values-nl/translations.xml @@ -8,12 +8,7 @@ "Iedereen kan deze kamer vinden. Je kunt dit op elk gewenst moment wijzigen in de kamerinstellingen." "Openbare kamer" - "Iedereen kan toetreden tot deze kamer" - "Iedereen" - "Toegang tot de kamer" "Iedereen kan vragen om toe te treden tot de kamer, maar een beheerder of moderator moet het verzoek accepteren" "Vraag om toe te treden" - "Naam van de kamer" - "Creëer een kamer" "Onderwerp (optioneel)" diff --git a/features/createroom/impl/src/main/res/values-pl/translations.xml b/features/createroom/impl/src/main/res/values-pl/translations.xml index 446644b622..f79c2cbb32 100644 --- a/features/createroom/impl/src/main/res/values-pl/translations.xml +++ b/features/createroom/impl/src/main/res/values-pl/translations.xml @@ -8,15 +8,10 @@ "Każdy może znaleźć ten pokój. Możesz to zmienić w ustawieniach pokoju." "Pokój publiczny" - "Każdy może dołączyć do tego pokoju" - "Wszyscy" - "Dostęp do pokoju" "Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić prośbę" "Poproś o dołączenie" "Aby ten pokój był widoczny w katalogu pomieszczeń publicznych, będziesz potrzebował adres pokoju." "Adres pokoju" - "Nazwa pokoju" "Widoczność pomieszczenia" - "Utwórz pokój" "Temat (opcjonalnie)" diff --git a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml index 399c9fec17..becc333d0d 100644 --- a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml @@ -8,15 +8,10 @@ "Qualquer um pode encontrar esta sala. Você pode mudar isso a qualquer momento nas configurações da sala." "Sala pública" - "Qualquer pessoa pode entrar nesta sala" - "Qualquer pessoa" - "Acesso à sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação" "Pedir para entrar" "Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala." "Endereço da sala" - "Nome da sala" "Visibilidade da sala" - "Criar uma sala" "Tópico (opcional)" diff --git a/features/createroom/impl/src/main/res/values-pt/translations.xml b/features/createroom/impl/src/main/res/values-pt/translations.xml index 1524914bb2..942c39edf3 100644 --- a/features/createroom/impl/src/main/res/values-pt/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt/translations.xml @@ -8,15 +8,10 @@ "Qualquer um pode encontrar esta sala. Pode alterar esta opção nas definições da sala." "Sala pública" - "Qualquer pessoa pode entrar nesta sala" - "Qualquer pessoa" - "Acesso à sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou um moderador terá de aceitar o pedido" "Pedir para participar" "Para que esta sala seja visível no diretório público de salas, precisas de um endereço de sala." "Endereço da sala" - "Nome da sala" "Visibilidade da sala" - "Criar uma sala" "Descrição (opcional)" diff --git a/features/createroom/impl/src/main/res/values-ro/translations.xml b/features/createroom/impl/src/main/res/values-ro/translations.xml index b9fe78bb19..e4a3e0dba1 100644 --- a/features/createroom/impl/src/main/res/values-ro/translations.xml +++ b/features/createroom/impl/src/main/res/values-ro/translations.xml @@ -8,15 +8,10 @@ "Oricine poate găsi această cameră. Puteți modifica acest lucru oricând în setări." "Cameră publică" - "Oricine se poate alătura acestei camere" - "Oricine" - "Acces la cameră" "Oricine poate cere să se alăture camerei, dar un administrator sau un moderator va trebui să accepte cererea" "Cereți să vă alăturați" "Pentru ca această cameră să fie vizibilă în directorul de camere publice, veți avea nevoie de o adresă de cameră." "Adresa camerei" - "Numele camerei" "Vizibilitatea camerei" - "Creați o cameră" "Subiect (opțional)" diff --git a/features/createroom/impl/src/main/res/values-ru/translations.xml b/features/createroom/impl/src/main/res/values-ru/translations.xml index e871673114..68cdad1ad4 100644 --- a/features/createroom/impl/src/main/res/values-ru/translations.xml +++ b/features/createroom/impl/src/main/res/values-ru/translations.xml @@ -8,15 +8,10 @@ "Любой желающий может найти эту комнату. Вы можете изменить это в любое время в настройках комнаты." "Общедоступная комната" - "Любой желающий может присоединиться к этой комнате" - "Любой" - "Доступ в комнату" "Любой желающий может подать заявку на присоединение к комнате, но администратор или модератор должен будет принять запрос." "Попросить присоединиться" "Чтобы эта комната была видна в каталоге общедоступных, вам необходим ее адрес" "Адрес комнаты" - "Название комнаты" "Видимость комнаты" - "Создать комнату" "Тема (необязательно)" diff --git a/features/createroom/impl/src/main/res/values-sk/translations.xml b/features/createroom/impl/src/main/res/values-sk/translations.xml index 7b6d89b2e1..dacec52b33 100644 --- a/features/createroom/impl/src/main/res/values-sk/translations.xml +++ b/features/createroom/impl/src/main/res/values-sk/translations.xml @@ -8,15 +8,10 @@ "Túto miestnosť môže nájsť ktokoľvek. Môžete to kedykoľvek zmeniť v nastaveniach miestnosti." "Verejná miestnosť" - "Do tejto miestnosti sa môže pripojiť ktokoľvek" - "Ktokoľvek" - "Prístup do miestnosti" "Ktokoľvek môže požiadať o pripojenie sa k miestnosti, ale administrátor alebo moderátor bude musieť žiadosť schváliť" "Požiadať o pripojenie" "Aby bola táto miestnosť viditeľná v adresári verejných miestností, budete potrebovať adresu miestnosti." "Adresa miestnosti" - "Názov miestnosti" "Viditeľnosť miestnosti" - "Vytvoriť miestnosť" "Téma (voliteľné)" diff --git a/features/createroom/impl/src/main/res/values-sv/translations.xml b/features/createroom/impl/src/main/res/values-sv/translations.xml index 8cd01ebd0e..3c0de1aa65 100644 --- a/features/createroom/impl/src/main/res/values-sv/translations.xml +++ b/features/createroom/impl/src/main/res/values-sv/translations.xml @@ -8,15 +8,10 @@ "Vem som helst kan hitta det här rummet. Du kan ändra detta när som helst i rumsinställningarna." "Offentligt rum" - "Vem som helst kan gå med i det här rummet" - "Vem som helst" - "Rumsåtkomst" "Vem som helst kan be om att gå med i rummet men en administratör eller en moderator måste acceptera begäran" "Be om att gå med" "För att detta rum ska vara synligt i den allmänna rumskatalogen behöver du en rumsadress." "Rumsadress" - "Rumsnamn" "Rumssynlighet" - "Skapa ett rum" "Ämne (valfritt)" diff --git a/features/createroom/impl/src/main/res/values-tr/translations.xml b/features/createroom/impl/src/main/res/values-tr/translations.xml index d97139c973..b5a8f131a0 100644 --- a/features/createroom/impl/src/main/res/values-tr/translations.xml +++ b/features/createroom/impl/src/main/res/values-tr/translations.xml @@ -8,15 +8,10 @@ "Bu odayı herkes bulabilir. Bunu istediğiniz zaman oda ayarlarından değiştirebilirsiniz." "Herkese açık oda" - "Bu odaya herkes katılabilir" - "Herkes" - "Oda Erişimi" "Herkes odaya katılmayı isteyebilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekecektir" "Katılmak için sor" "Bu odanın genel oda dizininde görünür olması için bir oda adresine ihtiyacınız olacaktır." "Oda adresi" - "Oda adı" "Oda görünürlüğü" - "Bir oda oluştur" "Konu (isteğe bağlı)" diff --git a/features/createroom/impl/src/main/res/values-uk/translations.xml b/features/createroom/impl/src/main/res/values-uk/translations.xml index 047b4dd9d2..e83359b89c 100644 --- a/features/createroom/impl/src/main/res/values-uk/translations.xml +++ b/features/createroom/impl/src/main/res/values-uk/translations.xml @@ -8,15 +8,10 @@ "Будь-хто може знайти цю кімнату. Ви можете змінити це в будь-який час у налаштуваннях кімнати." "Загальнодоступна кімната" - "Будь-хто може приєднатися до цієї кімнати" - "Кожний" - "Доступ до кімнати" "Будь-хто може попросити приєднатися до кімнати, але адміністратор або модератор повинен буде прийняти запит" "Запросити приєднатися" "Щоб цю кімнату було видно в каталозі загальнодоступних кімнат, вам знадобиться її адреса." "Адреса кімнати" - "Назва кімнати" "Видимість кімнати" - "Створити кімнату" "Тема (необов\'язково)" diff --git a/features/createroom/impl/src/main/res/values-ur/translations.xml b/features/createroom/impl/src/main/res/values-ur/translations.xml index b68992085f..1783963c67 100644 --- a/features/createroom/impl/src/main/res/values-ur/translations.xml +++ b/features/createroom/impl/src/main/res/values-ur/translations.xml @@ -8,7 +8,5 @@ "کوئی بھی یہ کمرہ ڈھونڈ سکتا ہے۔ آپ اسے کمرے کی ترتیبات میں کسی بھی وقت تبدیل کرسکتے ہیں۔" "عوامی کمرہ" - "کمرے کا نام" - "ایک کمرہ بنائیں" "موضوع (اختیاری)" diff --git a/features/createroom/impl/src/main/res/values-uz/translations.xml b/features/createroom/impl/src/main/res/values-uz/translations.xml index 34062f9669..665851ce02 100644 --- a/features/createroom/impl/src/main/res/values-uz/translations.xml +++ b/features/createroom/impl/src/main/res/values-uz/translations.xml @@ -8,14 +8,9 @@ "Bu xonani har kim topishi mumkin. Buni xona sozlamalaridan istalgan vaqtda oʻzgartirishingiz mumkin." "Jamoat xonasi" - "Bu xonaga istalgan kishi qo‘shilishi mumkin" - "Har kim" - "Xonaga kirish" "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" "Qo‘shilishni so‘rang" "Ushbu xona ommaviy xonalar ro‘yxatida ko‘rinishi uchun sizga xona manzili kerak bo‘ladi." - "Xona nomi" "Xonaning ko‘rinishi" - "Xonani yaratish" "Mavzu (ixtiyoriy)" diff --git a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml index 476f9cff7e..065e05f321 100644 --- a/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh-rTW/translations.xml @@ -8,15 +8,10 @@ "任何人都可以找到此聊天室。 您隨時都可以在聊天室設定中變更此設定。" "公開的聊天室" - "任何人都可以加入此聊天室" - "任何人" - "聊天室存取權" "任何人都可以要求加入聊天室,但管理員或版主必須接受該請求" "要求加入" "為了讓此聊天室在公開聊天室目錄中可見,您需要聊天室地址。" "聊天室地址" - "聊天室名稱" "聊天室能見度" - "建立聊天室" "主題(非必填)" diff --git a/features/createroom/impl/src/main/res/values-zh/translations.xml b/features/createroom/impl/src/main/res/values-zh/translations.xml index d20e34801d..f17accb9fd 100644 --- a/features/createroom/impl/src/main/res/values-zh/translations.xml +++ b/features/createroom/impl/src/main/res/values-zh/translations.xml @@ -8,15 +8,10 @@ "任何人都能找到此聊天室。 你可以随时在聊天室设置中更改。" "公共聊天室" - "任何人都可以加入此房间" - "任何人" - "房间访问权限" "任何人都可以请求加入房间,但必须由管理员或审核人接受" "请求加入" "要使该房间在公开房间目录中可见,您需要一个房间地址。" "房间地址" - "聊天室名称" "房间可见性" - "创建聊天室" "主题(可选)" diff --git a/features/createroom/impl/src/main/res/values/localazy.xml b/features/createroom/impl/src/main/res/values/localazy.xml index fa9a1cb276..3ec2d9d6f3 100644 --- a/features/createroom/impl/src/main/res/values/localazy.xml +++ b/features/createroom/impl/src/main/res/values/localazy.xml @@ -3,20 +3,26 @@ "New room" "Invite people" "An error occurred when creating the room" - "Only people invited can access this room. All messages are end-to-end encrypted." - "Private room" + "The space could not be created because of an unknown error. Try again later." + "Add name…" + "New room" + "New space" + "Only people invited can join." + "Private" "Anyone can find this room. You can change this anytime in room settings." - "Public room" - "Anyone can join this room" - "Anyone" - "Room Access" - "Anyone can ask to join the room but an administrator or a moderator will have to accept the request" - "Ask to join" - "In order for this room to be visible in the public room directory, you will need a room address." - "Room address" - "Room name" + "Anyone can join." + "Public" + "Anyone can ask to join but an administrator or a moderator must accept the request." + "Allow ask to join" + "Only people invited can join." + "Private" + "Anyone can join." + "Public" + "Who has access" + "You’ll need an address in order to make it visible in the public directory." + "Address" "Room visibility" - "Create a room" "Topic (optional)" + "Add description…" diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt index 35b6637bbf..5b7a6c1142 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultCreateRoomEntryPointTest.kt @@ -40,6 +40,7 @@ class DefaultCreateRoomEntryPointTest { override fun onRoomCreated(roomId: RoomId) = lambdaError() } val result = entryPoint.createNode( + isSpace = false, parentNode = parentNode, buildContext = BuildContext.root(null), callback = callback, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt index 6de15904d7..e82d8c3912 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/startchat/impl/configureroom/ConfigureRoomPresenterTest.kt @@ -380,6 +380,7 @@ class ConfigureRoomPresenterTest { ) private fun createConfigureRoomPresenter( + isSpace: Boolean = false, roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(), dataStore: CreateRoomConfigStore = CreateRoomConfigStore(roomAliasHelper), matrixClient: MatrixClient = createMatrixClient(), @@ -390,6 +391,7 @@ class ConfigureRoomPresenterTest { isKnockFeatureEnabled: Boolean = true, mediaOptimizationConfigProvider: FakeMediaOptimizationConfigProvider = FakeMediaOptimizationConfigProvider(), ) = ConfigureRoomPresenter( + isSpace = isSpace, dataStore = dataStore, matrixClient = matrixClient, mediaPickerProvider = pickerProvider, diff --git a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt index 2beaecf013..bbeb69c26b 100644 --- a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt +++ b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/api/FakeCreateRoomEntryPoint.kt @@ -14,6 +14,7 @@ import io.element.android.tests.testutils.lambda.lambdaError class FakeCreateRoomEntryPoint : CreateRoomEntryPoint { override fun createNode( + isSpace: Boolean, parentNode: Node, buildContext: BuildContext, callback: CreateRoomEntryPoint.Callback, diff --git a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt index 71ee093985..1a90245611 100644 --- a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt +++ b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt @@ -25,6 +25,7 @@ interface HomeEntryPoint : FeatureEntryPoint { interface Callback : Plugin { fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) fun navigateToCreateRoom() + fun navigateToCreateSpace() fun navigateToSettings() fun navigateToSetUpRecovery() fun navigateToEnterRecoveryKey() diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt index d9f87e2edd..0e92761bd5 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt @@ -220,6 +220,7 @@ class HomeFlowNode( onRoomClick = ::navigateToRoom, onSettingsClick = callback::navigateToSettings, onStartChatClick = callback::navigateToCreateRoom, + onCreateSpaceClick = callback::navigateToCreateSpace, onSetUpRecoveryClick = callback::navigateToSetUpRecovery, onConfirmRecoveryKeyClick = callback::navigateToEnterRecoveryKey, onRoomSettingsClick = callback::navigateToRoomSettings, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt index 1b05fc99ec..f55183feb0 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeView.kt @@ -74,6 +74,7 @@ fun HomeView( onSetUpRecoveryClick: () -> Unit, onConfirmRecoveryKeyClick: () -> Unit, onStartChatClick: () -> Unit, + onCreateSpaceClick: () -> Unit, onRoomSettingsClick: (roomId: RoomId) -> Unit, onMenuActionClick: (RoomListMenuAction) -> Unit, onReportRoomClick: (roomId: RoomId) -> Unit, @@ -113,6 +114,7 @@ fun HomeView( onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) }, onOpenSettings = { if (firstThrottler.canHandle()) onSettingsClick() }, onStartChatClick = { if (firstThrottler.canHandle()) onStartChatClick() }, + onCreateSpaceClick = { if (firstThrottler.canHandle()) onCreateSpaceClick() }, onMenuActionClick = onMenuActionClick, ) // This overlaid view will only be visible when state.displaySearchResults is true @@ -138,6 +140,7 @@ private fun HomeScaffold( onRoomClick: (RoomId) -> Unit, onOpenSettings: () -> Unit, onStartChatClick: () -> Unit, + onCreateSpaceClick: () -> Unit, onMenuActionClick: (RoomListMenuAction) -> Unit, modifier: Modifier = Modifier, ) { @@ -164,6 +167,7 @@ private fun HomeScaffold( modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { HomeTopBar( + selectedNavigationItem = state.currentHomeNavigationBarItem, title = stringResource(state.currentHomeNavigationBarItem.labelRes), currentUserAndNeighbors = state.currentUserAndNeighbors, showAvatarIndicator = state.showAvatarIndicator, @@ -174,10 +178,11 @@ private fun HomeScaffold( onAccountSwitch = { state.eventSink(HomeEvents.SwitchToAccount(it)) }, + onCreateSpace = onCreateSpaceClick, scrollBehavior = scrollBehavior, - displayMenuItems = state.displayActions, displayFilters = state.displayRoomListFilters, filtersState = roomListState.filtersState, + canCreateSpaces = state.homeSpacesState.canCreateSpaces, canReportBug = state.canReportBug, modifier = Modifier.hazeEffect( state = hazeState, @@ -328,6 +333,7 @@ internal fun HomeViewPreview(@PreviewParameter(HomeStateProvider::class) state: onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {}, + onCreateSpaceClick = {}, onRoomSettingsClick = {}, onReportRoomClick = {}, onMenuActionClick = {}, @@ -347,6 +353,7 @@ internal fun HomeViewA11yPreview() = ElementPreview { onSetUpRecoveryClick = {}, onConfirmRecoveryKeyClick = {}, onStartChatClick = {}, + onCreateSpaceClick = {}, onRoomSettingsClick = {}, onReportRoomClick = {}, onMenuActionClick = {}, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt index 093b91fb66..c92a5b9fb8 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/HomeTopBar.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp import io.element.android.appconfig.RoomListConfig import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.features.home.impl.HomeNavigationBarItem import io.element.android.features.home.impl.R import io.element.android.features.home.impl.filters.RoomListFiltersState import io.element.android.features.home.impl.filters.RoomListFiltersView @@ -73,6 +74,7 @@ import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeTopBar( + selectedNavigationItem: HomeNavigationBarItem, title: String, currentUserAndNeighbors: ImmutableList, showAvatarIndicator: Boolean, @@ -81,8 +83,9 @@ fun HomeTopBar( onMenuActionClick: (RoomListMenuAction) -> Unit, onOpenSettings: () -> Unit, onAccountSwitch: (SessionId) -> Unit, + onCreateSpace: () -> Unit, scrollBehavior: TopAppBarScrollBehavior, - displayMenuItems: Boolean, + canCreateSpaces: Boolean, canReportBug: Boolean, displayFilters: Boolean, filtersState: RoomListFiltersState, @@ -117,63 +120,16 @@ fun HomeTopBar( ) }, actions = { - if (displayMenuItems) { - IconButton( - onClick = onToggleSearch, - ) { - Icon( - imageVector = CompoundIcons.Search(), - contentDescription = stringResource(CommonStrings.action_search), - ) - } - if (RoomListConfig.HAS_DROP_DOWN_MENU) { - var showMenu by remember { mutableStateOf(false) } - IconButton( - onClick = { showMenu = !showMenu } - ) { - Icon( - imageVector = CompoundIcons.OverflowVertical(), - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu, - onDismissRequest = { showMenu = false } - ) { - if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClick(RoomListMenuAction.InviteFriends) - }, - text = { Text(stringResource(id = CommonStrings.action_invite)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ShareAndroid(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) - } - ) - } - if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) { - DropdownMenuItem( - onClick = { - showMenu = false - onMenuActionClick(RoomListMenuAction.ReportBug) - }, - text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, - leadingIcon = { - Icon( - imageVector = CompoundIcons.ChatProblem(), - tint = ElementTheme.colors.iconSecondary, - contentDescription = null, - ) - } - ) - } - } - } + when (selectedNavigationItem) { + HomeNavigationBarItem.Chats -> RoomListMenuItems( + onToggleSearch = onToggleSearch, + onMenuActionClick = onMenuActionClick, + canReportBug = canReportBug + ) + HomeNavigationBarItem.Spaces -> SpacesMenuItems( + canCreateSpaces = canCreateSpaces, + onCreateSpace = onCreateSpace + ) } }, // We want a 16dp left padding for the navigationIcon : @@ -193,6 +149,85 @@ fun HomeTopBar( } } +@Composable +private fun RoomListMenuItems( + onToggleSearch: () -> Unit, + onMenuActionClick: (RoomListMenuAction) -> Unit, + canReportBug: Boolean, +) { + IconButton( + onClick = onToggleSearch, + ) { + Icon( + imageVector = CompoundIcons.Search(), + contentDescription = stringResource(CommonStrings.action_search), + ) + } + if (RoomListConfig.HAS_DROP_DOWN_MENU) { + var showMenu by remember { mutableStateOf(false) } + IconButton( + onClick = { showMenu = !showMenu } + ) { + Icon( + imageVector = CompoundIcons.OverflowVertical(), + contentDescription = null, + ) + } + DropdownMenu( + expanded = showMenu, + onDismissRequest = { showMenu = false } + ) { + if (RoomListConfig.SHOW_INVITE_MENU_ITEM) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClick(RoomListMenuAction.InviteFriends) + }, + text = { Text(stringResource(id = CommonStrings.action_invite)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ShareAndroid(), + tint = ElementTheme.colors.iconSecondary, + contentDescription = null, + ) + } + ) + } + if (RoomListConfig.SHOW_REPORT_PROBLEM_MENU_ITEM && canReportBug) { + DropdownMenuItem( + onClick = { + showMenu = false + onMenuActionClick(RoomListMenuAction.ReportBug) + }, + text = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, + leadingIcon = { + Icon( + imageVector = CompoundIcons.ChatProblem(), + tint = ElementTheme.colors.iconSecondary, + contentDescription = null, + ) + } + ) + } + } + } +} + +@Composable +private fun SpacesMenuItems( + canCreateSpaces: Boolean, + onCreateSpace: () -> Unit +) { + if (canCreateSpaces) { + IconButton(onClick = onCreateSpace) { + Icon( + imageVector = CompoundIcons.Plus(), + contentDescription = stringResource(CommonStrings.action_create_space) + ) + } + } +} + @Composable private fun NavigationIcon( currentUserAndNeighbors: ImmutableList, @@ -273,6 +308,7 @@ private fun AccountIcon( @Composable internal fun HomeTopBarPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), showAvatarIndicator = false, @@ -281,7 +317,8 @@ internal fun HomeTopBarPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), @@ -289,11 +326,35 @@ internal fun HomeTopBarPreview() = ElementPreview { ) } +@OptIn(ExperimentalMaterial3Api::class) +@PreviewsDayNight +@Composable +internal fun HomeTopBarSpacesPreview() = ElementPreview { + HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Spaces, + title = stringResource(R.string.screen_home_tab_spaces), + currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), + showAvatarIndicator = false, + areSearchResultsDisplayed = false, + scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()), + onOpenSettings = {}, + onAccountSwitch = {}, + onToggleSearch = {}, + onCreateSpace = {}, + canCreateSpaces = true, + canReportBug = true, + displayFilters = false, + filtersState = aRoomListFiltersState(), + onMenuActionClick = {}, + ) +} + @OptIn(ExperimentalMaterial3Api::class) @PreviewsDayNight @Composable internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = persistentListOf(MatrixUser(UserId("@id:domain"), "Alice")), showAvatarIndicator = true, @@ -302,7 +363,8 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), @@ -315,6 +377,7 @@ internal fun HomeTopBarWithIndicatorPreview() = ElementPreview { @Composable internal fun HomeTopBarMultiAccountPreview() = ElementPreview { HomeTopBar( + selectedNavigationItem = HomeNavigationBarItem.Chats, title = stringResource(R.string.screen_roomlist_main_space_title), currentUserAndNeighbors = aMatrixUserList().take(3).toImmutableList(), showAvatarIndicator = false, @@ -323,7 +386,8 @@ internal fun HomeTopBarMultiAccountPreview() = ElementPreview { onOpenSettings = {}, onAccountSwitch = {}, onToggleSearch = {}, - displayMenuItems = true, + onCreateSpace = {}, + canCreateSpaces = true, canReportBug = true, displayFilters = true, filtersState = aRoomListFiltersState(), diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt index a890a61ac3..00129235fe 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenter.kt @@ -15,6 +15,8 @@ import androidx.compose.runtime.remember import dev.zacsweers.metro.Inject import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.ui.safety.rememberHideInvitesAvatar import kotlinx.collections.immutable.persistentListOf @@ -27,9 +29,11 @@ import kotlinx.coroutines.flow.map class HomeSpacesPresenter( private val client: MatrixClient, private val seenInvitesStore: SeenInvitesStore, + private val featureFlagsService: FeatureFlagService, ) : Presenter { @Composable override fun present(): HomeSpacesState { + val canCreateSpaces by featureFlagsService.isFeatureEnabledFlow(FeatureFlags.CreateSpaces).collectAsState(false) val hideInvitesAvatar by client.rememberHideInvitesAvatar() val spaceRooms by remember { client.spaceService.spaceRoomsFlow.map { it.toImmutableList() } @@ -48,6 +52,7 @@ class HomeSpacesPresenter( spaceRooms = spaceRooms, seenSpaceInvites = seenSpaceInvites, hideInvitesAvatar = hideInvitesAvatar, + canCreateSpaces = canCreateSpaces, eventSink = ::handleEvent, ) } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt index 7dcb370219..9bcf7131c8 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesState.kt @@ -18,6 +18,7 @@ data class HomeSpacesState( val spaceRooms: ImmutableList, val seenSpaceInvites: ImmutableSet, val hideInvitesAvatar: Boolean, + val canCreateSpaces: Boolean, val eventSink: (HomeSpacesEvents) -> Unit, ) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt index 8c03cff7ee..c1a32a1f34 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesStateProvider.kt @@ -30,6 +30,13 @@ open class HomeSpacesStateProvider : PreviewParameterProvider { ), spaceRooms = aListOfSpaceRooms(), ), + aHomeSpacesState( + space = CurrentSpace.Space( + spaceRoom = aSpaceRoom(roomId = RoomId("!mySpace:example.com")) + ), + spaceRooms = aListOfSpaceRooms(), + canCreateSpaces = false, + ), ) } @@ -38,12 +45,14 @@ internal fun aHomeSpacesState( spaceRooms: List = aListOfSpaceRooms(), seenSpaceInvites: Set = emptySet(), hideInvitesAvatar: Boolean = false, + canCreateSpaces: Boolean = true, eventSink: (HomeSpacesEvents) -> Unit = {}, ) = HomeSpacesState( space = space, spaceRooms = spaceRooms.toImmutableList(), seenSpaceInvites = seenSpaceInvites.toImmutableSet(), hideInvitesAvatar = hideInvitesAvatar, + canCreateSpaces = canCreateSpaces, eventSink = eventSink, ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt index 9778556dd2..582de66414 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt @@ -47,6 +47,7 @@ class DefaultHomeEntryPointTest { val callback = object : HomeEntryPoint.Callback { override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) = lambdaError() override fun navigateToCreateRoom() = lambdaError() + override fun navigateToCreateSpace() = lambdaError() override fun navigateToSettings() = lambdaError() override fun navigateToSetUpRecovery() = lambdaError() override fun navigateToEnterRecoveryKey() = lambdaError() diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt index bb82d51a79..a07093aa9f 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt @@ -273,6 +273,7 @@ private fun AndroidComposeTestRule.setRoomL onSetUpRecoveryClick: () -> Unit = EnsureNeverCalled(), onConfirmRecoveryKeyClick: () -> Unit = EnsureNeverCalled(), onCreateRoomClick: () -> Unit = EnsureNeverCalled(), + onCreateSpaceClick: () -> Unit = EnsureNeverCalled(), onRoomSettingsClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(), onMenuActionClick: (RoomListMenuAction) -> Unit = EnsureNeverCalledWithParam(), onReportRoomClick: (RoomId) -> Unit = EnsureNeverCalledWithParam(), @@ -286,6 +287,7 @@ private fun AndroidComposeTestRule.setRoomL onSetUpRecoveryClick = onSetUpRecoveryClick, onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick, onStartChatClick = onCreateRoomClick, + onCreateSpaceClick = onCreateSpaceClick, onRoomSettingsClick = onRoomSettingsClick, onMenuActionClick = onMenuActionClick, onDeclineInviteAndBlockUser = onDeclineInviteAndBlockUser, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt index c7608833ac..43d3a8896d 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/spaces/HomeSpacesPresenterTest.kt @@ -11,6 +11,9 @@ package io.element.android.features.home.impl.spaces import com.google.common.truth.Truth.assertThat import io.element.android.features.invite.api.SeenInvitesStore import io.element.android.features.invite.test.InMemorySeenInvitesStore +import io.element.android.libraries.featureflag.api.FeatureFlagService +import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.tests.testutils.test @@ -23,18 +26,25 @@ class HomeSpacesPresenterTest { val presenter = createPresenter() presenter.test { val state = awaitItem() + // canCreateSpaces is initially false + assertThat(state.canCreateSpaces).isFalse() assertThat(state.space).isEqualTo(CurrentSpace.Root) assertThat(state.spaceRooms).isEmpty() assertThat(state.hideInvitesAvatar).isFalse() assertThat(state.seenSpaceInvites).isEmpty() + + // It'll eventually be true + assertThat(awaitItem().canCreateSpaces).isTrue() } } private fun createPresenter( client: MatrixClient = FakeMatrixClient(), seenInvitesStore: SeenInvitesStore = InMemorySeenInvitesStore(), + featureFlagsService: FeatureFlagService = FakeFeatureFlagService(initialState = mapOf(FeatureFlags.CreateSpaces.key to true)), ) = HomeSpacesPresenter( client = client, seenInvitesStore = seenInvitesStore, + featureFlagsService = featureFlagsService, ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt index 5b42440101..e997f08d65 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt @@ -34,6 +34,7 @@ import io.element.android.features.preferences.impl.R import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults +import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton @@ -47,7 +48,8 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet -import io.element.android.libraries.matrix.ui.components.EditableAvatarView +import io.element.android.libraries.matrix.ui.components.AvatarPickerState +import io.element.android.libraries.matrix.ui.components.AvatarPickerView import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.ui.strings.CommonStrings @@ -103,13 +105,17 @@ fun EditUserProfileView( .verticalScroll(rememberScrollState()) ) { Spacer(modifier = Modifier.height(24.dp)) - EditableAvatarView( - matrixId = state.userId.value, - displayName = state.displayName, - avatarUrl = state.userAvatarUrl, - avatarSize = AvatarSize.EditProfileDetails, - avatarType = AvatarType.User, - onAvatarClick = { onAvatarClick() }, + val avatarPickerState = remember(state.userAvatarUrl) { + val size = AvatarSize.EditProfileDetails + val type = AvatarType.User + AvatarPickerState.Selected( + avatarData = AvatarData(id = state.userId.value, name = state.displayName, size = size, url = state.userAvatarUrl), + type = type + ) + } + AvatarPickerView( + state = avatarPickerState, + onClick = ::onAvatarClick, modifier = Modifier.align(Alignment.CenterHorizontally), ) Spacer(modifier = Modifier.height(16.dp)) diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index cd90edf709..ca00571dd1 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -63,7 +63,7 @@ "Profile" "Requests to join" "Roles & permissions" - "Room name" + "Name" "Security & privacy" "Security" "Share room" @@ -143,7 +143,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Enable end-to-end encryption" "Anyone can join." "Anyone" - "Choose which spaces’ members can join this room without an invitation. %1$s" + "Choose which spaces’ members can join this room without an invitation. %1$s" "Manage spaces" "Only invited people can join." "Invite only" diff --git a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt index aedb9bd16b..d2de2ba260 100644 --- a/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt +++ b/features/roomdetailsedit/impl/src/main/kotlin/io/element/android/features/roomdetailsedit/impl/RoomDetailsEditView.kt @@ -13,7 +13,6 @@ package io.element.android.features.roomdetailsedit.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding @@ -24,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource @@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults +import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton @@ -45,7 +46,8 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet -import io.element.android.libraries.matrix.ui.components.EditableAvatarView +import io.element.android.libraries.matrix.ui.components.AvatarPickerState +import io.element.android.libraries.matrix.ui.components.AvatarPickerView import io.element.android.libraries.permissions.api.PermissionsView import io.element.android.libraries.ui.strings.CommonStrings @@ -99,20 +101,18 @@ fun RoomDetailsEditView( .verticalScroll(rememberScrollState()) ) { Spacer(modifier = Modifier.height(24.dp)) - EditableAvatarView( - matrixId = state.roomId.value, - // As per Element Web, we use the raw name for the avatar as well - displayName = state.roomRawName, - avatarUrl = state.roomAvatarUrl, - avatarSize = AvatarSize.EditRoomDetails, - avatarType = if (state.isSpace) { - AvatarType.Space() - } else { - AvatarType.Room() - }, - enabled = state.canChangeAvatar, - onAvatarClick = ::onAvatarClick, - modifier = Modifier.fillMaxWidth(), + val avatarPickerState = remember(state.roomAvatarUrl) { + val size = AvatarSize.EditRoomDetails + val type = AvatarType.Room() + AvatarPickerState.Selected( + avatarData = AvatarData(id = state.roomId.value, name = state.roomRawName, size = size, url = state.roomAvatarUrl), + type = type + ) + } + AvatarPickerView( + state = avatarPickerState, + onClick = ::onAvatarClick, + modifier = Modifier.align(Alignment.CenterHorizontally), ) Spacer(modifier = Modifier.height(32.dp)) diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index 902a89d7bd..5cb5cdf5ec 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -22,7 +22,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Enable end-to-end encryption" "Anyone can join." "Anyone" - "Choose which spaces’ members can join this room without an invitation. %1$s" + "Choose which spaces’ members can join this room without an invitation. %1$s" "Manage spaces" "Only invited people can join." "Invite only" diff --git a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt index 236d92fd4a..c7d9aa4fd0 100644 --- a/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt +++ b/features/startchat/impl/src/main/kotlin/io/element/android/features/startchat/impl/StartChatFlowNode.kt @@ -81,6 +81,7 @@ class StartChatFlowNode( } } createRoomEntryPoint.createNode( + isSpace = false, parentNode = this, buildContext = buildContext, callback = callback, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 0f99349494..4124d7a967 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -46,7 +46,7 @@ enum class AvatarSize(val dp: Dp) { RoomInviteItem(52.dp), InviteSender(16.dp), - EditRoomDetails(70.dp), + EditRoomDetails(68.dp), RoomListManageUser(96.dp), NotificationsOptIn(32.dp), diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 08bdaf942f..a77e09711f 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -70,6 +70,13 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), + CreateSpaces( + key = "feature.createSpaces", + title = "Create spaces", + description = "Allow creating spaces.", + defaultValue = { false }, + isFinished = false, + ), SpaceSettings( key = "feature.spaceSettings", title = "Space settings", diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt index a0a0bde1ed..1f23d32df6 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt @@ -26,4 +26,5 @@ data class CreateRoomParameters( val joinRuleOverride: JoinRule? = null, val historyVisibilityOverride: RoomHistoryVisibility? = null, val roomAliasName: Optional = Optional.empty(), + val isSpace: Boolean = false, ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 4cb84abc03..b4f39d2693 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -393,6 +393,7 @@ class RustMatrixClient( joinRuleOverride = createRoomParams.joinRuleOverride?.map(), historyVisibilityOverride = createRoomParams.historyVisibilityOverride?.map(), canonicalAlias = createRoomParams.roomAliasName.getOrNull(), + isSpace = createRoomParams.isSpace, ) val roomId = RoomId(innerClient.createRoom(rustParams)) // Wait to receive the room back from the sync but do not returns failure if it fails. diff --git a/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt b/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt index b6093cd327..9d7767e42d 100644 --- a/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt +++ b/libraries/matrixmedia/impl/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactory.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.matrix.ui.media import coil3.ImageLoader import coil3.fetch.Fetcher import coil3.request.Options +import coil3.toUri import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.media.MatrixMediaLoader @@ -21,10 +22,19 @@ internal class AvatarDataFetcherFactory( data: AvatarData, options: Options, imageLoader: ImageLoader - ): Fetcher { - return CoilMediaFetcher( - mediaLoader = matrixMediaLoader, - mediaData = data.toMediaRequestData(), - ) + ): Fetcher? { + return when { + data.url == null -> null + data.url?.startsWith("mxc") == true -> CoilMediaFetcher( + mediaLoader = matrixMediaLoader, + mediaData = data.toMediaRequestData(), + ) + else -> { + // If the URL does not use the mxc scheme, it might be a local one using `content://`, try using a fallback fetcher + data.url?.toUri()?.let { uri -> + imageLoader.components.newFetcher(uri, options, imageLoader) + }?.first + } + } } } diff --git a/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt b/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt new file mode 100644 index 0000000000..eefacb3065 --- /dev/null +++ b/libraries/matrixmedia/impl/src/test/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataFetcherFactoryTest.kt @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2026 Element Creations 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.libraries.matrix.ui.media + +import android.graphics.Bitmap +import coil3.ComponentRegistry +import coil3.ImageLoader +import coil3.asImage +import coil3.disk.DiskCache +import coil3.memory.MemoryCache +import coil3.request.Disposable +import coil3.request.ImageRequest +import coil3.request.ImageResult +import coil3.request.Options +import coil3.request.SuccessResult +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.designsystem.components.avatar.anAvatarData +import io.element.android.libraries.matrix.test.media.FakeMatrixMediaLoader +import io.mockk.mockk +import org.junit.Test + +class AvatarDataFetcherFactoryTest { + @Test + fun `create - with mxc returns CoilMediaFetcher`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcher = factory.create(anAvatarData(url = "mxc://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcher).isInstanceOf(CoilMediaFetcher::class.java) + } + + @Test + fun `create - with http or https returns null, which means fallback default fetcher will be used`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcherHttp = factory.create(anAvatarData(url = "http://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcherHttp).isNull() + + val fetcherHttps = factory.create(anAvatarData(url = "https://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcherHttps).isNull() + } + + @Test + fun `create - with content scheme returns null, which means fallback default fetcher will be used`() { + val factory = AvatarDataFetcherFactory(matrixMediaLoader = FakeMatrixMediaLoader()) + + val fetcher = factory.create(anAvatarData(url = "content://test"), Options(mockk()), imageLoader = FakeImageLoader()) + assertThat(fetcher).isNull() + } +} + +private class FakeImageLoader : ImageLoader { + override val defaults: ImageRequest.Defaults = ImageRequest.Defaults.DEFAULT + override val components: ComponentRegistry = ComponentRegistry.Builder().build() + override val memoryCache: MemoryCache? = null + override val diskCache: DiskCache? = null + + override fun enqueue(request: ImageRequest): Disposable { + return mockk() + } + + override suspend fun execute(request: ImageRequest): ImageResult { + return SuccessResult( + image = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).asImage(), + request = request, + ) + } + + override fun shutdown() {} + + override fun newBuilder(): ImageLoader.Builder { + return ImageLoader.Builder(mockk()) + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt new file mode 100644 index 0000000000..1c904e891b --- /dev/null +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AvatarPickerView.kt @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2026 Element Creations 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.libraries.matrix.ui.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.CompositingStrategy +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.avatar.AvatarType +import io.element.android.libraries.designsystem.icons.CompoundDrawables +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.HorizontalDivider +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.testtags.TestTags +import io.element.android.libraries.testtags.testTag +import io.element.android.libraries.ui.strings.CommonStrings + +/** + * Avatar picker view, based on https://www.figma.com/design/kcnHxunG1LDWXsJhaNuiHz/ER-145--Spaces-on-Element-X?node-id=5918-97417&t=JYDQysgjS33AZb74-4 + * + * It takes a [state], which can be [AvatarPickerState.Pick] for displaying the 'pick avatar' button, or [AvatarPickerState.Selected] when an avatar has + * already been selected. + * + * Note: this function contains lots of 'magic numbers', but those are just the fractions used to scale the different dimensions based on the Figma design. + */ +@Composable +fun AvatarPickerView( + state: AvatarPickerState, + modifier: Modifier = Modifier, + onClick: (() -> Unit) = {}, + onClickLabel: String? = stringResource(CommonStrings.a11y_edit_avatar), + enabled: Boolean = true, +) { + val a11yAvatar = stringResource(CommonStrings.a11y_avatar) + + val clickableModifier = Modifier.clickable( + enabled = enabled, + interactionSource = remember { MutableInteractionSource() }, + onClickLabel = onClickLabel, + onClick = onClick, + indication = ripple(bounded = false), + ) + .testTag(TestTags.editAvatar) + .clearAndSetSemantics { + contentDescription = a11yAvatar + } + + val layoutDirection = LocalLayoutDirection.current + + fun eraseBackgroundModifier( + parentWidth: Dp, + editIconRadius: Dp, + ) = Modifier + .graphicsLayer { + compositingStrategy = CompositingStrategy.Offscreen + } + .drawWithContent { + drawContent() + drawCircle( + color = Color.Black, + center = Offset( + x = if (layoutDirection == LayoutDirection.Ltr) { + parentWidth.toPx() - editIconRadius.toPx() * 0.48f + } else { + editIconRadius.toPx() * 0.48f + }, + y = size.height - editIconRadius.toPx(), + ), + radius = editIconRadius.toPx() * 1.2f, + blendMode = BlendMode.Clear, + ) + } + + when (state) { + is AvatarPickerState.Pick -> { + PickButton( + buttonSize = state.buttonSize, + iconSize = state.iconSize, + iconId = state.iconId, + modifier = modifier.padding(state.externalPadding).then(clickableModifier), + ) + } + is AvatarPickerState.Selected -> { + Box(modifier = modifier) { + Avatar( + avatarData = state.avatarData, + avatarType = state.type, + modifier = clickableModifier.then(eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f)), + ) + + OverlayEditButton(editButtonSize = state.avatarData.size.dp * 0.44f) + } + } + } +} + +@Composable +private fun PickButton( + buttonSize: Dp, + iconSize: Dp, + @DrawableRes iconId: Int, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .size(buttonSize) + .clip(CircleShape) + .border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape) + ) { + Icon( + resourceId = iconId, + contentDescription = null, + modifier = Modifier + .align(Alignment.Center) + .size(iconSize), + tint = ElementTheme.colors.iconPrimary, + ) + } +} + +@Composable +private fun BoxScope.OverlayEditButton(editButtonSize: Dp) { + Box( + modifier = Modifier.align(Alignment.BottomEnd) + .size(editButtonSize) + .offset(x = editButtonSize * 0.266f) + .clip(CircleShape) + .background(ElementTheme.colors.bgCanvasDefault) + .border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape), + contentAlignment = Alignment.Center, + ) { + Icon( + modifier = Modifier.size(editButtonSize * 0.66f), + imageVector = CompoundIcons.Edit(), + contentDescription = null, + ) + } +} + +@Immutable +sealed interface AvatarPickerState { + data class Pick( + val buttonSize: Dp, + val iconSize: Dp = buttonSize / 2, + val externalPadding: PaddingValues = PaddingValues.Zero, + @DrawableRes val iconId: Int = CompoundDrawables.ic_compound_take_photo, + ) : AvatarPickerState + + data class Selected( + val avatarData: AvatarData, + val type: AvatarType, + ) : AvatarPickerState +} + +@PreviewsDayNight +@Composable +internal fun AvatarPickerViewPreview() = ElementPreview { + PreviewContent() +} + +@PreviewsDayNight +@Composable +internal fun AvatarPickerViewRtlPreview() = CompositionLocalProvider( + LocalLayoutDirection provides LayoutDirection.Rtl, +) { + ElementPreview { PreviewContent() } +} + +@PreviewsDayNight +@Composable +internal fun AvatarPickerSizesPreview() = ElementPreview { + Column { + Row { + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 24.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 32.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 64.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 96.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + } + Row { + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + } + Row { + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.TimelineThreadLatestEventSender), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.ReadReceiptList), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.SelectedUser), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.RoomListManageUser), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(6.dp) + ) + } + } +} + +@Composable +private fun PreviewContent() { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text("Pick image") + AvatarPickerView(AvatarPickerState.Pick(buttonSize = 48.dp, externalPadding = PaddingValues(6.dp)), onClick = {}) + HorizontalDivider() + + Text("User avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("@user:example.com", "User", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.User + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + HorizontalDivider() + + Text("Room avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Room", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Room() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + HorizontalDivider() + + Text("Space avatar") + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("No url") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", null, size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("Local") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", "content://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text("MXC") + AvatarPickerView( + AvatarPickerState.Selected( + avatarData = AvatarData("!room:example.com", "Space", "mxc://test", size = AvatarSize.EditRoomDetails), + type = AvatarType.Space() + ), + onClick = {}, + modifier = Modifier.padding(10.dp) + ) + } + } + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt deleted file mode 100644 index 284ffcbab1..0000000000 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/EditableAvatarView.kt +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-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.libraries.matrix.ui.components - -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.BlendMode -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.CompositingStrategy -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.clearAndSetSemantics -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons -import io.element.android.libraries.designsystem.components.avatar.Avatar -import io.element.android.libraries.designsystem.components.avatar.AvatarData -import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.avatar.AvatarType -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.utils.CommonDrawables -import io.element.android.libraries.testtags.TestTags -import io.element.android.libraries.testtags.testTag -import io.element.android.libraries.ui.strings.CommonStrings - -@Composable -fun EditableAvatarView( - matrixId: String, - displayName: String?, - avatarUrl: String?, - avatarSize: AvatarSize, - avatarType: AvatarType, - onAvatarClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, -) { - val a11yAvatar = stringResource(CommonStrings.a11y_avatar) - val editIconRadius = 15.dp - val parentHeight = avatarSize.dp - val parentWidth = avatarSize.dp + editIconRadius / 2f - Box( - modifier = modifier - .wrapContentSize() - .size(height = parentHeight, width = parentWidth) - .clickable( - enabled = enabled, - interactionSource = remember { MutableInteractionSource() }, - onClickLabel = stringResource(CommonStrings.a11y_edit_avatar), - onClick = onAvatarClick, - indication = ripple(bounded = false), - ) - .testTag(TestTags.editAvatar) - .clearAndSetSemantics { - contentDescription = a11yAvatar - }, - ) { - Box( - modifier = Modifier - .graphicsLayer { - compositingStrategy = CompositingStrategy.Offscreen - } - .drawWithContent { - drawContent() - drawCircle( - color = Color.Black, - center = Offset( - x = parentWidth.toPx() - editIconRadius.toPx(), - y = size.height - editIconRadius.toPx(), - ), - radius = (editIconRadius + 4.dp).toPx(), - blendMode = BlendMode.Clear, - ) - } - ) { - when { - avatarUrl == null || avatarUrl.startsWith("mxc://") -> { - Avatar( - avatarData = AvatarData( - id = matrixId, - name = displayName, - url = avatarUrl, - size = avatarSize, - ), - avatarType = avatarType, - ) - } - else -> { - UnsavedAvatar( - avatarUri = avatarUrl, - avatarSize = avatarSize, - avatarType = avatarType, - ) - } - } - } - Icon( - modifier = Modifier - .align(Alignment.BottomEnd) - .size(editIconRadius * 2) - .border(1.dp, ElementTheme.colors.borderInteractiveSecondary, CircleShape) - .padding(6.dp), - imageVector = CompoundIcons.Edit(), - contentDescription = null, - tint = ElementTheme.colors.iconPrimary, - ) - } -} - -@PreviewsDayNight -@Composable -internal fun EditableAvatarViewPreview( - @PreviewParameter(EditableAvatarViewUriProvider::class) uri: String? -) = ElementPreview( - drawableFallbackForImages = CommonDrawables.sample_avatar, -) { - EditableAvatarView( - matrixId = "id", - displayName = "Room", - avatarUrl = uri, - avatarSize = AvatarSize.RoomDetailsHeader, - avatarType = AvatarType.User, - onAvatarClick = {}, - ) -} - -open class EditableAvatarViewUriProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - null, - "mxc://matrix.org/123456", - "https://example.com/avatar.jpg", - ) -} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt deleted file mode 100644 index 104a418360..0000000000 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/UnsavedAvatar.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-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.libraries.matrix.ui.components - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.AddAPhoto -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.painter.ColorPainter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage -import coil3.request.ImageRequest -import io.element.android.compound.theme.ElementTheme -import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.avatar.AvatarType -import io.element.android.libraries.designsystem.components.avatar.avatarShape -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.temporaryColorBgSpecial - -/** - * An avatar that the user has selected, but which has not yet been uploaded to Matrix. - * - * The image is loaded from a local resource instead of from a MXC URI. - */ -@Composable -fun UnsavedAvatar( - avatarUri: String?, - avatarSize: AvatarSize, - avatarType: AvatarType, - modifier: Modifier = Modifier, -) { - val commonModifier = modifier - .size(avatarSize.dp) - .clip(avatarType.avatarShape(avatarSize.dp)) - - if (avatarUri != null) { - val context = LocalContext.current - val model = ImageRequest.Builder(context) - .data(avatarUri) - .build() - AsyncImage( - modifier = commonModifier, - model = model, - placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant), - contentScale = ContentScale.Crop, - contentDescription = null, - ) - } else { - Box(modifier = commonModifier.background(ElementTheme.colors.temporaryColorBgSpecial)) { - Icon( - imageVector = Icons.Outlined.AddAPhoto, - contentDescription = null, - modifier = Modifier - .align(Alignment.Center) - .size(avatarSize.dp * 4 / 7), - tint = ElementTheme.colors.iconSecondary, - ) - } - } -} - -@PreviewsDayNight -@Composable -internal fun UnsavedAvatarPreview() = ElementPreview { - Row( - modifier = Modifier.padding(8.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.User) - UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.User) - UnsavedAvatar(null, AvatarSize.EditRoomDetails, AvatarType.Space()) - UnsavedAvatar("", AvatarSize.EditRoomDetails, AvatarType.Space()) - } -} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt index 4166f37cd7..ec494c2888 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressField.kt @@ -27,7 +27,7 @@ fun RoomAddressField( homeserverName: String, addressValidity: RoomAddressValidity, onAddressChange: (String) -> Unit, - label: String, + label: String?, supportingText: String, modifier: Modifier = Modifier, ) { diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 3a108277ba..5d65ecdbe3 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -56,6 +56,7 @@ "Your avatar" "Accept" "Add caption" + "Add existing rooms" "Add to timeline" "Back" "Call" @@ -75,6 +76,7 @@ "Copy text" "Create" "Create a room" + "Create space" "Deactivate" "Deactivate account" "Decline" @@ -112,6 +114,7 @@ "Load more" "Manage account" "Manage devices" + "Manage rooms" "Message" "Minimise" "Next" @@ -191,6 +194,7 @@ "Copied to clipboard" "Copyright" "Creating room…" + "Creating space…" "Request canceled" "Left room" "Left space" @@ -337,6 +341,7 @@ Reason: %1$s." "Starting chat…" "Sticker" "Success" + "Suggested" "Suggestions" "Syncing" "System" @@ -473,6 +478,7 @@ Are you sure you want to continue?" "Share this location" "Spaces you have created or joined." "%1$s • %2$s" + "Create spaces to organize rooms" "%1$s space" "Spaces" "View members" diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index b7ee2d5743..e4a9d60679 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -79,6 +79,9 @@ class KonsistPreviewTest { private val previewNameExceptions = listOf( "AsyncIndicatorFailurePreview", "AsyncIndicatorLoadingPreview", + "AvatarPickerSizesPreview", + "AvatarPickerViewPreview", + "AvatarPickerViewRtlPreview", "BackgroundVerticalGradientDisabledPreview", "BackgroundVerticalGradientPreview", "ColorAliasesPreview", @@ -86,6 +89,7 @@ class KonsistPreviewTest { "GradientFloatingActionButtonCircleShapePreview", "HeaderFooterPageScrollablePreview", "HomeTopBarMultiAccountPreview", + "HomeTopBarSpacesPreview", "HomeTopBarWithIndicatorPreview", "IconsOtherPreview", "MarkdownTextComposerEditPreview", diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png index 01986a9c5f..ae1511ef58 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61d96e2f91d217a1112421633426692fc5a2c35e9756d4980bd75fb3088a4b8f -size 29568 +oid sha256:9719e20a56fa6bcbd6afd5fd4cef5877af0d0664dfb9559e84dd332d1a161b7f +size 29538 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png index 2f8038140b..d2e5ed4ff2 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4cf57997e6ca0c7244811154564f27c2af135f0a85dc4598e16df51251096b65 -size 35844 +oid sha256:20c185481e6a13fbccae6e4d8c02752222f8cfcc5c03398c255666beb5df5cc4 +size 34243 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png index 07a00b2546..de71057a78 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c -size 56375 +oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa +size 41893 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png index 4a562be62c..ff8f88d0fd 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c80c8f9ee81b35b6054a10872e14d4fc4d8654b7747a620ea4b9a79d3595265 -size 56756 +oid sha256:a601ab64bac5f2c11480892e4b81dcaf3b9fe72afd222f6f42d1e5f577220a8c +size 42786 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png index d2d4c19999..3e2a94d2ba 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27c31889281d6ba95448b033a07f1e41bc1c55bed26840cc796283a0f9368bf0 -size 58454 +oid sha256:f8a2dd4b01f32b9325e9adf8340f18b6776ff20c06f4e27590bde207d802b3c8 +size 44542 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png index 07a00b2546..de71057a78 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f8f4593373a4229d852a8b4e2e3b937796e45135a032afbbd0563a4fa5e651c -size 56375 +oid sha256:2d0fb8d4c5acde1b03908f15eb959d3e544917a53c529f5971804eb674f989fa +size 41893 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png new file mode 100644 index 0000000000..ff18c21fbf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewDark_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0f2a05605785d5a9484e6e34b03c6074125927f6b8130f5e60f54e3922d7bc4 +size 42863 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png index e6a51b3035..c9e3ba2b8b 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3e9fb42af90f7db14c02d572366ce59808ebd551cac7cc8552ee308d65f7c83 -size 30607 +oid sha256:9c955974f899511eb023e0b25f067cff55edd6d360ebbba5081df5662445d0e4 +size 30753 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png index 0bbe373b9d..8f1e0520e9 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b9bb30aec0b92dd5d352dd9dec4d26177ecb38a10c2984bab5c4bd4584b9b2d -size 36992 +oid sha256:fd25259e89b4a8833c884727d23fb503b53099b698ff2eafd812bf70422b5cbe +size 35631 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png index dd9a8c8bf5..7e6d2bf350 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59 -size 58228 +oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c +size 43653 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png index 7067367b4d..68a1d1bfd0 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ee8385caada3a2739834bbabe1411d2f6da4d645d5b99cf07a6da96fe5eabb9 -size 58584 +oid sha256:ab5d721149a96e53f850d7792653b0b71d41124c0db82d653ad79c66c72dabee +size 44600 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png index 152991f1ef..87c118d7f0 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fb1bff539ab70b3d8bb8ae5f5490374e855c9b7807d1868b0aa1cffacc10e1f5 -size 60382 +oid sha256:b7a8c9c3cb8f877d3dc2deb1b918666143c73aed34fdd3d3961bc2530f32d0f5 +size 46369 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png index dd9a8c8bf5..7e6d2bf350 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c7b44d045dbea3f47c774465be245046e972ade8ad6b9240df956c685dcbd59 -size 58228 +oid sha256:30a4f34c42cb57b3cbd08114fef8531175890d46d0033f0dc5d1337189e33d1c +size 43653 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png new file mode 100644 index 0000000000..b4d8ddbeb2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.configureroom_ConfigureRoomViewLight_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3cb687ded32d38164cb67657b495958f1632457d1e49ede0d8c9f1b1f5a287b +size 44675 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png new file mode 100644 index 0000000000..a436e9b1e4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08e7f4dad9666652eea98b7ecf807f2d0050024a59e8b25113b00d7584ff7fa7 +size 12382 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png new file mode 100644 index 0000000000..1be8da04e4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_HomeTopBarSpaces_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d8783952c0fd66f6ca762b79061d26abdf6aedbf601266292a6507da674792 +size 11419 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png new file mode 100644 index 0000000000..834f73ab9f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:542d8ba6a6031fe2789cf111f333eef22acf95281f57421ace2c7b5b0a599cc2 +size 41140 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png new file mode 100644 index 0000000000..7dc28605d2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.spaces_HomeSpacesView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c31cd78bc054610be05012cdba7eb0cbc770435b0e12bc065f6eae4a773ca39e +size 40121 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png index 5cd1c50997..2e8c314c9d 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:27c5418d421ca6cf0069e34ca3e22ca807203d252b9c1424eca447f070fbbbdf -size 54177 +oid sha256:d398e399f468705b9f78283535c2b0e3f44f8be0456cf99bb9b3611746cd0af2 +size 54380 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png index d6b722a3f3..f23d07d437 100644 --- a/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.home.impl_HomeView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc4c11b4d2c83b179409083ca36fcb95e44b7d8c51abd23e9c07f4d3be8a339c -size 52626 +oid sha256:7fce6676e186e13f14ea8cc8436fdbcadcf41bf84a1999104794bd2245814337 +size 52805 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png index b509b7fff7..cd447a2df1 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5896d5e6fd21697d6270aedb4389eee0d57a9796536b847ae657f57e6c2dab3d -size 20974 +oid sha256:4f3dff815d0233a7a3716ec2298e06f78bf3b52806412c4f628a81ed53e841c3 +size 21818 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png index c7aa6f6105..417ebf2b1f 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95100c25fb085329f8968a765a4f4359678be67309d5e086ead311c48cfda29f -size 67826 +oid sha256:bbadbe374c9a0235af368e9ceedd9aadd4cd736ca7f68592a656b2bd854fe3de +size 63364 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png index 17eb214c80..a92c5f5c0a 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b6869e6026df038d739cc14a0a585563d595b1430ba23a985ec57680506ead2 -size 29857 +oid sha256:f78f81d996c9124b2c06406fc0b86f242c0a05b9e85fe19ea550769682e9ba11 +size 30493 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png index 3920f3fe0c..e52e8f373d 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f103f89c71cc97a837cf0edc1035c580bfdf2d682857897241a6dec23c91436 -size 21163 +oid sha256:1ff355d7046ae53a00a0a0c6432823f31f73cd3206268c72414f5e6172d588a0 +size 21994 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png index 1a31286fd6..8543f0f600 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9989d429a1ed9f3190a19c0678168de77aca597ed8fda5208e19bbe109ab9ada -size 66391 +oid sha256:14dfa82a7762b5a787ba5b663878854adce1db268f5764f2deb695284d077412 +size 62305 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png index 8ee822b18b..df3d2a522f 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b3eb9e8908deb84153b19d3735dd2338fac2a7998793915eeec32d7607a0b94 -size 28671 +oid sha256:856b6175eb5331d079ceb4b9037045738aaf42ffe55e3fe8fe32bcb948c2225c +size 29235 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png index 98fffb180d..d046fd1e4c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c200761849da1ba650f38adfeed65fcc35f4fda94a4b1302447faf55d4196c16 -size 28211 +oid sha256:9f22ca53d5ab8897718c6628efc436566d648bff8736f592f456b56502eb18f7 +size 28189 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png index 146d245888..219c962a9c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:282680791aed814f49e25134742e55270ffa155004d48a4f4645ef160450c529 -size 21933 +oid sha256:32773f03c02c65758cf122566c28b633474dc31e1f4e84a36bf8a89bda6791c0 +size 21904 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png index f9fb3f287d..b89f6150b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc04e9e69f8111c2837d998f6503e2ea146d91284d1839ac8619d5d9325645d7 -size 29613 +oid sha256:4f2f2548c1fd553657e1b8b13613a691371f053d12dc3a8e08016deb8cd671f2 +size 29532 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png index 169e16037f..15ac502c6b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7579d7b70e81228d997f8390285210a6e6a7c764523a82b59cd68b2e1969656 -size 52193 +oid sha256:44363d7d7ed3abd614fe9cc6f4fce750c280335ae34177a9a147c1c9b5a18f9a +size 50999 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png index fc9cf97e30..596057c7fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eaad1ca1ef992a03aae784836139963e5ac8867d5fc70871eb63d273acf05948 -size 49266 +oid sha256:e8c00c06c9da1432f196aafa11e529e393f6b03310fa4d9984bf66d4f7faa058 +size 44922 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png index 817b7943b8..637db7b7c9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44331b9967290ab96c55cce7a5f8a3531564ad0c074ea6b25adf9299a6ec0239 -size 28165 +oid sha256:7b6ee74993d1fa47bba94df064612aa80a5d0be3333d9986a5caf0e1aa7d0089 +size 28328 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png index 74c01ba304..b4a57f090f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d037d7c70b304980c4c0a2c292fdcf800eafff15aee8c3c3adbf180e7e47a557 -size 28293 +oid sha256:13d339ed6e27f32f7820048acf35008f406f7ad2597cf1487a05b0a7e6b1ab5b +size 28289 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png index a01340b169..fc613213a8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4467db8409103caf24b97dab28e5280da60ca420d951d689d353ebaf63841bf -size 24737 +oid sha256:1858184e176bdf7dce86d39da44b1732f31ff5d516c154d42de063def0b13fb7 +size 24897 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png index e3e8f0a8c0..12a3e650ed 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:109a1451e031bcc46e55c2c111a4ce65eb5635a3b66b1ba6a5e6a0980184ec0d -size 26087 +oid sha256:674a37e0ff50291151afcef77e81f449e234112ebc1c103bcfdfd9c7c223a0f3 +size 26152 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png index a1da37b1de..d996f53828 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3d196d9b4946165718d8a4ad37869d1d81c6134e94e05dcc1b23b71338482cb -size 28941 +oid sha256:dd0a5f6164167b707a3765f3aef44da02c5a74e24a6ee4d5f8fe2e8f15b88f85 +size 29012 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png index de17d9174f..226e57c2cf 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d797584eca407120de11bdac2792a4501dd414274e5acf786fab74b7df668209 -size 27518 +oid sha256:95dc827f3f94a9c6b9b8e71f0057271e47cddbe18a60833d633f80b9a9a55e0f +size 27485 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png index df8188c586..b57822d36b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ba88593c26798de646f331f68c48b4675f33090e7533b88f6a31e0c5cfbd081 -size 21538 +oid sha256:599e7d7c23b137a8f234481b130724aba799ccde53601e600f623e0b130181db +size 21564 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png index da0a0553d5..8c7ae4e616 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:16c5f05bb20e9a1f5b3480827fe7c7c4384daa60496da0ee0dc9bcdd77ccdddd -size 29004 +oid sha256:b6fac75a22e067ec468e1c0dc80ba039f886ce622c5696c89e8ba88f78057d2e +size 28970 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png index 9cd03d2914..fbf8c6a0ba 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7616b1926b6b6f1c6aa19d797866a74cb7db487fa72e59b291e715f22d961607 -size 50787 +oid sha256:8f0f25c356fce23df0dd5b07352a52c4510a559c81733c424027ab1966fe30d3 +size 49577 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png index ae64071349..eab0932ee8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2c9d431942b442b2620268cec8f06166db18b5df732b7a77cd71a11228106c6 -size 48325 +oid sha256:9f9eb9966b578538160a181719f3ea1a22caa0541ccc579f363f9e0f00f5851c +size 43811 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png index 051a142e26..bdc56406d7 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd244116c434d143950d0bb7c291d3a4faf4540f34112286b9069c41eb7de576 -size 27509 +oid sha256:8910fdb134040309196009b90d499d89acc085ca5d20dbefaf4781f0f8d02a6c +size 27596 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png index c0fadc78e5..a42d10c37b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e98e5bdd03bdd7c2da11595416987398ec4af4ba88010a0eab25f11da149ea7 -size 27520 +oid sha256:0c3abff638ea74e7d2913ce45de920f896b546d705424ea09e10eda4b1ff6072 +size 27467 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png index e7c94c7669..4936178a29 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd96a05649a403454636d07168398476b25aae4aaad76cac4e41265478ec4791 -size 23768 +oid sha256:5d060c0fe749dca414d99f6820c174e9423248e08f2a1724f6bc13cc04c3abe1 +size 24046 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png index 4e8cabc23c..f64b7f30fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c95f90eba87b390c09894087d4c55dfe8e7797af712315ccbee3f927be4e5d5 -size 24314 +oid sha256:74bd3527bc14031b326008ec61743f71a26008ee11f7ed6d34b3776d0e792cbf +size 24500 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png index 1643569702..a916008e8f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetailsedit.impl_RoomDetailsEditView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9187a1e5fc63707a2c1a9804411e15439469f8562eac2c9766a4e033e214166 -size 27289 +oid sha256:5a6d90e7299cb60f6d2ee1b083134daab398ac93394dc8aa6b03dc5b74f10dfe +size 27497 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png index 04d7a13388..36132424ed 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da260572a274c3fedcc81b055e1c52b8cf7467692287aa176b0dd9171be76937 -size 25139 +oid sha256:48a00c3111761d2f8d058bb1b782c066222edd7963f2154b7b59e5d2907972ac +size 25100 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png index 8eb93a77e0..92622922a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 -size 51849 +oid sha256:120a6bf52ad4144f423eb80d86defa794ef2ae2c05ee36d7e3b2930ae18466e5 +size 51811 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index 8eb93a77e0..92622922a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da888123f37a0dcc7d80849216044b82a442052c900d636d006020ad42469a71 -size 51849 +oid sha256:120a6bf52ad4144f423eb80d86defa794ef2ae2c05ee36d7e3b2930ae18466e5 +size 51811 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index d320c0dc11..70947dd13f 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64134bc23ef38b73a087ec5679784516bfd66f23dd675a3771e1aa8cf6159836 -size 44729 +oid sha256:e93b37a435d6465e5b4285b705d0e6b7f2702fc53d2763c0d4779931c2380195 +size 44681 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index 9de784287c..06ef3ad65a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d -size 59154 +oid sha256:262bfe062d02b42c061603ee697a1bba55f68de10ff87da9c1afcbeb2418efec +size 59105 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index 9de784287c..06ef3ad65a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56d1614ce5e0da0bc29f8184f045339e263087676e9d7908a94007f410924b5d -size 59154 +oid sha256:262bfe062d02b42c061603ee697a1bba55f68de10ff87da9c1afcbeb2418efec +size 59105 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png index c200e6a21c..5d780a3a05 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:20a302e03d4f10c912c249f7c26f8ecc06472dd2a2ad4abe91607bb7527de732 -size 25577 +oid sha256:0c4363353050180ba9bf64cf571d846b1c4fa15dbae96a6a2a81502f1363957d +size 25535 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png index e0f67fd111..1f065f09d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 -size 53555 +oid sha256:fea1457bf9f172e9a635ca83529c5c79d0886c8c492d0454306d6899bbd85591 +size 53482 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index e0f67fd111..1f065f09d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9939e7a38e0e280d42a996576a3cfbeb773625cf43ddf8afd04aad6ab35fd955 -size 53555 +oid sha256:fea1457bf9f172e9a635ca83529c5c79d0886c8c492d0454306d6899bbd85591 +size 53482 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index 264166a069..e097ccb8c5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:093bb9672ecd80432c7e6102bd5ed2d1184cd384c91e479d99d13c0ba773bf78 -size 46448 +oid sha256:bda2d33e58d4dc1b2c1fd19a5fe0b2e574315b5b1a4f6a6367360dd31c602c51 +size 46390 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index 920c64d380..4669fb8074 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 -size 61069 +oid sha256:890064df86090c0003ae6fc4f461e392a3cbfa95b6d8a1f937bc1058580697d1 +size 61001 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index 920c64d380..4669fb8074 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee80f7a765a453c3704af6d1f38f90637528bcf1e5966dc1bd016f4d34f21fa4 -size 61069 +oid sha256:890064df86090c0003ae6fc4f461e392a3cbfa95b6d8a1f937bc1058580697d1 +size 61001 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png new file mode 100644 index 0000000000..e4ae3155a6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:193626470640c2d6499d8155a4a18836bf5564678b5f78b6a187f0d7505a61a7 +size 217630 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png new file mode 100644 index 0000000000..07599ae211 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerSizes_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3eab1e9017e55668ded1c01a7051aded0b99932986afc22d477e5ad0d500cd33 +size 212898 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png new file mode 100644 index 0000000000..945a52bcbc --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ac5166b6bf6c040c726321be6130f7d557b33e9ac6e111ddcd5c95be1d5d389 +size 183882 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png new file mode 100644 index 0000000000..f7fb461a63 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerViewRtl_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d07761ac69d93cd40592ff78566079be0c9c0e566b8606be1939f96440262f9 +size 180551 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png new file mode 100644 index 0000000000..30cee8ca0b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ed5ce625e3cd20ad173b96ef67ca3c274e4310d55794502a5e23235d580f775 +size 180934 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png new file mode 100644 index 0000000000..9f6fec05f0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_AvatarPickerView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d3d87bd05c47e9e150d92287499503af0c148ba015d46b080ad6dd3e575554f +size 179035 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png deleted file mode 100644 index 0e5502a30c..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0635fa0f0ca2b150f598279fee291f25203c6313f8d5fe449e4c1629c96637a -size 8528 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png deleted file mode 100644 index 11f2b08dc7..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 -size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png deleted file mode 100644 index 11f2b08dc7..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f8fe5034ae0b5bb611df443e7c1054f3f5e61e608894b14b79aba287eb6fa47 -size 11643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png deleted file mode 100644 index bb5b9d07ee..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:66242e5546b6f853a2d78493ece0bca7065c036246cd88d83301887b9edc362e -size 8628 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png deleted file mode 100644 index 27f54811e1..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b -size 11823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png deleted file mode 100644 index 27f54811e1..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_EditableAvatarView_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f3d1e3d3d5212df16af61a9ec5a8904fe71bfff4bbfe5086f08e6a2dbc9e58b -size 11823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png deleted file mode 100644 index c0eccb5941..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a22271c3970f9ddf514b271d1ac012c07dadef134470c95eea58c645e02f173 -size 68699 diff --git a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png deleted file mode 100644 index fa1880b64b..0000000000 --- a/tests/uitests/src/test/snapshots/images/libraries.matrix.ui.components_UnsavedAvatar_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1da0dcdb96fe88591d97b6f38b2f4b11b095af981340c1d87a805b866182574c -size 68171