Let SearchBar/SearchField use TextFieldState

This commit is contained in:
ganfra 2026-01-22 16:34:22 +01:00
parent 87619e50e8
commit fa1b32f0ba
48 changed files with 197 additions and 298 deletions

View file

@ -16,5 +16,4 @@ sealed interface RoomSelectEvents {
// TODO remove to restore multi-selection
data object RemoveSelectedRoom : RoomSelectEvents
data object ToggleSearchActive : RoomSelectEvents
data class UpdateQuery(val query: String) : RoomSelectEvents
}

View file

@ -8,6 +8,7 @@
package io.element.android.libraries.roomselect.impl
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
@ -42,12 +43,13 @@ class RoomSelectPresenter(
@Composable
override fun present(): RoomSelectState {
var selectedRooms by remember { mutableStateOf(persistentListOf<SelectRoomInfo>()) }
var searchQuery by remember { mutableStateOf("") }
val queryState = rememberTextFieldState()
var isSearchActive by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val dataSource = remember { dataSourceFactory.create(coroutineScope) }
val searchQuery = queryState.text.toString()
LaunchedEffect(searchQuery) {
dataSource.setSearchQuery(searchQuery)
}
@ -77,7 +79,6 @@ class RoomSelectPresenter(
// }
}
RoomSelectEvents.RemoveSelectedRoom -> selectedRooms = persistentListOf()
is RoomSelectEvents.UpdateQuery -> searchQuery = event.query
RoomSelectEvents.ToggleSearchActive -> isSearchActive = !isSearchActive
}
}
@ -85,7 +86,7 @@ class RoomSelectPresenter(
return RoomSelectState(
mode = mode,
resultState = searchResults,
query = searchQuery,
searchQuery = queryState,
isSearchActive = isSearchActive,
selectedRooms = selectedRooms,
eventSink = ::handleEvent,

View file

@ -8,6 +8,7 @@
package io.element.android.libraries.roomselect.impl
import androidx.compose.foundation.text.input.TextFieldState
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.ui.model.SelectRoomInfo
import io.element.android.libraries.roomselect.api.RoomSelectMode
@ -16,7 +17,7 @@ import kotlinx.collections.immutable.ImmutableList
data class RoomSelectState(
val mode: RoomSelectMode,
val resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>>,
val query: String,
val searchQuery: TextFieldState,
val isSearchActive: Boolean,
val selectedRooms: ImmutableList<SelectRoomInfo>,
val eventSink: (RoomSelectEvents) -> Unit

View file

@ -8,6 +8,7 @@
package io.element.android.libraries.roomselect.impl
import androidx.compose.foundation.text.input.TextFieldState
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
@ -22,16 +23,16 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
override val values: Sequence<RoomSelectState>
get() = sequenceOf(
aRoomSelectState(),
aRoomSelectState(query = "Test", isSearchActive = true),
aRoomSelectState(searchQuery = "Test", isSearchActive = true),
aRoomSelectState(resultState = SearchBarResultState.Results(aRoomSelectRoomList())),
aRoomSelectState(
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
query = "Test",
searchQuery = "Test",
isSearchActive = true,
),
aRoomSelectState(
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
query = "Test",
searchQuery = "Test",
isSearchActive = true,
selectedRooms = aRoomSelectRoomList().subList(0, 1),
),
@ -45,13 +46,13 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
private fun aRoomSelectState(
mode: RoomSelectMode = RoomSelectMode.Forward,
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial(),
query: String = "",
searchQuery: String = "",
isSearchActive: Boolean = false,
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),
) = RoomSelectState(
mode = mode,
resultState = resultState,
query = query,
searchQuery = TextFieldState(initialText = searchQuery),
isSearchActive = isSearchActive,
selectedRooms = selectedRooms,
eventSink = {}

View file

@ -132,8 +132,7 @@ fun RoomSelectView(
SearchBar(
modifier = Modifier.fillMaxWidth(),
placeHolderTitle = stringResource(CommonStrings.action_search),
query = state.query,
onQueryChange = { state.eventSink(RoomSelectEvents.UpdateQuery(it)) },
queryState = state.searchQuery,
active = state.isSearchActive,
onActiveChange = { state.eventSink(RoomSelectEvents.ToggleSearchActive) },
resultState = state.resultState,

View file

@ -8,6 +8,7 @@
package io.element.android.libraries.roomselect.impl
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
@ -78,13 +79,13 @@ class RoomSelectPresenterTest {
assertThat(result).isEqualTo(listOf(expectedRoomInfo))
initialState.eventSink(RoomSelectEvents.ToggleSearchActive)
skipItems(1)
initialState.eventSink(RoomSelectEvents.UpdateQuery("string not contained"))
initialState.searchQuery.setTextAndPlaceCursorAtEnd("string not contained")
assertThat(
roomListService.allRooms.currentFilter.value
).isEqualTo(
RoomListFilter.NormalizedMatchRoomName("string not contained")
)
assertThat(awaitItem().query).isEqualTo("string not contained")
assertThat(awaitItem().searchQuery.text.toString()).isEqualTo("string not contained")
roomListService.postAllRooms(
emptyList()
)