Skip to content

Commit 7a37d85

Browse files
authored
feat(YouTube - Hide layout components): Add "Hide view count" and "Hide upload time" settings (#5983)
1 parent 0ed7067 commit 7a37d85

File tree

5 files changed

+127
-2
lines changed

5 files changed

+127
-2
lines changed

extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import static app.revanced.extension.youtube.shared.NavigationBar.NavigationButton;
44

55
import android.graphics.drawable.Drawable;
6+
import android.text.SpannableString;
7+
import android.text.SpannableStringBuilder;
8+
import android.text.TextUtils;
69
import android.view.View;
710
import android.widget.ImageView;
811

@@ -500,4 +503,62 @@ private static boolean hideShelves() {
500503
// This check is important as the shelf layout is used for the library tab playlists.
501504
return NavigationButton.getSelectedNavigationButton() != NavigationButton.LIBRARY;
502505
}
506+
507+
/**
508+
* Injection point.
509+
*/
510+
public static SpannableString modifyFeedSubtitleSpan(SpannableString original, float truncationDimension) {
511+
try {
512+
final boolean hideViewCount = Settings.HIDE_VIEW_COUNT.get();
513+
final boolean hideUploadTime = Settings.HIDE_UPLOAD_TIME.get();
514+
if (!hideViewCount && !hideUploadTime) {
515+
return original;
516+
}
517+
518+
// Applies only for these specific dimensions.
519+
if (truncationDimension == 16f || truncationDimension == 42f) {
520+
String delimiter = " · ";
521+
final int delimiterLength = delimiter.length();
522+
523+
// Index includes the starting delimiter.
524+
final int viewCountStartIndex = TextUtils.indexOf(original, delimiter);
525+
if (viewCountStartIndex < 0) {
526+
return original;
527+
}
528+
529+
final int uploadTimeStartIndex = TextUtils.indexOf(original, delimiter,
530+
viewCountStartIndex + delimiterLength);
531+
if (uploadTimeStartIndex < 0) {
532+
return original;
533+
}
534+
535+
// Ensure there is exactly 2 delimiters.
536+
if (TextUtils.indexOf(original, delimiter,
537+
uploadTimeStartIndex + delimiterLength) >= 0) {
538+
return original;
539+
}
540+
541+
// Make a mutable copy that keeps existing span styling.
542+
SpannableStringBuilder builder = new SpannableStringBuilder(original);
543+
544+
// Remove the sections.
545+
if (hideUploadTime) {
546+
builder.delete(uploadTimeStartIndex, original.length());
547+
}
548+
549+
if (hideViewCount) {
550+
builder.delete(viewCountStartIndex, uploadTimeStartIndex);
551+
}
552+
553+
SpannableString replacement = new SpannableString(builder);
554+
Logger.printDebug(() -> "Replacing feed subtitle span: " + original + " with: " + replacement);
555+
556+
return replacement;
557+
}
558+
} catch (Exception ex) {
559+
Logger.printException(() -> "modifyFeedSubtitleSpan failure", ex);
560+
}
561+
562+
return original;
563+
}
503564
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ public class Settings extends BaseSettings {
112112
public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
113113
public static final BooleanSetting HIDE_SURVEYS = new BooleanSetting("revanced_hide_surveys", TRUE);
114114
public static final BooleanSetting HIDE_TICKET_SHELF = new BooleanSetting("revanced_hide_ticket_shelf", FALSE);
115+
public static final BooleanSetting HIDE_UPLOAD_TIME = new BooleanSetting("revanced_hide_upload_time", FALSE, "revanced_hide_upload_time_user_dialog_message");
115116
public static final BooleanSetting HIDE_VIDEO_RECOMMENDATION_LABELS = new BooleanSetting("revanced_hide_video_recommendation_labels", TRUE);
117+
public static final BooleanSetting HIDE_VIEW_COUNT = new BooleanSetting("revanced_hide_view_count", FALSE, "revanced_hide_view_count_user_dialog_message");
116118

117119
// Alternative thumbnails
118120
public static final EnumSetting<ThumbnailOption> ALT_THUMBNAIL_HOME = new EnumSetting<>("revanced_alt_thumbnail_home", ThumbnailOption.ORIGINAL);

patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/Fingerprints.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,17 @@ internal val showFloatingMicrophoneButtonFingerprint = fingerprint {
147147
)
148148
literal { fabButtonId }
149149
}
150+
151+
internal val hideViewCountFingerprint = fingerprint {
152+
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
153+
returns("Ljava/lang/CharSequence;")
154+
155+
opcodes(
156+
Opcode.RETURN_OBJECT,
157+
Opcode.CONST_STRING,
158+
Opcode.RETURN_OBJECT,
159+
)
160+
strings(
161+
"Has attachmentRuns but drawableRequester is missing.",
162+
)
163+
}

patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
3636
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
3737
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
3838
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
39+
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
3940

4041
var expandButtonDownId = -1L
4142
private set
@@ -239,6 +240,8 @@ val hideLayoutComponentsPatch = bytecodePatch(
239240
SwitchPreference("revanced_hide_surveys"),
240241
SwitchPreference("revanced_hide_ticket_shelf"),
241242
SwitchPreference("revanced_hide_video_recommendation_labels"),
243+
SwitchPreference("revanced_hide_view_count"),
244+
SwitchPreference("revanced_hide_upload_time"),
242245
SwitchPreference("revanced_hide_doodles"),
243246
)
244247

@@ -397,6 +400,39 @@ val hideLayoutComponentsPatch = bytecodePatch(
397400

398401
// endregion
399402

403+
404+
// region hide view count
405+
406+
hideViewCountFingerprint.method.apply {
407+
val startIndex = hideViewCountFingerprint.patternMatch!!.startIndex
408+
var returnStringRegister = getInstruction<OneRegisterInstruction>(startIndex).registerA
409+
410+
// Find the instruction where the text dimension is retrieved.
411+
val applyDimensionIndex = indexOfFirstInstructionReversedOrThrow {
412+
val reference = getReference<MethodReference>()
413+
opcode == Opcode.INVOKE_STATIC &&
414+
reference?.definingClass == "Landroid/util/TypedValue;" &&
415+
reference.returnType == "F" &&
416+
reference.name == "applyDimension" &&
417+
reference.parameterTypes == listOf("I", "F", "Landroid/util/DisplayMetrics;")
418+
}
419+
420+
// A float value is passed which is used to determine subtitle text size.
421+
val floatDimensionRegister = getInstruction<OneRegisterInstruction>(
422+
applyDimensionIndex + 1
423+
).registerA
424+
425+
addInstructions(
426+
applyDimensionIndex - 1,
427+
"""
428+
invoke-static { v$returnStringRegister, v$floatDimensionRegister }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->modifyFeedSubtitleSpan(Landroid/text/SpannableString;F)Landroid/text/SpannableString;
429+
move-result-object v$returnStringRegister
430+
"""
431+
)
432+
}
433+
434+
// endregion
435+
400436
// region hide filter bar
401437

402438
/**

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ If a Doodle is currently showing in your region and this hide setting is on, the
450450
<string name="revanced_hide_comments_thanks_button_title">Hide Thanks button</string>
451451
<string name="revanced_hide_comments_thanks_button_summary_on">Thanks button is hidden</string>
452452
<string name="revanced_hide_comments_thanks_button_summary_off">Thanks button is shown</string>
453-
454453
<string name="revanced_custom_filter_screen_title">Custom filter</string>
455454
<string name="revanced_custom_filter_screen_summary">Hide components using custom filters</string>
456455
<string name="revanced_custom_filter_title">Enable custom filter</string>
@@ -460,7 +459,20 @@ If a Doodle is currently showing in your region and this hide setting is on, the
460459
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
461460
<string name="revanced_custom_filter_strings_summary">List of component path builder strings to filter separated by new line</string>
462461
<string name="revanced_custom_filter_toast_invalid_syntax">Invalid custom filter: %s</string>
463-
462+
<string name="revanced_hide_view_count_title">Hide view count</string>
463+
<string name="revanced_hide_view_count_summary_on">View count is hidden in feed and search results</string>
464+
<string name="revanced_hide_view_count_summary_off">View count is shown in feed and search results</string>
465+
<!-- Translations should lanaguge similar to revanced_hide_upload_time_user_dialog_message -->
466+
<string name="revanced_hide_view_count_user_dialog_message">"Limitations:
467+
• Shorts shelves, channel pages, and search results may still show view counts
468+
• This feature does not work with automotive form factor"</string>
469+
<string name="revanced_hide_upload_time_title">Hide upload time</string>
470+
<string name="revanced_hide_upload_time_summary_on">Upload time is hidden in feed and search results</string>
471+
<string name="revanced_hide_upload_time_summary_off">Upload time is shown in feed and search results</string>
472+
<!-- Translations should lanaguge similar to revanced_hide_view_count_user_dialog_message -->
473+
<string name="revanced_hide_upload_time_user_dialog_message">"Limitations:
474+
• Shorts shelves, channel pages, and search results may still show upload times
475+
• This feature does not work with automotive form factor"</string>
464476
<string name="revanced_hide_keyword_content_screen_title">Hide keyword content</string>
465477
<string name="revanced_hide_keyword_content_screen_summary">Hide feed and search videos using keyword filters</string>
466478
<string name="revanced_hide_keyword_content_home_title">Hide Home videos by keywords</string>

0 commit comments

Comments
 (0)