diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java index e1b0fb14c..e72135f21 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -344,13 +344,14 @@ public class Settings extends BaseSettings { public static final IntegerSetting SB_CREATE_NEW_SEGMENT_STEP = new IntegerSetting("sb_create_new_segment_step", 150, parent(SB_ENABLED)); public static final BooleanSetting SB_VOTING_BUTTON = new BooleanSetting("sb_voting_button", FALSE, parent(SB_ENABLED)); public static final BooleanSetting SB_CREATE_NEW_SEGMENT = new BooleanSetting("sb_create_new_segment", FALSE, parent(SB_ENABLED)); + public static final BooleanSetting SB_SQUARE_LAYOUT = new BooleanSetting("sb_square_layout", FALSE, parent(SB_ENABLED)); public static final BooleanSetting SB_COMPACT_SKIP_BUTTON = new BooleanSetting("sb_compact_skip_button", FALSE, parent(SB_ENABLED)); public static final BooleanSetting SB_AUTO_HIDE_SKIP_BUTTON = new BooleanSetting("sb_auto_hide_skip_button", TRUE, parent(SB_ENABLED)); public static final BooleanSetting SB_TOAST_ON_SKIP = new BooleanSetting("sb_toast_on_skip", TRUE, parent(SB_ENABLED)); public static final BooleanSetting SB_TOAST_ON_CONNECTION_ERROR = new BooleanSetting("sb_toast_on_connection_error", TRUE, parent(SB_ENABLED)); public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED)); public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED)); - public static final BooleanSetting SB_VIDEO_LENGTH_WITHOUT_SEGMENTS = new BooleanSetting("sb_video_length_without_segments", TRUE, parent(SB_ENABLED)); + public static final BooleanSetting SB_VIDEO_LENGTH_WITHOUT_SEGMENTS = new BooleanSetting("sb_video_length_without_segments", FALSE, parent(SB_ENABLED)); public static final StringSetting SB_API_URL = new StringSetting("sb_api_url", "https://sponsor.ajay.app"); public static final BooleanSetting SB_USER_IS_VIP = new BooleanSetting("sb_user_is_vip", FALSE); public static final IntegerSetting SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS = new IntegerSetting("sb_local_time_saved_number_segments", 0); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockPreferenceFragment.java index 6f7706924..18cf149dc 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockPreferenceFragment.java @@ -36,8 +36,9 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment { private SwitchPreference sbEnabled; private SwitchPreference addNewSegment; private SwitchPreference votingEnabled; - private SwitchPreference compactSkipButton; private SwitchPreference autoHideSkipSegmentButton; + private SwitchPreference compactSkipButton; + private SwitchPreference squareLayout; private SwitchPreference showSkipToast; private SwitchPreference trackSkips; private SwitchPreference showTimeWithoutSegments; @@ -61,7 +62,9 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment { } else if (!Settings.SB_CREATE_NEW_SEGMENT.get()) { SponsorBlockViewController.hideNewSegmentLayout(); } - // Voting and add new segment buttons automatically shows/hide themselves. + // Voting and add new segment buttons automatically show/hide themselves. + + SponsorBlockViewController.updateLayout(); sbEnabled.setChecked(enabled); @@ -71,11 +74,14 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment { votingEnabled.setChecked(Settings.SB_VOTING_BUTTON.get()); votingEnabled.setEnabled(enabled); + autoHideSkipSegmentButton.setEnabled(enabled); + autoHideSkipSegmentButton.setChecked(Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()); + compactSkipButton.setChecked(Settings.SB_COMPACT_SKIP_BUTTON.get()); compactSkipButton.setEnabled(enabled); - autoHideSkipSegmentButton.setChecked(Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()); - autoHideSkipSegmentButton.setEnabled(enabled); + squareLayout.setChecked(Settings.SB_SQUARE_LAYOUT.get()); + squareLayout.setEnabled(enabled); showSkipToast.setChecked(Settings.SB_TOAST_ON_SKIP.get()); showSkipToast.setEnabled(enabled); @@ -175,6 +181,17 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment { return true; }); + autoHideSkipSegmentButton = new SwitchPreference(context); + autoHideSkipSegmentButton.setTitle(str("revanced_sb_enable_auto_hide_skip_segment_button")); + autoHideSkipSegmentButton.setSummaryOn(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_on")); + autoHideSkipSegmentButton.setSummaryOff(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_off")); + category.addPreference(autoHideSkipSegmentButton); + autoHideSkipSegmentButton.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_AUTO_HIDE_SKIP_BUTTON.save((Boolean) newValue); + updateUI(); + return true; + }); + compactSkipButton = new SwitchPreference(context); compactSkipButton.setTitle(str("revanced_sb_enable_compact_skip_button")); compactSkipButton.setSummaryOn(str("revanced_sb_enable_compact_skip_button_sum_on")); @@ -186,13 +203,13 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment { return true; }); - autoHideSkipSegmentButton = new SwitchPreference(context); - autoHideSkipSegmentButton.setTitle(str("revanced_sb_enable_auto_hide_skip_segment_button")); - autoHideSkipSegmentButton.setSummaryOn(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_on")); - autoHideSkipSegmentButton.setSummaryOff(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_off")); - category.addPreference(autoHideSkipSegmentButton); - autoHideSkipSegmentButton.setOnPreferenceChangeListener((preference1, newValue) -> { - Settings.SB_AUTO_HIDE_SKIP_BUTTON.save((Boolean) newValue); + squareLayout = new SwitchPreference(context); + squareLayout.setTitle(str("revanced_sb_square_layout")); + squareLayout.setSummaryOn(str("revanced_sb_square_layout_sum_on")); + squareLayout.setSummaryOff(str("revanced_sb_square_layout_sum_off")); + category.addPreference(squareLayout); + squareLayout.setOnPreferenceChangeListener((preference1, newValue) -> { + Settings.SB_SQUARE_LAYOUT.save((Boolean) newValue); updateUI(); return true; }); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/NewSegmentLayout.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/NewSegmentLayout.java index 1f8d80c50..0b0793388 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/NewSegmentLayout.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/NewSegmentLayout.java @@ -2,10 +2,11 @@ package app.revanced.extension.youtube.sponsorblock.ui; import android.content.Context; import android.content.res.ColorStateList; +import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.RippleDrawable; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageButton; @@ -14,15 +15,15 @@ import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.sponsorblock.SponsorBlockUtils; import app.revanced.extension.shared.Logger; +import static app.revanced.extension.shared.Utils.getResourceColor; import static app.revanced.extension.shared.Utils.getResourceDimensionPixelSize; import static app.revanced.extension.shared.Utils.getResourceIdentifier; public final class NewSegmentLayout extends FrameLayout { private static final ColorStateList rippleColorStateList = new ColorStateList( new int[][]{new int[]{android.R.attr.state_enabled}}, - new int[]{0x33ffffff} // sets the ripple color to white + new int[]{0x33ffffff} // Ripple effect color (semi-transparent white) ); - private final int rippleEffectId; final int defaultBottomMargin; final int ctaBottomMargin; @@ -47,10 +48,6 @@ public final class NewSegmentLayout extends FrameLayout { getResourceIdentifier(context, "revanced_sb_new_segment", "layout"), this, true ); - TypedValue rippleEffect = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, rippleEffect, true); - rippleEffectId = rippleEffect.resourceId; - initializeButton( context, "revanced_sb_new_segment_rewind", @@ -120,6 +117,28 @@ public final class NewSegmentLayout extends FrameLayout { }); } + /** + * Update the layout of this UI control. + */ + public void updateLayout() { + final boolean squareLayout = Settings.SB_SQUARE_LAYOUT.get(); + + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams(); + final int margin = squareLayout + ? 0 + : SponsorBlockViewController.ROUNDED_LAYOUT_MARGIN; + params.setMarginStart(margin); + setLayoutParams(params); + + GradientDrawable backgroundDrawable = new GradientDrawable(); + backgroundDrawable.setColor(getResourceColor("skip_ad_button_background_color")); + final float cornerRadius = squareLayout + ? 0 + : 16 * getResources().getDisplayMetrics().density; + backgroundDrawable.setCornerRadius(cornerRadius); + setBackground(backgroundDrawable); + } + @FunctionalInterface private interface ButtonOnClickHandlerFunction { void apply(); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SkipSponsorButton.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SkipSponsorButton.java index 11813aa84..6ca96cd37 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SkipSponsorButton.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SkipSponsorButton.java @@ -8,6 +8,7 @@ import static app.revanced.extension.shared.Utils.getResourceIdentifier; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.RectF; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -19,11 +20,19 @@ import androidx.annotation.NonNull; import java.util.Objects; +import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController; import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment; public class SkipSponsorButton extends FrameLayout { - private static final boolean highContrast = true; + /** + * Adds a high contrast border around the skip button. + * + * This feature is not currently used. + * If this is added, it needs an additional button width change because + * as-is the skip button text is clipped when this is on. + */ + private static final boolean highContrast = false; private final LinearLayout skipSponsorBtnContainer; private final TextView skipSponsorTextView; private final Paint background; @@ -49,18 +58,23 @@ public class SkipSponsorButton extends FrameLayout { LayoutInflater.from(context).inflate(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button", "layout"), this, true); // layout:skip_ad_button setMinimumHeight(getResourceDimensionPixelSize("ad_skip_ad_button_min_height")); // dimen:ad_skip_ad_button_min_height - skipSponsorBtnContainer = Objects.requireNonNull((LinearLayout) findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_container", "id"))); // id:skip_ad_button_container + skipSponsorBtnContainer = Objects.requireNonNull(findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_container", "id"))); // id:skip_ad_button_container + background = new Paint(); background.setColor(getResourceColor("skip_ad_button_background_color")); // color:skip_ad_button_background_color); background.setStyle(Paint.Style.FILL); + border = new Paint(); border.setColor(getResourceColor("skip_ad_button_border_color")); // color:skip_ad_button_border_color); border.setStrokeWidth(getResourceDimension("ad_skip_ad_button_border_width")); // dimen:ad_skip_ad_button_border_width); border.setStyle(Paint.Style.STROKE); - skipSponsorTextView = Objects.requireNonNull((TextView) findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_text", "id"))); // id:skip_ad_button_text; + + skipSponsorTextView = Objects.requireNonNull(findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_text", "id"))); // id:skip_ad_button_text; defaultBottomMargin = getResourceDimensionPixelSize("skip_button_default_bottom_margin"); // dimen:skip_button_default_bottom_margin ctaBottomMargin = getResourceDimensionPixelSize("skip_button_cta_bottom_margin"); // dimen:skip_button_cta_bottom_margin + updateLayout(); + skipSponsorBtnContainer.setOnClickListener(v -> { // The view controller handles hiding this button, but hide it here as well just in case something goofs. setVisibility(View.GONE); @@ -72,30 +86,56 @@ public class SkipSponsorButton extends FrameLayout { protected final void dispatchDraw(Canvas canvas) { final int left = skipSponsorBtnContainer.getLeft(); final int top = skipSponsorBtnContainer.getTop(); - final int leftPlusWidth = (left + skipSponsorBtnContainer.getWidth()); - final int topPlusHeight = (top + skipSponsorBtnContainer.getHeight()); - canvas.drawRect(left, top, leftPlusWidth, topPlusHeight, background); - if (!highContrast) { - canvas.drawLines(new float[]{ - leftPlusWidth, top, left, top, - left, top, left, topPlusHeight, - left, topPlusHeight, leftPlusWidth, topPlusHeight}, - border); + final int right = left + skipSponsorBtnContainer.getWidth(); + final int bottom = top + skipSponsorBtnContainer.getHeight(); + + // Determine corner radius for rounded button + float cornerRadius = skipSponsorBtnContainer.getHeight() / 2f; + + if (Settings.SB_SQUARE_LAYOUT.get()) { + // Square button. + canvas.drawRect(left, top, right, bottom, background); + if (highContrast) { + canvas.drawLines(new float[]{ + right, top, left, top, + left, top, left, bottom, + left, bottom, right, bottom}, + border); // Draw square border. + } + } else { + // Rounded button. + RectF rect = new RectF(left, top, right, bottom); + canvas.drawRoundRect(rect, cornerRadius, cornerRadius, background); // Draw rounded background. + if (highContrast) { + canvas.drawRoundRect(rect, cornerRadius, cornerRadius, border); // Draw rounded border. + } } super.dispatchDraw(canvas); } /** - * @return true, if this button state was changed + * Update the layout of this button. */ - public boolean updateSkipButtonText(@NonNull SponsorSegment segment) { + public void updateLayout() { + if (Settings.SB_SQUARE_LAYOUT.get()) { + // No padding for square corners. + setPadding(0, 0, 0, 0); + } else { + // Apply padding for rounded corners. + final int padding = SponsorBlockViewController.ROUNDED_LAYOUT_MARGIN; + setPadding(padding, 0, padding, 0); + } + } + + public void updateSkipButtonText(@NonNull SponsorSegment segment) { this.segment = segment; CharSequence newText = segment.getSkipButtonText(); + + //noinspection StringEqualsCharSequence if (newText.equals(skipSponsorTextView.getText())) { - return false; + return; } skipSponsorTextView.setText(newText); - return true; } } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java index 099f0d56e..78c48a779 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/sponsorblock/ui/SponsorBlockViewController.java @@ -19,8 +19,11 @@ import app.revanced.extension.shared.Utils; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment; +import kotlin.Unit; public class SponsorBlockViewController { + public static final int ROUNDED_LAYOUT_MARGIN = 12; + private static WeakReference inlineSponsorOverlayRef = new WeakReference<>(null); private static WeakReference youtubeOverlaysLayoutRef = new WeakReference<>(null); private static WeakReference skipHighlightButtonRef = new WeakReference<>(null); @@ -36,7 +39,7 @@ public class SponsorBlockViewController { static { PlayerType.getOnChange().addObserver((PlayerType type) -> { playerTypeChanged(type); - return null; + return Unit.INSTANCE; }); } @@ -80,12 +83,16 @@ public class SponsorBlockViewController { }); youtubeOverlaysLayoutRef = new WeakReference<>(viewGroup); - skipHighlightButtonRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_skip_highlight_button", "id")))); - skipSponsorButtonRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_skip_sponsor_button", "id")))); - newSegmentLayoutRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_new_segment_view", "id")))); + skipHighlightButtonRef = new WeakReference<>(Objects.requireNonNull( + layout.findViewById(getResourceIdentifier("revanced_sb_skip_highlight_button", "id")))); + + skipSponsorButtonRef = new WeakReference<>(Objects.requireNonNull( + layout.findViewById(getResourceIdentifier("revanced_sb_skip_sponsor_button", "id")))); + + NewSegmentLayout newSegmentLayout = Objects.requireNonNull( + layout.findViewById(getResourceIdentifier("revanced_sb_new_segment_view", "id"))); + newSegmentLayoutRef = new WeakReference<>(newSegmentLayout); + newSegmentLayout.updateLayout(); newSegmentLayoutVisible = false; skipHighlight = null; @@ -101,6 +108,23 @@ public class SponsorBlockViewController { hideNewSegmentLayout(); } + public static void updateLayout() { + SkipSponsorButton button = skipSponsorButtonRef.get(); + if (button != null) { + button.updateLayout(); + } + + button = skipHighlightButtonRef.get(); + if (button != null) { + button.updateLayout(); + } + + NewSegmentLayout newSegmentLayout = newSegmentLayoutRef.get(); + if (newSegmentLayout != null) { + newSegmentLayout.updateLayout(); + } + } + public static void showSkipHighlightButton(@NonNull SponsorSegment segment) { skipHighlight = Objects.requireNonNull(segment); NewSegmentLayout newSegmentLayout = newSegmentLayoutRef.get(); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt index cb1fcd935..19c6461cb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt @@ -70,12 +70,7 @@ private val sponsorBlockResourcePatch = resourcePatch { "revanced_sb_logo.xml", "revanced_sb_publish.xml", "revanced_sb_voting.xml", - ), - ResourceGroup( - // required resource for back button, because when the base APK is used, this resource will not exist - "drawable-xxxhdpi", - "quantum_ic_skip_next_white_24.png", - ), + ) ).forEach { resourceGroup -> copyResources("sponsorblock", resourceGroup) } diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 2ed29cebe..4b1dfe61e 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -909,6 +909,9 @@ This feature works best with a video quality of 720p or lower and when using a v Show voting button Segment voting button is shown Segment voting button is not shown + Use square layout + Buttons and controls are square + Buttons and controls are rounded Use compact skip button Skip button styled for minimum width diff --git a/patches/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png b/patches/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png deleted file mode 100644 index 19c4929cc..000000000 Binary files a/patches/src/main/resources/sponsorblock/drawable-xxxhdpi/quantum_ic_skip_next_white_24.png and /dev/null differ diff --git a/patches/src/main/resources/sponsorblock/layout/revanced_sb_new_segment.xml b/patches/src/main/resources/sponsorblock/layout/revanced_sb_new_segment.xml index 05b4dd89d..297266725 100644 --- a/patches/src/main/resources/sponsorblock/layout/revanced_sb_new_segment.xml +++ b/patches/src/main/resources/sponsorblock/layout/revanced_sb_new_segment.xml @@ -6,7 +6,6 @@ android:id="@+id/revanced_sb_new_segment_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="#66000000" android:gravity="start|center" android:orientation="vertical"> diff --git a/patches/src/main/resources/sponsorblock/layout/revanced_sb_skip_sponsor_button.xml b/patches/src/main/resources/sponsorblock/layout/revanced_sb_skip_sponsor_button.xml index b25987ff1..b9813567f 100644 --- a/patches/src/main/resources/sponsorblock/layout/revanced_sb_skip_sponsor_button.xml +++ b/patches/src/main/resources/sponsorblock/layout/revanced_sb_skip_sponsor_button.xml @@ -8,7 +8,7 @@ android:layout_height="32dp" android:layout_gravity="center_vertical" android:orientation="horizontal" - android:padding="8dp"> + android:padding="5dp"> \ No newline at end of file