Skip to content

Commit 91f1aad

Browse files
feat(YouTube - Hide layout components): Add "Hide collapse button" and "Hide fullscreen button" settings (#511)
1 parent 54d8a22 commit 91f1aad

5 files changed

Lines changed: 139 additions & 9 deletions

File tree

extensions/youtube/src/main/java/app/morphe/extension/youtube/patches/HidePlayerOverlayButtonsPatch.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,41 @@ public static void hideCaptionsButton(ImageView imageView) {
4646
imageView.setVisibility(Settings.HIDE_CAPTIONS_BUTTON.get() ? ImageView.GONE : ImageView.VISIBLE);
4747
}
4848

49+
/**
50+
* Injection point.
51+
*/
52+
public static void hideCollapseButton(ImageView imageView) {
53+
if (!Settings.HIDE_COLLAPSE_BUTTON.get()) return;
54+
55+
// Make the collapse button invisible
56+
imageView.setImageResource(android.R.color.transparent);
57+
imageView.setImageAlpha(0);
58+
imageView.setEnabled(false);
59+
60+
// Adjust layout params if RelativeLayout
61+
var layoutParams = imageView.getLayoutParams();
62+
if (layoutParams instanceof android.widget.RelativeLayout.LayoutParams) {
63+
android.widget.RelativeLayout.LayoutParams lp = new android.widget.RelativeLayout.LayoutParams(0, 0);
64+
imageView.setLayoutParams(lp);
65+
} else {
66+
Logger.printDebug(() -> "Unknown collapse button layout params: " + layoutParams);
67+
}
68+
}
69+
70+
/**
71+
* Injection point.
72+
*/
73+
public static void setTitleAnchorStartMargin(View titleAnchorView) {
74+
if (!Settings.HIDE_COLLAPSE_BUTTON.get()) return;
75+
76+
var layoutParams = titleAnchorView.getLayoutParams();
77+
if (layoutParams instanceof android.widget.RelativeLayout.LayoutParams relativeParams) {
78+
relativeParams.setMarginStart(0);
79+
} else {
80+
Logger.printDebug(() -> "Unknown title anchor layout params: " + layoutParams);
81+
}
82+
}
83+
4984
private static final boolean HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS_ENABLED
5085
= Settings.HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS.get();
5186

@@ -64,13 +99,28 @@ public static void hidePreviousNextButtons(View parentView) {
6499
}
65100

66101
// Must use a deferred call to main thread to hide the button.
67-
// Otherwise the layout crashes if set to hidden now.
102+
// Otherwise, the layout crashes if set to hidden now.
68103
Utils.runOnMainThread(() -> {
69104
hideView(parentView, PLAYER_CONTROL_PREVIOUS_BUTTON_TOUCH_AREA_ID);
70105
hideView(parentView, PLAYER_CONTROL_NEXT_BUTTON_TOUCH_AREA_ID);
71106
});
72107
}
73108

109+
/**
110+
* Injection point.
111+
*/
112+
public static ImageView hideFullscreenButton(ImageView imageView) {
113+
if (!Settings.HIDE_FULLSCREEN_BUTTON.get()) {
114+
return imageView;
115+
}
116+
117+
if (imageView != null) {
118+
imageView.setVisibility(View.GONE);
119+
}
120+
121+
return null;
122+
}
123+
74124
/**
75125
* Injection point.
76126
*/

