diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt index 694751ac4..5e75acd81 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/activity/BaseThemedActivity.kt @@ -18,8 +18,13 @@ abstract class BaseThemedActivity : AppCompatActivity() { companion object { fun AppCompatActivity.applyAppTheme(preferences: PreferencesHelper) { + getThemeResIds(preferences.appTheme().get(), preferences.themeDarkAmoled().get()) + .forEach { setTheme(it) } + } + + fun getThemeResIds(appTheme: PreferenceValues.AppTheme, isAmoled: Boolean): List { val resIds = mutableListOf() - when (preferences.appTheme().get()) { + when (appTheme) { PreferenceValues.AppTheme.MONET -> { resIds += R.style.Theme_Tachiyomi_Monet } @@ -53,13 +58,11 @@ abstract class BaseThemedActivity : AppCompatActivity() { } } - if (preferences.themeDarkAmoled().get()) { + if (isAmoled) { resIds += R.style.ThemeOverlay_Tachiyomi_Amoled } - resIds.forEach { - setTheme(it) - } + return resIds } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt index a57e1ee09..a3ad186ab 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt @@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.asImmediateFlow import eu.kanade.tachiyomi.util.preference.defaultValue import eu.kanade.tachiyomi.util.preference.entriesRes +import eu.kanade.tachiyomi.util.preference.initThenAdd import eu.kanade.tachiyomi.util.preference.intListPreference import eu.kanade.tachiyomi.util.preference.listPreference import eu.kanade.tachiyomi.util.preference.onChange @@ -17,6 +18,7 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.system.isTablet +import eu.kanade.tachiyomi.widget.preference.ThemesPreference import kotlinx.coroutines.flow.launchIn import java.util.Date import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys @@ -146,7 +148,7 @@ class SettingsGeneralController : SettingsController() { summary = "%s" } - listPreference { + initThenAdd(ThemesPreference(context)) { key = Keys.appTheme titleRes = R.string.pref_app_theme @@ -158,10 +160,8 @@ class SettingsGeneralController : SettingsController() { } it.titleResId != null && monetFilter } - entriesRes = appThemes.map { it.titleResId!! }.toTypedArray() - entryValues = appThemes.map { it.name }.toTypedArray() + entries = appThemes defaultValue = appThemes[0].name - summary = "%s" onChange { activity?.recreate() diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreference.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreference.kt new file mode 100644 index 000000000..2dec5a024 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreference.kt @@ -0,0 +1,40 @@ +package eu.kanade.tachiyomi.widget.preference + +import android.content.Context +import android.util.AttributeSet +import androidx.preference.ListPreference +import androidx.preference.PreferenceViewHolder +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferenceValues + +class ThemesPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : + ListPreference(context, attrs), + ThemesPreferenceAdapter.OnItemClickListener { + + private val adapter = ThemesPreferenceAdapter(this) + + init { + layoutResource = R.layout.pref_themes_list + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + val themesList = holder.findViewById(R.id.themes_list) as RecyclerView + themesList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + themesList.adapter = adapter + } + + override fun onItemClick(position: Int) { + value = entries[position].name + callChangeListener(value) + } + + var entries: List = emptyList() + set(value) { + field = value + adapter.setItems(value) + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreferenceAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreferenceAdapter.kt new file mode 100644 index 000000000..14f85ff44 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/preference/ThemesPreferenceAdapter.kt @@ -0,0 +1,67 @@ +package eu.kanade.tachiyomi.widget.preference + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.view.ContextThemeWrapper +import androidx.recyclerview.widget.RecyclerView +import eu.kanade.tachiyomi.data.preference.PreferenceValues +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.databinding.PrefThemeItemBinding +import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity +import uy.kohesive.injekt.injectLazy + +class ThemesPreferenceAdapter(private val clickListener: OnItemClickListener) : + RecyclerView.Adapter() { + + private val preferences: PreferencesHelper by injectLazy() + + private var themes = emptyList() + + private lateinit var binding: PrefThemeItemBinding + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ThemeViewHolder { + val themeResIds = BaseThemedActivity.getThemeResIds(themes[viewType], preferences.themeDarkAmoled().get()) + val themedContext = themeResIds.fold(parent.context) { + context, themeResId -> ContextThemeWrapper(context, themeResId) + } + + binding = PrefThemeItemBinding.inflate(LayoutInflater.from(themedContext), parent, false) + return ThemeViewHolder(binding.root) + } + + override fun getItemViewType(position: Int): Int = position + + override fun getItemCount(): Int = themes.size + + override fun onBindViewHolder(holder: ThemesPreferenceAdapter.ThemeViewHolder, position: Int) { + holder.bind(themes[position]) + } + + fun setItems(themes: List) { + this.themes = themes + notifyDataSetChanged() + } + + inner class ThemeViewHolder(private val view: View) : RecyclerView.ViewHolder(view) { + fun bind(appTheme: PreferenceValues.AppTheme) { + binding.name.text = view.context.getString(appTheme.titleResId!!) + + // Rounded corners + binding.coverContainer1.clipToOutline = true + binding.coverContainer2.clipToOutline = true + + binding.themeCard.isChecked = preferences.appTheme().get() == appTheme + + listOf(binding.root, binding.themeCard).forEach { + it.setOnClickListener { + clickListener.onItemClick(bindingAdapterPosition) + } + } + } + } + + interface OnItemClickListener { + fun onItemClick(position: Int) + } +} diff --git a/app/src/main/res/drawable/oval.xml b/app/src/main/res/drawable/oval.xml new file mode 100644 index 000000000..6df5dac5c --- /dev/null +++ b/app/src/main/res/drawable/oval.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/pref_theme_item.xml b/app/src/main/res/layout/pref_theme_item.xml new file mode 100644 index 000000000..ba73c2bff --- /dev/null +++ b/app/src/main/res/layout/pref_theme_item.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/pref_themes_list.xml b/app/src/main/res/layout/pref_themes_list.xml new file mode 100644 index 000000000..a957aa4c7 --- /dev/null +++ b/app/src/main/res/layout/pref_themes_list.xml @@ -0,0 +1,26 @@ + + + + + + + +