Show the alias or the direct message user's Matrix ID in the room picker

The forward and share room picker showed only a display name, so several
direct messages or rooms sharing a name were indistinguishable.

Render a secondary line: the canonical alias when the room has one, otherwise
the other person's Matrix ID for a direct message. No model change was needed,
because heroes is populated only for a direct message with exactly one hero,
so heroes.singleOrNull() is the peer.
This commit is contained in:
hayaksi1
2026-08-09 15:09:59 +03:00
parent 044737a3a7
commit ed82505946
3 changed files with 75 additions and 3 deletions
@@ -13,6 +13,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.ui.components.aMatrixUser
import io.element.android.libraries.matrix.ui.components.aSelectRoomInfo
import io.element.android.libraries.matrix.ui.model.SelectRoomInfo
import io.element.android.libraries.roomselect.api.RoomSelectMode
@@ -79,5 +80,12 @@ internal fun aRoomSelectRoomList() = persistentListOf(
),
aSelectRoomInfo(
roomId = RoomId("!room3:domain"),
name = "Alice",
heroes = persistentListOf(
aMatrixUser(id = "@alice:example.org", displayName = "Alice"),
),
),
aSelectRoomInfo(
roomId = RoomId("!room4:domain"),
),
)
@@ -260,10 +260,10 @@ private fun RoomSummaryView(
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
// Alias
roomInfo.canonicalAlias?.let { alias ->
val subtitle = roomInfo.canonicalAlias?.value ?: roomInfo.heroes.singleOrNull()?.userId?.value
if (subtitle != null) {
Text(
text = alias.value,
text = subtitle,
color = ElementTheme.colors.textSecondary,
style = ElementTheme.typography.fontBodySmRegular,
maxLines = 1,
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
@file:OptIn(ExperimentalTestApi::class)
package io.element.android.libraries.roomselect.impl
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.AndroidComposeUiTest
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.tests.testutils.EnsureNeverCalled
import io.element.android.tests.testutils.EnsureNeverCalledWithParam
import io.element.android.tests.testutils.robolectric.RobolectricTest
import org.junit.Test
import org.robolectric.annotation.Config
class RoomSelectViewTest : RobolectricTest() {
@Config(qualifiers = "h1024dp")
@Test
fun `a room with a canonical alias renders the alias`() = runAndroidComposeUiTest {
setRoomSelectView(
aRoomSelectState(
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
),
)
onNodeWithText("Room with alias").assertIsDisplayed()
onNodeWithText("#alias:example.org").assertIsDisplayed()
}
@Config(qualifiers = "h1024dp")
@Test
fun `a direct message without alias renders the matrix id of the other user`() = runAndroidComposeUiTest {
setRoomSelectView(
aRoomSelectState(
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
),
)
onNodeWithText("Alice").assertIsDisplayed()
onNodeWithText("@alice:example.org").assertIsDisplayed()
}
}
private fun AndroidComposeUiTest<ComponentActivity>.setRoomSelectView(
state: RoomSelectState,
onDismiss: () -> Unit = EnsureNeverCalled(),
onSubmit: (List<RoomId>) -> Unit = EnsureNeverCalledWithParam(),
) {
setContent {
RoomSelectView(
state = state,
onDismiss = onDismiss,
onSubmit = onSubmit,
)
}
}