diff --git a/changelog.d/211.wip b/changelog.d/211.wip new file mode 100644 index 0000000000..ccdceb1518 --- /dev/null +++ b/changelog.d/211.wip @@ -0,0 +1 @@ +[Create and join rooms] Show a single result when searching for a matrixId diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt index 2159caf0aa..ddf2003e83 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootEvents.kt @@ -16,7 +16,12 @@ package io.element.android.features.createroom.impl.root +import io.element.android.libraries.matrix.ui.model.MatrixUser + sealed interface CreateRoomRootEvents { + data class UpdateSearchQuery(val query: String) : CreateRoomRootEvents + data class StartDM(val matrixUser: MatrixUser) : CreateRoomRootEvents object CreateRoom : CreateRoomRootEvents object InvitePeople : CreateRoomRootEvents + data class OnSearchActiveChanged(val active: Boolean) : CreateRoomRootEvents } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt index 6ff99f421c..828f531211 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt @@ -17,23 +17,76 @@ package io.element.android.features.createroom.impl.root import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.core.MatrixPatterns +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import timber.log.Timber import javax.inject.Inject class CreateRoomRootPresenter @Inject constructor() : Presenter { @Composable override fun present(): CreateRoomRootState { + var isSearchActive by rememberSaveable { mutableStateOf(false) } + var searchQuery by rememberSaveable { mutableStateOf("") } + val searchResults: MutableState> = remember { + mutableStateOf(persistentListOf()) + } fun handleEvents(event: CreateRoomRootEvents) { when (event) { + is CreateRoomRootEvents.OnSearchActiveChanged -> isSearchActive = event.active + is CreateRoomRootEvents.UpdateSearchQuery -> searchQuery = event.query + is CreateRoomRootEvents.StartDM -> handleStartDM(event.matrixUser) CreateRoomRootEvents.CreateRoom -> Unit // Todo Handle create room action CreateRoomRootEvents.InvitePeople -> Unit // Todo Handle invite people action } } + LaunchedEffect(searchQuery) { + // Clear the search results before performing the search, manually add a fake result with the matrixId, if any + searchResults.value = if (MatrixPatterns.isUserId(searchQuery)) { + persistentListOf(MatrixUser(UserId(searchQuery))) + } else { + persistentListOf() + } + // Perform the search asynchronously + if (searchQuery.isNotEmpty()) { + searchResults.value = performSearch(searchQuery) + } + } + return CreateRoomRootState( - eventSink = ::handleEvents + eventSink = ::handleEvents, + isSearchActive = isSearchActive, + searchQuery = searchQuery, + searchResults = searchResults.value, ) } + + private fun performSearch(query: String): ImmutableList { + val isMatrixId = MatrixPatterns.isUserId(query) + val results = mutableListOf()// TODO trigger /search request + if (isMatrixId && results.none { it.id.value == query }) { + val getProfileResult: MatrixUser? = null // TODO trigger /profile request + val profile = getProfileResult ?: MatrixUser(UserId(query)) + results.add(0, profile) + } + return results.toImmutableList() + } + + private fun handleStartDM(matrixUser: MatrixUser) { + Timber.d("handleStartDM: $matrixUser") // Todo handle start DM action + } } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt index 3e47b322b7..be9757f122 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,8 +16,13 @@ package io.element.android.features.createroom.impl.root -// TODO add your ui models. Remove the eventSink if you don't have events. +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList + // Do not use default value, so no member get forgotten in the presenters. data class CreateRoomRootState( - val eventSink: (CreateRoomRootEvents) -> Unit + val eventSink: (CreateRoomRootEvents) -> Unit, + val isSearchActive: Boolean, + val searchQuery: String, + val searchResults: ImmutableList, ) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt index 4c3049d32f..5f050ab1cc 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,15 +17,43 @@ package io.element.android.features.createroom.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.persistentListOf open class CreateRoomRootStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aCreateRoomRootState(), - // Add other state here + aCreateRoomRootState().copy(isSearchActive = true), + aCreateRoomRootState().copy(isSearchActive = true, searchQuery = "someone"), + aCreateRoomRootState().copy( + isSearchActive = true, + searchQuery = "@someone:matrix.org", + searchResults = persistentListOf( + MatrixUser(id = UserId("@someone:matrix.org")), + MatrixUser(id = UserId("@someone:matrix.org"), username = "someone"), + MatrixUser( + id = UserId("@someone_with_a_very_long_matrix_identifier:a_very_long_domain.org"), + username = "hey, I am someone with a very long display name" + ), + MatrixUser(id = UserId("@someone_2:matrix.org"), username = "someone 2"), + MatrixUser(id = UserId("@someone_3:matrix.org"), username = "someone 3"), + MatrixUser(id = UserId("@someone_4:matrix.org"), username = "someone 4"), + MatrixUser(id = UserId("@someone_5:matrix.org"), username = "someone 5"), + MatrixUser(id = UserId("@someone_6:matrix.org"), username = "someone 6"), + MatrixUser(id = UserId("@someone_7:matrix.org"), username = "someone 7"), + MatrixUser(id = UserId("@someone_8:matrix.org"), username = "someone 8"), + MatrixUser(id = UserId("@someone_9:matrix.org"), username = "someone 9"), + MatrixUser(id = UserId("@someone_10:matrix.org"), username = "someone 10"), + ) + ), ) } fun aCreateRoomRootState() = CreateRoomRootState( - eventSink = {} + eventSink = {}, + isSearchActive = false, + searchQuery = "", + searchResults = persistentListOf(), ) 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 43662511f1..bab42c6964 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 @@ -22,18 +22,16 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Search import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SearchBarDefaults import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -45,15 +43,19 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.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.DockedSearchBar import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Scaffold +import io.element.android.libraries.designsystem.theme.components.SearchBar import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.matrix.ui.components.MatrixUserRow +import io.element.android.libraries.matrix.ui.model.MatrixUser +import kotlinx.collections.immutable.ImmutableList import io.element.android.libraries.designsystem.R as DrawableR import io.element.android.libraries.ui.strings.R as StringR @@ -64,12 +66,10 @@ fun CreateRoomRootView( modifier: Modifier = Modifier, onClosePressed: () -> Unit = {}, ) { - var searchText by rememberSaveable { mutableStateOf("") } - var isSearchActive by rememberSaveable { mutableStateOf(false) } Scaffold( modifier = modifier.fillMaxWidth(), topBar = { - if (!isSearchActive) { + if (!state.isSearchActive) { CreateRoomRootViewTopBar(onClosePressed = onClosePressed) } } @@ -80,14 +80,16 @@ fun CreateRoomRootView( ) { CreateRoomSearchBar( modifier = Modifier.fillMaxWidth(), - text = searchText, + query = state.searchQuery, placeHolderTitle = stringResource(StringR.string.search_for_someone), - active = isSearchActive, - onActiveChanged = { isSearchActive = it }, - onTextChanged = { searchText = it }, + results = state.searchResults, + active = state.isSearchActive, + onActiveChanged = { state.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(it)) }, + onTextChanged = { state.eventSink(CreateRoomRootEvents.UpdateSearchQuery(it)) }, + onResultSelected = { state.eventSink(CreateRoomRootEvents.StartDM(it)) } ) - if (!isSearchActive) { + if (!state.isSearchActive) { CreateRoomActionButtonsList( onNewRoomClicked = { state.eventSink(CreateRoomRootEvents.CreateRoom) }, onInvitePeopleClicked = { state.eventSink(CreateRoomRootEvents.InvitePeople) }, @@ -123,12 +125,14 @@ fun CreateRoomRootViewTopBar( @OptIn(ExperimentalMaterial3Api::class) @Composable fun CreateRoomSearchBar( - text: String, + query: String, placeHolderTitle: String, + results: ImmutableList, active: Boolean, modifier: Modifier = Modifier, onActiveChanged: (Boolean) -> Unit = {}, onTextChanged: (String) -> Unit = {}, + onResultSelected: (MatrixUser) -> Unit = {}, ) { val focusManager = LocalFocusManager.current @@ -137,8 +141,8 @@ fun CreateRoomSearchBar( focusManager.clearFocus() } - DockedSearchBar( - query = text, + SearchBar( + query = query, onQueryChange = onTextChanged, onSearch = { focusManager.clearFocus() }, active = active, @@ -153,9 +157,11 @@ fun CreateRoomSearchBar( }, leadingIcon = if (active) { { BackButton(onClick = { onActiveChanged(false) }) } - } else null, + } else { + null + }, trailingIcon = when { - active && text.isNotEmpty() -> { + active && query.isNotEmpty() -> { { IconButton(onClick = { onTextChanged("") }) { Icon(Icons.Default.Close, stringResource(StringR.string.a11y_clear)) @@ -173,9 +179,17 @@ fun CreateRoomSearchBar( } else -> null }, - shape = if (!active) SearchBarDefaults.dockedShape else SearchBarDefaults.fullScreenShape, colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent), - content = {}, + content = { + LazyColumn { + items(results) { + CreateRoomSearchResultItem( + matrixUser = it, + onClick = { onResultSelected(it) } + ) + } + } + }, ) } @@ -199,6 +213,20 @@ fun CreateRoomActionButtonsList( } } +@Composable +fun CreateRoomSearchResultItem( + matrixUser: MatrixUser, + modifier: Modifier = Modifier, + onClick: () -> Unit = {}, +) { + MatrixUserRow( + modifier = modifier, + matrixUser = matrixUser, + avatarSize = AvatarSize.Custom(36.dp), + onClick = onClick, + ) +} + @Composable fun CreateRoomActionButton( @DrawableRes iconRes: Int, @@ -209,7 +237,7 @@ fun CreateRoomActionButton( Row( modifier = modifier .fillMaxWidth() - .heightIn(min = 56.dp) + .height(56.dp) .clickable { onClick() } .padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), 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 e6c9155d88..c13d59f3a6 100644 --- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt +++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt @@ -22,8 +22,8 @@ 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.createroom.impl.root.CreateRoomRootEvents -import io.element.android.features.createroom.impl.root.CreateRoomRootPresenter +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.model.MatrixUser import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Test @@ -42,7 +42,7 @@ class CreateRoomRootPresenterTests { } @Test - fun `present - send event`() = runTest { + fun `present - trigger action buttons`() = runTest { val presenter = CreateRoomRootPresenter() moleculeFlow(RecompositionClock.Immediate) { presenter.present() @@ -52,4 +52,42 @@ class CreateRoomRootPresenterTests { initialState.eventSink(CreateRoomRootEvents.InvitePeople) // Not implemented yet } } + + @Test + fun `present - update search query`() = runTest { + val presenter = CreateRoomRootPresenter() + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + + initialState.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(true)) + assertThat(awaitItem().isSearchActive).isTrue() + + val matrixIdQuery = "@name:matrix.org" + initialState.eventSink(CreateRoomRootEvents.UpdateSearchQuery(matrixIdQuery)) + assertThat(awaitItem().searchQuery).isEqualTo(matrixIdQuery) + assertThat(awaitItem().searchResults).containsExactly(MatrixUser(UserId(matrixIdQuery))) + + val notMatrixIdQuery = "name" + initialState.eventSink(CreateRoomRootEvents.UpdateSearchQuery(notMatrixIdQuery)) + assertThat(awaitItem().searchQuery).isEqualTo(notMatrixIdQuery) + assertThat(awaitItem().searchResults).isEmpty() + + initialState.eventSink(CreateRoomRootEvents.OnSearchActiveChanged(false)) + assertThat(awaitItem().isSearchActive).isFalse() + } + } + + @Test + fun `present - trigger start DM action`() = runTest { + val presenter = CreateRoomRootPresenter() + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val matrixUser = MatrixUser(UserId("@name:matrix.org")) + initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser)) + } + } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 222d2a1502..06aa4435a0 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -94,7 +94,7 @@ private fun InitialsAvatar( Text( modifier = Modifier.align(Alignment.Center), text = avatarData.getInitial(), - fontSize = (avatarData.size.value / 2).sp, + fontSize = (avatarData.size.dp / 2).value.sp, color = Color.White, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 35689817b0..97069bab6f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -16,13 +16,16 @@ package io.element.android.libraries.designsystem.components.avatar +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -enum class AvatarSize(val value: Int) { - SMALL(32), - MEDIUM(40), - BIG(48), - HUGE(96); +sealed class AvatarSize(open val dp: Dp) { - val dp = value.dp + object SMALL : AvatarSize(32.dp) + object MEDIUM : AvatarSize(40.dp) + object BIG : AvatarSize(48.dp) + object HUGE : AvatarSize(96.dp) + + // FIXME maybe remove this field and switch back to an enum (or remove this class) when design system will be integrated + data class Custom(override val dp: Dp) : AvatarSize(dp) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DockedSearchBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt similarity index 91% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DockedSearchBar.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt index 100ae259f8..aa767e21ce 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DockedSearchBar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchBar.kt @@ -20,6 +20,7 @@ package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SearchBarColors import androidx.compose.material3.SearchBarDefaults @@ -34,7 +35,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight @OptIn(ExperimentalMaterial3Api::class) @Composable -fun DockedSearchBar( +fun SearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, @@ -45,13 +46,14 @@ fun DockedSearchBar( placeholder: @Composable (() -> Unit)? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, - shape: Shape = SearchBarDefaults.dockedShape, + shape: Shape = SearchBarDefaults.inputFieldShape, colors: SearchBarColors = SearchBarDefaults.colors(), tonalElevation: Dp = SearchBarDefaults.Elevation, + windowInsets: WindowInsets = SearchBarDefaults.windowInsets, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, content: @Composable ColumnScope.() -> Unit, ) { - androidx.compose.material3.DockedSearchBar( + androidx.compose.material3.SearchBar( query = query, onQueryChange = onQueryChange, onSearch = onSearch, @@ -65,6 +67,7 @@ fun DockedSearchBar( shape = shape, colors = colors, tonalElevation = tonalElevation, + windowInsets = windowInsets, interactionSource = interactionSource, content = content, ) @@ -80,7 +83,7 @@ internal fun DockedSearchBarDarkPreview() = ElementPreviewDark { ContentToPrevie @Composable private fun ContentToPreview() { - DockedSearchBar( + SearchBar( query = "Some text", onQueryChange = {}, onSearch = {}, 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 aaa5e35b16..035f2d3824 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 @@ -34,35 +34,34 @@ 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.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.Text import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.getBestName -// FIXME Row are not the same height if there is a name or not. @Composable fun MatrixUserRow( matrixUser: MatrixUser, modifier: Modifier = Modifier, + avatarSize: AvatarSize = matrixUser.avatarData.size, onClick: () -> Unit = {}, ) { Row( modifier = modifier .clickable(onClick = onClick) .fillMaxWidth() - .padding(horizontal = 16.dp) + .padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp) .height(IntrinsicSize.Min), verticalAlignment = Alignment.CenterVertically ) { Avatar( - matrixUser.avatarData, + matrixUser.avatarData.copy(size = avatarSize), ) Column( modifier = Modifier - .padding(start = 12.dp, end = 4.dp, top = 12.dp, bottom = 12.dp) - .alignByBaseline() - .weight(1f) + .padding(start = 12.dp), ) { // Name Text( diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataExt.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataExt.kt index 1392a1ff5c..6301503797 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataExt.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/media/AvatarDataExt.kt @@ -18,7 +18,8 @@ package io.element.android.libraries.matrix.ui.media import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.media.MediaResolver +import kotlin.math.roundToInt fun AvatarData.toMetadata(): MediaResolver.Meta { - return MediaResolver.Meta(url = url, kind = MediaResolver.Kind.Thumbnail(size.value)) + return MediaResolver.Meta(url = url, kind = MediaResolver.Kind.Thumbnail(size.dp.value.roundToInt())) } 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_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.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 50ca99cc2a..c963070276 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_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.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5451d8fb06cef9a346c92db43fa5994e39f3079b67b99d867a31d9b8a645cb0d -size 19198 +oid sha256:0161ce815927b9a7f21060d94a9e98cc67b832c945d7437848b118731aace5c4 +size 19221 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 new file mode 100644 index 0000000000..f13a65f8e2 --- /dev/null +++ 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 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89ea65099fb4981bbeb24e49afb7400b0e8da79e3b783e198519ba1e970404a8 +size 8317 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..74a7f599cd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a8ba207cf61c56b64c6855d04c8a30def0b3daf325adf57edd45b40981ed745 +size 7733 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..6d7f2c5d11 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6703f2cba99aa60bdf3ecd380a46846f0e1b95a0b2718ed707348b6bc1713b1 +size 107508 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_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.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png index deae75a4c1..00e81b473c 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_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.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:611b1efa9cf46316f96738130f326061595d2648ac7fb059df299e7c95f4e2a8 -size 18480 +oid sha256:07e26a6494155ad18acc5da1a9151ffb02910185a3d0a516884848d7b045e640 +size 18434 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 new file mode 100644 index 0000000000..eb23dcec96 --- /dev/null +++ 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 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8de2f28cf9918a7eddcc1311c34ba0376242a4708724b57689df000b7480524 +size 8197 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..e2e4a33e67 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:687133e4729ea42382ac0b76af6ceaf8b20cbc65923412fb97b077d2475c70f7 +size 7514 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..2746320bc2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8e1ca8a115c3e46c7f24fe41dc6c9448ffecc65a05c6be1945b84f35d60a099 +size 103642 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_DefaultGroup_DockedSearchBarDarkPreview_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_DefaultGroup_DockedSearchBarDarkPreview_0_null,NEXUS_5,1.0,en].png index 638282389c..71d010641b 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_DefaultGroup_DockedSearchBarDarkPreview_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_DefaultGroup_DockedSearchBarDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e89807d72107f1f8337e8de803791249b56bde6c4961805520195ea55563749a -size 8470 +oid sha256:5ba2ec897834fa0db2751c2c8a7b4427e278cf4711bed3fecf75937c080d42ba +size 8534 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_DefaultGroup_DockedSearchBarLightPreview_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_DefaultGroup_DockedSearchBarLightPreview_0_null,NEXUS_5,1.0,en].png index 2cc70fcb06..3fc73a2067 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_DefaultGroup_DockedSearchBarLightPreview_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_DefaultGroup_DockedSearchBarLightPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6381c125b8eaf6b116218bc4b0efda4866f19514139f4b45604909e462931c1f -size 8320 +oid sha256:75923126de5b769aa04de9214af14e3aec23e91b85f5a4c8d57c21025850ec1b +size 8358 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_MatrixUserRowDarkPreview_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_MatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png index 026e7a5402..385103eb68 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_MatrixUserRowDarkPreview_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_MatrixUserRowDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73594765454707aa2894d86432639edac0b59adaf554b0fe2fb7fc7e9976c4f8 -size 14445 +oid sha256:df97ab1093fd2c257f98b16fefeb28cc4a31747a7a9bda0725fa826a26c59906 +size 14299 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_MatrixUserRowDarkPreview_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_MatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png index 4beb170c1c..982c03bc9a 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_MatrixUserRowDarkPreview_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_MatrixUserRowDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e6ceaf1f7f7d8cd59327d7b88ba2136468de76542e84504a6ef689f0e58d896 -size 13695 +oid sha256:3b3649fa2543fd138246ac3281f491f2a0a1c9f38c977e57a840cd560038af2f +size 13782 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_MatrixUserRowLightPreview_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_MatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png index 3ea8ffa5f0..fbd698355c 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_MatrixUserRowLightPreview_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_MatrixUserRowLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ce4773eed490ebeb3ed46d534181afb90331ba1cbaab8ead7b192739beb29a6 -size 13681 +oid sha256:38556398b29c5230751f86b35b9e0b233c1ef4a84d1aa37928cc4d10a8062c9b +size 13567 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_MatrixUserRowLightPreview_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_MatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png index 1fc816818b..311836ee17 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_MatrixUserRowLightPreview_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_MatrixUserRowLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8a4a16c343f295a5270bb746024578dea8f3015ffe35a57b0ed667727d976e2 -size 13182 +oid sha256:e7a0cf84208247fe5a5a118a8e8133d79b875859a65788139b7c4459c575c5d8 +size 13226