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); }