Use materilalKolor for monet compat color scheme

(cherry picked from commit 9a11ec8ead41cb7199e10f3c7464790a0bd3b1ad)
This commit is contained in:
AntsyLich 2025-12-27 00:30:42 +06:00 committed by Cuong-Tran
parent 8eaa177ad5
commit bbb460bfd5
5 changed files with 43 additions and 91 deletions

View file

@ -289,10 +289,10 @@ dependencies {
implementation(libs.compose.grid) implementation(libs.compose.grid)
implementation(libs.reorderable) implementation(libs.reorderable)
implementation(libs.bundles.markdown) implementation(libs.bundles.markdown)
implementation(libs.materialKolor)
// KMK --> // KMK -->
implementation(libs.palette.ktx) implementation(libs.palette.ktx)
implementation(libs.materialKolor)
implementation(libs.haze) implementation(libs.haze)
implementation(compose.colorpicker) implementation(compose.colorpicker)
implementation(projects.flagkit) implementation(projects.flagkit)

View file

@ -1,13 +1,14 @@
package eu.kanade.presentation.theme package eu.kanade.presentation.theme
import android.app.UiModeManager import android.app.UiModeManager
import android.content.Context
import android.os.Build import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
@ -101,27 +102,36 @@ private fun BaseTachiyomiTheme(
isAmoled: Boolean, isAmoled: Boolean,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val context = LocalContext.current
val isDark = isSystemInDarkTheme()
MaterialTheme( MaterialTheme(
colorScheme = getThemeColorScheme(appTheme, isAmoled), colorScheme = remember(appTheme, isDark, isAmoled) {
getThemeColorScheme(
context = context,
appTheme = appTheme,
isDark = isDark,
isAmoled = isAmoled,
)
},
content = content, content = content,
) )
} }
@Composable
@ReadOnlyComposable
private fun getThemeColorScheme( private fun getThemeColorScheme(
context: Context,
appTheme: AppTheme, appTheme: AppTheme,
isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
): ColorScheme { ): ColorScheme {
val colorScheme = when (appTheme) { val colorScheme = when (appTheme) {
AppTheme.MONET -> { AppTheme.MONET -> {
MonetColorScheme(LocalContext.current) MonetColorScheme(context)
} }
// KMK --> // KMK -->
AppTheme.CUSTOM -> { AppTheme.CUSTOM -> {
val uiPreferences = Injekt.get<UiPreferences>() val uiPreferences = Injekt.get<UiPreferences>()
CustomColorScheme( CustomColorScheme(
context = LocalContext.current, context = context,
seed = uiPreferences.colorTheme().get(), seed = uiPreferences.colorTheme().get(),
style = uiPreferences.customThemeStyle().get(), style = uiPreferences.customThemeStyle().get(),
) )
@ -132,8 +142,9 @@ private fun getThemeColorScheme(
} }
} }
return colorScheme.getColorScheme( return colorScheme.getColorScheme(
isSystemInDarkTheme(), isDark = isDark,
isAmoled, isAmoled = isAmoled,
overrideDarkSurfaceContainers = appTheme != AppTheme.MONET,
) )
} }

View file

@ -14,16 +14,25 @@ internal abstract class BaseColorScheme {
private val surfaceContainerHigh = Color(0xFF131313) private val surfaceContainerHigh = Color(0xFF131313)
private val surfaceContainerHighest = Color(0xFF1B1B1B) private val surfaceContainerHighest = Color(0xFF1B1B1B)
fun getColorScheme(isDark: Boolean, isAmoled: Boolean): ColorScheme { fun getColorScheme(
isDark: Boolean,
isAmoled: Boolean,
overrideDarkSurfaceContainers: Boolean,
): ColorScheme {
if (!isDark) return lightScheme if (!isDark) return lightScheme
if (!isAmoled) return darkScheme if (!isAmoled) return darkScheme
return darkScheme.copy( val amoledScheme = darkScheme.copy(
background = Color.Black, background = Color.Black,
onBackground = Color.White, onBackground = Color.White,
surface = Color.Black, surface = Color.Black,
onSurface = Color.White, onSurface = Color.White,
)
if (!overrideDarkSurfaceContainers) return amoledScheme
return amoledScheme.copy(
surfaceVariant = surfaceContainer, // Navigation bar background (ThemePrefWidget) surfaceVariant = surfaceContainer, // Navigation bar background (ThemePrefWidget)
surfaceContainerLowest = surfaceContainer, surfaceContainerLowest = surfaceContainer,
surfaceContainerLow = surfaceContainer, surfaceContainerLow = surfaceContainer,

View file

@ -1,22 +1,15 @@
package eu.kanade.presentation.theme.colorscheme package eu.kanade.presentation.theme.colorscheme
import android.annotation.SuppressLint
import android.app.UiModeManager
import android.app.WallpaperManager import android.app.WallpaperManager
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import android.os.Build import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.core.content.getSystemService import com.materialkolor.ktx.DynamicScheme
import com.google.android.material.color.utilities.Hct import com.materialkolor.toColorScheme
import com.google.android.material.color.utilities.MaterialDynamicColors
import com.google.android.material.color.utilities.QuantizerCelebi
import com.google.android.material.color.utilities.SchemeContent
import com.google.android.material.color.utilities.Score
internal class MonetColorScheme(context: Context) : BaseColorScheme() { internal class MonetColorScheme(context: Context) : BaseColorScheme() {
@ -28,7 +21,7 @@ internal class MonetColorScheme(context: Context) : BaseColorScheme() {
?.primaryColor ?.primaryColor
?.toArgb() ?.toArgb()
if (seed != null) { if (seed != null) {
MonetCompatColorScheme(context, seed) MonetCompatColorScheme(Color(seed))
} else { } else {
TachiyomiColorScheme TachiyomiColorScheme
} }
@ -41,19 +34,6 @@ internal class MonetColorScheme(context: Context) : BaseColorScheme() {
override val lightScheme override val lightScheme
get() = monet.lightScheme get() = monet.lightScheme
companion object {
@Suppress("Unused")
@SuppressLint("RestrictedApi")
fun extractSeedColorFromImage(bitmap: Bitmap): Int? {
val width = bitmap.width
val height = bitmap.height
val bitmapPixels = IntArray(width * height)
bitmap.getPixels(bitmapPixels, 0, width, 0, 0, width, height)
return Score.score(QuantizerCelebi.quantize(bitmapPixels, 128), 1, 0)[0]
.takeIf { it != 0 } // Don't take fallback color
}
}
} }
@RequiresApi(Build.VERSION_CODES.S) @RequiresApi(Build.VERSION_CODES.S)
@ -62,64 +42,14 @@ private class MonetSystemColorScheme(context: Context) : BaseColorScheme() {
override val darkScheme = dynamicDarkColorScheme(context) override val darkScheme = dynamicDarkColorScheme(context)
} }
private class MonetCompatColorScheme(context: Context, seed: Int) : BaseColorScheme() { internal class MonetCompatColorScheme(seed: Color) : BaseColorScheme() {
override val lightScheme = generateColorSchemeFromSeed(seed = seed, dark = false)
override val lightScheme = generateColorSchemeFromSeed(context = context, seed = seed, dark = false) override val darkScheme = generateColorSchemeFromSeed(seed = seed, dark = true)
override val darkScheme = generateColorSchemeFromSeed(context = context, seed = seed, dark = true)
companion object { companion object {
private fun Int.toComposeColor(): Color = Color(this) fun generateColorSchemeFromSeed(seed: Color, dark: Boolean): ColorScheme {
return DynamicScheme(seedColor = seed, isDark = dark)
@SuppressLint("PrivateResource", "RestrictedApi") .toColorScheme(isAmoled = false)
private fun generateColorSchemeFromSeed(context: Context, seed: Int, dark: Boolean): ColorScheme {
val scheme = SchemeContent(
Hct.fromInt(seed),
dark,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
context.getSystemService<UiModeManager>()?.contrast?.toDouble() ?: 0.0
} else {
0.0
},
)
val dynamicColors = MaterialDynamicColors()
return ColorScheme(
primary = dynamicColors.primary().getArgb(scheme).toComposeColor(),
onPrimary = dynamicColors.onPrimary().getArgb(scheme).toComposeColor(),
primaryContainer = dynamicColors.primaryContainer().getArgb(scheme).toComposeColor(),
onPrimaryContainer = dynamicColors.onPrimaryContainer().getArgb(scheme).toComposeColor(),
inversePrimary = dynamicColors.inversePrimary().getArgb(scheme).toComposeColor(),
secondary = dynamicColors.secondary().getArgb(scheme).toComposeColor(),
onSecondary = dynamicColors.onSecondary().getArgb(scheme).toComposeColor(),
secondaryContainer = dynamicColors.secondaryContainer().getArgb(scheme).toComposeColor(),
onSecondaryContainer = dynamicColors.onSecondaryContainer().getArgb(scheme).toComposeColor(),
tertiary = dynamicColors.tertiary().getArgb(scheme).toComposeColor(),
onTertiary = dynamicColors.onTertiary().getArgb(scheme).toComposeColor(),
tertiaryContainer = dynamicColors.tertiary().getArgb(scheme).toComposeColor(),
onTertiaryContainer = dynamicColors.onTertiaryContainer().getArgb(scheme).toComposeColor(),
background = dynamicColors.background().getArgb(scheme).toComposeColor(),
onBackground = dynamicColors.onBackground().getArgb(scheme).toComposeColor(),
surface = dynamicColors.surface().getArgb(scheme).toComposeColor(),
onSurface = dynamicColors.onSurface().getArgb(scheme).toComposeColor(),
surfaceVariant = dynamicColors.surfaceVariant().getArgb(scheme).toComposeColor(),
onSurfaceVariant = dynamicColors.onSurfaceVariant().getArgb(scheme).toComposeColor(),
surfaceTint = dynamicColors.surfaceTint().getArgb(scheme).toComposeColor(),
inverseSurface = dynamicColors.inverseSurface().getArgb(scheme).toComposeColor(),
inverseOnSurface = dynamicColors.inverseOnSurface().getArgb(scheme).toComposeColor(),
error = dynamicColors.error().getArgb(scheme).toComposeColor(),
onError = dynamicColors.onError().getArgb(scheme).toComposeColor(),
errorContainer = dynamicColors.errorContainer().getArgb(scheme).toComposeColor(),
onErrorContainer = dynamicColors.onErrorContainer().getArgb(scheme).toComposeColor(),
outline = dynamicColors.outline().getArgb(scheme).toComposeColor(),
outlineVariant = dynamicColors.outlineVariant().getArgb(scheme).toComposeColor(),
scrim = Color.Black,
surfaceBright = dynamicColors.surfaceBright().getArgb(scheme).toComposeColor(),
surfaceDim = dynamicColors.surfaceDim().getArgb(scheme).toComposeColor(),
surfaceContainer = dynamicColors.surfaceContainer().getArgb(scheme).toComposeColor(),
surfaceContainerHigh = dynamicColors.surfaceContainerHigh().getArgb(scheme).toComposeColor(),
surfaceContainerHighest = dynamicColors.surfaceContainerHighest().getArgb(scheme).toComposeColor(),
surfaceContainerLow = dynamicColors.surfaceContainerLow().getArgb(scheme).toComposeColor(),
surfaceContainerLowest = dynamicColors.surfaceContainerLowest().getArgb(scheme).toComposeColor(),
)
} }
} }
} }

View file

@ -12,6 +12,7 @@ ktlint-core = "1.8.0"
firebase-bom = "34.5.0" firebase-bom = "34.5.0"
markdown = "0.38.1" markdown = "0.38.1"
junit = "6.0.1" junit = "6.0.1"
materialKolor = "5.0.0-alpha04"
[libraries] [libraries]
desugar = "com.android.tools:desugar_jdk_libs:2.1.5" desugar = "com.android.tools:desugar_jdk_libs:2.1.5"
@ -65,7 +66,6 @@ compose-webview = "io.github.kevinnzou:compose-webview:0.33.6"
compose-grid = "io.woong.compose.grid:grid:1.2.2" compose-grid = "io.woong.compose.grid:grid:1.2.2"
reorderable = { module = "sh.calvin.reorderable:reorderable", version = "3.0.0" } reorderable = { module = "sh.calvin.reorderable:reorderable", version = "3.0.0" }
palette-ktx = "androidx.palette:palette-ktx:1.0.0" palette-ktx = "androidx.palette:palette-ktx:1.0.0"
materialKolor = "com.materialkolor:material-kolor:4.0.3"
haze = "dev.chrisbanes.haze:haze:1.6.10" haze = "dev.chrisbanes.haze:haze:1.6.10"
swipe = "me.saket.swipe:swipe:1.3.0" swipe = "me.saket.swipe:swipe:1.3.0"
@ -108,6 +108,8 @@ ktlint-core = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlin
markdown-core = { module = "com.mikepenz:multiplatform-markdown-renderer", version.ref = "markdown" } markdown-core = { module = "com.mikepenz:multiplatform-markdown-renderer", version.ref = "markdown" }
markdown-coil = { module = "com.mikepenz:multiplatform-markdown-renderer-coil3", version.ref = "markdown" } markdown-coil = { module = "com.mikepenz:multiplatform-markdown-renderer-coil3", version.ref = "markdown" }
materialKolor = { module = "com.materialkolor:material-kolor", version.ref = "materialKolor" }
[plugins] [plugins]
google-services = { id = "com.google.gms.google-services", version = "4.4.4" } google-services = { id = "com.google.gms.google-services", version = "4.4.4" }
aboutLibraries = { id = "com.mikepenz.aboutlibraries.plugin.android", version.ref = "aboutlib_version" } aboutLibraries = { id = "com.mikepenz.aboutlibraries.plugin.android", version.ref = "aboutlib_version" }