mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
tint the library background and fab from the current artwork
This commit is contained in:
@@ -97,6 +97,11 @@ import com.subtracks.data.prefs.ListQuery
|
||||
import com.subtracks.data.prefs.PlaylistSort
|
||||
import com.subtracks.data.prefs.SongSort
|
||||
import com.subtracks.data.prefs.StarredFilter
|
||||
import com.subtracks.playback.PlaybackController
|
||||
import com.subtracks.ui.theme.ArtworkColors
|
||||
import com.subtracks.ui.theme.librarySurfaceColor
|
||||
import com.subtracks.ui.theme.rememberArtworkColors
|
||||
import org.koin.compose.koinInject
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
@@ -167,6 +172,7 @@ fun LibraryRoute(
|
||||
onOpenSettings: () -> Unit,
|
||||
bottomInset: Dp,
|
||||
viewModel: LibraryViewModel = koinViewModel(),
|
||||
playbackController: PlaybackController = koinInject(),
|
||||
) {
|
||||
var selectedTab by rememberSaveable { mutableStateOf(LibraryTab.Albums) }
|
||||
var previousTab by rememberSaveable { mutableStateOf(LibraryTab.Albums) }
|
||||
@@ -187,11 +193,14 @@ fun LibraryRoute(
|
||||
val term by viewModel.search(tab.listTab()).collectAsStateWithLifecycle()
|
||||
"${query.sort}|${query.descending}|${query.starred}|$term"
|
||||
}
|
||||
val playback by playbackController.state.collectAsStateWithLifecycle()
|
||||
val artwork = rememberArtworkColors(playbackController.coverArt(playback.item, thumbnail = true))
|
||||
LibraryScreen(
|
||||
selectedTab = selectedTab,
|
||||
onTabSelected = { selectedTab = it },
|
||||
syncing = syncing,
|
||||
bottomInset = bottomInset,
|
||||
artwork = artwork,
|
||||
albums = viewModel.albums.collectAsLazyPagingItems(),
|
||||
artists = viewModel.artists.collectAsLazyPagingItems(),
|
||||
songs = viewModel.songs.collectAsLazyPagingItems(),
|
||||
@@ -257,6 +266,7 @@ fun LibraryScreen(
|
||||
onClearFilters: () -> Unit = {},
|
||||
search: String = "",
|
||||
onSearchChange: (String) -> Unit = {},
|
||||
artwork: ArtworkColors? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val pagerState =
|
||||
@@ -302,7 +312,7 @@ fun LibraryScreen(
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.background(artwork?.let(::librarySurfaceColor) ?: MaterialTheme.colorScheme.background)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
) {
|
||||
Column(
|
||||
@@ -419,8 +429,8 @@ fun LibraryScreen(
|
||||
if (!searchActive) {
|
||||
FloatingActionButton(
|
||||
onClick = { showOptions = true },
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
contentColor = MaterialTheme.colorScheme.onBackground,
|
||||
containerColor = artwork?.scheme?.primary ?: MaterialTheme.colorScheme.surfaceContainerHigh,
|
||||
contentColor = artwork?.scheme?.onPrimary ?: MaterialTheme.colorScheme.onBackground,
|
||||
modifier = Modifier.align(Alignment.BottomEnd).padding(16.dp),
|
||||
) {
|
||||
Box {
|
||||
@@ -433,7 +443,7 @@ fun LibraryScreen(
|
||||
.offset(x = 4.dp, y = (-4).dp)
|
||||
.size(8.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.primary),
|
||||
.background(artwork?.scheme?.onPrimary ?: MaterialTheme.colorScheme.primary),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ private const val DARKEN_START_SCREENS = 0.5f
|
||||
private const val DARKEN_END_SCREENS = 1.5f
|
||||
private const val DARKEN_KNEE = 0.2f
|
||||
private const val PLAYER_SURFACE_SATURATION_FACTOR = 1.6f
|
||||
private const val LIBRARY_SURFACE_LIGHTNESS = 0.10f
|
||||
|
||||
@Immutable
|
||||
data class ArtworkColors(
|
||||
@@ -211,6 +212,11 @@ fun playerSurfaceColor(artwork: ArtworkColors): Color {
|
||||
return Color.hsl(hue, (saturation * PLAYER_SURFACE_SATURATION_FACTOR).coerceIn(0f, 1f), lightness)
|
||||
}
|
||||
|
||||
fun librarySurfaceColor(artwork: ArtworkColors): Color {
|
||||
val (hue, saturation, _) = artwork.scheme.surfaceContainerHigh.toHsl()
|
||||
return Color.hsl(hue, saturation, LIBRARY_SURFACE_LIGHTNESS)
|
||||
}
|
||||
|
||||
fun heroBarColor(
|
||||
artwork: ArtworkColors?,
|
||||
scrollPx: Float,
|
||||
|
||||
@@ -117,6 +117,44 @@ class AppScreenshotTest {
|
||||
composeRule.onRoot().captureRoboImage("src/test/screenshots/library_playlists.png")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun libraryWithMiniPlayer() {
|
||||
composeRule.setContent {
|
||||
SubtracksTheme {
|
||||
val artwork = artworkColorsFromSeed(Color.rgb(120, 80, 200))
|
||||
Column(Modifier.fillMaxSize()) {
|
||||
LibraryScreen(
|
||||
selectedTab = LibraryTab.Albums,
|
||||
onTabSelected = {},
|
||||
albums = remember { flowOf(PagingData.from(Fixtures.albums)) }.collectAsLazyPagingItems(),
|
||||
artists = remember { flowOf(PagingData.from(Fixtures.artists)) }.collectAsLazyPagingItems(),
|
||||
songs = remember { flowOf(PagingData.from(Fixtures.songItems)) }.collectAsLazyPagingItems(),
|
||||
playlists = remember { flowOf(PagingData.from(Fixtures.playlists)) }.collectAsLazyPagingItems(),
|
||||
coverArt = { id, _ -> id?.let { CoverArtRef(it, "test:$it") } },
|
||||
onAlbumClick = {},
|
||||
onArtistClick = {},
|
||||
onPlaylistClick = {},
|
||||
onSongClick = {},
|
||||
onSync = {},
|
||||
onOpenSettings = {},
|
||||
artwork = artwork,
|
||||
modifier = Modifier.weight(1f),
|
||||
)
|
||||
MiniPlayer(
|
||||
state = Fixtures.playbackState(),
|
||||
coverArt = CoverArtRef("art-al-kid-a", "test:art-al-kid-a"),
|
||||
artwork = artwork,
|
||||
onExpand = {},
|
||||
onPlayPause = {},
|
||||
onNext = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
awaitTag(ALBUM_COVER_TAG)
|
||||
composeRule.onRoot().captureRoboImage("src/test/screenshots/library_with_mini_player.png")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun albumDetail() {
|
||||
composeRule.setContent {
|
||||
@@ -396,6 +434,7 @@ class AppScreenshotTest {
|
||||
onSongClick = {},
|
||||
onSync = {},
|
||||
onOpenSettings = {},
|
||||
artwork = artworkColorsFromSeed(Color.rgb(120, 80, 200)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user