mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-20 04:29:18 +01:00
Splitting Light and Dark Theme setting
Soi you can stop complaining now
This commit is contained in:
parent
49e0d561b2
commit
bed52c7b86
@ -19,7 +19,8 @@ class SettingsGeneralController : SettingsController() {
|
||||
|
||||
private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
|
||||
|
||||
var lastThemeX: Int? = null
|
||||
var lastThemeXLight: Int? = null
|
||||
var lastThemeXDark: Int? = null
|
||||
var themePreference: ThemePreference? = null
|
||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
|
||||
titleRes = R.string.general
|
||||
@ -90,12 +91,13 @@ class SettingsGeneralController : SettingsController() {
|
||||
}
|
||||
|
||||
preferenceCategory {
|
||||
titleRes = R.string.display
|
||||
titleRes = R.string.app_theme
|
||||
|
||||
themePreference = themePreference {
|
||||
key = "theme_preference"
|
||||
titleRes = R.string.app_theme
|
||||
lastScrollPostion = lastThemeX
|
||||
lastScrollPostionLight = lastThemeXLight
|
||||
lastScrollPostionDark = lastThemeXDark
|
||||
summary = if (preferences.nightMode()
|
||||
.get() == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
) {
|
||||
@ -124,7 +126,8 @@ class SettingsGeneralController : SettingsController() {
|
||||
activity?.recreate()
|
||||
} else {
|
||||
preferences.nightMode().set(context.appDelegateNightMode())
|
||||
themePreference?.fastAdapter?.notifyDataSetChanged()
|
||||
themePreference?.fastAdapterLight?.notifyDataSetChanged()
|
||||
themePreference?.fastAdapterDark?.notifyDataSetChanged()
|
||||
}
|
||||
true
|
||||
}
|
||||
@ -270,13 +273,16 @@ class SettingsGeneralController : SettingsController() {
|
||||
}
|
||||
|
||||
override fun onSaveViewState(view: View, outState: Bundle) {
|
||||
outState.putInt(::lastThemeX.name, themePreference?.lastScrollPostion ?: 0)
|
||||
outState.putInt(::lastThemeXLight.name, themePreference?.lastScrollPostionLight ?: 0)
|
||||
outState.putInt(::lastThemeXDark.name, themePreference?.lastScrollPostionDark ?: 0)
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onRestoreViewState(view: View, savedViewState: Bundle) {
|
||||
super.onRestoreViewState(view, savedViewState)
|
||||
lastThemeX = savedViewState.getInt(::lastThemeX.name)
|
||||
themePreference?.lastScrollPostion = lastThemeX
|
||||
lastThemeXLight = savedViewState.getInt(::lastThemeXLight.name)
|
||||
lastThemeXDark = savedViewState.getInt(::lastThemeXDark.name)
|
||||
themePreference?.lastScrollPostionLight = lastThemeXLight
|
||||
themePreference?.lastScrollPostionDark = lastThemeXDark
|
||||
}
|
||||
}
|
||||
|
@ -27,88 +27,128 @@ import eu.kanade.tachiyomi.util.system.appDelegateNightMode
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.isInNightMode
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.max
|
||||
|
||||
class ThemePreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
Preference(context, attrs) {
|
||||
|
||||
var fastAdapter: FastAdapter<ThemeItem>
|
||||
private val itemAdapter = ItemAdapter<ThemeItem>()
|
||||
private var selectExtension: SelectExtension<ThemeItem>
|
||||
var fastAdapterLight: FastAdapter<ThemeItem>
|
||||
var fastAdapterDark: FastAdapter<ThemeItem>
|
||||
private val itemAdapterLight = ItemAdapter<ThemeItem>()
|
||||
private val itemAdapterDark = ItemAdapter<ThemeItem>()
|
||||
private var selectExtensionLight: SelectExtension<ThemeItem>
|
||||
private var selectExtensionDark: SelectExtension<ThemeItem>
|
||||
private val preferences: PreferencesHelper by injectLazy()
|
||||
var activity: Activity? = null
|
||||
var lastScrollPostion: Int? = null
|
||||
var lastScrollPostionLight: Int? = null
|
||||
var lastScrollPostionDark: Int? = null
|
||||
lateinit var binding: ThemesPreferenceBinding
|
||||
val manager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
private val managerLight = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
private val managerDark = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
init {
|
||||
layoutResource = R.layout.themes_preference
|
||||
fastAdapter = FastAdapter.with(itemAdapter)
|
||||
fastAdapter.setHasStableIds(true)
|
||||
selectExtension = fastAdapter.getSelectExtension().apply {
|
||||
isSelectable = true
|
||||
multiSelect = true
|
||||
selectionListener = object : ISelectionListener<ThemeItem> {
|
||||
override fun onSelectionChanged(item: ThemeItem, selected: Boolean) {
|
||||
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()
|
||||
}
|
||||
fastAdapterLight = FastAdapter.with(itemAdapterLight)
|
||||
fastAdapterDark = FastAdapter.with(itemAdapterDark)
|
||||
fastAdapterLight.setHasStableIds(true)
|
||||
fastAdapterDark.setHasStableIds(true)
|
||||
selectExtensionLight = fastAdapterLight.getSelectExtension().setThemeListener()
|
||||
selectExtensionDark = fastAdapterDark.getSelectExtension().setThemeListener()
|
||||
val enumConstants = Themes.values()
|
||||
itemAdapterLight.set(enumConstants.filter { it.nightMode == AppCompatDelegate.MODE_NIGHT_NO }.map(::ThemeItem))
|
||||
itemAdapterDark.set(enumConstants.filter { it.nightMode == AppCompatDelegate.MODE_NIGHT_YES }.map(::ThemeItem))
|
||||
isSelectable = false
|
||||
}
|
||||
|
||||
private fun SelectExtension<ThemeItem>.setThemeListener(): SelectExtension<ThemeItem> {
|
||||
isSelectable = true
|
||||
multiSelect = true
|
||||
selectionListener = object : ISelectionListener<ThemeItem> {
|
||||
override fun onSelectionChanged(item: ThemeItem, selected: Boolean) {
|
||||
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())
|
||||
) {
|
||||
fastAdapterLight.notifyDataSetChanged()
|
||||
fastAdapterDark.notifyDataSetChanged()
|
||||
} else {
|
||||
activity?.recreate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val enumConstants = Themes.values()
|
||||
itemAdapter.set(enumConstants.map(::ThemeItem))
|
||||
isSelectable = false
|
||||
return this
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
binding = ThemesPreferenceBinding.bind(holder.itemView)
|
||||
|
||||
binding.themePrefTitle.text = title
|
||||
binding.themeRecycler.setHasFixedSize(true)
|
||||
binding.themeRecycler.layoutManager = manager
|
||||
binding.themeRecycler.layoutManager = managerLight
|
||||
|
||||
binding.themeRecycler.adapter = fastAdapter
|
||||
binding.themeRecycler.adapter = fastAdapterLight
|
||||
|
||||
binding.themeRecycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
lastScrollPostion =
|
||||
lastScrollPostionLight =
|
||||
recyclerView.computeHorizontalScrollOffset()
|
||||
}
|
||||
})
|
||||
|
||||
if (lastScrollPostion != null) {
|
||||
val lX = lastScrollPostion!!
|
||||
binding.themeRecyclerDark.setHasFixedSize(true)
|
||||
binding.themeRecyclerDark.layoutManager = managerDark
|
||||
|
||||
binding.themeRecyclerDark.adapter = fastAdapterDark
|
||||
|
||||
binding.themeRecyclerDark.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
lastScrollPostionDark =
|
||||
recyclerView.computeHorizontalScrollOffset()
|
||||
}
|
||||
})
|
||||
|
||||
if (lastScrollPostionLight != null) {
|
||||
val lX = lastScrollPostionLight!!
|
||||
(binding.themeRecycler.layoutManager as LinearLayoutManager).apply {
|
||||
scrollToPositionWithOffset(
|
||||
lX / 110.dpToPx,
|
||||
-lX % 110.dpToPx
|
||||
)
|
||||
}
|
||||
lastScrollPostion = binding.themeRecycler.computeHorizontalScrollOffset()
|
||||
lastScrollPostionLight = binding.themeRecycler.computeHorizontalScrollOffset()
|
||||
} else {
|
||||
binding.themeRecycler.scrollToPosition(
|
||||
selectExtension.selections.firstOrNull() ?: 0
|
||||
max((selectExtensionLight.selections.firstOrNull() ?: 0) - 1, 0)
|
||||
)
|
||||
}
|
||||
|
||||
if (lastScrollPostionDark != null) {
|
||||
val lX = lastScrollPostionDark!!
|
||||
(binding.themeRecyclerDark.layoutManager as LinearLayoutManager).apply {
|
||||
scrollToPositionWithOffset(
|
||||
lX / 110.dpToPx,
|
||||
-lX % 110.dpToPx
|
||||
)
|
||||
}
|
||||
lastScrollPostionDark = binding.themeRecyclerDark.computeHorizontalScrollOffset()
|
||||
} else {
|
||||
binding.themeRecyclerDark.scrollToPosition(
|
||||
max((selectExtensionDark.selections.firstOrNull() ?: 0) - 1, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/theme_app_bar_preview"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:elevation="2dp"
|
||||
android:elevation="1dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
@ -5,18 +5,18 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/theme_pref_title"
|
||||
android:id="@+id/light_theme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/theme_recycler"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Menu"
|
||||
android:text="@string/app_theme"/>
|
||||
android:text="@string/light_theme"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/theme_recycler"
|
||||
@ -26,10 +26,42 @@
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/theme_pref_title"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/light_theme"
|
||||
app:layout_constraintBottom_toTopOf="@id/dark_theme"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:itemCount="2"
|
||||
tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
tools:orientation="horizontal"
|
||||
android:clipToPadding="false"/>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/dark_theme"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/theme_recycler"
|
||||
app:layout_constraintBottom_toTopOf="@id/theme_recycler_dark"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Menu"
|
||||
android:text="@string/dark_theme"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/theme_recycler_dark"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/theme_item"
|
||||
android:paddingStart="4dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/dark_theme"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
tools:orientation="horizontal"
|
||||
tools:itemCount="2"
|
||||
android:clipToPadding="false"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -602,6 +602,8 @@
|
||||
|
||||
<!-- General settings -->
|
||||
<string name="app_theme">App theme</string>
|
||||
<string name="light_theme">Light theme</string>
|
||||
<string name="dark_theme">Dark theme</string>
|
||||
<string name="light_blue">Light Blue</string>
|
||||
<string name="dark">Dark</string>
|
||||
<string name="amoled_black">AMOLED Black</string>
|
||||
|
Loading…
Reference in New Issue
Block a user