mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 15:29:15 +01:00
remember the library tab across restarts
The selected tab lived in rememberSaveable, which survives a rotation or a process-death restore but not a cold start, so the app always came back on Albums. It goes through DataStore now, like the per-tab sort and filters, which were already durable - landing on a different tab than the one you had filtered is what made the filters look reset.
This commit is contained in:
@@ -134,6 +134,14 @@ class UserPreferences(
|
|||||||
|
|
||||||
private fun listQueryKey(tab: LibraryListTab) = stringPreferencesKey("list_query_${tab.key}")
|
private fun listQueryKey(tab: LibraryListTab) = stringPreferencesKey("list_query_${tab.key}")
|
||||||
|
|
||||||
|
fun libraryTab(): Flow<String> = store.data.map { prefs -> prefs[libraryTabKey] ?: LibraryListTab.Albums.name }
|
||||||
|
|
||||||
|
suspend fun setLibraryTab(tab: String) {
|
||||||
|
store.edit { prefs -> prefs[libraryTabKey] = tab }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val libraryTabKey = stringPreferencesKey("library_tab")
|
||||||
|
|
||||||
private fun encode(query: ListQuery) =
|
private fun encode(query: ListQuery) =
|
||||||
"${query.sort}|${if (query.descending) 1 else 0}|${query.starred.ordinal}|${if (query.downloaded) 1 else 0}"
|
"${query.sort}|${if (query.descending) 1 else 0}|${query.starred.ordinal}|${if (query.downloaded) 1 else 0}"
|
||||||
|
|
||||||
|
|||||||
@@ -195,9 +195,8 @@ fun LibraryRoute(
|
|||||||
viewModel: LibraryViewModel = koinViewModel(),
|
viewModel: LibraryViewModel = koinViewModel(),
|
||||||
playbackController: PlaybackController = koinInject(),
|
playbackController: PlaybackController = koinInject(),
|
||||||
) {
|
) {
|
||||||
var selectedTabName by rememberSaveable { mutableStateOf(LibraryTab.Albums.name) }
|
val selectedTab by viewModel.selectedTab.collectAsStateWithLifecycle()
|
||||||
var previousTabName by rememberSaveable { mutableStateOf(LibraryTab.Albums.name) }
|
var previousTabName by rememberSaveable { mutableStateOf(selectedTab.name) }
|
||||||
val selectedTab = LibraryTab.entries.firstOrNull { it.name == selectedTabName } ?: LibraryTab.Albums
|
|
||||||
val previousTab = LibraryTab.entries.firstOrNull { it.name == previousTabName } ?: LibraryTab.Albums
|
val previousTab = LibraryTab.entries.firstOrNull { it.name == previousTabName } ?: LibraryTab.Albums
|
||||||
val syncing by viewModel.syncing.collectAsStateWithLifecycle()
|
val syncing by viewModel.syncing.collectAsStateWithLifecycle()
|
||||||
val listTab = selectedTab.listTab()
|
val listTab = selectedTab.listTab()
|
||||||
@@ -242,7 +241,7 @@ fun LibraryRoute(
|
|||||||
)
|
)
|
||||||
LibraryScreen(
|
LibraryScreen(
|
||||||
selectedTab = selectedTab,
|
selectedTab = selectedTab,
|
||||||
onTabSelected = { selectedTabName = it.name },
|
onTabSelected = { viewModel.selectTab(it) },
|
||||||
syncing = syncing,
|
syncing = syncing,
|
||||||
bottomInset = bottomInset,
|
bottomInset = bottomInset,
|
||||||
artwork = artwork,
|
artwork = artwork,
|
||||||
|
|||||||
@@ -135,6 +135,16 @@ class LibraryViewModel(
|
|||||||
|
|
||||||
fun listQuery(tab: LibraryListTab): StateFlow<ListQuery> = listQueries.getValue(tab)
|
fun listQuery(tab: LibraryListTab): StateFlow<ListQuery> = listQueries.getValue(tab)
|
||||||
|
|
||||||
|
val selectedTab: StateFlow<LibraryTab> =
|
||||||
|
userPreferences
|
||||||
|
.libraryTab()
|
||||||
|
.map { name -> LibraryTab.entries.firstOrNull { it.name == name } ?: LibraryTab.Albums }
|
||||||
|
.stateIn(viewModelScope, SharingStarted.Eagerly, LibraryTab.Albums)
|
||||||
|
|
||||||
|
fun selectTab(tab: LibraryTab) {
|
||||||
|
viewModelScope.launch { userPreferences.setLibraryTab(tab.name) }
|
||||||
|
}
|
||||||
|
|
||||||
fun setListQuery(
|
fun setListQuery(
|
||||||
tab: LibraryListTab,
|
tab: LibraryListTab,
|
||||||
query: ListQuery,
|
query: ListQuery,
|
||||||
|
|||||||
@@ -45,6 +45,22 @@ class UserPreferencesTest {
|
|||||||
file.delete()
|
file.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun theSelectedLibraryTabRoundTrips() =
|
||||||
|
runTest {
|
||||||
|
val file = File.createTempFile("user-prefs", ".preferences_pb").apply { delete() }
|
||||||
|
val store = PreferenceDataStoreFactory.create(scope = backgroundScope) { file }
|
||||||
|
val prefs = UserPreferences(store)
|
||||||
|
|
||||||
|
assertEquals("Albums", prefs.libraryTab().first())
|
||||||
|
|
||||||
|
prefs.setLibraryTab("Playlists")
|
||||||
|
|
||||||
|
assertEquals("Playlists", prefs.libraryTab().first())
|
||||||
|
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun aListQueryStoredBeforeTheDownloadedFilterStillDecodes() =
|
fun aListQueryStoredBeforeTheDownloadedFilterStillDecodes() =
|
||||||
runTest {
|
runTest {
|
||||||
|
|||||||
Reference in New Issue
Block a user