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 4c3cfa2e..90217aa1 100644 --- a/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt +++ b/app/src/main/kotlin/com/subtracks/data/prefs/UserPreferences.kt @@ -134,7 +134,7 @@ class UserPreferences( private fun listQueryKey(tab: LibraryListTab) = stringPreferencesKey("list_query_${tab.key}") - fun libraryTab(): Flow = store.data.map { prefs -> prefs[libraryTabKey] ?: LibraryListTab.Albums.name } + fun libraryTab(): Flow = store.data.map { prefs -> prefs[libraryTabKey] } suspend fun setLibraryTab(tab: String) { store.edit { prefs -> prefs[libraryTabKey] = tab } 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 264d5067..a4a0d9d8 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryScreen.kt @@ -151,6 +151,8 @@ data class SortOption( fun LibraryTab.listTab(): LibraryListTab = LibraryListTab.valueOf(name) +internal fun libraryTabFor(name: String?): LibraryTab = LibraryTab.entries.firstOrNull { it.name == name } ?: LibraryTab.Albums + fun sortOptionsFor(tab: LibraryTab): List = when (tab) { LibraryTab.Albums -> { @@ -195,8 +197,10 @@ fun LibraryRoute( viewModel: LibraryViewModel = koinViewModel(), playbackController: PlaybackController = koinInject(), ) { - val selectedTab by viewModel.selectedTab.collectAsStateWithLifecycle() - var previousTabName by rememberSaveable { mutableStateOf(selectedTab.name) } + // Wait for the stored tab before composing: the pager latches its initial page, so starting on + // the default and scrolling to the stored one would flash and, worse, report the default back. + val selectedTab = viewModel.selectedTab.collectAsStateWithLifecycle().value ?: return + var previousTabName by remember { mutableStateOf(selectedTab.name) } val previousTab = LibraryTab.entries.firstOrNull { it.name == previousTabName } ?: LibraryTab.Albums val syncing by viewModel.syncing.collectAsStateWithLifecycle() val listTab = selectedTab.listTab() @@ -241,7 +245,7 @@ fun LibraryRoute( ) LibraryScreen( selectedTab = selectedTab, - onTabSelected = { viewModel.selectTab(it) }, + onTabSelected = { tab -> if (viewModel.selectedTab.value != tab) viewModel.selectTab(tab) }, 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 ad927cb2..3ac317d2 100644 --- a/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt +++ b/app/src/main/kotlin/com/subtracks/ui/library/LibraryViewModel.kt @@ -135,11 +135,11 @@ class LibraryViewModel( fun listQuery(tab: LibraryListTab): StateFlow = listQueries.getValue(tab) - val selectedTab: StateFlow = + val selectedTab: StateFlow = userPreferences .libraryTab() - .map { name -> LibraryTab.entries.firstOrNull { it.name == name } ?: LibraryTab.Albums } - .stateIn(viewModelScope, SharingStarted.Eagerly, LibraryTab.Albums) + .map(::libraryTabFor) + .stateIn(viewModelScope, SharingStarted.Eagerly, null) fun selectTab(tab: LibraryTab) { viewModelScope.launch { userPreferences.setLibraryTab(tab.name) } 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 635663e0..4a584a09 100644 --- a/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt +++ b/app/src/test/kotlin/com/subtracks/data/prefs/UserPreferencesTest.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull import org.junit.Test import org.junit.runner.RunWith import java.io.File @@ -32,6 +33,7 @@ class UserPreferencesTest { ListQuery("Added", descending = true, starred = StarredFilter.Starred, downloaded = true), ) prefs.setListQuery(LibraryListTab.Artists, ListQuery("AlbumCount", descending = true)) + prefs.setListQuery(LibraryListTab.Playlists, ListQuery("Updated", starred = StarredFilter.NotStarred)) assertEquals( ListQuery("Added", descending = true, starred = StarredFilter.Starred, downloaded = true), @@ -41,30 +43,10 @@ class UserPreferencesTest { ListQuery("AlbumCount", descending = true), prefs.listQuery(LibraryListTab.Artists).first(), ) - - file.delete() - } - - @Test - fun everyTabsListQueryIsKeptIndependently() = - runTest { - val file = File.createTempFile("user-prefs", ".preferences_pb").apply { delete() } - val store = PreferenceDataStoreFactory.create(scope = backgroundScope) { file } - val prefs = UserPreferences(store) - - prefs.setListQuery(LibraryListTab.Albums, ListQuery("Added", descending = true, downloaded = true)) - prefs.setListQuery(LibraryListTab.Artists, ListQuery("AlbumCount", starred = StarredFilter.NotStarred)) - prefs.setListQuery(LibraryListTab.Playlists, ListQuery("Updated", descending = true)) - assertEquals( - ListQuery("Added", descending = true, downloaded = true), - prefs.listQuery(LibraryListTab.Albums).first(), + ListQuery("Updated", starred = StarredFilter.NotStarred), + prefs.listQuery(LibraryListTab.Playlists).first(), ) - assertEquals( - ListQuery("AlbumCount", starred = StarredFilter.NotStarred), - prefs.listQuery(LibraryListTab.Artists).first(), - ) - assertEquals(ListQuery("Updated", descending = true), prefs.listQuery(LibraryListTab.Playlists).first()) file.delete() } @@ -76,7 +58,7 @@ class UserPreferencesTest { val store = PreferenceDataStoreFactory.create(scope = backgroundScope) { file } val prefs = UserPreferences(store) - assertEquals("Albums", prefs.libraryTab().first()) + assertNull(prefs.libraryTab().first()) prefs.setLibraryTab("Playlists") diff --git a/app/src/test/kotlin/com/subtracks/ui/library/LibraryTabTest.kt b/app/src/test/kotlin/com/subtracks/ui/library/LibraryTabTest.kt new file mode 100644 index 00000000..5775dcc5 --- /dev/null +++ b/app/src/test/kotlin/com/subtracks/ui/library/LibraryTabTest.kt @@ -0,0 +1,16 @@ +package com.subtracks.ui.library + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class LibraryTabTest { + @Test + fun theStoredNameMapsToItsTabAndAnythingElseToAlbums() { + assertEquals(LibraryTab.Playlists, libraryTabFor("Playlists")) + assertEquals(LibraryTab.Albums, libraryTabFor(null)) + assertEquals(LibraryTab.Albums, libraryTabFor("Books")) + } +}