Combine light/dark themes in enum

Also combined the strawberry themes
This commit is contained in:
Jays2Kings 2021-07-14 15:15:48 -04:00
parent 9f26d142e2
commit b489e5bb56
7 changed files with 109 additions and 70 deletions

View File

@ -120,8 +120,8 @@ class PreferencesHelper(val context: Context) {
fun themeDarkAmoled() = flowPrefs.getBoolean(Keys.themeDarkAmoled, false) fun themeDarkAmoled() = flowPrefs.getBoolean(Keys.themeDarkAmoled, false)
fun lightTheme() = flowPrefs.getEnum(Keys.lightTheme, Themes.PURE_WHITE) fun lightTheme() = flowPrefs.getEnum(Keys.lightTheme, Themes.DEFAULT)
fun darkTheme() = flowPrefs.getEnum(Keys.darkTheme, Themes.DARK) fun darkTheme() = flowPrefs.getEnum(Keys.darkTheme, Themes.DEFAULT)
fun pageTransitions() = flowPrefs.getBoolean(Keys.enableTransitions, true) fun pageTransitions() = flowPrefs.getBoolean(Keys.enableTransitions, true)

View File

@ -53,36 +53,45 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
fastAdapterDark = FastAdapter.with(itemAdapterDark) fastAdapterDark = FastAdapter.with(itemAdapterDark)
fastAdapterLight.setHasStableIds(true) fastAdapterLight.setHasStableIds(true)
fastAdapterDark.setHasStableIds(true) fastAdapterDark.setHasStableIds(true)
selectExtensionLight = fastAdapterLight.getSelectExtension().setThemeListener() selectExtensionLight = fastAdapterLight.getSelectExtension().setThemeListener(false)
selectExtensionDark = fastAdapterDark.getSelectExtension().setThemeListener() selectExtensionDark = fastAdapterDark.getSelectExtension().setThemeListener(true)
val enumConstants = Themes.values() val enumConstants = Themes.values()
itemAdapterLight.set(enumConstants.filter { !it.isDarkTheme }.map(::ThemeItem)) itemAdapterLight.set(
itemAdapterDark.set(enumConstants.filter { it.isDarkTheme }.map(::ThemeItem)) enumConstants
.filter { !it.isDarkTheme || it.followsSystem }
.map { ThemeItem(it, false) }
)
itemAdapterDark.set(
enumConstants
.filter { it.isDarkTheme || it.followsSystem }
.map { ThemeItem(it, true) }
)
isSelectable = false isSelectable = false
} }
private fun SelectExtension<ThemeItem>.setThemeListener(): SelectExtension<ThemeItem> { private fun SelectExtension<ThemeItem>.setThemeListener(isDarkMode: Boolean): SelectExtension<ThemeItem> {
isSelectable = true isSelectable = true
multiSelect = true multiSelect = true
val nightMode = if (isDarkMode) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO
selectionListener = object : ISelectionListener<ThemeItem> { selectionListener = object : ISelectionListener<ThemeItem> {
override fun onSelectionChanged(item: ThemeItem, selected: Boolean) { override fun onSelectionChanged(item: ThemeItem, selected: Boolean) {
if (item.theme.isDarkTheme) { if (isDarkMode) {
preferences.darkTheme().set(item.theme) preferences.darkTheme().set(item.theme)
} else { } else {
preferences.lightTheme().set(item.theme) preferences.lightTheme().set(item.theme)
} }
if (!selected) { if (!selected) {
preferences.nightMode().set(item.theme.nightMode) preferences.nightMode().set(nightMode)
} else if (preferences.nightMode() } else if (preferences.nightMode()
.get() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM .get() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
) { ) {
preferences.nightMode().set(item.theme.nightMode) preferences.nightMode().set(nightMode)
} }
if (( if ((
preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM && preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM &&
item.theme.nightMode != context.appDelegateNightMode() nightMode != context.appDelegateNightMode()
) || ) ||
(!selected && item.theme.nightMode == context.appDelegateNightMode()) (!selected && nightMode == context.appDelegateNightMode())
) { ) {
fastAdapterLight.notifyDataSetChanged() fastAdapterLight.notifyDataSetChanged()
fastAdapterDark.notifyDataSetChanged() fastAdapterDark.notifyDataSetChanged()
@ -155,7 +164,7 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
} }
} }
inner class ThemeItem(val theme: Themes) : AbstractItem<FastAdapter.ViewHolder<ThemeItem>>() { inner class ThemeItem(val theme: Themes, val darkTheme: Boolean) : AbstractItem<FastAdapter.ViewHolder<ThemeItem>>() {
/** defines the type defining this item. must be unique. preferably an id */ /** defines the type defining this item. must be unique. preferably an id */
override val type: Int = R.id.theme_card_view override val type: Int = R.id.theme_card_view
@ -169,15 +178,15 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
return ViewHolder(v) return ViewHolder(v)
} }
val colors = theme.getColors() val colors = theme.getColors(if (darkTheme) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
override var isSelected: Boolean override var isSelected: Boolean
get() = when (preferences.nightMode().get()) { get() = when (preferences.nightMode().get()) {
AppCompatDelegate.MODE_NIGHT_YES -> preferences.darkTheme().get() == theme AppCompatDelegate.MODE_NIGHT_YES -> preferences.darkTheme().get() == theme && darkTheme
AppCompatDelegate.MODE_NIGHT_NO -> preferences.lightTheme().get() == theme AppCompatDelegate.MODE_NIGHT_NO -> preferences.lightTheme().get() == theme && !darkTheme
else -> preferences.darkTheme().get() == theme || else -> (preferences.darkTheme().get() == theme && darkTheme) ||
preferences.lightTheme().get() == theme (preferences.lightTheme().get() == theme && !darkTheme)
} }
set(value) {} set(value) {}
@ -185,16 +194,22 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
val binding = ThemeItemBinding.bind(view) val binding = ThemeItemBinding.bind(view)
override fun bindView(item: ThemeItem, payloads: List<Any>) { override fun bindView(item: ThemeItem, payloads: List<Any>) {
binding.themeNameText.setText(item.theme.nameRes) binding.themeNameText.setText(
if (item.darkTheme) {
item.theme.darkNameRes
} else {
item.theme.nameRes
}
)
binding.checkbox.isVisible = item.isSelected binding.checkbox.isVisible = item.isSelected
binding.themeSelected.isInvisible = !item.isSelected binding.themeSelected.isInvisible = !item.isSelected
if (binding.checkbox.isVisible) { if (binding.checkbox.isVisible) {
val themeMatchesApp = if (context.isInNightMode()) { val themeMatchesApp = if (context.isInNightMode()) {
item.theme.isDarkTheme item.darkTheme
} else { } else {
!item.theme.isDarkTheme !item.darkTheme
} }
binding.themeSelected.alpha = if (themeMatchesApp) 1f else 0.5f binding.themeSelected.alpha = if (themeMatchesApp) 1f else 0.5f
binding.checkbox.alpha = if (themeMatchesApp) 1f else 0.5f binding.checkbox.alpha = if (themeMatchesApp) 1f else 0.5f
@ -220,7 +235,7 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
binding.themeItem3.imageTintList = binding.themeItem3.imageTintList =
ColorStateList.valueOf(item.colors.inactiveTab) ColorStateList.valueOf(item.colors.inactiveTab)
binding.themeLayout.setBackgroundColor(item.colors.colorBackground) binding.themeLayout.setBackgroundColor(item.colors.colorBackground)
if (item.theme.isDarkTheme && preferences.themeDarkAmoled().get()) { if (item.darkTheme && preferences.themeDarkAmoled().get()) {
binding.themeLayout.setBackgroundColor(Color.BLACK) binding.themeLayout.setBackgroundColor(Color.BLACK)
if (!ThemeUtil.isColoredTheme(item.theme)) { if (!ThemeUtil.isColoredTheme(item.theme)) {
binding.themeBottomBar.setBackgroundColor(Color.BLACK) binding.themeBottomBar.setBackgroundColor(Color.BLACK)

View File

@ -146,7 +146,7 @@ open class BaseWebViewActivity : BaseActivity<WebviewActivityBinding>() {
val lightMode = !isInNightMode() val lightMode = !isInNightMode()
val prefTheme = getPrefTheme(preferences) val prefTheme = getPrefTheme(preferences)
setTheme(prefTheme.styleRes) setTheme(prefTheme.styleRes)
if (prefTheme.isDarkTheme && preferences.themeDarkAmoled().get()) { if (!lightMode && preferences.themeDarkAmoled().get()) {
setTheme(R.style.ThemeOverlay_Tachiyomi_Amoled) setTheme(R.style.ThemeOverlay_Tachiyomi_Amoled)
if (ThemeUtil.isColoredTheme(prefTheme)) { if (ThemeUtil.isColoredTheme(prefTheme)) {
setTheme(R.style.ThemeOverlay_Tachiyomi_AllBlue) setTheme(R.style.ThemeOverlay_Tachiyomi_AllBlue)

View File

@ -5,7 +5,10 @@ import android.content.res.Resources
import android.graphics.Color import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -22,18 +25,46 @@ object ThemeUtil {
) )
preferences.lightTheme().set( preferences.lightTheme().set(
when (theme) { when (theme) {
1 -> Themes.LIGHT_BLUE 1 -> Themes.CLASSIC_BLUE
else -> Themes.PURE_WHITE else -> Themes.DEFAULT
} }
) )
preferences.darkTheme().set( preferences.darkTheme().set(
when (theme) { when (theme) {
4 -> Themes.DARK_BLUE 4 -> Themes.CLASSIC_BLUE
else -> Themes.DARK else -> Themes.DEFAULT
} }
) )
} }
/** Migration method */
fun convertNewThemes(context: Context) {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val lightTheme = prefs.getString(PreferenceKeys.lightTheme, "DEFAULT")
val darkTheme = prefs.getString(PreferenceKeys.darkTheme, "DEFAULT")
prefs.edit {
putString(
PreferenceKeys.lightTheme,
when (lightTheme) {
"SPRING" -> Themes.SPRING_AND_DUSK
"STRAWBERRY_DAIQUIRI" -> Themes.STRAWBERRIES
"LIGHT_BLUE" -> Themes.CLASSIC_BLUE
else -> Themes.DEFAULT
}.name
)
putString(
PreferenceKeys.darkTheme,
when (darkTheme) {
"DUSK" -> Themes.SPRING_AND_DUSK
"CHOCOLATE_STRAWBERRIES" -> Themes.STRAWBERRIES
"DARK_BLUE" -> Themes.CLASSIC_BLUE
else -> Themes.DEFAULT
}.name
)
}
}
fun isColoredTheme(theme: Themes): Boolean { fun isColoredTheme(theme: Themes): Boolean {
return theme.styleRes == R.style.Theme_Tachiyomi_AllBlue return theme.styleRes == R.style.Theme_Tachiyomi_AllBlue
} }
@ -68,7 +99,9 @@ fun AppCompatActivity.setThemeAndNight(preferences: PreferencesHelper) {
fun AppCompatActivity.getThemeWithExtras(theme: Resources.Theme, preferences: PreferencesHelper): Resources.Theme { fun AppCompatActivity.getThemeWithExtras(theme: Resources.Theme, preferences: PreferencesHelper): Resources.Theme {
val prefTheme = getPrefTheme(preferences) val prefTheme = getPrefTheme(preferences)
if (prefTheme.isDarkTheme && preferences.themeDarkAmoled().get()) { if ((isInNightMode() || preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_YES) &&
preferences.themeDarkAmoled().get()
) {
theme.applyStyle(R.style.ThemeOverlay_Tachiyomi_Amoled, true) theme.applyStyle(R.style.ThemeOverlay_Tachiyomi_Amoled, true)
if (ThemeUtil.isColoredTheme(prefTheme)) { if (ThemeUtil.isColoredTheme(prefTheme)) {
theme.applyStyle(R.style.ThemeOverlay_Tachiyomi_AllBlue, true) theme.applyStyle(R.style.ThemeOverlay_Tachiyomi_AllBlue, true)
@ -86,8 +119,7 @@ fun Context.getPrefTheme(preferences: PreferencesHelper): Themes {
) preferences.darkTheme() else preferences.lightTheme() ) preferences.darkTheme() else preferences.lightTheme()
).get() ).get()
} catch (e: Exception) { } catch (e: Exception) {
preferences.lightTheme().set(Themes.PURE_WHITE) ThemeUtil.convertNewThemes(preferences.context)
preferences.darkTheme().set(Themes.DARK) getPrefTheme(preferences)
Themes.PURE_WHITE
} }
} }

View File

@ -10,27 +10,23 @@ import eu.kanade.tachiyomi.R
import kotlin.math.roundToInt import kotlin.math.roundToInt
@Suppress("unused") @Suppress("unused")
enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes val nameRes: Int) { enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes val nameRes: Int, @StringRes altNameRes: Int? = null) {
PURE_WHITE(R.style.Theme_Tachiyomi, AppCompatDelegate.MODE_NIGHT_NO, R.string.white_theme), DEFAULT(
DARK(R.style.Theme_Tachiyomi, AppCompatDelegate.MODE_NIGHT_YES, R.string.dark), R.style.Theme_Tachiyomi,
SPRING( AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
R.style.Theme_Tachiyomi_MidnightDusk, R.string.white_theme,
AppCompatDelegate.MODE_NIGHT_NO, R.string.dark
R.string.spring_blossom
), ),
DUSK( SPRING_AND_DUSK(
R.style.Theme_Tachiyomi_MidnightDusk, R.style.Theme_Tachiyomi_MidnightDusk,
AppCompatDelegate.MODE_NIGHT_YES, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
R.string.spring_blossom,
R.string.midnight_dusk R.string.midnight_dusk
), ),
STRAWBERRY_DAIQUIRI( STRAWBERRIES(
R.style.Theme_Tachiyomi_StrawberryDaiquiri, R.style.Theme_Tachiyomi_Strawberries,
AppCompatDelegate.MODE_NIGHT_NO, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
R.string.strawberry_daiquiri R.string.strawberry_daiquiri,
),
CHOCOLATE_STRAWBERRIES(
R.style.Theme_Tachiyomi_ChocolateStrawberries,
AppCompatDelegate.MODE_NIGHT_YES,
R.string.chocolate_strawberries R.string.chocolate_strawberries
), ),
LIME( LIME(
@ -43,28 +39,25 @@ enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes va
AppCompatDelegate.MODE_NIGHT_NO, AppCompatDelegate.MODE_NIGHT_NO,
R.string.yotsuba R.string.yotsuba
), ),
YANG( YIN_AND_YANG(
R.style.Theme_Tachiyomi_YinYang, R.style.Theme_Tachiyomi_YinYang,
AppCompatDelegate.MODE_NIGHT_NO, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
R.string.yang R.string.yang,
),
YIN(
R.style.Theme_Tachiyomi_YinYang,
AppCompatDelegate.MODE_NIGHT_YES,
R.string.yin R.string.yin
), ),
LIGHT_BLUE( CLASSIC_BLUE(
R.style.Theme_Tachiyomi_AllBlue, R.style.Theme_Tachiyomi_AllBlue,
AppCompatDelegate.MODE_NIGHT_NO, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
R.string.light_blue R.string.light_blue,
),
DARK_BLUE(
R.style.Theme_Tachiyomi_AllBlue,
AppCompatDelegate.MODE_NIGHT_YES,
R.string.dark_blue R.string.dark_blue
); ),
;
val isDarkTheme = nightMode == AppCompatDelegate.MODE_NIGHT_YES val isDarkTheme = nightMode == AppCompatDelegate.MODE_NIGHT_YES
val followsSystem = nightMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
@StringRes
val darkNameRes: Int = altNameRes ?: nameRes
fun getColors(mode: Int = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM): Colors { fun getColors(mode: Int = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM): Colors {
return when (nightMode) { return when (nightMode) {
@ -140,7 +133,7 @@ enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes va
@ColorInt @ColorInt
val darkBackground: Int = Color.parseColor( val darkBackground: Int = Color.parseColor(
when (styleRes) { when (styleRes) {
R.style.Theme_Tachiyomi_ChocolateStrawberries -> "#1a1716" R.style.Theme_Tachiyomi_Strawberries -> "#1a1716"
R.style.Theme_Tachiyomi_MidnightDusk -> "#16151D" R.style.Theme_Tachiyomi_MidnightDusk -> "#16151D"
R.style.Theme_Tachiyomi_FlatLime -> "#202125" R.style.Theme_Tachiyomi_FlatLime -> "#202125"
else -> "#1C1C1D" else -> "#1C1C1D"
@ -153,7 +146,7 @@ enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes va
when (styleRes) { when (styleRes) {
R.style.Theme_Tachiyomi_YinYang -> "#000000" R.style.Theme_Tachiyomi_YinYang -> "#000000"
R.style.Theme_Tachiyomi_MidnightDusk -> "#c43c97" R.style.Theme_Tachiyomi_MidnightDusk -> "#c43c97"
R.style.Theme_Tachiyomi_StrawberryDaiquiri -> "#ED4A65" R.style.Theme_Tachiyomi_Strawberries -> "#ED4A65"
R.style.Theme_Tachiyomi_Yotsuba -> "#dc6d3d" R.style.Theme_Tachiyomi_Yotsuba -> "#dc6d3d"
else -> "#2979FF" else -> "#2979FF"
} }
@ -165,7 +158,7 @@ enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes va
when (styleRes) { when (styleRes) {
R.style.Theme_Tachiyomi_YinYang -> "#FFFFFF" R.style.Theme_Tachiyomi_YinYang -> "#FFFFFF"
R.style.Theme_Tachiyomi_MidnightDusk -> "#F02475" R.style.Theme_Tachiyomi_MidnightDusk -> "#F02475"
R.style.Theme_Tachiyomi_ChocolateStrawberries -> "#AA2200" R.style.Theme_Tachiyomi_Strawberries -> "#AA2200"
R.style.Theme_Tachiyomi_FlatLime -> "#4AF88A" R.style.Theme_Tachiyomi_FlatLime -> "#4AF88A"
else -> "#3399FF" else -> "#3399FF"
} }
@ -214,7 +207,7 @@ enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes va
@ColorInt @ColorInt
val darkBottomBar: Int = Color.parseColor( val darkBottomBar: Int = Color.parseColor(
when (styleRes) { when (styleRes) {
R.style.Theme_Tachiyomi_ChocolateStrawberries -> "#211b19" R.style.Theme_Tachiyomi_Strawberries -> "#211b19"
R.style.Theme_Tachiyomi_AllBlue -> "#54759E" R.style.Theme_Tachiyomi_AllBlue -> "#54759E"
R.style.Theme_Tachiyomi_MidnightDusk -> "#201F27" R.style.Theme_Tachiyomi_MidnightDusk -> "#201F27"
R.style.Theme_Tachiyomi_FlatLime -> "#282A2E" R.style.Theme_Tachiyomi_FlatLime -> "#282A2E"

View File

@ -18,7 +18,7 @@
<item name="md_background_color">@color/colorAmoledPrimary</item> <item name="md_background_color">@color/colorAmoledPrimary</item>
</style> </style>
<style name="Theme.Tachiyomi.ChocolateStrawberries"> <style name="Theme.Tachiyomi.Strawberries">
<item name="colorPrimary">@color/primaryRed</item> <item name="colorPrimary">@color/primaryRed</item>
<item name="colorAccent">@color/holo_red</item> <item name="colorAccent">@color/holo_red</item>
<item name="colorAccentText">@color/md_red_500</item> <item name="colorAccentText">@color/md_red_500</item>

View File

@ -78,7 +78,6 @@
<item name="android:windowLightNavigationBar" tools:targetApi="27">false</item> <item name="android:windowLightNavigationBar" tools:targetApi="27">false</item>
</style> </style>
<style name="ThemeOverlay.Tachiyomi.Amoled" parent=""/> <style name="ThemeOverlay.Tachiyomi.Amoled" parent=""/>
<style name="Theme.Tachiyomi.ChocolateStrawberries"/>
<style name="Theme.Tachiyomi.FlatLime"/> <style name="Theme.Tachiyomi.FlatLime"/>
<style name="Theme.Tachiyomi.MidnightDusk"> <style name="Theme.Tachiyomi.MidnightDusk">
<item name="colorPrimary">@color/primaryDuskDawn</item> <item name="colorPrimary">@color/primaryDuskDawn</item>
@ -91,7 +90,7 @@
<item name="android:colorBackground">@color/backgroundDuskDawn</item> <item name="android:colorBackground">@color/backgroundDuskDawn</item>
<item name="actionBarTintColor">@color/appBarTextDuskDawn</item> <item name="actionBarTintColor">@color/appBarTextDuskDawn</item>
</style> </style>
<style name="Theme.Tachiyomi.StrawberryDaiquiri"> <style name="Theme.Tachiyomi.Strawberries">
<item name="colorAccent">@color/colorAccentStrawberry</item> <item name="colorAccent">@color/colorAccentStrawberry</item>
<item name="colorAccentText">@color/colorAccentStrawberryText</item> <item name="colorAccentText">@color/colorAccentStrawberryText</item>
</style> </style>