From 21c6f9297d5952de6b119f1d698d2ae41059651c Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Feb 2025 17:46:52 +0100 Subject: [PATCH 01/14] feat(join by alias) : replace Icons.Compose by Icons.Plus on home --- .../io/element/android/features/roomlist/impl/RoomListView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index 45fa5113e5..6bf916873e 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -153,7 +153,7 @@ private fun RoomListScaffold( ) { Icon( // Note cannot use Icons.Outlined.EditSquare, it does not exist :/ - imageVector = CompoundIcons.Compose(), + imageVector = CompoundIcons.Plus(), contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message), tint = ElementTheme.colors.iconOnSolidPrimary, ) From 2bfa62922c1c3b528a2fe14a81d115d069e25221 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Feb 2025 20:59:22 +0100 Subject: [PATCH 02/14] feat(join by alias) : refactor navigation for create room flow --- .../android/appnav/LoggedInFlowNode.kt | 4 +-- .../createroom/api/CreateRoomEntryPoint.kt | 4 +-- .../createroom/CreateRoomNavigator.kt | 35 +++++++++++++++++++ .../createroom/impl/ConfigureRoomFlowNode.kt | 6 ++-- .../createroom/impl/CreateRoomFlowNode.kt | 32 ++++++++--------- .../impl/configureroom/ConfigureRoomNode.kt | 18 +++++----- .../impl/root/CreateRoomRootNode.kt | 21 ++++------- 7 files changed, 72 insertions(+), 48 deletions(-) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt 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 9ae5cec637..54ec8f1f48 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -357,8 +357,8 @@ class LoggedInFlowNode @AssistedInject constructor( } NavTarget.CreateRoom -> { val callback = object : CreateRoomEntryPoint.Callback { - override fun onSuccess(roomId: RoomId) { - backstack.replace(NavTarget.Room(roomId.toRoomIdOrAlias())) + override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) { + backstack.replace(NavTarget.Room(roomIdOrAlias)) } } 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 b37c804701..e96d7e7879 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 @@ -11,7 +11,7 @@ import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import io.element.android.libraries.architecture.FeatureEntryPoint -import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias interface CreateRoomEntryPoint : FeatureEntryPoint { fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder @@ -21,6 +21,6 @@ interface CreateRoomEntryPoint : FeatureEntryPoint { } interface Callback : Plugin { - fun onSuccess(roomId: RoomId) + fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt new file mode 100644 index 0000000000..b2d8ea6828 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom + +import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.operation.push +import io.element.android.features.createroom.impl.CreateRoomFlowNode.NavTarget +import io.element.android.libraries.architecture.overlay.Overlay +import io.element.android.libraries.architecture.overlay.operation.hide +import io.element.android.libraries.architecture.overlay.operation.show +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias + +interface CreateRoomNavigator : Plugin { + fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) + fun onCreateNewRoom() +} + +class DefaultCreateRoomNavigator( + private val backstack: BackStack, + private val openRoom: (RoomIdOrAlias) -> Unit, +) : CreateRoomNavigator { + + override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) = openRoom(roomIdOrAlias) + + override fun onCreateNewRoom() { + backstack.push(NavTarget.NewRoom) + } + +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt index 1a2916b16a..0fdb16bd67 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt @@ -19,6 +19,7 @@ import com.bumble.appyx.navmodel.backstack.operation.push import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.createroom.CreateRoomNavigator import io.element.android.features.createroom.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode import io.element.android.features.createroom.impl.di.CreateRoomComponent @@ -46,6 +47,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor( private val component by lazy { parent!!.bindings().createRoomComponentBuilder().build() } + private val navigator = plugins().first() override val daggerComponent: Any get() = component @@ -58,6 +60,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor( data object ConfigureRoom : NavTarget } + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { NavTarget.Root -> { @@ -69,8 +72,7 @@ class ConfigureRoomFlowNode @AssistedInject constructor( createNode(buildContext = buildContext, plugins = listOf(callback)) } NavTarget.ConfigureRoom -> { - val callbacks = plugins() - createNode(buildContext = buildContext, plugins = callbacks) + createNode(buildContext = buildContext, plugins = listOf(navigator)) } } } 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 9e06bf6080..7b6185e0ca 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 @@ -9,24 +9,26 @@ package io.element.android.features.createroom.impl import android.os.Parcelable import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.navigation.transition.JumpToEndTransitionHandler import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.navmodel.backstack.BackStack -import com.bumble.appyx.navmodel.backstack.operation.push import dagger.assisted.Assisted import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.createroom.DefaultCreateRoomNavigator import io.element.android.features.createroom.api.CreateRoomEntryPoint -import io.element.android.features.createroom.impl.configureroom.ConfigureRoomNode import io.element.android.features.createroom.impl.root.CreateRoomRootNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import kotlinx.parcelize.Parcelize @ContributesNode(SessionScope::class) @@ -47,29 +49,23 @@ class CreateRoomFlowNode @AssistedInject constructor( @Parcelize data object NewRoom : NavTarget + } + private val navigator = DefaultCreateRoomNavigator( + backstack = backstack, + openRoom = { roomIdOrAlias -> + plugins().forEach { it.onOpenRoom(roomIdOrAlias) } + } + ) + override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { NavTarget.Root -> { - val callback = object : CreateRoomRootNode.Callback { - override fun onCreateNewRoom() { - backstack.push(NavTarget.NewRoom) - } - - override fun onStartChatSuccess(roomId: RoomId) { - plugins().forEach { it.onSuccess(roomId) } - } - } - createNode(buildContext = buildContext, plugins = listOf(callback)) + createNode(buildContext = buildContext, plugins = listOf(navigator)) } NavTarget.NewRoom -> { - val callback = object : ConfigureRoomNode.Callback { - override fun onCreateRoomSuccess(roomId: RoomId) { - plugins().forEach { it.onSuccess(roomId) } - } - } - createNode(buildContext = buildContext, plugins = listOf(callback)) + createNode(buildContext = buildContext, plugins = listOf(navigator)) } } } 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 966369e6e3..5dce257a23 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 @@ -18,8 +18,9 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.createroom.CreateRoomNavigator import io.element.android.features.createroom.impl.di.CreateRoomScope -import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.services.analytics.api.AnalyticsService @ContributesNode(CreateRoomScope::class) @@ -29,6 +30,9 @@ class ConfigureRoomNode @AssistedInject constructor( private val presenter: ConfigureRoomPresenter, private val analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { + + private val navigator = plugins().first() + init { lifecycle.subscribe( onResume = { @@ -37,14 +41,6 @@ class ConfigureRoomNode @AssistedInject constructor( ) } - interface Callback : Plugin { - fun onCreateRoomSuccess(roomId: RoomId) - } - - private fun onCreateRoomSuccess(roomId: RoomId) { - plugins().forEach { it.onCreateRoomSuccess(roomId) } - } - @Composable override fun View(modifier: Modifier) { val state = presenter.present() @@ -52,7 +48,9 @@ class ConfigureRoomNode @AssistedInject constructor( state = state, modifier = modifier, onBackClick = this::navigateUp, - onCreateRoomSuccess = this::onCreateRoomSuccess, + onCreateRoomSuccess = { + navigator.onOpenRoom(it.toRoomIdOrAlias()) + }, ) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index f3a836f441..58edb9d00e 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -20,9 +20,10 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.MobileScreen import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.createroom.CreateRoomNavigator import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.services.analytics.api.AnalyticsService @ContributesNode(SessionScope::class) @@ -33,18 +34,8 @@ class CreateRoomRootNode @AssistedInject constructor( private val analyticsService: AnalyticsService, private val inviteFriendsUseCase: InviteFriendsUseCase, ) : Node(buildContext, plugins = plugins) { - interface Callback : Plugin { - fun onCreateNewRoom() - fun onStartChatSuccess(roomId: RoomId) - } - - private fun onCreateNewRoom() { - plugins().forEach { it.onCreateNewRoom() } - } - private fun onStartChatSuccess(roomId: RoomId) { - plugins().forEach { it.onStartChatSuccess(roomId) } - } + private val navigator = plugins().first() init { lifecycle.subscribe( @@ -60,8 +51,10 @@ class CreateRoomRootNode @AssistedInject constructor( state = state, modifier = modifier, onCloseClick = this::navigateUp, - onNewRoomClick = ::onCreateNewRoom, - onOpenDM = ::onStartChatSuccess, + onNewRoomClick = navigator::onCreateNewRoom, + onOpenDM = { + navigator.onOpenRoom(it.toRoomIdOrAlias()) + }, onInviteFriendsClick = { invitePeople(activity) } ) } From 498f63e25e492a71a8a7a8b55db0ad026f52a232 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Feb 2025 20:59:42 +0100 Subject: [PATCH 03/14] feat(join by alias) : introduce the JoinRoomByAddress --- .../createroom/CreateRoomNavigator.kt | 10 ++ .../createroom/impl/CreateRoomFlowNode.kt | 14 ++- .../joinbyaddress/JoinRoomByAddressEvents.kt | 14 +++ .../joinbyaddress/JoinRoomByAddressNode.kt | 40 ++++++ .../JoinRoomByAddressPresenter.kt | 98 +++++++++++++++ .../joinbyaddress/JoinRoomByAddressState.kt | 23 ++++ .../JoinRoomByAddressStateProvider.kt | 31 +++++ .../joinbyaddress/JoinRoomByAddressView.kt | 114 ++++++++++++++++++ .../impl/root/CreateRoomRootNode.kt | 1 + .../impl/root/CreateRoomRootView.kt | 11 ++ 10 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt index b2d8ea6828..a7b15a4417 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt @@ -19,10 +19,13 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias interface CreateRoomNavigator : Plugin { fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) fun onCreateNewRoom() + fun onShowJoinRoomByAddress() + fun onDismissJoinRoomByAddress() } class DefaultCreateRoomNavigator( private val backstack: BackStack, + private val overlay: Overlay, private val openRoom: (RoomIdOrAlias) -> Unit, ) : CreateRoomNavigator { @@ -32,4 +35,11 @@ class DefaultCreateRoomNavigator( backstack.push(NavTarget.NewRoom) } + override fun onShowJoinRoomByAddress() { + overlay.show(NavTarget.JoinByAddress) + } + + override fun onDismissJoinRoomByAddress() { + overlay.hide() + } } 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 7b6185e0ca..7fb4830e0f 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 @@ -8,6 +8,7 @@ package io.element.android.features.createroom.impl import android.os.Parcelable +import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -22,9 +23,11 @@ import dagger.assisted.AssistedInject import io.element.android.anvilannotations.ContributesNode import io.element.android.features.createroom.DefaultCreateRoomNavigator import io.element.android.features.createroom.api.CreateRoomEntryPoint +import io.element.android.features.createroom.impl.joinbyaddress.JoinRoomByAddressNode import io.element.android.features.createroom.impl.root.CreateRoomRootNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode +import io.element.android.libraries.architecture.OverlayView import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.RoomId @@ -50,10 +53,13 @@ class CreateRoomFlowNode @AssistedInject constructor( @Parcelize data object NewRoom : NavTarget + @Parcelize + data object JoinByAddress : NavTarget } private val navigator = DefaultCreateRoomNavigator( backstack = backstack, + overlay = overlay, openRoom = { roomIdOrAlias -> plugins().forEach { it.onOpenRoom(roomIdOrAlias) } } @@ -67,11 +73,17 @@ class CreateRoomFlowNode @AssistedInject constructor( NavTarget.NewRoom -> { createNode(buildContext = buildContext, plugins = listOf(navigator)) } + NavTarget.JoinByAddress -> { + createNode(buildContext = buildContext, plugins = listOf(navigator)) + } } } @Composable override fun View(modifier: Modifier) { - BackstackView() + Box(modifier = modifier) { + BackstackView() + OverlayView(transitionHandler = remember { JumpToEndTransitionHandler() }) + } } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt new file mode 100644 index 0000000000..58a1223b8f --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +sealed interface JoinRoomByAddressEvents { + data object Dismiss : JoinRoomByAddressEvents + data object Continue: JoinRoomByAddressEvents + data class UpdateAddress(val address: String) : JoinRoomByAddressEvents +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt new file mode 100644 index 0000000000..ae12caa00e --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import com.bumble.appyx.core.plugin.plugins +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.features.createroom.CreateRoomNavigator +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +class JoinRoomByAddressNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + presenterFactory: JoinRoomByAddressPresenter.Factory, +) : Node(buildContext, plugins = plugins) { + + private val navigator = plugins().first() + private val presenter = presenterFactory.create(navigator) + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + JoinRoomByAddressView( + state = state, + modifier = modifier + ) + } +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt new file mode 100644 index 0000000000..d721deb467 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import io.element.android.features.createroom.CreateRoomNavigator +import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.core.data.tryOrNull +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomAlias +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias +import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper +import kotlinx.coroutines.delay + +class JoinRoomByAddressPresenter @AssistedInject constructor( + @Assisted private val navigator: CreateRoomNavigator, + private val client: MatrixClient, + private val roomAliasHelper: RoomAliasHelper, +) : Presenter { + + @AssistedFactory + interface Factory { + fun create(navigator: CreateRoomNavigator): JoinRoomByAddressPresenter + } + + @Composable + override fun present(): JoinRoomByAddressState { + var address by remember { mutableStateOf("") } + var addressState by remember { mutableStateOf(RoomAddressState.Unknown) } + + fun handleEvents(event: JoinRoomByAddressEvents) { + when (event) { + JoinRoomByAddressEvents.Continue -> { + navigator.onDismissJoinRoomByAddress() + navigator.onOpenRoom(RoomIdOrAlias.Alias(RoomAlias(address))) + } + JoinRoomByAddressEvents.Dismiss -> navigator.onDismissJoinRoomByAddress() + is JoinRoomByAddressEvents.UpdateAddress -> { + address = event.address.trim() + } + } + } + + RoomAddressStateEffect( + fullAddress = address, + onRoomAddressStateChange = { addressState = it } + ) + + return JoinRoomByAddressState( + address = address, + addressState = addressState, + eventSink = ::handleEvents + ) + } + + @Composable + private fun RoomAddressStateEffect( + fullAddress: String, + onRoomAddressStateChange: (RoomAddressState) -> Unit, + ) { + val onChange by rememberUpdatedState(onRoomAddressStateChange) + LaunchedEffect(fullAddress) { + if (fullAddress.isEmpty()) { + onChange(RoomAddressState.Unknown) + return@LaunchedEffect + } + // debounce the room address validation + delay(300) + val roomAlias = tryOrNull { RoomAlias(fullAddress) } + if (roomAlias == null || !roomAliasHelper.isRoomAliasValid(roomAlias)) { + onChange(RoomAddressState.Invalid) + } else { + onChange(RoomAddressState.Valid(matchingRoomFound = false)) + client.resolveRoomAlias(roomAlias) + .onSuccess { resolved -> + onChange(RoomAddressState.Valid(matchingRoomFound = resolved.isPresent)) + } + } + } + } +} + + + diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt new file mode 100644 index 0000000000..6d5be3dfef --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import androidx.compose.runtime.Immutable + +data class JoinRoomByAddressState( + val address: String, + val addressState: RoomAddressState, + val eventSink: (JoinRoomByAddressEvents) -> Unit +) + +@Immutable +sealed interface RoomAddressState { + data object Unknown : RoomAddressState + data object Invalid : RoomAddressState + data class Valid(val matchingRoomFound: Boolean) : RoomAddressState +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt new file mode 100644 index 0000000000..de20b1bc1c --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class JoinRoomByAddressStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aJoinRoomByAddressState(), + aJoinRoomByAddressState("#room-"), + aJoinRoomByAddressState("#room-", addressState = RoomAddressState.Invalid), + aJoinRoomByAddressState("#room-name:matrix.org", addressState = RoomAddressState.Valid(true)), + aJoinRoomByAddressState("#room-name-here:matrix.org", addressState = RoomAddressState.Valid(false)), + // Add other states here + ) +} + +fun aJoinRoomByAddressState( + address: String = "", + addressState: RoomAddressState = RoomAddressState.Unknown, +) = JoinRoomByAddressState( + address = address, + addressState = addressState, + eventSink = {} +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt new file mode 100644 index 0000000000..ccc2fd6dbd --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +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.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet +import io.element.android.libraries.designsystem.theme.components.TextField +import io.element.android.libraries.ui.strings.CommonStrings + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun JoinRoomByAddressView( + state: JoinRoomByAddressState, + modifier: Modifier = Modifier, +) { + val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + ModalBottomSheet( + modifier = modifier, + sheetState = sheetState, + onDismissRequest = { + state.eventSink(JoinRoomByAddressEvents.Dismiss) + }, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(all = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + RoomAddressField( + address = state.address, + addressState = state.addressState, + requestFocus = sheetState.isVisible, + onAddressChange = { + state.eventSink(JoinRoomByAddressEvents.UpdateAddress(it)) + } + ) + Spacer(modifier = Modifier.height(24.dp)) + Button( + text = stringResource(CommonStrings.action_continue), + modifier = Modifier.fillMaxWidth(), + enabled = state.addressState is RoomAddressState.Valid, + onClick = { + state.eventSink(JoinRoomByAddressEvents.Continue) + } + ) + } + } +} + +@Composable +private fun RoomAddressField( + address: String, + addressState: RoomAddressState, + requestFocus: Boolean, + onAddressChange: (String) -> Unit, + modifier: Modifier = Modifier, +) { + val focusRequester = remember { FocusRequester() } + if (requestFocus) { + LaunchedEffect(Unit) { focusRequester.requestFocus() } + } + TextField( + modifier = modifier.focusRequester(focusRequester), + value = address, + label = "Join room by address", + placeholder = "Enter...", + supportingText = when (addressState) { + RoomAddressState.Invalid -> "Not a valid address" + RoomAddressState.Unknown -> "e.g. #room-name:matrix.org" + is RoomAddressState.Valid -> if (addressState.matchingRoomFound) { + "Matching room found" + } else { + "e.g. #room-name:matrix.org" + } + }, + isError = addressState is RoomAddressState.Invalid, + onValueChange = onAddressChange, + singleLine = true, + ) +} + +@PreviewsDayNight +@Composable +internal fun JoinRoomByAddressViewPreview( + @PreviewParameter(JoinRoomByAddressStateProvider::class) state: JoinRoomByAddressState +) = ElementPreview { + JoinRoomByAddressView(state = state) +} + diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index 58edb9d00e..b20eb7cf3b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -55,6 +55,7 @@ class CreateRoomRootNode @AssistedInject constructor( onOpenDM = { navigator.onOpenRoom(it.toRoomIdOrAlias()) }, + onJoinByAddressClick = navigator::onShowJoinRoomByAddress, onInviteFriendsClick = { invitePeople(activity) } ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index 7eb2f49511..c24010942e 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -55,6 +55,7 @@ fun CreateRoomRootView( onNewRoomClick: () -> Unit, onOpenDM: (RoomId) -> Unit, onInviteFriendsClick: () -> Unit, + onJoinByAddressClick: () -> Unit, modifier: Modifier = Modifier, ) { Scaffold( @@ -89,6 +90,7 @@ fun CreateRoomRootView( state = state, onNewRoomClick = onNewRoomClick, onInvitePeopleClick = onInviteFriendsClick, + onJoinByAddressClick = onJoinByAddressClick, onDmClick = onOpenDM, ) } @@ -153,6 +155,7 @@ private fun CreateRoomActionButtonsList( state: CreateRoomRootState, onNewRoomClick: () -> Unit, onInvitePeopleClick: () -> Unit, + onJoinByAddressClick: () -> Unit, onDmClick: (RoomId) -> Unit, ) { LazyColumn { @@ -170,6 +173,13 @@ private fun CreateRoomActionButtonsList( onClick = onInvitePeopleClick, ) } + item { + CreateRoomActionButton( + iconRes = CompoundDrawables.ic_compound_mention, + text = "Join room by address", + onClick = onJoinByAddressClick, + ) + } if (state.userListState.recentDirectRooms.isNotEmpty()) { item { ListSectionHeader( @@ -230,6 +240,7 @@ internal fun CreateRoomRootViewPreview(@PreviewParameter(CreateRoomRootStateProv onCloseClick = {}, onNewRoomClick = {}, onOpenDM = {}, + onJoinByAddressClick = {}, onInviteFriendsClick = {}, ) } From 786c2adc97046051653364ae5803b77c1b386786 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Feb 2025 21:49:50 +0100 Subject: [PATCH 04/14] design(text field) : allow setting validity (instead of just isError bool) --- .../joinbyaddress/JoinRoomByAddressView.kt | 7 ++- .../rageshake/impl/bugreport/BugReportView.kt | 3 +- .../password/ResetIdentityPasswordView.kt | 7 ++- .../theme/components/TextField.kt | 62 ++++++++++++------- .../ui/room/address/RoomAddressField.kt | 6 +- .../ui/room/address/RoomAddressValidity.kt | 5 +- 6 files changed, 59 insertions(+), 31 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index ccc2fd6dbd..455f27c4bd 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet import io.element.android.libraries.designsystem.theme.components.TextField +import io.element.android.libraries.designsystem.theme.components.TextFieldValidity import io.element.android.libraries.ui.strings.CommonStrings @OptIn(ExperimentalMaterial3Api::class) @@ -98,7 +99,11 @@ private fun RoomAddressField( "e.g. #room-name:matrix.org" } }, - isError = addressState is RoomAddressState.Invalid, + validity = when (addressState) { + RoomAddressState.Unknown -> null + RoomAddressState.Invalid -> TextFieldValidity.Invalid + is RoomAddressState.Valid -> if (addressState.matchingRoomFound) TextFieldValidity.Valid else null + }, onValueChange = onAddressChange, singleLine = true, ) diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt index fbf91fa46d..04683d59f1 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt @@ -45,6 +45,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.debugPlaceholderBackground import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.TextField +import io.element.android.libraries.designsystem.theme.components.TextFieldValidity import io.element.android.libraries.ui.strings.CommonStrings @Composable @@ -90,7 +91,7 @@ fun BugReportView( keyboardController?.hide() }), minLines = 3, - isError = state.isDescriptionInError, + validity = if(state.isDescriptionInError) TextFieldValidity.Invalid else null, ) } Spacer(modifier = Modifier.height(16.dp)) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt index 2c118c3049..aedb962a64 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt @@ -33,6 +33,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.TextField +import io.element.android.libraries.designsystem.theme.components.TextFieldValidity import io.element.android.libraries.ui.strings.CommonStrings @Composable @@ -82,8 +83,8 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool var showPassword by remember { mutableStateOf(false) } TextField( modifier = Modifier - .fillMaxWidth() - .onTabOrEnterKeyFocusNext(LocalFocusManager.current), + .fillMaxWidth() + .onTabOrEnterKeyFocusNext(LocalFocusManager.current), value = text, onValueChange = onTextChange, placeholder = stringResource(CommonStrings.common_password), @@ -99,7 +100,7 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool Icon(imageVector = image, description) } }, - isError = hasError, + validity = if (hasError) TextFieldValidity.Invalid else null, supportingText = if (hasError) { stringResource(R.string.screen_reset_encryption_password_error) } else { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt index 333716e6c2..ca56fbf19e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt @@ -58,7 +58,7 @@ fun TextField( placeholder: String? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, - isError: Boolean = false, + validity: TextFieldValidity? = null, enabled: Boolean = true, readOnly: Boolean = false, singleLine: Boolean = false, @@ -93,7 +93,7 @@ fun TextField( readOnly = readOnly, enabled = enabled, isFocused = isFocused, - isError = isError, + validity = validity, leadingIcon = leadingIcon, placeholder = placeholder, isTextEmpty = value.isEmpty(), @@ -114,7 +114,7 @@ fun TextField( placeholder: String? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, - isError: Boolean = false, + validity: TextFieldValidity? = null, enabled: Boolean = true, readOnly: Boolean = false, singleLine: Boolean = false, @@ -149,7 +149,7 @@ fun TextField( readOnly = readOnly, enabled = enabled, isFocused = isFocused, - isError = isError, + validity = validity, leadingIcon = leadingIcon, placeholder = placeholder, isTextEmpty = value.text.isEmpty(), @@ -166,7 +166,7 @@ private fun DecorationBox( enabled: Boolean, readOnly: Boolean, isFocused: Boolean, - isError: Boolean, + validity: TextFieldValidity?, placeholder: String?, isTextEmpty: Boolean, supportingText: String?, @@ -187,7 +187,7 @@ private fun DecorationBox( enabled = enabled, readOnly = readOnly, isFocused = isFocused, - isError = isError + isError = validity == TextFieldValidity.Invalid ) { Row(modifier = Modifier.padding(16.dp)) { if (leadingIcon != null) { @@ -216,7 +216,7 @@ private fun DecorationBox( } if (supportingText != null) { Spacer(modifier = Modifier.height(4.dp)) - SupportingTextLayout(isError, supportingText) + SupportingTextLayout(validity, supportingText) } } } @@ -254,24 +254,44 @@ private fun TextFieldContainer( } @Composable -private fun SupportingTextLayout(isError: Boolean, supportingText: String) { +private fun SupportingTextLayout(validity: TextFieldValidity?, supportingText: String) { Row(horizontalArrangement = spacedBy(4.dp)) { - if (isError) { - Icon( - imageVector = CompoundIcons.Error(), - contentDescription = null, - modifier = Modifier.size(16.dp), - tint = ElementTheme.colors.iconCriticalPrimary - ) + when (validity) { + TextFieldValidity.Invalid -> { + Icon( + imageVector = CompoundIcons.Error(), + contentDescription = null, + modifier = Modifier.size(16.dp), + tint = ElementTheme.colors.iconCriticalPrimary + ) + } + TextFieldValidity.Valid -> { + Icon( + imageVector = CompoundIcons.CheckCircleSolid(), + contentDescription = null, + modifier = Modifier.size(16.dp), + tint = ElementTheme.colors.iconSuccessPrimary + ) + } + else -> Unit } Text( text = supportingText, - color = if (isError) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textSecondary, + color = when (validity) { + TextFieldValidity.Invalid -> ElementTheme.colors.textCriticalPrimary + TextFieldValidity.Valid -> ElementTheme.colors.textSuccessPrimary + else -> ElementTheme.colors.textSecondary + }, style = ElementTheme.typography.fontBodySmRegular, ) } } +enum class TextFieldValidity { + Invalid, + Valid +} + @Composable private fun textFieldStyle(enabled: Boolean): TextStyle { return ElementTheme.typography.fontBodyLgRegular.copy( @@ -283,11 +303,11 @@ private fun textFieldStyle(enabled: Boolean): TextStyle { ) } -@Preview(group = PreviewGroup.TextFields) +@Preview(group = PreviewGroup.TextFields, heightDp = 1000) @Composable internal fun TextFieldsLightPreview() = ElementPreviewLight { ContentToPreview() } -@Preview(group = PreviewGroup.TextFields) +@Preview(group = PreviewGroup.TextFields, heightDp = 1000) @Composable internal fun TextFieldsDarkPreview() = ElementPreviewDark { ContentToPreview() } @@ -295,15 +315,15 @@ internal fun TextFieldsDarkPreview() = ElementPreviewDark { ContentToPreview() } @ExcludeFromCoverage private fun ContentToPreview() { Column(modifier = Modifier.padding(4.dp)) { - allBooleans.forEach { isError -> + TextFieldValidity.entries.forEach { validity -> allBooleans.forEach { enabled -> allBooleans.forEach { readonly -> TextField( onValueChange = {}, label = "Label", - value = "Hello er=${isError.asInt()}, en=${enabled.asInt()}, ro=${readonly.asInt()}", + value = "Hello val=${validity}, en=${enabled.asInt()}, ro=${readonly.asInt()}", supportingText = "Supporting text", - isError = isError, + validity = validity, enabled = enabled, readOnly = readonly, ) 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 acd7723b87..fab4d153ec 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 @@ -15,6 +15,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextField +import io.element.android.libraries.designsystem.theme.components.TextFieldValidity import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.CommonStrings @@ -56,7 +57,10 @@ fun RoomAddressField( } else -> supportingText }, - isError = addressValidity.isError(), + validity = when (addressValidity) { + RoomAddressValidity.InvalidSymbols, RoomAddressValidity.NotAvailable -> TextFieldValidity.Invalid + else -> null + }, onValueChange = onAddressChange, singleLine = true, ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt index 25af0ab98d..d5813ce91f 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt @@ -8,6 +8,7 @@ package io.element.android.libraries.matrix.ui.room.address import androidx.compose.runtime.Immutable +import io.element.android.libraries.designsystem.theme.components.TextFieldValidity /** * Represents the validity state of a room address. @@ -19,8 +20,4 @@ sealed interface RoomAddressValidity { data object InvalidSymbols : RoomAddressValidity data object NotAvailable : RoomAddressValidity data object Valid : RoomAddressValidity - - fun isError(): Boolean { - return this is InvalidSymbols || this is NotAvailable - } } From 41fe0f1c75a0506fe3196330711f1823bd57edc3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Feb 2025 22:11:38 +0100 Subject: [PATCH 05/14] feat(join by alias) : better address keyboard config --- .../createroom/impl/joinbyaddress/JoinRoomByAddressView.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index 455f27c4bd..5e7d515090 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable @@ -22,6 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.libraries.designsystem.preview.ElementPreview @@ -106,6 +108,10 @@ private fun RoomAddressField( }, onValueChange = onAddressChange, singleLine = true, + keyboardOptions = KeyboardOptions( + capitalization = KeyboardCapitalization.None, + autoCorrectEnabled = false, + ), ) } From 676032d0fbd408921dfb7404f85ee9c7e7d263a6 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 24 Feb 2025 20:39:16 +0100 Subject: [PATCH 06/14] feat(join by alias) : improve state management --- .../JoinRoomByAddressPresenter.kt | 75 ++++++++++++++----- .../joinbyaddress/JoinRoomByAddressState.kt | 5 +- .../JoinRoomByAddressStateProvider.kt | 15 ++-- .../joinbyaddress/JoinRoomByAddressView.kt | 31 +++++--- 4 files changed, 92 insertions(+), 34 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt index d721deb467..be1334e253 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt @@ -9,6 +9,7 @@ package io.element.android.features.createroom.impl.joinbyaddress import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -22,9 +23,13 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomAlias -import io.element.android.libraries.matrix.api.core.RoomIdOrAlias +import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper import kotlinx.coroutines.delay +import kotlinx.coroutines.withTimeoutOrNull +import kotlin.time.Duration.Companion.seconds + +private const val ADDRESS_RESOLVE_TIMEOUT_IN_SECONDS = 10 class JoinRoomByAddressPresenter @AssistedInject constructor( @Assisted private val navigator: CreateRoomNavigator, @@ -40,16 +45,20 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( @Composable override fun present(): JoinRoomByAddressState { var address by remember { mutableStateOf("") } - var addressState by remember { mutableStateOf(RoomAddressState.Unknown) } + var internalAddressState by remember { mutableStateOf(RoomAddressState.Unknown) } + var validateAddress: Boolean by remember { mutableStateOf(false) } fun handleEvents(event: JoinRoomByAddressEvents) { when (event) { JoinRoomByAddressEvents.Continue -> { - navigator.onDismissJoinRoomByAddress() - navigator.onOpenRoom(RoomIdOrAlias.Alias(RoomAlias(address))) + when (val currentState = internalAddressState) { + is RoomAddressState.RoomFound -> onRoomFound(currentState) + else -> validateAddress = true + } } JoinRoomByAddressEvents.Dismiss -> navigator.onDismissJoinRoomByAddress() is JoinRoomByAddressEvents.UpdateAddress -> { + validateAddress = false address = event.address.trim() } } @@ -57,9 +66,25 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( RoomAddressStateEffect( fullAddress = address, - onRoomAddressStateChange = { addressState = it } + onRoomAddressStateChange = { addressState -> + internalAddressState = addressState + if (addressState is RoomAddressState.RoomFound && validateAddress) { + onRoomFound(addressState) + } + } ) + val addressState by remember { + derivedStateOf { + // We only want to show the "RoomFound" state as long as the user didn't validate the address. + if (validateAddress || internalAddressState is RoomAddressState.RoomFound) { + internalAddressState + } else { + RoomAddressState.Unknown + } + } + } + return JoinRoomByAddressState( address = address, addressState = addressState, @@ -67,6 +92,11 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( ) } + private fun onRoomFound(state: RoomAddressState.RoomFound) { + navigator.onDismissJoinRoomByAddress() + navigator.onOpenRoom(state.resolved.roomId.toRoomIdOrAlias()) + } + @Composable private fun RoomAddressStateEffect( fullAddress: String, @@ -74,24 +104,35 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( ) { val onChange by rememberUpdatedState(onRoomAddressStateChange) LaunchedEffect(fullAddress) { - if (fullAddress.isEmpty()) { - onChange(RoomAddressState.Unknown) - return@LaunchedEffect - } - // debounce the room address validation + // Whenever the address changes, reset the state to unknown + onChange(RoomAddressState.Unknown) + // debounce the room address resolution delay(300) val roomAlias = tryOrNull { RoomAlias(fullAddress) } - if (roomAlias == null || !roomAliasHelper.isRoomAliasValid(roomAlias)) { - onChange(RoomAddressState.Invalid) + if (roomAlias != null && roomAliasHelper.isRoomAliasValid(roomAlias)) { + onChange(RoomAddressState.Resolving) + onChange(client.resolveRoomAddress(roomAlias)) } else { - onChange(RoomAddressState.Valid(matchingRoomFound = false)) - client.resolveRoomAlias(roomAlias) - .onSuccess { resolved -> - onChange(RoomAddressState.Valid(matchingRoomFound = resolved.isPresent)) - } + onChange(RoomAddressState.Invalid) } } } + + private suspend fun MatrixClient.resolveRoomAddress(roomAlias: RoomAlias): RoomAddressState { + return withTimeoutOrNull(ADDRESS_RESOLVE_TIMEOUT_IN_SECONDS.seconds) { + resolveRoomAlias(roomAlias) + .fold( + onSuccess = { resolved -> + if (resolved.isPresent) { + RoomAddressState.RoomFound(resolved.get()) + } else { + RoomAddressState.RoomNotFound + } + }, + onFailure = { _ -> RoomAddressState.RoomNotFound } + ) + } ?: RoomAddressState.RoomNotFound + } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt index 6d5be3dfef..11791181e1 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressState.kt @@ -8,6 +8,7 @@ package io.element.android.features.createroom.impl.joinbyaddress import androidx.compose.runtime.Immutable +import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias data class JoinRoomByAddressState( val address: String, @@ -19,5 +20,7 @@ data class JoinRoomByAddressState( sealed interface RoomAddressState { data object Unknown : RoomAddressState data object Invalid : RoomAddressState - data class Valid(val matchingRoomFound: Boolean) : RoomAddressState + data object Resolving : RoomAddressState + data object RoomNotFound : RoomAddressState + data class RoomFound(val resolved: ResolvedRoomAlias) : RoomAddressState } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt index de20b1bc1c..12e605e04c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt @@ -8,16 +8,21 @@ package io.element.android.features.createroom.impl.joinbyaddress import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias open class JoinRoomByAddressStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aJoinRoomByAddressState(), - aJoinRoomByAddressState("#room-"), - aJoinRoomByAddressState("#room-", addressState = RoomAddressState.Invalid), - aJoinRoomByAddressState("#room-name:matrix.org", addressState = RoomAddressState.Valid(true)), - aJoinRoomByAddressState("#room-name-here:matrix.org", addressState = RoomAddressState.Valid(false)), - // Add other states here + aJoinRoomByAddressState(address = "#room-"), + aJoinRoomByAddressState(address = "#room-", addressState = RoomAddressState.Invalid), + aJoinRoomByAddressState(address = "#room-name:matrix.org", addressState = RoomAddressState.Resolving), + aJoinRoomByAddressState(address = "#room-name-none:matrix.org", addressState = RoomAddressState.RoomNotFound), + aJoinRoomByAddressState( + address = "#room-name:matrix.org", + addressState = RoomAddressState.RoomFound(ResolvedRoomAlias(RoomId("!aRoom:id"), emptyList())), + ), ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index 5e7d515090..8c27cbfe81 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.rememberModalBottomSheetState @@ -23,7 +24,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.libraries.designsystem.preview.ElementPreview @@ -60,13 +63,16 @@ fun JoinRoomByAddressView( requestFocus = sheetState.isVisible, onAddressChange = { state.eventSink(JoinRoomByAddressEvents.UpdateAddress(it)) - } + }, + onContinue = { + state.eventSink(JoinRoomByAddressEvents.Continue) + }, ) Spacer(modifier = Modifier.height(24.dp)) Button( text = stringResource(CommonStrings.action_continue), modifier = Modifier.fillMaxWidth(), - enabled = state.addressState is RoomAddressState.Valid, + showProgress = state.addressState is RoomAddressState.Resolving, onClick = { state.eventSink(JoinRoomByAddressEvents.Continue) } @@ -81,6 +87,7 @@ private fun RoomAddressField( addressState: RoomAddressState, requestFocus: Boolean, onAddressChange: (String) -> Unit, + onContinue: () -> Unit, modifier: Modifier = Modifier, ) { val focusRequester = remember { FocusRequester() } @@ -94,24 +101,26 @@ private fun RoomAddressField( placeholder = "Enter...", supportingText = when (addressState) { RoomAddressState.Invalid -> "Not a valid address" - RoomAddressState.Unknown -> "e.g. #room-name:matrix.org" - is RoomAddressState.Valid -> if (addressState.matchingRoomFound) { - "Matching room found" - } else { - "e.g. #room-name:matrix.org" - } + is RoomAddressState.RoomFound -> "Matching room found" + RoomAddressState.RoomNotFound -> "Room not found" + RoomAddressState.Unknown, RoomAddressState.Resolving -> "e.g. #room-name:matrix.org" }, validity = when (addressState) { - RoomAddressState.Unknown -> null - RoomAddressState.Invalid -> TextFieldValidity.Invalid - is RoomAddressState.Valid -> if (addressState.matchingRoomFound) TextFieldValidity.Valid else null + RoomAddressState.Unknown, RoomAddressState.Resolving -> null + RoomAddressState.Invalid, RoomAddressState.RoomNotFound -> TextFieldValidity.Invalid + is RoomAddressState.RoomFound -> TextFieldValidity.Valid }, onValueChange = onAddressChange, singleLine = true, keyboardOptions = KeyboardOptions( capitalization = KeyboardCapitalization.None, autoCorrectEnabled = false, + keyboardType = KeyboardType.Uri, + imeAction = ImeAction.Go ), + keyboardActions = KeyboardActions( + onGo = { onContinue() } + ) ) } From b42825c5a3ccb91467b6053c043463a3cd8b78c2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 24 Feb 2025 21:02:51 +0100 Subject: [PATCH 07/14] feat(join by alias) : use correct room icon --- .../android/features/createroom/impl/root/CreateRoomRootView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index c24010942e..31bd41a083 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -175,7 +175,7 @@ private fun CreateRoomActionButtonsList( } item { CreateRoomActionButton( - iconRes = CompoundDrawables.ic_compound_mention, + iconRes = CompoundDrawables.ic_compound_room, text = "Join room by address", onClick = onJoinByAddressClick, ) From 818af20f398fbb09fdf2e60d6289bdfc2839bd9e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 09:47:02 +0100 Subject: [PATCH 08/14] feat(join by alias) : use localazy strings --- .../impl/joinbyaddress/JoinRoomByAddressView.kt | 13 +++++++------ .../createroom/impl/root/CreateRoomRootView.kt | 2 +- .../impl/src/main/res/values/localazy.xml | 6 ++++++ tools/localazy/config.json | 3 ++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index 8c27cbfe81..1ae36c31b4 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp +import io.element.android.features.createroom.impl.R import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Button @@ -97,13 +98,13 @@ private fun RoomAddressField( TextField( modifier = modifier.focusRequester(focusRequester), value = address, - label = "Join room by address", - placeholder = "Enter...", + label = stringResource(R.string.screen_start_chat_join_room_by_address_action), + placeholder = stringResource(R.string.screen_start_chat_join_room_by_address_placeholder), supportingText = when (addressState) { - RoomAddressState.Invalid -> "Not a valid address" - is RoomAddressState.RoomFound -> "Matching room found" - RoomAddressState.RoomNotFound -> "Room not found" - RoomAddressState.Unknown, RoomAddressState.Resolving -> "e.g. #room-name:matrix.org" + RoomAddressState.Invalid -> stringResource(R.string.screen_start_chat_join_room_by_address_invalid_address) + is RoomAddressState.RoomFound -> stringResource(R.string.screen_start_chat_join_room_by_address_room_found) + RoomAddressState.RoomNotFound -> stringResource(R.string.screen_start_chat_join_room_by_address_room_not_found) + RoomAddressState.Unknown, RoomAddressState.Resolving -> stringResource(R.string.screen_start_chat_join_room_by_address_supporting_text) }, validity = when (addressState) { RoomAddressState.Unknown, RoomAddressState.Resolving -> null diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt index 31bd41a083..6f008d7283 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -176,7 +176,7 @@ private fun CreateRoomActionButtonsList( item { CreateRoomActionButton( iconRes = CompoundDrawables.ic_compound_room, - text = "Join room by address", + text = stringResource(R.string.screen_start_chat_join_room_by_address_action), onClick = onJoinByAddressClick, ) } diff --git a/features/createroom/impl/src/main/res/values/localazy.xml b/features/createroom/impl/src/main/res/values/localazy.xml index 6ed5510ce0..71208bf9e9 100644 --- a/features/createroom/impl/src/main/res/values/localazy.xml +++ b/features/createroom/impl/src/main/res/values/localazy.xml @@ -20,4 +20,10 @@ You can change this anytime in room settings." "Create a room" "Topic (optional)" "An error occurred when trying to start a chat" + "Join room by address" + "Not a valid address" + "Enter…" + "Matching room found" + "Room not found" + "e.g. #room-name:matrix.org" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index a085b36619..20a53fdcf0 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -64,7 +64,8 @@ "includeRegex" : [ "screen_create_room_.*", "screen\\.create_room\\..*", - "screen_start_chat_.*" + "screen_start_chat_.*", + "screen\\.start_chat\\..*" ] }, { From c220fb085a5a311aaa598a53a1d82d550b98e881 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 11:34:29 +0100 Subject: [PATCH 09/14] feat(join by alias) : makes sure to pass server names --- .../kotlin/io/element/android/appnav/LoggedInFlowNode.kt | 4 ++-- .../android/features/createroom/api/CreateRoomEntryPoint.kt | 2 +- .../android/features/createroom/CreateRoomNavigator.kt | 6 +++--- .../android/features/createroom/impl/CreateRoomFlowNode.kt | 4 ++-- .../createroom/impl/configureroom/ConfigureRoomNode.kt | 2 +- .../impl/joinbyaddress/JoinRoomByAddressPresenter.kt | 5 ++++- .../features/createroom/impl/root/CreateRoomRootNode.kt | 2 +- 7 files changed, 14 insertions(+), 11 deletions(-) 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 54ec8f1f48..f78f3aa668 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -357,8 +357,8 @@ class LoggedInFlowNode @AssistedInject constructor( } NavTarget.CreateRoom -> { val callback = object : CreateRoomEntryPoint.Callback { - override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) { - backstack.replace(NavTarget.Room(roomIdOrAlias)) + override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) { + backstack.replace(NavTarget.Room(roomIdOrAlias = roomIdOrAlias, serverNames = serverNames)) } } 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 e96d7e7879..c15db6dabd 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 @@ -21,6 +21,6 @@ interface CreateRoomEntryPoint : FeatureEntryPoint { } interface Callback : Plugin { - fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) + fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt index a7b15a4417..4f9319e292 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt @@ -17,7 +17,7 @@ import io.element.android.libraries.architecture.overlay.operation.show import io.element.android.libraries.matrix.api.core.RoomIdOrAlias interface CreateRoomNavigator : Plugin { - fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) + fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) fun onCreateNewRoom() fun onShowJoinRoomByAddress() fun onDismissJoinRoomByAddress() @@ -26,10 +26,10 @@ interface CreateRoomNavigator : Plugin { class DefaultCreateRoomNavigator( private val backstack: BackStack, private val overlay: Overlay, - private val openRoom: (RoomIdOrAlias) -> Unit, + private val openRoom: (RoomIdOrAlias, List) -> Unit, ) : CreateRoomNavigator { - override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias) = openRoom(roomIdOrAlias) + override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) = openRoom(roomIdOrAlias, serverNames) override fun onCreateNewRoom() { backstack.push(NavTarget.NewRoom) 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 7fb4830e0f..9d70950992 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 @@ -60,8 +60,8 @@ class CreateRoomFlowNode @AssistedInject constructor( private val navigator = DefaultCreateRoomNavigator( backstack = backstack, overlay = overlay, - openRoom = { roomIdOrAlias -> - plugins().forEach { it.onOpenRoom(roomIdOrAlias) } + openRoom = { roomIdOrAlias, viaServers -> + plugins().forEach { it.onOpenRoom(roomIdOrAlias, viaServers) } } ) 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 5dce257a23..355478d940 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 @@ -49,7 +49,7 @@ class ConfigureRoomNode @AssistedInject constructor( modifier = modifier, onBackClick = this::navigateUp, onCreateRoomSuccess = { - navigator.onOpenRoom(it.toRoomIdOrAlias()) + navigator.onOpenRoom(roomIdOrAlias = it.toRoomIdOrAlias(), serverNames = emptyList()) }, ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt index be1334e253..ec92d7bd57 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt @@ -94,7 +94,10 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( private fun onRoomFound(state: RoomAddressState.RoomFound) { navigator.onDismissJoinRoomByAddress() - navigator.onOpenRoom(state.resolved.roomId.toRoomIdOrAlias()) + navigator.onOpenRoom( + roomIdOrAlias = state.resolved.roomId.toRoomIdOrAlias(), + serverNames = state.resolved.servers + ) } @Composable diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index b20eb7cf3b..7053b0e856 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -53,7 +53,7 @@ class CreateRoomRootNode @AssistedInject constructor( onCloseClick = this::navigateUp, onNewRoomClick = navigator::onCreateNewRoom, onOpenDM = { - navigator.onOpenRoom(it.toRoomIdOrAlias()) + navigator.onOpenRoom(roomIdOrAlias = it.toRoomIdOrAlias(), serverNames = emptyList()) }, onJoinByAddressClick = navigator::onShowJoinRoomByAddress, onInviteFriendsClick = { invitePeople(activity) } From 14082bcd5b3fac7954694d16f5bc59675dcd1c7e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 15:31:05 +0100 Subject: [PATCH 10/14] feat(join by alias) : add tests --- .../JoinRoomByAddressStateProvider.kt | 3 +- .../impl/FakeCreateRoomNavigator.kt | 35 +++++ .../JoinRoomByAddressPresenterTest.kt | 141 ++++++++++++++++++ .../JoinRoomByAddressViewTest.kt | 64 ++++++++ .../impl/root/CreateRoomRootViewTest.kt | 17 +++ 5 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt create mode 100644 features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt create mode 100644 features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt index 12e605e04c..6281a8e8e3 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressStateProvider.kt @@ -29,8 +29,9 @@ open class JoinRoomByAddressStateProvider : PreviewParameterProvider Unit = {}, ) = JoinRoomByAddressState( address = address, addressState = addressState, - eventSink = {} + eventSink = eventSink ) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt new file mode 100644 index 0000000000..9196605800 --- /dev/null +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl + +import io.element.android.features.createroom.CreateRoomNavigator +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias + +class FakeCreateRoomNavigator( + private val openRoomLambda: (roomIdOrAlias: RoomIdOrAlias, serverNames: List) -> Unit = { _, _ -> }, + private val createNewRoomLambda: () -> Unit = {}, + private val showJoinRoomByAddressLambda: () -> Unit = {}, + private val dismissJoinRoomByAddressLambda: () -> Unit = {}, + + ) : CreateRoomNavigator { + override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) { + openRoomLambda(roomIdOrAlias, serverNames) + } + + override fun onCreateNewRoom() { + createNewRoomLambda() + } + + override fun onShowJoinRoomByAddress() { + showJoinRoomByAddressLambda() + } + + override fun onDismissJoinRoomByAddress() { + dismissJoinRoomByAddressLambda() + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt new file mode 100644 index 0000000000..02608e3c71 --- /dev/null +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt @@ -0,0 +1,141 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import com.google.common.truth.Truth.assertThat +import io.element.android.features.createroom.CreateRoomNavigator +import io.element.android.features.createroom.impl.FakeCreateRoomNavigator +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.RoomIdOrAlias +import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.room.alias.FakeRoomAliasHelper +import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.test +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class JoinRoomByAddressPresenterTest { + + @Test + fun `present - initial state`() = runTest { + val presenter = createJoinRoomByAddressPresenter() + presenter.test { + with(awaitItem()) { + assertThat(address).isEmpty() + assertThat(addressState).isEqualTo(RoomAddressState.Unknown) + } + } + } + + @Test + fun `present - invalid address`() = runTest { + val presenter = createJoinRoomByAddressPresenter( + roomAliasHelper = FakeRoomAliasHelper( + isRoomAliasValidLambda = { false } + ) + ) + presenter.test { + with(awaitItem()) { + eventSink(JoinRoomByAddressEvents.UpdateAddress("invalid_address")) + } + with(awaitItem()) { + assertThat(address).isEqualTo("invalid_address") + assertThat(addressState).isEqualTo(RoomAddressState.Unknown) + eventSink(JoinRoomByAddressEvents.Continue) + } + // The address should be marked as invalid only after the user tries to continue + with(awaitItem()) { + assertThat(address).isEqualTo("invalid_address") + assertThat(addressState).isEqualTo(RoomAddressState.Invalid) + } + } + } + + @Test + fun `present - room found`() = runTest { + val openRoomLambda = lambdaRecorder, Unit> { _, _ -> } + val dismissJoinRoomByAddressLambda = lambdaRecorder { } + val navigator = FakeCreateRoomNavigator( + openRoomLambda = openRoomLambda, + dismissJoinRoomByAddressLambda = dismissJoinRoomByAddressLambda + ) + val presenter = createJoinRoomByAddressPresenter(navigator = navigator) + presenter.test { + with(awaitItem()) { + eventSink(JoinRoomByAddressEvents.UpdateAddress("#room_found:matrix.org")) + } + with(awaitItem()) { + assertThat(address).isEqualTo("#room_found:matrix.org") + assertThat(addressState).isEqualTo(RoomAddressState.Unknown) + } + with(awaitItem()) { + assertThat(address).isEqualTo("#room_found:matrix.org") + assertThat(addressState).isInstanceOf(RoomAddressState.RoomFound::class.java) + eventSink(JoinRoomByAddressEvents.Continue) + } + assert(openRoomLambda).isCalledOnce() + assert(dismissJoinRoomByAddressLambda).isCalledOnce() + } + } + + @Test + fun `present - room not found`() = runTest { + val presenter = createJoinRoomByAddressPresenter( + matrixClient = FakeMatrixClient( + resolveRoomAliasResult = { Result.failure(RuntimeException()) } + ) + ) + presenter.test { + with(awaitItem()) { + eventSink(JoinRoomByAddressEvents.UpdateAddress("#room_not_found:matrix.org")) + } + with(awaitItem()) { + assertThat(address).isEqualTo("#room_not_found:matrix.org") + assertThat(addressState).isEqualTo(RoomAddressState.Unknown) + eventSink(JoinRoomByAddressEvents.Continue) + } + with(awaitItem()) { + assertThat(address).isEqualTo("#room_not_found:matrix.org") + assertThat(addressState).isEqualTo(RoomAddressState.Resolving) + } + with(awaitItem()) { + assertThat(address).isEqualTo("#room_not_found:matrix.org") + assertThat(addressState).isEqualTo(RoomAddressState.RoomNotFound) + } + } + } + + @Test + fun `present - dismiss`() = runTest { + val dismissJoinRoomByAddressLambda = lambdaRecorder { } + val navigator = FakeCreateRoomNavigator( + dismissJoinRoomByAddressLambda = dismissJoinRoomByAddressLambda + ) + val presenter = createJoinRoomByAddressPresenter(navigator = navigator) + presenter.test { + with(awaitItem()) { + eventSink(JoinRoomByAddressEvents.Dismiss) + } + assert(dismissJoinRoomByAddressLambda).isCalledOnce() + } + } + + private fun createJoinRoomByAddressPresenter( + navigator: CreateRoomNavigator = FakeCreateRoomNavigator(), + matrixClient: MatrixClient = FakeMatrixClient(), + roomAliasHelper: RoomAliasHelper = FakeRoomAliasHelper(), + ): JoinRoomByAddressPresenter { + return JoinRoomByAddressPresenter( + navigator = navigator, + client = matrixClient, + roomAliasHelper = roomAliasHelper, + ) + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt new file mode 100644 index 0000000000..79a4efdc02 --- /dev/null +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.joinbyaddress + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performTextInput +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.features.createroom.impl.R +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EventsRecorder +import io.element.android.tests.testutils.clickOn +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class JoinRoomByAddressViewTest { + + @get:Rule + val rule = createAndroidComposeRule() + + @Test + fun `entering text emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setJoinRoomByAddressView( + aJoinRoomByAddressState( + eventSink = eventsRecorder, + ) + ) + val text = rule.activity.getString(R.string.screen_start_chat_join_room_by_address_action) + rule.onNodeWithText(text).performTextInput("#address:matrix.org") + eventsRecorder.assertSingle(JoinRoomByAddressEvents.UpdateAddress("#address:matrix.org")) + } + + @Test + fun `clicking on continue emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setJoinRoomByAddressView( + aJoinRoomByAddressState( + eventSink = eventsRecorder, + ) + ) + rule.clickOn(CommonStrings.action_continue) + eventsRecorder.assertSingle(JoinRoomByAddressEvents.Continue) + } + +} + +private fun AndroidComposeTestRule.setJoinRoomByAddressView( + state: JoinRoomByAddressState, +) { + setContent { + JoinRoomByAddressView(state = state) + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootViewTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootViewTest.kt index 88390f3b8c..e446a13417 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootViewTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootViewTest.kt @@ -101,6 +101,21 @@ class CreateRoomRootViewTest { rule.onNodeWithText(firstRoom.matrixUser.getBestName()).performClick() } } + + @Config(qualifiers = "h1024dp") + @Test + fun `clicking on Join room by address invokes the expected callback`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { + rule.setCreateRoomRootView( + aCreateRoomRootState( + eventSink = eventsRecorder, + ), + onJoinRoomByAddressClick = it + ) + rule.clickOn(R.string.screen_start_chat_join_room_by_address_action) + } + } } private fun AndroidComposeTestRule.setCreateRoomRootView( @@ -109,6 +124,7 @@ private fun AndroidComposeTestRule.setCreat onNewRoomClick: () -> Unit = EnsureNeverCalled(), onOpenDM: (RoomId) -> Unit = EnsureNeverCalledWithParam(), onInviteFriendsClick: () -> Unit = EnsureNeverCalled(), + onJoinRoomByAddressClick: () -> Unit = EnsureNeverCalled(), ) { setContent { CreateRoomRootView( @@ -117,6 +133,7 @@ private fun AndroidComposeTestRule.setCreat onNewRoomClick = onNewRoomClick, onOpenDM = onOpenDM, onInviteFriendsClick = onInviteFriendsClick, + onJoinByAddressClick = onJoinRoomByAddressClick ) } } From 6f8ca622614c28f203f350f1375228017e8e80c1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 15:38:23 +0100 Subject: [PATCH 11/14] feat(join by alias) : format code --- .../android/features/createroom/CreateRoomNavigator.kt | 1 - .../android/features/createroom/impl/ConfigureRoomFlowNode.kt | 1 - .../android/features/createroom/impl/CreateRoomFlowNode.kt | 2 -- .../createroom/impl/configureroom/ConfigureRoomNode.kt | 1 - .../createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt | 2 +- .../createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt | 1 - .../impl/joinbyaddress/JoinRoomByAddressPresenter.kt | 4 ---- .../createroom/impl/joinbyaddress/JoinRoomByAddressView.kt | 1 - .../features/createroom/impl/root/CreateRoomRootNode.kt | 1 - .../features/createroom/impl/FakeCreateRoomNavigator.kt | 1 - .../impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt | 1 - .../impl/joinbyaddress/JoinRoomByAddressViewTest.kt | 2 -- .../features/rageshake/impl/bugreport/BugReportView.kt | 2 +- .../libraries/designsystem/theme/components/TextField.kt | 2 +- .../libraries/matrix/ui/room/address/RoomAddressValidity.kt | 1 - 15 files changed, 3 insertions(+), 20 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt index 4f9319e292..a63c99d06f 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/CreateRoomNavigator.kt @@ -28,7 +28,6 @@ class DefaultCreateRoomNavigator( private val overlay: Overlay, private val openRoom: (RoomIdOrAlias, List) -> Unit, ) : CreateRoomNavigator { - override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) = openRoom(roomIdOrAlias, serverNames) override fun onCreateNewRoom() { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt index 0fdb16bd67..a7678f130f 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/ConfigureRoomFlowNode.kt @@ -60,7 +60,6 @@ class ConfigureRoomFlowNode @AssistedInject constructor( data object ConfigureRoom : NavTarget } - override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { NavTarget.Root -> { 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 9d70950992..b58ebc083e 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 @@ -30,8 +30,6 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.OverlayView import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import kotlinx.parcelize.Parcelize @ContributesNode(SessionScope::class) 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 355478d940..e718825163 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 @@ -30,7 +30,6 @@ class ConfigureRoomNode @AssistedInject constructor( private val presenter: ConfigureRoomPresenter, private val analyticsService: AnalyticsService, ) : Node(buildContext, plugins = plugins) { - private val navigator = plugins().first() init { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt index 58a1223b8f..dbbcef56fa 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressEvents.kt @@ -9,6 +9,6 @@ package io.element.android.features.createroom.impl.joinbyaddress sealed interface JoinRoomByAddressEvents { data object Dismiss : JoinRoomByAddressEvents - data object Continue: JoinRoomByAddressEvents + data object Continue : JoinRoomByAddressEvents data class UpdateAddress(val address: String) : JoinRoomByAddressEvents } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt index ae12caa00e..d6338ab43c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressNode.kt @@ -25,7 +25,6 @@ class JoinRoomByAddressNode @AssistedInject constructor( @Assisted plugins: List, presenterFactory: JoinRoomByAddressPresenter.Factory, ) : Node(buildContext, plugins = plugins) { - private val navigator = plugins().first() private val presenter = presenterFactory.create(navigator) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt index ec92d7bd57..cf4788cbbf 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenter.kt @@ -36,7 +36,6 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( private val client: MatrixClient, private val roomAliasHelper: RoomAliasHelper, ) : Presenter { - @AssistedFactory interface Factory { fun create(navigator: CreateRoomNavigator): JoinRoomByAddressPresenter @@ -137,6 +136,3 @@ class JoinRoomByAddressPresenter @AssistedInject constructor( } ?: RoomAddressState.RoomNotFound } } - - - diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index 1ae36c31b4..6a4942af16 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -132,4 +132,3 @@ internal fun JoinRoomByAddressViewPreview( ) = ElementPreview { JoinRoomByAddressView(state = state) } - diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt index 7053b0e856..8ee982906c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootNode.kt @@ -34,7 +34,6 @@ class CreateRoomRootNode @AssistedInject constructor( private val analyticsService: AnalyticsService, private val inviteFriendsUseCase: InviteFriendsUseCase, ) : Node(buildContext, plugins = plugins) { - private val navigator = plugins().first() init { diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt index 9196605800..b173865b61 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/FakeCreateRoomNavigator.kt @@ -15,7 +15,6 @@ class FakeCreateRoomNavigator( private val createNewRoomLambda: () -> Unit = {}, private val showJoinRoomByAddressLambda: () -> Unit = {}, private val dismissJoinRoomByAddressLambda: () -> Unit = {}, - ) : CreateRoomNavigator { override fun onOpenRoom(roomIdOrAlias: RoomIdOrAlias, serverNames: List) { openRoomLambda(roomIdOrAlias, serverNames) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt index 02608e3c71..d1ee3e801c 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressPresenterTest.kt @@ -22,7 +22,6 @@ import kotlinx.coroutines.test.runTest import org.junit.Test class JoinRoomByAddressPresenterTest { - @Test fun `present - initial state`() = runTest { val presenter = createJoinRoomByAddressPresenter() diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt index 79a4efdc02..bb3ee3e493 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressViewTest.kt @@ -24,7 +24,6 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class JoinRoomByAddressViewTest { - @get:Rule val rule = createAndroidComposeRule() @@ -52,7 +51,6 @@ class JoinRoomByAddressViewTest { rule.clickOn(CommonStrings.action_continue) eventsRecorder.assertSingle(JoinRoomByAddressEvents.Continue) } - } private fun AndroidComposeTestRule.setJoinRoomByAddressView( diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt index 04683d59f1..cebf6a0ae4 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt @@ -91,7 +91,7 @@ fun BugReportView( keyboardController?.hide() }), minLines = 3, - validity = if(state.isDescriptionInError) TextFieldValidity.Invalid else null, + validity = if (state.isDescriptionInError) TextFieldValidity.Invalid else null, ) } Spacer(modifier = Modifier.height(16.dp)) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt index ca56fbf19e..63a5b166ac 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt @@ -321,7 +321,7 @@ private fun ContentToPreview() { TextField( onValueChange = {}, label = "Label", - value = "Hello val=${validity}, en=${enabled.asInt()}, ro=${readonly.asInt()}", + value = "Hello val=$validity, en=${enabled.asInt()}, ro=${readonly.asInt()}", supportingText = "Supporting text", validity = validity, enabled = enabled, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt index d5813ce91f..fef36ccd20 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/address/RoomAddressValidity.kt @@ -8,7 +8,6 @@ package io.element.android.libraries.matrix.ui.room.address import androidx.compose.runtime.Immutable -import io.element.android.libraries.designsystem.theme.components.TextFieldValidity /** * Represents the validity state of a room address. From 25d39c285b83bd1b3312d9f0ccf568fcec8f59a8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 20:27:54 +0100 Subject: [PATCH 12/14] feat(join by alias) : add TextFieldValidity.None instead of nullable --- .../createroom/impl/joinbyaddress/JoinRoomByAddressView.kt | 2 +- .../android/features/rageshake/impl/bugreport/BugReportView.kt | 2 +- .../impl/reset/password/ResetIdentityPasswordView.kt | 2 +- .../libraries/designsystem/theme/components/TextField.kt | 3 ++- .../libraries/matrix/ui/room/address/RoomAddressField.kt | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt index 6a4942af16..c256f5140c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/joinbyaddress/JoinRoomByAddressView.kt @@ -107,7 +107,7 @@ private fun RoomAddressField( RoomAddressState.Unknown, RoomAddressState.Resolving -> stringResource(R.string.screen_start_chat_join_room_by_address_supporting_text) }, validity = when (addressState) { - RoomAddressState.Unknown, RoomAddressState.Resolving -> null + RoomAddressState.Unknown, RoomAddressState.Resolving -> TextFieldValidity.None RoomAddressState.Invalid, RoomAddressState.RoomNotFound -> TextFieldValidity.Invalid is RoomAddressState.RoomFound -> TextFieldValidity.Valid }, diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt index cebf6a0ae4..2272e8fe94 100644 --- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt +++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt @@ -91,7 +91,7 @@ fun BugReportView( keyboardController?.hide() }), minLines = 3, - validity = if (state.isDescriptionInError) TextFieldValidity.Invalid else null, + validity = if (state.isDescriptionInError) TextFieldValidity.Invalid else TextFieldValidity.None, ) } Spacer(modifier = Modifier.height(16.dp)) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt index aedb962a64..b8545a271c 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt @@ -100,7 +100,7 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool Icon(imageVector = image, description) } }, - validity = if (hasError) TextFieldValidity.Invalid else null, + validity = if (hasError) TextFieldValidity.Invalid else TextFieldValidity.None, supportingText = if (hasError) { stringResource(R.string.screen_reset_encryption_password_error) } else { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt index 63a5b166ac..51041f8168 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt @@ -58,7 +58,7 @@ fun TextField( placeholder: String? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, - validity: TextFieldValidity? = null, + validity: TextFieldValidity = TextFieldValidity.None, enabled: Boolean = true, readOnly: Boolean = false, singleLine: Boolean = false, @@ -288,6 +288,7 @@ private fun SupportingTextLayout(validity: TextFieldValidity?, supportingText: S } enum class TextFieldValidity { + None, Invalid, Valid } 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 fab4d153ec..f97e2ff766 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 @@ -59,7 +59,7 @@ fun RoomAddressField( }, validity = when (addressValidity) { RoomAddressValidity.InvalidSymbols, RoomAddressValidity.NotAvailable -> TextFieldValidity.Invalid - else -> null + else -> TextFieldValidity.None }, onValueChange = onAddressChange, singleLine = true, From a6c3428680d7b4b3ce0ec72114e1676b3af000d3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Feb 2025 20:28:05 +0100 Subject: [PATCH 13/14] feat(join by alias) : small clean up --- .../io/element/android/features/roomlist/impl/RoomListView.kt | 1 - .../impl/reset/password/ResetIdentityPasswordView.kt | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt index 6bf916873e..877442ef1b 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt @@ -152,7 +152,6 @@ private fun RoomListScaffold( onClick = onCreateRoomClick ) { Icon( - // Note cannot use Icons.Outlined.EditSquare, it does not exist :/ imageVector = CompoundIcons.Plus(), contentDescription = stringResource(id = R.string.screen_roomlist_a11y_create_message), tint = ElementTheme.colors.iconOnSolidPrimary, diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt index b8545a271c..998b46046c 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/password/ResetIdentityPasswordView.kt @@ -83,8 +83,8 @@ private fun Content(text: String, onTextChange: (String) -> Unit, hasError: Bool var showPassword by remember { mutableStateOf(false) } TextField( modifier = Modifier - .fillMaxWidth() - .onTabOrEnterKeyFocusNext(LocalFocusManager.current), + .fillMaxWidth() + .onTabOrEnterKeyFocusNext(LocalFocusManager.current), value = text, onValueChange = onTextChange, placeholder = stringResource(CommonStrings.common_password), From f00337e98b425af4e485d529801a72cb0aa94d30 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 25 Feb 2025 19:39:04 +0000 Subject: [PATCH 14/14] Update screenshots --- ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en.png | 3 +++ ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en.png | 3 +++ ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en.png | 3 +++ ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en.png | 3 +++ ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en.png | 3 +++ ...room.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en.png | 3 +++ ...om.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en.png | 3 +++ ...tures.createroom.impl.root_CreateRoomRootView_Day_0_en.png | 4 ++-- ...tures.createroom.impl.root_CreateRoomRootView_Day_3_en.png | 4 ++-- ...res.createroom.impl.root_CreateRoomRootView_Night_0_en.png | 4 ++-- ...res.createroom.impl.root_CreateRoomRootView_Night_3_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_0_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_10_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_1_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_2_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_6_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_7_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_8_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_0_en.png | 4 ++-- .../features.roomlist.impl_RoomListView_Night_10_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_1_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_2_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_6_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_7_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_8_en.png | 4 ++-- ...gnsystem.theme.components_TextFieldsDark_TextFields_en.png | 4 ++-- ...nsystem.theme.components_TextFieldsLight_TextFields_en.png | 4 ++-- 32 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en.png new file mode 100644 index 0000000000..b46d76faa6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddac666d01929c8df834cff1e932eba12dbf377c7954cd4fdf2fa13bbb1e77be +size 16758 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en.png new file mode 100644 index 0000000000..e73def12a8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae779c152a099185e14a4301ff47825cfd809a81e651e36cb3261fb3371f61e7 +size 17424 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en.png new file mode 100644 index 0000000000..e9b5bde96e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3c89ad3af16b43b6798c30077651b7c9eefd0059d847f5ff643877a2d3d3403 +size 17025 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en.png new file mode 100644 index 0000000000..bca0bfcc78 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f39dc9170e9e85d1f56b8b7f1b80fbbb7d5acaa762a585a6c52b494c8b25b285 +size 20884 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en.png new file mode 100644 index 0000000000..3731d3e265 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30c89188415418f6015349fe9371792052f8c171272ce7ccb45352e79b15774f +size 20192 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en.png new file mode 100644 index 0000000000..dc23bff507 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a67b688327c3507e0072fad948b62c19acfb454aa05ac42832ee1a980c725492 +size 20174 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en.png new file mode 100644 index 0000000000..e5781c467d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4285614e42cec849331dfac0a8d67786cc95f768815d5818a1c06fb97f14530 +size 15599 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en.png new file mode 100644 index 0000000000..6e2fccda25 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9610111f2ad914faf1f890faa1b593ccf04ec42248f04586f403a0f8bfbd5991 +size 16196 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en.png new file mode 100644 index 0000000000..a6a270af66 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9be8c0f212d2ba8d1e4746038280114f50367f078e5ef63ae4e5faa730552630 +size 15629 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en.png new file mode 100644 index 0000000000..c59ae8781a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca43cfd340541ee672c5b79727f4033fa21a4e5351dbef55cf48999946d3a2c6 +size 19474 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en.png new file mode 100644 index 0000000000..e3d91770a6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e04c7204d560370bcd2ed9bf775a892b65f22bd395f7079375e963cd46cce8ec +size 18710 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en.png new file mode 100644 index 0000000000..f10cf4b795 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9824bb57bbe04b48d5a2750a56a9cd36cd32bf4a4a2ebf9dd19c213e1cfb9d6 +size 18565 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_0_en.png index ec1c92eb4e..a5a5d5f71e 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6c1aed2fb05e5220d335bc0ffc9a6851e9207efd2dcabb2ce2100e61516bc57 -size 21409 +oid sha256:f19636ec23d81de10c454b3a0f4c957b999b0fd706363854eb81b62d3072ebcd +size 25781 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_3_en.png index 9c0d5f7a9a..413ee4d711 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35e14513f620f9060ed5b7d8db55175f96d57b45f4187b4f9e2be4bb56016dcd -size 48218 +oid sha256:e86339de00f7e6d44c1d36004c79a9c077d7d99d55ba01da8ea9e4d3b4567367 +size 53085 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_0_en.png index f2582e324c..78416bc049 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2d669d6ce18e6cf641b85f7edf1870b96f3289d55dd89779e1c6388147b4055 -size 20409 +oid sha256:c9f8d6270b9db5463649ce357463cec93945d924bebaeb7da14bfa2936088620 +size 24735 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_3_en.png index 89544d8cec..77ff9cc7cd 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7976aeaf533239d0bda8204e305d1ef6b977b0f7f8755025c36fe76b1a36e8c4 -size 48097 +oid sha256:baa7c2ce997853e150eeb0193798af8d2ec1084b1791da579b2de6544e07d06f +size 52657 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png index 845f5acd9e..ccdeb22980 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09b8dcff40d9231cbd5b81db4836081046dba2bab37d9b4e7bae49abf7debd22 -size 82933 +oid sha256:5b120ebcbb9dae050b83d6d769918e2cb2a0088ea9670df9d15adc967ca69bbd +size 82399 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png index e7e953fd68..af8ab93af2 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:edb52d5fc252ee719f6aec12faf98b8976eb9a61992dba510c06386999975ed2 -size 105988 +oid sha256:aba3ee6d75f3b8671e4249e98386a689f59a8635bc43693c8333ea794b368726 +size 105477 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png index 845f5acd9e..ccdeb22980 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09b8dcff40d9231cbd5b81db4836081046dba2bab37d9b4e7bae49abf7debd22 -size 82933 +oid sha256:5b120ebcbb9dae050b83d6d769918e2cb2a0088ea9670df9d15adc967ca69bbd +size 82399 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png index d165a8c1f7..73e1e61ee7 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e398afce8d17e333d7f33ed134dbc1de6651e525f72dff0980827df2609b5273 -size 83578 +oid sha256:fff21c904f2fdfb25a39a931fc53909c35555247128959bd4cdd0c839b70c105 +size 83039 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png index 96cd13c035..4f7d62b822 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85925c39a59d3ceca4da5234084a3218a33670a9e3fbd3121ef601e06fb93297 -size 100367 +oid sha256:58178368a0a5de71b236c9f0f82457f0cc1a94ae0f828ba72c0851bbce0a29e9 +size 99858 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_7_en.png index 95582e918b..a8880ed6cb 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0762f1f181107fad31c233bb1013cf82c6de2b94500e592609fdcc43e53a5807 -size 46550 +oid sha256:9988051950123717fc5e2e6b6db2be0b905c6d47e81a485a20cd23daab9fbba1 +size 46019 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_8_en.png index a22032f937..6e0088ee14 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3fef8280fdce4608a30e24063699ab99bcb55865b2df51b070e2dc0eafce23a6 -size 41271 +oid sha256:f65131302fab3b0ba710528947376b57230a74731aa6549473998c30f4e07f6e +size 40681 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png index 5dc5152a67..7a84b4ad13 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc64620fffb86bb5bcbb175795ebde2b84c18e6989f99528046b1ab14f3c9005 -size 89396 +oid sha256:56ec28811fc81c49f1f3fa5c9125d668b0401ee4645feb33508ba32a33a6bf55 +size 88850 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png index 3bb6183058..c355721e47 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ee1b7d094db4cd00af34d1ef79c6e71ed61cec585612c538a0bc870c64b9966 -size 111814 +oid sha256:3125f559a0531c2b3b63957a7ca7cff2a718c5a2e00f5213e38e6e65b005f942 +size 111313 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png index 5dc5152a67..7a84b4ad13 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc64620fffb86bb5bcbb175795ebde2b84c18e6989f99528046b1ab14f3c9005 -size 89396 +oid sha256:56ec28811fc81c49f1f3fa5c9125d668b0401ee4645feb33508ba32a33a6bf55 +size 88850 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png index defce1a22e..c6ad887622 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28ba0acc4ef26efdb4bc2f18c1643a82a180cfa429302da9df3ebce73f3f6552 -size 89287 +oid sha256:961ea9cb682807f6a423cb3fa69f3d7a8838339fdb33de8de8baf55ac22ec239 +size 88758 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png index 3543bb4fb2..ecc286dbd9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49097acd61396b5190aa1820c61d826b04738dd56acb4cdfb5df5b04c486e961 -size 106227 +oid sha256:3cdebb7664e5a7aefbdc35f8d442cc39a07f5debc3fc9ceb7be384eefdf3da33 +size 105760 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_7_en.png index 6ab0b8da39..7552177fc0 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e339f50db6e8b06bdf5a26559827f92f5a9fd2f20bce4a45d4edf5d45e071b9 -size 53790 +oid sha256:2264d2aa03b36178a6ffa315a1147dba5cd6a698ae2fb4fe0942857964de2b47 +size 53250 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_8_en.png index fefb0a3731..66309e8b71 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9496a4dd417cb64c20a1d53fb27f9f567f0eefc8c0ad428a9c6c4041f66eddb0 -size 47845 +oid sha256:1c6dc3c0c72d1ea8a980f393d7cfe2c9e0392016c8fc25b901817dd077d8526c +size 47265 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsDark_TextFields_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsDark_TextFields_en.png index f0177c8a61..6302c4f1df 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsDark_TextFields_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsDark_TextFields_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:165bbcda11115c490250a86ac45d84277362a8c0fc0931473f1dc729b5eaa70d -size 42804 +oid sha256:0eb5d9fc0da36b69863c9ab9ebac6ef2cfe5d57c0f161be2ebc6247229819d17 +size 43209 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsLight_TextFields_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsLight_TextFields_en.png index 806bbe951c..24d888598d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsLight_TextFields_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_TextFieldsLight_TextFields_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86b121d1b8c7ea4b2401ca6ea36897b630f41b5fa9961c5bcb8746a142b8c26f -size 44373 +oid sha256:514cc5ef29ef732a2b03010cf05a79607498919fc0c9d8afedc8713b77b24ae0 +size 44877