mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 15:41:52 +01:00
Option to set Light/Dark Theme individually
Works "the exact same" as upstream, except ui and code is completely different With this there's less theme items in the general settings Also moved auto hide bottom nav to the first preference
This commit is contained in:
parent
e0c77abe1c
commit
4ef4dc2677
@ -7,7 +7,9 @@ object PreferenceKeys {
|
||||
|
||||
const val theme = "pref_theme_key"
|
||||
|
||||
const val themeStyle = "theme_style"
|
||||
const val nightMode = "night_mode"
|
||||
const val lightTheme = "light_theme"
|
||||
const val darkTheme = "dark_theme"
|
||||
|
||||
const val startingTab = "starting_tab"
|
||||
|
||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import com.f2prateek.rx.preferences.RxSharedPreferences
|
||||
@ -88,7 +89,10 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun oldTheme() = prefs.getInt(Keys.theme, 5)
|
||||
|
||||
fun theme() = flowPrefs.getEnum(Keys.themeStyle, ThemeUtil.Themes.DEFAULT)
|
||||
fun nightMode() = flowPrefs.getInt(Keys.nightMode, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
|
||||
fun lightTheme() = flowPrefs.getEnum(Keys.lightTheme, ThemeUtil.Themes.PURE_WHITE)
|
||||
fun darkTheme() = flowPrefs.getEnum(Keys.darkTheme, ThemeUtil.Themes.DARK)
|
||||
|
||||
fun rotation() = flowPrefs.getInt(Keys.rotation, 1)
|
||||
|
||||
|
@ -2,14 +2,13 @@ package eu.kanade.tachiyomi.ui.base.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.ui.main.SearchActivity
|
||||
import eu.kanade.tachiyomi.ui.security.BiometricActivity
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.setThemeAndNight
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
@ -23,18 +22,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (preferences.theme().isNotSet()) {
|
||||
ThemeUtil.convertTheme(preferences, preferences.oldTheme())
|
||||
}
|
||||
// Using a try catch in case I start to remove themes
|
||||
val theme = try {
|
||||
preferences.theme().get()
|
||||
} catch (e: Exception) {
|
||||
preferences.theme().set(ThemeUtil.Themes.DEFAULT)
|
||||
ThemeUtil.Themes.DEFAULT
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(theme.nightMode)
|
||||
setTheme(theme.styleRes)
|
||||
setThemeAndNight(preferences)
|
||||
super.onCreate(savedInstanceState)
|
||||
SecureActivityDelegate.setSecure(this)
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ package eu.kanade.tachiyomi.ui.base.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.setThemeAndNight
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
abstract class BaseThemedActivity : AppCompatActivity() {
|
||||
@ -12,13 +11,7 @@ abstract class BaseThemedActivity : AppCompatActivity() {
|
||||
val preferences: PreferencesHelper by injectLazy()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
if (preferences.theme().isNotSet()) {
|
||||
ThemeUtil.convertTheme(preferences, preferences.oldTheme())
|
||||
}
|
||||
val theme = preferences.theme().get()
|
||||
AppCompatDelegate.setDefaultNightMode(theme.nightMode)
|
||||
setTheme(theme.styleRes)
|
||||
|
||||
setThemeAndNight(preferences)
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ import eu.kanade.tachiyomi.util.moveCategories
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getPrefTheme
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
||||
import eu.kanade.tachiyomi.util.system.isOnline
|
||||
@ -361,7 +362,7 @@ class MangaDetailsController :
|
||||
val activity = activity as? MainActivity ?: return
|
||||
val activityBinding = activityBinding ?: return
|
||||
// if the theme is using inverted toolbar color
|
||||
if (ThemeUtil.hasDarkActionBarInLight(activity, presenter.preferences.theme().get())) {
|
||||
if (ThemeUtil.hasDarkActionBarInLight(activity, activity.getPrefTheme(presenter.preferences))) {
|
||||
if (forThis) activityBinding.appBar.context.setTheme(
|
||||
R.style.ThemeOverlay_AppCompat_DayNight_ActionBar
|
||||
)
|
||||
@ -1414,7 +1415,7 @@ class MangaDetailsController :
|
||||
|
||||
if (!activity.isInNightMode()) {
|
||||
activityBinding?.appBar?.context?.setTheme(
|
||||
presenter.preferences.theme().get().styleRes
|
||||
activity.getPrefTheme(presenter.preferences).styleRes
|
||||
)
|
||||
|
||||
val iconPrimary = currColor ?: Color.WHITE
|
||||
|
@ -21,7 +21,6 @@ import android.view.WindowManager
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.SeekBar
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.isVisible
|
||||
@ -59,6 +58,7 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getPrefTheme
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.hasSideNavBar
|
||||
import eu.kanade.tachiyomi.util.system.isBottomTappable
|
||||
@ -67,6 +67,7 @@ import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.launchIO
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.openInBrowser
|
||||
import eu.kanade.tachiyomi.util.system.setThemeAndNight
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.collapse
|
||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||
@ -198,9 +199,7 @@ class ReaderActivity :
|
||||
* Called when the activity is created. Initializes the presenter and configuration.
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val theme = preferences.theme().get()
|
||||
AppCompatDelegate.setDefaultNightMode(theme.nightMode)
|
||||
setTheme(theme.styleRes)
|
||||
setThemeAndNight(preferences)
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ReaderActivityBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
@ -244,7 +243,7 @@ class ReaderActivity :
|
||||
}
|
||||
|
||||
binding.chaptersSheet.chaptersBottomSheet.setup(this)
|
||||
if (ThemeUtil.isColoredTheme(preferences.theme().get())) {
|
||||
if (ThemeUtil.isColoredTheme(getPrefTheme(preferences))) {
|
||||
binding.chaptersSheet.chapterRecycler.setBackgroundColor(getResourceColor(android.R.attr.colorBackground))
|
||||
}
|
||||
config = ReaderConfig()
|
||||
|
@ -2,15 +2,20 @@ package eu.kanade.tachiyomi.ui.setting
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.biometric.BiometricManager
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||
import eu.kanade.tachiyomi.util.system.LocaleHelper
|
||||
import eu.kanade.tachiyomi.util.system.appDelegateNightMode
|
||||
import eu.kanade.tachiyomi.util.system.getPrefTheme
|
||||
import eu.kanade.tachiyomi.widget.preference.IntListMatPreference
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||
|
||||
class SettingsGeneralController : SettingsController() {
|
||||
@ -67,6 +72,13 @@ class SettingsGeneralController : SettingsController() {
|
||||
defaultValue = true
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = Keys.hideBottomNavOnScroll
|
||||
titleRes = R.string.hide_bottom_nav
|
||||
summaryRes = R.string.hides_on_scroll
|
||||
defaultValue = true
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = Keys.automaticUpdates
|
||||
titleRes = R.string.check_for_updates
|
||||
@ -92,18 +104,33 @@ class SettingsGeneralController : SettingsController() {
|
||||
titleRes = R.string.display
|
||||
|
||||
themePreference = themePreference {
|
||||
key = Keys.themeStyle
|
||||
key = "theme_preference"
|
||||
titleRes = R.string.app_theme
|
||||
lastScrollPostion = lastThemeX
|
||||
summaryRes = preferences.theme().get().nameRes
|
||||
summaryRes = context.getPrefTheme(preferences).nameRes
|
||||
activity = this@SettingsGeneralController.activity
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = Keys.hideBottomNavOnScroll
|
||||
titleRes = R.string.hide_bottom_nav
|
||||
summaryRes = R.string.hides_on_scroll
|
||||
defaultValue = true
|
||||
key = "night_mode_switch"
|
||||
isPersistent = false
|
||||
titleRes = R.string.follow_system_theme
|
||||
isChecked =
|
||||
preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
|
||||
onChange {
|
||||
if (it == true) {
|
||||
preferences.nightMode().set(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
activity?.recreate()
|
||||
} else {
|
||||
preferences.nightMode().set(context.appDelegateNightMode())
|
||||
themePreference?.fastAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
true
|
||||
}
|
||||
preferences.nightMode().asImmediateFlow { mode ->
|
||||
isChecked = mode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
}.launchIn(viewScope)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,16 +22,18 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.ThemeItemBinding
|
||||
import eu.kanade.tachiyomi.databinding.ThemesPreferenceBinding
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.appDelegateNightMode
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
||||
import eu.kanade.tachiyomi.util.view.visInvisIf
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class ThemePreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
Preference(context, attrs) {
|
||||
|
||||
private lateinit var fastAdapter: FastAdapter<ThemeItem>
|
||||
var fastAdapter: FastAdapter<ThemeItem>
|
||||
private val itemAdapter = ItemAdapter<ThemeItem>()
|
||||
private lateinit var selectExtension: SelectExtension<ThemeItem>
|
||||
private var selectExtension: SelectExtension<ThemeItem>
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
var activity: Activity? = null
|
||||
var lastScrollPostion: Int? = null
|
||||
@ -42,22 +44,41 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
fastAdapter = FastAdapter.with(itemAdapter)
|
||||
fastAdapter.setHasStableIds(true)
|
||||
val enumConstants = ThemeUtil.Themes::class.java.enumConstants
|
||||
val currentTheme = preferences.theme().get()
|
||||
val currentLightTheme = preferences.lightTheme().get()
|
||||
val currentDarkTheme = preferences.darkTheme().get()
|
||||
val nightMode = preferences.nightMode().get()
|
||||
selectExtension = fastAdapter.getSelectExtension().apply {
|
||||
isSelectable = true
|
||||
multiSelect = false
|
||||
multiSelect = true
|
||||
selectionListener = object : ISelectionListener<ThemeItem> {
|
||||
override fun onSelectionChanged(item: ThemeItem, selected: Boolean) {
|
||||
preferences.theme().set(item.theme)
|
||||
if (item.theme.nightMode == AppCompatDelegate.MODE_NIGHT_YES) {
|
||||
preferences.darkTheme().set(item.theme)
|
||||
} else {
|
||||
preferences.lightTheme().set(item.theme)
|
||||
}
|
||||
if (!selected) {
|
||||
preferences.nightMode().set(item.theme.nightMode)
|
||||
} else if (preferences.nightMode()
|
||||
.get() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
) {
|
||||
preferences.nightMode().set(item.theme.nightMode)
|
||||
}
|
||||
if ((
|
||||
preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM &&
|
||||
item.theme.nightMode != context.appDelegateNightMode()
|
||||
) ||
|
||||
(!selected && item.theme.nightMode == context.appDelegateNightMode())
|
||||
) {
|
||||
fastAdapter.notifyDataSetChanged()
|
||||
} else {
|
||||
activity?.recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemAdapter.set(enumConstants?.map(::ThemeItem).orEmpty())
|
||||
itemAdapter.adapterItems.forEach { item ->
|
||||
item.isSelected = currentTheme == item.theme
|
||||
}
|
||||
isSelectable = false
|
||||
}
|
||||
|
||||
@ -75,24 +96,22 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
lastScrollPostion =
|
||||
recyclerView.computeHorizontalScrollOffset() // (lastScrollPostion ?: 0) + dx
|
||||
recyclerView.computeHorizontalScrollOffset()
|
||||
}
|
||||
})
|
||||
|
||||
val enumConstants = ThemeUtil.Themes::class.java.enumConstants
|
||||
val currentTheme = preferences.theme().get()
|
||||
if (lastScrollPostion != null) {
|
||||
val lX = lastScrollPostion!!
|
||||
(binding.themeRecycler.layoutManager as LinearLayoutManager).apply {
|
||||
scrollToPositionWithOffset(
|
||||
lX / 110.dpToPx,
|
||||
-lX % 110.dpToPx + binding.themeRecycler.paddingStart
|
||||
-lX % 110.dpToPx
|
||||
)
|
||||
}
|
||||
lastScrollPostion = binding.themeRecycler.computeHorizontalScrollOffset()
|
||||
} else {
|
||||
binding.themeRecycler.scrollToPosition(
|
||||
enumConstants?.indexOf(currentTheme) ?: 0
|
||||
selectExtension.selections.firstOrNull() ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -112,11 +131,15 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
}
|
||||
|
||||
val colors = theme.getColors()
|
||||
val darkColors = if (theme.nightMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
|
||||
theme.getColors(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
} else {
|
||||
null
|
||||
|
||||
override var isSelected: Boolean
|
||||
get() = when (preferences.nightMode().get()) {
|
||||
AppCompatDelegate.MODE_NIGHT_YES -> preferences.darkTheme().get() == theme
|
||||
AppCompatDelegate.MODE_NIGHT_NO -> preferences.lightTheme().get() == theme
|
||||
else -> preferences.darkTheme().get() == theme ||
|
||||
preferences.lightTheme().get() == theme
|
||||
}
|
||||
set(value) {}
|
||||
|
||||
inner class ViewHolder(view: View) : FastAdapter.ViewHolder<ThemeItem>(view) {
|
||||
|
||||
@ -126,6 +149,16 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
|
||||
binding.checkbox.isVisible = item.isSelected
|
||||
binding.themeSelected.visInvisIf(item.isSelected)
|
||||
|
||||
if (binding.checkbox.isVisible) {
|
||||
val themeMatchesApp = if (context.isInNightMode()) {
|
||||
item.theme.nightMode == AppCompatDelegate.MODE_NIGHT_YES
|
||||
} else {
|
||||
item.theme.nightMode == AppCompatDelegate.MODE_NIGHT_NO
|
||||
}
|
||||
binding.themeSelected.alpha = if (themeMatchesApp) 1f else 0.5f
|
||||
binding.checkbox.alpha = if (themeMatchesApp) 1f else 0.5f
|
||||
}
|
||||
binding.themeToolbar.setBackgroundColor(item.colors.appBar)
|
||||
binding.themeAppBarText.imageTintList = ColorStateList.valueOf(item.colors.appBarText)
|
||||
binding.themeHeroImage.imageTintList = ColorStateList.valueOf(item.colors.primaryText)
|
||||
@ -138,23 +171,7 @@ class ThemePreference @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
binding.themeItem1.imageTintList = ColorStateList.valueOf(item.colors.inactiveTab)
|
||||
binding.themeItem2.imageTintList = ColorStateList.valueOf(item.colors.activeTab)
|
||||
binding.themeItem3.imageTintList = ColorStateList.valueOf(item.colors.inactiveTab)
|
||||
|
||||
binding.themeLayout.setBackgroundColor(item.colors.colorBackground)
|
||||
binding.darkThemeLayout.isVisible = item.darkColors != null
|
||||
|
||||
if (binding.darkThemeLayout.isVisible && item.darkColors != null) {
|
||||
binding.darkThemeToolbar.setBackgroundColor(item.darkColors.appBar)
|
||||
binding.darkThemeAppBarText.imageTintList = ColorStateList.valueOf(item.darkColors.appBarText)
|
||||
binding.darkThemeLayout.setBackgroundColor(item.darkColors.colorBackground)
|
||||
binding.darkThemePrimaryText.imageTintList = ColorStateList.valueOf(item.darkColors.primaryText)
|
||||
binding.darkThemeHeroImage.imageTintList = ColorStateList.valueOf(item.darkColors.primaryText)
|
||||
binding.darkThemeAccentedButton.imageTintList = ColorStateList.valueOf(item.darkColors.colorAccent)
|
||||
binding.darkThemeSecondaryText.imageTintList = ColorStateList.valueOf(item.darkColors.secondaryText)
|
||||
|
||||
binding.darkThemeBottomBar.setBackgroundColor(item.darkColors.bottomBar)
|
||||
binding.darkThemeItem2.imageTintList = ColorStateList.valueOf(item.darkColors.activeTab)
|
||||
binding.darkThemeItem3.imageTintList = ColorStateList.valueOf(item.darkColors.inactiveTab)
|
||||
}
|
||||
}
|
||||
|
||||
override fun unbindView(item: ThemeItem) {
|
||||
|
@ -32,7 +32,7 @@ open class BaseWebViewActivity : BaseActivity<WebviewActivityBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = WebviewActivityBinding.inflate(layoutInflater)
|
||||
delegate.localNightMode = preferences.theme().get().nightMode
|
||||
delegate.localNightMode = preferences.nightMode().get()
|
||||
setContentView(binding.root)
|
||||
setSupportActionBar(binding.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
@ -24,6 +24,7 @@ import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.browser.customtabs.CustomTabColorSchemeParams
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION
|
||||
@ -324,6 +325,11 @@ fun Context.isInNightMode(): Boolean {
|
||||
return currentNightMode == Configuration.UI_MODE_NIGHT_YES
|
||||
}
|
||||
|
||||
fun Context.appDelegateNightMode(): Int {
|
||||
return if (isInNightMode()) AppCompatDelegate.MODE_NIGHT_YES
|
||||
else AppCompatDelegate.MODE_NIGHT_NO
|
||||
}
|
||||
|
||||
fun Context.isOnline(): Boolean {
|
||||
val connectivityManager = this
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
|
||||
|
@ -1,5 +1,6 @@
|
||||
package eu.kanade.tachiyomi.util.system
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.ColorInt
|
||||
@ -15,17 +16,24 @@ object ThemeUtil {
|
||||
|
||||
/** Migration method */
|
||||
fun convertTheme(preferences: PreferencesHelper, theme: Int) {
|
||||
preferences.theme().set(
|
||||
preferences.nightMode().set(
|
||||
when (theme) {
|
||||
0, 1 -> AppCompatDelegate.MODE_NIGHT_NO
|
||||
2, 3, 4 -> AppCompatDelegate.MODE_NIGHT_YES
|
||||
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
}
|
||||
)
|
||||
preferences.lightTheme().set(
|
||||
when (theme) {
|
||||
0 -> Themes.PURE_WHITE
|
||||
1 -> Themes.LIGHT_BLUE
|
||||
2 -> Themes.DARK
|
||||
else -> Themes.PURE_WHITE
|
||||
}
|
||||
)
|
||||
preferences.darkTheme().set(
|
||||
when (theme) {
|
||||
3 -> Themes.AMOLED
|
||||
4 -> Themes.DARK_BLUE
|
||||
5 -> Themes.DEFAULT
|
||||
6 -> Themes.DEFAULT_AMOLED
|
||||
7 -> Themes.ALL_BLUE
|
||||
else -> Themes.DEFAULT
|
||||
else -> Themes.DARK
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -51,36 +59,21 @@ object ThemeUtil {
|
||||
|
||||
enum class Themes(@StyleRes val styleRes: Int, val nightMode: Int, @StringRes val nameRes: Int) {
|
||||
PURE_WHITE(R.style.Theme_Tachiyomi, AppCompatDelegate.MODE_NIGHT_NO, R.string.white_theme),
|
||||
LIGHT_BLUE(
|
||||
R.style.Theme_Tachiyomi_AllBlue,
|
||||
AppCompatDelegate.MODE_NIGHT_NO,
|
||||
R.string.light_blue
|
||||
),
|
||||
DARK(R.style.Theme_Tachiyomi, AppCompatDelegate.MODE_NIGHT_YES, R.string.dark),
|
||||
AMOLED(
|
||||
R.style.Theme_Tachiyomi_Amoled,
|
||||
AppCompatDelegate.MODE_NIGHT_YES,
|
||||
R.string.amoled_black
|
||||
),
|
||||
LIGHT_BLUE(
|
||||
R.style.Theme_Tachiyomi_AllBlue,
|
||||
AppCompatDelegate.MODE_NIGHT_NO,
|
||||
R.string.light_blue
|
||||
),
|
||||
DARK_BLUE(
|
||||
R.style.Theme_Tachiyomi_AllBlue,
|
||||
AppCompatDelegate.MODE_NIGHT_YES,
|
||||
R.string.dark_blue
|
||||
),
|
||||
DEFAULT(
|
||||
R.style.Theme_Tachiyomi,
|
||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
|
||||
R.string.system_default
|
||||
),
|
||||
DEFAULT_AMOLED(
|
||||
R.style.Theme_Tachiyomi_Amoled,
|
||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
|
||||
R.string.system_default_amoled
|
||||
),
|
||||
ALL_BLUE(
|
||||
R.style.Theme_Tachiyomi_AllBlue,
|
||||
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM,
|
||||
R.string.system_default_all_blue
|
||||
);
|
||||
|
||||
fun getColors(mode: Int = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM): Colors {
|
||||
@ -177,16 +170,21 @@ object ThemeUtil {
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
val lightBottomBar: Int = when (styleRes) {
|
||||
R.style.Theme_Tachiyomi_AllBlue -> Color.parseColor("#54759E")
|
||||
else -> Color.parseColor("#FFFFFF")
|
||||
val lightBottomBar: Int = Color.parseColor(
|
||||
when (styleRes) {
|
||||
R.style.Theme_Tachiyomi_AllBlue -> "#54759E"
|
||||
else -> "#FFFFFF"
|
||||
}
|
||||
)
|
||||
|
||||
@ColorInt
|
||||
val darkBottomBar: Int = when (styleRes) {
|
||||
R.style.Theme_Tachiyomi_AllBlue -> Color.parseColor("#54759E")
|
||||
else -> Color.parseColor("#212121")
|
||||
val darkBottomBar: Int = Color.parseColor(
|
||||
when (styleRes) {
|
||||
R.style.Theme_Tachiyomi_AllBlue -> "#54759E"
|
||||
R.style.Theme_Tachiyomi_Amoled -> "#000000"
|
||||
else -> "#212121"
|
||||
}
|
||||
)
|
||||
|
||||
@ColorInt
|
||||
val lightInactiveTab: Int = when (styleRes) {
|
||||
@ -225,3 +223,23 @@ object ThemeUtil {
|
||||
@ColorInt val activeTab: Int,
|
||||
)
|
||||
}
|
||||
|
||||
fun Activity.setThemeAndNight(preferences: PreferencesHelper) {
|
||||
if (preferences.nightMode().isNotSet()) {
|
||||
ThemeUtil.convertTheme(preferences, preferences.oldTheme())
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(preferences.nightMode().get())
|
||||
val theme = getPrefTheme(preferences)
|
||||
setTheme(theme.styleRes)
|
||||
}
|
||||
|
||||
fun Context.getPrefTheme(preferences: PreferencesHelper): ThemeUtil.Themes {
|
||||
// Using a try catch in case I start to remove themes
|
||||
return try {
|
||||
(if (isInNightMode() || preferences.nightMode().get() == AppCompatDelegate.MODE_NIGHT_YES) preferences.darkTheme() else preferences.lightTheme()).get()
|
||||
} catch (e: Exception) {
|
||||
preferences.lightTheme().set(ThemeUtil.Themes.PURE_WHITE)
|
||||
preferences.darkTheme().set(ThemeUtil.Themes.DARK)
|
||||
ThemeUtil.Themes.PURE_WHITE
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.util.system.ThemeUtil
|
||||
import eu.kanade.tachiyomi.util.system.contextCompatColor
|
||||
import eu.kanade.tachiyomi.util.system.getPrefTheme
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
@ -63,7 +63,7 @@ fun View.snack(
|
||||
if (f != null) {
|
||||
snack.f()
|
||||
}
|
||||
val theme = Injekt.get<PreferencesHelper>().theme().get()
|
||||
val theme = context.getPrefTheme(Injekt.get())
|
||||
if (ThemeUtil.isPitchBlack(context, theme)) {
|
||||
val textView: TextView =
|
||||
snack.view.findViewById(com.google.android.material.R.id.snackbar_text)
|
||||
|
@ -184,143 +184,6 @@
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/dark_theme_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:attr/colorBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_percent="0.50">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/dark_theme_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_app_bar_preview"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:elevation="2dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_app_bar_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_text_preview"
|
||||
android:layout_gravity="start|center"
|
||||
android:layout_marginEnd="@dimen/theme_app_bar_margin_end"
|
||||
android:src="@drawable/right_half_oval"
|
||||
app:tint="?actionBarTintColor"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_hero_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_hero_preview"
|
||||
android:layout_marginTop="@dimen/theme_padding_preview"
|
||||
android:layout_marginEnd="@dimen/theme_padding_preview"
|
||||
android:alpha="0.70"
|
||||
android:src="@drawable/right_half_oval"
|
||||
app:layout_constraintBottom_toTopOf="@id/dark_theme_hero_image"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dark_theme_toolbar"
|
||||
app:tint="?android:attr/textColorPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_primary_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_text_preview"
|
||||
android:layout_marginTop="@dimen/theme_text_padding_preview"
|
||||
android:layout_marginEnd="@dimen/theme_primary_margin_end"
|
||||
android:src="@drawable/right_half_oval"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dark_theme_hero_image"
|
||||
app:tint="?android:attr/textColorPrimary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_accented_button"
|
||||
android:layout_width="@dimen/theme_accent_width_preview"
|
||||
android:layout_height="@dimen/theme_text_preview"
|
||||
android:layout_marginStart="3dp"
|
||||
android:src="@drawable/oval"
|
||||
app:layout_constraintBottom_toBottomOf="@id/dark_theme_primary_text"
|
||||
app:layout_constraintStart_toEndOf="@id/dark_theme_primary_text"
|
||||
app:layout_constraintTop_toTopOf="@id/dark_theme_primary_text"
|
||||
app:tint="?colorAccent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_secondary_text"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="@dimen/theme_text_preview"
|
||||
android:layout_marginTop="@dimen/theme_text_padding_preview"
|
||||
android:src="@drawable/right_half_oval"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dark_theme_primary_text"
|
||||
app:tint="?android:attr/textColorSecondary"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/dark_theme_bottom_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_bottom_bar_preview"
|
||||
android:background="?colorPrimaryVariant"
|
||||
android:elevation="2dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_item_2"
|
||||
android:layout_width="@dimen/theme_bottom_item_half_preview"
|
||||
android:layout_height="@dimen/theme_bottom_item_preview"
|
||||
android:src="@drawable/right_half_oval"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/dark_theme_item_3"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="spread_inside"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/tabBarIconColor"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dark_theme_item_3"
|
||||
android:layout_width="@dimen/theme_bottom_item_preview"
|
||||
android:layout_height="@dimen/theme_bottom_item_preview"
|
||||
android:src="@drawable/oval"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/dark_theme_item_gap"
|
||||
app:layout_constraintStart_toEndOf="@id/dark_theme_item_2"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/tabBarIconInactive"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<Space
|
||||
android:id="@+id/dark_theme_item_gap"
|
||||
android:layout_width="0dp"
|
||||
app:layout_constraintWidth_percent="0.0"
|
||||
android:layout_height="30dp"
|
||||
android:src="@drawable/right_half_oval"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/dark_theme_item_3"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/tabBarIconColor"
|
||||
tools:ignore="ContentDescription" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/checkbox"
|
||||
android:background="@drawable/oval"
|
||||
@ -340,7 +203,7 @@
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/theme_name_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="50sp"
|
||||
android:layout_height="32sp"
|
||||
android:maxLines="3"
|
||||
android:layout_marginTop="2dp"
|
||||
android:textAlignment="center"
|
||||
|
@ -579,6 +579,7 @@
|
||||
<string name="auto_check_for_app_versions">Automatically check for new app versions</string>
|
||||
<string name="secure_screen">Secure screen</string>
|
||||
<string name="hide_bottom_nav">Auto-hide bottom navigation</string>
|
||||
<string name="follow_system_theme">Follow system theme</string>
|
||||
<string name="hides_on_scroll">Hides when scrolling</string>
|
||||
<string name="hide_tachi_from_recents">Hide Tachiyomi from the recents screen</string>
|
||||
<string name="security">Security</string>
|
||||
|
Loading…
Reference in New Issue
Block a user