[优化] 优化了Compose的主题系统,现在可以处理背景图片、纯黑暗色模式等情况
This commit is contained in:
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
@@ -29,19 +28,20 @@ import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.constant.Theme
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.ThemeConfig
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.theme.ThemeSyncer
|
||||
import io.legado.app.utils.applyOpenTint
|
||||
import io.legado.app.utils.applyTint
|
||||
import io.legado.app.utils.disableAutoFill
|
||||
import io.legado.app.utils.fullScreen
|
||||
import io.legado.app.utils.getPrefString
|
||||
import io.legado.app.utils.hideSoftInput
|
||||
import io.legado.app.utils.observeEvent
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.windowSize
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.utils.fullScreen
|
||||
import io.legado.app.utils.setNavigationBarColorAuto
|
||||
import io.legado.app.utils.setStatusBarColorAuto
|
||||
import io.legado.app.utils.themeColor
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.windowSize
|
||||
import java.io.File
|
||||
|
||||
|
||||
@@ -245,6 +245,7 @@ abstract class BaseActivity<VB : ViewBinding>(
|
||||
|
||||
open fun observeLiveBus() {
|
||||
observeEvent<String>(EventBus.RECREATE) {
|
||||
ThemeSyncer.syncAll()
|
||||
recreate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,23 @@
|
||||
package io.legado.app.base
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.graphics.scale
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import com.google.android.material.color.DynamicColorsOptions
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.EventBus
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.constant.Theme
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.ThemeConfig
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.theme.AppTheme
|
||||
import io.legado.app.ui.theme.ThemeState
|
||||
import io.legado.app.ui.theme.ThemeSyncer
|
||||
import io.legado.app.utils.disableAutoFill
|
||||
import io.legado.app.utils.fullScreen
|
||||
import io.legado.app.utils.getPrefString
|
||||
import io.legado.app.utils.observeEvent
|
||||
import io.legado.app.utils.setStatusBarColorAuto
|
||||
import io.legado.app.utils.themeColor
|
||||
import io.legado.app.utils.windowSize
|
||||
import java.io.File
|
||||
|
||||
abstract class BaseComposeActivity(
|
||||
val fullScreen: Boolean = true,
|
||||
@@ -85,7 +74,7 @@ abstract class BaseComposeActivity(
|
||||
|
||||
open fun observeLiveBus() {
|
||||
observeEvent<String>(EventBus.RECREATE) {
|
||||
ThemeState.updateThemeMode()
|
||||
ThemeSyncer.syncAll()
|
||||
recreate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -881,6 +881,15 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
appCtx.getPrefBoolean(PreferKey.pureBlack, value)
|
||||
}
|
||||
|
||||
val hasLightBg: Boolean
|
||||
get() = !appCtx.getPrefString(PreferKey.bgImage).isNullOrEmpty()
|
||||
|
||||
val hasDarkBg: Boolean
|
||||
get() = !appCtx.getPrefString(PreferKey.bgImageN).isNullOrEmpty()
|
||||
|
||||
val hasImageBg: Boolean
|
||||
get() = hasLightBg && hasDarkBg
|
||||
|
||||
var labelVisibilityMode
|
||||
get() = appCtx.getPrefString(PreferKey.labelVisibilityMode, "auto")
|
||||
set(value) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import io.legado.app.lib.prefs.ThemeCardPreference
|
||||
import io.legado.app.lib.prefs.ThemeModePreference
|
||||
import io.legado.app.lib.theme.ThemeStore
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.theme.ThemeSyncer
|
||||
import io.legado.app.ui.widget.number.NumberPickerDialog
|
||||
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
|
||||
import io.legado.app.utils.ColorUtils
|
||||
@@ -180,6 +181,7 @@ class ThemeConfigFragment : PreferenceFragmentCompat(),
|
||||
PreferKey.customMode -> handleRestartRequired()
|
||||
|
||||
PreferKey.pureBlack -> {
|
||||
ThemeSyncer.syncAll()
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
recreateActivities()
|
||||
}, 100)
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.MotionScheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.materialkolor.PaletteStyle
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.theme.colorScheme.AugustColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.CarlottaColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.ElinkColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.GRColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.KoharuColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.LemonColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.MujikaColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.PhoebeColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.SoraColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.TransparentColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.WHColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.YuukaColorScheme
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
@@ -35,30 +16,16 @@ fun AppTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val appThemeMode by ThemeState.themeMode.collectAsState()
|
||||
val isAmoled = AppConfig.pureBlack
|
||||
val isPureBlack by ThemeState.isPureBlack.collectAsState()
|
||||
val hasImageBg by ThemeState.hasImageBg.collectAsState()
|
||||
|
||||
val colorScheme = when (appThemeMode) {
|
||||
AppThemeMode.Dynamic -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
} else {
|
||||
GRColorScheme.getColorScheme(darkTheme, isAmoled)
|
||||
}
|
||||
}
|
||||
AppThemeMode.CUSTOM -> {
|
||||
CustomColorScheme(
|
||||
context = context,
|
||||
seed = context.primaryColor,
|
||||
style = PaletteStyle.Vibrant,
|
||||
).getColorScheme(darkTheme, isAmoled)
|
||||
}
|
||||
else -> {
|
||||
val scheme = colorSchemes.getOrDefault(appThemeMode, GRColorScheme)
|
||||
scheme.getColorScheme(darkTheme, isAmoled)
|
||||
}
|
||||
}
|
||||
val colorScheme = ThemeManager.getColorScheme(
|
||||
mode = appThemeMode,
|
||||
darkTheme = darkTheme,
|
||||
isAmoled = isPureBlack,
|
||||
isImageBg = hasImageBg
|
||||
)
|
||||
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
@@ -67,19 +34,4 @@ fun AppTheme(
|
||||
shapes = Shapes(),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
private val colorSchemes: Map<AppThemeMode, BaseColorScheme> = mapOf(
|
||||
AppThemeMode.GR to GRColorScheme,
|
||||
AppThemeMode.Lemon to LemonColorScheme,
|
||||
AppThemeMode.WH to WHColorScheme,
|
||||
AppThemeMode.Elink to ElinkColorScheme,
|
||||
AppThemeMode.Sora to SoraColorScheme,
|
||||
AppThemeMode.August to AugustColorScheme,
|
||||
AppThemeMode.Carlotta to CarlottaColorScheme,
|
||||
AppThemeMode.Koharu to KoharuColorScheme,
|
||||
AppThemeMode.Yuuka to YuukaColorScheme,
|
||||
AppThemeMode.Phoebe to PhoebeColorScheme,
|
||||
AppThemeMode.Mujika to MujikaColorScheme,
|
||||
AppThemeMode.Transparent to TransparentColorScheme,
|
||||
)
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package io.legado.app.ui.theme
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
abstract class BaseColorScheme {
|
||||
abstract val lightScheme: ColorScheme
|
||||
@@ -11,17 +10,7 @@ abstract class BaseColorScheme {
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun getColorScheme(
|
||||
darkTheme: Boolean,
|
||||
isAmoled: Boolean,
|
||||
): ColorScheme {
|
||||
var scheme = if (darkTheme) darkScheme else lightScheme
|
||||
if (darkTheme && isAmoled) {
|
||||
scheme = scheme.copy(
|
||||
background = Color.Black,
|
||||
surface = Color.Black,
|
||||
)
|
||||
}
|
||||
return scheme
|
||||
fun getColorScheme(darkTheme: Boolean): ColorScheme {
|
||||
return if (darkTheme) darkScheme else lightScheme
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,51 +3,42 @@ package io.legado.app.ui.theme
|
||||
import android.app.UiModeManager
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.core.content.getSystemService
|
||||
import com.materialkolor.Contrast
|
||||
import com.materialkolor.PaletteStyle
|
||||
import com.materialkolor.dynamicColorScheme
|
||||
|
||||
internal class CustomColorScheme(
|
||||
class CustomColorScheme(
|
||||
context: Context,
|
||||
seed: Int,
|
||||
style: PaletteStyle,
|
||||
) : BaseColorScheme() {
|
||||
private val custom = CustomCompatColorScheme(context, seed, style)
|
||||
|
||||
override val darkScheme
|
||||
get() = custom.darkScheme
|
||||
private val contrastLevel: Double =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
context.getSystemService<UiModeManager>()
|
||||
?.contrast
|
||||
?.toDouble()
|
||||
?: Contrast.Default.value
|
||||
} else {
|
||||
Contrast.Default.value
|
||||
}
|
||||
|
||||
override val lightScheme
|
||||
get() = custom.lightScheme
|
||||
}
|
||||
|
||||
private class CustomCompatColorScheme(
|
||||
context: Context,
|
||||
seed: Int,
|
||||
style: PaletteStyle,
|
||||
) : BaseColorScheme() {
|
||||
override val lightScheme = dynamicColorScheme(
|
||||
override val lightScheme: ColorScheme = dynamicColorScheme(
|
||||
seedColor = Color(seed),
|
||||
isDark = false,
|
||||
isAmoled = false,
|
||||
style = style,
|
||||
contrastLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
context.getSystemService<UiModeManager>()?.contrast?.toDouble() ?: Contrast.Default.value
|
||||
} else {
|
||||
Contrast.Default.value
|
||||
},
|
||||
contrastLevel = contrastLevel
|
||||
)
|
||||
override val darkScheme = dynamicColorScheme(
|
||||
|
||||
override val darkScheme: ColorScheme = dynamicColorScheme(
|
||||
seedColor = Color(seed),
|
||||
isDark = true,
|
||||
isAmoled = false,
|
||||
style = style,
|
||||
contrastLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
context.getSystemService<UiModeManager>()?.contrast?.toDouble() ?: Contrast.Default.value
|
||||
} else {
|
||||
Contrast.Default.value
|
||||
},
|
||||
contrastLevel = contrastLevel
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.materialkolor.PaletteStyle
|
||||
import io.legado.app.lib.theme.primaryColor
|
||||
import io.legado.app.ui.theme.colorScheme.AugustColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.CarlottaColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.ElinkColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.GRColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.KoharuColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.LemonColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.MujikaColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.PhoebeColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.SoraColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.TransparentColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.WHColorScheme
|
||||
import io.legado.app.ui.theme.colorScheme.YuukaColorScheme
|
||||
|
||||
object ThemeManager {
|
||||
|
||||
val colorSchemes: Map<AppThemeMode, BaseColorScheme> = mapOf(
|
||||
AppThemeMode.GR to GRColorScheme,
|
||||
AppThemeMode.Lemon to LemonColorScheme,
|
||||
AppThemeMode.WH to WHColorScheme,
|
||||
AppThemeMode.Elink to ElinkColorScheme,
|
||||
AppThemeMode.Sora to SoraColorScheme,
|
||||
AppThemeMode.August to AugustColorScheme,
|
||||
AppThemeMode.Carlotta to CarlottaColorScheme,
|
||||
AppThemeMode.Koharu to KoharuColorScheme,
|
||||
AppThemeMode.Yuuka to YuukaColorScheme,
|
||||
AppThemeMode.Phoebe to PhoebeColorScheme,
|
||||
AppThemeMode.Mujika to MujikaColorScheme,
|
||||
AppThemeMode.Transparent to TransparentColorScheme,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun getColorScheme(
|
||||
mode: AppThemeMode,
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
isAmoled: Boolean,
|
||||
isImageBg: Boolean,
|
||||
forceOpaque: Boolean = false
|
||||
): ColorScheme {
|
||||
val context = LocalContext.current
|
||||
|
||||
val actualMode = if (forceOpaque && mode == AppThemeMode.Transparent) {
|
||||
AppThemeMode.WH
|
||||
} else {
|
||||
mode
|
||||
}
|
||||
|
||||
var scheme = when (actualMode) {
|
||||
AppThemeMode.Dynamic -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(
|
||||
context
|
||||
)
|
||||
} else GRColorScheme.getColorScheme(darkTheme)
|
||||
}
|
||||
|
||||
AppThemeMode.CUSTOM -> {
|
||||
CustomColorScheme(context, context.primaryColor, PaletteStyle.Vibrant)
|
||||
.getColorScheme(darkTheme)
|
||||
}
|
||||
|
||||
else -> (colorSchemes[actualMode] ?: GRColorScheme).getColorScheme(darkTheme)
|
||||
}
|
||||
|
||||
if (darkTheme && isAmoled) {
|
||||
scheme = scheme.copy(
|
||||
surface = Color.Black,
|
||||
background = Color.Black,
|
||||
surfaceContainerLow = Color(0xFF0A0A0A),
|
||||
surfaceContainer = Color(0xFF121212)
|
||||
)
|
||||
}
|
||||
|
||||
return if (!forceOpaque && (isImageBg || actualMode == AppThemeMode.Transparent)) {
|
||||
scheme.copy(
|
||||
surface = Color.Transparent,
|
||||
background = Color.Transparent,
|
||||
surfaceContainerLow = Color.Transparent,
|
||||
surfaceContainer = Color.Transparent
|
||||
)
|
||||
} else {
|
||||
scheme
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
object ThemeResolver {
|
||||
|
||||
fun resolveThemeMode(value: String): AppThemeMode = when (value) {
|
||||
"0" -> AppThemeMode.Dynamic
|
||||
"1" -> AppThemeMode.GR
|
||||
"2" -> AppThemeMode.Lemon
|
||||
"3" -> AppThemeMode.WH
|
||||
"4" -> AppThemeMode.Elink
|
||||
"5" -> AppThemeMode.Sora
|
||||
"6" -> AppThemeMode.August
|
||||
"7" -> AppThemeMode.Carlotta
|
||||
"8" -> AppThemeMode.Koharu
|
||||
"9" -> AppThemeMode.Yuuka
|
||||
"10" -> AppThemeMode.Phoebe
|
||||
"11" -> AppThemeMode.Mujika
|
||||
"12" -> AppThemeMode.CUSTOM
|
||||
"13" -> AppThemeMode.Transparent
|
||||
else -> AppThemeMode.Dynamic
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,42 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import splitties.init.appCtx
|
||||
|
||||
object ThemeState {
|
||||
|
||||
private val _themeMode = MutableStateFlow(resolveThemeMode(AppConfig.AppTheme.toString()))
|
||||
private val _themeMode =
|
||||
MutableStateFlow(ThemeResolver.resolveThemeMode(AppConfig.AppTheme.toString()))
|
||||
val themeMode: StateFlow<AppThemeMode> = _themeMode.asStateFlow()
|
||||
|
||||
fun updateThemeMode() {
|
||||
val newMode = resolveThemeMode(AppConfig.AppTheme.toString())
|
||||
private val _isPureBlack =
|
||||
MutableStateFlow(appCtx.getPrefBoolean(PreferKey.pureBlack, false))
|
||||
val isPureBlack: StateFlow<Boolean> = _isPureBlack.asStateFlow()
|
||||
|
||||
private val _hasImageBg =
|
||||
MutableStateFlow(AppConfig.hasImageBg)
|
||||
val hasImageBg: StateFlow<Boolean> = _hasImageBg.asStateFlow()
|
||||
|
||||
fun updateThemeMode(newMode: AppThemeMode) {
|
||||
if (_themeMode.value != newMode) {
|
||||
_themeMode.value = newMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveThemeMode(value: String): AppThemeMode = when (value) {
|
||||
"0" -> AppThemeMode.Dynamic
|
||||
"1" -> AppThemeMode.GR
|
||||
"2" -> AppThemeMode.Lemon
|
||||
"3" -> AppThemeMode.WH
|
||||
"4" -> AppThemeMode.Elink
|
||||
"5" -> AppThemeMode.Sora
|
||||
"6" -> AppThemeMode.August
|
||||
"7" -> AppThemeMode.Carlotta
|
||||
"8" -> AppThemeMode.Koharu
|
||||
"9" -> AppThemeMode.Yuuka
|
||||
"10" -> AppThemeMode.Phoebe
|
||||
"11" -> AppThemeMode.Mujika
|
||||
"12" -> AppThemeMode.CUSTOM
|
||||
"13" -> AppThemeMode.Transparent
|
||||
else -> AppThemeMode.Dynamic
|
||||
}
|
||||
fun updatePureBlack(enabled: Boolean) {
|
||||
if (_isPureBlack.value != enabled) {
|
||||
_isPureBlack.value = enabled
|
||||
}
|
||||
}
|
||||
|
||||
fun updateImageBg(enabled: Boolean) {
|
||||
if (_hasImageBg.value != enabled) {
|
||||
_hasImageBg.value = enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.legado.app.ui.theme
|
||||
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import splitties.init.appCtx
|
||||
|
||||
object ThemeSyncer {
|
||||
|
||||
fun syncAll() {
|
||||
syncThemeMode()
|
||||
syncPureBlack()
|
||||
syncImageBg()
|
||||
}
|
||||
|
||||
fun syncThemeMode() {
|
||||
ThemeState.updateThemeMode(
|
||||
ThemeResolver.resolveThemeMode(AppConfig.AppTheme.toString())
|
||||
)
|
||||
}
|
||||
|
||||
fun syncPureBlack() {
|
||||
ThemeState.updatePureBlack(appCtx.getPrefBoolean(PreferKey.pureBlack, false))
|
||||
}
|
||||
|
||||
fun syncImageBg() {
|
||||
ThemeState.updateImageBg(AppConfig.hasImageBg)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.legado.app.ui.widget.components
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -12,10 +11,10 @@ import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -73,7 +72,7 @@ fun TextCard(
|
||||
Spacer(modifier = Modifier.width(spacing))
|
||||
}
|
||||
|
||||
Text(
|
||||
AnimatedText(
|
||||
text = text,
|
||||
style = textStyle,
|
||||
color = contentColor,
|
||||
|
||||
+20
-5
@@ -1,20 +1,35 @@
|
||||
package io.legado.app.ui.widget.components.exportComponents
|
||||
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
|
||||
import androidx.compose.material.icons.filled.CloudUpload
|
||||
import androidx.compose.material.icons.filled.FolderOpen
|
||||
import androidx.compose.material.icons.filled.SaveAlt
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.legado.app.R
|
||||
import io.legado.app.ui.widget.components.modalBottomSheet.GlobalModalBottomSheet
|
||||
|
||||
enum class FilePickerSheetMode {
|
||||
DIR, FILE, EXPORT
|
||||
@@ -31,10 +46,10 @@ fun FilePickerSheet(
|
||||
onUpload: (() -> Unit)? = null,
|
||||
allowExtensions: Array<String>? = null,
|
||||
) {
|
||||
ModalBottomSheet(
|
||||
GlobalModalBottomSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
containerColor = { it.surface }
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package io.legado.app.ui.widget.components.modalBottomSheet
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.MaterialExpressiveTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.MotionScheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import io.legado.app.ui.theme.ThemeManager
|
||||
import io.legado.app.ui.theme.ThemeState
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun GlobalModalBottomSheet(
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
sheetState: SheetState = rememberModalBottomSheetState(),
|
||||
containerColor: (ColorScheme) -> Color = { it.surfaceContainerLow },
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val themeMode by ThemeState.themeMode.collectAsState()
|
||||
val isPureBlack by ThemeState.isPureBlack.collectAsState()
|
||||
val hasImageBg by ThemeState.hasImageBg.collectAsState()
|
||||
|
||||
val colorScheme = ThemeManager.getColorScheme(
|
||||
mode = themeMode,
|
||||
isAmoled = isPureBlack,
|
||||
isImageBg = hasImageBg,
|
||||
forceOpaque = true
|
||||
)
|
||||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = containerColor(colorScheme),
|
||||
contentColor = colorScheme.onSurface
|
||||
) {
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = Typography(),
|
||||
motionScheme = MotionScheme.expressive(),
|
||||
shapes = Shapes()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize()
|
||||
.then(modifier),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user