From c789d6ee14bbe59cae40a9958f152a7cdb1878f9 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 9 Feb 2024 01:17:02 +0100 Subject: [PATCH] feat(YouTube Music): Add `Settings` patch --- api/revanced-patches.api | 33 +- .../music/misc/debugging/DebuggingPatch.kt | 13 + .../music/misc/settings/SettingsPatch.kt | 70 ++ .../misc/settings/SettingsResourcePatch.kt | 31 + .../FullStackTraceActivityFingerprint.kt | 11 + .../misc/debugging/BaseDebuggingPatch.kt | 41 ++ .../twitch/misc/settings/SettingsPatch.kt | 4 +- .../youtube/misc/debugging/DebuggingPatch.kt | 34 +- .../misc/settings/SettingsResourcePatch.kt | 7 +- .../resources/addresources/values/strings.xml | 614 +++++++++++++----- .../layout/revanced_settings_with_toolbar.xml | 2 +- 11 files changed, 665 insertions(+), 195 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsResourcePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/misc/settings/fingerprints/FullStackTraceActivityFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 10956e60c..41f98f424 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -346,6 +346,10 @@ public final class app/revanced/patches/music/misc/androidauto/BypassCertificate public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/misc/debugging/DebuggingPatch : app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch { + public static final field INSTANCE Lapp/revanced/patches/music/misc/debugging/DebuggingPatch; +} + public final class app/revanced/patches/music/misc/gms/Constants { public static final field INSTANCE Lapp/revanced/patches/music/misc/gms/Constants; } @@ -362,6 +366,26 @@ public final class app/revanced/patches/music/misc/integrations/IntegrationsPatc public static final field INSTANCE Lapp/revanced/patches/music/misc/integrations/IntegrationsPatch; } +public final class app/revanced/patches/music/misc/settings/SettingsPatch : app/revanced/patcher/patch/BytecodePatch, java/io/Closeable { + public static final field INSTANCE Lapp/revanced/patches/music/misc/settings/SettingsPatch; + public fun close ()V + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public final fun newIntent (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent; +} + +public final class app/revanced/patches/music/misc/settings/SettingsPatch$PreferenceScreen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen { + public static final field INSTANCE Lapp/revanced/patches/music/misc/settings/SettingsPatch$PreferenceScreen; + public fun commit (Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen;)V + public final fun getMISC ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen; +} + +public final class app/revanced/patches/music/misc/settings/SettingsResourcePatch : app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch { + public static final field INSTANCE Lapp/revanced/patches/music/misc/settings/SettingsResourcePatch; + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V +} + public final class app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -580,6 +604,13 @@ public final class app/revanced/patches/serviceportalbund/detection/root/RootDet public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public abstract class app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch : app/revanced/patcher/patch/ResourcePatch { + public fun (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/util/Set;Ljava/util/Set;)V + public synthetic fun (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V +} + public final class app/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -1473,7 +1504,7 @@ public final class app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/youtube/misc/debugging/DebuggingPatch : app/revanced/patcher/patch/ResourcePatch { +public final class app/revanced/patches/youtube/misc/debugging/DebuggingPatch : app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/debugging/DebuggingPatch; public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V diff --git a/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt new file mode 100644 index 000000000..edcf34bbf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/debugging/DebuggingPatch.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.music.misc.debugging + +import app.revanced.patches.music.misc.integrations.IntegrationsPatch +import app.revanced.patches.music.misc.settings.SettingsPatch +import app.revanced.patches.shared.misc.debugging.BaseDebuggingPatch + +@Suppress("unused") +object DebuggingPatch : BaseDebuggingPatch( + integrationsPatch = IntegrationsPatch::class, + settingsPatch = SettingsPatch::class, + compatiblePackages = setOf(CompatiblePackage("com.google.android.apps.youtube.music")), + miscPreferenceScreen = SettingsPatch.PreferenceScreen.MISC, +) diff --git a/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt new file mode 100644 index 000000000..da0589564 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt @@ -0,0 +1,70 @@ +package app.revanced.patches.music.misc.settings + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch +import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.music.misc.integrations.IntegrationsPatch +import app.revanced.patches.music.misc.settings.fingerprints.FullStackTraceActivityFingerprint +import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen +import app.revanced.patches.shared.misc.settings.preference.IntentPreference +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.util.MethodUtil +import java.io.Closeable + +@Patch( + description = "Adds settings for ReVanced to YouTube Music.", + dependencies = [ + IntegrationsPatch::class, + SettingsResourcePatch::class, + AddResourcesPatch::class + ] +) +object SettingsPatch : BytecodePatch( + setOf(FullStackTraceActivityFingerprint) +), Closeable { + private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/music" + private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/FullStackTraceActivityHook;" + + override fun execute(context: BytecodeContext) { + AddResourcesPatch(this::class) + + FullStackTraceActivityFingerprint.result?.let { result -> + result.mutableMethod.addInstructions( + 1, + """ + invoke-static { p0 }, $ACTIVITY_HOOK_CLASS_DESCRIPTOR->initialize(Landroid/app/Activity;)V + return-void + """ + ) + + // Remove other methods as they will break as the onCreate method is modified above. + result.mutableClass.apply { + methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) } + } + } ?: throw FullStackTraceActivityFingerprint.exception + } + + /** + * Creates an intent to open ReVanced settings. + */ + fun newIntent(settingsName: String) = IntentPreference.Intent( + data = settingsName, + targetClass = "com.google.android.libraries.strictmode.penalties.notification.FullStackTraceActivity" + ) { + // The package name change has to be reflected in the intent. + ChangePackageNamePatch.setOrGetFallbackPackageName("com.google.android.apps.youtube.music") + } + + object PreferenceScreen : BasePreferenceScreen() { + val MISC = Screen("revanced_misc_screen") + + override fun commit(screen: app.revanced.patches.shared.misc.settings.preference.PreferenceScreen) { + SettingsResourcePatch += screen + } + } + + override fun close() = PreferenceScreen.close() +} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsResourcePatch.kt new file mode 100644 index 000000000..b1a392ad9 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsResourcePatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.music.misc.settings + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch +import app.revanced.patches.shared.misc.settings.BaseSettingsResourcePatch +import app.revanced.patches.shared.misc.settings.preference.IntentPreference +import app.revanced.util.ResourceGroup +import app.revanced.util.copyResources + +object SettingsResourcePatch : BaseSettingsResourcePatch( + IntentPreference( + "revanced_settings", + intent = SettingsPatch.newIntent("revanced_settings_intent") + ) to "settings_headers", + dependencies = setOf( + ResourceMappingPatch::class, + AddResourcesPatch::class, + ) +) { + override fun execute(context: ResourceContext) { + super.execute(context) + + AddResourcesPatch(this::class) + + context.copyResources( + "settings", + ResourceGroup("layout", "revanced_settings_with_toolbar.xml") + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/settings/fingerprints/FullStackTraceActivityFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/settings/fingerprints/FullStackTraceActivityFingerprint.kt new file mode 100644 index 000000000..c350d31bb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/misc/settings/fingerprints/FullStackTraceActivityFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.music.misc.settings.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object FullStackTraceActivityFingerprint : MethodFingerprint( + returnType = "V", + parameters = listOf("Landroid/os/Bundle;"), + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("/FullStackTraceActivity;") && methodDef.name == "onCreate" + } +) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch.kt new file mode 100644 index 000000000..af87ab79e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/misc/debugging/BaseDebuggingPatch.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.shared.misc.debugging + +import app.revanced.patcher.PatchClass +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.BasePreference +import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen +import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen +import app.revanced.patches.shared.misc.settings.preference.SwitchPreference + +abstract class BaseDebuggingPatch( + integrationsPatch: PatchClass, + settingsPatch: PatchClass, + compatiblePackages: Set, + // TODO: Settings patch should probably be abstracted + // so we do not have to pass it in as a dependency AND it's preference screen at the same time. + private val miscPreferenceScreen: BasePreferenceScreen.Screen, + private val additionalDebugPreferences: Set = emptySet(), + additionalDependencies: Set = emptySet() +) : ResourcePatch( + name = "Enable debugging", + description = "Adds options for debugging.", + dependencies = setOf(integrationsPatch, settingsPatch) + AddResourcesPatch::class + additionalDependencies, + compatiblePackages = compatiblePackages +) { + override fun execute(context: ResourceContext) { + AddResourcesPatch(BaseDebuggingPatch::class) + + miscPreferenceScreen.addPreferences( + PreferenceScreen( + "revanced_debug_preference_screen", + preferences = setOf( + SwitchPreference("revanced_debug"), + SwitchPreference("revanced_debug_stacktrace"), + SwitchPreference("revanced_debug_toast_on_error") + ) + additionalDebugPreferences + ) + ) + } +} diff --git a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt index e8ec635c8..d3f5f1c83 100644 --- a/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt @@ -12,9 +12,9 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.AddResourcesPatch +import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen import app.revanced.patches.twitch.misc.integrations.IntegrationsPatch import app.revanced.patches.twitch.misc.settings.fingerprints.MenuGroupsOnClickFingerprint import app.revanced.patches.twitch.misc.settings.fingerprints.MenuGroupsUpdatedFingerprint @@ -48,7 +48,7 @@ object SettingsPatch : BytecodePatch( ), Closeable { private const val REVANCED_SETTINGS_MENU_ITEM_NAME = "RevancedSettings" private const val REVANCED_SETTINGS_MENU_ITEM_ID = 0x7 - private const val REVANCED_SETTINGS_MENU_ITEM_TITLE_RES = "revanced_settings" + private const val REVANCED_SETTINGS_MENU_ITEM_TITLE_RES = "revanced_settings_title" private const val REVANCED_SETTINGS_MENU_ITEM_ICON_RES = "ic_settings" private const val MENU_ITEM_ENUM_CLASS_DESCRIPTOR = "Ltv/twitch/android/feature/settings/menu/SettingsMenuItem;" diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt index 01576ee2c..0db6a5acc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/DebuggingPatch.kt @@ -1,36 +1,26 @@ package app.revanced.patches.youtube.misc.debugging import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.ResourcePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.all.misc.resources.AddResourcesPatch -import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen +import app.revanced.patches.shared.misc.debugging.BaseDebuggingPatch import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch -@Patch( - name = "Enable debugging", - description = "Adds options for debugging.", - dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], - compatiblePackages = [CompatiblePackage("com.google.android.youtube")] -) @Suppress("unused") -object DebuggingPatch : ResourcePatch() { +object DebuggingPatch : BaseDebuggingPatch( + integrationsPatch = IntegrationsPatch::class, + settingsPatch = SettingsPatch::class, + compatiblePackages = setOf(CompatiblePackage("com.google.android.youtube")), + miscPreferenceScreen = SettingsPatch.PreferenceScreen.MISC, + additionalDebugPreferences = setOf( + SwitchPreference("revanced_debug_protobuffer") + ), + additionalDependencies = setOf(AddResourcesPatch::class) +) { override fun execute(context: ResourceContext) { AddResourcesPatch(this::class) - SettingsPatch.PreferenceScreen.MISC.addPreferences( - PreferenceScreen( - "revanced_debug_preference_screen", - preferences = setOf( - SwitchPreference("revanced_debug"), - SwitchPreference("revanced_debug_protobuffer"), - SwitchPreference("revanced_debug_stacktrace"), - SwitchPreference("revanced_debug_toast_on_error") - ) - ) - ) + super.execute(context) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt index b4b50461a..aa7ca558e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsResourcePatch.kt @@ -32,11 +32,10 @@ object SettingsResourcePatch : BaseSettingsResourcePatch( it.type == "string" && it.name == "app_theme_appearance_dark" }!!.id - arrayOf( + context.copyResources( + "settings", ResourceGroup("layout", "revanced_settings_with_toolbar.xml") - ).forEach { resourceGroup -> - context.copyResources("settings", resourceGroup) - } + ) // Modify the manifest and add a data intent filter to the LicenseActivity. // Some devices freak out if undeclared data is passed to an intent, diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index fbda6995c..de3a9f5c5 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -1,7 +1,6 @@ - ReVanced Do you wish to proceed? Reset Refresh and restart @@ -14,20 +13,43 @@ GmsCore is not installed. Please install. - GmsCore is failing to run. Please follow the \"Don\'t kill my app\" guide for GmsCore. + GmsCore is failing to run. Please follow the \"Don\'t kill my + app\" guide for GmsCore. + + + + Debug logging + Debug logs are enabled + Debug logs are disabled + Debugging + Log stack traces + Debug logs include stack trace + Debug logs do not include stack trace + Show toast on ReVanced error + Toast shown if error occurs + Toast not shown if error occurs + Turning off error toasts hides all ReVanced + error notifications.\n\nYou will not be notified of any unexpected events. + + Enable or disable debugging options Showing original YouTube thumbnails Showing still video captures - Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then the original YouTube thumbnails are shown - Showing DeArrow thumbnails. If a video has no DeArrow thumbnails then still video captures are shown - DeArrow temporarily not available (status code: %s) + Showing DeArrow thumbnails. If a video has no + DeArrow thumbnails then the original YouTube thumbnails are shown + + Showing DeArrow thumbnails. If a video has + no DeArrow thumbnails then still video captures are shown + + DeArrow temporarily not available (status code: %s) + DeArrow temporarily not available - ReVanced + ReVanced ReVanced specific settings Import / Export Import / Export ReVanced settings @@ -45,21 +67,9 @@ Miscellaneous patches - Debug logging - Debug logs are enabled - Debug logs are disabled - Debugging Log protocol buffer Debug logs include proto buffer Debug logs do not include proto buffer - Log stack traces - Debug logs include stack trace - Debug logs do not include stack trace - Show toast on ReVanced error - Toast shown if error occurs - Toast not shown if error occurs - Turning off error toasts hides all ReVanced error notifications.\n\nYou will not be notified of any unexpected events. - Enable or disable debugging options Ads @@ -82,7 +92,9 @@ Hide timed reactions Timed reactions are hidden Timed reactions are shown - Hide \'People also watched\' recommendations + Hide \'People also watched\' + recommendations + Recommendations are hidden Recommendations are shown Hide search result shelf header @@ -95,8 +107,10 @@ Expandable chips are hidden Expandable chips are shown Hide video quality menu footer - Video quality menu footer is hidden - Video quality menu footer is shown + Video quality menu footer is hidden + + Video quality menu footer is shown + Hide chapters in the video description Chapters are hidden Chapters are shown @@ -115,9 +129,14 @@ Hide community guidelines Community guidelines are hidden Community guidelines are shown - Hide subscribers community guidelines - Subscribers community guidelines are hidden - Subscribers community guidelines are shown + Hide subscribers community guidelines + + Subscribers community guidelines + are hidden + + Subscribers community guidelines + are shown + Hide channel member shelf Channel member shelf is hidden Channel member shelf is shown @@ -154,7 +173,9 @@ Hide chips shelf Chips shelf is hidden Chips shelf is shown - Hide components in the video description + Hide components in the video + description + Hide info cards section Info cards section is hidden Info cards section is shown @@ -170,15 +191,22 @@ Hide transcript section Transcript section is hidden Transcript section is shown - Hide components under the video description + Hide components under the + video description + Custom filter Enable custom filter Custom filter is enabled Custom filter is disabled Custom filter - List of component path builder strings to filter separated by new line - Hide components using custom filters - Invalid custom filter (must be ASCII only): %s + List of component path builder strings to filter + separated by new line + + Hide components using custom filters + + Invalid custom filter (must be ASCII only): + %s + Invalid custom filter: %s Custom filter reset to default @@ -213,8 +241,12 @@ Hide YouTube Premium promotions - YouTube Premium promotions under video player are hidden - YouTube Premium promotions under video player are shown + YouTube Premium promotions under video player are + hidden + + YouTube Premium promotions under video player are + shown + Hide video ads @@ -226,28 +258,41 @@ URL with timestamp copied Copy video URL settings Show copy video URL button - Button is shown. Tap to copy video URL. Tap and hold to copy video URL with timestamp + Button is shown. Tap to copy video URL. Tap and hold to + copy video URL with timestamp + Button is not shown Show copy timestamp URL button - Button is shown. Tap to copy video URL with timestamp. Tap and hold to copy video without timestamp + Button is shown. Tap to copy video URL with + timestamp. Tap and hold to copy video without timestamp + Button is not shown - Settings related to copy URL buttons in video player + Settings related to copy URL buttons in + video player + Remove viewer discretion dialog Dialog will be removed Dialog will be shown - This does not bypass the age restriction. It just accepts it automatically. + This does not bypass the age + restriction. It just accepts it automatically. + - %s is not installed. Please install it. + %s is not installed. Please install it. + External download settings Show external download button Download button shown in player Download button not shown in player Downloader package name - Package name of your installed external downloader app, such as NewPipe or Seal - Settings for using an external downloader + Package name of your installed external downloader + app, such as NewPipe or Seal + + Settings for using an external + downloader + Disable precise seeking gesture @@ -274,14 +319,20 @@ Haptic feedback is enabled Haptic feedback is disabled Save and restore brightness - Save and restore brightness when exiting or entering fullscreen - Do not save and restore brightness when exiting or entering fullscreen + Save and restore brightness when + exiting or entering fullscreen + + Do not save and restore brightness + when exiting or entering fullscreen + Swipe overlay timeout - The amount of milliseconds the overlay is visible + The amount of milliseconds the overlay is visible + Swipe overlay text size The text size for swipe overlay Swipe background visibility - The visibility of swipe overlay background + The visibility of swipe overlay background + Swipe magnitude threshold The amount of threshold for swipe to occur Control volume and brightness @@ -354,20 +405,33 @@ Hide create button Create button is hidden Create button is shown - Switch create with notifications button - Create button is switched with notifications - Create button is not switched with notifications - Hide or change buttons in the navigation bar + Switch create with notifications + button + + Create button is switched with + notifications + + Create button is not switched + with notifications + + Hide or change buttons in the + navigation bar + Player flyout menu items - Manage the visibility of player flyout menu items + Manage the visibility of player flyout menu items + Hide Captions menu Captions menu item is hidden Captions menu item is shown Hide Additional settings menu - Additional settings menu item is hidden - Additional settings menu item is shown + Additional settings menu item is + hidden + + Additional settings menu item is + shown + Hide Loop video menu Loop video menu item is hidden Loop video menu item is shown @@ -416,7 +480,9 @@ Hide preview comment Preview comment is hidden Preview comment is shown - Manage the visibility of comments section components + Manage the visibility of comments section + components + Hide crowdfunding box @@ -439,7 +505,9 @@ Hide in related videos Hidden in related videos Shown in related videos - Manage the visibility of the filter bar in the feed, search and related videos + Manage the visibility of the filter bar in the + feed, search and related videos + Hide floating microphone button @@ -466,7 +534,8 @@ Disable rolling number animations - Rolling numbers are not animated + Rolling numbers are not animated + Rolling numbers are animated @@ -519,8 +588,10 @@ Disable suggested video end screen - Suggested videos will be disabled - Suggested videos will be shown + Suggested videos will be disabled + + Suggested videos will be shown + Hide video timestamp @@ -534,26 +605,36 @@ Player overlay opacity - Opacity value between 0-100, where 0 is transparent + Opacity value between 0-100, where 0 is transparent + Return YouTube Dislike Settings for Return YouTube Dislike Hidden - Dislikes temporarily not available (API timed out) - Dislikes not available (status %d) - Dislikes not available (client API limit reached) + Dislikes temporarily not available (API timed out) + + Dislikes not available (status + %d) + + Dislikes not available (client API limit + reached) + Dislikes not available (%s) - Reload video to vote using ReturnYouTubeDislike + Reload video to vote + using ReturnYouTubeDislike + Return YouTube Dislike Dislikes are shown Dislikes are not shown Show dislikes on Shorts Dislikes shown on Shorts %s Dislikes hidden on Shorts - Limitation: Dislikes may not appear in incognito mode + Limitation: Dislikes may not appear in incognito + mode + Dislikes as percentage Dislikes shown as percentage Dislikes shown as number @@ -561,27 +642,49 @@ Like button styled for minimum width Like button styled for best appearance Show a toast if API is not available - Toast is shown if Return YouTube Dislike is not available - Toast is not shown if Return YouTube Dislike is not available + Toast is shown if Return YouTube Dislike is + not available + + Toast is not shown if Return YouTube + Dislike is not available + About ReturnYouTubeDislike.com - Data is provided by the Return YouTube Dislike API. Tap here to learn more - ReturnYouTubeDislike API statistics of this device - API response time, average + Data is provided by the Return YouTube Dislike API. Tap here + to learn more + + ReturnYouTubeDislike API statistics of this device + + API response time, average + API response time, minimum API response time, maximum - API response time, last video - Dislikes temporarily not available - Client API rate limit in effect + API response time, last video + + Dislikes temporarily + not available - Client API rate limit in effect + API fetch votes, number of calls No network calls made %d network calls made - API fetch votes, number of timeouts + API fetch votes, number of + timeouts + No - network calls timed out - %d network calls timed out - API client rate limits - No client rate limits encountered - Client rate limit encountered %d times + network calls timed out + + %d network calls timed + out + + API client rate + limits + + No client rate + limits encountered + + Client rate + limit encountered %d times + %d milliseconds @@ -591,8 +694,12 @@ Restore old seekbar thumbnails - Seekbar thumbnails will appear above the seekbar - Seekbar thumbnails will appear in fullscreen + Seekbar thumbnails will appear above the + seekbar + + Seekbar thumbnails will appear in + fullscreen + Seekbar @@ -602,81 +709,136 @@ SponsorBlock SponsorBlock related settings Enable SponsorBlock - SponsorBlock is a crowd-sourced system for skipping annoying parts of YouTube videos + SponsorBlock is a crowd-sourced system for skipping annoying parts + of YouTube videos + Appearance Show voting button Segment voting button is shown Segment voting button is not shown Use compact skip button Skip button styled for minimum width - Skip button styled for best appearance + Skip button styled for best appearance + Automatically hide skip button - Skip button hides after a few seconds - Skip button displayed for entire segment + Skip button hides after a few + seconds + + Skip button displayed for entire + segment + Show a toast when skipping automatically - Toast is shown when a segment is automatically skipped. Tap here to see an example + Toast is shown when a segment is automatically skipped. + Tap here to see an example + Toast is not shown. Tap here to see an example Show video length without segments - Video length minus all segments, shown in parentheses next to the full video length + Video length minus all segments, shown in parentheses + next to the full video length + Full video length shown Creating new segments Show create new segment button Create new segment button is shown Create new segment button is not shown Adjust new segment step - Number of milliseconds the time adjustment buttons move when creating new segments + Number of milliseconds the time adjustment buttons move + when creating new segments + Value must be a positive number View guidelines - Guidelines contain rules and tips for creating new segments + Guidelines contain rules and tips for creating new + segments + Follow the guidelines - Read the SponsorBlock guidelines before creating new segments + Read the SponsorBlock guidelines before creating new + segments + Already read Show me General Show a toast if API is not available - Toast is shown if SponsorBlock is not available - Toast is not shown if SponsorBlock is not available + Toast is shown if SponsorBlock is not + available + + Toast is not shown if SponsorBlock is not + available + Enable skip count tracking - Lets the SponsorBlock leaderboard know how much time is saved. A message is sent to the leaderboard each time a segment is skipped + Lets the SponsorBlock leaderboard know how much time is + saved. A message is sent to the leaderboard each time a segment is skipped + Skip count tracking is not enabled Minimum segment duration - Segments shorter than this value (in seconds) will not be shown or skipped + Segments shorter than this value (in seconds) will not + be shown or skipped + Your private user id - This should be kept private. This is like a password and should not be shared with anyone. If someone has this, they can impersonate you + This should be kept private. This is like a password and should + not be shared with anyone. If someone has this, they can impersonate you + Private user id must be at least 30 characters long Change API URL - The address SponsorBlock uses to make calls to the server. Do not change this unless you know what you\'re doing + The address SponsorBlock uses to make calls to the server. Do + not change this unless you know what you\'re doing + API URL reset API URL is invalid API URL changed Import/Export settings Copy - Your SponsorBlock JSON configuration that can be imported/exported to ReVanced and other SponsorBlock platforms %s - This includes your private user id. Be sure to share this wisely + Your SponsorBlock JSON configuration that can be + imported/exported to ReVanced and other SponsorBlock platforms %s + + This includes your private user id. Be sure to share this + wisely + Settings imported successfully Failed to import: %s Failed to export: %s - Your settings contain a private SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n + Your settings contain a private + SponsorBlock userid.\n\nYour user id is like a password and it should never be shared.\n + Do not show again Change segment behavior Sponsor - Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shout-outs to causes/creators/websites/products they like + Paid promotion, paid referrals and direct advertisements. + Not for self-promotion or free shout-outs to causes/creators/websites/products they like + Unpaid/Self Promotion - Similar to \'Sponsor\' except for unpaid or self promotion. Includes sections about merchandise, donations, or information about who they collaborated with + Similar to \'Sponsor\' except for unpaid or self + promotion. Includes sections about merchandise, donations, or information about who they collaborated + with + Interaction Reminder (Subscribe) - A short reminder to like, subscribe or follow them in the middle of content. If it is long or about something specific, it should instead be under self promotion + A short reminder to like, subscribe or follow them in + the middle of content. If it is long or about something specific, it should instead be under self + promotion + Highlight - The part of the video that most people are looking for + The part of the video that most people are looking for + Intermission/Intro Animation - An interval without actual content. Could be a pause, static frame, or repeating animation. Does not include transitions containing information + An interval without actual content. Could be a pause, static + frame, or repeating animation. Does not include transitions containing information + Endcards/Credits - Credits or when the YouTube endcards appear. Not for conclusions with information + Credits or when the YouTube endcards appear. Not for + conclusions with information + Preview/Recap/Hook - Collection of clips that show what is coming up or what happened in the video or in other videos of a series, where all information is repeated elsewhere + Collection of clips that show what is coming up or what + happened in the video or in other videos of a series, where all information is repeated elsewhere + Filler Tangent/Jokes - Tangential scenes added only for filler or humor that are not required to understand the main content of the video. Does not include segments providing context or background details + Tangential scenes added only for filler or humor that are not + required to understand the main content of the video. Does not include segments providing context or + background details + Music: Non-Music Section - Only for use in music videos. Sections of music videos without music, that aren\'t already covered by another category + Only for use in music videos. Sections of music videos + without music, that aren\'t already covered by another category + Skip Highlight Skip sponsor @@ -715,37 +877,59 @@ Disable Unable to submit segment: %s SponsorBlock is temporarily down - Unable to submit segment (status: %d %s) - Unable to submit segment.\nRate Limited (too many from the same user or IP) + Unable to submit segment (status: + %d %s) + + Unable to submit segment.\nRate Limited (too many from + the same user or IP) + Can\'t submit the segment: %s Can\'t submit the segment.\nAlready exists Segment submitted successfully - SponsorBlock temporarily not available - SponsorBlock temporarily not available (status %d) - SponsorBlock temporarily not available (API timed out) + SponsorBlock temporarily not available + + SponsorBlock temporarily + not available (status %d) + + SponsorBlock temporarily not available + (API timed out) + Unable to vote for segment (API timed out) - Unable to vote for segment (status: %d %s) + Unable to vote for segment (status: + %d %s) + Unable to vote for segment: %s Upvote Downvote Change category There are no segments to vote for Choose the segment category - Category is disabled in settings. Enable category to submit. + Category is disabled in settings. Enable category + to submit. + New SponsorBlock segment - Set %02d:%02d:%03d as the start or end of a new segment? + Set %02d:%02d:%03d as the + start or end of a new segment? + start end now Time the segment begins at Time the segment ends at Are the times correct? - The segment lasts from %02d:%02d to %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? + The segment lasts from %02d:%02d to + %02d:%02d (%d minutes %02d seconds)\nIs it ready to submit? + Start must be before the end - Mark two locations on the time bar first - Preview the segment, and ensure it skips smoothly + Mark two locations on the time bar first + + Preview the segment, and ensure it skips + smoothly + Edit timing of segment manually - Do you want to edit the timing for the start or end of the segment? + Do you want to edit the timing for the start or + end of the segment? + Invalid time given Stats Stats temporarily not available (API is down) @@ -753,15 +937,24 @@ SponsorBlock is disabled Your username: <b>%s</b> Tap here to change your username - Unable to change username: Status: %d %s + Unable to change username: + Status: %d %s + Username successfully changed Your reputation is <b>%.2f</b> - You\'ve created <b>%s</b> segments + You\'ve created <b>%s</b> segments + SponsorBlock leaderboard - You\'ve saved people from <b>%s</b> segments - Tap here to see the global stats and top contributors - That\'s <b>%s</b> of their lives.<br>Tap here to see the leaderboard - You\'ve skipped <b>%s</b> segments + You\'ve saved people from <b>%s</b> + segments + + Tap here to see the global stats and top contributors + + That\'s <b>%s</b> of their lives.<br>Tap + here to see the leaderboard + + You\'ve skipped <b>%s</b> segments + That\'s <b>%s</b> Reset skipped segments counter? %s hours %s minutes @@ -775,20 +968,30 @@ Reset About sponsor.ajay.app - Data is provided by the SponsorBlock API. Tap here to learn more and see downloads for other platforms + Data is provided by the SponsorBlock API. Tap here to learn more + and see downloads for other platforms + Spoof app version Version spoofed Version not spoofed - App version will be spoofed to an older version of YouTube.\n\nThis will change the appearance and features of the app, but unknown side effects may occur.\n\nIf later turned off, it is recommended to clear the app data to prevent UI bugs. + App version will be spoofed to an older + version of YouTube.\n\nThis will change the appearance and features of the app, but unknown side effects + may occur.\n\nIf later turned off, it is recommended to clear the app data to prevent UI bugs. + Spoof app version target - 18.33.40 - Restore RYD Shorts incognito mode - 18.20.39 - Restore wide video speed & quality menu + 18.33.40 - Restore RYD Shorts incognito mode + + 18.20.39 - Restore wide video speed & quality + menu + 18.09.39 - Restore library tab 17.08.35 - Restore old UI layout 16.08.35 - Restore explore tab - 16.01.35 - Restore fewer video player action buttons + 16.01.35 - Restore fewer video player action + buttons + Set start page @@ -805,15 +1008,20 @@ Disable resuming Shorts player - Shorts player will not resume on app startup - Shorts player will resume on app startup + Shorts player will not resume on app + startup + + Shorts player will resume on app + startup + Enable tablet layout Settings related to the layout Tablet layout is enabled Tablet layout is disabled - Community posts do not show up on tablet layouts + Community posts do not show up on tablet layouts + Enable tablet mini player @@ -822,8 +1030,10 @@ Enable gradient loading screen - Loading screen will have a gradient background - Loading screen will have a solid background + Loading screen will have a gradient background + + Loading screen will have a solid background + Enable custom seekbar color @@ -831,7 +1041,8 @@ Original seekbar color is shown Custom seekbar color The color of the seekbar - Invalid seekbar color value. Using default value. + Invalid seekbar color value. Using default value. + Alternative thumbnails @@ -839,13 +1050,24 @@ Enable DeArrow thumbnails Using DeArrow thumbnails Not using DeArrow thumbnails - Show a toast if API is not available - Toast is shown if DeArrow is not available - Toast is not shown if DeArrow is not available + Show a toast if API is not available + + Toast is shown if DeArrow is not + available + + Toast is not shown if DeArrow is + not available + DeArrow API endpoint - The URL of the DeArrow thumbnail cache endpoint. Do not change this unless you know what you\'re doing + The URL of the DeArrow thumbnail cache + endpoint. Do not change this unless you know what you\'re doing + About DeArrow - DeArrow provides crowd-sourced thumbnails for YouTube videos. These thumbnails are often more relevant than those provided by YouTube. If enabled, video URLs will be sent to the API server and no other data is sent\n\nTap here to learn more about DeArrow + DeArrow provides crowd-sourced thumbnails for + YouTube videos. These thumbnails are often more relevant than those provided by YouTube. If enabled, + video URLs will be sent to the API server and no other data is sent\n\nTap here to learn more about + DeArrow + Enable still video captures Using YouTube still video captures Not using YouTube still video captures @@ -854,10 +1076,14 @@ Middle of video End of video Use fast still captures - Using medium quality still captures. Thumbnails will load faster, but live streams, unreleased, or very old videos may show blank thumbnails + Using medium quality still captures. Thumbnails + will load faster, but live streams, unreleased, or very old videos may show blank thumbnails + Using high quality still captures About still video captures - Still captures are taken from the beginning/middle/end of each video. These images are built into YouTube and no external API is used + Still captures are taken from the + beginning/middle/end of each video. These images are built into YouTube and no external API is used + Video thumbnail settings @@ -875,23 +1101,44 @@ Spoof device dimensions Device dimensions spoofed - Device dimensions not spoofed\n\nSpoofing the device dimensions can unlock higher video qualities but unknown side effects may occur + Device dimensions not spoofed\n\nSpoofing the + device dimensions can unlock higher video qualities but unknown side effects may occur + Spoof app signature Spoof app signature - App signature spoofed\n\nSide effects include:\n• Enhanced bitrate is not available\n• Videos cannot be downloaded\n• No seekbar thumbnails for paid videos - App signature not spoofed\n\nVideo playback may not work - Turning off this setting will cause video playback issues. + App signature spoofed\n\nSide + effects include:\n• Enhanced bitrate is not available\n• Videos cannot be downloaded\n• No seekbar + thumbnails for paid videos + + App signature not spoofed\n\nVideo + playback may not work + + Turning off this setting + will cause video playback issues. + Spoof app signature in feed - App signature spoofed\n\nSide effects include:\n• Feed videos are missing subtitles\n• Automatically played feed videos will show up in your watch history - App signature not spoofed for feed videos\n\nFeed videos will play for less than 1 minute before encountering playback issues + App signature spoofed\n\nSide effects + include:\n• Feed videos are missing subtitles\n• Automatically played feed videos will show up in your + watch history + + App signature not spoofed for feed + videos\n\nFeed videos will play for less than 1 minute before encountering playback issues + Spoof storyboard Storyboard spoofed - Storyboard not spoofed\n\nSide effects include:\n• No ambient mode\n• Seekbar thumbnails are hidden - Spoof the app signature to prevent playback issues - Spoof storyboard temporarily not available (API timed out) - Spoof storyboard temporarily not available: %s + Storyboard not spoofed\n\nSide effects include:\n• No + ambient mode\n• Seekbar thumbnails are hidden + + Spoof the app signature to prevent playback + issues + + Spoof storyboard temporarily not available (API timed + out) + + Spoof storyboard temporarily not available: %s + GmsCore Settings @@ -909,12 +1156,18 @@ Minimized playback - This setting can be found in Settings -> Background + This setting can be found in Settings -> + Background + Remove tracking query parameter - Tracking query parameter is removed from links - Tracking query parameter is not removed from links + Tracking query parameter is removed from + links + + Tracking query parameter is not removed + from links + Disable zoom haptics @@ -937,31 +1190,46 @@ 240p 144p Remember video quality changes - Quality changes apply to all videos - Quality changes only apply to the current video + Quality changes apply to all + videos + + Quality changes only apply to the + current video + Default video quality on Wi-Fi network Default video quality on mobile network mobile wifi - Changed default %s quality to: %s + Changed default %s quality to: %s + Custom playback speeds Add or change the available playback speeds - Custom speeds must be less than %s Using default values. - Invalid custom playback speeds. Using default values. + Custom speeds must be less than %s + Using default values. + + Invalid custom playback speeds. Using default + values. + Remember playback speed changes - Playback speed changes apply to all videos - Playback speed changes only apply to the current video + Playback speed changes apply to all + videos + + Playback speed changes only apply + to the current video + Default playback speed - Changed default speed to: %s + Changed default speed to: %s + Restore old video quality menu Old video quality menu is shown - Old video quality menu is not shown + Old video quality menu is not shown + Enable slide to seek @@ -969,6 +1237,16 @@ Slide to seek is not enabled + + + ReVanced + ReVanced specific settings + + + Misc + Miscellaneous patches + + Block audio ads @@ -976,8 +1254,12 @@ Audio ads are unblocked - %s is unavailable. Ads may show. Try switching to another ad block service in settings. - %s server returned an error. Ads may show. Try switching to another ad block service in settings. + %s is unavailable. Ads may show. Try switching to + another ad block service in settings. + + %s server returned an error. Ads may show. Try switching + to another ad block service in settings. + Block embedded video ads Disabled Luminous proxy @@ -997,8 +1279,10 @@ Automatically claim Channel Points - Channel Points are claimed automatically - Channel Points are not claimed automatically + Channel Points are claimed automatically + + Channel Points are not claimed automatically + Enable Twitch debug mode @@ -1006,7 +1290,7 @@ Twitch debug mode is disabled - ReVanced Settings + ReVanced Settings Debug logging Debug logs are enabled Debug logs are disabled diff --git a/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml b/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml index 150088114..f3d5fc143 100644 --- a/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml +++ b/src/main/resources/settings/layout/revanced_settings_with_toolbar.xml @@ -21,7 +21,7 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/ytBrandBackgroundSolid" app:navigationIcon="@drawable/yt_outline_arrow_left_black_24" - app:title="@string/revanced_settings" /> + app:title="@string/revanced_settings_title" />