Use materilalKolor for monet compat color scheme
(cherry picked from commit 9a11ec8ead41cb7199e10f3c7464790a0bd3b1ad)
This commit is contained in:
@@ -265,6 +265,7 @@ 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)
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation(libs.logcat)
|
implementation(libs.logcat)
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package eu.kanade.presentation.theme
|
package eu.kanade.presentation.theme
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
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.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.ReadOnlyComposable
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.domain.ui.model.AppTheme
|
import eu.kanade.domain.ui.model.AppTheme
|
||||||
@@ -53,26 +54,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 = if (appTheme == AppTheme.MONET) {
|
val colorScheme = if (appTheme == AppTheme.MONET) {
|
||||||
MonetColorScheme(LocalContext.current)
|
MonetColorScheme(context)
|
||||||
} else {
|
} else {
|
||||||
colorSchemes.getOrDefault(appTheme, TachiyomiColorScheme)
|
colorSchemes.getOrDefault(appTheme, TachiyomiColorScheme)
|
||||||
}
|
}
|
||||||
return colorScheme.getColorScheme(
|
return colorScheme.getColorScheme(
|
||||||
isSystemInDarkTheme(),
|
isDark = isDark,
|
||||||
isAmoled,
|
isAmoled = isAmoled,
|
||||||
|
overrideDarkSurfaceContainers = appTheme != AppTheme.MONET,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ ktlint-core = "1.8.0"
|
|||||||
firebase-bom = "34.7.0"
|
firebase-bom = "34.7.0"
|
||||||
markdown = "0.39.0"
|
markdown = "0.39.0"
|
||||||
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"
|
||||||
@@ -106,6 +107,8 @@ markdown-coil = { module = "com.mikepenz:multiplatform-markdown-renderer-coil3",
|
|||||||
|
|
||||||
stringSimilarity = { module = "com.aallam.similarity:string-similarity-kotlin", version = "0.1.0" }
|
stringSimilarity = { module = "com.aallam.similarity:string-similarity-kotlin", version = "0.1.0" }
|
||||||
|
|
||||||
|
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" }
|
||||||
|
|||||||
Reference in New Issue
Block a user