save the lazy list state and make it scroll in the search view model to avoid coming back on another feed position

This commit is contained in:
Vitor Pamplona
2026-03-10 16:56:31 -04:00
parent 26b7efafe8
commit a1e90b8c9f
2 changed files with 12 additions and 27 deletions
@@ -20,6 +20,7 @@
*/
package com.vitorpamplona.amethyst.ui.screen.loggedIn.search
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -87,8 +88,10 @@ class SearchBarViewModel(
val searchDataSourceState = SearchQueryState(MutableStateFlow(searchValue), account)
val listState: LazyListState = LazyListState(0, 0)
val directNip05Resolver: Flow<User?> =
searchValueFlow
searchTerm
.debounce(400)
.mapLatest { term ->
if (term.contains('@')) {
@@ -248,11 +251,12 @@ class SearchBarViewModel(
fun clear() = updateSearchValue("")
fun updateDataSource(searchTerm: String) {
suspend fun updateDataSource(searchTerm: String) {
if (searchTerm.isBlank()) {
searchDataSourceState.searchQuery.tryEmit("")
} else {
searchDataSourceState.searchQuery.tryEmit(searchTerm)
listState.scrollToItem(0, 0)
}
}
@@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
@@ -58,9 +57,7 @@ import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.TextSearchDataSourceSubscription
import com.vitorpamplona.amethyst.ui.feeds.ScrollStateKeys
import com.vitorpamplona.amethyst.ui.feeds.WatchLifecycleAndUpdateModel
import com.vitorpamplona.amethyst.ui.feeds.rememberForeverLazyListState
import com.vitorpamplona.amethyst.ui.layouts.DisappearingScaffold
import com.vitorpamplona.amethyst.ui.navigation.bottombars.AppBottomBar
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
@@ -109,16 +106,16 @@ fun SearchScreen(
) {
WatchLifecycleAndUpdateModel(searchBarViewModel)
val listState = rememberForeverLazyListState(ScrollStateKeys.SEARCH_SCREEN)
LaunchedEffect(searchBarViewModel.focusRequester) {
searchBarViewModel.focusRequester.requestFocus()
if (searchBarViewModel.listState.firstVisibleItemIndex == 0) {
searchBarViewModel.focusRequester.requestFocus()
}
}
DisappearingScaffold(
isInvertedLayout = false,
topBar = {
SearchBar(searchBarViewModel, listState, accountViewModel, nav)
SearchBar(searchBarViewModel, accountViewModel, nav)
},
bottomBar = {
AppBottomBar(Route.Search, accountViewModel) { route ->
@@ -131,7 +128,7 @@ fun SearchScreen(
modifier = Modifier.padding(it).consumeWindowInsets(it),
) {
ObserveRelayListForSearchAndDisplayIfNotFound(accountViewModel, nav)
DisplaySearchResults(searchBarViewModel, listState, nav, accountViewModel)
DisplaySearchResults(searchBarViewModel, nav, accountViewModel)
}
}
}
@@ -140,7 +137,6 @@ fun SearchScreen(
@Composable
private fun SearchBar(
searchBarViewModel: SearchBarViewModel,
listState: LazyListState,
accountViewModel: AccountViewModel,
nav: INav,
) {
@@ -164,23 +160,9 @@ private fun SearchBar(
}
}
AnimateOnNewSearch(searchBarViewModel, listState)
SearchTextField(searchBarViewModel, Modifier.statusBarsPadding())
}
@Composable
fun AnimateOnNewSearch(
searchBarViewModel: SearchBarViewModel,
listState: LazyListState,
) {
val searchTerm by searchBarViewModel.searchTerm.collectAsStateWithLifecycle()
LaunchedEffect(searchTerm) {
listState.animateScrollToItem(0)
}
}
@Composable
private fun SearchTextField(
searchBarViewModel: SearchBarViewModel,
@@ -237,7 +219,6 @@ private fun SearchTextField(
@Composable
private fun DisplaySearchResults(
searchBarViewModel: SearchBarViewModel,
listState: LazyListState,
nav: INav,
accountViewModel: AccountViewModel,
) {
@@ -256,7 +237,7 @@ private fun DisplaySearchResults(
LazyColumn(
modifier = Modifier.fillMaxHeight(),
contentPadding = FeedPadding,
state = listState,
state = searchBarViewModel.listState,
) {
itemsIndexed(
hashTags,