Show result when searching for matrix id

This commit is contained in:
Florian Renaud
2023-03-09 18:46:57 +01:00
parent 567ff3eb15
commit 33890aca70
6 changed files with 63 additions and 15 deletions

View File

@@ -17,6 +17,7 @@
package io.element.android.features.createroom.impl.root
sealed interface CreateRoomRootEvents {
data class UpdateSearchQuery(val query: String): CreateRoomRootEvents
object CreateRoom : CreateRoomRootEvents
object InvitePeople : CreateRoomRootEvents
}

View File

@@ -17,7 +17,15 @@
package io.element.android.features.createroom.impl.root
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 com.bumble.appyx.core.collections.immutableListOf
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 javax.inject.Inject
class CreateRoomRootPresenter @Inject constructor() : Presenter<CreateRoomRootState> {
@@ -25,15 +33,27 @@ class CreateRoomRootPresenter @Inject constructor() : Presenter<CreateRoomRootSt
@Composable
override fun present(): CreateRoomRootState {
var searchQuery by rememberSaveable { mutableStateOf("") }
val searchResults = if (MatrixPatterns.isUserId(searchQuery)) {
immutableListOf(MatrixUser(UserId(searchQuery)))
} else {
immutableListOf()
}
fun handleEvents(event: CreateRoomRootEvents) {
when (event) {
CreateRoomRootEvents.CreateRoom -> Unit // Todo Handle create room action
CreateRoomRootEvents.InvitePeople -> Unit // Todo Handle invite people action
is CreateRoomRootEvents.UpdateSearchQuery -> {
searchQuery = event.query
}
}
}
return CreateRoomRootState(
eventSink = ::handleEvents
eventSink = ::handleEvents,
searchQuery = searchQuery,
searchResults = searchResults,
)
}
}

View File

@@ -16,8 +16,12 @@
package io.element.android.features.createroom.impl.root
// TODO add your ui models. Remove the eventSink if you don't have events.
import com.bumble.appyx.core.collections.ImmutableList
import io.element.android.libraries.matrix.ui.model.MatrixUser
// 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 searchQuery: String,
val searchResults: ImmutableList<MatrixUser>,
)

View File

@@ -17,6 +17,9 @@
package io.element.android.features.createroom.impl.root
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.bumble.appyx.core.collections.immutableListOf
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.ui.model.MatrixUser
open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRootState> {
override val values: Sequence<CreateRoomRootState>
@@ -27,5 +30,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRoot
}
fun aCreateRoomRootState() = CreateRoomRootState(
eventSink = {}
eventSink = {},
searchQuery = "@someone:example.org",
searchResults = immutableListOf(MatrixUser(UserId("@someone:example.org"))),
)

View File

@@ -45,6 +45,7 @@ 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
@@ -54,6 +55,8 @@ 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.Text
import io.element.android.libraries.matrix.ui.components.MatrixUserRow
import io.element.android.libraries.matrix.ui.model.MatrixUser
import io.element.android.libraries.designsystem.R as DrawableR
import io.element.android.libraries.ui.strings.R as StringR
@@ -64,7 +67,6 @@ fun CreateRoomRootView(
modifier: Modifier = Modifier,
onClosePressed: () -> Unit = {},
) {
var searchText by rememberSaveable { mutableStateOf("") }
var isSearchActive by rememberSaveable { mutableStateOf(false) }
Scaffold(
modifier = modifier.fillMaxWidth(),
@@ -80,11 +82,12 @@ fun CreateRoomRootView(
) {
CreateRoomSearchBar(
modifier = Modifier.fillMaxWidth(),
text = searchText,
query = state.searchQuery,
placeHolderTitle = stringResource(StringR.string.search_for_someone),
results = state.searchResults,
active = isSearchActive,
onActiveChanged = { isSearchActive = it },
onTextChanged = { searchText = it },
onTextChanged = { state.eventSink(CreateRoomRootEvents.UpdateSearchQuery(it)) },
)
if (!isSearchActive) {
@@ -123,8 +126,9 @@ fun CreateRoomRootViewTopBar(
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CreateRoomSearchBar(
text: String,
query: String,
placeHolderTitle: String,
results: List<MatrixUser>,
active: Boolean,
modifier: Modifier = Modifier,
onActiveChanged: (Boolean) -> Unit = {},
@@ -138,7 +142,7 @@ fun CreateRoomSearchBar(
}
DockedSearchBar(
query = text,
query = query,
onQueryChange = onTextChanged,
onSearch = { focusManager.clearFocus() },
active = active,
@@ -155,7 +159,7 @@ fun CreateRoomSearchBar(
{ BackButton(onClick = { onActiveChanged(false) }) }
} else null,
trailingIcon = when {
active && text.isNotEmpty() -> {
active && query.isNotEmpty() -> {
{
IconButton(onClick = { onTextChanged("") }) {
Icon(Icons.Default.Close, stringResource(StringR.string.a11y_clear))
@@ -175,7 +179,9 @@ fun CreateRoomSearchBar(
},
shape = if (!active) SearchBarDefaults.dockedShape else SearchBarDefaults.fullScreenShape,
colors = if (!active) SearchBarDefaults.colors() else SearchBarDefaults.colors(containerColor = Color.Transparent),
content = {},
content = {
results.forEach { CreateRoomSearchResultItem(matrixUser = it) }
},
)
}
@@ -199,6 +205,18 @@ fun CreateRoomActionButtonsList(
}
}
@Composable
fun CreateRoomSearchResultItem(
matrixUser: MatrixUser,
modifier: Modifier = Modifier,
) {
MatrixUserRow(
modifier = modifier.heightIn(min = 56.dp),
matrixUser = matrixUser,
avatarSize = AvatarSize.SMALL,
)
}
@Composable
fun CreateRoomActionButton(
@DrawableRes iconRes: Int,

View File

@@ -34,6 +34,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.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
@@ -45,6 +46,7 @@ import io.element.android.libraries.matrix.ui.model.getBestName
fun MatrixUserRow(
matrixUser: MatrixUser,
modifier: Modifier = Modifier,
avatarSize: AvatarSize = matrixUser.avatarData.size,
onClick: () -> Unit = {},
) {
Row(
@@ -56,13 +58,11 @@ fun MatrixUserRow(
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, end = 4.dp, top = 12.dp, bottom = 12.dp),
) {
// Name
Text(