diff --git a/build.gradle.kts b/build.gradle.kts index f06c924d37..431a83540f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.cli.common.toBooleanLenient buildscript { dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10") } } diff --git a/changelog.d/108.wip b/changelog.d/108.wip new file mode 100644 index 0000000000..e483e7f6ea --- /dev/null +++ b/changelog.d/108.wip @@ -0,0 +1 @@ +[Create and join rooms] Select members before creating a room (UI for selection) diff --git a/changelog.d/89.bugfix b/changelog.d/89.bugfix new file mode 100644 index 0000000000..8c3faa2e4b --- /dev/null +++ b/changelog.d/89.bugfix @@ -0,0 +1 @@ +Design fixes for the session verification flow and button components. diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index dc7eaded75..366cc1e0bd 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -38,9 +38,8 @@ anvil { } dependencies { - anvil(projects.anvilcodegen) implementation(projects.anvilannotations) - + anvil(projects.anvilcodegen) implementation(projects.libraries.core) implementation(projects.libraries.architecture) implementation(projects.libraries.matrix.api) @@ -48,6 +47,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) + implementation(projects.features.selectusers.api) api(projects.features.createroom.api) testImplementation(libs.test.junit) @@ -56,6 +56,7 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) + testImplementation(projects.features.selectusers.impl) androidTestImplementation(libs.test.junitext) 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 618eda0166..13c3ff52be 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt @@ -24,9 +24,11 @@ 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.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.impl.addpeople.AddPeopleNode import io.element.android.features.createroom.impl.root.CreateRoomRootNode import io.element.android.libraries.architecture.BackstackNode import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler @@ -50,11 +52,22 @@ class CreateRoomFlowNode @AssistedInject constructor( sealed interface NavTarget : Parcelable { @Parcelize object Root : NavTarget + + @Parcelize + object NewRoom : NavTarget } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { return when (navTarget) { - NavTarget.Root -> createNode(buildContext) + NavTarget.Root -> { + val callback = object : CreateRoomRootNode.Callback { + override fun onCreateNewRoom() { + backstack.push(NavTarget.NewRoom) + } + } + createNode(buildContext, plugins = listOf(callback)) + } + NavTarget.NewRoom -> createNode(buildContext) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleEvents.kt new file mode 100644 index 0000000000..5d246be501 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleEvents.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +sealed interface AddPeopleEvents diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt new file mode 100644 index 0000000000..5393075d18 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +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 dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.di.SessionScope + +@ContributesNode(SessionScope::class) +class AddPeopleNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: AddPeoplePresenter, +) : Node(buildContext, plugins = plugins) { + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + AddPeopleView( + state = state, + modifier = modifier, + onBackPressed = { navigateUp() }, + onNextPressed = { }, + ) + } +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt new file mode 100644 index 0000000000..51b2928862 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenter.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +import androidx.compose.runtime.Composable +import io.element.android.features.selectusers.api.SelectUsersPresenter +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.api.SelectionMode +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +class AddPeoplePresenter @Inject constructor( + private val selectUsersPresenterFactory: SelectUsersPresenter.Factory, +) : Presenter { + + private val selectUsersPresenter by lazy { + selectUsersPresenterFactory.create(SelectUsersPresenterArgs(SelectionMode.Multiple)) + } + + @Composable + override fun present(): AddPeopleState { + val selectUsersState = selectUsersPresenter.present() + + fun handleEvents(event: AddPeopleEvents) { + // do nothing for now + } + + return AddPeopleState( + selectUsersState = selectUsersState, + eventSink = ::handleEvents, + ) + } +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleState.kt new file mode 100644 index 0000000000..8212d02cc4 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleState.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +import io.element.android.features.selectusers.api.SelectUsersState + +data class AddPeopleState( + val selectUsersState: SelectUsersState, + val eventSink: (AddPeopleEvents) -> Unit, +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleStateProvider.kt new file mode 100644 index 0000000000..6f1679e252 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleStateProvider.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.features.selectusers.api.SelectionMode +import io.element.android.features.selectusers.api.aListOfSelectedUsers +import io.element.android.features.selectusers.api.aSelectUsersState + +open class AddPeopleStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aAddPeopleState(), + aAddPeopleState().copy( + selectUsersState = aSelectUsersState().copy( + selectedUsers = aListOfSelectedUsers(), + selectionMode = SelectionMode.Multiple, + ) + ), + aAddPeopleState().copy( + selectUsersState = aSelectUsersState().copy( + selectedUsers = aListOfSelectedUsers(), + isSearchActive = true, + selectionMode = SelectionMode.Multiple, + ) + ) + ) +} + +fun aAddPeopleState() = AddPeopleState( + selectUsersState = aSelectUsersState(), + eventSink = {} +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt new file mode 100644 index 0000000000..ba2abb498d --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.createroom.impl.addpeople + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.features.selectusers.api.SelectUsersView +import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar +import io.element.android.libraries.designsystem.theme.components.Scaffold +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.components.TextButton +import io.element.android.libraries.ui.strings.R as StringR + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AddPeopleView( + state: AddPeopleState, + modifier: Modifier = Modifier, + onBackPressed: () -> Unit = {}, + onNextPressed: () -> Unit = {}, +) { + val eventSink = state.eventSink + + Scaffold( + topBar = { + if (!state.selectUsersState.isSearchActive) { + AddPeopleViewTopBar( + hasSelectedUsers = state.selectUsersState.selectedUsers.isNotEmpty(), + onBackPressed = onBackPressed, + onNextPressed = onNextPressed, + ) + } + } + ) { padding -> + Column( + modifier = modifier + .fillMaxSize() + .padding(padding), + ) { + SelectUsersView( + modifier = Modifier.fillMaxWidth(), + state = state.selectUsersState, + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AddPeopleViewTopBar( + hasSelectedUsers: Boolean, + modifier: Modifier = Modifier, + onBackPressed: () -> Unit = {}, + onNextPressed: () -> Unit = {}, +) { + CenterAlignedTopAppBar( + modifier = modifier, + title = { + Text( + text = stringResource(id = StringR.string.add_people), + fontSize = 16.sp, + fontWeight = FontWeight.SemiBold, + ) + }, + navigationIcon = { BackButton(onClick = onBackPressed) }, + actions = { + TextButton( + modifier = Modifier.padding(horizontal = 8.dp), + onClick = onNextPressed, + ) { + val textActionResId = if (hasSelectedUsers) StringR.string.action_next else StringR.string.action_skip + Text( + text = stringResource(id = textActionResId), + fontSize = 16.sp, + ) + } + } + ) +} + +@Preview +@Composable +internal fun AddPeopleViewLightPreview(@PreviewParameter(AddPeopleStateProvider::class) state: AddPeopleState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +internal fun AddPeopleViewDarkPreview(@PreviewParameter(AddPeopleStateProvider::class) state: AddPeopleState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: AddPeopleState) { + AddPeopleView(state = state) +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt index ddf2003e83..5d2f0f684c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt @@ -19,9 +19,6 @@ package io.element.android.features.createroom.impl.root import io.element.android.libraries.matrix.ui.model.MatrixUser sealed interface CreateRoomRootEvents { - data class UpdateSearchQuery(val query: String) : CreateRoomRootEvents data class StartDM(val matrixUser: MatrixUser) : CreateRoomRootEvents - object CreateRoom : CreateRoomRootEvents object InvitePeople : CreateRoomRootEvents - data class OnSearchActiveChanged(val active: Boolean) : CreateRoomRootEvents } 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 16a965695f..dadc16efc4 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 @@ -22,6 +22,7 @@ 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 @@ -35,6 +36,14 @@ class CreateRoomRootNode @AssistedInject constructor( private val presenter: CreateRoomRootPresenter, ) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun onCreateNewRoom() + } + + private fun onCreateNewRoom() { + plugins().forEach { it.onCreateNewRoom() } + } + sealed interface NavTarget : Parcelable { @Parcelize object Root : NavTarget @@ -47,6 +56,7 @@ class CreateRoomRootNode @AssistedInject constructor( state = state, modifier = modifier, onClosePressed = this::navigateUp, + onNewRoomClicked = this::onCreateNewRoom, ) } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt index 828f531211..2f3f3ded4a 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt @@ -17,75 +17,39 @@ package io.element.android.features.createroom.impl.root import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue +import io.element.android.features.selectusers.api.SelectUsersPresenter +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.api.SelectionMode import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.core.MatrixPatterns -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.ui.model.MatrixUser -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList import timber.log.Timber import javax.inject.Inject -class CreateRoomRootPresenter @Inject constructor() : Presenter { +class CreateRoomRootPresenter @Inject constructor( + private val presenterFactory: SelectUsersPresenter.Factory, +) : Presenter { + + private val presenter by lazy { + presenterFactory.create(SelectUsersPresenterArgs(SelectionMode.Single)) + } @Composable override fun present(): CreateRoomRootState { - var isSearchActive by rememberSaveable { mutableStateOf(false) } - var searchQuery by rememberSaveable { mutableStateOf("") } - val searchResults: MutableState> = remember { - mutableStateOf(persistentListOf()) - } + val selectUsersState = presenter.present() fun handleEvents(event: CreateRoomRootEvents) { when (event) { - is CreateRoomRootEvents.OnSearchActiveChanged -> isSearchActive = event.active - is CreateRoomRootEvents.UpdateSearchQuery -> searchQuery = event.query is CreateRoomRootEvents.StartDM -> handleStartDM(event.matrixUser) - CreateRoomRootEvents.CreateRoom -> Unit // Todo Handle create room action CreateRoomRootEvents.InvitePeople -> Unit // Todo Handle invite people action } } - LaunchedEffect(searchQuery) { - // Clear the search results before performing the search, manually add a fake result with the matrixId, if any - searchResults.value = if (MatrixPatterns.isUserId(searchQuery)) { - persistentListOf(MatrixUser(UserId(searchQuery))) - } else { - persistentListOf() - } - // Perform the search asynchronously - if (searchQuery.isNotEmpty()) { - searchResults.value = performSearch(searchQuery) - } - } - return CreateRoomRootState( + selectUsersState = selectUsersState, eventSink = ::handleEvents, - isSearchActive = isSearchActive, - searchQuery = searchQuery, - searchResults = searchResults.value, ) } - private fun performSearch(query: String): ImmutableList { - val isMatrixId = MatrixPatterns.isUserId(query) - val results = mutableListOf()// TODO trigger /search request - if (isMatrixId && results.none { it.id.value == query }) { - val getProfileResult: MatrixUser? = null // TODO trigger /profile request - val profile = getProfileResult ?: MatrixUser(UserId(query)) - results.add(0, profile) - } - return results.toImmutableList() - } - private fun handleStartDM(matrixUser: MatrixUser) { Timber.d("handleStartDM: $matrixUser") // Todo handle start DM action } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt index be9757f122..a57d6aaaf6 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt @@ -16,13 +16,9 @@ package io.element.android.features.createroom.impl.root -import io.element.android.libraries.matrix.ui.model.MatrixUser -import kotlinx.collections.immutable.ImmutableList +import io.element.android.features.selectusers.api.SelectUsersState -// Do not use default value, so no member get forgotten in the presenters. data class CreateRoomRootState( + val selectUsersState: SelectUsersState, val eventSink: (CreateRoomRootEvents) -> Unit, - val isSearchActive: Boolean, - val searchQuery: String, - val searchResults: ImmutableList, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt index 5f050ab1cc..678f02476c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt @@ -17,43 +17,16 @@ package io.element.android.features.createroom.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.ui.model.MatrixUser -import kotlinx.collections.immutable.persistentListOf +import io.element.android.features.selectusers.api.aSelectUsersState open class CreateRoomRootStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aCreateRoomRootState(), - aCreateRoomRootState().copy(isSearchActive = true), - aCreateRoomRootState().copy(isSearchActive = true, searchQuery = "someone"), - aCreateRoomRootState().copy( - isSearchActive = true, - searchQuery = "@someone:matrix.org", - searchResults = persistentListOf( - MatrixUser(id = UserId("@someone:matrix.org")), - MatrixUser(id = UserId("@someone:matrix.org"), username = "someone"), - MatrixUser( - id = UserId("@someone_with_a_very_long_matrix_identifier:a_very_long_domain.org"), - username = "hey, I am someone with a very long display name" - ), - MatrixUser(id = UserId("@someone_2:matrix.org"), username = "someone 2"), - MatrixUser(id = UserId("@someone_3:matrix.org"), username = "someone 3"), - MatrixUser(id = UserId("@someone_4:matrix.org"), username = "someone 4"), - MatrixUser(id = UserId("@someone_5:matrix.org"), username = "someone 5"), - MatrixUser(id = UserId("@someone_6:matrix.org"), username = "someone 6"), - MatrixUser(id = UserId("@someone_7:matrix.org"), username = "someone 7"), - MatrixUser(id = UserId("@someone_8:matrix.org"), username = "someone 8"), - MatrixUser(id = UserId("@someone_9:matrix.org"), username = "someone 9"), - MatrixUser(id = UserId("@someone_10:matrix.org"), username = "someone 10"), - ) - ), ) } fun aCreateRoomRootState() = CreateRoomRootState( eventSink = {}, - isSearchActive = false, - searchQuery = "", - searchResults = persistentListOf(), + selectUsersState = aSelectUsersState(), ) 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 bab42c6964..b0791c5331 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 @@ -24,38 +24,27 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close -import androidx.compose.material.icons.filled.Search import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SearchBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.features.selectusers.api.SelectUsersView import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Scaffold -import io.element.android.libraries.designsystem.theme.components.SearchBar import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.matrix.ui.components.MatrixUserRow -import io.element.android.libraries.matrix.ui.model.MatrixUser -import kotlinx.collections.immutable.ImmutableList import io.element.android.libraries.designsystem.R as DrawableR import io.element.android.libraries.ui.strings.R as StringR @@ -65,11 +54,12 @@ fun CreateRoomRootView( state: CreateRoomRootState, modifier: Modifier = Modifier, onClosePressed: () -> Unit = {}, + onNewRoomClicked: () -> Unit = {}, ) { Scaffold( modifier = modifier.fillMaxWidth(), topBar = { - if (!state.isSearchActive) { + if (!state.selectUsersState.isSearchActive) { CreateRoomRootViewTopBar(onClosePressed = onClosePressed) } } @@ -78,20 +68,15 @@ fun CreateRoomRootView( modifier = Modifier.padding(paddingValues), verticalArrangement = Arrangement.spacedBy(8.dp), ) { - CreateRoomSearchBar( + SelectUsersView( modifier = Modifier.fillMaxWidth(), - query = state.searchQuery, - placeHolderTitle = stringResource(StringR.string.search_for_someone), - results = state.searchResults, - active = state.isSearchActive, - onActiveChanged = { state.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(it)) }, - onTextChanged = { state.eventSink(CreateRoomRootEvents.UpdateSearchQuery(it)) }, - onResultSelected = { state.eventSink(CreateRoomRootEvents.StartDM(it)) } + state = state.selectUsersState, + onUserSelected = { state.eventSink.invoke(CreateRoomRootEvents.StartDM(it)) }, ) - if (!state.isSearchActive) { + if (!state.selectUsersState.isSearchActive) { CreateRoomActionButtonsList( - onNewRoomClicked = { state.eventSink(CreateRoomRootEvents.CreateRoom) }, + onNewRoomClicked = onNewRoomClicked, onInvitePeopleClicked = { state.eventSink(CreateRoomRootEvents.InvitePeople) }, ) } @@ -122,77 +107,6 @@ fun CreateRoomRootViewTopBar( ) } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun CreateRoomSearchBar( - query: String, - placeHolderTitle: String, - results: ImmutableList, - active: Boolean, - modifier: Modifier = Modifier, - onActiveChanged: (Boolean) -> Unit = {}, - onTextChanged: (String) -> Unit = {}, - onResultSelected: (MatrixUser) -> Unit = {}, -) { - val focusManager = LocalFocusManager.current - - if (!active) { - onTextChanged("") - focusManager.clearFocus() - } - - SearchBar( - query = query, - onQueryChange = onTextChanged, - onSearch = { focusManager.clearFocus() }, - active = active, - onActiveChange = onActiveChanged, - modifier = modifier - .padding(horizontal = if (!active) 16.dp else 0.dp), - placeholder = { - Text( - text = placeHolderTitle, - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) - ) - }, - leadingIcon = if (active) { - { BackButton(onClick = { onActiveChanged(false) }) } - } else { - null - }, - trailingIcon = when { - active && query.isNotEmpty() -> { - { - IconButton(onClick = { onTextChanged("") }) { - Icon(Icons.Default.Close, stringResource(StringR.string.a11y_clear)) - } - } - } - !active -> { - { - Icon( - imageVector = Icons.Default.Search, - contentDescription = stringResource(StringR.string.search), - modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) - ) - } - } - else -> null - }, - colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), - content = { - LazyColumn { - items(results) { - CreateRoomSearchResultItem( - matrixUser = it, - onClick = { onResultSelected(it) } - ) - } - } - }, - ) -} - @Composable fun CreateRoomActionButtonsList( modifier: Modifier = Modifier, @@ -213,20 +127,6 @@ fun CreateRoomActionButtonsList( } } -@Composable -fun CreateRoomSearchResultItem( - matrixUser: MatrixUser, - modifier: Modifier = Modifier, - onClick: () -> Unit = {}, -) { - MatrixUserRow( - modifier = modifier, - matrixUser = matrixUser, - avatarSize = AvatarSize.Custom(36.dp), - onClick = onClick, - ) -} - @Composable fun CreateRoomActionButton( @DrawableRes iconRes: Int, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt new file mode 100644 index 0000000000..d9f40c1dbf --- /dev/null +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeoplePresenterTests.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.features.createroom.impl.addpeople + +import app.cash.molecule.RecompositionClock +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.impl.DefaultSelectUsersPresenter +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test + +class AddPeoplePresenterTests { + + private lateinit var presenter: AddPeoplePresenter + + @Before + fun setup() { + val selectUsersFactory = object : DefaultSelectUsersPresenter.DefaultSelectUsersFactory { + override fun create(args: SelectUsersPresenterArgs) = DefaultSelectUsersPresenter(args) + } + presenter = AddPeoplePresenter(selectUsersFactory) + } + + @Test + fun `present - initial state`() = runTest { + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState) + } + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt index c13d59f3a6..5dc9ec00e9 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -22,17 +22,29 @@ import app.cash.molecule.RecompositionClock import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.impl.DefaultSelectUsersPresenter import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.ui.model.MatrixUser import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.Before import org.junit.Test class CreateRoomRootPresenterTests { + private lateinit var presenter: CreateRoomRootPresenter + + @Before + fun setup() { + val selectUsersPresenter = object : DefaultSelectUsersPresenter.DefaultSelectUsersFactory { + override fun create(args: SelectUsersPresenterArgs) = DefaultSelectUsersPresenter(args) + } + presenter = CreateRoomRootPresenter(selectUsersPresenter) + } + @Test fun `present - initial state`() = runTest { - val presenter = CreateRoomRootPresenter() moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { @@ -43,45 +55,16 @@ class CreateRoomRootPresenterTests { @Test fun `present - trigger action buttons`() = runTest { - val presenter = CreateRoomRootPresenter() moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { val initialState = awaitItem() - initialState.eventSink(CreateRoomRootEvents.CreateRoom) // Not implemented yet initialState.eventSink(CreateRoomRootEvents.InvitePeople) // Not implemented yet } } - @Test - fun `present - update search query`() = runTest { - val presenter = CreateRoomRootPresenter() - moleculeFlow(RecompositionClock.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - - initialState.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(true)) - assertThat(awaitItem().isSearchActive).isTrue() - - val matrixIdQuery = "@name:matrix.org" - initialState.eventSink(CreateRoomRootEvents.UpdateSearchQuery(matrixIdQuery)) - assertThat(awaitItem().searchQuery).isEqualTo(matrixIdQuery) - assertThat(awaitItem().searchResults).containsExactly(MatrixUser(UserId(matrixIdQuery))) - - val notMatrixIdQuery = "name" - initialState.eventSink(CreateRoomRootEvents.UpdateSearchQuery(notMatrixIdQuery)) - assertThat(awaitItem().searchQuery).isEqualTo(notMatrixIdQuery) - assertThat(awaitItem().searchResults).isEmpty() - - initialState.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(false)) - assertThat(awaitItem().isSearchActive).isFalse() - } - } - @Test fun `present - trigger start DM action`() = runTest { - val presenter = CreateRoomRootPresenter() moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt index db284e0910..f2e688812c 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt @@ -69,7 +69,7 @@ class ChangeServerPresenter @Inject constructor(private val authenticationServic private fun CoroutineScope.submit(homeserverUrl: MutableState, changeServerAction: MutableState>) = launch { suspend { val domain = tryOrNull { URL(homeserverUrl.value) }?.host ?: homeserverUrl.value - authenticationService.setHomeserver(domain) + authenticationService.setHomeserver(domain).getOrThrow() homeserverUrl.value = domain }.execute(changeServerAction, errorMapping = ChangeServerError::from) } diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt index a47a7977b4..70ecae44b8 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt @@ -134,6 +134,7 @@ class ChangeServerPresenterTest { val initialState = awaitItem() authServer.givenChangeServerError(Throwable()) initialState.eventSink.invoke(ChangeServerEvents.Submit) + skipItems(1) // Loading val failureState = awaitItem() assertThat(failureState.submitEnabled).isFalse() assertThat(failureState.changeServerAction).isInstanceOf(Async.Failure::class.java) @@ -155,6 +156,8 @@ class ChangeServerPresenterTest { authenticationService.givenChangeServerError(A_THROWABLE) initialState.eventSink(ChangeServerEvents.Submit) + skipItems(1) // Loading + // Check an error was returned val submittedState = awaitItem() assertThat(submittedState.changeServerAction).isInstanceOf(Async.Failure::class.java) 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 88209c31f6..810cb74715 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 @@ -135,7 +135,7 @@ fun RoomListContent( if (state.presentVerificationSuccessfulMessage) { snackbarHostState.showSnackbar( message = verificationCompleteMessage, - duration = SnackbarDuration.Short + duration = SnackbarDuration.Short, ) state.eventSink(RoomListEvents.ClearSuccessfulVerificationMessage) } @@ -194,8 +194,6 @@ fun RoomListContent( SnackbarHost (snackbarHostState) { data -> Snackbar( snackbarData = data, - containerColor = MaterialTheme.colorScheme.surfaceVariant, - contentColor = MaterialTheme.colorScheme.primary ) } }, diff --git a/features/selectusers/api/build.gradle.kts b/features/selectusers/api/build.gradle.kts new file mode 100644 index 0000000000..d46ed2fbf1 --- /dev/null +++ b/features/selectusers/api/build.gradle.kts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("io.element.android-compose-library") +} + +android { + namespace = "io.element.android.features.selectusers.api" +} + +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.uiStrings) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.matrixui) +} diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersEvents.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersEvents.kt new file mode 100644 index 0000000000..e0ee6ddf68 --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersEvents.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +import io.element.android.libraries.matrix.ui.model.MatrixUser + +sealed interface SelectUsersEvents { + data class UpdateSearchQuery(val query: String) : SelectUsersEvents + data class AddToSelection(val matrixUser: MatrixUser) : SelectUsersEvents + data class RemoveFromSelection(val matrixUser: MatrixUser) : SelectUsersEvents + data class OnSearchActiveChanged(val active: Boolean) : SelectUsersEvents +} diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenter.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenter.kt new file mode 100644 index 0000000000..be85455d09 --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenter.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +import io.element.android.libraries.architecture.Presenter + +interface SelectUsersPresenter : Presenter { + + interface Factory { + fun create(args: SelectUsersPresenterArgs): SelectUsersPresenter + } +} diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenterArgs.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenterArgs.kt new file mode 100644 index 0000000000..543e73b77e --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersPresenterArgs.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +data class SelectUsersPresenterArgs( + val selectionMode: SelectionMode, +) + +enum class SelectionMode { + Single, + Multiple, +} diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersState.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersState.kt new file mode 100644 index 0000000000..2a1a2c48e3 --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersState.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +import androidx.compose.foundation.lazy.LazyListState +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList + +data class SelectUsersState( + val searchQuery: String, + val searchResults: ImmutableList, + val selectedUsers: ImmutableList, + val selectedUsersListState: LazyListState, + val isSearchActive: Boolean, + val selectionMode: SelectionMode, + val eventSink: (SelectUsersEvents) -> Unit, +) { + val isMultiSelectionEnabled = selectionMode == SelectionMode.Multiple +} diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersStateProvider.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersStateProvider.kt new file mode 100644 index 0000000000..93209a632c --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersStateProvider.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.persistentListOf + +open class SelectUsersStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aSelectUsersState(), + aSelectUsersState().copy( + isSearchActive = false, + selectedUsers = aListOfSelectedUsers(), + selectionMode = SelectionMode.Multiple, + ), + aSelectUsersState().copy(isSearchActive = true), + aSelectUsersState().copy(isSearchActive = true, searchQuery = "someone"), + aSelectUsersState().copy(isSearchActive = true, searchQuery = "someone", selectionMode = SelectionMode.Multiple), + aSelectUsersState().copy( + isSearchActive = true, + searchQuery = "@someone:matrix.org", + selectedUsers = aListOfSelectedUsers(), + searchResults = aListOfResults(), + ), + aSelectUsersState().copy( + isSearchActive = true, + searchQuery = "@someone:matrix.org", + selectionMode = SelectionMode.Multiple, + selectedUsers = aListOfSelectedUsers(), + searchResults = aListOfResults(), + ) + ) +} + +fun aSelectUsersState() = SelectUsersState( + isSearchActive = false, + searchQuery = "", + searchResults = persistentListOf(), + selectedUsers = persistentListOf(), + selectedUsersListState = LazyListState( + firstVisibleItemIndex = 0, + firstVisibleItemScrollOffset = 0, + ), + selectionMode = SelectionMode.Single, + eventSink = {} +) + +fun aListOfSelectedUsers() = persistentListOf( + MatrixUser(id = UserId("@someone:matrix.org")), + MatrixUser(id = UserId("@other:matrix.org"), username = "other"), +) + +fun aListOfResults() = persistentListOf( + MatrixUser(id = UserId("@someone:matrix.org")), + MatrixUser(id = UserId("@other:matrix.org"), username = "other"), + MatrixUser( + id = UserId("@someone_with_a_very_long_matrix_identifier:a_very_long_domain.org"), + username = "hey, I am someone with a very long display name" + ), + MatrixUser(id = UserId("@someone_2:matrix.org"), username = "someone 2"), + MatrixUser(id = UserId("@someone_3:matrix.org"), username = "someone 3"), + MatrixUser(id = UserId("@someone_4:matrix.org"), username = "someone 4"), + MatrixUser(id = UserId("@someone_5:matrix.org"), username = "someone 5"), + MatrixUser(id = UserId("@someone_6:matrix.org"), username = "someone 6"), + MatrixUser(id = UserId("@someone_7:matrix.org"), username = "someone 7"), + MatrixUser(id = UserId("@someone_8:matrix.org"), username = "someone 8"), + MatrixUser(id = UserId("@someone_9:matrix.org"), username = "someone 9"), + MatrixUser(id = UserId("@someone_10:matrix.org"), username = "someone 10"), +) diff --git a/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersView.kt b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersView.kt new file mode 100644 index 0000000000..60d7785b69 --- /dev/null +++ b/features/selectusers/api/src/main/kotlin/io/element/android/features/selectusers/api/SelectUsersView.kt @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.api + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SearchBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.IconButton +import io.element.android.libraries.designsystem.theme.components.SearchBar +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.matrix.ui.components.CheckableMatrixUserRow +import io.element.android.libraries.matrix.ui.components.MatrixUserRow +import io.element.android.libraries.matrix.ui.model.MatrixUser +import io.element.android.libraries.matrix.ui.model.getBestName +import kotlinx.collections.immutable.ImmutableList +import io.element.android.libraries.ui.strings.R as StringR + +@Composable +fun SelectUsersView( + state: SelectUsersState, + modifier: Modifier = Modifier, + onUserSelected: (MatrixUser) -> Unit = {}, + onUserDeselected: (MatrixUser) -> Unit = {}, +) { + Column( + modifier = modifier, + ) { + SearchUserBar( + modifier = Modifier.fillMaxWidth(), + query = state.searchQuery, + results = state.searchResults, + selectedUsers = state.selectedUsers, + selectedUsersListState = state.selectedUsersListState, + active = state.isSearchActive, + isMultiSelectionEnabled = state.isMultiSelectionEnabled, + onActiveChanged = { state.eventSink(SelectUsersEvents.OnSearchActiveChanged(it)) }, + onTextChanged = { state.eventSink(SelectUsersEvents.UpdateSearchQuery(it)) }, + onUserSelected = { + state.eventSink(SelectUsersEvents.AddToSelection(it)) + onUserSelected(it) + }, + onUserDeselected = { + state.eventSink(SelectUsersEvents.RemoveFromSelection(it)) + onUserDeselected(it) + }, + ) + + if (state.isMultiSelectionEnabled && !state.isSearchActive && state.selectedUsers.isNotEmpty()) { + SelectedUsersList( + listState = state.selectedUsersListState, + modifier = Modifier.padding(16.dp), + selectedUsers = state.selectedUsers, + onUserRemoved = { + state.eventSink(SelectUsersEvents.RemoveFromSelection(it)) + onUserDeselected(it) + }, + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchUserBar( + query: String, + results: ImmutableList, + selectedUsers: ImmutableList, + selectedUsersListState: LazyListState, + active: Boolean, + isMultiSelectionEnabled: Boolean, + modifier: Modifier = Modifier, + placeHolderTitle: String = stringResource(StringR.string.search_for_someone), + onActiveChanged: (Boolean) -> Unit = {}, + onTextChanged: (String) -> Unit = {}, + onUserSelected: (MatrixUser) -> Unit = {}, + onUserDeselected: (MatrixUser) -> Unit = {}, +) { + val focusManager = LocalFocusManager.current + + if (!active) { + onTextChanged("") + focusManager.clearFocus() + } + + SearchBar( + query = query, + onQueryChange = onTextChanged, + onSearch = { focusManager.clearFocus() }, + active = active, + onActiveChange = onActiveChanged, + modifier = modifier + .padding(horizontal = if (!active) 16.dp else 0.dp), + placeholder = { + Text( + text = placeHolderTitle, + modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + ) + }, + leadingIcon = if (active) { + { BackButton(onClick = { onActiveChanged(false) }) } + } else { + null + }, + trailingIcon = when { + active && query.isNotEmpty() -> { + { + IconButton(onClick = { onTextChanged("") }) { + Icon(Icons.Default.Close, stringResource(StringR.string.a11y_clear)) + } + } + } + !active -> { + { + Icon( + imageVector = Icons.Default.Search, + contentDescription = stringResource(StringR.string.search), + modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + ) + } + } + else -> null + }, + colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), + content = { + if (isMultiSelectionEnabled && active && selectedUsers.isNotEmpty()) { + SelectedUsersList( + listState = selectedUsersListState, + modifier = Modifier.padding(16.dp), + selectedUsers = selectedUsers, + onUserRemoved = onUserDeselected, + ) + } + + LazyColumn { + if (isMultiSelectionEnabled) { + items(results) { matrixUser -> + SearchMultipleUsersResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + isUserSelected = selectedUsers.find { it.id == matrixUser.id } != null, + onCheckedChange = { checked -> + if (checked) { + onUserSelected(matrixUser) + } else { + onUserDeselected(matrixUser) + } + } + ) + } + } else { + items(results) { matrixUser -> + SearchSingleUserResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + onClick = { onUserSelected(matrixUser) } + ) + } + } + } + }, + ) +} + +@Composable +fun SearchMultipleUsersResultItem( + matrixUser: MatrixUser, + isUserSelected: Boolean, + modifier: Modifier = Modifier, + onCheckedChange: (Boolean) -> Unit, +) { + CheckableMatrixUserRow( + checked = isUserSelected, + modifier = modifier, + matrixUser = matrixUser, + avatarSize = AvatarSize.Custom(36.dp), + onCheckedChange = onCheckedChange, + ) +} + +@Composable +fun SearchSingleUserResultItem( + matrixUser: MatrixUser, + modifier: Modifier = Modifier, + onClick: () -> Unit = {}, +) { + MatrixUserRow( + modifier = modifier.clickable(onClick = onClick), + matrixUser = matrixUser, + avatarSize = AvatarSize.Custom(36.dp), + ) +} + +@Composable +fun SelectedUsersList( + listState: LazyListState, + selectedUsers: ImmutableList, + modifier: Modifier = Modifier, + onUserRemoved: (MatrixUser) -> Unit = {}, +) { + LazyRow( + state = listState, + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(24.dp), + ) { + items(selectedUsers.toList()) { matrixUser -> + SelectedUser( + matrixUser = matrixUser, + onUserRemoved = onUserRemoved, + ) + } + } +} + +@Composable +fun SelectedUser( + matrixUser: MatrixUser, + modifier: Modifier = Modifier, + onUserRemoved: (MatrixUser) -> Unit, +) { + Box(modifier = modifier.width(56.dp)) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Avatar(matrixUser.avatarData.copy(size = AvatarSize.Custom(56.dp))) + Text( + text = matrixUser.getBestName(), + overflow = TextOverflow.Ellipsis, + maxLines = 1, + style = MaterialTheme.typography.bodyLarge, + ) + } + IconButton( + modifier = Modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.primary) + .size(20.dp) + .align(Alignment.TopEnd), + onClick = { onUserRemoved(matrixUser) } + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = stringResource(id = StringR.string.action_remove), + tint = MaterialTheme.colorScheme.onPrimary, + ) + } + } +} + +@Preview +@Composable +internal fun SelectUsersViewLightPreview(@PreviewParameter(SelectUsersStateProvider::class) state: SelectUsersState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +internal fun SelectUsersViewDarkPreview(@PreviewParameter(SelectUsersStateProvider::class) state: SelectUsersState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: SelectUsersState) { + SelectUsersView(state = state) +} diff --git a/features/selectusers/impl/build.gradle.kts b/features/selectusers/impl/build.gradle.kts new file mode 100644 index 0000000000..baac7d2d2f --- /dev/null +++ b/features/selectusers/impl/build.gradle.kts @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed +@Suppress("DSL_SCOPE_VIOLATION") +plugins { + id("io.element.android-compose-library") + alias(libs.plugins.anvil) + alias(libs.plugins.ksp) +} + +android { + namespace = "io.element.android.features.selectusers.impl" +} + +anvil { + generateDaggerFactories.set(true) +} + +dependencies { + implementation(projects.anvilannotations) + anvil(projects.anvilcodegen) + implementation(projects.libraries.core) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.matrixui) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.elementresources) + implementation(projects.libraries.testtags) + implementation(projects.libraries.uiStrings) + api(projects.features.selectusers.api) + ksp(libs.showkase.processor) + + testImplementation(libs.test.junit) + testImplementation(libs.coroutines.test) + testImplementation(libs.coroutines.core) + testImplementation(libs.molecule.runtime) + testImplementation(libs.test.truth) + testImplementation(libs.test.turbine) + testImplementation(libs.test.mockk) + testImplementation(projects.libraries.matrix.test) + + androidTestImplementation(libs.test.junitext) +} diff --git a/features/selectusers/impl/src/main/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenter.kt b/features/selectusers/impl/src/main/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenter.kt new file mode 100644 index 0000000000..e1135cd1a2 --- /dev/null +++ b/features/selectusers/impl/src/main/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenter.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.impl + +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import com.squareup.anvil.annotations.ContributesBinding +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import io.element.android.features.selectusers.api.SelectUsersEvents +import io.element.android.features.selectusers.api.SelectUsersPresenter +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.api.SelectUsersState +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.matrix.api.core.MatrixPatterns +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +class DefaultSelectUsersPresenter @AssistedInject constructor( + @Assisted val args: SelectUsersPresenterArgs, +) : SelectUsersPresenter { + + @AssistedFactory + @ContributesBinding(SessionScope::class) + interface DefaultSelectUsersFactory : SelectUsersPresenter.Factory { + override fun create(args: SelectUsersPresenterArgs): DefaultSelectUsersPresenter + } + + @Composable + override fun present(): SelectUsersState { + val localCoroutineScope = rememberCoroutineScope() + var isSearchActive by rememberSaveable { mutableStateOf(false) } + val selectedUsers: MutableState> = remember { + mutableStateOf(persistentListOf()) + } + val selectedUsersListState = rememberLazyListState() + var searchQuery by rememberSaveable { mutableStateOf("") } + val searchResults: MutableState> = remember { + mutableStateOf(persistentListOf()) + } + + fun handleEvents(event: SelectUsersEvents) { + when (event) { + is SelectUsersEvents.OnSearchActiveChanged -> isSearchActive = event.active + is SelectUsersEvents.UpdateSearchQuery -> searchQuery = event.query + is SelectUsersEvents.AddToSelection -> { + if (event.matrixUser !in selectedUsers.value) { + selectedUsers.value = selectedUsers.value.plus(event.matrixUser).toImmutableList() + } + localCoroutineScope.scrollToFirstSelectedUser(selectedUsersListState) + } + is SelectUsersEvents.RemoveFromSelection -> selectedUsers.value = selectedUsers.value.minus(event.matrixUser).toImmutableList() + } + } + + LaunchedEffect(searchQuery) { + // Clear the search results before performing the search, manually add a fake result with the matrixId, if any + searchResults.value = if (MatrixPatterns.isUserId(searchQuery)) { + persistentListOf(MatrixUser(UserId(searchQuery))) + } else { + persistentListOf() + } + // Perform the search asynchronously + if (searchQuery.isNotEmpty()) { + searchResults.value = performSearch(searchQuery) + } + } + + return SelectUsersState( + searchQuery = searchQuery, + searchResults = searchResults.value, + selectedUsers = selectedUsers.value.reversed().toImmutableList(), + selectedUsersListState = selectedUsersListState, + isSearchActive = isSearchActive, + selectionMode = args.selectionMode, + eventSink = ::handleEvents, + ) + } + + private fun performSearch(query: String): ImmutableList { + val isMatrixId = MatrixPatterns.isUserId(query) + val results = mutableListOf()// TODO trigger /search request + if (isMatrixId && results.none { it.id.value == query }) { + val getProfileResult: MatrixUser? = null // TODO trigger /profile request + val profile = getProfileResult ?: MatrixUser(UserId(query)) + results.add(0, profile) + } + return results.toImmutableList() + } + + private fun CoroutineScope.scrollToFirstSelectedUser(listState: LazyListState) = launch { + listState.scrollToItem(index = 0) + } +} diff --git a/features/selectusers/impl/src/test/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenterTests.kt b/features/selectusers/impl/src/test/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenterTests.kt new file mode 100644 index 0000000000..f5b0b43d0e --- /dev/null +++ b/features/selectusers/impl/src/test/kotlin/io/element/android/features/selectusers/impl/DefaultSelectUsersPresenterTests.kt @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.selectusers.impl + +import androidx.compose.foundation.lazy.LazyListState +import app.cash.molecule.RecompositionClock +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.features.selectusers.api.SelectUsersEvents +import io.element.android.features.selectusers.api.SelectUsersPresenterArgs +import io.element.android.features.selectusers.api.SelectionMode +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.components.aMatrixUser +import io.element.android.libraries.matrix.ui.model.MatrixUser +import io.mockk.coJustRun +import io.mockk.mockkConstructor +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultSelectUsersPresenterTests { + + @Test + fun `present - initial state for single selection`() = runTest { + val presenter = DefaultSelectUsersPresenter(SelectUsersPresenterArgs(SelectionMode.Single)) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.searchQuery).isEmpty() + assertThat(initialState.isMultiSelectionEnabled).isFalse() + assertThat(initialState.isSearchActive).isFalse() + assertThat(initialState.selectedUsers).isEmpty() + assertThat(initialState.searchResults).isEmpty() + } + } + + @Test + fun `present - initial state for multiple selection`() = runTest { + val presenter = DefaultSelectUsersPresenter(SelectUsersPresenterArgs(SelectionMode.Multiple)) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.searchQuery).isEmpty() + assertThat(initialState.isMultiSelectionEnabled).isTrue() + assertThat(initialState.isSearchActive).isFalse() + assertThat(initialState.selectedUsers).isEmpty() + assertThat(initialState.searchResults).isEmpty() + } + } + + @Test + fun `present - update search query`() = runTest { + val presenter = DefaultSelectUsersPresenter(SelectUsersPresenterArgs(SelectionMode.Single)) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + + initialState.eventSink(SelectUsersEvents.OnSearchActiveChanged(true)) + assertThat(awaitItem().isSearchActive).isTrue() + + val matrixIdQuery = "@name:matrix.org" + initialState.eventSink(SelectUsersEvents.UpdateSearchQuery(matrixIdQuery)) + assertThat(awaitItem().searchQuery).isEqualTo(matrixIdQuery) + assertThat(awaitItem().searchResults).containsExactly(MatrixUser(UserId(matrixIdQuery))) + + val notMatrixIdQuery = "name" + initialState.eventSink(SelectUsersEvents.UpdateSearchQuery(notMatrixIdQuery)) + assertThat(awaitItem().searchQuery).isEqualTo(notMatrixIdQuery) + assertThat(awaitItem().searchResults).isEmpty() + + initialState.eventSink(SelectUsersEvents.OnSearchActiveChanged(false)) + assertThat(awaitItem().isSearchActive).isFalse() + } + } + + @Test + fun `present - select a user`() = runTest { + mockkConstructor(LazyListState::class) + coJustRun { anyConstructed().scrollToItem(index = any()) } + + val presenter = DefaultSelectUsersPresenter(SelectUsersPresenterArgs(SelectionMode.Single)) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + + val userA = aMatrixUser("userA", "A") + val userB = aMatrixUser("userB", "B") + val userABis = aMatrixUser("userA", "A") + val userC = aMatrixUser("userC", "C") + + initialState.eventSink(SelectUsersEvents.AddToSelection(userA)) + assertThat(awaitItem().selectedUsers).containsExactly(userA) + + initialState.eventSink(SelectUsersEvents.AddToSelection(userB)) + // the last added user should be presented first + assertThat(awaitItem().selectedUsers).containsExactly(userB, userA) + + initialState.eventSink(SelectUsersEvents.AddToSelection(userABis)) + initialState.eventSink(SelectUsersEvents.AddToSelection(userC)) + // duplicated users should be ignored + assertThat(awaitItem().selectedUsers).containsExactly(userC, userB, userA) + + initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userB)) + assertThat(awaitItem().selectedUsers).containsExactly(userC, userA) + initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userA)) + assertThat(awaitItem().selectedUsers).containsExactly(userC) + initialState.eventSink(SelectUsersEvents.RemoveFromSelection(userC)) + assertThat(awaitItem().selectedUsers).isEmpty() + } + } +} diff --git a/features/verifysession/impl/build.gradle.kts b/features/verifysession/impl/build.gradle.kts index ab42b9e9e5..3aca74afed 100644 --- a/features/verifysession/impl/build.gradle.kts +++ b/features/verifysession/impl/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) + implementation(projects.libraries.statemachine) implementation(libs.accompanist.flowlayout) api(projects.features.verifysession.api) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt index 5f43372e55..aa1fe59c32 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt @@ -85,11 +85,14 @@ class VerifySelfSessionPresenter @Inject constructor( StateMachineState.RequestingVerification, StateMachineState.StartingSasVerification, StateMachineState.SasVerificationStarted, - StateMachineState.VerificationRequestAccepted, StateMachineState.Canceling -> { VerifySelfSessionState.VerificationStep.AwaitingOtherDeviceResponse } + StateMachineState.VerificationRequestAccepted -> { + VerifySelfSessionState.VerificationStep.Ready + } + StateMachineState.Canceled -> { VerifySelfSessionState.VerificationStep.Canceled } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt index 6f24e238cc..752cf942c1 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt @@ -32,6 +32,7 @@ data class VerifySelfSessionState( object Initial : VerificationStep object Canceled : VerificationStep object AwaitingOtherDeviceResponse : VerificationStep + object Ready : VerificationStep data class Verifying(val emojiList: List, val state: Async) : VerificationStep object Completed : VerificationStep } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt index 466db2aa99..8006a0b24f 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt @@ -17,7 +17,7 @@ @file:Suppress("WildcardImport") package io.element.android.features.verifysession.impl -import io.element.android.libraries.core.statemachine.createStateMachine +import io.element.android.libraries.statemachine.createStateMachine import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.VerificationEmoji import io.element.android.libraries.matrix.api.verification.VerificationFlowState @@ -81,6 +81,7 @@ class VerifySelfSessionStateMachine( // Observe the verification service state, translate it to state machine input events sessionVerificationService.verificationFlowState.onEach { verificationAttemptState -> when (verificationAttemptState) { + VerificationFlowState.Initial -> stateMachine.restart() VerificationFlowState.AcceptedVerificationRequest -> { stateMachine.process(Event.DidAcceptVerificationRequest) } @@ -102,7 +103,6 @@ class VerifySelfSessionStateMachine( VerificationFlowState.Failed -> { stateMachine.process(Event.DidFail) } - else -> Unit } }.launchIn(coroutineScope) } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt index 01b0e6bea6..54a59dee01 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt @@ -36,6 +36,9 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider R.drawable.ic_verification_devices FlowStep.Canceled -> R.drawable.ic_verification_warning FlowStep.AwaitingOtherDeviceResponse -> R.drawable.ic_verification_waiting - is FlowStep.Verifying, FlowStep.Completed -> R.drawable.ic_verification_emoji + FlowStep.Ready, is FlowStep.Verifying, FlowStep.Completed -> R.drawable.ic_verification_emoji } val titleTextId = when (verificationFlowStep) { FlowStep.Initial -> StringR.string.verification_title_initial FlowStep.Canceled -> StringR.string.verification_title_canceled FlowStep.AwaitingOtherDeviceResponse -> StringR.string.verification_title_waiting - is FlowStep.Verifying, FlowStep.Completed -> StringR.string.verification_title_verifying + FlowStep.Ready, is FlowStep.Verifying, FlowStep.Completed -> StringR.string.verification_title_verifying } val subtitleTextId = when (verificationFlowStep) { FlowStep.Initial -> StringR.string.verification_subtitle_initial FlowStep.Canceled -> StringR.string.verification_subtitle_canceled FlowStep.AwaitingOtherDeviceResponse -> StringR.string.verification_subtitle_waiting - is FlowStep.Verifying, FlowStep.Completed -> StringR.string.verification_subtitle_verifying + FlowStep.Ready, is FlowStep.Verifying, FlowStep.Completed -> StringR.string.verification_subtitle_verifying } + Column(modifier) { - Spacer(Modifier.height(68.dp)) + Spacer(Modifier.height(80.dp)) Box( modifier = Modifier .size(width = 70.dp, height = 70.dp) @@ -164,14 +167,14 @@ internal fun HeaderContent(verificationFlowStep: FlowStep, modifier: Modifier = @Composable internal fun Content(flowState: FlowStep, modifier: Modifier = Modifier) { - Column(modifier) { - Spacer(Modifier.height(56.dp)) + Column(modifier, verticalArrangement = Arrangement.Center) { + Spacer(Modifier.shrinkableHeight(min = 20.dp, max = 56.dp)) when (flowState) { - FlowStep.Initial, FlowStep.Canceled, FlowStep.Completed -> Unit + FlowStep.Initial, FlowStep.Ready, FlowStep.Canceled, FlowStep.Completed -> Unit FlowStep.AwaitingOtherDeviceResponse -> ContentWaiting() is FlowStep.Verifying -> ContentVerifying(flowState) } - Spacer(Modifier.height(56.dp)) + Spacer(Modifier.shrinkableHeight(min = 20.dp, max = 56.dp)) } } @@ -185,19 +188,22 @@ internal fun ContentWaiting(modifier: Modifier = Modifier) { @Composable internal fun ContentVerifying(verificationFlowStep: FlowStep.Verifying, modifier: Modifier = Modifier) { FlowRow( - modifier = modifier.fillMaxWidth(), + modifier = modifier + .fillMaxWidth() + .verticalScroll(rememberScrollState()), mainAxisAlignment = MainAxisAlignment.Center, mainAxisSpacing = 32.dp, crossAxisSpacing = 40.dp ) { for (entry in verificationFlowStep.emojiList) { - Column( - modifier = Modifier.defaultMinSize(minWidth = 56.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { Text(entry.code, fontSize = 34.sp) Spacer(modifier = Modifier.height(16.dp)) - Text(entry.name, style = ElementTextStyles.Regular.body) + Text( + entry.name, + style = ElementTextStyles.Regular.bodyMD, + color = MaterialTheme.colorScheme.secondary, + ) } } } @@ -219,6 +225,7 @@ internal fun BottomMenu(screenState: VerifySelfSessionState, goBack: () -> Unit) StringR.string.verification_positive_button_verifying_start } } + FlowStep.Ready -> StringR.string.verification_positive_button_ready else -> null } val negativeButtonTitle = when (verificationViewState) { @@ -231,6 +238,7 @@ internal fun BottomMenu(screenState: VerifySelfSessionState, goBack: () -> Unit) val positiveButtonEvent = when (verificationViewState) { FlowStep.Initial -> VerifySelfSessionViewEvents.RequestVerification + FlowStep.Ready -> VerifySelfSessionViewEvents.StartSasVerification is FlowStep.Verifying -> if (!isVerifying) VerifySelfSessionViewEvents.ConfirmVerification else null FlowStep.Canceled -> VerifySelfSessionViewEvents.Restart else -> null @@ -254,23 +262,25 @@ internal fun BottomMenu(screenState: VerifySelfSessionState, goBack: () -> Unit) modifier = Modifier.fillMaxWidth(), onClick = { positiveButtonEvent?.let { eventSink(it) } } ) { - positiveButtonTitle?.let { Text(stringResource(it)) } + positiveButtonTitle?.let { Text(stringResource(it), style = ElementTextStyles.Button) } } } else { Button( modifier = Modifier.fillMaxWidth(), onClick = { positiveButtonEvent?.let { eventSink(it) } } ) { - positiveButtonTitle?.let { Text(stringResource(it)) } + positiveButtonTitle?.let { Text(stringResource(it), style = ElementTextStyles.Button) } } } - Spacer(modifier = Modifier.height(16.dp)) - TextButton( - modifier = Modifier.fillMaxWidth(), - onClick = negativeButtonCallback, - enabled = negativeButtonEnabled, - ) { - negativeButtonTitle?.let { Text(stringResource(it)) } + if (negativeButtonTitle != null) { + Spacer(modifier = Modifier.height(16.dp)) + TextButton( + modifier = Modifier.fillMaxWidth(), + onClick = negativeButtonCallback, + enabled = negativeButtonEnabled, + ) { + Text(stringResource(negativeButtonTitle), fontSize = 16.sp) + } } Spacer(Modifier.height(40.dp)) } @@ -293,3 +303,15 @@ private fun ContentToPreview(state: VerifySelfSessionState) { goBack = {}, ) } + +private fun Modifier.shrinkableHeight( + min: Dp, + max: Dp, + minScreenHeight: Int = 720 +): Modifier = composed { + if (LocalConfiguration.current.screenHeightDp >= minScreenHeight) { + then(Modifier.height(max)) + } else { + then(Modifier.height(min)) + } +} diff --git a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt index 9a25a60323..6c79c1b762 100644 --- a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt +++ b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt @@ -56,6 +56,10 @@ class VerifySelfSessionPresenterTests { eventSink(VerifySelfSessionViewEvents.RequestVerification) // Await for other device response: assertThat(awaitItem().verificationFlowStep).isEqualTo(VerificationStep.AwaitingOtherDeviceResponse) + // Await for the state to be Ready + assertThat(awaitItem().verificationFlowStep).isEqualTo(VerificationStep.Ready) + // Await for other device response (again): + assertThat(awaitItem().verificationFlowStep).isEqualTo(VerificationStep.AwaitingOtherDeviceResponse) // Finally, ChallengeReceived: val verifyingState = awaitItem() assertThat(verifyingState.verificationFlowStep).isInstanceOf(VerificationStep.Verifying::class.java) @@ -233,8 +237,8 @@ class VerifySelfSessionPresenterTests { } private suspend fun ReceiveTurbine.awaitChallengeReceivedState(): VerifySelfSessionState { - // Skip 'waiting for response' state - skipItems(1) + // Skip 'waiting for response', 'ready' and 'starting verification' state + skipItems(3) // Received challenge return awaitItem() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b8ce5b521f..3bac7e6cca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ serialization_json = "1.5.0" showkase = "1.0.0-beta17" jsoup = "1.15.4" appyx = "1.0.5" -dependencycheck = "8.2.0" +dependencycheck = "8.2.1" stem = "2.3.0" sqldelight = "1.5.5" diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ElementTextStyles.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ElementTextStyles.kt index 9af09f83db..13820ed83b 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ElementTextStyles.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ElementTextStyles.kt @@ -26,7 +26,7 @@ import androidx.compose.ui.unit.sp object ElementTextStyles { val Button = TextStyle( - fontSize = 17.sp, + fontSize = 16.sp, fontWeight = FontWeight.Bold, lineHeight = 22.sp, fontStyle = FontStyle.Normal, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index 04834da309..50fbf6f232 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -38,6 +38,7 @@ class RustSessionVerificationService @Inject constructor() : SessionVerification _isReady.value = value != null // If status was 'Unknown', move it to either 'Verified' or 'NotVerified' if (value != null) { + value.setDelegate(this) updateVerificationStatus(value.isVerified()) } } @@ -52,7 +53,6 @@ class RustSessionVerificationService @Inject constructor() : SessionVerification override val sessionVerifiedStatus: StateFlow = _sessionVerifiedStatus.asStateFlow() override fun requestVerification() = tryOrFail { - verificationController?.setDelegate(this) verificationController?.requestVerification() } @@ -63,7 +63,6 @@ class RustSessionVerificationService @Inject constructor() : SessionVerification override fun declineVerification() = tryOrFail { verificationController?.declineVerification() } override fun startVerification() = tryOrFail { - verificationController?.setDelegate(this) verificationController?.startSasVerification() } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt index e44a1d18a8..886eac95ef 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeAuthenticationService.kt @@ -53,20 +53,13 @@ class FakeAuthenticationService : MatrixAuthenticationService { } override suspend fun setHomeserver(homeserver: String): Result { - changeServerError?.let { throw it } delay(100) - return Result.success(Unit) + return changeServerError?.let { Result.failure(it) } ?: Result.success(Unit) } override suspend fun login(username: String, password: String): Result { delay(100) - return loginError.let { loginError -> - if (loginError == null) { - Result.success(A_USER_ID) - } else { - Result.failure(loginError) - } - } + return loginError?.let { Result.failure(it) } ?: Result.success(A_USER_ID) } fun givenLoginError(throwable: Throwable?) { diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt new file mode 100644 index 0000000000..e61f02ebf6 --- /dev/null +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/CheckableMatrixUserRow.kt @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.ui.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Checkbox +import io.element.android.libraries.matrix.ui.model.MatrixUser + +@Composable +fun CheckableMatrixUserRow( + checked: Boolean, + matrixUser: MatrixUser, + modifier: Modifier = Modifier, + avatarSize: AvatarSize = matrixUser.avatarData.size, + onCheckedChange: (Boolean) -> Unit = {}, + enabled: Boolean = true, +) { + + Row( + modifier = modifier + .fillMaxWidth() + .clickable(role = Role.Checkbox) { onCheckedChange(!checked) }, + verticalAlignment = Alignment.CenterVertically, + ) { + MatrixUserRow( + modifier = Modifier.weight(1f), + matrixUser = matrixUser, + avatarSize = avatarSize, + ) + + Checkbox( + checked = checked, + onCheckedChange = onCheckedChange, + enabled = enabled, + ) + } +} + +@Preview +@Composable +internal fun CheckableMatrixUserRowLightPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = + ElementPreviewLight { ContentToPreview(matrixUser) } + +@Preview +@Composable +internal fun CheckableMatrixUserRowDarkPreview(@PreviewParameter(MatrixUserProvider::class) matrixUser: MatrixUser) = + ElementPreviewDark { ContentToPreview(matrixUser) } + +@Composable +private fun ContentToPreview(matrixUser: MatrixUser) { + Column { + CheckableMatrixUserRow(checked = true, matrixUser) + CheckableMatrixUserRow(checked = false, matrixUser) + } +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserProvider.kt index b19424c28b..b95b93d348 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserProvider.kt @@ -32,9 +32,9 @@ open class MatrixUserProvider : PreviewParameterProvider { ) } -fun aMatrixUser() = MatrixUser( - id = UserId("@id_of_alice:server.org"), - username = "Alice", +fun aMatrixUser(id: String = "@id_of_alice:server.org", userName: String = "Alice") = MatrixUser( + id = UserId(id), + username = userName, avatarData = anAvatarData() ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt index 035f2d3824..e4d2386c1c 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt @@ -16,7 +16,6 @@ package io.element.android.libraries.matrix.ui.components -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row @@ -46,11 +45,9 @@ fun MatrixUserRow( matrixUser: MatrixUser, modifier: Modifier = Modifier, avatarSize: AvatarSize = matrixUser.avatarData.size, - onClick: () -> Unit = {}, ) { Row( modifier = modifier - .clickable(onClick = onClick) .fillMaxWidth() .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp) .height(IntrinsicSize.Min), diff --git a/libraries/statemachine/build.gradle.kts b/libraries/statemachine/build.gradle.kts new file mode 100644 index 0000000000..31fe22b5f8 --- /dev/null +++ b/libraries/statemachine/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed +@Suppress("DSL_SCOPE_VIOLATION") +plugins { + id("java-library") + id("com.android.lint") + alias(libs.plugins.kotlin.jvm) +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + implementation(libs.coroutines.core) + + testImplementation(libs.test.junit) + testImplementation(libs.test.truth) +} diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/statemachine/StateMachine.kt b/libraries/statemachine/src/main/kotlin/io/element/android/libraries/statemachine/StateMachine.kt similarity index 98% rename from libraries/core/src/main/kotlin/io/element/android/libraries/core/statemachine/StateMachine.kt rename to libraries/statemachine/src/main/kotlin/io/element/android/libraries/statemachine/StateMachine.kt index 81451b7e74..c1620fd97e 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/statemachine/StateMachine.kt +++ b/libraries/statemachine/src/main/kotlin/io/element/android/libraries/statemachine/StateMachine.kt @@ -14,9 +14,8 @@ * limitations under the License. */ -package io.element.android.libraries.core.statemachine +package io.element.android.libraries.statemachine -import io.element.android.libraries.core.bool.orFalse import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -64,7 +63,7 @@ class StateMachine( private fun findMatchingRoute(event: E): StateMachineRoute? { val routesForEvent = routes.filter { it.eventType.isInstance(event) } - return (routesForEvent.firstOrNull { it.fromState?.isInstance(currentState).orFalse() } + return (routesForEvent.firstOrNull { it.fromState?.isInstance(currentState) == true } ?: routesForEvent.firstOrNull { it.fromState == null }) as? StateMachineRoute } diff --git a/libraries/core/src/test/kotlin/io/element/android/libraries/core/statemachine/StateMachineTests.kt b/libraries/statemachine/src/test/kotlin/io/element/android/libraries/statemachine/StateMachineTests.kt similarity index 99% rename from libraries/core/src/test/kotlin/io/element/android/libraries/core/statemachine/StateMachineTests.kt rename to libraries/statemachine/src/test/kotlin/io/element/android/libraries/statemachine/StateMachineTests.kt index 2120724d79..722ed1c004 100644 --- a/libraries/core/src/test/kotlin/io/element/android/libraries/core/statemachine/StateMachineTests.kt +++ b/libraries/statemachine/src/test/kotlin/io/element/android/libraries/statemachine/StateMachineTests.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.libraries.core.statemachine +package io.element.android.libraries.statemachine import com.google.common.truth.Truth.assertThat import org.junit.Assert.fail diff --git a/libraries/ui-strings/src/main/res/values/strings_eax.xml b/libraries/ui-strings/src/main/res/values/strings_eax.xml index 40563c0a3b..f0f4bc1be7 100644 --- a/libraries/ui-strings/src/main/res/values/strings_eax.xml +++ b/libraries/ui-strings/src/main/res/values/strings_eax.xml @@ -47,6 +47,7 @@ I am ready Retry verification + Start They match Waiting to match diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 4287d74101..314421ebc8 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -77,6 +77,7 @@ fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:dateformatter:impl")) implementation(project(":libraries:di")) implementation(project(":libraries:session-storage:impl")) + implementation(project(":libraries:statemachine")) } diff --git a/settings.gradle.kts b/settings.gradle.kts index fcdd72ba4a..2a491a2743 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -64,6 +64,7 @@ include(":libraries:encrypted-db") include(":libraries:session-storage:api") include(":libraries:session-storage:impl") include(":libraries:session-storage:impl-memory") +include(":libraries:statemachine") include(":services:analytics:api") include(":services:analytics:noop") @@ -72,7 +73,6 @@ include(":services:appnavstate:impl") include(":services:toolbox:api") include(":services:toolbox:impl") - fun includeProjects(directory: File, path: String) { directory.listFiles().orEmpty().forEach { file -> if (file.isDirectory) { diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..525854695a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55d774d5e61f8832162859ec9d22299efa5b0728cfc3308b13fb11df31c5130e +size 13790 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..ad94119f4c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:489aa166bf6d0f283da497b2752e457f81620959d404b5b9c3d96c7e18e8b953 +size 28100 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..85c608618b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a8969c9a82f41bbdbdfb013412d039f3be4fcf450a0dd55f3217c64d51c8489 +size 23495 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8ea3902e3a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ed229820d7cbd6b550e98116ec3bf688c52957e2a57ab296bfc5abd212345b1 +size 13784 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2074516963 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5f29443193cd21eeb721a4c86f9063466439dd5ad4830708e6fa587f95e5abd +size 27456 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2139d8a6c5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa79c54d2431dc0c8399a2bcb8e03d73749e9d54f505ac893e2376fded0e7dfe +size 22599 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index f13a65f8e2..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89ea65099fb4981bbeb24e49afb7400b0e8da79e3b783e198519ba1e970404a8 -size 8317 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png deleted file mode 100644 index 74a7f599cd..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a8ba207cf61c56b64c6855d04c8a30def0b3daf325adf57edd45b40981ed745 -size 7733 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png deleted file mode 100644 index 6d7f2c5d11..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b6703f2cba99aa60bdf3ecd380a46846f0e1b95a0b2718ed707348b6bc1713b1 -size 107508 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index eb23dcec96..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b8de2f28cf9918a7eddcc1311c34ba0376242a4708724b57689df000b7480524 -size 8197 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png deleted file mode 100644 index e2e4a33e67..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:687133e4729ea42382ac0b76af6ceaf8b20cbc65923412fb97b077d2475c70f7 -size 7514 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png deleted file mode 100644 index 2746320bc2..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d8e1ca8a115c3e46c7f24fe41dc6c9448ffecc65a05c6be1945b84f35d60a099 -size 103642 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 82668021bf..7aa5b9b9ba 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:47cc4075122ec2d0a1420e6c3c8765f6d28b521927034067a1ff1c877bf069fb -size 41214 +oid sha256:2fac7314c1dee8d4570922b984b0749f24ec8984e5e602892e2e4ed925d143b6 +size 41145 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 35f655bf97..bcae624eb5 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8d776746230925c8b35bb688ae51d3b3eca0ebee6beb9e716dabcbf4ae57361 -size 44563 +oid sha256:dff29249aabb7818151e55dbc9a1290bc09cf0e638e3ad2842791904b14368ca +size 44381 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 2a6549e79c..79436794bb 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c22ea865154e6c55cdc04acd4a96c3d0c87e1918c29604d72d37d1b29466ff46 -size 43877 +oid sha256:cb351458d7b5d70f2201f94e4466d5c7dbebb60bca164a986967d2d8006405da +size 43814 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 1f72911953..1bea49ba74 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:95a4f4ce5871c6c65dfd732bde01ea3a80c47fd97a83e306642b4b3821b23b65 -size 48597 +oid sha256:4363256d328a0ab2cc3966b42827c7a7319bee962710a0bac542f6494799ff71 +size 48526 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png index 82fee58c8c..6740abc12a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:74483873056b7dab096936e09e07249b84ffebe42619f20a829e9994b3b01ced -size 43840 +oid sha256:afa9ab67471727f4c396d1919fd1187ec28a40b8cb9b03c2b35400c5e32f4eda +size 43776 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png index c92686807a..17f36f745e 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c2700fd98861f5bb34ee48b24c7ddceea57971fbe9e9b0aa0d5b24edc90cc6a -size 43809 +oid sha256:6b724d1b93a04117fc3cc405920fd22530e004cc9ba9c39f88ca1a2a2a4229c4 +size 43743 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 18419dcadb..d97cb348db 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:86c3bc2523fd194a87d062bb122a8d84d412db419c0a9e2f0c6e51ccd338119a -size 37809 +oid sha256:28c23058fdd9b24a7079251a2ab1ae2f85dafe0c1d4f01be3ffeca91984e0805 +size 37703 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index c32968c45e..2520176bfd 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e0c3a87fb5fc5c3e8c31df3c071bf69b956e0dcfc35f5168452253c9e55b6fd -size 41535 +oid sha256:7779d6bf28eca6e72f9f1bcbd8b27881d0df0e594041269367a1f909e941cec9 +size 41368 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index f54f15bda4..087add28f7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f841b8076376b61a21c517e93627992a179ef1042566133367229c4926322279 -size 40436 +oid sha256:f51052d3ece86fe7e07cc686a539b81d23f795c64bf66bd093b9d0e8e9fc7192 +size 40335 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 23d5346e68..d5c33e67c3 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:091e106c67c1a503c98c36a0ed58a3cb08461840643cd2fe2ffc7e1f46ab3774 -size 47711 +oid sha256:27d2d879493e8ed1cc17dcdbb384504126fad63eb7e53a069f530457c35b94b3 +size 47609 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_4,NEXUS_5,1.0,en].png index 494a6e911d..488e1403d4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9496dd89a284f77cb01295a69dcf60ccdb566224560139d13f926e38a0bd226c -size 40436 +oid sha256:66e9060ad93cec0e1bf8e284ac959a713a8201a33ff931aeb61aaf29ab7d9640 +size 40335 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_5,NEXUS_5,1.0,en].png index af47554d4f..1cc8419b21 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.changeserver_null_DefaultGroup_ChangeServerViewLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be6c0687f8ac84831db038a9846aefba81c4a6af08237d89b2cdba5676f31142 -size 40419 +oid sha256:7f7ecb805b73afe15db56853fec77d92f28fc9f8080dc7f1b2bb9f99cc262719 +size 40317 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 634ed7c29b..cb0afeb4a0 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae82ef6285127f343f0ebee35cedc6f28132dde37c3303bbc33aa881c471c48c -size 32466 +oid sha256:a302148918d0f328b778c18de007538724879fd6f02babf667504ab049c02511 +size 32428 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 76a5a91ded..c14094b9a7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50627ff6140b8fb9eed181e812740a8bf8cf4cdb23cb4cf2fa9cd0b37fb880bc -size 35224 +oid sha256:1f67b9a62ee3628af0308b2a01883e09d4068c3c833a79c702a204942e2d2133 +size 35180 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png index c0db30a3a7..6ccda1c2a4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f94523e18a1eb82324325f0e3f8439d4d457d6d4883cd75a7fa6169f90bbdf4 -size 34229 +oid sha256:5c0b9edebd50e38f07ae3663f0f760674e8d9194d41077c70f93d8af46a78f0a +size 34139 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png index b36d41cb72..ff1bec8155 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe3431804d6d84b8588b0fb475bd824159abe4d0a7e35f0b7967b08477b07778 -size 33523 +oid sha256:3d552e8ad5f20ce2c08c3f7a4b970d552743b473acdc7a75d5414520a9db7421 +size 33475 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_4,NEXUS_5,1.0,en].png index 2bb1ba397f..358e8f4902 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d1c502239f0fd9cdd7fa286275d299b74597a2b0b5d0f081503a7db3cb39f52 -size 30277 +oid sha256:f548bca0c797f35eec698f28daf74d409210d076b91ef5e4db1501ed12cefb88 +size 30197 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_5,NEXUS_5,1.0,en].png index c0db30a3a7..6ccda1c2a4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f94523e18a1eb82324325f0e3f8439d4d457d6d4883cd75a7fa6169f90bbdf4 -size 34229 +oid sha256:5c0b9edebd50e38f07ae3663f0f760674e8d9194d41077c70f93d8af46a78f0a +size 34139 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png index 044c705c0b..6f26876131 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e3e148e980f5096934ec4742a3f8b05442f0019dbcf6435fcdc1875c326a6ae -size 31513 +oid sha256:7890d36ac726a7f0764319a72d0d3aca13d2c1d382616f0f1bdb5cc19926b168 +size 31455 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png index 8093da465f..215cf8e799 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21e9c4c0ecf5a348361ff30195195743192cb784c9d6d248ca83010e3646c39f -size 34212 +oid sha256:978d1b6b40b4109a1dd941574b08d39093c5a1eeaf3da18c24a677080bfb378a +size 34158 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png index 2ea09c2a08..6feb0ddb81 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04f73ec1830baa28808881f040f6bfc2b1ce0de1ca2d4b3e16a3b57513814a7f -size 33173 +oid sha256:785ad6fe0af439444b469ae0189ea627600fc0ba71f1dff1af470ce10ce81d4e +size 33105 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png index 98896a556b..ee94587696 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da84d9195ed0cac06efff562156ed8abc161a6dbd3272727c1cb787b83c62558 -size 32253 +oid sha256:ea3ff5e912f88f12bdbf65ce027a5bde87472bbafd0146ebf609f36027dda31a +size 32194 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_4,NEXUS_5,1.0,en].png index f7e513c68a..36c73ddbf0 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea2dce0fde5ff6563f283e643edadd5c95c29a4084c8f1d3902ec3c759cccea7 -size 30070 +oid sha256:09ff583713751988f4ccdb465b1b53d88b788d6b275512afde08ce4e5d3e4346 +size 30022 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_5,NEXUS_5,1.0,en].png index 2ea09c2a08..6feb0ddb81 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.root_null_DefaultGroup_LoginRootScreenLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04f73ec1830baa28808881f040f6bfc2b1ce0de1ca2d4b3e16a3b57513814a7f -size 33173 +oid sha256:785ad6fe0af439444b469ae0189ea627600fc0ba71f1dff1af470ce10ce81d4e +size 33105 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderDark_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderDark_0_null,NEXUS_5,1.0,en].png index 21f1bae12a..4264691620 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderDark_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderDark_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:474c799a08ccba7c8b4d9ba3d120b103d0e8bb9654bb4da576d4eee579e5d517 -size 28222 +oid sha256:5a06f563a1b006bd007c123a03486bb26ec93029e65c3a3c71a6ead01f747ddf +size 28139 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderLight_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderLight_0_null,NEXUS_5,1.0,en].png index 902862a63b..603ef7da0e 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderLight_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_PreviewRequestVerificationHeaderLight_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c705a9c97a0bc5a2987cef4db6fd9b79de1cf1f5405035c6371615fb72fc5f36 -size 27715 +oid sha256:8796755d5118f24c6d3632cf1b0cee2b1d2b3743620d24e65f57ceb27bc7a48e +size 27627 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 9a5b02d262..1fa7abc24e 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f653439749b16d9f683b63984855e2dad576e5d567eeed792f28e9484b12b67f -size 60599 +oid sha256:d51bcda4d9b04e7569aff45bcf599c779bbcad52de8c4700036abe4084128707 +size 60513 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 6ce2a97c89..0f011129a8 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomlist.impl_null_DefaultGroup_RoomListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d88db44fb66340043d83e256b1eb7655e66af5e11daa55bd1336b4ff6e57883d -size 59472 +oid sha256:69f1674c3e4dc3afc194c0a7bd1064ae37722cc132ead43bf02a1183cc1e2ece +size 59392 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index f7019f8b86..e9dfd4557b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07e72c29b3a928eaa86ec7c97cb680cf2eaacebf6512390eb9dda47bdc2a9c7e -size 29249 +oid sha256:b964fd69198367cd702d8ff09d75a79a66bbee22798cbaa381fabde9bab5fda0 +size 29646 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index aaf919abe1..1a79f10ed9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76b4ac8395ac876c4ff979bd92279b9735fae581987326c6ab929e8578335c5a -size 26657 +oid sha256:0162d20f04bfdd0fdd6eb6e00b18b5774f83f07a5c7a72d20d0f51988b05dc66 +size 26899 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index fd7959efbe..08ee7998e9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca4957bb6995efbf398bf211da38cafb6b2c1693167f9c940d6a31343bfcf127 -size 61454 +oid sha256:2f38843f426b531b5ec9febae2d2d442bfdf29c9fe8dda52bf27a53c8226a9d2 +size 60873 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 3e2a239d90..8431a01af7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7590a2604bb93de8a416e7e45b6c410c27fd83481cfb08f3f41e820d22fc5582 -size 62046 +oid sha256:c97fd08e6cf3df11f285c1e94d869e492b168be339dcbe2a3a841395b9549f12 +size 61452 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png index 22c9cd5705..4a3156cc09 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4861b0c969a8af115ad2638b54f5893e813633a61bebb8bccafa01cfda320ea9 -size 31937 +oid sha256:15b907fd9177e6e0b7b3e0371f42899099913d40b439da2addb18afb912dc69d +size 32864 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..f514a4c394 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:949bd00ccc555ef5e3218d37e418a45c303d7eab6af652f5d48d380b1a8e19ca +size 27302 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 32ff815fd8..b95a350e79 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ee6ee256e59932e2d6aa29c393ec30499da06c6759ed33e8298838618bbfb9f -size 28465 +oid sha256:97a422ee19417033b00cbc829f4755992be068b42d2889597ad0bba68dd18fe4 +size 29172 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 34b728f940..24cdb7b67a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:586954a4fae4405f47a02140ec0ea9c89b2f6becc1b9b852d0a8fa28e10bf089 -size 25959 +oid sha256:dd0c4a8485e00b917265b6061ee901a9f131883069621d55f3f5c9a42673046c +size 26182 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index fffb4c902d..7d5bcedbe3 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:083f2c5ba49a4579015c38ffa2e0c2dd4ed04f389faa4c90cf6afa6438e08ca7 -size 59174 +oid sha256:079be728240bef9778a26f623ff19e28756921b5e30ce34d3fe360eade47789e +size 59359 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 25d0a3d145..e3d2cf70a9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed5e914779a3dcfbed0af73cace4e9141259932a892ae57ee902aec4860bd879 -size 59628 +oid sha256:76aa30f5693cdc8e654dbb5927db092da91815e83222d0f540782e1d7945542f +size 59761 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_4,NEXUS_5,1.0,en].png index c08447d227..283819318a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c8534d5464f3ee2551df199d18af1589f6c1e0c66292756be1e1af9deee1b17 -size 31580 +oid sha256:e782e332af35ea98bc19a2154d7d8a24aeb68636f1cba768b36599010aad1722 +size 32486 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_5,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..dfc1cb59b3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.verifysession.impl_null_DefaultGroup_VerifySelfSessionViewLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:06a31254e0ff962006c35a9c54ca2e6136ce51bfb267bbf61f9a941dd3720fe4 +size 26828 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..02c9c42691 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1ec43b9fa3fd3906bc1d55145320a91a08f9222928ac55f7c264a7b5fa27ad8 +size 24303 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3f174ff793 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59478d13aa6150c097167e3b2d984f5f82d46a74326b7e69c74b9785cae9bd56 +size 23382 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..1e8d75d01a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5c6225b33876b3a3878f0bfc230c081e798f6e0aae53286b93eb1ac76c17b35 +size 23116 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7ca77c5fff --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_CheckableMatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d13731b708adb16d1524d66a13daea13071cfd5ba646d21ef80fd682c28f6a4 +size 22450