From ba15aba063d95116d8f028cf9c3b72aa2737fc30 Mon Sep 17 00:00:00 2001
From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
Date: Sat, 18 Nov 2023 21:10:26 +0200
Subject: [PATCH] fix(YouTube - ReturnYouTubeDislike): Improve layout padding
 (#517)

---
 .../patches/ReturnYouTubeDislikePatch.java    | 62 +++++++++----------
 .../ReturnYouTubeDislike.java                 | 24 ++-----
 2 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java b/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java
index c4e39572..075a0300 100644
--- a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java
+++ b/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java
@@ -4,7 +4,6 @@ import android.graphics.Rect;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.Build;
 import android.text.*;
-import android.view.Gravity;
 import android.view.View;
 import android.widget.TextView;
 import androidx.annotation.NonNull;
@@ -310,42 +309,50 @@ public class ReturnYouTubeDislikePatch {
     }
 
     /**
-     * Remove Rolling Number text view modifications made by this patch.
-     * Required as it appears text views can be reused for other rolling numbers (view count, upload time, etc).
+     * Injection point.
+     *
+     * Called for all usage of Rolling Number.
+     * Modifies the measured String text width to include the left separator and padding, if needed.
      */
-    private static void removeRollingNumberPatchChanges(TextView view) {
-        if (view.getCompoundDrawablePadding() != 0) {
-            LogHelper.printDebug(() -> "Removing rolling number styling from TextView");
-            view.setCompoundDrawablePadding(0);
-            view.setCompoundDrawables(null, null, null, null);
-            view.setGravity(Gravity.NO_GRAVITY);
-            view.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
-            view.setSingleLine(false);
+    public static float onRollingNumberMeasured(String text, float measuredTextWidth) {
+        try {
+            if (SettingsEnum.RYD_ENABLED.getBoolean() && !SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean()) {
+                if (ReturnYouTubeDislike.isPreviouslyCreatedSegmentedSpan(text)) {
+                    return measuredTextWidth + ReturnYouTubeDislike.leftSeparatorBounds.right
+                            + ReturnYouTubeDislike.leftSeparatorShapePaddingPixels;
+                }
+            }
+        } catch (Exception ex) {
+            LogHelper.printException(() -> "onRollingNumberMeasured failure", ex);
         }
+        return measuredTextWidth;
     }
 
     /**
      * Add Rolling Number text view modifications.
      */
     private static void addRollingNumberPatchChanges(TextView view) {
+        // YouTube Rolling Numbers do not use compound drawables or drawable padding.
         if (view.getCompoundDrawablePadding() == 0) {
-            LogHelper.printDebug(() -> "Adding rolling number styling to TextView");
-            // YouTube Rolling Numbers do not use compound drawables or drawable padding.
-            //
-            // Single line mode prevents entire words from being entirely clipped,
-            // and instead only clips the portion of text that runs off.
-            // The text should not clip due to the empty end padding,
-            // but use the feature just in case.
-            view.setSingleLine(true);
-            // Center align to distribute the horizontal padding.
-            view.setGravity(Gravity.CENTER);
-            view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
-            ShapeDrawable shapeDrawable = ReturnYouTubeDislike.getLeftSeparatorDrawable();
-            view.setCompoundDrawables(shapeDrawable, null, null, null);
+            LogHelper.printDebug(() -> "Adding rolling number TextView changes");
+            ShapeDrawable leftSeparator = ReturnYouTubeDislike.getLeftSeparatorDrawable();
+            view.setCompoundDrawables(leftSeparator, null, null, null);
             view.setCompoundDrawablePadding(ReturnYouTubeDislike.leftSeparatorShapePaddingPixels);
         }
     }
 
+    /**
+     * Remove Rolling Number text view modifications made by this patch.
+     * Required as it appears text views can be reused for other rolling numbers (view count, upload time, etc).
+     */
+    private static void removeRollingNumberPatchChanges(TextView view) {
+        if (view.getCompoundDrawablePadding() != 0) {
+            LogHelper.printDebug(() -> "Removing rolling number TextView changes");
+            view.setCompoundDrawablePadding(0);
+            view.setCompoundDrawables(null, null, null, null);
+        }
+    }
+
     /**
      * Injection point.
      */
@@ -372,14 +379,7 @@ public class ReturnYouTubeDislikePatch {
                 return original;
             }
 
-            // TextView does not display the tall left separator correctly,
-            // as it goes outside the height bounds and messes up the layout.
-            // Fix this by applying the left separator as a text view compound drawable.
-            // This creates a new issue as the compound drawable is not taken into the
-            // layout width sizing, but that is fixed in the span itself where it uses a blank
-            // padding string that adds to the layout width but is later ignored during UI drawing.
             if (SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean()) {
-                // Do not apply any TextView changes, and text should always fit without clipping.
                 removeRollingNumberPatchChanges(view);
             } else {
                 addRollingNumberPatchChanges(view);
diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java b/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java
index f1ed3d12..c0495384 100644
--- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java
+++ b/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java
@@ -113,7 +113,7 @@ public class ReturnYouTubeDislike {
     private static NumberFormat dislikePercentageFormatter;
 
     // Used for segmented dislike spans in Litho regular player.
-    private static final Rect leftSeparatorBounds;
+    public static final Rect leftSeparatorBounds;
     private static final Rect middleSeparatorBounds;
 
     /**
@@ -260,31 +260,17 @@ public class ReturnYouTubeDislike {
         ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
         shapeDrawable.getPaint().setColor(getSeparatorColor());
         shapeDrawable.setBounds(middleSeparatorBounds);
-        // Use original text width if using compact layout with Rolling Number,
-        // as there is no empty padding to allow any layout width differences.
+        // Use original text width if using Rolling Number,
+        // to ensure the replacement styled span has the same width as the measured String,
+        // otherwise layout can be broken (especially on devices with small system font sizes).
         middleSeparatorSpan.setSpan(
-                new VerticallyCenteredImageSpan(shapeDrawable, isRollingNumber && compactLayout),
+                new VerticallyCenteredImageSpan(shapeDrawable, isRollingNumber),
                 shapeInsertionIndex, shapeInsertionIndex + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
         builder.append(middleSeparatorSpan);
 
         // dislikes
         builder.append(newSpannableWithDislikes(oldSpannable, voteData));
 
-        // Add some padding for Rolling Number segmented span.
-        // Use an empty width span, as the layout uses the measured text width and not the
-        // actual span width.  So adding padding and then removing it while drawing gives some
-        // extra wiggle room for the left separator drawable (which is not included in layout width).
-        if (isRollingNumber && !compactLayout) {
-            // To test this, set the device system font to the smallest available.
-            // If text clipping still occurs, then increase the number of padding spaces below.
-            // Any extra width will be padded around the like/dislike string
-            // as it's set to center text alignment.
-            Spannable rightPaddingString = new SpannableString("      ");
-            rightPaddingString.setSpan(new FixedWidthEmptySpan(0), 0,
-                    rightPaddingString.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
-            builder.append(rightPaddingString);
-        }
-
         return new SpannableString(builder);
     }