Skip to content

Commit

Permalink
fix: persist top app bar filter mode when popping off backstack; requ…
Browse files Browse the repository at this point in the history
…est keyboard focus on end of query rather than beginning

use a plain class state holder

fixes #1037
  • Loading branch information
lydavid committed Aug 3, 2024
1 parent 9105f33 commit efcf128
Show file tree
Hide file tree
Showing 45 changed files with 348 additions and 395 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import app.cash.paging.compose.LazyPagingItems
import app.cash.paging.compose.collectAsLazyPagingItems
import com.slack.circuit.foundation.NavEvent
Expand All @@ -21,6 +17,8 @@ import ly.david.musicsearch.core.models.network.MusicBrainzEntity
import ly.david.musicsearch.shared.domain.nowplaying.usecase.DeleteNowPlayingHistory
import ly.david.musicsearch.shared.domain.nowplaying.usecase.GetNowPlayingHistory
import ly.david.musicsearch.ui.common.screen.SearchScreen
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.rememberTopAppBarFilterState

internal class NowPlayingHistoryPresenter(
private val navigator: Navigator,
Expand All @@ -30,9 +28,9 @@ internal class NowPlayingHistoryPresenter(

@Composable
override fun present(): NowPlayingHistoryUiState {
var query by rememberSaveable { mutableStateOf("") }
val topAppBarFilterState = rememberTopAppBarFilterState()
val lazyPagingItems: LazyPagingItems<ListItemModel> = getNowPlayingHistory(
query = query,
query = topAppBarFilterState.filterText,
).collectAsLazyPagingItems()
val lazyListState = rememberLazyListState()

Expand All @@ -42,10 +40,6 @@ internal class NowPlayingHistoryPresenter(
navigator.pop()
}

is NowPlayingHistoryUiEvent.UpdateQuery -> {
query = event.query
}

is NowPlayingHistoryUiEvent.DeleteHistory -> {
deleteNowPlayingHistory(event.id)
}
Expand All @@ -64,7 +58,7 @@ internal class NowPlayingHistoryPresenter(
}

return NowPlayingHistoryUiState(
query = query,
topAppBarFilterState = topAppBarFilterState,
lazyPagingItems = lazyPagingItems,
lazyListState = lazyListState,
eventSink = ::eventSink,
Expand All @@ -74,15 +68,14 @@ internal class NowPlayingHistoryPresenter(

@Stable
internal data class NowPlayingHistoryUiState(
val query: String,
val topAppBarFilterState: TopAppBarFilterState,
val lazyPagingItems: LazyPagingItems<ListItemModel>,
val lazyListState: LazyListState,
val eventSink: (NowPlayingHistoryUiEvent) -> Unit,
) : CircuitUiState

internal sealed interface NowPlayingHistoryUiEvent : CircuitUiEvent {
data object NavigateUp : NowPlayingHistoryUiEvent
data class UpdateQuery(val query: String) : NowPlayingHistoryUiEvent
data class DeleteHistory(val id: String) : NowPlayingHistoryUiEvent
data class GoToSearch(
val query: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import ly.david.musicsearch.core.models.network.MusicBrainzEntity
import ly.david.musicsearch.ui.common.listitem.ListSeparatorHeader
import ly.david.musicsearch.ui.common.listitem.SwipeToDeleteListItem
import ly.david.musicsearch.ui.common.paging.ScreenWithPagingLoadingAndError
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.TopAppBarWithFilter
import ly.david.musicsearch.ui.core.LocalStrings
import ly.david.musicsearch.ui.core.theme.PreviewTheme
Expand All @@ -51,10 +52,7 @@ internal fun NowPlayingHistoryUi(
),
)
},
filterText = state.query,
onFilterTextChange = {
eventSink(NowPlayingHistoryUiEvent.UpdateQuery(it))
},
topAppBarFilterState = state.topAppBarFilterState,
onDelete = { id ->
eventSink(NowPlayingHistoryUiEvent.DeleteHistory(id))
},
Expand All @@ -67,10 +65,9 @@ private fun NowPlayingHistoryUi(
lazyPagingItems: LazyPagingItems<ListItemModel>,
modifier: Modifier = Modifier,
lazyListState: LazyListState = LazyListState(),
topAppBarFilterState: TopAppBarFilterState = TopAppBarFilterState(),
onBack: () -> Unit = {},
searchMusicBrainz: (query: String, entity: MusicBrainzEntity) -> Unit = { _, _ -> },
filterText: String = "",
onFilterTextChange: (String) -> Unit = {},
onDelete: (String) -> Unit = {},
) {
val strings = LocalStrings.current
Expand All @@ -85,8 +82,7 @@ private fun NowPlayingHistoryUi(
onBack = onBack,
title = strings.nowPlayingHistory,
scrollBehavior = scrollBehavior,
filterText = filterText,
onFilterTextChange = onFilterTextChange,
topAppBarFilterState = topAppBarFilterState,
)
},
) { innerPadding ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import app.cash.paging.compose.LazyPagingItems
import app.cash.paging.compose.collectAsLazyPagingItems
import com.slack.circuit.foundation.NavEvent
Expand All @@ -21,6 +17,8 @@ import ly.david.musicsearch.core.models.listitem.SpotifyHistoryListItemModel
import ly.david.musicsearch.core.models.network.MusicBrainzEntity
import ly.david.musicsearch.shared.domain.spotify.SpotifyHistoryRepository
import ly.david.musicsearch.ui.common.screen.SearchScreen
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.rememberTopAppBarFilterState

internal class SpotifyHistoryPresenter(
private val navigator: Navigator,
Expand All @@ -29,9 +27,9 @@ internal class SpotifyHistoryPresenter(

@Composable
override fun present(): SpotifyUiState {
var query by rememberSaveable { mutableStateOf("") }
val topAppBarFilterState = rememberTopAppBarFilterState()
val lazyPagingItems: LazyPagingItems<ListItemModel> = spotifyHistoryRepository.observeSpotifyHistory(
query = query,
query = topAppBarFilterState.filterText,
).collectAsLazyPagingItems()
val lazyListState = rememberLazyListState()

Expand All @@ -41,10 +39,6 @@ internal class SpotifyHistoryPresenter(
navigator.pop()
}

is SpotifyUiEvent.UpdateQuery -> {
query = event.query
}

is SpotifyUiEvent.GoToSearch -> {
navigator.onNavEvent(
NavEvent.GoTo(
Expand Down Expand Up @@ -80,7 +74,7 @@ internal class SpotifyHistoryPresenter(
}

return SpotifyUiState(
query = query,
topAppBarFilterState = topAppBarFilterState,
lazyPagingItems = lazyPagingItems,
lazyListState = lazyListState,
eventSink = ::eventSink,
Expand All @@ -90,15 +84,14 @@ internal class SpotifyHistoryPresenter(

@Stable
internal data class SpotifyUiState(
val query: String,
val topAppBarFilterState: TopAppBarFilterState,
val lazyPagingItems: LazyPagingItems<ListItemModel>,
val lazyListState: LazyListState,
val eventSink: (SpotifyUiEvent) -> Unit,
) : CircuitUiState

internal sealed interface SpotifyUiEvent : CircuitUiEvent {
data object NavigateUp : SpotifyUiEvent
data class UpdateQuery(val query: String) : SpotifyUiEvent
data class GoToSearch(
val query: String,
val entity: MusicBrainzEntity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import ly.david.musicsearch.core.models.network.MusicBrainzEntity
import ly.david.musicsearch.ui.common.listitem.ListSeparatorHeader
import ly.david.musicsearch.ui.common.listitem.SwipeToDeleteListItem
import ly.david.musicsearch.ui.common.paging.ScreenWithPagingLoadingAndError
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.TopAppBarWithFilter
import ly.david.musicsearch.ui.core.LocalStrings
import ly.david.musicsearch.ui.core.theme.PreviewTheme
Expand All @@ -67,10 +68,7 @@ internal fun SpotifyHistoryUi(
),
)
},
filterText = state.query,
onFilterTextChange = {
eventSink(SpotifyUiEvent.UpdateQuery(it))
},
topAppBarFilterState = state.topAppBarFilterState,
onMarkForDeletion = {
eventSink(SpotifyUiEvent.MarkForDeletion(it))
},
Expand All @@ -88,11 +86,10 @@ internal fun SpotifyHistoryUi(
private fun SpotifyHistoryUi(
lazyPagingItems: LazyPagingItems<ListItemModel>,
modifier: Modifier = Modifier,
topAppBarFilterState: TopAppBarFilterState = TopAppBarFilterState(),
lazyListState: LazyListState = LazyListState(),
onBack: () -> Unit = {},
searchMusicBrainz: (query: String, entity: MusicBrainzEntity) -> Unit = { _, _ -> },
filterText: String = "",
onFilterTextChange: (String) -> Unit = {},
onMarkForDeletion: (SpotifyHistoryListItemModel) -> Unit = {},
onUndoMarkForDeletion: (SpotifyHistoryListItemModel) -> Unit = {},
onDelete: (SpotifyHistoryListItemModel) -> Unit = {},
Expand All @@ -111,8 +108,7 @@ private fun SpotifyHistoryUi(
onBack = onBack,
title = strings.spotifyHistory,
scrollBehavior = scrollBehavior,
filterText = filterText,
onFilterTextChange = onFilterTextChange,
topAppBarFilterState = topAppBarFilterState,
)
},
snackbarHost = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import app.cash.paging.compose.LazyPagingItems
import app.cash.paging.compose.collectAsLazyPagingItems
import com.slack.circuit.runtime.CircuitUiEvent
Expand All @@ -22,6 +19,8 @@ import ly.david.musicsearch.shared.domain.collection.usecase.CreateCollection
import ly.david.musicsearch.shared.domain.collection.usecase.GetAllCollections
import ly.david.musicsearch.shared.feature.collections.create.NewCollection
import ly.david.musicsearch.ui.common.screen.CollectionScreen
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.rememberTopAppBarFilterState

internal class CollectionListPresenter(
private val navigator: Navigator,
Expand All @@ -31,7 +30,8 @@ internal class CollectionListPresenter(
) : Presenter<CollectionListUiState> {
@Composable
override fun present(): CollectionListUiState {
var query by rememberSaveable { mutableStateOf("") }
val topAppBarFilterState = rememberTopAppBarFilterState()
val query = topAppBarFilterState.filterText
val showLocal by appPreferences.showLocalCollections.collectAsState(true)
val showRemote by appPreferences.showRemoteCollections.collectAsState(true)
val sortOption by appPreferences.collectionSortOption.collectAsState(CollectionSortOption.ALPHABETICALLY)
Expand All @@ -45,10 +45,6 @@ internal class CollectionListPresenter(

fun eventSink(event: CollectionListUiEvent) {
when (event) {
is CollectionListUiEvent.UpdateQuery -> {
query = event.query
}

is CollectionListUiEvent.UpdateShowLocal -> {
appPreferences.setShowLocalCollections(event.show)
}
Expand Down Expand Up @@ -77,7 +73,7 @@ internal class CollectionListPresenter(
}

return CollectionListUiState(
query = query,
topAppBarFilterState = topAppBarFilterState,
showLocal = showLocal,
showRemote = showRemote,
sortOption = sortOption,
Expand All @@ -90,7 +86,7 @@ internal class CollectionListPresenter(

@Stable
internal data class CollectionListUiState(
val query: String,
val topAppBarFilterState: TopAppBarFilterState = TopAppBarFilterState(),
val showLocal: Boolean,
val showRemote: Boolean,
val sortOption: CollectionSortOption,
Expand All @@ -100,7 +96,6 @@ internal data class CollectionListUiState(
) : CircuitUiState

internal sealed interface CollectionListUiEvent : CircuitUiEvent {
data class UpdateQuery(val query: String) : CollectionListUiEvent
data class UpdateShowLocal(val show: Boolean) : CollectionListUiEvent
data class UpdateShowRemote(val show: Boolean) : CollectionListUiEvent
data class UpdateSortOption(val sortOption: CollectionSortOption) : CollectionListUiEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import ly.david.musicsearch.shared.feature.collections.components.CollectionList
import ly.david.musicsearch.shared.feature.collections.create.CreateNewCollectionDialogContent
import ly.david.musicsearch.shared.feature.collections.create.NewCollection
import ly.david.musicsearch.ui.common.paging.ScreenWithPagingLoadingAndError
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.TopAppBarWithFilter
import ly.david.musicsearch.ui.core.LocalStrings

Expand Down Expand Up @@ -64,8 +65,7 @@ internal fun CollectionListUi(
lazyListState = state.lazyListState,
modifier = modifier,
sortOption = state.sortOption,
filterText = state.query,
onFilterTextChange = { eventSink(CollectionListUiEvent.UpdateQuery(it)) },
topAppBarFilterState = state.topAppBarFilterState,
onCreateCollectionClick = {
scope.launch {
val result = overlayHost.show(
Expand Down Expand Up @@ -118,8 +118,7 @@ internal fun CollectionListUi(
lazyPagingItems: LazyPagingItems<CollectionListItemModel>,
modifier: Modifier = Modifier,
lazyListState: LazyListState = LazyListState(),
filterText: String = "",
onFilterTextChange: (String) -> Unit = {},
topAppBarFilterState: TopAppBarFilterState = TopAppBarFilterState(),
onCreateCollectionClick: () -> Unit = {},
showLocal: Boolean = true,
onShowLocalToggle: (Boolean) -> Unit = {},
Expand All @@ -140,8 +139,7 @@ internal fun CollectionListUi(
showBackButton = false,
title = strings.collections,
scrollBehavior = scrollBehavior,
filterText = filterText,
onFilterTextChange = onFilterTextChange,
topAppBarFilterState = topAppBarFilterState,
additionalActions = {
IconButton(onClick = onCreateCollectionClick) {
Icon(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ import ly.david.musicsearch.ui.common.releasegroup.ReleaseGroupsByEntityUiEvent
import ly.david.musicsearch.ui.common.releasegroup.ReleaseGroupsByEntityUiState
import ly.david.musicsearch.ui.common.screen.CollectionScreen
import ly.david.musicsearch.ui.common.screen.DetailsScreen
import ly.david.musicsearch.ui.common.topappbar.TopAppBarFilterState
import ly.david.musicsearch.ui.common.topappbar.rememberTopAppBarFilterState
import ly.david.musicsearch.ui.common.work.WorksByEntityPresenter
import ly.david.musicsearch.ui.common.work.WorksByEntityUiEvent
import ly.david.musicsearch.ui.common.work.WorksByEntityUiState
Expand Down Expand Up @@ -83,7 +85,8 @@ internal class CollectionPresenter(
val scope = rememberCoroutineScope()
var collection: CollectionListItemModel? by remember { mutableStateOf(null) }
var actionableResult: ActionableResult? by remember { mutableStateOf(null) }
var query by rememberSaveable { mutableStateOf("") }
val topAppBarFilterState = rememberTopAppBarFilterState()
val query = topAppBarFilterState.filterText
var recordedHistory by rememberSaveable { mutableStateOf(false) }
var isRemote: Boolean by rememberSaveable { mutableStateOf(false) }
var collectableItems: Flow<PagingData<ListItemModel>> by remember { mutableStateOf(emptyFlow()) }
Expand Down Expand Up @@ -308,17 +311,13 @@ internal class CollectionPresenter(

is CollectionUiEvent.DeleteItem -> {
}

is CollectionUiEvent.UpdateQuery -> {
query = event.query
}
}
}

return CollectionUiState(
collection = collection,
actionableResult = actionableResult,
query = query,
topAppBarFilterState = topAppBarFilterState,
lazyPagingItems = collectableItems.collectAsLazyPagingItems(),
artistsByEntityUiState = artistsByEntityUiState,
eventsByEntityUiState = eventsByEntityUiState,
Expand All @@ -335,7 +334,7 @@ internal class CollectionPresenter(
internal data class CollectionUiState(
val collection: CollectionListItemModel?,
val actionableResult: ActionableResult?,
val query: String,
val topAppBarFilterState: TopAppBarFilterState = TopAppBarFilterState(),
val lazyPagingItems: LazyPagingItems<ListItemModel>,
val artistsByEntityUiState: ArtistsByEntityUiState,
val eventsByEntityUiState: EventsByEntityUiState,
Expand All @@ -349,8 +348,6 @@ internal data class CollectionUiState(
internal sealed interface CollectionUiEvent : CircuitUiEvent {
data object NavigateUp : CollectionUiEvent

data class UpdateQuery(val query: String) : CollectionUiEvent

data class MarkItemForDeletion(
val collectableId: String,
val name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,7 @@ internal fun CollectionUi(
)
}
},
filterText = state.query,
onFilterTextChange = {
eventSink(CollectionUiEvent.UpdateQuery(it))
},
topAppBarFilterState = state.topAppBarFilterState,
)
},
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
Expand Down
Loading

0 comments on commit efcf128

Please sign in to comment.