Merge pull request #7266 from element-hq/feature/fga/searchbar-result-state-refactor

Refactor SearchBarResultState.Initial/NoResultsFound to data objects
This commit is contained in:
ganfra
2026-07-24 09:58:15 +02:00
committed by GitHub
15 changed files with 38 additions and 54 deletions
@@ -59,7 +59,7 @@ fun <T> SearchBar(
modifier: Modifier = Modifier,
enabled: Boolean = true,
showBackButton: Boolean = true,
resultState: SearchBarResultState<T> = SearchBarResultState.Initial(),
resultState: SearchBarResultState<T> = SearchBarResultState.Initial,
shape: Shape = SearchBarDefaults.inputFieldShape,
tonalElevation: Dp = SearchBarDefaults.TonalElevation,
windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
@@ -134,7 +134,7 @@ fun <T> SearchBar(
resultHandler(resultState.results)
}
is SearchBarResultState.NoResultsFound<T> -> {
is SearchBarResultState.NoResultsFound -> {
// No results found, show a message
Spacer(Modifier.size(80.dp))
@@ -200,12 +200,12 @@ object ElementSearchBarDefaults {
}
@Immutable
sealed interface SearchBarResultState<in T> {
sealed interface SearchBarResultState<out T> {
/** No search results are available yet (e.g. because the user hasn't entered a search term). */
class Initial<T> : SearchBarResultState<T>
data object Initial : SearchBarResultState<Nothing>
/** The search has completed, but no results were found. */
class NoResultsFound<T> : SearchBarResultState<T>
data object NoResultsFound : SearchBarResultState<Nothing>
/** The search has completed, and some matching users were found. */
data class Results<T>(val results: T) : SearchBarResultState<T>
@@ -249,7 +249,7 @@ internal fun SearchBarActiveWithNoResultsPreview() = ElementThemedPreview {
ContentToPreview(
initialQuery = "search term",
active = true,
resultState = SearchBarResultState.NoResultsFound<String>(),
resultState = SearchBarResultState.NoResultsFound,
)
}
@@ -293,7 +293,7 @@ private fun ContentToPreview(
initialQuery: String = "",
active: Boolean = false,
showBackButton: Boolean = true,
resultState: SearchBarResultState<String> = SearchBarResultState.Initial(),
resultState: SearchBarResultState<String> = SearchBarResultState.Initial,
contentPrefix: @Composable ColumnScope.() -> Unit = {},
contentSuffix: @Composable ColumnScope.() -> Unit = {},
resultHandler: @Composable ColumnScope.(String) -> Unit = {},
@@ -55,7 +55,7 @@ class DefaultEmojiPickerPresenter(
override fun present(): EmojiPickerState {
val queryState = rememberTextFieldState()
var isSearchActive by remember { mutableStateOf(false) }
var emojiResults by remember { mutableStateOf<SearchBarResultState<ImmutableList<Emoji>>>(SearchBarResultState.Initial()) }
var emojiResults by remember { mutableStateOf<SearchBarResultState<ImmutableList<Emoji>>>(SearchBarResultState.Initial) }
val data by produceState(EmojiPickerData.Empty) {
val storeDeferred = async { emojibaseProvider.getStore() }
@@ -93,11 +93,7 @@ class DefaultEmojiPickerPresenter(
val searchQuery = queryState.text.toString()
LaunchedEffect(searchQuery, data) {
if (searchQuery.isEmpty() || data.allEmojis.isEmpty()) {
// `SearchBarResultState.Initial` has no `equals` override, so reassigning a new instance
// would trigger a redundant emission each time this effect re-runs while the query is empty.
if (emojiResults !is SearchBarResultState.Initial) {
emojiResults = SearchBarResultState.Initial()
}
emojiResults = SearchBarResultState.Initial
return@LaunchedEffect
}
delay(100.milliseconds)
@@ -62,7 +62,7 @@ internal fun aDefaultEmojiPickerState(
}.toImmutableList(),
searchQuery: String = "",
isSearchActive: Boolean = false,
searchResults: SearchBarResultState<ImmutableList<Emoji>> = SearchBarResultState.Initial(),
searchResults: SearchBarResultState<ImmutableList<Emoji>> = SearchBarResultState.Initial,
eventSink: (EmojiPickerEvent) -> Unit = {},
) = DefaultEmojiPickerState(
categories = categories,
@@ -65,8 +65,8 @@ class RoomSelectPresenter(
derivedStateOf {
when {
roomSummaryDetailsList.isNotEmpty() -> SearchBarResultState.Results(roomSummaryDetailsList.toImmutableList())
isSearchActive -> SearchBarResultState.NoResultsFound()
else -> SearchBarResultState.Initial()
isSearchActive -> SearchBarResultState.NoResultsFound
else -> SearchBarResultState.Initial
}
}
}
@@ -52,7 +52,7 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
internal fun aRoomSelectState(
mode: RoomSelectMode = RoomSelectMode.Forward,
maxNumberOfRooms: Int = 10,
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial(),
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial,
searchQuery: String = "",
isSearchActive: Boolean = false,
selectedRooms: ImmutableList<SelectRoomInfo> = persistentListOf(),