mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
apply the prefetched theme on open and soften the hero darkening
This commit is contained in:
@@ -68,11 +68,14 @@ private object Routes {
|
||||
const val LIBRARY = "library"
|
||||
const val SETTINGS = "settings"
|
||||
const val ADD_SERVER = "add-server"
|
||||
const val ALBUM_DETAIL = "album/{albumId}"
|
||||
const val ALBUM_DETAIL = "album/{albumId}?coverArt={coverArt}"
|
||||
const val ARTIST_DETAIL = "artist/{artistId}"
|
||||
const val PLAYLIST_DETAIL = "playlist/{playlistId}"
|
||||
|
||||
fun album(id: String) = "album/${Uri.encode(id)}"
|
||||
fun album(
|
||||
id: String,
|
||||
coverArt: String? = null,
|
||||
) = "album/${Uri.encode(id)}?coverArt=${Uri.encode(coverArt.orEmpty())}"
|
||||
|
||||
fun artist(id: String) = "artist/${Uri.encode(id)}"
|
||||
|
||||
@@ -135,7 +138,7 @@ private fun MainNavigation() {
|
||||
) {
|
||||
composable(Routes.LIBRARY) {
|
||||
LibraryRoute(
|
||||
onAlbumClick = { album -> navController.navigate(Routes.album(album.id)) },
|
||||
onAlbumClick = { album -> navController.navigate(Routes.album(album.id, album.coverArt)) },
|
||||
onArtistClick = { artist -> navController.navigate(Routes.artist(artist.id)) },
|
||||
onPlaylistClick = { playlist -> navController.navigate(Routes.playlist(playlist.id)) },
|
||||
onOpenSettings = { navController.navigate(Routes.SETTINGS) },
|
||||
@@ -150,10 +153,22 @@ private fun MainNavigation() {
|
||||
}
|
||||
composable(
|
||||
route = Routes.ALBUM_DETAIL,
|
||||
arguments = listOf(navArgument("albumId") { type = NavType.StringType }),
|
||||
arguments =
|
||||
listOf(
|
||||
navArgument("albumId") { type = NavType.StringType },
|
||||
navArgument("coverArt") {
|
||||
type = NavType.StringType
|
||||
defaultValue = ""
|
||||
},
|
||||
),
|
||||
) { entry ->
|
||||
AlbumDetailRoute(
|
||||
albumId = entry.arguments?.getString("albumId").orEmpty(),
|
||||
coverArtId =
|
||||
entry.arguments
|
||||
?.getString("coverArt")
|
||||
.orEmpty()
|
||||
.ifEmpty { null },
|
||||
onBack = { navController.popBackStack() },
|
||||
)
|
||||
}
|
||||
@@ -164,7 +179,7 @@ private fun MainNavigation() {
|
||||
ArtistDetailRoute(
|
||||
artistId = entry.arguments?.getString("artistId").orEmpty(),
|
||||
onBack = { navController.popBackStack() },
|
||||
onAlbumClick = { album -> navController.navigate(Routes.album(album.id)) },
|
||||
onAlbumClick = { album -> navController.navigate(Routes.album(album.id, album.coverArt)) },
|
||||
)
|
||||
}
|
||||
composable(
|
||||
|
||||
@@ -89,6 +89,7 @@ private const val THEME_TRANSITION_MS = 100
|
||||
@Composable
|
||||
fun AlbumDetailRoute(
|
||||
albumId: String,
|
||||
coverArtId: String?,
|
||||
onBack: () -> Unit,
|
||||
viewModel: AlbumDetailViewModel = koinViewModel(key = albumId) { parametersOf(albumId) },
|
||||
playbackController: PlaybackController = koinInject(),
|
||||
@@ -97,11 +98,12 @@ fun AlbumDetailRoute(
|
||||
val songs by viewModel.songs.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
val playback by playbackController.state.collectAsStateWithLifecycle()
|
||||
val context = playback.context
|
||||
val shortcutArt = remember(coverArtId) { coverArtId?.let { viewModel.coverArt(it, true) } }
|
||||
AlbumDetailScreen(
|
||||
album = album,
|
||||
songs = songs,
|
||||
coverArt = viewModel::coverArt,
|
||||
artwork = rememberArtworkColors(viewModel.coverArt(album?.coverArt, true), THEME_TRANSITION_MS),
|
||||
artwork = rememberArtworkColors(shortcutArt ?: viewModel.coverArt(album?.coverArt, true), THEME_TRANSITION_MS),
|
||||
onBack = onBack,
|
||||
onSongClick = viewModel::play,
|
||||
playingSongId = playback.item?.id.takeIf { context?.kind == QueueKind.Album && context.refId == albumId },
|
||||
|
||||
@@ -44,6 +44,8 @@ object ArtworkSeedCache {
|
||||
this.store = store
|
||||
}
|
||||
|
||||
fun cached(cacheKey: String): Pair<Int, Int?>? = cache.get(cacheKey)
|
||||
|
||||
suspend fun seeds(
|
||||
context: Context,
|
||||
ref: CoverArtRef,
|
||||
|
||||
@@ -27,7 +27,7 @@ private const val BLOB_COUNT = 4
|
||||
private const val ACCENT_MAX_LUMINANCE = 0.18f
|
||||
private const val PRIMARY_MIN_LUMINANCE = 0.30f
|
||||
private const val MIN_GRADIENT_SATURATION = 0.30f
|
||||
private const val HERO_DARKEN_MAX = 1.0f
|
||||
private const val HERO_DARKEN_MAX = 0.88f
|
||||
private const val DARKEN_START_SCREENS = 0.5f
|
||||
private const val DARKEN_END_SCREENS = 1.5f
|
||||
private const val DARKEN_KNEE = 0.2f
|
||||
@@ -166,8 +166,10 @@ fun rememberArtworkColors(
|
||||
ref: CoverArtRef?,
|
||||
durationMillis: Int = ARTWORK_THEME_TRANSITION_MS,
|
||||
): ArtworkColors {
|
||||
val cached = remember(ref?.cacheKey) { ref?.cacheKey?.let(ArtworkSeedCache::cached) }
|
||||
val seeds by rememberArtworkSeed(ref)
|
||||
val target = remember(seeds) { seeds?.let { (primary, secondary) -> artworkColorsFromSeeds(primary, secondary) } }
|
||||
val effective = seeds ?: cached
|
||||
val target = remember(effective) { effective?.let { (primary, secondary) -> artworkColorsFromSeeds(primary, secondary) } }
|
||||
return rememberAnimatedArtworkColors(target, durationMillis)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user