Skip to content

Commit

Permalink
feat(YouTube): Reorganize settings menu (ReVanced#2737)
Browse files Browse the repository at this point in the history
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: dic1911 <htk030@protonmail.com>
  • Loading branch information
4 people authored Mar 2, 2024
1 parent 0342c79 commit 36132df
Show file tree
Hide file tree
Showing 80 changed files with 605 additions and 504 deletions.
30 changes: 21 additions & 9 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -723,10 +723,8 @@ public abstract class app/revanced/patches/shared/misc/settings/preference/BaseP
}

public class app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen : app/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$BasePreferenceCollection {
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;)V
public synthetic fun <init> (Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun addPreferences ([Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;)V
public final fun getCategories ()Ljava/util/Set;
public synthetic fun transform ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreference;
Expand Down Expand Up @@ -798,12 +796,22 @@ public class app/revanced/patches/shared/misc/settings/preference/PreferenceCate
}

public class app/revanced/patches/shared/misc/settings/preference/PreferenceScreen : app/revanced/patches/shared/misc/settings/preference/BasePreference {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getPreferences ()Ljava/util/Set;
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
}

public final class app/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting : java/lang/Enum {
public static final field BY_KEY Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static final field BY_TITLE Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static final field UNSORTED Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public final fun getKeySuffix ()Ljava/lang/String;
public static fun valueOf (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
public static fun values ()[Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen$Sorting;
}

public final class app/revanced/patches/shared/misc/settings/preference/SummaryType : java/lang/Enum {
public static final field DEFAULT Lapp/revanced/patches/shared/misc/settings/preference/SummaryType;
public static final field OFF Lapp/revanced/patches/shared/misc/settings/preference/SummaryType;
Expand Down Expand Up @@ -1468,7 +1476,6 @@ public final class app/revanced/patches/youtube/layout/tabletminiplayer/TabletMi
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public final fun unwrap (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lkotlin/Triple;
}

public final class app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch : app/revanced/patcher/patch/BytecodePatch {
Expand Down Expand Up @@ -1617,9 +1624,14 @@ public final class app/revanced/patches/youtube/misc/settings/SettingsPatch$Pref
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/settings/SettingsPatch$PreferenceScreen;
public fun commit (Lapp/revanced/patches/shared/misc/settings/preference/PreferenceScreen;)V
public final fun getADS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getINTERACTIONS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getLAYOUT ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getALTERNATIVE_THUMBNAILS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getFEED ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getGENERAL_LAYOUT ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getMISC ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getPLAYER ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSEEKBAR ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSHORTS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getSWIPE_CONTROLS ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
public final fun getVIDEO ()Lapp/revanced/patches/shared/misc/settings/preference/BasePreferenceScreen$Screen;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.ad.comments.fingerprints.HideCommentAdsFingerprint

@Patch(description = "Removes ads in the comments.",)
@Patch(description = "Removes ads in the comments.")
object HideCommentAdsPatch : BytecodePatch(
setOf(HideCommentAdsFingerprint)
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.fingerprints.PiracyDetectionFingerprint

@Patch(description = "Disables detection of modified versions.",)
@Patch(description = "Disables detection of modified versions.")
object DisablePiracyDetectionPatch : BytecodePatch(setOf(PiracyDetectionFingerprint)) {
override fun execute(context: BytecodeContext) {
// Do not throw an error if the fingerprint is not resolved.
// This is fine because new versions of the target app do not need this patch.
PiracyDetectionFingerprint.result?.mutableMethod?.apply {
addInstruction(
0,
"""
return-void
"""
)
addInstruction(0, "return-void")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,26 @@ abstract class BaseSettingsResourcePatch(
}

override fun close() {
fun Node.addPreference(preference: BasePreference) {
fun Node.addPreference(preference: BasePreference, prepend: Boolean = false) {
preference.serialize(ownerDocument) { resource ->
// TODO: Currently, resources can only be added to "values", which may not be the correct place.
// It may be necessary to ask for the desired resourceValue in the future.
AddResourcesPatch("values", resource)
}.let(this::appendChild)
}.let { preferenceNode ->
if (prepend && firstChild != null) {
insertBefore(preferenceNode, firstChild)
} else {
appendChild(preferenceNode)
}
}
}

// Add the root preference to an existing fragment if needed.
rootPreference?.let { (intentPreference, fragment) ->
context.xmlEditor["res/xml/$fragment.xml"].use { editor ->
val document = editor.file

document.getNode("PreferenceScreen").addPreference(intentPreference)
document.getNode("PreferenceScreen").addPreference(intentPreference, true)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package app.revanced.patches.shared.misc.settings.preference

import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import java.io.Closeable

abstract class BasePreferenceScreen(
private val root: MutableSet<Screen> = mutableSetOf()
private val root: MutableSet<Screen> = mutableSetOf(),
) : Closeable {

override fun close() {
Expand All @@ -24,33 +25,27 @@ abstract class BasePreferenceScreen(
titleKey: String = "${key}_title",
private val summaryKey: String? = "${key}_summary",
preferences: MutableSet<BasePreference> = mutableSetOf(),
val categories: MutableSet<Category> = mutableSetOf()
val categories: MutableSet<Category> = mutableSetOf(),
private val sorting: Sorting = Sorting.BY_TITLE,
) : BasePreferenceCollection(key, titleKey, preferences) {

/**
* Initialize using title and summary keys with suffix "_title" and "_summary".
*/
constructor(
key: String? = null,
preferences: MutableSet<BasePreference> = mutableSetOf(),
categories: MutableSet<Category> = mutableSetOf()
) : this(key, key + "_title", key + "_summary", preferences, categories)

override fun transform(): PreferenceScreen {
return PreferenceScreen(
key,
titleKey,
summaryKey,
sorting,
// Screens and preferences are sorted at runtime by integrations code,
// so they appear in alphabetical order for the localized language in use.
preferences = preferences + categories.map { it.transform() }
// so title sorting uses the localized language in use.
preferences = preferences + categories.map { it.transform() },
)
}

private fun ensureScreenInserted() {
// Add to screens if not yet done
if (!root.contains(this))
if (!root.contains(this)) {
root.add(this)
}
}

fun addPreferences(vararg preferences: BasePreference) {
Expand All @@ -61,22 +56,23 @@ abstract class BasePreferenceScreen(
open inner class Category(
key: String? = null,
titleKey: String = "${key}_title",
preferences: MutableSet<BasePreference> = mutableSetOf()
preferences: MutableSet<BasePreference> = mutableSetOf(),
) : BasePreferenceCollection(key, titleKey, preferences) {
override fun transform(): PreferenceCategory {
return PreferenceCategory(
key,
titleKey,
preferences = preferences
preferences = preferences,
)
}

fun addPreferences(vararg preferences: BasePreference) {
ensureScreenInserted()

// Add to the categories if not done yet.
if (!categories.contains(this))
if (!categories.contains(this)) {
categories.add(this)
}

this.preferences.addAll(preferences)
}
Expand All @@ -86,8 +82,8 @@ abstract class BasePreferenceScreen(
abstract class BasePreferenceCollection(
val key: String? = null,
val titleKey: String = "${key}_title",
val preferences: MutableSet<BasePreference> = mutableSetOf()
val preferences: MutableSet<BasePreference> = mutableSetOf(),
) {
abstract fun transform(): BasePreference
}
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
package app.revanced.patches.shared.misc.settings.preference

import app.revanced.patches.shared.misc.settings.preference.IntentPreference.Intent
import app.revanced.util.resource.BaseResource
import org.w3c.dom.Document

/**
* A preference that opens an intent.
*
* @param key The preference key. If null, other parameters must be specified.
* @param key Optional preference key.
* @param titleKey The preference title key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param intent The intent to open.
*
* @see Intent
*/
class IntentPreference(
key: String? = null,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
val intent: Intent,
) : BasePreference(null, titleKey, summaryKey, tag) {
) : BasePreference(key, titleKey, summaryKey, tag) {

override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import org.w3c.dom.Document
/**
* A non-interactive preference.
*
* Typically used to present static text, but also used for custom integration code that responds to taps.
*
* @param key The preference key.
* @param summaryKey The preference summary key.
* @param tag The preference tag.
* @param selectable Whether the preference is selectable.
* @param tag The tag or full class name of the preference.
* @param selectable If the preference is selectable and responds to tap events.
*/
@Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import org.w3c.dom.Document
* @param key The key of the preference. If null, other parameters must be specified.
* @param titleKey The key of the preference title.
* @param summaryKey The key of the preference summary.
* @param sorting Sorting to use. If the sorting is not [Sorting.UNSORTED],
* then the key parameter will be modified to include the sort type.
* @param tag The tag or full class name of the preference.
* @param preferences The preferences in this screen.
*/
Expand All @@ -17,14 +19,40 @@ open class PreferenceScreen(
key: String? = null,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
sorting: Sorting = Sorting.BY_TITLE,
tag: String = "PreferenceScreen",
val preferences: Set<BasePreference>
) : BasePreference(key, titleKey, summaryKey, tag) {

val preferences: Set<BasePreference>,
// Alternatively, instead of repurposing the key for sorting,
// an extra bundle parameter can be added to the preferences XML declaration.
// This would require bundling and referencing an additional XML file
// or adding new attributes to the attrs.xml file.
// Since the key value is not currently used by integrations,
// for now it's much simpler to modify the key to include the sort parameter.
) : BasePreference(if (sorting == Sorting.UNSORTED) key else (key + sorting.keySuffix), titleKey, summaryKey, tag) {
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
preferences.forEach {
appendChild(it.serialize(ownerDocument, resourceCallback))
}
}

/**
* How a PreferenceScreen should be sorted.
*/
enum class Sorting(val keySuffix: String) {
/**
* Sort by the localized preference title.
*/
BY_TITLE("_sort_by_title"),

/**
* Sort by the preference keys.
*/
BY_KEY("_sort_by_key"),

/**
* Unspecified sorting.
*/
UNSORTED("_sort_by_unsorted"),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ object AudioAdsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(SwitchPreference("revanced_block_audio_ads"))
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
SwitchPreference("revanced_block_audio_ads")
)

// Block playAds call
with(AudioAdsPresenterPlayFingerprint.result!!) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ object VideoAdsPatch : BaseAdPatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(SwitchPreference("revanced_block_video_ads"))
SettingsPatch.PreferenceScreen.ADS.CLIENT_SIDE.addPreferences(
SwitchPreference("revanced_block_video_ads")
)

/* Amazon ads SDK */
context.blockMethods(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ object DebugModePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(SwitchPreference("revanced_twitch_debug_mode"))
SettingsPatch.PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_twitch_debug_mode")
)

listOf(
IsDebugConfigEnabledFingerprint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableField
import java.io.Closeable


@Patch(
name = "Settings",
description = "Adds settings menu to Twitch.",
Expand Down Expand Up @@ -62,7 +61,9 @@ object SettingsPatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

PreferenceScreen.MISC.OTHER.addPreferences(SwitchPreference("revanced_debug"))
PreferenceScreen.MISC.OTHER.addPreferences(
SwitchPreference("revanced_debug")
)

// Hook onCreate to handle fragment creation
SettingsActivityOnCreateFingerprint.result?.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch.PreferenceScreen

@Patch(
dependencies = [
Expand All @@ -27,7 +26,7 @@ object HideAdsResourcePatch : ResourcePatch() {
override fun execute(context: ResourceContext) {
AddResourcesPatch(this::class)

PreferenceScreen.ADS.addPreferences(
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference("revanced_hide_general_ads"),
SwitchPreference("revanced_hide_fullscreen_ads"),
SwitchPreference("revanced_hide_buttoned_ads"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ object HideGetPremiumPatch : BytecodePatch(setOf(GetPremiumViewFingerprint)) {
override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

SettingsPatch.PreferenceScreen.ADS.addPreferences(SwitchPreference("revanced_hide_get_premium"))
SettingsPatch.PreferenceScreen.ADS.addPreferences(
SwitchPreference("revanced_hide_get_premium")
)

GetPremiumViewFingerprint.result?.let {
it.mutableMethod.apply {
Expand Down
Loading

0 comments on commit 36132df

Please sign in to comment.