mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-30 22:07:57 +01:00 
			
		
		
		
	Manage sources from extension details (closes #3152)
This commit is contained in:
		| @@ -1,23 +1,61 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.extension | ||||
|  | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.os.Bundle | ||||
| import android.util.TypedValue | ||||
| import android.view.LayoutInflater | ||||
| import android.view.Menu | ||||
| import android.view.MenuInflater | ||||
| import android.view.MenuItem | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import androidx.appcompat.view.ContextThemeWrapper | ||||
| import androidx.preference.DialogPreference | ||||
| import androidx.preference.EditTextPreference | ||||
| import androidx.preference.EditTextPreferenceDialogController | ||||
| import androidx.preference.ListPreference | ||||
| import androidx.preference.ListPreferenceDialogController | ||||
| import androidx.preference.MultiSelectListPreference | ||||
| import androidx.preference.MultiSelectListPreferenceDialogController | ||||
| import androidx.preference.Preference | ||||
| import androidx.preference.PreferenceGroupAdapter | ||||
| import androidx.preference.PreferenceManager | ||||
| import androidx.preference.PreferenceScreen | ||||
| import androidx.recyclerview.widget.DividerItemDecoration | ||||
| import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore | ||||
| import eu.kanade.tachiyomi.data.preference.PreferencesHelper | ||||
| import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore | ||||
| import eu.kanade.tachiyomi.databinding.ExtensionDetailControllerBinding | ||||
| import eu.kanade.tachiyomi.extension.model.Extension | ||||
| import eu.kanade.tachiyomi.source.CatalogueSource | ||||
| import eu.kanade.tachiyomi.source.ConfigurableSource | ||||
| import eu.kanade.tachiyomi.source.Source | ||||
| import eu.kanade.tachiyomi.ui.base.controller.NucleusController | ||||
| import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction | ||||
| import eu.kanade.tachiyomi.util.preference.checkBoxPreference | ||||
| import eu.kanade.tachiyomi.util.preference.onChange | ||||
| import eu.kanade.tachiyomi.util.preference.preference | ||||
| import eu.kanade.tachiyomi.util.preference.preferenceCategory | ||||
| import eu.kanade.tachiyomi.util.system.LocaleHelper | ||||
| import eu.kanade.tachiyomi.util.view.visible | ||||
| import kotlinx.coroutines.flow.launchIn | ||||
| import kotlinx.coroutines.flow.onEach | ||||
| import reactivecircus.flowbinding.android.view.clicks | ||||
| import uy.kohesive.injekt.injectLazy | ||||
|  | ||||
| @SuppressLint("RestrictedApi") | ||||
| class ExtensionDetailsController(bundle: Bundle? = null) : | ||||
|     NucleusController<ExtensionDetailControllerBinding, ExtensionDetailsPresenter>(bundle) { | ||||
|     NucleusController<ExtensionDetailControllerBinding, ExtensionDetailsPresenter>(bundle), | ||||
|     PreferenceManager.OnDisplayPreferenceDialogListener, | ||||
|     DialogPreference.TargetFragment { | ||||
|  | ||||
|     private val preferences: PreferencesHelper by injectLazy() | ||||
|  | ||||
|     private var preferenceScreen: PreferenceScreen? = null | ||||
|     private var lastOpenPreferencePosition: Int? = null | ||||
|  | ||||
|     constructor(pkgName: String) : this( | ||||
|         Bundle().apply { | ||||
| @@ -25,8 +63,13 @@ class ExtensionDetailsController(bundle: Bundle? = null) : | ||||
|         } | ||||
|     ) | ||||
|  | ||||
|     init { | ||||
|         setHasOptionsMenu(true) | ||||
|     } | ||||
|  | ||||
|     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { | ||||
|         binding = ExtensionDetailControllerBinding.inflate(inflater) | ||||
|         val themedInflater = inflater.cloneInContext(getPreferenceThemeContext()) | ||||
|         binding = ExtensionDetailControllerBinding.inflate(themedInflater) | ||||
|         return binding.root | ||||
|     } | ||||
|  | ||||
| @@ -65,25 +108,186 @@ class ExtensionDetailsController(bundle: Bundle? = null) : | ||||
|             binding.extensionWarningBanner.setText(R.string.unofficial_extension_message) | ||||
|         } | ||||
|  | ||||
|         if (presenter.extension?.sources?.find { it is ConfigurableSource } != null) { | ||||
|             binding.extensionPrefs.visible() | ||||
|             binding.extensionPrefs.clicks() | ||||
|                 .onEach { openPreferences() } | ||||
|                 .launchIn(scope) | ||||
|         initPreferences(context, extension) | ||||
|     } | ||||
|  | ||||
|     private fun initPreferences(context: Context, extension: Extension.Installed) { | ||||
|         val themedContext by lazy { getPreferenceThemeContext() } | ||||
|         val manager = PreferenceManager(themedContext) | ||||
|         manager.preferenceDataStore = EmptyPreferenceDataStore() | ||||
|         manager.onDisplayPreferenceDialogListener = this | ||||
|         val screen = manager.createPreferenceScreen(themedContext) | ||||
|         preferenceScreen = screen | ||||
|  | ||||
|         with(screen) { | ||||
|             extension.sources | ||||
|                 .groupBy { (it as CatalogueSource).lang } | ||||
|                 .toSortedMap(compareBy { LocaleHelper.getSourceDisplayName(it, context) }) | ||||
|                 .forEach { | ||||
|                     preferenceCategory { | ||||
|                         title = LocaleHelper.getSourceDisplayName(it.key, context) | ||||
|                         it.value | ||||
|                             .sortedWith(compareBy({ !it.isEnabled() }, { it.name })) | ||||
|                             .forEach { source -> | ||||
|                                 val sourcePrefs = mutableListOf<Preference>() | ||||
|  | ||||
|                                 // Source enable/disable | ||||
|                                 checkBoxPreference { | ||||
|                                     key = getSourceKey(source.id) | ||||
|                                     title = source.toString() | ||||
|                                     isPersistent = false | ||||
|                                     isChecked = source.isEnabled() | ||||
|  | ||||
|                                     onChange { newValue -> | ||||
|                                         val checked = newValue as Boolean | ||||
|                                         toggleSource(source, checked) | ||||
|                                         true | ||||
|                                     } | ||||
|  | ||||
|                                     // React to enable/disable all changes | ||||
|                                     preferences.hiddenCatalogues().asFlow() | ||||
|                                         .onEach { | ||||
|                                             val enabled = source.isEnabled() | ||||
|                                             isChecked = enabled | ||||
|                                             sourcePrefs.forEach { pref -> pref.isVisible = enabled } | ||||
|                                         } | ||||
|                                         .launchIn(scope) | ||||
|                                 } | ||||
|  | ||||
|                                 // Source preferences | ||||
|                                 if (source is ConfigurableSource) { | ||||
|                                     // TODO | ||||
|                                     val dataStore = SharedPreferencesDataStore(/*if (source is HttpSource) { | ||||
|                                         source.preferences | ||||
|                                     } else {*/ | ||||
|                                         context.getSharedPreferences(getSourceKey(source.id), Context.MODE_PRIVATE) | ||||
|                                         /*}*/ | ||||
|                                     ) | ||||
|  | ||||
|                                     val newScreen = screen.preferenceManager.createPreferenceScreen(context) | ||||
|                                     source.setupPreferenceScreen(newScreen) | ||||
|  | ||||
|                                     // Reparent the preferences | ||||
|                                     while (newScreen.preferenceCount != 0) { | ||||
|                                         val pref = newScreen.getPreference(0) | ||||
|                                         sourcePrefs.add(pref) | ||||
|  | ||||
|                                         pref.preferenceDataStore = dataStore | ||||
|                                         pref.order = Int.MAX_VALUE // reset to default order | ||||
|                                         pref.isVisible = source.isEnabled() | ||||
|  | ||||
|                                         newScreen.removePreference(pref) | ||||
|                                         screen.addPreference(pref) | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                     } | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|         binding.extensionPrefsRecycler.layoutManager = LinearLayoutManager(context) | ||||
|         binding.extensionPrefsRecycler.adapter = PreferenceGroupAdapter(screen) | ||||
|         binding.extensionPrefsRecycler.addItemDecoration(DividerItemDecoration(context, VERTICAL)) | ||||
|     } | ||||
|  | ||||
|     override fun onSaveInstanceState(outState: Bundle) { | ||||
|         lastOpenPreferencePosition?.let { outState.putInt(LASTOPENPREFERENCE_KEY, it) } | ||||
|         super.onSaveInstanceState(outState) | ||||
|     } | ||||
|  | ||||
|     override fun onRestoreInstanceState(savedInstanceState: Bundle) { | ||||
|         super.onRestoreInstanceState(savedInstanceState) | ||||
|         lastOpenPreferencePosition = savedInstanceState.get(LASTOPENPREFERENCE_KEY) as? Int | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyView(view: View) { | ||||
|         preferenceScreen = null | ||||
|         super.onDestroyView(view) | ||||
|     } | ||||
|  | ||||
|     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { | ||||
|         inflater.inflate(R.menu.extension_details, menu) | ||||
|     } | ||||
|  | ||||
|     override fun onOptionsItemSelected(item: MenuItem): Boolean { | ||||
|         when (item.itemId) { | ||||
|             R.id.action_enable_all -> toggleAllSources(true) | ||||
|             R.id.action_disable_all -> toggleAllSources(false) | ||||
|         } | ||||
|         return super.onOptionsItemSelected(item) | ||||
|     } | ||||
|  | ||||
|     fun onExtensionUninstalled() { | ||||
|         router.popCurrentController() | ||||
|     } | ||||
|  | ||||
|     private fun openPreferences() { | ||||
|         router.pushController( | ||||
|             ExtensionPreferencesController(presenter.extension!!.pkgName).withFadeTransaction() | ||||
|     private fun toggleAllSources(enable: Boolean) { | ||||
|         presenter.extension?.sources?.forEach { toggleSource(it, enable) } | ||||
|     } | ||||
|  | ||||
|     private fun toggleSource(source: Source, enable: Boolean) { | ||||
|         val current = preferences.hiddenCatalogues().get() | ||||
|  | ||||
|         preferences.hiddenCatalogues().set( | ||||
|             if (enable) { | ||||
|                 current - source.id.toString() | ||||
|             } else { | ||||
|                 current + source.id.toString() | ||||
|             } | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     private fun Source.isEnabled(): Boolean { | ||||
|         return id.toString() !in preferences.hiddenCatalogues().get() | ||||
|     } | ||||
|  | ||||
|     private fun getSourceKey(sourceId: Long): String { | ||||
|         return "source_$sourceId" | ||||
|     } | ||||
|  | ||||
|     private fun getPreferenceThemeContext(): Context { | ||||
|         val tv = TypedValue() | ||||
|         activity!!.theme.resolveAttribute(R.attr.preferenceTheme, tv, true) | ||||
|         return ContextThemeWrapper(activity, tv.resourceId) | ||||
|     } | ||||
|  | ||||
|     override fun onDisplayPreferenceDialog(preference: Preference) { | ||||
|         if (!isAttached) return | ||||
|  | ||||
|         val screen = preference.parent!! | ||||
|  | ||||
|         lastOpenPreferencePosition = (0 until screen.preferenceCount).indexOfFirst { | ||||
|             screen.getPreference(it) === preference | ||||
|         } | ||||
|  | ||||
|         val f = when (preference) { | ||||
|             is EditTextPreference -> | ||||
|                 EditTextPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             is ListPreference -> | ||||
|                 ListPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             is MultiSelectListPreference -> | ||||
|                 MultiSelectListPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             else -> throw IllegalArgumentException( | ||||
|                 "Tried to display dialog for unknown " + | ||||
|                     "preference type. Did you forget to override onDisplayPreferenceDialog()?" | ||||
|             ) | ||||
|         } | ||||
|         f.targetController = this | ||||
|         f.showDialog(router) | ||||
|     } | ||||
|  | ||||
|     @Suppress("UNCHECKED_CAST") | ||||
|     override fun <T : Preference> findPreference(key: CharSequence): T? { | ||||
|         // We track [lastOpenPreferencePosition] when displaying the dialog | ||||
|         // [key] isn't useful since there may be duplicates | ||||
|         return preferenceScreen!!.getPreference(lastOpenPreferencePosition!!) as T | ||||
|     } | ||||
|  | ||||
|     private companion object { | ||||
|         const val PKGNAME_KEY = "pkg_name" | ||||
|         const val LASTOPENPREFERENCE_KEY = "last_open_preference" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -36,11 +36,13 @@ class ExtensionFilterController : SettingsController() { | ||||
|                     val checked = newValue as Boolean | ||||
|                     val currentActiveLangs = preferences.enabledLanguages().get() | ||||
|  | ||||
|                     preferences.enabledLanguages().set(if (checked) { | ||||
|                         currentActiveLangs + it | ||||
|                     } else { | ||||
|                         currentActiveLangs - it | ||||
|                     }) | ||||
|                     preferences.enabledLanguages().set( | ||||
|                         if (checked) { | ||||
|                             currentActiveLangs + it | ||||
|                         } else { | ||||
|                             currentActiveLangs - it | ||||
|                         } | ||||
|                     ) | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -1,196 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.extension | ||||
|  | ||||
| import android.annotation.SuppressLint | ||||
| import android.content.Context | ||||
| import android.os.Bundle | ||||
| import android.util.TypedValue | ||||
| import android.view.ContextThemeWrapper | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import androidx.preference.DialogPreference | ||||
| import androidx.preference.EditTextPreference | ||||
| import androidx.preference.EditTextPreferenceDialogController | ||||
| import androidx.preference.ListPreference | ||||
| import androidx.preference.ListPreferenceDialogController | ||||
| import androidx.preference.MultiSelectListPreference | ||||
| import androidx.preference.MultiSelectListPreferenceDialogController | ||||
| import androidx.preference.Preference | ||||
| import androidx.preference.PreferenceGroupAdapter | ||||
| import androidx.preference.PreferenceManager | ||||
| import androidx.preference.PreferenceScreen | ||||
| import androidx.recyclerview.widget.DividerItemDecoration | ||||
| import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL | ||||
| import androidx.recyclerview.widget.LinearLayoutManager | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore | ||||
| import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore | ||||
| import eu.kanade.tachiyomi.databinding.ExtensionPreferencesControllerBinding | ||||
| import eu.kanade.tachiyomi.source.ConfigurableSource | ||||
| import eu.kanade.tachiyomi.source.Source | ||||
| import eu.kanade.tachiyomi.ui.base.controller.NucleusController | ||||
| import eu.kanade.tachiyomi.util.preference.preferenceCategory | ||||
| import timber.log.Timber | ||||
|  | ||||
| @SuppressLint("RestrictedApi") | ||||
| class ExtensionPreferencesController(bundle: Bundle? = null) : | ||||
|     NucleusController<ExtensionPreferencesControllerBinding, ExtensionPreferencesPresenter>(bundle), | ||||
|     PreferenceManager.OnDisplayPreferenceDialogListener, | ||||
|     DialogPreference.TargetFragment { | ||||
|  | ||||
|     private var lastOpenPreferencePosition: Int? = null | ||||
|  | ||||
|     private var preferenceScreen: PreferenceScreen? = null | ||||
|  | ||||
|     constructor(pkgName: String) : this( | ||||
|         Bundle().apply { | ||||
|             putString(PKGNAME_KEY, pkgName) | ||||
|         } | ||||
|     ) | ||||
|  | ||||
|     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { | ||||
|         val themedInflater = inflater.cloneInContext(getPreferenceThemeContext()) | ||||
|         binding = ExtensionPreferencesControllerBinding.inflate(themedInflater) | ||||
|         return binding.root | ||||
|     } | ||||
|  | ||||
|     override fun createPresenter(): ExtensionPreferencesPresenter { | ||||
|         return ExtensionPreferencesPresenter(args.getString(PKGNAME_KEY)!!) | ||||
|     } | ||||
|  | ||||
|     override fun getTitle(): String? { | ||||
|         return resources?.getString(R.string.label_extension_info) | ||||
|     } | ||||
|  | ||||
|     @SuppressLint("PrivateResource") | ||||
|     override fun onViewCreated(view: View) { | ||||
|         super.onViewCreated(view) | ||||
|  | ||||
|         val extension = presenter.extension ?: return | ||||
|         val context = view.context | ||||
|  | ||||
|         val themedContext by lazy { getPreferenceThemeContext() } | ||||
|         val manager = PreferenceManager(themedContext) | ||||
|         manager.preferenceDataStore = EmptyPreferenceDataStore() | ||||
|         manager.onDisplayPreferenceDialogListener = this | ||||
|         val screen = manager.createPreferenceScreen(themedContext) | ||||
|         preferenceScreen = screen | ||||
|  | ||||
|         val multiSource = extension.sources.size > 1 | ||||
|  | ||||
|         extension.sources | ||||
|             .filterIsInstance<ConfigurableSource>() | ||||
|             .forEach { source -> | ||||
|                 try { | ||||
|                     addPreferencesForSource(screen, source, multiSource) | ||||
|                 } catch (e: AbstractMethodError) { | ||||
|                     Timber.e("Source did not implement [addPreferencesForSource]: ${source.name}") | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         manager.setPreferences(screen) | ||||
|  | ||||
|         binding.extensionPrefsRecycler.layoutManager = LinearLayoutManager(context) | ||||
|         binding.extensionPrefsRecycler.adapter = PreferenceGroupAdapter(screen) | ||||
|         binding.extensionPrefsRecycler.addItemDecoration(DividerItemDecoration(context, VERTICAL)) | ||||
|  | ||||
|         if (screen.preferenceCount == 0) { | ||||
|             binding.extensionPrefsEmptyView.show(R.string.ext_empty_preferences) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onDestroyView(view: View) { | ||||
|         preferenceScreen = null | ||||
|         super.onDestroyView(view) | ||||
|     } | ||||
|  | ||||
|     override fun onSaveInstanceState(outState: Bundle) { | ||||
|         lastOpenPreferencePosition?.let { outState.putInt(LASTOPENPREFERENCE_KEY, it) } | ||||
|         super.onSaveInstanceState(outState) | ||||
|     } | ||||
|  | ||||
|     override fun onRestoreInstanceState(savedInstanceState: Bundle) { | ||||
|         super.onRestoreInstanceState(savedInstanceState) | ||||
|         lastOpenPreferencePosition = savedInstanceState.get(LASTOPENPREFERENCE_KEY) as? Int | ||||
|     } | ||||
|  | ||||
|     private fun addPreferencesForSource(screen: PreferenceScreen, source: Source, multiSource: Boolean) { | ||||
|         val context = screen.context | ||||
|  | ||||
|         // TODO | ||||
|         val dataStore = SharedPreferencesDataStore(/*if (source is HttpSource) { | ||||
|             source.preferences | ||||
|         } else {*/ | ||||
|             context.getSharedPreferences("source_${source.id}", Context.MODE_PRIVATE) | ||||
|             /*}*/ | ||||
|         ) | ||||
|  | ||||
|         if (source is ConfigurableSource) { | ||||
|             if (multiSource) { | ||||
|                 screen.preferenceCategory { | ||||
|                     title = source.toString() | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             val newScreen = screen.preferenceManager.createPreferenceScreen(context) | ||||
|             source.setupPreferenceScreen(newScreen) | ||||
|  | ||||
|             // Reparent the preferences | ||||
|             while (newScreen.preferenceCount != 0) { | ||||
|                 val pref = newScreen.getPreference(0) | ||||
|                 pref.isIconSpaceReserved = false | ||||
|                 pref.preferenceDataStore = dataStore | ||||
|                 pref.order = Int.MAX_VALUE // reset to default order | ||||
|  | ||||
|                 newScreen.removePreference(pref) | ||||
|                 screen.addPreference(pref) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun getPreferenceThemeContext(): Context { | ||||
|         val tv = TypedValue() | ||||
|         activity!!.theme.resolveAttribute(R.attr.preferenceTheme, tv, true) | ||||
|         return ContextThemeWrapper(activity, tv.resourceId) | ||||
|     } | ||||
|  | ||||
|     override fun onDisplayPreferenceDialog(preference: Preference) { | ||||
|         if (!isAttached) return | ||||
|  | ||||
|         val screen = preference.parent!! | ||||
|  | ||||
|         lastOpenPreferencePosition = (0 until screen.preferenceCount).indexOfFirst { | ||||
|             screen.getPreference(it) === preference | ||||
|         } | ||||
|  | ||||
|         val f = when (preference) { | ||||
|             is EditTextPreference -> | ||||
|                 EditTextPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             is ListPreference -> | ||||
|                 ListPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             is MultiSelectListPreference -> | ||||
|                 MultiSelectListPreferenceDialogController | ||||
|                     .newInstance(preference.getKey()) | ||||
|             else -> throw IllegalArgumentException( | ||||
|                 "Tried to display dialog for unknown " + | ||||
|                     "preference type. Did you forget to override onDisplayPreferenceDialog()?" | ||||
|             ) | ||||
|         } | ||||
|         f.targetController = this | ||||
|         f.showDialog(router) | ||||
|     } | ||||
|  | ||||
|     @Suppress("UNCHECKED_CAST") | ||||
|     override fun <T : Preference> findPreference(key: CharSequence): T? { | ||||
|         // We track [lastOpenPreferencePosition] when displaying the dialog | ||||
|         // [key] isn't useful since there may be duplicates | ||||
|         return preferenceScreen!!.getPreference(lastOpenPreferencePosition!!) as T | ||||
|     } | ||||
|  | ||||
|     private companion object { | ||||
|         const val PKGNAME_KEY = "pkg_name" | ||||
|         const val LASTOPENPREFERENCE_KEY = "last_open_preference" | ||||
|     } | ||||
| } | ||||
| @@ -1,14 +0,0 @@ | ||||
| package eu.kanade.tachiyomi.ui.browse.extension | ||||
|  | ||||
| import eu.kanade.tachiyomi.extension.ExtensionManager | ||||
| import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| class ExtensionPreferencesPresenter( | ||||
|     val pkgName: String, | ||||
|     extensionManager: ExtensionManager = Injekt.get() | ||||
| ) : BasePresenter<ExtensionPreferencesController>() { | ||||
|  | ||||
|     val extension = extensionManager.installedExtensions.find { it.pkgName == pkgName } | ||||
| } | ||||
| @@ -1,15 +1,11 @@ | ||||
| package eu.kanade.tachiyomi.ui.setting | ||||
|  | ||||
| import android.graphics.drawable.Drawable | ||||
| import androidx.preference.CheckBoxPreference | ||||
| import androidx.preference.PreferenceGroup | ||||
| import androidx.preference.PreferenceScreen | ||||
| import eu.kanade.tachiyomi.R | ||||
| import eu.kanade.tachiyomi.source.SourceManager | ||||
| import eu.kanade.tachiyomi.source.icon | ||||
| import eu.kanade.tachiyomi.source.online.HttpSource | ||||
| import eu.kanade.tachiyomi.util.preference.onChange | ||||
| import eu.kanade.tachiyomi.util.preference.switchPreferenceCategory | ||||
| import eu.kanade.tachiyomi.util.preference.switchPreference | ||||
| import eu.kanade.tachiyomi.util.preference.titleRes | ||||
| import eu.kanade.tachiyomi.util.system.LocaleHelper | ||||
| import java.util.TreeMap | ||||
| @@ -33,28 +29,22 @@ class SettingsSourcesController : SettingsController() { | ||||
|         val orderedLangs = sourcesByLang.keys.sortedWith(compareBy({ it !in activeLangsCodes }, { LocaleHelper.getSourceDisplayName(it, context) })) | ||||
|  | ||||
|         orderedLangs.forEach { lang -> | ||||
|             val sources = sourcesByLang[lang].orEmpty().sortedBy { it.name } | ||||
|  | ||||
|             // Create a preference group and set initial state and change listener | ||||
|             switchPreferenceCategory { | ||||
|             switchPreference { | ||||
|                 preferenceScreen.addPreference(this) | ||||
|                 title = LocaleHelper.getSourceDisplayName(lang, context) | ||||
|                 isPersistent = false | ||||
|                 if (lang in activeLangsCodes) { | ||||
|                     setChecked(true) | ||||
|                     addLanguageSources(this, sources) | ||||
|                 } | ||||
|                 isChecked = lang in activeLangsCodes | ||||
|  | ||||
|                 onChange { newValue -> | ||||
|                     val checked = newValue as Boolean | ||||
|                     val current = preferences.enabledLanguages().get() | ||||
|                     if (!checked) { | ||||
|                         preferences.enabledLanguages().set(current - lang) | ||||
|                         removeAll() | ||||
|                     } else { | ||||
|                         preferences.enabledLanguages().set(current + lang) | ||||
|                         addLanguageSources(this, sources) | ||||
|                     } | ||||
|                     preferences.enabledLanguages().set( | ||||
|                         if (!checked) { | ||||
|                             current - lang | ||||
|                         } else { | ||||
|                             current + lang | ||||
|                         } | ||||
|                     ) | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
| @@ -64,49 +54,4 @@ class SettingsSourcesController : SettingsController() { | ||||
|     override fun setDivider(divider: Drawable?) { | ||||
|         super.setDivider(null) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds the source list for the given group (language). | ||||
|      * | ||||
|      * @param group the language category. | ||||
|      */ | ||||
|     private fun addLanguageSources(group: PreferenceGroup, sources: List<HttpSource>) { | ||||
|         val hiddenCatalogues = preferences.hiddenCatalogues().get() | ||||
|  | ||||
|         sources.forEach { source -> | ||||
|             val sourcePreference = CheckBoxPreference(group.context).apply { | ||||
|                 val id = source.id.toString() | ||||
|                 title = source.name | ||||
|                 key = getSourceKey(source.id) | ||||
|                 isPersistent = false | ||||
|                 isChecked = id !in hiddenCatalogues | ||||
|  | ||||
|                 val sourceIcon = source.icon() | ||||
|                 if (sourceIcon != null) { | ||||
|                     icon = sourceIcon | ||||
|                 } | ||||
|  | ||||
|                 onChange { newValue -> | ||||
|                     val checked = newValue as Boolean | ||||
|                     val current = preferences.hiddenCatalogues().get() | ||||
|  | ||||
|                     preferences.hiddenCatalogues().set( | ||||
|                         if (checked) { | ||||
|                             current - id | ||||
|                         } else { | ||||
|                             current + id | ||||
|                         } | ||||
|                     ) | ||||
|  | ||||
|                     true | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             group.addPreference(sourcePreference) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun getSourceKey(sourceId: Long): String { | ||||
|         return "source_$sourceId" | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user