From 421dfb4a2d190a21d4862ef7da21b540ac6473ab Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 8 Aug 2020 18:17:42 -0400 Subject: [PATCH] Allow partially loading extensions with individually marked NSFW sources --- .../eu/kanade/tachiyomi/annoations/Nsfw.kt | 5 +++++ .../data/preference/PreferenceKeys.kt | 2 +- .../data/preference/PreferenceValues.kt | 6 ++++++ .../data/preference/PreferencesHelper.kt | 3 ++- .../extension/util/ExtensionLoader.kt | 18 ++++++++++++++--- .../ui/browse/extension/ExtensionPresenter.kt | 9 +++++---- .../ui/setting/SettingsBrowseController.kt | 20 ++++++++++++++++--- app/src/main/res/values/strings.xml | 5 ++++- 8 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt b/app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt new file mode 100644 index 000000000..5cff119a0 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt @@ -0,0 +1,5 @@ +package eu.kanade.tachiyomi.annoations + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +annotation class Nsfw diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index c4e50ea94..818c6c718 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -117,7 +117,7 @@ object PreferenceKeys { const val automaticExtUpdates = "automatic_ext_updates" - const val allowNsfwSources = "allow_nsfw_sources" + const val allowNsfwSource = "allow_nsfw_source" const val startScreen = "start_screen" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt index e60f7f508..d0afd208d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceValues.kt @@ -37,4 +37,10 @@ object PreferenceValues { VERTICAL, BOTH } + + enum class NsfwAllowance { + ALLOWED, + PARTIAL, + BLOCKED + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index e6ff999b8..f7a0ecd59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode +import eu.kanade.tachiyomi.data.preference.PreferenceValues.NsfwAllowance import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.anilist.Anilist import java.io.File @@ -217,7 +218,7 @@ class PreferencesHelper(val context: Context) { fun automaticExtUpdates() = flowPrefs.getBoolean(Keys.automaticExtUpdates, true) - fun allowNsfwSources() = prefs.getBoolean(Keys.allowNsfwSources, true) + fun allowNsfwSource() = flowPrefs.getEnum(Keys.allowNsfwSource, NsfwAllowance.ALLOWED) fun extensionUpdatesCount() = flowPrefs.getInt("ext_updates_count", 0) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt index e0caa0e2c..fbbb71585 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt @@ -5,6 +5,8 @@ import android.content.Context import android.content.pm.PackageInfo import android.content.pm.PackageManager import dalvik.system.PathClassLoader +import eu.kanade.tachiyomi.annoations.Nsfw +import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.LoadResult @@ -15,7 +17,6 @@ import eu.kanade.tachiyomi.util.lang.Hash import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import timber.log.Timber -import uy.kohesive.injekt.api.get import uy.kohesive.injekt.injectLazy /** @@ -128,7 +129,7 @@ internal object ExtensionLoader { } val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1 - if (!preferences.allowNsfwSources() && isNsfw) { + if (preferences.allowNsfwSource().get() == PreferenceValues.NsfwAllowance.BLOCKED && isNsfw) { return LoadResult.Error("NSFW extension $pkgName not allowed") } @@ -156,10 +157,11 @@ internal object ExtensionLoader { return LoadResult.Error(e) } } + .filter { preferences.allowNsfwSource().get() == PreferenceValues.NsfwAllowance.ALLOWED || !isSourceNsfw(it) } + val langs = sources.filterIsInstance() .map { it.lang } .toSet() - val lang = when (langs.size) { 0 -> "" 1 -> langs.first() @@ -195,4 +197,14 @@ internal object ExtensionLoader { null } } + + /** + * Checks whether a source is annotated with @Nsfw. + */ + private fun isSourceNsfw(source: Source): Boolean { + // Annotations are proxied, hence this janky way of checking for them + return source.javaClass.annotations + .flatMap { it.javaClass.interfaces.map { it.simpleName } } + .firstOrNull { it == Nsfw::class.java.simpleName } != null + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt index 7731b737d..f9ca2b386 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/ExtensionPresenter.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.browse.extension import android.app.Application import android.os.Bundle import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferenceValues import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.model.Extension @@ -55,14 +56,14 @@ open class ExtensionPresenter( private fun toItems(tuple: ExtensionTuple): List { val context = Injekt.get() val activeLangs = preferences.enabledLanguages().get() - val allowNsfw = preferences.allowNsfwSources() + val showNsfwExtensions = preferences.allowNsfwSource().get() != PreferenceValues.NsfwAllowance.BLOCKED val (installed, untrusted, available) = tuple val items = mutableListOf() - val updatesSorted = installed.filter { it.hasUpdate && (allowNsfw || !it.isNsfw) }.sortedBy { it.pkgName } - val installedSorted = installed.filter { !it.hasUpdate && (allowNsfw || !it.isNsfw) }.sortedWith(compareBy({ !it.isObsolete }, { it.pkgName })) + val updatesSorted = installed.filter { it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }.sortedBy { it.pkgName } + val installedSorted = installed.filter { !it.hasUpdate && (showNsfwExtensions || !it.isNsfw) }.sortedWith(compareBy({ !it.isObsolete }, { it.pkgName })) val untrustedSorted = untrusted.sortedBy { it.pkgName } val availableSorted = available // Filter out already installed extensions and disabled languages @@ -70,7 +71,7 @@ open class ExtensionPresenter( installed.none { it.pkgName == avail.pkgName } && untrusted.none { it.pkgName == avail.pkgName } && (avail.lang in activeLangs || avail.lang == "all") && - (allowNsfw || !avail.isNsfw) + (showNsfwExtensions || !avail.isNsfw) } .sortedBy { it.pkgName } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt index 4aa6a109c..41ab6017a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBrowseController.kt @@ -3,8 +3,11 @@ package eu.kanade.tachiyomi.ui.setting import androidx.preference.PreferenceScreen import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys +import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values import eu.kanade.tachiyomi.extension.ExtensionUpdateJob import eu.kanade.tachiyomi.util.preference.defaultValue +import eu.kanade.tachiyomi.util.preference.entriesRes +import eu.kanade.tachiyomi.util.preference.listPreference import eu.kanade.tachiyomi.util.preference.onChange import eu.kanade.tachiyomi.util.preference.preferenceCategory import eu.kanade.tachiyomi.util.preference.switchPreference @@ -29,10 +32,21 @@ class SettingsBrowseController : SettingsController() { true } } - switchPreference { - key = Keys.allowNsfwSources + listPreference { + key = Keys.allowNsfwSource titleRes = R.string.pref_allow_nsfw_sources - defaultValue = true + entriesRes = arrayOf( + R.string.pref_allow_nsfw_sources_allowed, + R.string.pref_allow_nsfw_sources_allowed_multisource, + R.string.pref_allow_nsfw_sources_blocked + ) + entryValues = arrayOf( + Values.NsfwAllowance.ALLOWED.name, + Values.NsfwAllowance.PARTIAL.name, + Values.NsfwAllowance.BLOCKED.name + ) + defaultValue = Values.NsfwAllowance.ALLOWED.name + summary = "%s" } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb787f879..b33b8ac88 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -330,7 +330,10 @@ Check for extension updates - Allow sources with NSFW content + NSFW sources + Allowed + Block source but show in extensions list + Blocked Only include pinned sources