extensions/youtube/src/main/java/app/morphe/extension/youtube/settings/Settings.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,14 @@ public class Settings extends BaseSettings {
157157
public static final BooleanSetting HIDE_AUTOPLAY_PREVIEW = new BooleanSetting("morphe_hide_autoplay_preview", FALSE, true);
158158
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("morphe_hide_captions_button", FALSE);
159159
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("morphe_hide_cast_button", TRUE, true);
160+
public static final BooleanSetting HIDE_COLLAPSE_BUTTON = new BooleanSetting("morphe_hide_collapse_button", FALSE, true);
160161
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("morphe_hide_channel_bar", FALSE);
161162
public static final BooleanSetting HIDE_CHANNEL_WATERMARK = new BooleanSetting("morphe_hide_channel_watermark", TRUE);
162163
public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("morphe_hide_crowdfunding_box", FALSE, true);
163164
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("morphe_hide_emergency_box", TRUE);
164165
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("morphe_hide_endscreen_cards", FALSE);
165166
public static final BooleanSetting HIDE_END_SCREEN_SUGGESTED_VIDEO = new BooleanSetting("morphe_end_screen_suggested_video", FALSE, true);
167+
public static final BooleanSetting HIDE_FULLSCREEN_BUTTON = new BooleanSetting("morphe_hide_fullscreen_button", FALSE, true);
166168
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("morphe_hide_info_cards", FALSE);
167169
public static final BooleanSetting HIDE_INFO_PANELS = new BooleanSetting("morphe_hide_info_panels", TRUE);
168170
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("morphe_hide_join_membership_button", TRUE, parentNot(HIDE_CHANNEL_BAR));

patches/src/main/kotlin/app/morphe/patches/youtube/layout/buttons/overlay/Fingerprints.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package app.morphe.patches.youtube.layout.buttons.overlay
33
import app.morphe.patcher.Fingerprint
44
import app.morphe.patcher.literal
55
import app.morphe.patcher.methodCall
6+
import app.morphe.patcher.opcode
67
import app.morphe.patches.shared.misc.mapping.ResourceType
78
import app.morphe.patches.shared.misc.mapping.resourceLiteral
89
import com.android.tools.smali.dexlib2.AccessFlags
10+
import com.android.tools.smali.dexlib2.Opcode
911

1012
internal object MediaRouteButtonFingerprint : Fingerprint(
1113
parameters = listOf("I"),
@@ -37,3 +39,24 @@ internal object InflateControlsGroupLayoutStubFingerprint : Fingerprint(
3739
methodCall(name = "inflate")
3840
)
3941
)
42+
43+
internal object FullscreenButtonFingerprint : Fingerprint(
44+
accessFlags = listOf(AccessFlags.PUBLIC, AccessFlags.FINAL),
45+
parameters = listOf("Landroid/view/View;"),
46+
returnType = "V",
47+
filters = listOf(
48+
resourceLiteral(ResourceType.ID, "fullscreen_button"),
49+
opcode(Opcode.CHECK_CAST)
50+
)
51+
)
52+
53+
internal object TitleAnchorFingerprint : Fingerprint(
54+
returnType = "V",
55+
filters = listOf(
56+
resourceLiteral(ResourceType.ID, "player_collapse_button"),
57+
opcode(Opcode.CHECK_CAST),
58+
59+
resourceLiteral(ResourceType.ID, "title_anchor"),
60+
opcode(Opcode.MOVE_RESULT_OBJECT)
61+
)
62+
)

patches/src/main/kotlin/app/morphe/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
4545

4646
execute {
4747
PreferenceScreen.PLAYER.addPreferences(
48-
SwitchPreference("morphe_hide_player_previous_next_buttons"),
49-
SwitchPreference("morphe_hide_cast_button"),
50-
SwitchPreference("morphe_hide_captions_button"),
5148
SwitchPreference("morphe_hide_autoplay_button"),
49+
SwitchPreference("morphe_hide_captions_button"),
50+
SwitchPreference("morphe_hide_cast_button"),
51+
SwitchPreference("morphe_hide_collapse_button"),
52+
SwitchPreference("morphe_hide_fullscreen_button"),
5253
SwitchPreference("morphe_hide_player_control_buttons_background"),
54+
SwitchPreference("morphe_hide_player_previous_next_buttons"),
5355
)
5456

5557
// region Hide player next/previous button.
@@ -137,6 +139,53 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
137139

138140
// endregion
139141

142+
// region Hide collapse button.
143+
144+
TitleAnchorFingerprint.let {
145+
it.method.apply {
146+
val titleAnchorIndex = it.instructionMatches.last().index
147+
val titleAnchorRegister = getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
148+
149+
addInstruction(
150+
titleAnchorIndex + 1,
151+
"invoke-static { v$titleAnchorRegister }, $EXTENSION_CLASS_DESCRIPTOR->setTitleAnchorStartMargin(Landroid/view/View;)V"
152+
)
153+
154+
val playerCollapseButtonIndex = it.instructionMatches[1].index
155+
val playerCollapseButtonRegister = getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
156+
157+
addInstruction(
158+
playerCollapseButtonIndex + 1,
159+
"invoke-static { v$playerCollapseButtonRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideCollapseButton(Landroid/widget/ImageView;)V"
160+
)
161+
}
162+
}
163+
164+
// endregion
165+
166+
// region Hide fullscreen button.
167+
168+
FullscreenButtonFingerprint.let {
169+
it.method.apply {
170+
val castIndex = it.instructionMatches[1].index
171+
val insertIndex = castIndex + 1
172+
val insertRegister = getInstruction<OneRegisterInstruction>(castIndex).registerA
173+
174+
addInstructionsWithLabels(
175+
insertIndex,
176+
"""
177+
invoke-static { v$insertRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideFullscreenButton(Landroid/widget/ImageView;)Landroid/widget/ImageView;
178+
move-result-object v$insertRegister
179+
if-nez v$insertRegister, :show
180+
return-void
181+
""",
182+
ExternalLabel("show", getInstruction(insertIndex))
183+
)
184+
}
185+
}
186+
187+
// endregion
188+
140189
// region Hide player control buttons background.
141190

142191
InflateControlsGroupLayoutStubFingerprint.let {

patches/src/main/resources/addresources/values/youtube/strings.xml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -768,22 +768,28 @@ To show the Audio track menu, change \'Spoof video streams\' to \'TV\'"</string>
768768
<string name="morphe_hide_player_flyout_video_quality_footer_summary_on">Quality menu footer is hidden</string>
769769
<string name="morphe_hide_player_flyout_video_quality_footer_summary_off">Quality menu footer is shown</string>
770770

771-
<!-- layout.buttons.overlay.hidePlayerOverlayButtonsPatch -->
772-
<string name="morphe_hide_autoplay_button_title">Hide Autoplay button</string>
773-
<string name="morphe_hide_autoplay_button_summary_on">Autoplay button is hidden</string>
774-
<string name="morphe_hide_autoplay_button_summary_off">Autoplay button is shown</string>
775-
776771
<!-- layout.hide.autoplaypreview.hideAutoplayPreviewPatch -->
777772
<string name="morphe_hide_autoplay_preview_title">Hide autoplay preview</string>
778773
<string name="morphe_hide_autoplay_preview_summary_on">Autoplay preview is hidden</string>
779774
<string name="morphe_hide_autoplay_preview_summary_off">Autoplay preview is shown</string>
775+
776+
<!-- layout.buttons.overlay.hidePlayerOverlayButtonsPatch -->
777+
<string name="morphe_hide_autoplay_button_title">Hide Autoplay button</string>
778+
<string name="morphe_hide_autoplay_button_summary_on">Autoplay button is hidden</string>
779+
<string name="morphe_hide_autoplay_button_summary_off">Autoplay button is shown</string>
780780
<!-- This button does not display any text, but 'Captions' should match the language used in 'morphe_hide_player_flyout_captions_title'. -->
781781
<string name="morphe_hide_captions_button_title">Hide Captions button</string>
782782
<string name="morphe_hide_captions_button_summary_on">Captions button is hidden</string>
783783
<string name="morphe_hide_captions_button_summary_off">Captions button is shown</string>
784784
<string name="morphe_hide_cast_button_title">Hide Cast button</string>
785785
<string name="morphe_hide_cast_button_summary_on">Cast button is hidden</string>
786786
<string name="morphe_hide_cast_button_summary_off">Cast button is shown</string>
787+
<string name="morphe_hide_collapse_button_title">Hide Collapse button</string>
788+
<string name="morphe_hide_collapse_button_summary_on">Collapse button is hidden</string>
789+
<string name="morphe_hide_collapse_button_summary_off">Collapse button is shown</string>
790+
<string name="morphe_hide_fullscreen_button_title">Hide Fullscreen button</string>
791+
<string name="morphe_hide_fullscreen_button_summary_on">Fullscreen button is hidden</string>
792+
<string name="morphe_hide_fullscreen_button_summary_off">Fullscreen button is shown</string>
787793
<string name="morphe_hide_player_control_buttons_background_title">Hide player controls background</string>
788794
<string name="morphe_hide_player_control_buttons_background_summary_on">Player controls background is hidden</string>
789795
<string name="morphe_hide_player_control_buttons_background_summary_off">Player controls background is shown</string>

0 commit comments

Comments
 (0)