mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-06-12 05:07:45 +02:00
feat(YouTube - Miniplayer): Add horizontal drag gesture (#3859)
This commit is contained in:

committed by
oSumAtrIX

parent
e377b1e6ad
commit
e32b19e170
@ -1133,17 +1133,6 @@ public final class app/revanced/patches/youtube/layout/hide/time/HideTimestampPa
|
||||
public static final fun getHideTimestampPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/miniplayer/FingerprintsKt {
|
||||
public static final field ANIMATION_INTERPOLATION_FEATURE_KEY J
|
||||
public static final field DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL J
|
||||
public static final field DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL J
|
||||
public static final field DROP_SHADOW_FEATURE_KEY J
|
||||
public static final field INITIAL_SIZE_FEATURE_KEY_LITERAL J
|
||||
public static final field MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL J
|
||||
public static final field MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY J
|
||||
public static final field ROUNDED_CORNERS_FEATURE_KEY J
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatchKt {
|
||||
public static final fun getFloatyBarButtonTopMargin ()J
|
||||
public static final fun getMiniplayerMaxSize ()J
|
||||
@ -1188,10 +1177,6 @@ public final class app/revanced/patches/youtube/layout/searchbar/WideSearchbarPa
|
||||
public static final fun getWideSearchbarPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/seekbar/FingerprintsKt {
|
||||
public static final field PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG J
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatchKt {
|
||||
public static final fun getSeekbarColorPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
@ -1274,10 +1259,6 @@ public final class app/revanced/patches/youtube/misc/extension/SharedExtensionPa
|
||||
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/cairo/FingerprintsKt {
|
||||
public static final field CAIRO_CONFIG_LITERAL_VALUE J
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatchKt {
|
||||
public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("SpellCheckingInspection")
|
||||
|
||||
package app.revanced.patches.youtube.layout.miniplayer
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
@ -33,16 +35,14 @@ internal val miniplayerModernCloseButtonFingerprint = fingerprint {
|
||||
literal { modernMiniplayerClose }
|
||||
}
|
||||
|
||||
const val MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL = 45622882L
|
||||
|
||||
internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L
|
||||
// In later targets this feature flag does nothing and is dead code.
|
||||
const val MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY = 45630429L
|
||||
const val DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL = 45628823L
|
||||
const val DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL = 45628752L
|
||||
const val INITIAL_SIZE_FEATURE_KEY_LITERAL = 45640023L
|
||||
const val ANIMATION_INTERPOLATION_FEATURE_KEY = 45647018L
|
||||
const val DROP_SHADOW_FEATURE_KEY = 45652223L
|
||||
const val ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
||||
internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L
|
||||
internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L
|
||||
internal const val MINIPLAYER_DRAG_DROP_FEATURE_KEY = 45628752L
|
||||
internal const val MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY = 45658112L
|
||||
internal const val MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
||||
internal const val MINIPLAYER_INITIAL_SIZE_FEATURE_KEY = 45640023L
|
||||
|
||||
internal val miniplayerModernConstructorFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("SpellCheckingInspection")
|
||||
|
||||
package app.revanced.patches.youtube.layout.miniplayer
|
||||
|
||||
import app.revanced.patcher.Match
|
||||
@ -204,6 +206,10 @@ val miniplayerPatch = bytecodePatch(
|
||||
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
||||
}
|
||||
|
||||
if (is_19_43_or_greater) {
|
||||
preferences += SwitchPreference("revanced_miniplayer_horizontal_drag")
|
||||
}
|
||||
|
||||
if (is_19_36_or_greater) {
|
||||
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
||||
}
|
||||
@ -291,7 +297,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
addInstructions(
|
||||
targetIndex + 1,
|
||||
"""
|
||||
invoke-static {v$register}, $EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(F)F
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(F)F
|
||||
move-result v$register
|
||||
""",
|
||||
)
|
||||
@ -302,13 +308,13 @@ val miniplayerPatch = bytecodePatch(
|
||||
* Adds an override to specify which modern miniplayer is used.
|
||||
*/
|
||||
fun MutableMethod.insertModernMiniplayerTypeOverride(iPutIndex: Int) {
|
||||
val targetInstruction = getInstruction<TwoRegisterInstruction>(iPutIndex)
|
||||
val register = getInstruction<TwoRegisterInstruction>(iPutIndex).registerA
|
||||
|
||||
addInstructionsAtControlFlowLabel(
|
||||
iPutIndex,
|
||||
"""
|
||||
invoke-static { v${targetInstruction.registerA} }, $EXTENSION_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I
|
||||
move-result v${targetInstruction.registerA}
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I
|
||||
move-result v$register
|
||||
""",
|
||||
)
|
||||
}
|
||||
@ -378,24 +384,31 @@ val miniplayerPatch = bytecodePatch(
|
||||
|
||||
if (is_19_23_or_greater) {
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL,
|
||||
MINIPLAYER_DRAG_DROP_FEATURE_KEY,
|
||||
"enableMiniplayerDragAndDrop",
|
||||
)
|
||||
}
|
||||
|
||||
if (is_19_43_or_greater) {
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
MINIPLAYER_HORIZONTAL_DRAG_FEATURE_KEY,
|
||||
"setHorizontalDrag",
|
||||
)
|
||||
}
|
||||
|
||||
if (is_19_25_or_greater) {
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY,
|
||||
MINIPLAYER_MODERN_FEATURE_LEGACY_KEY,
|
||||
"getModernMiniplayerOverride",
|
||||
)
|
||||
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL,
|
||||
MINIPLAYER_MODERN_FEATURE_KEY,
|
||||
"getModernFeatureFlagsActiveOverride",
|
||||
)
|
||||
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL,
|
||||
MINIPLAYER_DOUBLE_TAP_FEATURE_KEY,
|
||||
"enableMiniplayerDoubleTapAction",
|
||||
)
|
||||
}
|
||||
@ -403,7 +416,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
if (is_19_26_or_greater) {
|
||||
miniplayerModernConstructorMatch.mutableMethod.apply {
|
||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
|
||||
INITIAL_SIZE_FEATURE_KEY_LITERAL,
|
||||
MINIPLAYER_INITIAL_SIZE_FEATURE_KEY,
|
||||
)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT)
|
||||
|
||||
@ -418,7 +431,7 @@ val miniplayerPatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
// Override a mininimum miniplayer size constant.
|
||||
// Override a minimum size constant.
|
||||
miniplayerMinimumSizeMatch.mutableMethod.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_16 && (this as NarrowLiteralInstruction).narrowLiteral == 192
|
||||
@ -432,22 +445,9 @@ val miniplayerPatch = bytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
if (is_19_32_or_greater) {
|
||||
// Feature is not exposed in the settings, and currently only for debugging.
|
||||
miniplayerModernConstructorMatch.insertLiteralValueFloatOverride(
|
||||
ANIMATION_INTERPOLATION_FEATURE_KEY,
|
||||
"setMovementBoundFactor",
|
||||
)
|
||||
}
|
||||
|
||||
if (is_19_36_or_greater) {
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
DROP_SHADOW_FEATURE_KEY,
|
||||
"setDropShadow",
|
||||
)
|
||||
|
||||
miniplayerModernConstructorMatch.insertLiteralValueBooleanOverride(
|
||||
ROUNDED_CORNERS_FEATURE_KEY,
|
||||
MINIPLAYER_ROUNDED_CORNERS_FEATURE_KEY,
|
||||
"setRoundedCorners",
|
||||
)
|
||||
}
|
||||
@ -551,9 +551,9 @@ val miniplayerPatch = bytecodePatch(
|
||||
invoke-super { p0, p1, p2, p3 }, Landroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup${'$'}LayoutParams;)V
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->playerOverlayGroupCreated(Landroid/view/View;)V
|
||||
return-void
|
||||
""",
|
||||
"""
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
@ -34,7 +34,7 @@ internal val shortsSeekbarColorFingerprint = fingerprint {
|
||||
literal { reelTimeBarPlayedColorId }
|
||||
}
|
||||
|
||||
const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
||||
internal const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
||||
|
||||
internal val playerSeekbarGradientConfigFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
|
@ -57,22 +57,62 @@ val enableDebuggingPatch = bytecodePatch(
|
||||
),
|
||||
)
|
||||
|
||||
// Hook the method that looks up if a feature flag is active or not.
|
||||
experimentalFeatureFlagFingerprint.applyMatch(
|
||||
// Hook the methods that look up if a feature flag is active.
|
||||
|
||||
experimentalBooleanFeatureFlagFingerprint.applyMatch(
|
||||
context,
|
||||
experimentalFeatureFlagParentMatch
|
||||
).mutableMethod.apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
|
||||
|
||||
// It appears that all usage of this method has a default of 'false',
|
||||
// so there's no need to pass in the default.
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result v0
|
||||
invoke-static { p1, p2, v0 }, $EXTENSION_CLASS_DESCRIPTOR->isFeatureFlagEnabled(JZ)Z
|
||||
invoke-static { v0, p1, p2 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZJ)Z
|
||||
move-result v0
|
||||
return v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
experimentalDoubleFeatureFlagFingerprint.applyMatch(
|
||||
context,
|
||||
experimentalFeatureFlagParentMatch
|
||||
).mutableMethod.apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
|
||||
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
|
||||
move-result-wide v0
|
||||
return-wide v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
experimentalLongFeatureFlagFingerprint.applyMatch(
|
||||
context,
|
||||
experimentalFeatureFlagParentMatch
|
||||
).mutableMethod.apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result-wide v0
|
||||
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
|
||||
move-result-wide v0
|
||||
return-wide v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// There exists other experimental accessor methods for String, byte[], and wrappers for obfuscated classes,
|
||||
// but currently none of those are hooked.
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,21 @@ internal val experimentalFeatureFlagParentFingerprint = fingerprint {
|
||||
strings("Unable to parse proto typed experiment flag: ")
|
||||
}
|
||||
|
||||
internal val experimentalFeatureFlagFingerprint = fingerprint {
|
||||
internal val experimentalBooleanFeatureFlagFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Z")
|
||||
parameters("J", "Z")
|
||||
}
|
||||
|
||||
internal val experimentalDoubleFeatureFlagFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("D")
|
||||
parameters("J", "D")
|
||||
}
|
||||
|
||||
internal val experimentalLongFeatureFlagFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("J")
|
||||
parameters("J", "J")
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
* When this value is true, Cairo Fragment is used.
|
||||
* In this case, some of the patches may be broken, so set this value to FALSE.
|
||||
*/
|
||||
const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
||||
internal const val CAIRO_CONFIG_LITERAL_VALUE = 45532100L
|
||||
|
||||
internal val cairoFragmentConfigFingerprint = fingerprint {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
|
@ -1035,6 +1035,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_miniplayer_drag_and_drop_title">Enable drag and drop</string>
|
||||
<string name="revanced_miniplayer_drag_and_drop_summary_on">Drag and drop is enabled\n\nMiniplayer can be dragged to any corner of the screen</string>
|
||||
<string name="revanced_miniplayer_drag_and_drop_summary_off">Drag and drop is disabled</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_title">Enable horizontal drag gesture</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_on">Horizontal drag gesture enabled\n\nMiniplayer can be dragged off screen to the left or right</string>
|
||||
<string name="revanced_miniplayer_horizontal_drag_summary_off">Horizontal drag gesture disabled</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_title">Hide close button</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_on">Close button is hidden</string>
|
||||
<string name="revanced_miniplayer_hide_expand_close_summary_off">Close button is shown</string>
|
||||
|
Reference in New Issue
Block a user