mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	Allow partially loading extensions with individually marked NSFW sources
This commit is contained in:
		
							
								
								
									
										5
									
								
								app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/src/main/java/eu/kanade/tachiyomi/annoations/Nsfw.kt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| package eu.kanade.tachiyomi.annoations | ||||
|  | ||||
| @Retention(AnnotationRetention.RUNTIME) | ||||
| @Target(AnnotationTarget.CLASS) | ||||
| annotation class Nsfw | ||||
| @@ -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" | ||||
|  | ||||
|   | ||||
| @@ -37,4 +37,10 @@ object PreferenceValues { | ||||
|         VERTICAL, | ||||
|         BOTH | ||||
|     } | ||||
|  | ||||
|     enum class NsfwAllowance { | ||||
|         ALLOWED, | ||||
|         PARTIAL, | ||||
|         BLOCKED | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
| @@ -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<CatalogueSource>() | ||||
|             .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 | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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<ExtensionItem> { | ||||
|         val context = Injekt.get<Application>() | ||||
|         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<ExtensionItem>() | ||||
|  | ||||
|         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 } | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user