Missing-file lifecycle end to end, UPnP stall recovery, Android browse parity, Flutter client removed #126

Merged
bvandeusen merged 23 commits from dev into main 2026-08-17 16:28:14 -04:00
2 changed files with 36 additions and 17 deletions
Showing only changes of commit bfb6c9acfe - Show all commits
@@ -240,6 +240,11 @@ fun visibleGenres(
}
}
// Integer division by this floors a year to its decade: 2007 -> 2000. Named
// because detekt counts it as magic, and because the arithmetic reads as
// arbitrary otherwise.
private const val YEARS_PER_DECADE = 10
/** A decade's worth of the year index, newest year first. */
data class DecadeGroup(
val decade: Int,
@@ -255,7 +260,7 @@ data class DecadeGroup(
* same reason as [visibleGenres].
*/
fun groupByDecade(years: List<YearCount>): List<DecadeGroup> =
years.groupBy { (it.year / 10) * 10 }
years.groupBy { (it.year / YEARS_PER_DECADE) * YEARS_PER_DECADE }
.map { (decade, entries) ->
DecadeGroup(
decade = decade,
@@ -117,26 +117,40 @@ fun LibraryScreen(
state = pagerState,
modifier = Modifier.fillMaxSize().padding(inner),
) { page ->
when (page) {
TAB_ARTISTS -> ArtistsTab(viewModel = viewModel, navController = navController)
TAB_ALBUMS -> AlbumsTab(viewModel = viewModel, navController = navController)
TAB_GENRES -> GenresTab(
onAlbumClick = { id -> navController.navigate(AlbumDetail(id)) },
)
TAB_YEARS -> YearsTab(
onAlbumClick = { id -> navController.navigate(AlbumDetail(id)) },
)
TAB_HISTORY -> HistoryTab(
onNavigateToAlbum = { id -> navController.navigate(AlbumDetail(id)) },
onNavigateToArtist = { id -> navController.navigate(ArtistDetail(id)) },
)
TAB_LIKED -> LikedTab(navController = navController)
TAB_HIDDEN -> HiddenTab()
}
LibraryTabPage(page = page, viewModel = viewModel, navController = navController)
}
}
}
/**
* The pager's page bodies, split out of [LibraryScreen] so the screen stays
* the scaffold + tab bar and this stays the routing table. Adding a tab is
* then one line here and one label in [LIBRARY_TABS].
*/
@Composable
private fun LibraryTabPage(
page: Int,
viewModel: LibraryViewModel,
navController: NavHostController,
) {
when (page) {
TAB_ARTISTS -> ArtistsTab(viewModel = viewModel, navController = navController)
TAB_ALBUMS -> AlbumsTab(viewModel = viewModel, navController = navController)
TAB_GENRES -> GenresTab(
onAlbumClick = { id -> navController.navigate(AlbumDetail(id)) },
)
TAB_YEARS -> YearsTab(
onAlbumClick = { id -> navController.navigate(AlbumDetail(id)) },
)
TAB_HISTORY -> HistoryTab(
onNavigateToAlbum = { id -> navController.navigate(AlbumDetail(id)) },
onNavigateToArtist = { id -> navController.navigate(ArtistDetail(id)) },
)
TAB_LIKED -> LikedTab(navController = navController)
TAB_HIDDEN -> HiddenTab()
}
}
private const val TAB_ARTISTS = 0
private const val TAB_ALBUMS = 1
private const val TAB_GENRES = 2