From 270d749f0cadb8e3808eb09a27599f4735c98789 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Mon, 28 Sep 2026 13:04:14 +0000 Subject: [PATCH] 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. --- .../com/subtracks/data/prefs/UserPreferences.kt | 8 ++++++++ .../com/subtracks/ui/library/LibraryScreen.kt | 7 +++---- .../com/subtracks/ui/library/LibraryViewModel.kt | 10 ++++++++++ .../subtracks/data/prefs/UserPreferencesTest.kt | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt b/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt index bb74c11f..4c3cfa2e 100644 --- a/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt +++ b/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt @@ -134,6 +134,14 @@ class UserPreferences( private fun listQueryKey(tab: LibraryListTab) = stringPreferencesKey("list_query_${tab.key}") + fun libraryTab(): Flow = 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) = "${query.sort}|${if (query.descending) 1 else 0}|${query.starred.ordinal}|${if (query.downloaded) 1 else 0}" diff --git a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt index df2fa3df..264d5067 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt @@ -195,9 +195,8 @@ fun LibraryRoute( viewModel: LibraryViewModel = koinViewModel(), playbackController: PlaybackController = koinInject(), ) { - var selectedTabName by rememberSaveable { mutableStateOf(LibraryTab.Albums.name) } - var previousTabName by rememberSaveable { mutableStateOf(LibraryTab.Albums.name) } - val selectedTab = LibraryTab.entries.firstOrNull { it.name == selectedTabName } ?: LibraryTab.Albums + val selectedTab by viewModel.selectedTab.collectAsStateWithLifecycle() + var previousTabName by rememberSaveable { mutableStateOf(selectedTab.name) } val previousTab = LibraryTab.entries.firstOrNull { it.name == previousTabName } ?: LibraryTab.Albums val syncing by viewModel.syncing.collectAsStateWithLifecycle() val listTab = selectedTab.listTab() @@ -242,7 +241,7 @@ fun LibraryRoute( ) LibraryScreen( selectedTab = selectedTab, - onTabSelected = { selectedTabName = it.name }, + onTabSelected = { viewModel.selectTab(it) }, syncing = syncing, bottomInset = bottomInset, artwork = artwork, diff --git a/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt b/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt index 2900c114..ad927cb2 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt @@ -135,6 +135,16 @@ class LibraryViewModel( fun listQuery(tab: LibraryListTab): StateFlow = listQueries.getValue(tab) + val selectedTab: StateFlow = + 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( tab: LibraryListTab, query: ListQuery, diff --git a/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt b/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt index e088a833..0676e99d 100644 --- a/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt +++ b/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt @@ -45,6 +45,22 @@ class UserPreferencesTest { 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 fun aListQueryStoredBeforeTheDownloadedFilterStillDecodes() = runTest {