mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 23:21:59 +01:00
default to the Material You dark scheme instead of black and white
This commit is contained in:
@@ -95,7 +95,7 @@ fun HeroDetailScaffold(
|
||||
content: LazyListScope.(rowModifier: Modifier) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val effectiveArtwork = artwork ?: baseArtworkColors
|
||||
val effectiveArtwork = artwork ?: baseArtworkColors()
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||
ArtworkTheme(effectiveArtwork) {
|
||||
BoxWithConstraints(modifier.fillMaxSize().background(Color.Black)) {
|
||||
|
||||
@@ -272,7 +272,7 @@ fun ArtistDetailScreen(
|
||||
)
|
||||
val nameBusy = rememberOverlaidNameBusy(artThumbnail ?: art)
|
||||
val nameScrimAlpha by animateFloatAsState(if (nameBusy) 1f else 0f, tween(SCRIM_FADE_MS), label = "artistNameScrim")
|
||||
val effectiveArtwork = artwork ?: baseArtworkColors
|
||||
val effectiveArtwork = artwork ?: baseArtworkColors()
|
||||
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onBackground) {
|
||||
ArtworkTheme(effectiveArtwork) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.subtracks.ui.theme
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -16,29 +17,35 @@ const val ARTWORK_THEME_TRANSITION_MS = 600
|
||||
|
||||
private const val TRANSITION_STEPS = 24
|
||||
|
||||
internal val baseArtworkColors =
|
||||
ArtworkColors(
|
||||
scheme = SubtracksColorScheme,
|
||||
gradientHigh = SubtracksColorScheme.surfaceContainerHigh,
|
||||
gradientLow = SubtracksColorScheme.background,
|
||||
accents = listOf(SubtracksColorScheme.surfaceContainerHighest, SubtracksColorScheme.surfaceContainerLow),
|
||||
darkPrimary = SubtracksColorScheme.background,
|
||||
blobSeed = 0,
|
||||
)
|
||||
@Composable
|
||||
internal fun baseArtworkColors(): ArtworkColors {
|
||||
val scheme = MaterialTheme.colorScheme
|
||||
return remember(scheme) {
|
||||
ArtworkColors(
|
||||
scheme = scheme,
|
||||
gradientHigh = scheme.surfaceContainerHigh,
|
||||
gradientLow = scheme.background,
|
||||
accents = listOf(scheme.surfaceContainerHighest, scheme.surfaceContainerLow),
|
||||
darkPrimary = scheme.background,
|
||||
blobSeed = 0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun rememberAnimatedArtworkColors(
|
||||
target: ArtworkColors?,
|
||||
base: ArtworkColors,
|
||||
durationMillis: Int = ARTWORK_THEME_TRANSITION_MS,
|
||||
): ArtworkColors {
|
||||
var from by remember { mutableStateOf(target ?: baseArtworkColors) }
|
||||
var to by remember { mutableStateOf(target ?: baseArtworkColors) }
|
||||
var from by remember { mutableStateOf(target ?: base) }
|
||||
var to by remember { mutableStateOf(target ?: base) }
|
||||
val progress = remember { Animatable(1f) }
|
||||
|
||||
LaunchedEffect(target, durationMillis) {
|
||||
val next = target ?: baseArtworkColors
|
||||
LaunchedEffect(target, base, durationMillis) {
|
||||
val next = target ?: base
|
||||
if (next !== to) {
|
||||
if (to === baseArtworkColors) {
|
||||
if (to === base) {
|
||||
from = next
|
||||
to = next
|
||||
} else {
|
||||
|
||||
@@ -194,7 +194,8 @@ fun rememberArtworkColors(
|
||||
}
|
||||
}
|
||||
val target = remember(effective) { effective?.let { (primary, secondary) -> artworkColorsFromSeeds(primary, secondary) } }
|
||||
val colors = rememberAnimatedArtworkColors(target, durationMillis)
|
||||
val base = baseArtworkColors()
|
||||
val colors = rememberAnimatedArtworkColors(target, base, durationMillis)
|
||||
return if (target == null) null else colors
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.subtracks.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val Black = Color(0xFF000000)
|
||||
val NearBlack = Color(0xFF0A0A0A)
|
||||
val DarkGrey = Color(0xFF1A1A1A)
|
||||
val MidGrey = Color(0xFF2C2C2C)
|
||||
val LightGrey = Color(0xFF9E9E9E)
|
||||
val White = Color(0xFFFFFFFF)
|
||||
@@ -1,40 +1,26 @@
|
||||
package com.subtracks.ui.theme
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
internal val SubtracksColorScheme =
|
||||
darkColorScheme(
|
||||
primary = White,
|
||||
onPrimary = Black,
|
||||
primaryContainer = White,
|
||||
onPrimaryContainer = Black,
|
||||
secondary = White,
|
||||
onSecondary = Black,
|
||||
secondaryContainer = White,
|
||||
onSecondaryContainer = Black,
|
||||
tertiary = White,
|
||||
onTertiary = Black,
|
||||
background = Black,
|
||||
onBackground = White,
|
||||
surface = Black,
|
||||
onSurface = White,
|
||||
surfaceVariant = DarkGrey,
|
||||
onSurfaceVariant = LightGrey,
|
||||
surfaceContainerLowest = Black,
|
||||
surfaceContainerLow = NearBlack,
|
||||
surfaceContainer = NearBlack,
|
||||
surfaceContainerHigh = DarkGrey,
|
||||
surfaceContainerHighest = MidGrey,
|
||||
outline = MidGrey,
|
||||
outlineVariant = DarkGrey,
|
||||
)
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
||||
@Composable
|
||||
fun SubtracksTheme(content: @Composable () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val colorScheme =
|
||||
remember(context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
dynamicDarkColorScheme(context)
|
||||
} else {
|
||||
darkColorScheme()
|
||||
}
|
||||
}
|
||||
MaterialTheme(
|
||||
colorScheme = SubtracksColorScheme,
|
||||
colorScheme = colorScheme,
|
||||
typography = SubtracksTypography,
|
||||
content = content,
|
||||
)
|
||||
|
||||
@@ -68,7 +68,9 @@ class ArtworkExtractionTest {
|
||||
val ref = CoverArtRef(url = "art", cacheKey = "art")
|
||||
var colors: ArtworkColors? = null
|
||||
composeRule.setContent {
|
||||
colors = rememberArtworkColors(ref)
|
||||
SubtracksTheme {
|
||||
colors = rememberArtworkColors(ref)
|
||||
}
|
||||
}
|
||||
composeRule.waitUntil(timeoutMillis = 5_000) { colors != null }
|
||||
assertNotNull(colors)
|
||||
@@ -99,15 +101,18 @@ class ArtworkExtractionTest {
|
||||
val artwork = mutableStateOf<ArtworkColors?>(null)
|
||||
val seen = mutableListOf<androidx.compose.ui.graphics.Color>()
|
||||
composeRule.setContent {
|
||||
val colors = rememberAnimatedArtworkColors(artwork.value)
|
||||
SideEffect { seen += colors.scheme.background }
|
||||
SubtracksTheme {
|
||||
val colors = rememberAnimatedArtworkColors(artwork.value, baseArtworkColors())
|
||||
SideEffect { seen += colors.scheme.background }
|
||||
}
|
||||
}
|
||||
composeRule.waitForIdle()
|
||||
val baseBackground = seen.first()
|
||||
|
||||
composeRule.runOnIdle { artwork.value = target }
|
||||
composeRule.waitForIdle()
|
||||
|
||||
val firstPainting = seen.first { it != baseArtworkColors.scheme.background }
|
||||
val firstPainting = seen.first { it != baseBackground }
|
||||
assertEquals(target.scheme.background, firstPainting)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.subtracks.ui.theme
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ThemeTest {
|
||||
@get:Rule
|
||||
val composeRule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun defaultSchemeIsNotMonochrome() {
|
||||
var scheme: ColorScheme? = null
|
||||
composeRule.setContent {
|
||||
SubtracksTheme {
|
||||
scheme = MaterialTheme.colorScheme
|
||||
}
|
||||
}
|
||||
val resolved = requireNotNull(scheme)
|
||||
assertNotEquals(Color.White, resolved.primary)
|
||||
assertNotEquals(Color.Black, resolved.background)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user