From 6641afdd17daf2aa62067458de8c1f7125ad9b60 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 9 May 2023 18:08:45 +0200 Subject: [PATCH 01/33] WIP pick avatar image --- features/createroom/impl/build.gradle.kts | 1 + .../impl/configureroom/ConfigureRoomEvents.kt | 2 - .../configureroom/ConfigureRoomPresenter.kt | 32 ++++- .../impl/configureroom/ConfigureRoomState.kt | 2 + .../ConfigureRoomStateProvider.kt | 9 +- .../impl/configureroom/ConfigureRoomView.kt | 33 ++++- .../impl/configureroom/avatar/AvatarAction.kt | 34 +++++ .../avatar/AvatarActionListEvents.kt | 21 +++ .../avatar/AvatarActionListState.kt | 26 ++++ .../avatar/AvatarActionListStateProvider.kt | 30 +++++ .../avatar/AvatarActionListView.kt | 121 ++++++++++++++++++ .../libraries/mediapickers/api/PickerType.kt | 7 + .../mediapickers/impl/PickerProviderImpl.kt | 14 ++ 13 files changed, 323 insertions(+), 9 deletions(-) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarAction.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListEvents.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListState.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 0515bbbfc7..6a9b0c28ff 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -48,6 +48,7 @@ dependencies { implementation(projects.features.userlist.api) api(projects.features.createroom.api) implementation(libs.coil.compose) // FIXME temp + implementation(projects.libraries.mediapickers) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt index f2c454656c..58cdae613c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt @@ -16,14 +16,12 @@ package io.element.android.features.createroom.impl.configureroom -import android.net.Uri import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface ConfigureRoomEvents { data class RoomNameChanged(val name: String) : ConfigureRoomEvents data class TopicChanged(val topic: String) : ConfigureRoomEvents - data class AvatarUriChanged(val uri: Uri?) : ConfigureRoomEvents data class RoomPrivacyChanged(val privacy: RoomPrivacy?) : ConfigureRoomEvents data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index fa61c7f643..e38b9c06a7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -26,6 +26,9 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListEvents +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute @@ -34,6 +37,8 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility +import io.element.android.libraries.mediapickers.PickerProvider +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject @@ -41,6 +46,7 @@ import javax.inject.Inject class ConfigureRoomPresenter @Inject constructor( private val dataStore: CreateRoomDataStore, private val matrixClient: MatrixClient, + private val mediaPickerProvider: PickerProvider, ) : Presenter { @Composable @@ -52,6 +58,13 @@ class ConfigureRoomPresenter @Inject constructor( } } + val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(onResult = { uri -> + if (uri != null) dataStore.setAvatarUrl(uri.toString()) + }) + val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(onResult = { uri -> + if (uri != null) dataStore.setAvatarUrl(uri.toString()) + }) + val localCoroutineScope = rememberCoroutineScope() val createRoomAction: MutableState> = remember { mutableStateOf(Async.Uninitialized) } @@ -62,7 +75,6 @@ class ConfigureRoomPresenter @Inject constructor( fun handleEvents(event: ConfigureRoomEvents) { when (event) { - is ConfigureRoomEvents.AvatarUriChanged -> dataStore.setAvatarUrl(event.uri?.toString()) is ConfigureRoomEvents.RoomNameChanged -> dataStore.setRoomName(event.name) is ConfigureRoomEvents.TopicChanged -> dataStore.setTopic(event.topic) is ConfigureRoomEvents.RoomPrivacyChanged -> dataStore.setPrivacy(event.privacy) @@ -72,9 +84,27 @@ class ConfigureRoomPresenter @Inject constructor( } } + fun handleAvatarEvents(event: AvatarActionListEvents) { + when (event) { + is AvatarActionListEvents.HandleAction -> when (event.action) { + AvatarAction.ChoosePhoto -> galleryImagePicker.launch() + AvatarAction.TakePhoto -> cameraPhotoPicker.launch() + } + } + } + + val avatarActionListState = AvatarActionListState( + actions = persistentListOf( + AvatarAction.ChoosePhoto, + AvatarAction.TakePhoto, + ), + eventSink = ::handleAvatarEvents, + ) + return ConfigureRoomState( config = createRoomConfig.value, isCreateButtonEnabled = isCreateButtonEnabled, + avatarActionListState = avatarActionListState, createRoomAction = createRoomAction.value, eventSink = ::handleEvents, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index b5f804fcde..1b01c3a642 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -17,12 +17,14 @@ package io.element.android.features.createroom.impl.configureroom import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId data class ConfigureRoomState( val config: CreateRoomConfig, val isCreateButtonEnabled: Boolean, + val avatarActionListState: AvatarActionListState, val createRoomAction: Async, val eventSink: (ConfigureRoomEvents) -> Unit ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 67e0b91bba..3383b13b2a 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -18,8 +18,11 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.features.userlist.api.aListOfSelectedUsers import io.element.android.libraries.architecture.Async +import kotlinx.collections.immutable.persistentListOf open class ConfigureRoomStateProvider : PreviewParameterProvider { override val values: Sequence @@ -40,6 +43,10 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Unit = {}, onRoomCreated: (RoomId) -> Unit = {}, ) { + val coroutineScope = rememberCoroutineScope() + val itemActionsBottomSheetState = rememberModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + ) + if (state.createRoomAction is Async.Success) { LaunchedEffect(state.createRoomAction) { onRoomCreated(state.createRoomAction.state) } } - val context = LocalContext.current + fun onAvatarClicked() { + coroutineScope.launch { + itemActionsBottomSheetState.show() + } + } + Scaffold( modifier = modifier, topBar = { @@ -92,7 +107,7 @@ fun ConfigureRoomView( modifier = Modifier.padding(horizontal = 16.dp), avatarUri = state.config.avatarUrl?.toUri(), roomName = state.config.roomName.orEmpty(), - onAvatarClick = { Toast.makeText(context, "not implemented yet", Toast.LENGTH_SHORT).show() }, + onAvatarClick = ::onAvatarClicked, onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) }, ) RoomTopic( @@ -114,10 +129,17 @@ fun ConfigureRoomView( } } + AvatarActionListView( + state = state.avatarActionListState, + modalBottomSheetState = itemActionsBottomSheetState, + onActionSelected = { state.avatarActionListState.eventSink(AvatarActionListEvents.HandleAction(it)) } + ) + when (state.createRoomAction) { is Async.Loading -> { ProgressDialog(text = stringResource(StringR.string.common_creating_room)) } + is Async.Failure -> { RetryDialog( content = stringResource(R.string.screen_create_room_error_creating_room), @@ -125,6 +147,7 @@ fun ConfigureRoomView( onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) }, ) } + else -> Unit } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarAction.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarAction.kt new file mode 100644 index 0000000000..029732f173 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarAction.kt @@ -0,0 +1,34 @@ +/* + * 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.configureroom.avatar + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.PhotoCamera +import androidx.compose.material.icons.filled.PhotoLibrary +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.vector.ImageVector +import io.element.android.libraries.ui.strings.R + +@Immutable +sealed class AvatarAction( + @StringRes val titleResId: Int, + val icon: ImageVector, +) { + object TakePhoto : AvatarAction(titleResId = R.string.action_take_photo, icon = Icons.Default.PhotoCamera) + object ChoosePhoto : AvatarAction(titleResId = R.string.action_choose_photo, icon = Icons.Default.PhotoLibrary) +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListEvents.kt new file mode 100644 index 0000000000..2e81ea6500 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListEvents.kt @@ -0,0 +1,21 @@ +/* + * 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.configureroom.avatar + +sealed interface AvatarActionListEvents { + data class HandleAction(val action: AvatarAction) : AvatarActionListEvents +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListState.kt new file mode 100644 index 0000000000..35a34b20a9 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListState.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.createroom.impl.configureroom.avatar + +import androidx.compose.runtime.Immutable +import kotlinx.collections.immutable.ImmutableList + +@Immutable +data class AvatarActionListState( + val actions: ImmutableList, + val eventSink: (AvatarActionListEvents) -> Unit, +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt new file mode 100644 index 0000000000..6cb6ce1361 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt @@ -0,0 +1,30 @@ +/* + * 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.configureroom.avatar + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import kotlinx.collections.immutable.persistentListOf + +open class ActionListStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf(anActionListState()) +} + +fun anActionListState() = AvatarActionListState( + actions = persistentListOf(AvatarAction.TakePhoto, AvatarAction.ChoosePhoto), + eventSink = {} +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt new file mode 100644 index 0000000000..515faee0f5 --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt @@ -0,0 +1,121 @@ +/* + * 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(ExperimentalMaterialApi::class, ExperimentalMaterialApi::class) + +package io.element.android.features.createroom.impl.configureroom.avatar + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ListItem +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +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.ModalBottomSheetLayout +import kotlinx.coroutines.launch + +@Composable +fun AvatarActionListView( + state: AvatarActionListState, + modalBottomSheetState: ModalBottomSheetState, + modifier: Modifier = Modifier, + onActionSelected: (action: AvatarAction) -> Unit = {}, +) { + val coroutineScope = rememberCoroutineScope() + fun onItemActionClicked(itemAction: AvatarAction) { + onActionSelected(itemAction) + coroutineScope.launch { + modalBottomSheetState.hide() + } + } + + ModalBottomSheetLayout( + modifier = modifier, + sheetState = modalBottomSheetState, + sheetContent = { + SheetContent( + state = state, + onActionClicked = ::onItemActionClicked, + modifier = Modifier + .navigationBarsPadding() + .imePadding() + ) + } + ) +} + +@Composable +private fun SheetContent( + state: AvatarActionListState, + modifier: Modifier = Modifier, + onActionClicked: (AvatarAction) -> Unit = { }, +) { + val actions = state.actions + LazyColumn( + modifier = modifier.fillMaxWidth() + ) { + items( + items = actions, + ) { action -> + ListItem( + modifier = Modifier.clickable { onActionClicked(action) }, + text = { + Text(text = stringResource(action.titleResId)) + }, + icon = { + Icon( + imageVector = action.icon, + contentDescription = stringResource(action.titleResId), + ) + } + ) + } + } +} + +@Preview +@Composable +fun SheetContentLightPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +fun SheetContentDarkPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: AvatarActionListState) { + AvatarActionListView( + state = state, + modalBottomSheetState = ModalBottomSheetState( + initialValue = ModalBottomSheetValue.Expanded + ), + ) +} diff --git a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt index ad89175ddf..7c86009d34 100644 --- a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt +++ b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerType.kt @@ -26,6 +26,13 @@ sealed interface PickerType { fun getContract(): ActivityResultContract fun getDefaultRequest(): Input + object Image : PickerType { + override fun getContract() = ActivityResultContracts.PickVisualMedia() + override fun getDefaultRequest(): PickVisualMediaRequest { + return PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly) + } + } + object ImageAndVideo : PickerType { override fun getContract() = ActivityResultContracts.PickVisualMedia() override fun getDefaultRequest(): PickVisualMediaRequest { diff --git a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt index b7e9bad420..11f172fd4c 100644 --- a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt +++ b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt @@ -59,6 +59,20 @@ class PickerProviderImpl constructor(private val isInTest: Boolean) : PickerProv } } + /** + * Remembers and returns a [PickerLauncher] for a gallery picture. + * [onResult] will be called with either the selected file's [Uri] or `null` if nothing was selected. + */ + @Composable + fun registerGalleryImagePicker(onResult: (Uri?) -> Unit): PickerLauncher { + // Tests and UI preview can't handle Contexts, so we might as well disable the whole picker + return if (LocalInspectionMode.current || isInTest) { + NoOpPickerLauncher { onResult(null) } + } else { + rememberPickerLauncher(type = PickerType.Image) { uri -> onResult(uri) } + } + } + /** * Remembers and returns a [PickerLauncher] for a gallery item, either a picture or a video. * [onResult] will be called with either the selected file's [Uri] or `null` if nothing was selected. From 554ce9f6500a4ec4b7576636217570ae716a9b82 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 9 May 2023 22:08:47 +0200 Subject: [PATCH 02/33] Rework and add remove button --- .../impl/configureroom/ConfigureRoomEvents.kt | 2 + .../configureroom/ConfigureRoomPresenter.kt | 44 ++++++++++--------- .../impl/configureroom/ConfigureRoomState.kt | 5 ++- .../ConfigureRoomStateProvider.kt | 7 +-- .../impl/configureroom/ConfigureRoomView.kt | 5 +-- .../impl/configureroom/avatar/AvatarAction.kt | 11 +++-- .../avatar/AvatarActionListEvents.kt | 21 --------- .../avatar/AvatarActionListState.kt | 26 ----------- .../avatar/AvatarActionListStateProvider.kt | 30 ------------- .../avatar/AvatarActionListView.kt | 29 +++++++----- 10 files changed, 55 insertions(+), 125 deletions(-) delete mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListEvents.kt delete mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListState.kt delete mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt index 58cdae613c..52389d97fb 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt @@ -17,6 +17,7 @@ package io.element.android.features.createroom.impl.configureroom import io.element.android.features.createroom.impl.CreateRoomConfig +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface ConfigureRoomEvents { @@ -25,5 +26,6 @@ sealed interface ConfigureRoomEvents { data class RoomPrivacyChanged(val privacy: RoomPrivacy?) : ConfigureRoomEvents data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents + data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents object CancelCreateRoom : ConfigureRoomEvents } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index e38b9c06a7..399bb2d763 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -27,8 +27,6 @@ import androidx.compose.runtime.rememberCoroutineScope import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListEvents -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute @@ -38,7 +36,7 @@ import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility import io.element.android.libraries.mediapickers.PickerProvider -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject @@ -65,6 +63,19 @@ class ConfigureRoomPresenter @Inject constructor( if (uri != null) dataStore.setAvatarUrl(uri.toString()) }) + val avatarActions by remember(createRoomConfig.value.avatarUrl) { + derivedStateOf { + mutableListOf( + AvatarAction.TakePhoto, + AvatarAction.ChoosePhoto, + ).apply { + if (createRoomConfig.value.avatarUrl != null) { + add(AvatarAction.Remove) + } + }.toImmutableList() + } + } + val localCoroutineScope = rememberCoroutineScope() val createRoomAction: MutableState> = remember { mutableStateOf(Async.Uninitialized) } @@ -80,31 +91,22 @@ class ConfigureRoomPresenter @Inject constructor( is ConfigureRoomEvents.RoomPrivacyChanged -> dataStore.setPrivacy(event.privacy) is ConfigureRoomEvents.RemoveFromSelection -> dataStore.selectedUserListDataStore.removeUserFromSelection(event.matrixUser) is ConfigureRoomEvents.CreateRoom -> createRoom(event.config) + is ConfigureRoomEvents.HandleAvatarAction -> { + when (event.action) { + AvatarAction.ChoosePhoto -> galleryImagePicker.launch() + AvatarAction.TakePhoto -> cameraPhotoPicker.launch() + AvatarAction.Remove -> dataStore.setAvatarUrl(null) + } + } + ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = Async.Uninitialized } } - fun handleAvatarEvents(event: AvatarActionListEvents) { - when (event) { - is AvatarActionListEvents.HandleAction -> when (event.action) { - AvatarAction.ChoosePhoto -> galleryImagePicker.launch() - AvatarAction.TakePhoto -> cameraPhotoPicker.launch() - } - } - } - - val avatarActionListState = AvatarActionListState( - actions = persistentListOf( - AvatarAction.ChoosePhoto, - AvatarAction.TakePhoto, - ), - eventSink = ::handleAvatarEvents, - ) - return ConfigureRoomState( config = createRoomConfig.value, isCreateButtonEnabled = isCreateButtonEnabled, - avatarActionListState = avatarActionListState, + avatarActions = avatarActions, createRoomAction = createRoomAction.value, eventSink = ::handleEvents, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index 1b01c3a642..0e0c465b52 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -17,14 +17,15 @@ package io.element.android.features.createroom.impl.configureroom import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId +import kotlinx.collections.immutable.ImmutableList data class ConfigureRoomState( val config: CreateRoomConfig, val isCreateButtonEnabled: Boolean, - val avatarActionListState: AvatarActionListState, + val avatarActions: ImmutableList, val createRoomAction: Async, val eventSink: (ConfigureRoomEvents) -> Unit ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 3383b13b2a..2dd4854f3a 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -18,8 +18,6 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListState import io.element.android.features.userlist.api.aListOfSelectedUsers import io.element.android.libraries.architecture.Async import kotlinx.collections.immutable.persistentListOf @@ -43,10 +41,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider, - val eventSink: (AvatarActionListEvents) -> Unit, -) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt deleted file mode 100644 index 6cb6ce1361..0000000000 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListStateProvider.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.configureroom.avatar - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import kotlinx.collections.immutable.persistentListOf - -open class ActionListStateProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf(anActionListState()) -} - -fun anActionListState() = AvatarActionListState( - actions = persistentListOf(AvatarAction.TakePhoto, AvatarAction.ChoosePhoto), - eventSink = {} -) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt index 515faee0f5..f68db3a4b7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt @@ -29,21 +29,23 @@ import androidx.compose.material.ListItem import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter 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.ModalBottomSheetLayout +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.launch @Composable fun AvatarActionListView( - state: AvatarActionListState, + actions: ImmutableList, modalBottomSheetState: ModalBottomSheetState, modifier: Modifier = Modifier, onActionSelected: (action: AvatarAction) -> Unit = {}, @@ -61,7 +63,7 @@ fun AvatarActionListView( sheetState = modalBottomSheetState, sheetContent = { SheetContent( - state = state, + actions = actions, onActionClicked = ::onItemActionClicked, modifier = Modifier .navigationBarsPadding() @@ -73,11 +75,10 @@ fun AvatarActionListView( @Composable private fun SheetContent( - state: AvatarActionListState, + actions: ImmutableList, modifier: Modifier = Modifier, onActionClicked: (AvatarAction) -> Unit = { }, ) { - val actions = state.actions LazyColumn( modifier = modifier.fillMaxWidth() ) { @@ -87,12 +88,16 @@ private fun SheetContent( ListItem( modifier = Modifier.clickable { onActionClicked(action) }, text = { - Text(text = stringResource(action.titleResId)) + Text( + text = stringResource(action.titleResId), + color = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, + ) }, icon = { Icon( imageVector = action.icon, contentDescription = stringResource(action.titleResId), + tint = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, ) } ) @@ -102,18 +107,18 @@ private fun SheetContent( @Preview @Composable -fun SheetContentLightPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = - ElementPreviewLight { ContentToPreview(state) } +fun SheetContentLightPreview() = + ElementPreviewLight { ContentToPreview() } @Preview @Composable -fun SheetContentDarkPreview(@PreviewParameter(ActionListStateProvider::class) state: AvatarActionListState) = - ElementPreviewDark { ContentToPreview(state) } +fun SheetContentDarkPreview() = + ElementPreviewDark { ContentToPreview() } @Composable -private fun ContentToPreview(state: AvatarActionListState) { +private fun ContentToPreview() { AvatarActionListView( - state = state, + actions = persistentListOf(AvatarAction.ChoosePhoto, AvatarAction.TakePhoto, AvatarAction.Remove), modalBottomSheetState = ModalBottomSheetState( initialValue = ModalBottomSheetValue.Expanded ), From a38fbb3419e7b02c8bd83ea2bc7c397c8fb59f97 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 10 May 2023 11:08:43 +0200 Subject: [PATCH 03/33] Delete cached avatar URI --- .../createroom/impl/CreateRoomConfig.kt | 3 ++- .../createroom/impl/CreateRoomDataStore.kt | 12 +++++++++-- .../configureroom/ConfigureRoomPresenter.kt | 21 ++++++++++--------- .../impl/configureroom/ConfigureRoomView.kt | 3 +-- .../ConfigureRoomPresenterTests.kt | 21 ++++++++++++++----- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt index 21662fdb64..23b6f3239d 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt @@ -16,6 +16,7 @@ package io.element.android.features.createroom.impl +import android.net.Uri import io.element.android.features.createroom.impl.configureroom.RoomPrivacy import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList @@ -24,7 +25,7 @@ import kotlinx.collections.immutable.persistentListOf data class CreateRoomConfig( val roomName: String? = null, val topic: String? = null, - val avatarUrl: String? = null, + val avatarUri: Uri? = null, val invites: ImmutableList = persistentListOf(), val privacy: RoomPrivacy? = null, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index e55fca755d..8d124d25de 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -16,6 +16,7 @@ package io.element.android.features.createroom.impl +import android.net.Uri import io.element.android.features.createroom.impl.configureroom.RoomPrivacy import io.element.android.features.createroom.impl.di.CreateRoomScope import io.element.android.features.userlist.api.UserListDataStore @@ -24,6 +25,7 @@ import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine +import java.io.File import javax.inject.Inject @SingleIn(CreateRoomScope::class) @@ -32,6 +34,11 @@ class CreateRoomDataStore @Inject constructor( ) { private val createRoomConfigFlow: MutableStateFlow = MutableStateFlow(CreateRoomConfig()) + private var cachedAvatarUri: Uri? = null + set(value) { + field?.path?.let { File(it) }?.delete() + field = value + } fun getCreateRoomConfig(): Flow = combine( selectedUserListDataStore.selectedUsers(), @@ -48,8 +55,9 @@ class CreateRoomDataStore @Inject constructor( createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(topic = topic?.takeIf { it.isNotEmpty() })) } - fun setAvatarUrl(avatarUrl: String?) { - createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(avatarUrl = avatarUrl)) + fun setAvatarUri(uri: Uri?, cached: Boolean = false) { + cachedAvatarUri = uri.takeIf { cached } + createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(avatarUri = uri)) } fun setPrivacy(privacy: RoomPrivacy?) { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 399bb2d763..941a03f84c 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -56,20 +56,21 @@ class ConfigureRoomPresenter @Inject constructor( } } - val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker(onResult = { uri -> - if (uri != null) dataStore.setAvatarUrl(uri.toString()) - }) - val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker(onResult = { uri -> - if (uri != null) dataStore.setAvatarUrl(uri.toString()) - }) + val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker( + onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) }, + deleteAfter = false, + ) + val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker( + onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri) } + ) - val avatarActions by remember(createRoomConfig.value.avatarUrl) { + val avatarActions by remember(createRoomConfig.value.avatarUri) { derivedStateOf { mutableListOf( AvatarAction.TakePhoto, AvatarAction.ChoosePhoto, ).apply { - if (createRoomConfig.value.avatarUrl != null) { + if (createRoomConfig.value.avatarUri != null) { add(AvatarAction.Remove) } }.toImmutableList() @@ -95,7 +96,7 @@ class ConfigureRoomPresenter @Inject constructor( when (event.action) { AvatarAction.ChoosePhoto -> galleryImagePicker.launch() AvatarAction.TakePhoto -> cameraPhotoPicker.launch() - AvatarAction.Remove -> dataStore.setAvatarUrl(null) + AvatarAction.Remove -> dataStore.setAvatarUri(uri = null) } } @@ -122,7 +123,7 @@ class ConfigureRoomPresenter @Inject constructor( visibility = if (config.privacy == RoomPrivacy.Public) RoomVisibility.PUBLIC else RoomVisibility.PRIVATE, preset = if (config.privacy == RoomPrivacy.Public) RoomPreset.PUBLIC_CHAT else RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, - avatar = config.avatarUrl, + avatar = config.avatarUri?.toString(), ) matrixClient.createRoom(params).getOrThrow() }.execute(createRoomAction) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 214ec89efb..b019e693e0 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -41,7 +41,6 @@ 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 androidx.core.net.toUri import io.element.android.features.createroom.impl.R import io.element.android.features.createroom.impl.components.Avatar import io.element.android.features.createroom.impl.components.LabelledTextField @@ -104,7 +103,7 @@ fun ConfigureRoomView( ) { RoomNameWithAvatar( modifier = Modifier.padding(horizontal = 16.dp), - avatarUri = state.config.avatarUrl?.toUri(), + avatarUri = state.config.avatarUri, roomName = state.config.roomName.orEmpty(), onAvatarClick = ::onAvatarClicked, onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) }, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 8be1e777a8..e1ed1f9c71 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -25,6 +25,7 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore +import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction import io.element.android.features.userlist.api.UserListDataStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId @@ -34,6 +35,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.ui.components.aMatrixUser +import io.element.android.libraries.mediapickers.PickerProvider import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -48,15 +50,18 @@ class ConfigureRoomPresenterTests { private lateinit var presenter: ConfigureRoomPresenter private lateinit var userListDataStore: UserListDataStore + private lateinit var createRoomDataStore: CreateRoomDataStore private lateinit var fakeMatrixClient: FakeMatrixClient @Before fun setup() { fakeMatrixClient = FakeMatrixClient() userListDataStore = UserListDataStore() + createRoomDataStore = CreateRoomDataStore(userListDataStore) presenter = ConfigureRoomPresenter( - dataStore = CreateRoomDataStore(userListDataStore), - matrixClient = fakeMatrixClient + dataStore = createRoomDataStore, + matrixClient = fakeMatrixClient, + mediaPickerProvider = PickerProvider(isInTest = true), ) } @@ -70,7 +75,7 @@ class ConfigureRoomPresenterTests { assertThat(initialState.config.roomName).isNull() assertThat(initialState.config.topic).isNull() assertThat(initialState.config.invites).isEmpty() - assertThat(initialState.config.avatarUrl).isNull() + assertThat(initialState.config.avatarUri).isNull() assertThat(initialState.config.privacy).isNull() } } @@ -139,10 +144,16 @@ class ConfigureRoomPresenterTests { assertThat(newState.config).isEqualTo(expectedConfig) // Room avatar + // Add val anUri = Uri.parse(AN_AVATAR_URL) - newState.eventSink(ConfigureRoomEvents.AvatarUriChanged(anUri)) + createRoomDataStore.setAvatarUri(anUri) newState = awaitItem() - expectedConfig = expectedConfig.copy(avatarUrl = anUri.toString()) + expectedConfig = expectedConfig.copy(avatarUri = anUri) + assertThat(newState.config).isEqualTo(expectedConfig) + // Remove + newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.Remove)) + newState = awaitItem() + expectedConfig = expectedConfig.copy(avatarUri = null) assertThat(newState.config).isEqualTo(expectedConfig) // Room privacy From c81e673111c64427c134639b6ed554a7c691dce6 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 10 May 2023 11:45:27 +0200 Subject: [PATCH 04/33] Fix tests after rebase --- features/createroom/impl/build.gradle.kts | 5 +++-- .../impl/configureroom/ConfigureRoomPresenter.kt | 3 +-- .../impl/configureroom/ConfigureRoomPresenterTests.kt | 9 ++++++--- .../android/libraries/mediapickers/api/PickerProvider.kt | 6 +++++- .../libraries/mediapickers/impl/PickerProviderImpl.kt | 2 +- .../libraries/mediapickers/test/FakePickerProvider.kt | 5 +++++ 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 6a9b0c28ff..08cd6fa0e8 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -46,9 +46,9 @@ dependencies { implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) implementation(projects.features.userlist.api) + implementation(projects.libraries.mediapickers.api) + implementation(libs.coil.compose) api(projects.features.createroom.api) - implementation(libs.coil.compose) // FIXME temp - implementation(projects.libraries.mediapickers) testImplementation(libs.test.junit) testImplementation(libs.coroutines.test) @@ -59,6 +59,7 @@ dependencies { testImplementation(projects.libraries.matrix.test) testImplementation(projects.features.userlist.impl) testImplementation(projects.features.userlist.test) + testImplementation(projects.libraries.mediapickers.test) androidTestImplementation(libs.test.junitext) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 941a03f84c..553ddf795b 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -35,7 +35,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility -import io.element.android.libraries.mediapickers.PickerProvider +import io.element.android.libraries.mediapickers.api.PickerProvider import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -58,7 +58,6 @@ class ConfigureRoomPresenter @Inject constructor( val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker( onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) }, - deleteAfter = false, ) val galleryImagePicker = mediaPickerProvider.registerGalleryImagePicker( onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri) } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index e1ed1f9c71..9eefdb8929 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -35,7 +35,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.ui.components.aMatrixUser -import io.element.android.libraries.mediapickers.PickerProvider +import io.element.android.libraries.mediapickers.test.FakePickerProvider import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -52,16 +52,18 @@ class ConfigureRoomPresenterTests { private lateinit var userListDataStore: UserListDataStore private lateinit var createRoomDataStore: CreateRoomDataStore private lateinit var fakeMatrixClient: FakeMatrixClient + private lateinit var fakePickerProvider: FakePickerProvider @Before fun setup() { fakeMatrixClient = FakeMatrixClient() userListDataStore = UserListDataStore() createRoomDataStore = CreateRoomDataStore(userListDataStore) + fakePickerProvider = FakePickerProvider() presenter = ConfigureRoomPresenter( dataStore = createRoomDataStore, matrixClient = fakeMatrixClient, - mediaPickerProvider = PickerProvider(isInTest = true), + mediaPickerProvider = fakePickerProvider, ) } @@ -146,7 +148,8 @@ class ConfigureRoomPresenterTests { // Room avatar // Add val anUri = Uri.parse(AN_AVATAR_URL) - createRoomDataStore.setAvatarUri(anUri) + fakePickerProvider.givenResult(anUri) + newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) newState = awaitItem() expectedConfig = expectedConfig.copy(avatarUri = anUri) assertThat(newState.config).isEqualTo(expectedConfig) diff --git a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerProvider.kt b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerProvider.kt index 9b0b248aa5..9becdc8aee 100644 --- a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerProvider.kt +++ b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerProvider.kt @@ -27,6 +27,11 @@ interface PickerProvider { onResult: (uri: Uri?, mimeType: String?) -> Unit ): PickerLauncher + @Composable + fun registerGalleryImagePicker( + onResult: (Uri?) -> Unit + ): PickerLauncher + @Composable fun registerFilePicker( mimeType: String, @@ -38,5 +43,4 @@ interface PickerProvider { @Composable fun registerCameraVideoPicker(onResult: (Uri?) -> Unit): PickerLauncher - } diff --git a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt index 11f172fd4c..201fd9b069 100644 --- a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt +++ b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/PickerProviderImpl.kt @@ -64,7 +64,7 @@ class PickerProviderImpl constructor(private val isInTest: Boolean) : PickerProv * [onResult] will be called with either the selected file's [Uri] or `null` if nothing was selected. */ @Composable - fun registerGalleryImagePicker(onResult: (Uri?) -> Unit): PickerLauncher { + override fun registerGalleryImagePicker(onResult: (Uri?) -> Unit): PickerLauncher { // Tests and UI preview can't handle Contexts, so we might as well disable the whole picker return if (LocalInspectionMode.current || isInTest) { NoOpPickerLauncher { onResult(null) } diff --git a/libraries/mediapickers/test/src/main/kotlin/io/element/android/libraries/mediapickers/test/FakePickerProvider.kt b/libraries/mediapickers/test/src/main/kotlin/io/element/android/libraries/mediapickers/test/FakePickerProvider.kt index 2a32387db4..e243a22138 100644 --- a/libraries/mediapickers/test/src/main/kotlin/io/element/android/libraries/mediapickers/test/FakePickerProvider.kt +++ b/libraries/mediapickers/test/src/main/kotlin/io/element/android/libraries/mediapickers/test/FakePickerProvider.kt @@ -33,6 +33,11 @@ class FakePickerProvider : PickerProvider { return NoOpPickerLauncher { onResult(result, mimeType) } } + @Composable + override fun registerGalleryImagePicker(onResult: (uri: Uri?) -> Unit): PickerLauncher { + return NoOpPickerLauncher { onResult(result) } + } + @Composable override fun registerFilePicker(mimeType: String, onResult: (Uri?) -> Unit): PickerLauncher { return NoOpPickerLauncher { onResult(result) } From 4fd3cb4c0e696ebcb53c1bb6249f5288114a3ef7 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 10 May 2023 15:13:56 +0200 Subject: [PATCH 05/33] Add todo and screenshot tests --- .../createroom/impl/configureroom/ConfigureRoomPresenter.kt | 1 + ...ultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png | 3 +++ ...ltGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 553ddf795b..3117be0657 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -114,6 +114,7 @@ class ConfigureRoomPresenter @Inject constructor( private fun CoroutineScope.createRoom(config: CreateRoomConfig, createRoomAction: MutableState>) = launch { suspend { + // TODO pre-process and upload the avatar before creating the room val params = CreateRoomParameters( name = config.roomName, topic = config.topic, diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..6b5ba60f36 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58efadd0883968cedfe5d74c4269edb3e7cadd1150fd0e9bd3425efcc717ec01 +size 14040 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..fdfcbb6e11 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cd407cdbaab5e3fe6b42ceb98c5b9b6a4012e3781ad7e754531c2ce04d9ee4e +size 14810 From 83463a731bcda5d1b65b05820400ace146d380dd Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 10 May 2023 15:29:46 +0200 Subject: [PATCH 06/33] changelogs --- changelog.d/122.feature | 1 + changelog.d/123.feature | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelog.d/122.feature create mode 100644 changelog.d/123.feature diff --git a/changelog.d/122.feature b/changelog.d/122.feature new file mode 100644 index 0000000000..c163e6d53b --- /dev/null +++ b/changelog.d/122.feature @@ -0,0 +1 @@ +[Create and join rooms] Select a media from the camera diff --git a/changelog.d/123.feature b/changelog.d/123.feature new file mode 100644 index 0000000000..f8b4d36f2d --- /dev/null +++ b/changelog.d/123.feature @@ -0,0 +1 @@ +[Create and join rooms] Select a media from the gallery From 4a444c24c4dff02ea5a1b377adf607e6f3a3fed8 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Wed, 10 May 2023 16:16:26 +0200 Subject: [PATCH 07/33] Add missing tests --- .../ConfigureRoomPresenterTests.kt | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 9eefdb8929..8710a28735 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -29,7 +29,6 @@ import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAc import io.element.android.features.userlist.api.UserListDataStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_THROWABLE @@ -45,6 +44,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner +private const val AN_URI_FROM_CAMERA = "content://uri_from_camera" +private const val AN_URI_FROM_GALLERY = "content://uri_from_gallery" + @RunWith(RobolectricTestRunner::class) class ConfigureRoomPresenterTests { @@ -146,12 +148,23 @@ class ConfigureRoomPresenterTests { assertThat(newState.config).isEqualTo(expectedConfig) // Room avatar - // Add - val anUri = Uri.parse(AN_AVATAR_URL) - fakePickerProvider.givenResult(anUri) + // Pick avatar + fakePickerProvider.givenResult(null) + newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) + newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + // From gallery + val uriFromGallery = Uri.parse(AN_URI_FROM_GALLERY) + fakePickerProvider.givenResult(uriFromGallery) newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) newState = awaitItem() - expectedConfig = expectedConfig.copy(avatarUri = anUri) + expectedConfig = expectedConfig.copy(avatarUri = uriFromGallery) + assertThat(newState.config).isEqualTo(expectedConfig) + // From camera + val uriFromCamera = Uri.parse(AN_URI_FROM_CAMERA) + fakePickerProvider.givenResult(uriFromCamera) + newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.TakePhoto)) + newState = awaitItem() + expectedConfig = expectedConfig.copy(avatarUri = uriFromCamera) assertThat(newState.config).isEqualTo(expectedConfig) // Remove newState.eventSink(ConfigureRoomEvents.HandleAvatarAction(AvatarAction.Remove)) From 5a0665a27aa19285f10b3e8725b8ec57394c4721 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 08:32:08 +0200 Subject: [PATCH 08/33] upload avatar within the room creation --- features/createroom/impl/build.gradle.kts | 1 + .../configureroom/ConfigureRoomPresenter.kt | 21 ++++++++++++++++--- .../libraries/matrix/api/MatrixClient.kt | 4 +++- .../libraries/matrix/impl/RustMatrixClient.kt | 21 ++++++++++++------- .../libraries/matrix/test/FakeMatrixClient.kt | 12 +++++++---- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 08cd6fa0e8..2f8894b402 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.features.userlist.api) implementation(projects.libraries.mediapickers.api) + implementation(projects.libraries.mediaupload.api) implementation(libs.coil.compose) api(projects.features.createroom.api) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 3117be0657..0d60158b8d 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -16,6 +16,7 @@ package io.element.android.features.createroom.impl.configureroom +import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState @@ -30,12 +31,16 @@ import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAc import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute +import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomVisibility import io.element.android.libraries.mediapickers.api.PickerProvider +import io.element.android.libraries.mediaupload.api.MediaPreProcessor +import io.element.android.libraries.mediaupload.api.MediaType +import io.element.android.libraries.mediaupload.api.MediaUploadInfo import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -45,6 +50,7 @@ class ConfigureRoomPresenter @Inject constructor( private val dataStore: CreateRoomDataStore, private val matrixClient: MatrixClient, private val mediaPickerProvider: PickerProvider, + private val mediaPreProcessor: MediaPreProcessor, ) : Presenter { @Composable @@ -112,9 +118,12 @@ class ConfigureRoomPresenter @Inject constructor( ) } - private fun CoroutineScope.createRoom(config: CreateRoomConfig, createRoomAction: MutableState>) = launch { + private fun CoroutineScope.createRoom( + config: CreateRoomConfig, + createRoomAction: MutableState> + ) = launch { + val mxc = config.avatarUri?.let { uploadAvatar(it) } suspend { - // TODO pre-process and upload the avatar before creating the room val params = CreateRoomParameters( name = config.roomName, topic = config.topic, @@ -123,9 +132,15 @@ class ConfigureRoomPresenter @Inject constructor( visibility = if (config.privacy == RoomPrivacy.Public) RoomVisibility.PUBLIC else RoomVisibility.PRIVATE, preset = if (config.privacy == RoomPrivacy.Public) RoomPreset.PUBLIC_CHAT else RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, - avatar = config.avatarUri?.toString(), + avatar = mxc, ) matrixClient.createRoom(params).getOrThrow() }.execute(createRoomAction) } + + private suspend fun uploadAvatar(avatarUri: Uri): String? { + val preprocessed = mediaPreProcessor.process(avatarUri, MediaType.Image).getOrThrow() as? MediaUploadInfo.Image + val byteArray = preprocessed?.file?.readBytes() + return byteArray?.let { matrixClient.uploadMedia(MimeTypes.Jpeg, it) }?.getOrThrow() + } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index dce2b15485..6d357ad912 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -42,6 +42,7 @@ interface MatrixClient : Closeable { suspend fun createRoom(createRoomParams: CreateRoomParameters): Result suspend fun createDM(userId: UserId): Result suspend fun getProfile(userId: UserId): Result + suspend fun searchUsers(searchTerm: String, limit: Long): Result fun startSync() fun stopSync() fun mediaResolver(): MediaResolver @@ -58,9 +59,10 @@ interface MatrixClient : Closeable { height: Long ): Result + suspend fun uploadMedia(mimeType: String, data: ByteArray): Result + fun onSlidingSyncUpdate() fun roomMembershipObserver(): RoomMembershipObserver - suspend fun searchUsers(searchTerm: String, limit: Long): Result } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index cce7ac90c7..0381869503 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -280,6 +280,13 @@ class RustMatrixClient constructor( } } + override suspend fun searchUsers(searchTerm: String, limit: Long): Result = + withContext(dispatchers.io) { + runCatching { + client.searchUsers(searchTerm, limit.toULong()).let(UserSearchResultMapper::map) + } + } + override fun mediaResolver(): MediaResolver = mediaResolver override fun sessionVerificationService(): SessionVerificationService = verificationService @@ -368,6 +375,13 @@ class RustMatrixClient constructor( } } + @OptIn(ExperimentalUnsignedTypes::class) + override suspend fun uploadMedia(mimeType: String, data: ByteArray): Result = withContext(dispatchers.io) { + runCatching { + client.uploadMedia(mimeType, data.toUByteArray().toList()) + } + } + override fun onSlidingSyncUpdate() { if (!verificationService.isReady.value) { try { @@ -380,13 +394,6 @@ class RustMatrixClient constructor( override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver - override suspend fun searchUsers(searchTerm: String, limit: Long): Result = - withContext(dispatchers.io) { - runCatching { - client.searchUsers(searchTerm, limit.toULong()).let(UserSearchResultMapper::map) - } - } - private fun File.deleteSessionDirectory(userID: String): Boolean { // Rust sanitises the user ID replacing invalid characters with an _ val sanitisedUserID = userID.replace(":", "_") diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 9d3ce40da1..51088115ed 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -91,6 +91,10 @@ class FakeMatrixClient( return getProfileResults[userId] ?: Result.failure(IllegalStateException("No profile found for $userId")) } + override suspend fun searchUsers(searchTerm: String, limit: Long): Result { + return searchUserResults[searchTerm] ?: Result.failure(IllegalStateException("No response defined for $searchTerm")) + } + override fun startSync() = Unit override fun stopSync() = Unit @@ -122,6 +126,10 @@ class FakeMatrixClient( return Result.success(ByteArray(0)) } + override suspend fun uploadMedia(mimeType: String, data: ByteArray): Result { + return Result.success("") + } + override fun sessionVerificationService(): SessionVerificationService = sessionVerificationService override fun pushersService(): PushersService = pushersService @@ -134,10 +142,6 @@ class FakeMatrixClient( return RoomMembershipObserver() } - override suspend fun searchUsers(searchTerm: String, limit: Long): Result { - return searchUserResults[searchTerm] ?: Result.failure(IllegalStateException("No response defined for $searchTerm")) - } - // Mocks fun givenLogoutError(failure: Throwable?) { From 1b1dbca96b0373153b8c5502ad1c1a4a8840800b Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 16:30:20 +0200 Subject: [PATCH 09/33] Clear cached image after room creation --- .../android/features/createroom/impl/CreateRoomDataStore.kt | 4 ++++ .../createroom/impl/configureroom/ConfigureRoomPresenter.kt | 1 + 2 files changed, 5 insertions(+) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index 8d124d25de..3c594a0f1e 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -63,4 +63,8 @@ class CreateRoomDataStore @Inject constructor( fun setPrivacy(privacy: RoomPrivacy?) { createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(privacy = privacy)) } + + fun clearCachedData() { + cachedAvatarUri = null + } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 0d60158b8d..8ce4a58e43 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -135,6 +135,7 @@ class ConfigureRoomPresenter @Inject constructor( avatar = mxc, ) matrixClient.createRoom(params).getOrThrow() + .also { dataStore.clearCachedData() } }.execute(createRoomAction) } From 14fba4c5597d34c5f9069ef1f7d99c312aaed30e Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 17:31:46 +0200 Subject: [PATCH 10/33] Reformat some code --- .../impl/configureroom/ConfigureRoomPresenter.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 8ce4a58e43..c0a43784f7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -71,14 +71,11 @@ class ConfigureRoomPresenter @Inject constructor( val avatarActions by remember(createRoomConfig.value.avatarUri) { derivedStateOf { - mutableListOf( + listOfNotNull( AvatarAction.TakePhoto, AvatarAction.ChoosePhoto, - ).apply { - if (createRoomConfig.value.avatarUri != null) { - add(AvatarAction.Remove) - } - }.toImmutableList() + AvatarAction.Remove.takeIf { createRoomConfig.value.avatarUri != null }, + ).toImmutableList() } } From 5e38049e75509c3dc3e2303888d75e673ed9f501 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 17:34:40 +0200 Subject: [PATCH 11/33] Fix test build --- features/createroom/impl/build.gradle.kts | 1 + .../impl/configureroom/ConfigureRoomPresenterTests.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 2f8894b402..4d3e8f191d 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -61,6 +61,7 @@ dependencies { testImplementation(projects.features.userlist.impl) testImplementation(projects.features.userlist.test) testImplementation(projects.libraries.mediapickers.test) + testImplementation(projects.libraries.mediaupload.test) androidTestImplementation(libs.test.junitext) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 8710a28735..71ea4062f1 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.mediapickers.test.FakePickerProvider +import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -66,6 +67,7 @@ class ConfigureRoomPresenterTests { dataStore = createRoomDataStore, matrixClient = fakeMatrixClient, mediaPickerProvider = fakePickerProvider, + mediaPreProcessor = FakeMediaPreProcessor(), ) } From deea472001d6816a4af568121c2653528c17bc84 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 23:03:47 +0200 Subject: [PATCH 12/33] Add more tests --- features/createroom/impl/build.gradle.kts | 1 + .../configureroom/ConfigureRoomPresenter.kt | 2 +- .../ConfigureRoomPresenterTests.kt | 44 ++++++++++++++++++- .../libraries/matrix/test/FakeMatrixClient.kt | 7 ++- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 4d3e8f191d..2026ac5214 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -52,6 +52,7 @@ dependencies { api(projects.features.createroom.api) testImplementation(libs.test.junit) + testImplementation(libs.test.mockk) testImplementation(libs.coroutines.test) testImplementation(libs.molecule.runtime) testImplementation(libs.test.truth) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index c0a43784f7..7659226bd9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -119,8 +119,8 @@ class ConfigureRoomPresenter @Inject constructor( config: CreateRoomConfig, createRoomAction: MutableState> ) = launch { - val mxc = config.avatarUri?.let { uploadAvatar(it) } suspend { + val mxc = config.avatarUri?.let { uploadAvatar(it) } val params = CreateRoomParameters( name = config.roomName, topic = config.topic, diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 71ea4062f1..eadad19d23 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -29,21 +29,29 @@ import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAc import io.element.android.features.userlist.api.UserListDataStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.mediapickers.test.FakePickerProvider +import io.element.android.libraries.mediaupload.api.MediaUploadInfo import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkAll import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner +import java.io.File private const val AN_URI_FROM_CAMERA = "content://uri_from_camera" private const val AN_URI_FROM_GALLERY = "content://uri_from_gallery" @@ -56,6 +64,7 @@ class ConfigureRoomPresenterTests { private lateinit var createRoomDataStore: CreateRoomDataStore private lateinit var fakeMatrixClient: FakeMatrixClient private lateinit var fakePickerProvider: FakePickerProvider + private lateinit var fakeMediaPreProcessor: FakeMediaPreProcessor @Before fun setup() { @@ -63,12 +72,21 @@ class ConfigureRoomPresenterTests { userListDataStore = UserListDataStore() createRoomDataStore = CreateRoomDataStore(userListDataStore) fakePickerProvider = FakePickerProvider() + fakeMediaPreProcessor = FakeMediaPreProcessor() presenter = ConfigureRoomPresenter( dataStore = createRoomDataStore, matrixClient = fakeMatrixClient, mediaPickerProvider = fakePickerProvider, - mediaPreProcessor = FakeMediaPreProcessor(), + mediaPreProcessor = fakeMediaPreProcessor, ) + + mockkStatic(File::readBytes) + every { any().readBytes() } returns byteArrayOf() + } + + @After + fun tearDown() { + unmockkAll() } @Test @@ -206,6 +224,30 @@ class ConfigureRoomPresenterTests { } } + @Test + fun `present - trigger create room with upload error and retry`() = runTest { + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + createRoomDataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY)) + fakeMediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), null))) + fakeMatrixClient.givenUploadMediaResult(Result.failure(A_THROWABLE)) + + val initialState = awaitItem() + initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) + val stateAfterCreateRoom = awaitItem() + assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(Async.Failure::class.java) + + fakeMatrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL)) + stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config)) + assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Uninitialized::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java) + assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Success::class.java) + + } + } + @Test fun `present - trigger retry and cancel actions`() = runTest { moleculeFlow(RecompositionClock.Immediate) { diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index 51088115ed..bdf76c8e05 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -59,6 +59,7 @@ class FakeMatrixClient( private val getRoomResults = mutableMapOf() private val searchUserResults = mutableMapOf>() private val getProfileResults = mutableMapOf>() + private var uploadMediaResult: Result = Result.success(AN_AVATAR_URL) override fun getRoom(roomId: RoomId): MatrixRoom? { return getRoomResults[roomId] @@ -127,7 +128,7 @@ class FakeMatrixClient( } override suspend fun uploadMedia(mimeType: String, data: ByteArray): Result { - return Result.success("") + return uploadMediaResult } override fun sessionVerificationService(): SessionVerificationService = sessionVerificationService @@ -183,4 +184,8 @@ class FakeMatrixClient( fun givenGetProfileResult(userId: UserId, result: Result) { getProfileResults[userId] = result } + + fun givenUploadMediaResult(result: Result) { + uploadMediaResult = result + } } From 37045641985e1a9fa7893724ae742c1a84a90a2f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 May 2023 12:28:31 +0200 Subject: [PATCH 13/33] Use default material3 version again and cleanup `@OptIn` annotations. Material3 is now 1.1.0 --- .../features/createroom/impl/addpeople/AddPeopleView.kt | 1 - .../createroom/impl/configureroom/ConfigureRoomView.kt | 3 +-- .../features/createroom/impl/root/CreateRoomRootView.kt | 1 - .../element/android/features/messages/impl/MessagesView.kt | 7 ++----- .../features/messages/impl/actionlist/ActionListView.kt | 5 +++-- .../messages/textcomposer/MessageComposerPresenterTest.kt | 3 --- .../android/features/onboarding/impl/OnBoardingScreen.kt | 3 --- .../roomdetails/impl/members/RoomMemberListView.kt | 1 - .../element/android/features/roomlist/impl/RoomListView.kt | 2 +- .../features/roomlist/impl/components/RoomListTopBar.kt | 2 -- gradle/libs.versions.toml | 2 +- .../components/preferences/PreferenceScreen.kt | 1 - .../theme/components/CenterAlignedTopAppBar.kt | 2 -- .../designsystem/theme/components/MediumTopAppBar.kt | 3 +-- .../theme/components/ModalBottomSheetLayout.kt | 3 +-- .../designsystem/theme/components/OutlinedTextField.kt | 2 +- .../libraries/designsystem/theme/components/Scaffold.kt | 2 -- .../libraries/designsystem/theme/components/SearchBar.kt | 3 +-- .../libraries/designsystem/theme/components/TopAppBar.kt | 2 -- .../android/libraries/matrix/impl/RustMatrixClient.kt | 3 --- .../matrix/impl/room/RustRoomSummaryDataSource.kt | 1 - plugins/src/main/kotlin/extension/DependencyHandleScope.kt | 4 +--- .../io/element/android/samples/minimal/MainActivity.kt | 3 --- .../android/tests/testutils/TestCoroutineDispatchers.kt | 3 --- 24 files changed, 13 insertions(+), 49 deletions(-) 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 index ebf3e9d508..3746fef4df 100644 --- 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 @@ -41,7 +41,6 @@ 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: UserListState, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index cb699f4599..3a59760ac8 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.features.createroom.impl.configureroom import android.net.Uri @@ -129,6 +127,7 @@ fun ConfigureRoomView( } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun ConfigureRoomToolbar( isNextActionEnabled: Boolean, 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 a80cf821fd..2de52b89f7 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt @@ -55,7 +55,6 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.designsystem.R as DrawableR import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) @Composable fun CreateRoomRootView( state: CreateRoomRootState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index cd70dc97cd..f98b19575a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -14,11 +14,6 @@ * limitations under the License. */ -@file:OptIn( - ExperimentalMaterial3Api::class, - ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class, -) - package io.element.android.features.messages.impl import androidx.activity.compose.BackHandler @@ -84,6 +79,7 @@ import io.element.android.libraries.designsystem.utils.LogCompositions import kotlinx.coroutines.launch import timber.log.Timber +@OptIn(ExperimentalMaterialApi::class) @Composable fun MessagesView( state: MessagesState, @@ -239,6 +235,7 @@ fun MessagesViewContent( } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MessagesViewTopBar( roomTitle: String?, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index c2becf71cf..9dcabd8af7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterialApi::class) - package io.element.android.features.messages.impl.actionlist import androidx.compose.foundation.clickable @@ -49,6 +47,7 @@ import io.element.android.libraries.designsystem.theme.components.ModalBottomShe import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterialApi::class) @Composable fun ActionListView( state: ActionListState, @@ -90,6 +89,7 @@ fun ActionListView( ) } +@OptIn(ExperimentalMaterialApi::class) @Composable private fun SheetContent( state: ActionListState, @@ -145,6 +145,7 @@ fun SheetContentLightPreview(@PreviewParameter(ActionListStateProvider::class) s fun SheetContentDarkPreview(@PreviewParameter(ActionListStateProvider::class) state: ActionListState) = ElementPreviewDark { ContentToPreview(state) } +@OptIn(ExperimentalMaterialApi::class) @Composable private fun ContentToPreview(state: ActionListState) { ActionListView( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index 0c0b46cbe2..9639759529 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - package io.element.android.features.messages.textcomposer import app.cash.molecule.RecompositionClock @@ -52,7 +50,6 @@ import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.libraries.textcomposer.MessageComposerMode import io.mockk.mockk import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt index 9fb54c7b45..8694865938 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt @@ -41,7 +41,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.HorizontalPager import com.google.accompanist.pager.HorizontalPagerIndicator import com.google.accompanist.pager.rememberPagerState @@ -53,9 +52,7 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalPagerApi::class) @Composable fun OnBoardingScreen( modifier: Modifier = Modifier, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 3a3ea3daa1..07facd77bd 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -54,7 +54,6 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser -@OptIn(ExperimentalMaterial3Api::class) @Composable fun RoomMemberListView( state: RoomMemberListState, 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 d41b8c28fc..acfc822658 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 @@ -116,7 +116,7 @@ fun RoomListView( } } -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun RoomListContent( state: RoomListState, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index 32bf30b082..f7fee35c75 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.features.roomlist.impl.components import androidx.activity.compose.BackHandler diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 40d89b7dd2..1138ad49d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ activity = "1.7.1" startup = "1.1.1" # Compose -compose_bom = "2023.04.01" +compose_bom = "2023.05.01" composecompiler = "1.4.7" # Coroutines diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt index 531c18ed6b..03ba290829 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt @@ -45,7 +45,6 @@ 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.TopAppBar -@OptIn(ExperimentalMaterial3Api::class) @Composable fun PreferenceView( title: String, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt index 5c2e741814..dab180e1c2 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.layout.RowScope diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt index 7f864bcb5c..d3cd2fee07 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/MediumTopAppBar.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.layout.RowScope @@ -57,6 +55,7 @@ fun MediumTopAppBar( internal fun MediumTopAppBarPreview() = ElementThemedPreview { ContentToPreview() } +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun ContentToPreview() { MediumTopAppBar(title = { Text(text = "Title") }) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ModalBottomSheetLayout.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ModalBottomSheetLayout.kt index 95d603b9dd..2f40a90615 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ModalBottomSheetLayout.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ModalBottomSheetLayout.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialApi::class) - package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.background @@ -107,6 +105,7 @@ internal fun ModalBottomSheetLayoutLightPreview() = internal fun ModalBottomSheetLayoutDarkPreview() = ElementPreviewDark { ContentToPreview() } +@OptIn(ExperimentalMaterialApi::class) @Composable private fun ContentToPreview() { ModalBottomSheetLayout( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt index 046dc5aa89..4bca15daca 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt @@ -49,7 +49,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.utils.allBooleans import io.element.android.libraries.designsystem.utils.asInt -@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun OutlinedTextField( value: String, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Scaffold.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Scaffold.kt index 99a69c0553..20e30e55b3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Scaffold.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Scaffold.kt @@ -18,7 +18,6 @@ package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FabPosition import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ScaffoldDefaults @@ -27,7 +26,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -@OptIn(ExperimentalMaterial3Api::class) @Composable fun Scaffold( modifier: Modifier = Modifier, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index ca25501446..9a037cb7bb 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.interaction.MutableInteractionSource @@ -77,6 +75,7 @@ fun SearchBar( @Composable internal fun DockedSearchBarPreview() = ElementThemedPreview { ContentToPreview() } +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun ContentToPreview() { SearchBar( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt index 602818f233..23848ef76d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TopAppBar.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.layout.RowScope diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 8709db67f0..7f1b78ebf7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -14,8 +14,6 @@ * limitations under the License. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - package io.element.android.libraries.matrix.impl import io.element.android.libraries.core.coroutine.CoroutineDispatchers @@ -46,7 +44,6 @@ import io.element.android.libraries.matrix.impl.verification.RustSessionVerifica import io.element.android.libraries.sessionstorage.api.SessionStore import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.filter diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt index c908651e75..2574e96d3b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt @@ -91,7 +91,6 @@ internal class RustRoomSummaryDataSource( coroutineScope.cancel() } - //@OptIn(FlowPreview::class) override fun roomSummaries(): StateFlow> { return roomSummaries } diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 885a830b96..962cb2c18d 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -43,9 +43,7 @@ fun DependencyHandlerScope.composeDependencies(libs: LibrariesForLibs) { androidTestImplementation(composeBom) implementation("androidx.compose.ui:ui") implementation("androidx.compose.material:material") - // Override BOM version, SearchBar is not available in the actual version - // do not use latest version because of clashes on androidx lifecycle dependency - implementation("androidx.compose.material3:material3:1.1.0-alpha04") + implementation("androidx.compose.material3:material3") implementation("androidx.compose.material:material-icons-extended") implementation("androidx.compose.ui:ui-tooling-preview") implementation(libs.androidx.activity.compose) diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index 1accae8464..ef776c613c 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -14,15 +14,12 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterial3Api::class) - package io.element.android.samples.minimal import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt index 1309a14cb1..e155eabd73 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - package io.element.android.tests.testutils import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScheduler import kotlinx.coroutines.test.TestDispatcher import kotlinx.coroutines.test.UnconfinedTestDispatcher From 22e86bdfc85a30dcfe2cc0b76ac40e4de8cfaab8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 May 2023 13:43:27 +0200 Subject: [PATCH 14/33] Fix more warning and replace deprecated code. Also use `TextField` from our components. --- .../features/roomlist/impl/search/RoomListSearch.kt | 11 ++++++----- .../theme/components/OutlinedTextField.kt | 8 +++----- .../designsystem/theme/components/TextField.kt | 6 ++---- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt index c2baca9a6b..021959c3aa 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt @@ -20,7 +20,6 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -30,7 +29,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable @@ -60,6 +58,7 @@ import io.element.android.libraries.designsystem.modifiers.applyIf 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.TextField import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.designsystem.utils.copy import io.element.android.libraries.matrix.api.core.RoomId @@ -128,12 +127,14 @@ internal fun RoomListSearchResultContent( .focusRequester(focusRequester), value = filter, onValueChange = { state.eventSink(RoomListEvents.UpdateFilter(it)) }, - colors = TextFieldDefaults.textFieldColors( - containerColor = Color.Transparent, + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, errorIndicatorColor = Color.Transparent, - disabledIndicatorColor = Color.Transparent ), trailingIcon = { if (filter.isNotEmpty()) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt index 4bca15daca..e0edeed050 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/OutlinedTextField.kt @@ -23,10 +23,9 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.TextFieldColors -import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.ExperimentalComposeUiApi @@ -49,7 +48,6 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.utils.allBooleans import io.element.android.libraries.designsystem.utils.asInt -@OptIn(ExperimentalMaterial3Api::class) @Composable fun OutlinedTextField( value: String, @@ -70,8 +68,8 @@ fun OutlinedTextField( singleLine: Boolean = false, maxLines: Int = Int.MAX_VALUE, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - shape: Shape = TextFieldDefaults.outlinedShape, - colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors() + shape: Shape = OutlinedTextFieldDefaults.shape, + colors: TextFieldColors = OutlinedTextFieldDefaults.colors() ) { androidx.compose.material3.OutlinedTextField( value = value, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt index a4f07a61fb..54fe50b8bf 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/TextField.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.TextFieldColors import androidx.compose.material3.TextFieldDefaults @@ -50,7 +49,6 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.utils.allBooleans import io.element.android.libraries.designsystem.utils.asInt -@OptIn(ExperimentalMaterial3Api::class) @Composable fun TextField( value: String, @@ -71,8 +69,8 @@ fun TextField( singleLine: Boolean = false, maxLines: Int = Int.MAX_VALUE, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - shape: Shape = TextFieldDefaults.filledShape, - colors: TextFieldColors = TextFieldDefaults.textFieldColors() + shape: Shape = TextFieldDefaults.shape, + colors: TextFieldColors = TextFieldDefaults.colors() ) { androidx.compose.material3.TextField( value = value, From 7e6aec173aec66013d407704d6cd518624f8e650 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 15 May 2023 13:50:21 +0200 Subject: [PATCH 15/33] Record screenshots. --- ...up_LabelledTextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...p_LabelledTextFieldLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ..._ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...p_ChangeServerViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._ChangeServerViewLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...up_LoginRootScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...up_LoginRootScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...up_LoginRootScreenDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...up_LoginRootScreenDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...p_LoginRootScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...p_LoginRootScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...p_LoginRootScreenLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...p_LoginRootScreenLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...roup_BugReportViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...roup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...roup_BugReportViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...oup_BugReportViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...oup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...oup_BugReportViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...s_OutlinedTextFieldsDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ields_OutlinedTextFieldsPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...TextFields_TextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...extFields_TextFieldLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- 36 files changed, 72 insertions(+), 72 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_LabelledTextFieldDarkPreview_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.createroom.impl.components_null_DefaultGroup_LabelledTextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png index 2b77d948e4..7daf56c098 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_LabelledTextFieldDarkPreview_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.createroom.impl.components_null_DefaultGroup_LabelledTextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f92e4287ae8db895d18452840a29240989597dea560640244b8188ee61e8c266 -size 30730 +oid sha256:57c89db393e87207bb9628244c435ee1541df327814d1ef7f296b80df8b8100c +size 30821 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_LabelledTextFieldLightPreview_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.createroom.impl.components_null_DefaultGroup_LabelledTextFieldLightPreview_0_null,NEXUS_5,1.0,en].png index c36b73a560..55b5f262b6 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_LabelledTextFieldLightPreview_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.createroom.impl.components_null_DefaultGroup_LabelledTextFieldLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c66806646645afee1654b50818c539863e60129eba7fcd608e9801bd34d0fe30 -size 30028 +oid sha256:89bcb8fd5b3f68fbfc1568cd5e7d5c7bbabd3ca05836fbb1d8e75fbc32379317 +size 30222 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 699b8973c1..160def016f 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:756d835de7820c96019995ab47d34c2663330c4ddc9ca124eac266ea9eeef0ab -size 64397 +oid sha256:24ad0b5edc27ddddca573b37f82579715d880793c0dc880248d2b572dd6d6a40 +size 64379 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 62e855dab1..c6a054a2d3 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df7631ad85dc6b3fbdabfc820b11b4e12a6128202e3faa2d105ba22793fe8c22 -size 103428 +oid sha256:b0c9d4eaaaf6a691f43d25e0855ee056b69fa090ad8c53b26732c8f2532e2138 +size 103384 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index a9a3720ece..26129e266a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a03aa11c787804adc5b2947359421b90e6abcdc7e840983a0276a6e02da59a2f -size 58526 +oid sha256:4023481d2a045d7e0d824db81b28ee47c4bcdc568d98537b3573d554e0b76e32 +size 58445 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 4045dae649..af4d0b2046 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c2731ea21ca5b001aadc29ecbb15a2b263b0c042b7344cb10149174ff88ec0a -size 96835 +oid sha256:8f953d0df467ad4cd1ae24291e9593945b945712506f093bdcae3da975f8ca91 +size 96800 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 7aa5b9b9ba..f2249286f5 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:2fac7314c1dee8d4570922b984b0749f24ec8984e5e602892e2e4ed925d143b6 -size 41145 +oid sha256:c9e1058bff99d3193f3e69d7635a0446f76295ecdd47a16b03e39690a7a4852f +size 41232 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 bcae624eb5..5332196c0c 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:dff29249aabb7818151e55dbc9a1290bc09cf0e638e3ad2842791904b14368ca -size 44381 +oid sha256:42e2f813350feb63441492b67653fd22edb311d4e7068d32a42a537c9e78e94f +size 44632 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 ba0061da9b..eae8a2c125 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:5450116320f6d75befbc784a31a8ad51c868936794e75e65bf24e6e1b69f1e23 -size 44421 +oid sha256:29c3ac70cd3f7a66d2be73996fe93825f850bb5a73312e9a0f2434a5e7003035 +size 44631 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 1bea49ba74..3f6519d314 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:4363256d328a0ab2cc3966b42827c7a7319bee962710a0bac542f6494799ff71 -size 48526 +oid sha256:494167e5d7f96bf16b16f5b7c53b304dacf4015b31ce0cd51bfe9e05802664df +size 48831 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 6740abc12a..7f8690a106 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:afa9ab67471727f4c396d1919fd1187ec28a40b8cb9b03c2b35400c5e32f4eda -size 43776 +oid sha256:746b009cb527d5ed6be3c8b30bac9465c42970bd9766e259aee2957aaeb96da7 +size 44007 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 17f36f745e..d6ebbc9165 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:6b724d1b93a04117fc3cc405920fd22530e004cc9ba9c39f88ca1a2a2a4229c4 -size 43743 +oid sha256:cc677f36b2262eabc091023be5a373aaa51d47237fc6777d9b4950f16efa6ea2 +size 43964 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 d97cb348db..0827e7d026 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:28c23058fdd9b24a7079251a2ab1ae2f85dafe0c1d4f01be3ffeca91984e0805 -size 37703 +oid sha256:ad6c6bdc7d4e4c405231c2c8944613ff151eb309e00821ac7eda107e853ed456 +size 37891 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 2520176bfd..e005e5910d 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:7779d6bf28eca6e72f9f1bcbd8b27881d0df0e594041269367a1f909e941cec9 -size 41368 +oid sha256:4cfd887060df1a1b7e12e3f47010e813678fec822595d90b19c51af99b42ab16 +size 41714 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 c48eee4f48..32208a1dde 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:af77d0276f38c78524201c49484548e29d1c99168e68e11874c49f0db0803df2 -size 41392 +oid sha256:ede9377d3fbceae95a10e02cb1c033f9bbd53901137ef88ca52fdd4041737c70 +size 41695 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 d5c33e67c3..72944ac735 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:27d2d879493e8ed1cc17dcdbb384504126fad63eb7e53a069f530457c35b94b3 -size 47609 +oid sha256:6a976609ec6f5ce83388242db7a43ff6c062f84011ce7d2263e5ff8d23c64a96 +size 47912 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 488e1403d4..2b16953c1c 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:66e9060ad93cec0e1bf8e284ac959a713a8201a33ff931aeb61aaf29ab7d9640 -size 40335 +oid sha256:e0a065c5a4c0af748524b0600e1b5233023cdff0eaae8a2039649323e8a19fe3 +size 40635 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 1cc8419b21..bb4d824ee8 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:7f7ecb805b73afe15db56853fec77d92f28fc9f8080dc7f1b2bb9f99cc262719 -size 40317 +oid sha256:dfa33ed990249e2d3e0097521bc51a3028bf51537736839a1301b54f99ad473b +size 40598 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 558ba024ca..1277ac6fa1 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:1501fd1372e15cd6f7693c4c854afcfd5ade3eb7a972f8cc76aea10de8416a20 -size 33382 +oid sha256:2bd0026073c5d0b7bb916bff9a034aca6393d005e299298f089f2f64d541f166 +size 33301 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 8341e4aa97..9919e584a6 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:762a1d43dc3bc9edfa47f081b8385614f7075b5cecdd3eb3cb6b4959baf6811c -size 33445 +oid sha256:cbf81d780ebde2c089327df2b1397a6b879b9729dacefa78304e0d16e0a4dc11 +size 33318 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 a0dbfd3863..a73c22ff1a 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:7559f64cb74c33ef441dd15d557607061b72ffcdd3dce7ec7f8a663d928fd681 -size 29585 +oid sha256:4777def89f3b8717c8f9cba0023d33d8e244b3041270d283da28b813fd8f52ad +size 29606 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 558ba024ca..1277ac6fa1 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:1501fd1372e15cd6f7693c4c854afcfd5ade3eb7a972f8cc76aea10de8416a20 -size 33382 +oid sha256:2bd0026073c5d0b7bb916bff9a034aca6393d005e299298f089f2f64d541f166 +size 33301 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 d713681419..0ec9d0351d 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:68ef9478a9bbf361a7ace91b9214c6fca449a23b2756f0e0692e634f25c98181 -size 32385 +oid sha256:3eaf06ed9c04ad6b2d9314e7305b4c090cc5d78e6621628eed5c16a9e2738c0d +size 32196 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 7140bc573f..bd0731900e 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:2fafe08ac635bf3f0e62753c832ead92de297f0826ec735efe1a1f90481cb421 -size 32417 +oid sha256:227596a612d3e87d4dd55ef43068875b1d50e334056b48e956e2708e5ed10645 +size 32220 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 a7010b4602..36576c6d42 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:7954d3f7064666b287ce6ab05fb6814f0e4570db2db6a44437291f0f90d8e87f -size 29062 +oid sha256:beeb25a16dd5662be9b633b761fae145b91515859f87bda2399323c38cc0e561 +size 28995 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 d713681419..0ec9d0351d 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:68ef9478a9bbf361a7ace91b9214c6fca449a23b2756f0e0692e634f25c98181 -size 32385 +oid sha256:3eaf06ed9c04ad6b2d9314e7305b4c090cc5d78e6621628eed5c16a9e2738c0d +size 32196 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index a1f391b1b1..cd34f90d2b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d38eddd629e8c46993e616ed5bab2689fa5f24bb023ae43afca1a41ef5381ea5 -size 59843 +oid sha256:847c42b0aec8b12708f2a429bbbe2a86ca2b149b5963dd16135f3b34d9d0c073 +size 60153 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 2968e30033..07451a0330 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9630d9b5e3d26b677eaa8c0496d76d73f95d28a487ef0ef845d3a89747d6a8cb -size 179668 +oid sha256:628f1f00dca9d15faabd8288a3c54b1b8581a380cf14edf364f0dee9ecc187d5 +size 180117 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 2d89c7181f..87ba73daee 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dcff656fe8f2b1233dc55e5e4bc80800aa8ed511bb328b178f8944c83d4199a2 -size 59284 +oid sha256:43974ffd4bec4c2d8e07a6d4798f00db1aec316a11633c6d2eb5c6608deb694d +size 59586 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 3dba4f5dbc..a86c5980de 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60ee09b1052414f00af4d80dcf63c738d7dc937f5d58a3a043840cacc3618317 -size 58781 +oid sha256:18597d5e200b7079201cfa169ac3f9266c089b7dadde691c750192d2e22c1dea +size 59035 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 3292b422ee..8146c241cb 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f8ad5f69dbcda0284f731a01851fc73dc93ba9b1fad9e778b23f0155bfc7107 -size 178346 +oid sha256:827bccb0fdd3106fb24a95d665b4da2cfc15de48e8f508ae809c9f75d6d1bbf0 +size 178915 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index 4470d22005..7aa17c8c18 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f01532b48a428362db2f963861a0ec5731ee3b1f13869a526facce3a85f82e8f -size 56677 +oid sha256:6bfb40e55460e4c11fdf0f020982b63e2b726a329902ceaa57522bafa328789d +size 56987 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsDarkPreview_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.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsDarkPreview_0_null,NEXUS_5,1.0,en].png index a1f82c98d8..a75c5f4399 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsDarkPreview_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.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02be8bb5887ed87aadc9758466cd4f3c622255fd32bccd347cedb70f509efa73 -size 49879 +oid sha256:916228ae8244eb2dd1602d6e3030890138d92c0775e1c8d8c11fcea810b32e6a +size 50153 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsPreview_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.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsPreview_0_null,NEXUS_5,1.0,en].png index 29d860ddc9..2fe01fc5ff 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsPreview_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.libraries.designsystem.theme.components_null_TextFields_OutlinedTextFieldsPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38fdce46be1fd5acf8c8f9e23e59a1cae5f458daa191d7ba9fde6c929b380823 -size 45128 +oid sha256:914aecd8cef405ffd0c8d33b65d718ecad50060e95cb4b866de914a79c5ce6aa +size 45342 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_TextFieldDarkPreview_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.libraries.designsystem.theme.components_null_TextFields_TextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png index 80f1a795af..c802637d6c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_TextFieldDarkPreview_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.libraries.designsystem.theme.components_null_TextFields_TextFieldDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:505c2f4449cf297eec253c4a027b268e7f774bebd65dce94b651578b4659cb1f -size 55908 +oid sha256:52de83a9b21ff774b53db05f287fd76dcae248e6f509f8ff9873d1a252313dc2 +size 55177 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_TextFieldLightPreview_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.libraries.designsystem.theme.components_null_TextFields_TextFieldLightPreview_0_null,NEXUS_5,1.0,en].png index 70831eed9a..afe53b155a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_TextFields_TextFieldLightPreview_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.libraries.designsystem.theme.components_null_TextFields_TextFieldLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f44ac6df2ab5199c0243c2b01e503912f2272657223abf1de22b359b2df2dfd -size 55733 +oid sha256:12283d22402cc6bb118e8ea5c2ef6c294f46e8c0f5d594ddfb374931e2717069 +size 55224 From 181852c277ac5f1fea3df1fd8c8f735183aad5cb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 17:32:55 +0000 Subject: [PATCH 16/33] Update dependency org.matrix.rustcomponents:sdk-android to v0.1.14 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b343e4980..ec47b2eea0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -129,7 +129,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = { module = "app.cash.molecule:molecule-runtime", version.ref = "molecule" } timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.13" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.1.14" sqldelight-driver-android = { module = "com.squareup.sqldelight:android-driver", version.ref = "sqldelight" } sqldelight-driver-jvm = { module = "com.squareup.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extensions", version.ref = "sqldelight" } From da57e17dfb7e27f52bc480b27abd97d3adf1fce6 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 16 May 2023 14:29:18 +0200 Subject: [PATCH 17/33] Use material3 ListItem --- .../impl/configureroom/avatar/AvatarActionListView.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt index f68db3a4b7..422a187290 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/avatar/AvatarActionListView.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -@file:OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialApi::class) +@file:OptIn(ExperimentalMaterialApi::class) package io.element.android.features.createroom.impl.configureroom.avatar @@ -25,10 +25,10 @@ import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ListItem import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text +import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope @@ -87,13 +87,13 @@ private fun SheetContent( ) { action -> ListItem( modifier = Modifier.clickable { onActionClicked(action) }, - text = { + headlineContent = { Text( text = stringResource(action.titleResId), color = if (action.destructive) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.primary, ) }, - icon = { + leadingContent = { Icon( imageVector = action.icon, contentDescription = stringResource(action.titleResId), @@ -118,7 +118,7 @@ fun SheetContentDarkPreview() = @Composable private fun ContentToPreview() { AvatarActionListView( - actions = persistentListOf(AvatarAction.ChoosePhoto, AvatarAction.TakePhoto, AvatarAction.Remove), + actions = persistentListOf(AvatarAction.TakePhoto, AvatarAction.ChoosePhoto, AvatarAction.Remove), modalBottomSheetState = ModalBottomSheetState( initialValue = ModalBottomSheetValue.Expanded ), From 723e0d561c99813634823400a74a6ecb4b5ef8d7 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 16 May 2023 14:32:23 +0200 Subject: [PATCH 18/33] Update screenshots --- ...ltGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...tGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png index 6b5ba60f36..1a8de3bbb4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58efadd0883968cedfe5d74c4269edb3e7cadd1150fd0e9bd3425efcc717ec01 -size 14040 +oid sha256:c824fcf4167c6315d0d6568a4d300375a7bf6d4818e3d0dae9ed055f3269313d +size 13072 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png index fdfcbb6e11..809b8135eb 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_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.createroom.impl.configureroom.avatar_null_DefaultGroup_SheetContentLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cd407cdbaab5e3fe6b42ceb98c5b9b6a4012e3781ad7e754531c2ce04d9ee4e -size 14810 +oid sha256:8bad887952347b21606a783a19390fe73e5d6deb19390e2d413304398cff810c +size 13872 From 9c3a639fec207de405c4d97b3900e8f357bb1c20 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 16 May 2023 15:37:22 +0200 Subject: [PATCH 19/33] Fix test compilation --- .../impl/configureroom/ConfigureRoomPresenterTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 0c3f64b056..b4632ab0e8 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -228,7 +228,7 @@ class ConfigureRoomPresenterTests { }.test { skipItems(1) createRoomDataStore.setAvatarUri(Uri.parse(AN_URI_FROM_GALLERY)) - fakeMediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), null))) + fakeMediaPreProcessor.givenResult(Result.success(MediaUploadInfo.Image(mockk(), mockk(), mockk()))) fakeMatrixClient.givenUploadMediaResult(Result.failure(A_THROWABLE)) val initialState = awaitItem() From 8c6bf1ba18c51ac9687489ca2219576485f3b0bc Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 23:37:00 +0200 Subject: [PATCH 20/33] Make the configure room screen scrollable --- .../impl/configureroom/ConfigureRoomView.kt | 59 +++++++++++-------- ...ewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 6f7f21875b..4b23d5f389 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -21,8 +21,8 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetValue @@ -96,33 +96,42 @@ fun ConfigureRoomView( ) } ) { padding -> - Column( + LazyColumn( modifier = Modifier.padding(padding), verticalArrangement = Arrangement.spacedBy(24.dp), ) { - RoomNameWithAvatar( - modifier = Modifier.padding(horizontal = 16.dp), - avatarUri = state.config.avatarUri, - roomName = state.config.roomName.orEmpty(), - onAvatarClick = ::onAvatarClicked, - onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) }, - ) - RoomTopic( - modifier = Modifier.padding(horizontal = 16.dp), - topic = state.config.topic.orEmpty(), - onTopicChanged = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) }, - ) - SelectedUsersList( - contentPadding = PaddingValues(horizontal = 24.dp), - selectedUsers = state.config.invites, - onUserRemoved = { state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it)) }, - ) - Spacer(Modifier.weight(1f)) - RoomPrivacyOptions( - modifier = Modifier.padding(bottom = 40.dp), - selected = state.config.privacy, - onOptionSelected = { state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy)) }, - ) + item { + RoomNameWithAvatar( + modifier = Modifier.padding(horizontal = 16.dp), + avatarUri = state.config.avatarUri, + roomName = state.config.roomName.orEmpty(), + onAvatarClick = ::onAvatarClicked, + onRoomNameChanged = { state.eventSink(ConfigureRoomEvents.RoomNameChanged(it)) }, + ) + } + item { + RoomTopic( + modifier = Modifier.padding(horizontal = 16.dp), + topic = state.config.topic.orEmpty(), + onTopicChanged = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) }, + ) + } + if (state.config.invites.isNotEmpty()) { + item { + SelectedUsersList( + contentPadding = PaddingValues(horizontal = 24.dp), + selectedUsers = state.config.invites, + onUserRemoved = { state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it)) }, + ) + } + } + item { + RoomPrivacyOptions( + modifier = Modifier.padding(bottom = 40.dp), + selected = state.config.privacy, + onOptionSelected = { state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy)) }, + ) + } } } diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 160def016f..dbf9ad3653 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:24ad0b5edc27ddddca573b37f82579715d880793c0dc880248d2b572dd6d6a40 -size 64379 +oid sha256:7a3923915741c22054ceb2f34acdfdb629ccc14b8aad844206c64a7c63ef6cf6 +size 63704 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index c6a054a2d3..a04545bc27 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b0c9d4eaaaf6a691f43d25e0855ee056b69fa090ad8c53b26732c8f2532e2138 -size 103384 +oid sha256:6c6f2959adf84474dba18c44d81c2d9805ebb06ba8c8bf204f1845d2e62be84d +size 103395 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 26129e266a..2990badc15 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4023481d2a045d7e0d824db81b28ee47c4bcdc568d98537b3573d554e0b76e32 -size 58445 +oid sha256:02c3a6d536136e6c4db7e1b40a53506ec21e29810ee4067be4066851edfe8aee +size 57519 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index af4d0b2046..996b70e65e 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_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.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f953d0df467ad4cd1ae24291e9593945b945712506f093bdcae3da975f8ca91 -size 96800 +oid sha256:758362366ee7b50a33761401fd400698c124e468183459d4657cb707ea965424 +size 96777 From 52f2a32bf8c34858763b19184487665d75ac4640 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Thu, 11 May 2023 23:46:37 +0200 Subject: [PATCH 21/33] Select private privacy by default --- .../android/features/createroom/impl/CreateRoomConfig.kt | 2 +- .../features/createroom/impl/CreateRoomDataStore.kt | 2 +- .../createroom/impl/configureroom/ConfigureRoomEvents.kt | 2 +- .../impl/configureroom/ConfigureRoomPresenter.kt | 6 ------ .../createroom/impl/configureroom/ConfigureRoomState.kt | 5 +++-- .../impl/configureroom/ConfigureRoomStateProvider.kt | 4 +--- .../impl/configureroom/ConfigureRoomPresenterTests.kt | 9 +-------- ...igureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...igureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...gureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...gureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- 11 files changed, 16 insertions(+), 30 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt index 23b6f3239d..8f6f6e14d9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt @@ -27,5 +27,5 @@ data class CreateRoomConfig( val topic: String? = null, val avatarUri: Uri? = null, val invites: ImmutableList = persistentListOf(), - val privacy: RoomPrivacy? = null, + val privacy: RoomPrivacy = RoomPrivacy.Private, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index 3c594a0f1e..2a0dedc3e5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -60,7 +60,7 @@ class CreateRoomDataStore @Inject constructor( createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(avatarUri = uri)) } - fun setPrivacy(privacy: RoomPrivacy?) { + fun setPrivacy(privacy: RoomPrivacy) { createRoomConfigFlow.tryEmit(createRoomConfigFlow.value.copy(privacy = privacy)) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt index 52389d97fb..9082849954 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomEvents.kt @@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser sealed interface ConfigureRoomEvents { data class RoomNameChanged(val name: String) : ConfigureRoomEvents data class TopicChanged(val topic: String) : ConfigureRoomEvents - data class RoomPrivacyChanged(val privacy: RoomPrivacy?) : ConfigureRoomEvents + data class RoomPrivacyChanged(val privacy: RoomPrivacy) : ConfigureRoomEvents data class RemoveFromSelection(val matrixUser: MatrixUser) : ConfigureRoomEvents data class CreateRoom(val config: CreateRoomConfig) : ConfigureRoomEvents data class HandleAvatarAction(val action: AvatarAction) : ConfigureRoomEvents diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 7659226bd9..cf43c9ceb6 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -56,11 +56,6 @@ class ConfigureRoomPresenter @Inject constructor( @Composable override fun present(): ConfigureRoomState { val createRoomConfig = dataStore.getCreateRoomConfig().collectAsState(CreateRoomConfig()) - val isCreateButtonEnabled by remember(createRoomConfig.value.roomName, createRoomConfig.value.privacy) { - derivedStateOf { - createRoomConfig.value.roomName.isNullOrEmpty().not() && createRoomConfig.value.privacy != null - } - } val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker( onResult = { uri -> if (uri != null) dataStore.setAvatarUri(uri = uri, cached = true) }, @@ -108,7 +103,6 @@ class ConfigureRoomPresenter @Inject constructor( return ConfigureRoomState( config = createRoomConfig.value, - isCreateButtonEnabled = isCreateButtonEnabled, avatarActions = avatarActions, createRoomAction = createRoomAction.value, eventSink = ::handleEvents, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index 0e0c465b52..b99d70bb13 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -24,8 +24,9 @@ import kotlinx.collections.immutable.ImmutableList data class ConfigureRoomState( val config: CreateRoomConfig, - val isCreateButtonEnabled: Boolean, val avatarActions: ImmutableList, val createRoomAction: Async, val eventSink: (ConfigureRoomEvents) -> Unit -) +) { + val isCreateButtonEnabled: Boolean = config.roomName.isNullOrEmpty().not() +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 2dd4854f3a..9cb62d4f28 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -31,16 +31,14 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Date: Fri, 12 May 2023 00:24:03 +0200 Subject: [PATCH 22/33] Close keyboard when textfields lose focus --- .../impl/configureroom/ConfigureRoomView.kt | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 4b23d5f389..3fb3675e62 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -17,6 +17,7 @@ package io.element.android.features.createroom.impl.configureroom import android.net.Uri +import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -33,6 +34,10 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.composed +import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.input.pointer.pointerInput +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 @@ -68,6 +73,7 @@ fun ConfigureRoomView( onRoomCreated: (RoomId) -> Unit = {}, ) { val coroutineScope = rememberCoroutineScope() + val focusManager = LocalFocusManager.current val itemActionsBottomSheetState = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, ) @@ -79,18 +85,20 @@ fun ConfigureRoomView( } fun onAvatarClicked() { + focusManager.clearFocus() coroutineScope.launch { itemActionsBottomSheetState.show() } } Scaffold( - modifier = modifier, + modifier = modifier.clearFocusOnTap(focusManager), topBar = { ConfigureRoomToolbar( isNextActionEnabled = state.isCreateButtonEnabled, onBackPressed = onBackPressed, onNextPressed = { + focusManager.clearFocus() state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) }, ) @@ -121,7 +129,10 @@ fun ConfigureRoomView( SelectedUsersList( contentPadding = PaddingValues(horizontal = 24.dp), selectedUsers = state.config.invites, - onUserRemoved = { state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it)) }, + onUserRemoved = { + focusManager.clearFocus() + state.eventSink(ConfigureRoomEvents.RemoveFromSelection(it)) + }, ) } } @@ -129,7 +140,10 @@ fun ConfigureRoomView( RoomPrivacyOptions( modifier = Modifier.padding(bottom = 40.dp), selected = state.config.privacy, - onOptionSelected = { state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy)) }, + onOptionSelected = { + focusManager.clearFocus() + state.eventSink(ConfigureRoomEvents.RoomPrivacyChanged(it.privacy)) + }, ) } } @@ -268,3 +282,11 @@ private fun ContentToPreview(state: ConfigureRoomState) { state = state, ) } + +private fun Modifier.clearFocusOnTap(focusManager: FocusManager) = composed { + pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + }) + } +} From adc1c377893d3a05685e81969cbec98206f35e34 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Fri, 12 May 2023 00:26:50 +0200 Subject: [PATCH 23/33] restrict room name to single line --- .../features/createroom/impl/components/LabelledTextField.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/LabelledTextField.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/LabelledTextField.kt index 382e4b8de2..2a28c56253 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/LabelledTextField.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/LabelledTextField.kt @@ -54,6 +54,7 @@ fun LabelledTextField( value = value, placeholder = { Text(placeholder) }, onValueChange = onValueChange, + singleLine = maxLines == 1, maxLines = maxLines, ) } From 1f9812aaf05c6eda26111188a5711ca43ee47b3a Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Fri, 12 May 2023 08:40:24 +0200 Subject: [PATCH 24/33] Rename preview --- .../libraries/designsystem/theme/components/SearchBar.kt | 3 +-- ...ll_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png} | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_DockedSearchBarPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png} (100%) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 9a037cb7bb..4a0990bee4 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -31,7 +31,6 @@ import androidx.compose.ui.unit.Dp import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup -@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchBar( query: String, @@ -73,7 +72,7 @@ fun SearchBar( @Preview(group = PreviewGroup.Search) @Composable -internal fun DockedSearchBarPreview() = ElementThemedPreview { ContentToPreview() } +internal fun SearchBarPreview() = ElementThemedPreview { ContentToPreview() } @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_DockedSearchBarPreview_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_DockedSearchBarPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png From d9d3fc3fa72602c7a401a2262aa72de13c182023 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Fri, 12 May 2023 08:57:06 +0200 Subject: [PATCH 25/33] change wording for DM creation dialog --- .../features/createroom/impl/root/CreateRoomRootView.kt | 2 +- libraries/ui-strings/src/main/res/values/localazy.xml | 4 +++- ...CreateRoomRootViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...reateRoomRootViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) 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 2de52b89f7..8d78311dc1 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 @@ -101,7 +101,7 @@ fun CreateRoomRootView( when (state.startDmAction) { is Async.Loading -> { - ProgressDialog(text = stringResource(id = StringR.string.common_creating_room)) + ProgressDialog(text = stringResource(id = StringR.string.common_starting_chat)) } is Async.Failure -> { diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index fe7cc27a84..5e28338e22 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -63,6 +63,7 @@ "Developer options" "(edited)" "Editing" + "* %1$@ %2$@" "Encryption enabled" "Error" "File" @@ -90,6 +91,7 @@ "Server not supported" "Server URL" "Settings" + "Starting chat…" "Sticker" "Success" "Suggestions" @@ -159,4 +161,4 @@ "You can read all our terms %1$s." "here" "Block user" - \ No newline at end of file + 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 index 1e92cf978d..2a7a10f2c1 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f29da5d5aeb65659b065b7bd6afe276f83e020545a027780d2391308d1a4076 -size 20750 +oid sha256:56c23bd0880524cc56b713c93c5358e9f3771291c20f7a149bad00465f3f987a +size 20648 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 index 23c4de3194..69d05b132c 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae3e8c4e952b97628d026dfe78781aef894d6c2e742ac6ae1f1a2c0170df159e -size 20382 +oid sha256:f12591531cfdce24378003dda48940c20d8c9cf7bfac73ac1e7713e925bfac4d +size 20214 From 0b7569c578132e25a369564396cd38ad967345ba Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Fri, 12 May 2023 09:54:00 +0200 Subject: [PATCH 26/33] Remove useless `composed` call --- .../createroom/impl/configureroom/ConfigureRoomView.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 3fb3675e62..0b1e3d71c0 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -34,7 +34,6 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.composed import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalFocusManager @@ -283,10 +282,10 @@ private fun ContentToPreview(state: ConfigureRoomState) { ) } -private fun Modifier.clearFocusOnTap(focusManager: FocusManager) = composed { +private fun Modifier.clearFocusOnTap(focusManager: FocusManager): Modifier = pointerInput(Unit) { detectTapGestures(onTap = { focusManager.clearFocus() }) } -} + From 7206894c0ec3810a1bea77fbe1bc013346449b18 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Mon, 15 May 2023 18:08:24 +0200 Subject: [PATCH 27/33] Sync strings --- .../impl/src/main/res/values/localazy.xml | 32 ++++++++++--------- .../src/main/res/values/localazy.xml | 3 +- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 7c5006cc21..e7ffee267a 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -1,22 +1,24 @@ - - "1 person" - "%1$d people" - - "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them." - "Message encryption enabled" - "Share room" - "Pending" - "Block" - "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime." - "Block user" - "Unblock" - "On unblocking the user, you will be able to see all messages by them again." - "Unblock user" + + "1 person" + "%1$d people" + + "Already a member" + "Already invited" + "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them." + "Message encryption enabled" + "Share room" + "Pending" + "Block" + "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime." + "Block user" + "Unblock" + "On unblocking the user, you will be able to see all messages by them again." + "Unblock user" "Invite people" "Leave room" "People" "Security" "Topic" - \ No newline at end of file + diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 5e28338e22..849f306133 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -63,7 +63,7 @@ "Developer options" "(edited)" "Editing" - "* %1$@ %2$@" + "* %1$s %2$s" "Encryption enabled" "Error" "File" @@ -85,6 +85,7 @@ "Report a bug" "Report submitted" "Search for someone" + "Search results" "Security" "Select your server" "Sending…" From b157a42f8ab32dd3512faf0f2abc42cec7a75e03 Mon Sep 17 00:00:00 2001 From: Florian Renaud Date: Tue, 16 May 2023 16:41:43 +0200 Subject: [PATCH 28/33] Restore missing OptIn annotation --- .../android/libraries/designsystem/theme/components/SearchBar.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 4a0990bee4..f0e9eaf906 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.unit.Dp import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SearchBar( query: String, From 0f8b83d3ba2bc44ff5974056131f2274f5f27cd6 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Wed, 17 May 2023 15:21:23 +0200 Subject: [PATCH 29/33] New copy for members search results (#430) * New copy for members search results Context: https://matrix.to/#/!dypRwVXIkJaTAACHPd:element.io/$Obt7MbgGtHBqJHpZqcdd6OQ5XgxxNXSJofnFG1NyWWM?via=matrix.org&via=element.io&via=t2l.io Related to: https://github.com/vector-im/element-x-android/issues/246 --- .../impl/members/RoomMemberListView.kt | 17 ++++++--- .../impl/src/main/res/values/localazy.xml | 35 ++++++++++--------- ...stDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +-- ...tLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +-- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index ab52b9774a..3358451784 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -113,7 +113,8 @@ fun RoomMemberListView( if (state.roomMembers is Async.Success) { RoomMemberList( roomMembers = state.roomMembers.state, - onUserSelected = ::onUserSelected, + showMembersCount = true, + onUserSelected = ::onUserSelected ) } else if (state.roomMembers.isLoading()) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { @@ -128,6 +129,7 @@ fun RoomMemberListView( @Composable private fun RoomMemberList( roomMembers: RoomMembers, + showMembersCount: Boolean, onUserSelected: (RoomMember) -> Unit, ) { LazyColumn(modifier = Modifier.fillMaxWidth(), state = rememberLazyListState()) { @@ -139,9 +141,15 @@ private fun RoomMemberList( ) } if (roomMembers.joined.isNotEmpty()) { - val memberCount = roomMembers.joined.count() roomMemberListSection( - headerText = { pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) }, + headerText = { + if (showMembersCount) { + val memberCount = roomMembers.joined.count() + pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) + } else { + stringResource(id = R.string.screen_room_member_list_room_members_header_title) + } + }, members = roomMembers.joined, onMemberSelected = { onUserSelected(it) } ) @@ -272,7 +280,8 @@ private fun RoomMemberSearchBar( if (state is RoomMemberSearchResultState.Results) { RoomMemberList( roomMembers = state.results, - onUserSelected = { onUserSelected(it) } + showMembersCount = false, + onUserSelected = onUserSelected ) } else if (state is RoomMemberSearchResultState.NoResults) { Spacer(Modifier.size(80.dp)) diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index e7ffee267a..156261f66a 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -1,24 +1,25 @@ - - "1 person" - "%1$d people" - - "Already a member" - "Already invited" - "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them." - "Message encryption enabled" - "Share room" - "Pending" - "Block" - "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime." - "Block user" - "Unblock" - "On unblocking the user, you will be able to see all messages by them again." - "Unblock user" + + "1 person" + "%1$d people" + + "Already a member" + "Already invited" + "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them." + "Message encryption enabled" + "Share room" + "Pending" + "Room members" + "Block" + "Blocked users will not be able to send you messages and all message by them will be hidden. You can reverse this action anytime." + "Block user" + "Unblock" + "On unblocking the user, you will be able to see all messages by them again." + "Unblock user" "Invite people" "Leave room" "People" "Security" "Topic" - + \ No newline at end of file diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_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.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_5,NEXUS_5,1.0,en].png index 31ca39b498..22fe768986 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_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.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92c4537ed8794f4db08b4edec74a0de41847c4fd8c4fe03b7112bc63124b0a61 -size 29326 +oid sha256:070c93168058fded5a76e49050f6c4554c7fe483a19aae13c1af4426a6b575f1 +size 30582 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_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.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_5,NEXUS_5,1.0,en].png index 4275020d4c..1b35815820 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_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.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f663a70c43b9f2e66b651f17169b63859fe7c87c21312b61ed61a9136eabe5f -size 27989 +oid sha256:9dd67135f57c6e8a336e238384b02cd6068770b84f429f357d03d5e1e4c22ab6 +size 29286 From 32cc1f2a35e252e3b68ca3dc70862ab2fdb44f91 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 21 May 2023 19:57:07 +0000 Subject: [PATCH 30/33] Update coil to v2.4.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cbd56b3ed6..8e5ac0ba87 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,7 +32,7 @@ accompanist = "0.30.1" test_core = "1.5.0" #other -coil = "2.3.0" +coil = "2.4.0" datetime = "0.4.0" serialization_json = "1.5.0" showkase = "1.0.0-beta18" From 1eac67bf2577f1a24c87c4762fe83aca29fa7592 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 22 May 2023 10:06:54 +0100 Subject: [PATCH 31/33] Refactor search related functionality (#436) Refactor search related functionality This is a prelude to adding the feature of inviting users to a room, getting everything in the right place and reusable. What this does: ## User search refactor Moves the (global) user search logic (dealing with MXIDs, minimum lengths, debounces) into a `UserRepository`. This now sits in a `usersearch` library, which will be used by the create room flow and the new invite flow. ## SearchBar logic pull-up Every place we use SearchBar, we're doing the same things to style placeholders, show back/cancel buttons, etc. We also have a results type that is duplicated for basically every feature that uses the search bar. I've pushed all this common functionality into the SearchBar itself. This makes the component a bit less general purpose, but saves a lot of repetition. ## Remove the userlist feature Almost all the functionality of the userlist feature is now exclusively used by the create room feature. Room details uses its own version because the requirements are different. Components useful elsewhere (SelectedUsers and SelectedUser) have gone to matrixui, everything else has gone to createroom. ## Other bits and pieces I've fixed everywhere that uses Scaffold to correctly consume the WindowInsets if the contentPadding is applied to the contents (which it universally is). This was a change in the last version of Material3 (I guess previously Scaffold handled the consumption for us). This fixes weird gaps above search bars. Added overloads for the MatrixUserRow and CheckedMatrixUserRow that take the name/subtitle/avatar separately, so the invites list can pass arbitrary text like "User has already been invited". The `blockuser` package was for some reason not under `impl` but alongside it, I've bumped it into the right place. --- features/createroom/impl/build.gradle.kts | 5 +- .../createroom/impl/CreateRoomDataStore.kt | 2 +- .../impl/addpeople/AddPeoplePresenter.kt | 17 +- .../AddPeopleUserListStateProvider.kt | 14 +- .../impl/addpeople/AddPeopleView.kt | 16 +- .../SearchMultipleUsersResultItem.kt | 2 +- .../components/SearchSingleUserResultItem.kt | 2 +- .../impl/components/SearchUserBar.kt | 95 +++++++++ .../impl}/components/UserListView.kt | 9 +- .../ConfigureRoomStateProvider.kt | 2 +- .../impl/configureroom/ConfigureRoomView.kt | 10 +- .../impl/root/CreateRoomRootPresenter.kt | 17 +- .../impl/root/CreateRoomRootState.kt | 2 +- .../impl/root/CreateRoomRootStateProvider.kt | 9 +- .../impl/root/CreateRoomRootView.kt | 11 +- .../userlist}/DefaultUserListPresenter.kt | 53 ++--- .../impl/userlist}/UserListDataStore.kt | 2 +- .../impl/userlist}/UserListEvents.kt | 2 +- .../impl/userlist}/UserListPresenter.kt | 5 +- .../impl/userlist}/UserListPresenterArgs.kt | 11 +- .../impl/userlist}/UserListState.kt | 16 +- .../impl/userlist}/UserListStateProvider.kt | 11 +- .../impl/addpeople/AddPeoplePresenterTests.kt | 13 +- .../ConfigureRoomPresenterTests.kt | 2 +- .../impl/root/CreateRoomRootPresenterTests.kt | 16 +- .../DefaultUserListPresenterTests.kt | 143 ++++++++----- .../impl/userlist}/FakeUserListPresenter.kt | 5 +- .../userlist}/FakeUserListPresenterFactory.kt | 9 +- .../invitelist/impl/InviteListView.kt | 8 +- .../impl/changeserver/ChangeServerView.kt | 5 +- .../features/login/impl/root/LoginRootView.kt | 5 +- .../features/messages/impl/MessagesView.kt | 8 +- features/roomdetails/impl/build.gradle.kts | 2 +- .../roomdetails/impl/RoomDetailsFlowNode.kt | 1 - .../roomdetails/impl/RoomDetailsView.kt | 9 +- .../{ => impl}/blockuser/BlockUserSection.kt | 2 +- .../impl/members/RoomMemberListPresenter.kt | 9 +- .../impl/members/RoomMemberListState.kt | 14 +- .../members/RoomMemberListStateProvider.kt | 8 +- .../impl/members/RoomMemberListView.kt | 110 +++------- .../members/details/RoomMemberDetailsView.kt | 9 +- .../members/RoomMemberListPresenterTests.kt | 10 +- .../features/roomlist/impl/RoomListView.kt | 5 +- .../roomlist/impl/search/RoomListSearch.kt | 5 +- .../userlist/api/components/SearchUserBar.kt | 163 --------------- .../preferences/PreferenceScreen.kt | 4 + .../theme/components/SearchBar.kt | 196 +++++++++++++++--- libraries/matrixui/build.gradle.kts | 1 + .../ui/components/CheckableMatrixUserRow.kt | 36 +++- .../matrix/ui/components/MatrixUserRow.kt | 24 ++- .../matrix/ui}/components/SelectedUser.kt | 7 +- .../ui}/components/SelectedUsersList.kt | 6 +- .../src/main/res/values/localazy.xml | 4 +- .../usersearch}/api/build.gradle.kts | 10 +- .../usersearch}/api/UserListDataSource.kt | 2 +- .../usersearch/api/UserRepository.kt | 20 +- .../usersearch}/impl/build.gradle.kts | 25 +-- .../impl/MatrixUserListDataSource.kt | 9 +- .../usersearch/impl/MatrixUserRepository.kt | 64 ++++++ .../impl/MatrixUserListDataSourceTest.kt | 22 +- .../impl/MatrixUserRepositoryTest.kt | 140 +++++++++++++ .../usersearch}/test/build.gradle.kts | 10 +- .../test/FakeUserListDataSource.kt | 4 +- .../usersearch/test/FakeUserRepository.kt | 40 ++++ .../kotlin/extension/DependencyHandleScope.kt | 1 + ...atarDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...tarLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...temDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...emLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...temDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...emLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_0,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_1,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_2,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_3,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_4,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_5,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_6,NEXUS_5,1.0,en].png} | 0 ...wDarkPreview_0_null_7,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_0,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_1,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_2,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_3,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_4,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_5,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_6,NEXUS_5,1.0,en].png} | 0 ...LightPreview_0_null_7,NEXUS_5,1.0,en].png} | 0 ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...onDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...nLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ViewDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...iewLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...ewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 2 +- ...ewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...wLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 +- ...reenDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...eenLightPreview_0_null,NEXUS_5,1.0,en].png | 4 +- ...ewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...ctiveEmptyQuery_0_null,NEXUS_5,1.0,en].png | 3 + ...tiveWithContent_0_null,NEXUS_5,1.0,en].png | 3 + ...veWithNoResults_0_null,NEXUS_5,1.0,en].png | 3 + ...ActiveWithQuery_0_null,NEXUS_5,1.0,en].png | 3 + ...PreviewInactive_0_null,NEXUS_5,1.0,en].png | 3 + ...earchBarPreview_0_null,NEXUS_5,1.0,en].png | 3 - ...owDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...owDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...wLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 +- ...serDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...erLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...istDarkPreview_0_null,NEXUS_5,1.0,en].png} | 0 ...stLightPreview_0_null,NEXUS_5,1.0,en].png} | 0 137 files changed, 1002 insertions(+), 675 deletions(-) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/SearchMultipleUsersResultItem.kt (97%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/SearchSingleUserResultItem.kt (96%) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl}/components/UserListView.kt (89%) rename features/{userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/DefaultUserListPresenter.kt (57%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListDataStore.kt (95%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListEvents.kt (94%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListPresenter.kt (83%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListPresenterArgs.kt (74%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListState.kt (64%) rename features/{userlist/api/src/main/kotlin/io/element/android/features/userlist/api => createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist}/UserListStateProvider.kt (83%) rename features/{userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/DefaultUserListPresenterTests.kt (54%) rename features/{userlist/test/src/main/kotlin/io/element/android/features/userlist/test => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/FakeUserListPresenter.kt (79%) rename features/{userlist/test/src/main/kotlin/io/element/android/features/userlist/test => createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist}/FakeUserListPresenterFactory.kt (71%) rename features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/{ => impl}/blockuser/BlockUserSection.kt (98%) delete mode 100644 features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api => libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui}/components/SelectedUser.kt (92%) rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api => libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui}/components/SelectedUsersList.kt (94%) rename {features/userlist => libraries/usersearch}/api/build.gradle.kts (70%) rename {features/userlist/api/src/main/kotlin/io/element/android/features/userlist => libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch}/api/UserListDataSource.kt (94%) rename features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt => libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt (51%) rename {features/userlist => libraries/usersearch}/impl/build.gradle.kts (61%) rename features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt => libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt (79%) create mode 100644 libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt rename features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt => libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt (81%) create mode 100644 libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt rename {features/userlist => libraries/usersearch}/test/build.gradle.kts (78%) rename {features/userlist/test/src/main/kotlin/io/element/android/features/userlist => libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch}/test/FakeUserListDataSource.kt (90%) create mode 100644 libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png} (100%) create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png delete mode 100644 tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png} (100%) diff --git a/features/createroom/impl/build.gradle.kts b/features/createroom/impl/build.gradle.kts index 2026ac5214..feab0f16e7 100644 --- a/features/createroom/impl/build.gradle.kts +++ b/features/createroom/impl/build.gradle.kts @@ -45,10 +45,10 @@ dependencies { implementation(projects.libraries.designsystem) implementation(projects.libraries.elementresources) implementation(projects.libraries.uiStrings) - implementation(projects.features.userlist.api) implementation(projects.libraries.mediapickers.api) implementation(projects.libraries.mediaupload.api) implementation(libs.coil.compose) + implementation(projects.libraries.usersearch.impl) api(projects.features.createroom.api) testImplementation(libs.test.junit) @@ -59,10 +59,9 @@ dependencies { testImplementation(libs.test.turbine) testImplementation(libs.test.robolectric) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.features.userlist.impl) - testImplementation(projects.features.userlist.test) testImplementation(projects.libraries.mediapickers.test) testImplementation(projects.libraries.mediaupload.test) + testImplementation(projects.libraries.usersearch.test) androidTestImplementation(libs.test.junitext) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index 2a0dedc3e5..46de8fff91 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -19,7 +19,7 @@ package io.element.android.features.createroom.impl import android.net.Uri import io.element.android.features.createroom.impl.configureroom.RoomPrivacy import io.element.android.features.createroom.impl.di.CreateRoomScope -import io.element.android.features.userlist.api.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.libraries.di.SingleIn import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.Flow 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 index 50e84ebec6..0927e193ad 100644 --- 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 @@ -18,18 +18,17 @@ package io.element.android.features.createroom.impl.addpeople import androidx.compose.runtime.Composable import io.element.android.features.createroom.impl.CreateRoomDataStore -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserListState +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListPresenter +import io.element.android.features.createroom.impl.userlist.UserListPresenterArgs +import io.element.android.features.createroom.impl.userlist.UserListState import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.usersearch.api.UserRepository import javax.inject.Inject -import javax.inject.Named class AddPeoplePresenter @Inject constructor( private val userListPresenterFactory: UserListPresenter.Factory, - @Named("AllUsers") private val userListDataSource: UserListDataSource, + private val userRepository: UserRepository, private val dataStore: CreateRoomDataStore, ) : Presenter { @@ -37,10 +36,8 @@ class AddPeoplePresenter @Inject constructor( userListPresenterFactory.create( UserListPresenterArgs( selectionMode = SelectionMode.Multiple, - minimumSearchLength = 3, - searchDebouncePeriodMillis = UserListPresenterArgs.DEFAULT_DEBOUNCE ), - userListDataSource, + userRepository, dataStore.selectedUserListDataStore, ) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt index d005fe8dda..48ad56caf4 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleUserListStateProvider.kt @@ -17,11 +17,11 @@ package io.element.android.features.createroom.impl.addpeople import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.api.aListOfSelectedUsers -import io.element.android.features.userlist.api.aUserListState +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListState +import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers +import io.element.android.features.createroom.impl.userlist.aUserListState +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUserList import kotlinx.collections.immutable.toImmutableList @@ -30,13 +30,13 @@ open class AddPeopleUserListStateProvider : PreviewParameterProvider Unit = {}, ) { Scaffold( + modifier = modifier, topBar = { if (!state.isSearchActive) { AddPeopleViewTopBar( @@ -60,12 +64,14 @@ fun AddPeopleView( } ) { padding -> Column( - modifier = modifier + modifier = Modifier .fillMaxSize() - .padding(padding), + .padding(padding) + .consumeWindowInsets(padding), ) { UserListView( - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .fillMaxWidth(), state = state, ) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt similarity index 97% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt index f153d3671a..cf13768a82 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchMultipleUsersResultItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchMultipleUsersResultItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt similarity index 96% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt index 5f42438868..8dcaeb2bdf 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchSingleUserResultItem.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchSingleUserResultItem.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.clickable import androidx.compose.runtime.Composable diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt new file mode 100644 index 0000000000..33d308941f --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/SearchUserBar.kt @@ -0,0 +1,95 @@ +/* + * 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.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.SearchBar +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.components.SelectedUsersList +import io.element.android.libraries.ui.strings.R +import kotlinx.collections.immutable.ImmutableList + +@Composable +fun SearchUserBar( + query: String, + state: SearchBarResultState>, + selectedUsers: ImmutableList, + active: Boolean, + isMultiSelectionEnabled: Boolean, + modifier: Modifier = Modifier, + placeHolderTitle: String = stringResource(R.string.common_search_for_someone), + onActiveChanged: (Boolean) -> Unit = {}, + onTextChanged: (String) -> Unit = {}, + onUserSelected: (MatrixUser) -> Unit = {}, + onUserDeselected: (MatrixUser) -> Unit = {}, +) { + SearchBar( + query = query, + onQueryChange = onTextChanged, + active = active, + onActiveChange = onActiveChanged, + modifier = modifier, + placeHolderTitle = placeHolderTitle, + contentPrefix = { + if (isMultiSelectionEnabled && active && selectedUsers.isNotEmpty()) { + SelectedUsersList( + contentPadding = PaddingValues(16.dp), + selectedUsers = selectedUsers, + autoScroll = true, + onUserRemoved = onUserDeselected, + ) + } + }, + resultState = state, + resultHandler = { users -> + LazyColumn { + if (isMultiSelectionEnabled) { + items(users) { matrixUser -> + SearchMultipleUsersResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + isUserSelected = selectedUsers.find { it.userId == matrixUser.userId } != null, + onCheckedChange = { checked -> + if (checked) { + onUserSelected(matrixUser) + } else { + onUserDeselected(matrixUser) + } + } + ) + } + } else { + items(users) { matrixUser -> + SearchSingleUserResultItem( + modifier = Modifier.fillMaxWidth(), + matrixUser = matrixUser, + onClick = { onUserSelected(matrixUser) } + ) + } + } + } + }, + ) +} diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt similarity index 89% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt index afff072d9f..299dc59abf 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/UserListView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/components/UserListView.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.features.createroom.impl.components import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -24,12 +24,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserListStateProvider +import io.element.android.features.createroom.impl.userlist.UserListEvents +import io.element.android.features.createroom.impl.userlist.UserListState +import io.element.android.features.createroom.impl.userlist.UserListStateProvider import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.components.SelectedUsersList @Composable fun UserListView( diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index 9cb62d4f28..0e31e9e1c0 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -18,7 +18,7 @@ package io.element.android.features.createroom.impl.configureroom import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.createroom.impl.CreateRoomConfig -import io.element.android.features.userlist.api.aListOfSelectedUsers +import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers import io.element.android.libraries.architecture.Async import kotlinx.collections.immutable.persistentListOf diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt index 0b1e3d71c0..53d46b03c9 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt @@ -20,8 +20,10 @@ import android.net.Uri import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.selection.selectableGroup @@ -48,7 +50,6 @@ import io.element.android.features.createroom.impl.components.Avatar import io.element.android.features.createroom.impl.components.LabelledTextField import io.element.android.features.createroom.impl.components.RoomPrivacyOption import io.element.android.features.createroom.impl.configureroom.avatar.AvatarActionListView -import io.element.android.features.userlist.api.components.SelectedUsersList import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.button.BackButton @@ -60,10 +61,11 @@ 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.matrix.api.core.RoomId +import io.element.android.libraries.matrix.ui.components.SelectedUsersList import kotlinx.coroutines.launch import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterialApi::class) @Composable fun ConfigureRoomView( state: ConfigureRoomState, @@ -104,7 +106,9 @@ fun ConfigureRoomView( } ) { padding -> LazyColumn( - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(24.dp), ) { item { 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 0ac9611fc7..602f0a575b 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 @@ -21,25 +21,24 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import io.element.android.features.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs +import io.element.android.features.createroom.impl.userlist.SelectionMode +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListPresenter +import io.element.android.features.createroom.impl.userlist.UserListPresenterArgs import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.execute import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject -import javax.inject.Named class CreateRoomRootPresenter @Inject constructor( private val presenterFactory: UserListPresenter.Factory, - @Named("AllUsers") private val userListDataSource: UserListDataSource, + private val userRepository: UserRepository, private val userListDataStore: UserListDataStore, private val matrixClient: MatrixClient, ) : Presenter { @@ -48,10 +47,8 @@ class CreateRoomRootPresenter @Inject constructor( presenterFactory.create( UserListPresenterArgs( selectionMode = SelectionMode.Single, - minimumSearchLength = 3, - searchDebouncePeriodMillis = UserListPresenterArgs.DEFAULT_DEBOUNCE, ), - userListDataSource, + userRepository, userListDataStore, ) } 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 d8e7533b0b..e4e7f821c7 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,7 +16,7 @@ package io.element.android.features.createroom.impl.root -import io.element.android.features.userlist.api.UserListState +import io.element.android.features.createroom.impl.userlist.UserListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId 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 ccfad47a86..d3e8492240 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,9 +17,10 @@ package io.element.android.features.createroom.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.api.aUserListState +import io.element.android.features.createroom.impl.userlist.aUserListState + import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUser import kotlinx.collections.immutable.persistentListOf @@ -32,7 +33,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider Column( - modifier = Modifier.padding(paddingValues), + modifier = Modifier + .padding(paddingValues) + .consumeWindowInsets(paddingValues), verticalArrangement = Arrangement.spacedBy(8.dp), ) { - val context = LocalContext.current UserListView( modifier = Modifier.fillMaxWidth(), state = state.userListState, diff --git a/features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt similarity index 57% rename from features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt index 24ee9d4e26..2efbdb7b9a 100644 --- a/features/userlist/impl/src/main/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenter.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.impl +package io.element.android.features.createroom.impl.userlist import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -28,24 +28,16 @@ import com.squareup.anvil.annotations.ContributesBinding import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.UserSearchResultState +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState 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.api.user.MatrixUser -import kotlinx.collections.immutable.persistentListOf +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList -import kotlinx.coroutines.delay class DefaultUserListPresenter @AssistedInject constructor( @Assisted val args: UserListPresenterArgs, - @Assisted val userListDataSource: UserListDataSource, + @Assisted val userRepository: UserRepository, @Assisted val userListDataStore: UserListDataStore, ) : UserListPresenter { @@ -54,7 +46,7 @@ class DefaultUserListPresenter @AssistedInject constructor( interface DefaultUserListFactory : UserListPresenter.Factory { override fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): DefaultUserListPresenter } @@ -64,24 +56,18 @@ class DefaultUserListPresenter @AssistedInject constructor( var isSearchActive by rememberSaveable { mutableStateOf(false) } val selectedUsers by userListDataStore.selectedUsers().collectAsState(emptyList()) var searchQuery by rememberSaveable { mutableStateOf("") } - var searchResults: UserSearchResultState by remember { - mutableStateOf(UserSearchResultState.NotSearching) + var searchResults: SearchBarResultState> by remember { + mutableStateOf(SearchBarResultState.NotSearching()) } LaunchedEffect(searchQuery) { - // Clear the search results before performing the search, manually add a fake result with the matrixId, if any - searchResults = if (MatrixPatterns.isUserId(searchQuery)) { - UserSearchResultState.Results(persistentListOf(MatrixUser(UserId(searchQuery)))) - } else { - UserSearchResultState.NotSearching - } + searchResults = SearchBarResultState.NotSearching() - // Debounce - delay(args.searchDebouncePeriodMillis) - - // Perform the search asynchronously - if (searchQuery.length >= args.minimumSearchLength) { - searchResults = performSearch(searchQuery) + userRepository.search(searchQuery).collect { + searchResults = when { + it.isEmpty() -> SearchBarResultState.NoResults() + else -> SearchBarResultState.Results(it.toImmutableList()) + } } } @@ -101,15 +87,4 @@ class DefaultUserListPresenter @AssistedInject constructor( }, ) } - - private suspend fun performSearch(query: String): UserSearchResultState { - val isMatrixId = MatrixPatterns.isUserId(query) - val results = userListDataSource.search(query).toMutableList() - if (isMatrixId && results.none { it.userId.value == query }) { - val getProfileResult: MatrixUser? = userListDataSource.getProfile(UserId(query)) - val profile = getProfileResult ?: MatrixUser(UserId(query)) - results.add(0, profile) - } - return if (results.isEmpty()) UserSearchResultState.NoResults else UserSearchResultState.Results(results.toImmutableList()) - } } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt similarity index 95% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt index 31750e5350..8de7be3114 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListDataStore.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.coroutines.flow.Flow diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt index fe0d681fe1..6dc817d22c 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListEvents.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.matrix.api.user.MatrixUser diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt similarity index 83% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt index 90205eab2a..e5d68a2e28 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenter.kt @@ -14,16 +14,17 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.usersearch.api.UserRepository interface UserListPresenter : Presenter { interface Factory { fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): UserListPresenter } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt similarity index 74% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt index e00aa89155..15c2a94a24 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListPresenterArgs.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListPresenterArgs.kt @@ -14,18 +14,11 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist data class UserListPresenterArgs( val selectionMode: SelectionMode, - val minimumSearchLength: Int = 1, - val searchDebouncePeriodMillis: Long = NO_DEBOUNCE, -) { - companion object { - const val NO_DEBOUNCE = 0L - const val DEFAULT_DEBOUNCE = 500L - } -} +) enum class SelectionMode { Single, diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt similarity index 64% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt index 490a1fdde3..d8ff391163 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListState.kt @@ -14,14 +14,15 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList data class UserListState( val searchQuery: String, - val searchResults: UserSearchResultState, + val searchResults: SearchBarResultState>, val selectedUsers: ImmutableList, val isSearchActive: Boolean, val selectionMode: SelectionMode, @@ -29,14 +30,3 @@ data class UserListState( ) { val isMultiSelectionEnabled = selectionMode == SelectionMode.Multiple } - -sealed interface UserSearchResultState { - /** No search results are available yet (e.g. because the user hasn't entered a (long enough) search term). */ - object NotSearching : UserSearchResultState - - /** The search has completed, but no results were found. */ - object NoResults : UserSearchResultState - - /** The search has completed, and some matching users were found. */ - data class Results(val results: ImmutableList) : UserSearchResultState -} diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt similarity index 83% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt rename to features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt index d0047e4717..cb8bf284b0 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/userlist/UserListStateProvider.kt @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.features.createroom.impl.userlist import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUserList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -37,19 +38,19 @@ open class UserListStateProvider : PreviewParameterProvider { isSearchActive = true, searchQuery = "@someone:matrix.org", selectedUsers = aListOfSelectedUsers(), - searchResults = UserSearchResultState.Results(aMatrixUserList().toImmutableList()), + searchResults = SearchBarResultState.Results(aMatrixUserList().toImmutableList()), ), aUserListState().copy( isSearchActive = true, searchQuery = "@someone:matrix.org", selectionMode = SelectionMode.Multiple, selectedUsers = aListOfSelectedUsers(), - searchResults = UserSearchResultState.Results(aMatrixUserList().toImmutableList()), + searchResults = SearchBarResultState.Results(aMatrixUserList().toImmutableList()), ), aUserListState().copy( isSearchActive = true, searchQuery = "something-with-no-results", - searchResults = UserSearchResultState.NoResults + searchResults = SearchBarResultState.NoResults() ), ) } @@ -57,7 +58,7 @@ open class UserListStateProvider : PreviewParameterProvider { fun aUserListState() = UserListState( isSearchActive = false, searchQuery = "", - searchResults = UserSearchResultState.NotSearching, + searchResults = SearchBarResultState.NotSearching(), selectedUsers = persistentListOf(), selectionMode = SelectionMode.Single, eventSink = {} 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 index d7ee836453..fe8c7b7462 100644 --- 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 @@ -21,9 +21,9 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.createroom.impl.CreateRoomDataStore -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.features.userlist.test.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -34,7 +34,11 @@ class AddPeoplePresenterTests { @Before fun setup() { - presenter = AddPeoplePresenter(FakeUserListPresenterFactory(), FakeUserListDataSource(), CreateRoomDataStore(UserListDataStore())) + presenter = AddPeoplePresenter( + FakeUserListPresenterFactory(), + FakeUserRepository(), + CreateRoomDataStore(UserListDataStore()) + ) } @Test @@ -42,6 +46,7 @@ class AddPeoplePresenterTests { moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + // TODO This doesn't actually test anything... val initialState = awaitItem() assertThat(initialState) } diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt index 82a35cf2ee..ed44cc1983 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt @@ -24,7 +24,7 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.features.createroom.impl.configureroom.avatar.AvatarAction -import io.element.android.features.userlist.api.UserListDataStore +import io.element.android.features.createroom.impl.userlist.UserListDataStore import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.test.AN_AVATAR_URL 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 2a06278934..517afc9fe9 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 @@ -20,11 +20,10 @@ 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.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.aUserListState -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.features.userlist.test.FakeUserListPresenter -import io.element.android.features.userlist.test.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenter +import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory +import io.element.android.features.createroom.impl.userlist.UserListDataStore +import io.element.android.features.createroom.impl.userlist.aUserListState import io.element.android.libraries.architecture.Async import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId @@ -32,6 +31,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.A_THROWABLE import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Before @@ -39,7 +39,7 @@ import org.junit.Test class CreateRoomRootPresenterTests { - private lateinit var userListDataSource: FakeUserListDataSource + private lateinit var userRepository: FakeUserRepository private lateinit var presenter: CreateRoomRootPresenter private lateinit var fakeUserListPresenter: FakeUserListPresenter private lateinit var fakeMatrixClient: FakeMatrixClient @@ -48,8 +48,8 @@ class CreateRoomRootPresenterTests { fun setup() { fakeUserListPresenter = FakeUserListPresenter() fakeMatrixClient = FakeMatrixClient() - userListDataSource = FakeUserListDataSource() - presenter = CreateRoomRootPresenter(FakeUserListPresenterFactory(fakeUserListPresenter), userListDataSource, UserListDataStore(), fakeMatrixClient) + userRepository = FakeUserRepository() + presenter = CreateRoomRootPresenter(FakeUserListPresenterFactory(fakeUserListPresenter), userRepository, UserListDataStore(), fakeMatrixClient) } @Test diff --git a/features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt similarity index 54% rename from features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt index b13881dc5b..40b7e6549b 100644 --- a/features/userlist/impl/src/test/kotlin/io/element/android/features/userlist/impl/DefaultUserListPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/DefaultUserListPresenterTests.kt @@ -14,77 +14,78 @@ * limitations under the License. */ -package io.element.android.features.userlist.impl +package io.element.android.features.createroom.impl.userlist 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.userlist.api.SelectionMode -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListEvents -import io.element.android.features.userlist.api.UserListPresenterArgs -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.features.userlist.test.FakeUserListDataSource -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.ui.components.aMatrixUser +import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.libraries.usersearch.test.FakeUserRepository import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Test class DefaultUserListPresenterTests { - private val userListDataSource = FakeUserListDataSource() + private val userRepository = FakeUserRepository() @Test fun `present - initial state for single selection`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() assertThat(initialState.searchQuery).isEmpty() assertThat(initialState.isMultiSelectionEnabled).isFalse() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isEqualTo(UserSearchResultState.NotSearching) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) } } @Test fun `present - initial state for multiple selection`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Multiple), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Multiple), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() assertThat(initialState.searchQuery).isEmpty() assertThat(initialState.isMultiSelectionEnabled).isTrue() assertThat(initialState.isSearchActive).isFalse() assertThat(initialState.selectedUsers).isEmpty() - assertThat(initialState.searchResults).isEqualTo(UserSearchResultState.NotSearching) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) } } @Test fun `present - update search query`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() initialState.eventSink(UserListEvents.OnSearchActiveChanged(true)) @@ -93,12 +94,14 @@ class DefaultUserListPresenterTests { val matrixIdQuery = "@name:matrix.org" initialState.eventSink(UserListEvents.UpdateSearchQuery(matrixIdQuery)) assertThat(awaitItem().searchQuery).isEqualTo(matrixIdQuery) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.Results(persistentListOf(MatrixUser(UserId(matrixIdQuery))))) + assertThat(userRepository.providedQuery).isEqualTo(matrixIdQuery) + skipItems(1) val notMatrixIdQuery = "name" initialState.eventSink(UserListEvents.UpdateSearchQuery(notMatrixIdQuery)) assertThat(awaitItem().searchQuery).isEqualTo(notMatrixIdQuery) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NoResults) + assertThat(userRepository.providedQuery).isEqualTo(notMatrixIdQuery) + skipItems(1) initialState.eventSink(UserListEvents.OnSearchActiveChanged(false)) assertThat(awaitItem().isSearchActive).isFalse() @@ -106,39 +109,83 @@ class DefaultUserListPresenterTests { } @Test - fun `present - searches when minimum length exceeded`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single, minimumSearchLength = 3), - userListDataSource, - UserListDataStore(), - ) + fun `present - presents search results`() = runTest { + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs( + selectionMode = SelectionMode.Single, + ), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() - // When the search term is too short, nothing happens - initialState.eventSink(UserListEvents.UpdateSearchQuery("al")) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NotSearching) - - // When it reaches the minimum length, a search is performed asynchronously - userListDataSource.givenSearchResult(listOf(aMatrixUser())) initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.NotSearching) - assertThat(awaitItem().searchResults).isEqualTo(UserSearchResultState.Results(persistentListOf(aMatrixUser()))) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(userRepository.providedQuery).isEqualTo("alice") + skipItems(2) + + // When the user repository emits a result, it's copied to the state + userRepository.emitResult(listOf(aMatrixUser())) + assertThat(awaitItem().searchResults).isEqualTo( + SearchBarResultState.Results( + persistentListOf(aMatrixUser()) + ) + ) + + // When the user repository emits another result, it replaces the previous value + userRepository.emitResult(aMatrixUserList()) + assertThat(awaitItem().searchResults).isEqualTo( + SearchBarResultState.Results( + aMatrixUserList() + ) + ) + } + } + + @Test + fun `present - presents search results when not found`() = runTest { + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs( + selectionMode = SelectionMode.Single, + ), + userRepository, + UserListDataStore(), + ) + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + + initialState.eventSink(UserListEvents.UpdateSearchQuery("alice")) + assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) + assertThat(userRepository.providedQuery).isEqualTo("alice") + skipItems(2) + + // When the results list is empty, the state is set to NoResults + userRepository.emitResult(emptyList()) + assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) } } @Test fun `present - select a user`() = runTest { - val presenter = DefaultUserListPresenter( - UserListPresenterArgs(selectionMode = SelectionMode.Single), - userListDataSource, - UserListDataStore(), - ) + val presenter = + DefaultUserListPresenter( + UserListPresenterArgs(selectionMode = SelectionMode.Single), + userRepository, + UserListDataStore(), + ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() }.test { + skipItems(1) val initialState = awaitItem() val userA = aMatrixUser("@userA:domain", "A") diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt similarity index 79% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt index 54aef4a6f7..45eb712dc1 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenter.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenter.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.features.createroom.impl.userlist import androidx.compose.runtime.Composable -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListState -import io.element.android.features.userlist.api.aUserListState class FakeUserListPresenter : UserListPresenter { diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt similarity index 71% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt rename to features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt index 00966a5082..07697ce458 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListPresenterFactory.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/userlist/FakeUserListPresenterFactory.kt @@ -14,12 +14,9 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.features.createroom.impl.userlist -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.features.userlist.api.UserListDataStore -import io.element.android.features.userlist.api.UserListPresenter -import io.element.android.features.userlist.api.UserListPresenterArgs +import io.element.android.libraries.usersearch.api.UserRepository class FakeUserListPresenterFactory( private val fakeUserListPresenter: FakeUserListPresenter = FakeUserListPresenter() @@ -27,7 +24,7 @@ class FakeUserListPresenterFactory( override fun create( args: UserListPresenterArgs, - userListDataSource: UserListDataSource, + userRepository: UserRepository, userListDataStore: UserListDataStore, ): UserListPresenter = fakeUserListPresenter } diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt index 78c4c140a1..d714eda319 100644 --- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt +++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt @@ -17,7 +17,9 @@ package io.element.android.features.invitelist.impl import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -103,7 +105,7 @@ fun InviteListView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun InviteListContent( state: InviteListState, @@ -124,7 +126,9 @@ fun InviteListContent( }, content = { padding -> Column( - modifier = Modifier.padding(padding) + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding) ) { if (state.inviteList.isEmpty()) { Spacer(Modifier.size(80.dp)) diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt index 2137760085..cbd2bc9308 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt @@ -20,7 +20,9 @@ import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -81,7 +83,7 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class, ExperimentalLayoutApi::class) @Composable fun ChangeServerView( state: ChangeServerState, @@ -121,6 +123,7 @@ fun ChangeServerView( .fillMaxSize() .imePadding() .padding(padding) + .consumeWindowInsets(padding) ) { Column( modifier = Modifier diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt index b7491f5b3b..b72122c914 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/root/LoginRootView.kt @@ -21,8 +21,10 @@ 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.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -86,7 +88,7 @@ import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun LoginRootView( state: LoginRootState, @@ -113,6 +115,7 @@ fun LoginRootView( .fillMaxSize() .imePadding() .padding(padding) + .consumeWindowInsets(padding) ) { val scrollState = rememberScrollState() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index f98b19575a..a55ea1021d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -19,9 +19,11 @@ package io.element.android.features.messages.impl import androidx.activity.compose.BackHandler import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.imePadding @@ -79,7 +81,7 @@ import io.element.android.libraries.designsystem.utils.LogCompositions import kotlinx.coroutines.launch import timber.log.Timber -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalLayoutApi::class) @Composable fun MessagesView( state: MessagesState, @@ -183,7 +185,9 @@ fun MessagesView( content = { padding -> MessagesViewContent( state = state, - modifier = Modifier.padding(padding), + modifier = Modifier + .padding(padding) + .consumeWindowInsets(padding), onMessageClicked = ::onMessageClicked, onMessageLongClicked = ::onMessageLongClicked ) diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index 7b072a5faf..05181c3f67 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) api(projects.features.roomdetails.api) + api(projects.libraries.usersearch.api) implementation(libs.coil.compose) testImplementation(libs.test.junit) @@ -50,7 +51,6 @@ dependencies { testImplementation(libs.test.truth) testImplementation(libs.test.turbine) testImplementation(projects.libraries.matrix.test) - testImplementation(projects.features.userlist.test) testImplementation(projects.tests.testutils) ksp(libs.showkase.processor) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index f3a0ef9001..8c7d9cd375 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -35,7 +35,6 @@ import io.element.android.libraries.architecture.animation.rememberDefaultTransi import io.element.android.libraries.architecture.createNode import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.room.RoomMember import kotlinx.parcelize.Parcelize @ContributesNode(RoomScope::class) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index f9f6d43720..c09a80cf1b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -19,8 +19,10 @@ package io.element.android.features.roomdetails.impl import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -43,8 +45,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.blockuser.BlockUserDialogs -import io.element.android.features.roomdetails.blockuser.BlockUserSection +import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs +import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberHeaderSection import io.element.android.features.roomdetails.impl.members.details.RoomMemberMainActionsSection import io.element.android.libraries.architecture.isLoading @@ -68,7 +70,7 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomDetailsView( state: RoomDetailsState, @@ -91,6 +93,7 @@ fun RoomDetailsView( ) { padding -> Column(modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) .verticalScroll(rememberScrollState()) ) { when (state.roomType) { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt similarity index 98% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt rename to features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt index 49daa15af3..3effaca4a1 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/blockuser/BlockUserSection.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.roomdetails.blockuser +package io.element.android.features.roomdetails.impl.blockuser import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Block diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 3a719983b6..ddf7864b96 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -26,6 +26,7 @@ import androidx.compose.runtime.setValue import io.element.android.libraries.architecture.Async import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.RoomMembershipState import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.withContext @@ -41,7 +42,7 @@ class RoomMemberListPresenter @Inject constructor( var roomMembers by remember { mutableStateOf>(Async.Loading()) } var searchQuery by rememberSaveable { mutableStateOf("") } var searchResults by remember { - mutableStateOf(RoomMemberSearchResultState.NotSearching) + mutableStateOf>(SearchBarResultState.NotSearching()) } var isSearchActive by rememberSaveable { mutableStateOf(false) } @@ -60,11 +61,11 @@ class RoomMemberListPresenter @Inject constructor( LaunchedEffect(searchQuery) { withContext(coroutineDispatchers.io) { searchResults = if (searchQuery.isEmpty()) { - RoomMemberSearchResultState.NotSearching + SearchBarResultState.NotSearching() } else { val results = roomMemberListDataSource.search(searchQuery).groupBy { it.membership } - if (results.isEmpty()) RoomMemberSearchResultState.NoResults - else RoomMemberSearchResultState.Results( + if (results.isEmpty()) SearchBarResultState.NoResults() + else SearchBarResultState.Results( RoomMembers( invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(), joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList()).toImmutableList(), diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index a689ad1fd2..93e2142a19 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -17,13 +17,14 @@ package io.element.android.features.roomdetails.impl.members import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.RoomMember import kotlinx.collections.immutable.ImmutableList data class RoomMemberListState( val roomMembers: Async, val searchQuery: String, - val searchResults: RoomMemberSearchResultState, + val searchResults: SearchBarResultState, val isSearchActive: Boolean, val eventSink: (RoomMemberListEvents) -> Unit, ) @@ -32,14 +33,3 @@ data class RoomMembers( val invited: ImmutableList, val joined: ImmutableList ) - -sealed interface RoomMemberSearchResultState { - /** No search results are available yet (e.g. because the user hasn't entered a (long enough) search term). */ - object NotSearching : RoomMemberSearchResultState - - /** The search has completed, but no results were found. */ - object NoResults : RoomMemberSearchResultState - - /** The search has completed, and some matching users were found. */ - data class Results(val results: RoomMembers) : RoomMemberSearchResultState -} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 7f91969bcd..9bc8c00a1e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -18,11 +18,11 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState import kotlinx.collections.immutable.persistentListOf -import kotlinx.collections.immutable.toImmutableList internal class RoomMemberListStateProvider : PreviewParameterProvider { override val values: Sequence @@ -42,7 +42,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider = Async.Uninitialized, - searchResults: RoomMemberSearchResultState = RoomMemberSearchResultState.NotSearching, + searchResults: SearchBarResultState = SearchBarResultState.NotSearching(), ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 3358451784..ff7bb54f9e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -20,27 +20,20 @@ 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.Spacer +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState -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.graphics.Color -import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -59,10 +52,9 @@ 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.CircularProgressIndicator -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.SearchBarResultState import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.RoomMember @@ -71,6 +63,7 @@ import io.element.android.libraries.matrix.ui.components.MatrixUserRow import kotlinx.collections.immutable.ImmutableList import io.element.android.libraries.ui.strings.R as StringR +@OptIn(ExperimentalLayoutApi::class) @Composable fun RoomMemberListView( state: RoomMemberListState, @@ -93,21 +86,20 @@ fun RoomMemberListView( Column( modifier = modifier .fillMaxWidth() - .padding(padding), + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { - Column { - RoomMemberSearchBar( - query = state.searchQuery, - state = state.searchResults, - active = state.isSearchActive, - placeHolderTitle = stringResource(StringR.string.common_search_for_someone), - onActiveChanged = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, - onTextChanged = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, - onUserSelected = ::onUserSelected, - modifier = Modifier.fillMaxWidth() - ) - } + RoomMemberSearchBar( + query = state.searchQuery, + state = state.searchResults, + active = state.isSearchActive, + placeHolderTitle = stringResource(StringR.string.common_search_for_someone), + onActiveChanged = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, + onTextChanged = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, + onUserSelected = ::onUserSelected, + modifier = Modifier.fillMaxWidth() + ) if (!state.isSearchActive) { if (state.roomMembers is Async.Success) { @@ -216,11 +208,10 @@ private fun RoomMemberListTopBar( ) } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun RoomMemberSearchBar( query: String, - state: RoomMemberSearchResultState, + state: SearchBarResultState, active: Boolean, placeHolderTitle: String, onActiveChanged: (Boolean) -> Unit, @@ -228,72 +219,21 @@ private fun RoomMemberSearchBar( onUserSelected: (RoomMember) -> Unit, modifier: Modifier = Modifier, ) { - 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) + modifier = modifier, + placeHolderTitle = placeHolderTitle, + resultState = state, + resultHandler = { results -> + RoomMemberList( + roomMembers = results, + showMembersCount = false, + onUserSelected = { onUserSelected(it) } ) }, - leadingIcon = if (active) { - { BackButton(onClick = { onActiveChanged(false) }) } - } else { - null - }, - trailingIcon = when { - active && query.isNotEmpty() -> { - { - IconButton(onClick = { onTextChanged("") }) { - Icon(Icons.Default.Close, stringResource(StringR.string.action_clear)) - } - } - } - - !active -> { - { - Icon( - imageVector = Icons.Default.Search, - contentDescription = stringResource(StringR.string.action_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 (state is RoomMemberSearchResultState.Results) { - RoomMemberList( - roomMembers = state.results, - showMembersCount = false, - onUserSelected = onUserSelected - ) - } else if (state is RoomMemberSearchResultState.NoResults) { - Spacer(Modifier.size(80.dp)) - - Text( - text = stringResource(StringR.string.common_no_results), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.fillMaxWidth() - ) - } - }, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt index a8ef557289..62b3d07a85 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt @@ -19,8 +19,10 @@ package io.element.android.features.roomdetails.impl.members.details import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -39,8 +41,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.blockuser.BlockUserDialogs -import io.element.android.features.roomdetails.blockuser.BlockUserSection +import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs +import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection import io.element.android.libraries.designsystem.ElementTextStyles import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -57,7 +59,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.R as StringR -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomMemberDetailsView( state: RoomMemberDetailsState, @@ -74,6 +76,7 @@ fun RoomMemberDetailsView( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) .verticalScroll(rememberScrollState()) ) { RoomMemberHeaderSection( diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt index 48cf660877..73c873701e 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt @@ -24,12 +24,12 @@ import io.element.android.features.roomdetails.aMatrixRoom import io.element.android.features.roomdetails.impl.members.RoomMemberListDataSource import io.element.android.features.roomdetails.impl.members.RoomMemberListEvents import io.element.android.features.roomdetails.impl.members.RoomMemberListPresenter -import io.element.android.features.roomdetails.impl.members.RoomMemberSearchResultState import io.element.android.features.roomdetails.impl.members.aRoomMemberList import io.element.android.features.roomdetails.impl.members.aVictor import io.element.android.features.roomdetails.impl.members.aWalter import io.element.android.libraries.architecture.Async import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.tests.testutils.testCoroutineDispatchers @@ -49,7 +49,7 @@ class RoomMemberListPresenterTests { val initialState = awaitItem() Truth.assertThat(initialState.roomMembers).isInstanceOf(Async.Loading::class.java) Truth.assertThat(initialState.searchQuery).isEmpty() - Truth.assertThat(initialState.searchResults).isEqualTo(RoomMemberSearchResultState.NotSearching) + Truth.assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java) Truth.assertThat(initialState.isSearchActive).isFalse() val loadedState = awaitItem() @@ -89,7 +89,7 @@ class RoomMemberListPresenterTests { val searchQueryUpdatedState = awaitItem() Truth.assertThat((searchQueryUpdatedState.searchQuery)).isEqualTo("something") val searchSearchResultDelivered = awaitItem() - Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(RoomMemberSearchResultState.NoResults::class.java) + Truth.assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.NoResults::class.java) } } @@ -107,8 +107,8 @@ class RoomMemberListPresenterTests { val searchQueryUpdatedState = awaitItem() Truth.assertThat((searchQueryUpdatedState.searchQuery)).isEqualTo("Alice") val searchSearchResultDelivered = awaitItem() - Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(RoomMemberSearchResultState.Results::class.java) - Truth.assertThat((searchSearchResultDelivered.searchResults as RoomMemberSearchResultState.Results).results.joined.first().displayName) + Truth.assertThat((searchSearchResultDelivered.searchResults)).isInstanceOf(SearchBarResultState.Results::class.java) + Truth.assertThat((searchSearchResultDelivered.searchResults as SearchBarResultState.Results).results.joined.first().displayName) .isEqualTo("Alice") } 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 acfc822658..dc3c7bff7a 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 @@ -22,9 +22,11 @@ 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.ExperimentalLayoutApi import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -116,7 +118,7 @@ fun RoomListView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun RoomListContent( state: RoomListState, @@ -190,6 +192,7 @@ fun RoomListContent( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) ) { LazyColumn( modifier = Modifier diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt index 021959c3aa..bdd4858ce3 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/search/RoomListSearch.kt @@ -20,6 +20,8 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -89,7 +91,7 @@ internal fun RoomListSearchResultView( } } -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable internal fun RoomListSearchResultContent( state: RoomListState, @@ -183,6 +185,7 @@ internal fun RoomListSearchResultContent( Column( modifier = Modifier .padding(padding) + .consumeWindowInsets(padding) ) { LazyColumn( modifier = Modifier diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt b/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt deleted file mode 100644 index 1e82936c92..0000000000 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SearchUserBar.kt +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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.userlist.api.components - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -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.MaterialTheme -import androidx.compose.material3.SearchBarDefaults -import androidx.compose.runtime.Composable -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.style.TextAlign -import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.UserSearchResultState -import io.element.android.libraries.designsystem.components.button.BackButton -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.api.user.MatrixUser -import io.element.android.libraries.ui.strings.R -import kotlinx.collections.immutable.ImmutableList - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchUserBar( - query: String, - state: UserSearchResultState, - selectedUsers: ImmutableList, - active: Boolean, - isMultiSelectionEnabled: Boolean, - modifier: Modifier = Modifier, - placeHolderTitle: String = stringResource(R.string.common_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(R.string.action_clear)) - } - } - } - - !active -> { - { - Icon( - imageVector = Icons.Default.Search, - contentDescription = stringResource(R.string.action_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( - contentPadding = PaddingValues(16.dp), - selectedUsers = selectedUsers, - autoScroll = true, - onUserRemoved = onUserDeselected, - ) - } - - - if (state is UserSearchResultState.Results) { - LazyColumn { - if (isMultiSelectionEnabled) { - items(state.results) { matrixUser -> - SearchMultipleUsersResultItem( - modifier = Modifier.fillMaxWidth(), - matrixUser = matrixUser, - isUserSelected = selectedUsers.find { it.userId == matrixUser.userId } != null, - onCheckedChange = { checked -> - if (checked) { - onUserSelected(matrixUser) - } else { - onUserDeselected(matrixUser) - } - } - ) - } - } else { - items(state.results) { matrixUser -> - SearchSingleUserResultItem( - modifier = Modifier.fillMaxWidth(), - matrixUser = matrixUser, - onClick = { onUserSelected(matrixUser) } - ) - } - } - } - } else if (state is UserSearchResultState.NoResults) { - Spacer(Modifier.size(80.dp)) - - Text( - text = stringResource(R.string.common_no_results), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.fillMaxWidth() - ) - } - }, - ) -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt index 03ba290829..eacdf82fb7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt @@ -18,8 +18,10 @@ package io.element.android.libraries.designsystem.components.preferences import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding @@ -45,6 +47,7 @@ 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.TopAppBar +@OptIn(ExperimentalLayoutApi::class) @Composable fun PreferenceView( title: String, @@ -69,6 +72,7 @@ fun PreferenceView( Column( modifier = Modifier .padding(it) + .consumeWindowInsets(it) .verticalScroll( state = scrollState, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index f0e9eaf906..8d91404d29 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -16,74 +16,216 @@ package io.element.android.libraries.designsystem.theme.components +import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +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.SearchBarColors +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SearchBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.ui.strings.R @OptIn(ExperimentalMaterial3Api::class) @Composable -fun SearchBar( +fun SearchBar( query: String, onQueryChange: (String) -> Unit, - onSearch: (String) -> Unit, active: Boolean, onActiveChange: (Boolean) -> Unit, + placeHolderTitle: String, modifier: Modifier = Modifier, enabled: Boolean = true, - placeholder: @Composable (() -> Unit)? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, + resultState: SearchBarResultState = SearchBarResultState.NotSearching(), shape: Shape = SearchBarDefaults.inputFieldShape, - colors: SearchBarColors = SearchBarDefaults.colors(), tonalElevation: Dp = SearchBarDefaults.Elevation, windowInsets: WindowInsets = SearchBarDefaults.windowInsets, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - content: @Composable ColumnScope.() -> Unit, + contentPrefix: @Composable ColumnScope.() -> Unit = {}, + contentSuffix: @Composable ColumnScope.() -> Unit = {}, + resultHandler: @Composable ColumnScope.(T) -> Unit = {}, ) { + val focusManager = LocalFocusManager.current + + if (!active) { + onQueryChange("") + focusManager.clearFocus() + } + androidx.compose.material3.SearchBar( query = query, onQueryChange = onQueryChange, - onSearch = onSearch, + onSearch = { focusManager.clearFocus() }, active = active, onActiveChange = onActiveChange, - modifier = modifier, + modifier = modifier.padding(horizontal = if (!active) 16.dp else 0.dp), enabled = enabled, - placeholder = placeholder, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, + 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 = { onActiveChange(false) }) } + } else { + null + }, + trailingIcon = when { + active && query.isNotEmpty() -> { + { + IconButton(onClick = { onQueryChange("") }) { + Icon(Icons.Default.Close, stringResource(R.string.action_clear)) + } + } + } + + !active -> { + { + Icon( + imageVector = Icons.Default.Search, + contentDescription = stringResource(R.string.action_search), + modifier = Modifier.alpha(0.4f), // FIXME align on Design system theme (removing alpha should be fine) + ) + } + } + + else -> null + }, shape = shape, - colors = colors, + colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), tonalElevation = tonalElevation, windowInsets = windowInsets, interactionSource = interactionSource, - content = content, + content = { + contentPrefix() + when (resultState) { + is SearchBarResultState.Results -> { + resultHandler(resultState.results) + } + + is SearchBarResultState.NoResults -> { + // No results found, show a message + Spacer(Modifier.size(80.dp)) + + Text( + text = stringResource(R.string.common_no_results), + textAlign = TextAlign.Center, + color = MaterialTheme.colorScheme.tertiary, + modifier = Modifier.fillMaxWidth() + ) + } + + else -> { + // Not searching - nothing to show. + } + } + contentSuffix() + }, + ) +} + +sealed interface SearchBarResultState { + /** No search results are available yet (e.g. because the user hasn't entered a search term). */ + class NotSearching : SearchBarResultState + + /** The search has completed, but no results were found. */ + class NoResults : SearchBarResultState + + /** The search has completed, and some matching users were found. */ + data class Results(val results: T) : SearchBarResultState +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewInactive() = ElementThemedPreview { ContentToPreview() } + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveEmptyQuery() = ElementThemedPreview { + ContentToPreview( + query = "", + active = true, ) } @Preview(group = PreviewGroup.Search) @Composable -internal fun SearchBarPreview() = ElementThemedPreview { ContentToPreview() } - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ContentToPreview() { - SearchBar( - query = "Some text", - onQueryChange = {}, - onSearch = {}, - active = false, - onActiveChange = {}, - content = {}, +internal fun SearchBarPreviewActiveWithQuery() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + ) +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveWithNoResults() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + resultState = SearchBarResultState.NoResults(), + ) +} + +@Preview(group = PreviewGroup.Search) +@Composable +internal fun SearchBarPreviewActiveWithContent() = ElementThemedPreview { + ContentToPreview( + query = "search term", + active = true, + resultState = SearchBarResultState.Results("result!"), + contentPrefix = { + Text(text = "Content that goes before the search results", modifier = Modifier.background(color = Color.Red).fillMaxWidth()) + }, + contentSuffix = { + Text(text = "Content that goes after the search results", modifier = Modifier.background(color = Color.Blue).fillMaxWidth()) + }, + resultHandler = { + Text(text = "Results go here", modifier = Modifier.background(color = Color.Green).fillMaxWidth()) + } + ) +} + +@Composable +private fun ContentToPreview( + query: String = "", + active: Boolean = false, + resultState: SearchBarResultState = SearchBarResultState.NotSearching(), + contentPrefix: @Composable ColumnScope.() -> Unit = {}, + contentSuffix: @Composable ColumnScope.() -> Unit = {}, + resultHandler: @Composable ColumnScope.(String) -> Unit = {}, +) { + SearchBar( + query = query, + active = active, + resultState = resultState, + onQueryChange = {}, + onActiveChange = {}, + placeHolderTitle = "Search for things", + contentPrefix = contentPrefix, + contentSuffix = contentSuffix, + resultHandler = resultHandler, ) } diff --git a/libraries/matrixui/build.gradle.kts b/libraries/matrixui/build.gradle.kts index 17d9522aeb..380f19f792 100644 --- a/libraries/matrixui/build.gradle.kts +++ b/libraries/matrixui/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { implementation(projects.libraries.matrix.api) implementation(projects.libraries.designsystem) implementation(projects.libraries.core) + implementation(projects.libraries.uiStrings) implementation(libs.coil.compose) ksp(libs.showkase.processor) 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 index 14ed5ef134..5c7a5eb458 100644 --- 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 @@ -26,11 +26,14 @@ 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.AvatarData 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.api.user.MatrixUser +import io.element.android.libraries.matrix.ui.model.getAvatarData +import io.element.android.libraries.matrix.ui.model.getBestName @Composable fun CheckableMatrixUserRow( @@ -40,18 +43,39 @@ fun CheckableMatrixUserRow( avatarSize: AvatarSize = AvatarSize.MEDIUM, onCheckedChange: (Boolean) -> Unit = {}, enabled: Boolean = true, -) { +) = CheckableUserRow( + checked = checked, + avatarData = matrixUser.getAvatarData(avatarSize), + name = matrixUser.getBestName(), + subtext = if (matrixUser.displayName.isNullOrEmpty()) null else matrixUser.userId.value, + modifier = modifier, + onCheckedChange = onCheckedChange, + enabled = enabled, +) +@Composable +fun CheckableUserRow( + checked: Boolean, + avatarData: AvatarData, + name: String, + subtext: String?, + modifier: Modifier = Modifier, + onCheckedChange: (Boolean) -> Unit = {}, + enabled: Boolean = true, +) { Row( modifier = modifier .fillMaxWidth() - .clickable(role = Role.Checkbox) { onCheckedChange(!checked) }, + .clickable(role = Role.Checkbox, enabled = enabled) { + onCheckedChange(!checked) + }, verticalAlignment = Alignment.CenterVertically, ) { - MatrixUserRow( + UserRow( modifier = Modifier.weight(1f), - matrixUser = matrixUser, - avatarSize = avatarSize, + avatarData = avatarData, + name = name, + subtext = subtext, ) Checkbox( @@ -77,5 +101,7 @@ private fun ContentToPreview(matrixUser: MatrixUser) { Column { CheckableMatrixUserRow(checked = true, matrixUser) CheckableMatrixUserRow(checked = false, matrixUser) + CheckableMatrixUserRow(checked = true, matrixUser, enabled = false) + CheckableMatrixUserRow(checked = false, matrixUser, enabled = false) } } 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 721682f3a3..0ad787b79b 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 @@ -33,6 +33,7 @@ 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.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight @@ -46,6 +47,19 @@ fun MatrixUserRow( matrixUser: MatrixUser, modifier: Modifier = Modifier, avatarSize: AvatarSize = AvatarSize.MEDIUM, +) = UserRow( + avatarData = matrixUser.getAvatarData(avatarSize), + name = matrixUser.getBestName(), + subtext = if (matrixUser.displayName.isNullOrEmpty()) null else matrixUser.userId.value, + modifier = modifier, +) + +@Composable +fun UserRow( + avatarData: AvatarData, + name: String, + subtext: String?, + modifier: Modifier = Modifier, ) { Row( modifier = modifier @@ -54,9 +68,7 @@ fun MatrixUserRow( .height(IntrinsicSize.Min), verticalAlignment = Alignment.CenterVertically ) { - Avatar( - matrixUser.getAvatarData(size = avatarSize), - ) + Avatar(avatarData) Column( modifier = Modifier .padding(start = 12.dp), @@ -65,15 +77,15 @@ fun MatrixUserRow( Text( fontSize = 16.sp, fontWeight = FontWeight.SemiBold, - text = matrixUser.getBestName(), + text = name, maxLines = 1, overflow = TextOverflow.Ellipsis, color = MaterialTheme.colorScheme.primary, ) // Id - if (matrixUser.displayName.isNullOrEmpty().not()) { + subtext?.let { Text( - text = matrixUser.userId.value, + text = subtext, color = MaterialTheme.colorScheme.secondary, fontSize = 14.sp, maxLines = 1, diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt similarity index 92% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt rename to libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt index d43281bbb1..6d31666822 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUser.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUser.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -41,10 +41,9 @@ 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.Text import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.ui.components.aMatrixUser import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.getBestName -import io.element.android.libraries.ui.strings.R +import io.element.android.libraries.ui.strings.R as StringR @Composable fun SelectedUser( @@ -74,7 +73,7 @@ fun SelectedUser( ) { Icon( imageVector = Icons.Default.Close, - contentDescription = stringResource(id = R.string.action_remove), + contentDescription = stringResource(id = StringR.string.action_remove), tint = MaterialTheme.colorScheme.onPrimary, ) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt rename to libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt index c9279a3389..c9f819a3d5 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/components/SelectedUsersList.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SelectedUsersList.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api.components +package io.element.android.libraries.matrix.ui.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues @@ -30,11 +30,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import io.element.android.features.userlist.api.aListOfSelectedUsers import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList @Composable fun SelectedUsersList( @@ -82,6 +82,6 @@ internal fun SelectedUsersListDarkPreview() = ElementPreviewDark { ContentToPrev @Composable private fun ContentToPreview() { SelectedUsersList( - selectedUsers = aListOfSelectedUsers(), + selectedUsers = aMatrixUserList().take(6).toImmutableList(), ) } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index 849f306133..40468f8a05 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -85,14 +85,14 @@ "Report a bug" "Report submitted" "Search for someone" - "Search results" + "Search results" "Security" "Select your server" "Sending…" "Server not supported" "Server URL" "Settings" - "Starting chat…" + "Starting chat…" "Sticker" "Success" "Suggestions" diff --git a/features/userlist/api/build.gradle.kts b/libraries/usersearch/api/build.gradle.kts similarity index 70% rename from features/userlist/api/build.gradle.kts rename to libraries/usersearch/api/build.gradle.kts index fb994538f6..39b03bfe90 100644 --- a/features/userlist/api/build.gradle.kts +++ b/libraries/usersearch/api/build.gradle.kts @@ -13,20 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { - id("io.element.android-compose-library") - alias(libs.plugins.ksp) + id("io.element.android-library") } android { - namespace = "io.element.android.features.userlist.api" + namespace = "io.element.android.libraries.usersearch.api" } dependencies { implementation(projects.libraries.architecture) - implementation(projects.libraries.designsystem) - implementation(projects.libraries.uiStrings) implementation(projects.libraries.matrix.api) - implementation(projects.libraries.matrixui) - ksp(libs.showkase.processor) } diff --git a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt similarity index 94% rename from features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt rename to libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt index 0f579b48b7..f855e20861 100644 --- a/features/userlist/api/src/main/kotlin/io/element/android/features/userlist/api/UserListDataSource.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserListDataSource.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.userlist.api +package io.element.android.libraries.usersearch.api import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt similarity index 51% rename from features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt rename to libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt index f3b293c602..bbb124c3c5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/di/CreateRoomModule.kt +++ b/libraries/usersearch/api/src/main/kotlin/io/element/android/libraries/usersearch/api/UserRepository.kt @@ -14,22 +14,12 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl.di +package io.element.android.libraries.usersearch.api -import com.squareup.anvil.annotations.ContributesTo -import dagger.Binds -import dagger.Module -import io.element.android.features.createroom.impl.AllMatrixUsersDataSource -import io.element.android.features.userlist.api.UserListDataSource -import io.element.android.libraries.di.SessionScope -import javax.inject.Named +import io.element.android.libraries.matrix.api.user.MatrixUser +import kotlinx.coroutines.flow.Flow -@Module -@ContributesTo(SessionScope::class) -interface CreateRoomModule { - - @Binds - @Named("AllUsers") - fun bindAllUserListDataSource(dataSource: AllMatrixUsersDataSource): UserListDataSource +interface UserRepository { + suspend fun search(query: String): Flow> } diff --git a/features/userlist/impl/build.gradle.kts b/libraries/usersearch/impl/build.gradle.kts similarity index 61% rename from features/userlist/impl/build.gradle.kts rename to libraries/usersearch/impl/build.gradle.kts index 28fe788ffe..226860e86f 100644 --- a/features/userlist/impl/build.gradle.kts +++ b/libraries/usersearch/impl/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * 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. @@ -15,13 +15,12 @@ */ plugins { - id("io.element.android-compose-library") + id("io.element.android-library") alias(libs.plugins.anvil) - alias(libs.plugins.ksp) } android { - namespace = "io.element.android.features.userlist.impl" + namespace = "io.element.android.libraries.usersearch.impl" } anvil { @@ -29,28 +28,18 @@ anvil { } dependencies { - implementation(projects.anvilannotations) - anvil(projects.anvilcodegen) implementation(projects.libraries.core) implementation(projects.libraries.architecture) - implementation(projects.libraries.matrix.api) + implementation(projects.libraries.di) implementation(projects.libraries.matrixui) - implementation(projects.libraries.designsystem) - implementation(projects.libraries.elementresources) - implementation(projects.libraries.testtags) - implementation(projects.libraries.uiStrings) - api(projects.features.userlist.api) - ksp(libs.showkase.processor) + implementation(projects.libraries.matrix.api) + api(projects.libraries.usersearch.api) 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) - testImplementation(projects.features.userlist.test) - - androidTestImplementation(libs.test.junitext) + testImplementation(projects.libraries.usersearch.test) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt similarity index 79% rename from features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt rename to libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt index b79ccc1d5b..53985415f1 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSource.kt +++ b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSource.kt @@ -14,15 +14,18 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl +package io.element.android.libraries.usersearch.impl -import io.element.android.features.userlist.api.UserListDataSource +import com.squareup.anvil.annotations.ContributesBinding +import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource import javax.inject.Inject -class AllMatrixUsersDataSource @Inject constructor( +@ContributesBinding(SessionScope::class) +class MatrixUserListDataSource @Inject constructor( private val client: MatrixClient ) : UserListDataSource { override suspend fun search(query: String): List { diff --git a/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt new file mode 100644 index 0000000000..7577e8f6e8 --- /dev/null +++ b/libraries/usersearch/impl/src/main/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepository.kt @@ -0,0 +1,64 @@ +/* + * 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.usersearch.impl + +import com.squareup.anvil.annotations.ContributesBinding +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.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import javax.inject.Inject + +@ContributesBinding(SessionScope::class) +class MatrixUserRepository @Inject constructor( + private val dataSource: UserListDataSource +) : UserRepository { + + override suspend fun search(query: String): Flow> = flow { + // Manually add a fake result with the matrixId, if any + val isUserId = MatrixPatterns.isUserId(query) + if (isUserId) { + emit(listOf(MatrixUser(UserId(query)))) + } + + if (query.length >= MINIMUM_SEARCH_LENGTH) { + // Debounce + delay(DEBOUNCE_TIME_MILLIS) + + val results = dataSource.search(query).toMutableList() + + // If the query is a user ID and the result doesn't contain that user ID, query the profile information explicitly + if (isUserId && results.none { it.userId.value == query }) { + val getProfileResult: MatrixUser? = dataSource.getProfile(UserId(query)) + val profile = getProfileResult ?: MatrixUser(UserId(query)) + results.add(0, profile) + } + + emit(results) + } + } + + companion object { + private const val DEBOUNCE_TIME_MILLIS = 500L + private const val MINIMUM_SEARCH_LENGTH = 3 + } +} diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt similarity index 81% rename from features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt rename to libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt index 043ad06361..5dc42773d3 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/AllMatrixUsersDataSourceTest.kt +++ b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserListDataSourceTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.element.android.features.createroom.impl +package io.element.android.libraries.usersearch.impl import com.google.common.truth.Truth import io.element.android.libraries.matrix.api.core.UserId @@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import kotlinx.coroutines.test.runTest import org.junit.Test -internal class AllMatrixUsersDataSourceTest { +internal class MatrixUserListDataSourceTest { @Test fun `search - returns users on success`() = runTest { @@ -37,15 +37,21 @@ internal class AllMatrixUsersDataSourceTest { searchTerm = "test", result = Result.success( MatrixSearchUserResults( - results = listOf(aMatrixUserProfile(), aMatrixUserProfile(userId = A_USER_ID_2)), + results = listOf( + aMatrixUserProfile(), + aMatrixUserProfile(userId = A_USER_ID_2) + ), limited = false ) ) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val results = dataSource.search("test") - Truth.assertThat(results).containsExactly(aMatrixUserProfile(), aMatrixUserProfile(userId = A_USER_ID_2)) + Truth.assertThat(results).containsExactly( + aMatrixUserProfile(), + aMatrixUserProfile(userId = A_USER_ID_2) + ) } @Test @@ -55,7 +61,7 @@ internal class AllMatrixUsersDataSourceTest { searchTerm = "test", result = Result.failure(Throwable("Ruhroh")) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val results = dataSource.search("test") Truth.assertThat(results).isEmpty() @@ -68,7 +74,7 @@ internal class AllMatrixUsersDataSourceTest { userId = A_USER_ID, result = Result.success(aMatrixUserProfile()) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val result = dataSource.getProfile(A_USER_ID) Truth.assertThat(result).isEqualTo(aMatrixUserProfile()) @@ -81,7 +87,7 @@ internal class AllMatrixUsersDataSourceTest { userId = A_USER_ID, result = Result.failure(Throwable("Ruhroh")) ) - val dataSource = AllMatrixUsersDataSource(matrixClient) + val dataSource = MatrixUserListDataSource(matrixClient) val result = dataSource.getProfile(A_USER_ID) Truth.assertThat(result).isNull() diff --git a/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt new file mode 100644 index 0000000000..e2eab067e6 --- /dev/null +++ b/libraries/usersearch/impl/src/test/kotlin/io/element/android/libraries/usersearch/impl/MatrixUserRepositoryTest.kt @@ -0,0 +1,140 @@ +/* + * 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.usersearch.impl + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.test.A_USER_ID +import io.element.android.libraries.matrix.test.A_USER_NAME +import io.element.android.libraries.matrix.ui.components.aMatrixUserList +import io.element.android.libraries.usersearch.test.FakeUserListDataSource +import kotlinx.coroutines.test.runTest +import org.junit.Test + +internal class MatrixUserRepositoryTest { + + @Test + fun `search - emits nothing if the search query is too short`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("x") + + result.test { + awaitComplete() + } + } + + @Test + fun `search - returns empty list if no results are found`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("some query") + + result.test { + assertThat(awaitItem()).isEmpty() + awaitComplete() + } + } + + @Test + fun `search - returns users if results are found`() = runTest { + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(aMatrixUserList()) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search("some query") + + result.test { + assertThat(awaitItem()).isEqualTo(aMatrixUserList()) + awaitComplete() + } + } + + @Test + fun `search - immediately returns placeholder if search is mxid`() = runTest { + val dataSource = FakeUserListDataSource() + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + assertThat(awaitItem()).isEqualTo(listOf(MatrixUser(userId = A_USER_ID))) + skipItems(1) + awaitComplete() + } + } + + @Test + fun `search - does not change results if they contain searched mxid`() = runTest { + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(searchResults) + awaitComplete() + } + } + + @Test + fun `search - gets profile results if searched mxid not in results`() = runTest { + val userProfile = MatrixUser(userId = A_USER_ID, displayName = A_USER_NAME) + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + dataSource.givenUserProfile(userProfile) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(listOf(userProfile) + searchResults) + awaitComplete() + } + } + + @Test + fun `search - just shows id if profile can't be loaded`() = runTest { + val searchResults = aMatrixUserListWithoutUserId(A_USER_ID) + + val dataSource = FakeUserListDataSource() + dataSource.givenSearchResult(searchResults) + dataSource.givenUserProfile(null) + val repository = MatrixUserRepository(dataSource) + + val result = repository.search(A_USER_ID.value) + + result.test { + skipItems(1) + assertThat(awaitItem()).isEqualTo(listOf(MatrixUser(userId = A_USER_ID)) + searchResults) + awaitComplete() + } + } + + private fun aMatrixUserListWithoutUserId(userId: UserId) = aMatrixUserList().filterNot { it.userId == userId } + +} diff --git a/features/userlist/test/build.gradle.kts b/libraries/usersearch/test/build.gradle.kts similarity index 78% rename from features/userlist/test/build.gradle.kts rename to libraries/usersearch/test/build.gradle.kts index a064038665..dc8a0b3d69 100644 --- a/features/userlist/test/build.gradle.kts +++ b/libraries/usersearch/test/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * 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. @@ -13,18 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { - id("io.element.android-compose-library") + id("io.element.android-library") } android { - namespace = "io.element.android.features.userlist.test" + namespace = "io.element.android.libraries.usersearch" } dependencies { implementation(projects.libraries.architecture) implementation(projects.libraries.matrixui) implementation(projects.libraries.matrix.api) - api(projects.features.userlist.api) - api(libs.coroutines.core) + api(projects.libraries.usersearch.api) } diff --git a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt similarity index 90% rename from features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt rename to libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt index 1f656e388f..d5f5183a4f 100644 --- a/features/userlist/test/src/main/kotlin/io/element/android/features/userlist/test/FakeUserListDataSource.kt +++ b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserListDataSource.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.element.android.features.userlist.test +package io.element.android.libraries.usersearch.test -import io.element.android.features.userlist.api.UserListDataSource import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserListDataSource class FakeUserListDataSource : UserListDataSource { diff --git a/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt new file mode 100644 index 0000000000..ea0d93a197 --- /dev/null +++ b/libraries/usersearch/test/src/main/kotlin/io/element/android/libraries/usersearch/test/FakeUserRepository.kt @@ -0,0 +1,40 @@ +/* + * 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.usersearch.test + +import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.usersearch.api.UserRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow + +class FakeUserRepository : UserRepository { + + var providedQuery: String? = null + private set + + private val flow = MutableSharedFlow>() + + override suspend fun search(query: String): Flow> { + providedQuery = query + return flow + } + + suspend fun emitResult(result: List) { + flow.emit(result) + } + +} diff --git a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt index 962cb2c18d..e7023ad88e 100644 --- a/plugins/src/main/kotlin/extension/DependencyHandleScope.kt +++ b/plugins/src/main/kotlin/extension/DependencyHandleScope.kt @@ -90,6 +90,7 @@ fun DependencyHandlerScope.allLibrariesImpl() { implementation(project(":libraries:statemachine")) implementation(project(":libraries:mediapickers:impl")) implementation(project(":libraries:mediaupload:impl")) + implementation(project(":libraries:usersearch:impl")) } fun DependencyHandlerScope.allServicesImpl() { diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_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.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png index a7e6d29b5f..efe83873c0 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_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.createroom.impl.components_null_DefaultGroup_AvatarDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbfbfa08085539bbfa4f20bc5d149bf0db0036169a32747c96f956d0d0f4b42d -size 93741 +oid sha256:b7787897d8dda469f17da7151260f26b6dcc5500f93ce44fb317af42ae8d457c +size 93739 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_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.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png index e278779a22..6dae242f3c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_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.createroom.impl.components_null_DefaultGroup_AvatarLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e0ba60e784a0dc582826a3f5679a6015531dc9aca22617ec1e0dede38b97f30 -size 93678 +oid sha256:6691512398d2c7e319d15397120054f1c2aae452ffed0be47df72ecb906ac4fa +size 93675 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_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.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_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.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchMultipleUsersResultItemLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_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.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_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.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_SearchSingleUserResultItemLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_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.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,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.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_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.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,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.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,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.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.components_null_DefaultGroup_UserListViewLightPreview_0_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_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.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index ca85a9b25c..964891e6d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_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.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79 -size 492165 +oid sha256:44313efc4d87857b9eb0bb05c8d24330b17353fd95344bcce06c1ad1bba8df81 +size 492167 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_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.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index ca85a9b25c..964891e6d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_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.messages.impl.timeline.components.event_null_DefaultGroup_TimelineItemImageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:766b2d44b51a36d1b15d8a39434ce5237f8427d1150f9b4c1255043fc1e4bb79 -size 492165 +oid sha256:44313efc4d87857b9eb0bb05c8d24330b17353fd95344bcce06c1ad1bba8df81 +size 492167 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 7d93e5c715..17e1d2852a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3443f60b8ceec7eccfee92c1bca8cad151e25cff8e7845459a5f4c3d50e5e08 -size 3330 +oid sha256:523d6607d70a331d2ec32aeabf033d59c4dc60e0e7373982893df0245ae924ce +size 3332 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 7b025a402e..abfa1dae68 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0b0cdb7e39d5ca5ce874477da4397ebed00ecf9f5d8980f9f3b03ab72259d9f -size 4000 +oid sha256:266490a1bdce29ac65d875543deda072d7f2a9aa2e216efb0d54b93c2a11aa5f +size 4001 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 7d93e5c715..17e1d2852a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3443f60b8ceec7eccfee92c1bca8cad151e25cff8e7845459a5f4c3d50e5e08 -size 3330 +oid sha256:523d6607d70a331d2ec32aeabf033d59c4dc60e0e7373982893df0245ae924ce +size 3332 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 7b025a402e..abfa1dae68 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0b0cdb7e39d5ca5ce874477da4397ebed00ecf9f5d8980f9f3b03ab72259d9f -size 4000 +oid sha256:266490a1bdce29ac65d875543deda072d7f2a9aa2e216efb0d54b93c2a11aa5f +size 4001 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png index eb0f1bcfde..66a540e8a7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d35eb1aac0d413c216dc77f45f655be97ae9d36c3cade57ee8f70e25c44fafd1 -size 3142 +oid sha256:e94515b43bc4b8427edc60456ec657ec38b33539a034a2c45c92624a6b75d4e8 +size 3138 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png index 69b558a480..6a087cd16c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:782a439312e4b616a6dd3020d8c99d04042208b2ebc416fab73c95344adeba67 -size 3834 +oid sha256:a4dc928a04bfc6331673be2fa0bf7f12e384dfd8ff91b07dc57b220c8dbbdd71 +size 3829 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png index eb0f1bcfde..66a540e8a7 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d35eb1aac0d413c216dc77f45f655be97ae9d36c3cade57ee8f70e25c44fafd1 -size 3142 +oid sha256:e94515b43bc4b8427edc60456ec657ec38b33539a034a2c45c92624a6b75d4e8 +size 3138 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png index 69b558a480..6a087cd16c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:782a439312e4b616a6dd3020d8c99d04042208b2ebc416fab73c95344adeba67 -size 3834 +oid sha256:a4dc928a04bfc6331673be2fa0bf7f12e384dfd8ff91b07dc57b220c8dbbdd71 +size 3829 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png index d6eab0d361..89034f66b9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_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.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cab21ee595c96700e4577554f9c98fdc56a59bf5093aa9d81a54d10381ba122 -size 6065 +oid sha256:25d0334932490997d432115c550c42e74e7226399ef82031430bf86ba33972bd +size 6066 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png index 70722aa53f..c407012dfd 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_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.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9235621126fe90a51d557df616878d53120dada814830fba006b54f1556e69e -size 5895 +oid sha256:a2d15387248308e5234c84b9b2b282e736f05f0495c80807bacfb0acff31eb2b +size 5890 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index b11864d276..3fc91b65e4 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:562e83b7771ff2209c7882180af55a8f3123c12c020b294858b1b46bff8a8a95 -size 30928 +oid sha256:5315b975f8b9def0b0d7575160cb34300511f1b83845ee2d1762188481cf6fe9 +size 30927 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index a55c0f8cdc..7a61ecf737 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79b16cbbbf36e6de4ea6270476371c7097424b26d4066f7156738c084fe061de +oid sha256:099401d03621aca301d3c4590d90ba4e4642d400d7603a8e15140a1bfef0c0ec size 42758 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index f1bd1303ce..e361e4a2d2 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7534d8379a1ab220833b8c877f9b3021a665cdb97c71ba383695276d83757702 -size 32721 +oid sha256:ca5dbc3aa00d6116de38fc0217b20ab0db4096b1f76bcc18b43ab9fd343f8110 +size 32722 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index 2fa40047c6..42f22c9a26 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3123fce3d4e4ed0480d2757e4daa70ecd14ddad1e8471523638561cccbab8dc -size 44568 +oid sha256:6211ec07d10d48e4713206e4c1fe24eae890fe2310d5bcc1f4ca54cc57f84ec9 +size 44564 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png index d0b80fcd37..b974aec366 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32d8032b1b2b3ae2b2795dea60b6395104df24790450f9452bbe82e81d9e62e8 -size 28911 +oid sha256:8ac7985e70782a84fc351cb15536bfd700ca8d6d48d5da0ee9dcaf5c78226479 +size 28909 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png index c14452b104..cf23661de1 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abff6db46d39ec39f3c0d5366f91252b58cbf62e6850bc86a6e81e52c80ba096 -size 45979 +oid sha256:c99138940ed1a8beac7da3c673600016a03b87195e07f205d5d389ef05be0fb0 +size 45978 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index 3123c5dd15..20f62bf8e6 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34469e4b86a441fb6f7cfbdce4b622109c093a234ae5d35d895dce35ef10c20c -size 30327 +oid sha256:2f24112ad89e5ef93917d45e3232043168d5092ce6d62a7d414773dd0afda963 +size 30326 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 6d5c269d4c..534402d370 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11c677ab3124a94f531f1db14eb2b2f19a493470620f7375cf7c1d14056cdbc9 -size 42429 +oid sha256:9c696c464515873a94d28f8909dc47255717fc3b012ce0d80000769714e3cb9c +size 42427 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index 3b8db29b08..88014ea46b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a35878a3d306b1a6d1768669904ee1f9e0a71abd4ab3c04ff6564027732614f -size 32077 +oid sha256:0fe506e4e7adbfe19fd48f0a40c19343471e0bb06e12fac8d5e6d54595e7193a +size 32076 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 816518f7aa..e70fa9d639 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1b3b0b538dafa85849c6e255bcff6b1a82a52d49be1fe4ded9b7f7c2ec06bff -size 44431 +oid sha256:c9c9374c303c9a71b0526fccfd18903d145c1b3b0059de3ccd41cf80f1541a80 +size 44427 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png index 25f8d272a1..4ebc61d047 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef18369400f738e94c5a812dc0ec4c8473659eafb11d7361385647ba6a640d15 -size 28320 +oid sha256:5f18d8b33eace857f78b92eed035621125bbfca1f0d43e5e47fd1c3965324de0 +size 28319 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png index 49caf143da..336334e955 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_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.messages.impl.timeline_null_DefaultGroup_TimelineViewLightPreview_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:633210082fc83be3628250fa35768969aad136035924667bd2f3c6c8307fd87c -size 45641 +oid sha256:be0722a804c2fc264f931f8784635bceab7ddcf08e378bed8ea510bd76813fbf +size 45642 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 580da9ceb6..1ba319f8ee 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01f54909964a4ed07d8850ab2bffad8b99ed641d731c1808b04f164ff3e0cbba -size 39632 +oid sha256:b77478183675fd3bb9a7ef34ef808e3ad75b504a0236b4dcb0d96a7faafc29cc +size 39629 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index ff59a95d62..27b4e07cb9 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ea39fdf1cb61657bc1eafb7d353ee15517c26c0e6bb2804b7c8350fa651299e -size 41508 +oid sha256:2645c93a097d35725a7afb83c97dd0ea6b5623990cbae2372aaf66c9011e353c +size 41506 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png index 1d82aaf60b..dee6d7dd1a 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7d7470933e27c64182c5f8acec7b4ce3896db1cc3836ff6aa6cf33fe8688f10 +oid sha256:394ffe0b730e7d4010ec0d7f96b5487b2775e70aa7e42b6bf8b2535ad5acc244 size 37524 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png index a943b1245f..4aa436dc8c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_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.messages.impl_null_DefaultGroup_MessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ac05963f89ac0d3045700447a40a4a6f38cc155812de7eb9a87fb9a01643033 -size 36300 +oid sha256:b87be006b0125029391e74a09bc2a07a906c33d9ea21ca17f884f2d8862af32a +size 36302 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index a24d98a08c..c3e23147ca 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6c558d2a8e6adb4831b91aff249d16dfc48389adef5ada6e1215df1d597639a -size 38654 +oid sha256:93f8dd057f245d454a6ebf81607c879b6ae4c20287a64d001bee36764e0802a5 +size 38657 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 549011130b..c3d01356c6 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:946802d97d29f9fe41a71f1ee343e298e1b0d9dbbc6561cc82fed712e623f89c +oid sha256:2a4ce62d7f8f27128fd59cd3e7eea068a002d7e2c0a054fef1f555d06cf91ebe size 40708 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png index 3586f9c218..4660650dfb 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97f10ca5290a0b4b1e034e157abb0f069fac2f2c2e88234edb1efc25c6c111f0 -size 36228 +oid sha256:bee8752a24938844cae76aadae9148a19001302a9e4909cf69a192a98d583ba4 +size 36230 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png index 8866feaf6f..6e04daf76b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl_null_DefaultGroup_MessagesViewLightPreview_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.messages.impl_null_DefaultGroup_MessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfc76bb6a8d8b269f53c2cc1c369a5c5ffb0f0fb858ebfa50c613a793bc1b421 -size 35195 +oid sha256:8f89eebcabe514594c53e6e436ae63685e6b693628f2acf796c6306298aff1a8 +size 35199 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_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.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png index 9749477ebd..b1f708d57c 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_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.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c820bd324df729db08710d1a6c17ca34a451a3bb94da2206fc57d6b4efe91e2f -size 60019 +oid sha256:b53d55b5085673ac3a0a7663f7ff68e7d510fe352f3931b49c7e75e4c3767b93 +size 60007 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_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.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png index f24edcc4a1..d020b1e521 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_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.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da2f9f87d89382b4b18d39a477a8e86f98067e2326adae4def8374b5bf09f316 -size 57588 +oid sha256:a761318f3dfbc2ce6e777cfabc19eeb2f89100ae7631660f4b4d7550cd947c84 +size 57580 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 07451a0330..01ec8ec0fc 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:628f1f00dca9d15faabd8288a3c54b1b8581a380cf14edf364f0dee9ecc187d5 +oid sha256:147786f2cfcf7674147253cca5e41b4af96587a27216076a1c0802c81b0b1b46 size 180117 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png index 8146c241cb..a49d11835b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_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.rageshake.impl.bugreport_null_DefaultGroup_BugReportViewLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:827bccb0fdd3106fb24a95d665b4da2cfc15de48e8f508ae809c9f75d6d1bbf0 -size 178915 +oid sha256:789a979f7207531b4b9ba488ae2de52e6046809e788baf6690e1383a933cf624 +size 178916 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..030fb820b7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveEmptyQuery_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4cbf23d459e0eb3bbe1e368ab481d7f5eed081b509e4e14e609cb39cfcf48be8 +size 7740 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..34fa9c6c48 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithContent_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cfe71589b04ee2842891d156144c8ba5fdce9cc45e598a29c6fb88a9ba7b0a2 +size 23703 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8a1696e8d5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithNoResults_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b9511f6e2d61f6779c5a7e5de2086ccb6cf262a40892d513432deddf852adf3 +size 9971 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2b3c997070 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewActiveWithQuery_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36b46cd1c92f38e10d6590d388d5d63f93b1bb594646c4a237912f1a6ca95aee +size 7929 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7b91e01600 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreviewInactive_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4844839df09fe09a60136fc284e0d17047e162852c82a00c71a1c799587dd3d8 +size 24687 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_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.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index d1f5f87768..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Searchviews_SearchBarPreview_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0b6a919d51f99281574b6b337614c14e120f0496c4e3616db2e75283ea282cc0 -size 20655 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 index 3dfe0d733a..9ee0c6f7da 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:30c90c24433d78554597a31fd1219ca3ad5538343b56b6ca32812f66757fa26e -size 53630 +oid sha256:928ca6703262b25b95c5db3e57683d1ca93e52a56919f5b49be2bce2048c7f81 +size 108583 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 index c3461af285..e3a85d6ed2 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da34205fab6387e76410a05efa0ea509d8a6b1b051628847b7420abf6c58d12d -size 52180 +oid sha256:48cd12b8a729b9d05f2fc85eb5eda8f0df3a29e45d3a7d5f64d087e1d48cfbc2 +size 104207 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 index ef64232112..09ab29f73d 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a31c217b10467f987d9fa0c387a32b493ff07eb0891715406f141b5f3dd447bf -size 52045 +oid sha256:8ee67026a3d030a6aeec422866e75dae820853dcb1108b34a060d6020865a35e +size 104725 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 index 9ee1c0e61b..8b550991ad 100644 --- 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 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56af20b122a1cda4f472b572f71a6f1411d759855f81ed99f24448d43739133c -size 50292 +oid sha256:f33ca29caddd1134e4d94f823ee5a9ac307ac9ec6806fd1910aef96b3d39c39b +size 100419 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_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.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_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.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUserLightPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_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.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListDarkPreview_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_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.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.userlist.api.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.matrix.ui.components_null_DefaultGroup_SelectedUsersListLightPreview_0_null,NEXUS_5,1.0,en].png From ab9f58446e2bb272ba0b38617c1d862ac2c8aaf2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 12:29:26 +0200 Subject: [PATCH 32/33] Update dependency org.robolectric:robolectric to v4.10.3 (#434) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8e5ac0ba87..76435c8e18 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -115,7 +115,7 @@ test_orchestrator = "androidx.test:orchestrator:1.4.2" test_turbine = "app.cash.turbine:turbine:0.12.3" test_truth = "com.google.truth:truth:1.1.3" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.11" -test_robolectric = "org.robolectric:robolectric:4.10.2" +test_robolectric = "org.robolectric:robolectric:4.10.3" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } # Others From 882a155f07acd15c482bcfda11b1691d7c8158f4 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 22 May 2023 17:52:31 +0200 Subject: [PATCH 33/33] Try to fix flaky test by setting a longer timeout in runTest (#442) --- .../impl/detection/RageshakeDetectionPresenterTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt index 369cb0833b..869f0412cd 100644 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/detection/RageshakeDetectionPresenterTest.kt @@ -85,7 +85,7 @@ class RageshakeDetectionPresenterTest { } @Test - fun `present - screenshot with success then dismiss`() = runTest { + fun `present - screenshot with success then dismiss`() = runTest(timeout = 30.seconds) { val screenshotHolder = FakeScreenshotHolder(screenshotUri = null) val rageshake = FakeRageShake(isAvailableValue = true) val rageshakeDataStore = FakeRageshakeDataStore(isEnabled = true) @@ -99,7 +99,7 @@ class RageshakeDetectionPresenterTest { ) moleculeFlow(RecompositionClock.Immediate) { presenter.present() - }.test(timeout = 30.seconds) { + }.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.isStarted).isFalse()