feat(YouTube - Theme): Add option to use custom seekbar accent color (#4337)

This commit is contained in:
LisoUseInAIKyrios 2025-01-23 22:15:23 +02:00 committed by GitHub
parent e69197c6e5
commit 952b4fc4c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 124 additions and 87 deletions

View File

@ -9,14 +9,23 @@ import app.revanced.extension.shared.settings.BaseSettings;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class EnableDebuggingPatch { public final class EnableDebuggingPatch {
private static final ConcurrentMap<Long, Boolean> featureFlags /**
= new ConcurrentHashMap<>(300, 0.75f, 1); * Only log if debugging is enabled on startup.
* This prevents enabling debugging
* while the app is running then failing to restart
* resulting in an incomplete log.
*/
private static final boolean LOG_FEATURE_FLAGS = BaseSettings.DEBUG.get();
private static final ConcurrentMap<Long, Boolean> featureFlags = LOG_FEATURE_FLAGS
? new ConcurrentHashMap<>(800, 0.5f, 1)
: null;
/** /**
* Injection point. * Injection point.
*/ */
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) { public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
if (value && BaseSettings.DEBUG.get()) { if (LOG_FEATURE_FLAGS && value) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> "boolean feature is enabled: " + flag); Logger.printDebug(() -> "boolean feature is enabled: " + flag);
} }
@ -29,7 +38,7 @@ public final class EnableDebuggingPatch {
* Injection point. * Injection point.
*/ */
public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) { public static double isDoubleFeatureFlagEnabled(double value, long flag, double defaultValue) {
if (defaultValue != value && BaseSettings.DEBUG.get()) { if (LOG_FEATURE_FLAGS && defaultValue != value) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
// Align the log outputs to make post processing easier. // Align the log outputs to make post processing easier.
Logger.printDebug(() -> " double feature is enabled: " + flag Logger.printDebug(() -> " double feature is enabled: " + flag
@ -44,7 +53,7 @@ public final class EnableDebuggingPatch {
* Injection point. * Injection point.
*/ */
public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) { public static long isLongFeatureFlagEnabled(long value, long flag, long defaultValue) {
if (defaultValue != value && BaseSettings.DEBUG.get()) { if (LOG_FEATURE_FLAGS && defaultValue != value) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> " long feature is enabled: " + flag Logger.printDebug(() -> " long feature is enabled: " + flag
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue)); + " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
@ -58,7 +67,7 @@ public final class EnableDebuggingPatch {
* Injection point. * Injection point.
*/ */
public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) { public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) {
if (BaseSettings.DEBUG.get() && !defaultValue.equals(value)) { if (LOG_FEATURE_FLAGS && !defaultValue.equals(value)) {
if (featureFlags.putIfAbsent(flag, true) == null) { if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> " string feature is enabled: " + flag Logger.printDebug(() -> " string feature is enabled: " + flag
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue)); + " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));

View File

@ -36,6 +36,11 @@ public final class SeekbarColorPatch {
*/ */
private static final float[] FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = { 0.8f, 1.0f }; private static final float[] FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS = { 0.8f, 1.0f };
/**
* Empty seekbar gradient, if hide seekbar in feed is enabled.
*/
private static final int[] HIDDEN_SEEKBAR_GRADIENT_COLORS = { 0x0, 0x0 };
/** /**
* Default YouTube seekbar color brightness. * Default YouTube seekbar color brightness.
*/ */
@ -43,10 +48,10 @@ public final class SeekbarColorPatch {
/** /**
* If {@link Settings#SEEKBAR_CUSTOM_COLOR} is enabled, * If {@link Settings#SEEKBAR_CUSTOM_COLOR} is enabled,
* this is the color value of {@link Settings#SEEKBAR_CUSTOM_COLOR_VALUE}. * this is the color value of {@link Settings#SEEKBAR_CUSTOM_COLOR_PRIMARY}.
* Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}. * Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}.
*/ */
private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR; private static int customSeekbarColor = ORIGINAL_SEEKBAR_COLOR;
/** /**
* Custom seekbar hue, saturation, and brightness values. * Custom seekbar hue, saturation, and brightness values.
@ -56,7 +61,7 @@ public final class SeekbarColorPatch {
/** /**
* Custom seekbar color, used for linear gradient replacements. * Custom seekbar color, used for linear gradient replacements.
*/ */
private static final int[] customSeekbarColorInt = new int[2]; private static final int[] customSeekbarColorGradient = new int[2];
static { static {
float[] hsv = new float[3]; float[] hsv = new float[3];
@ -65,24 +70,27 @@ public final class SeekbarColorPatch {
if (SEEKBAR_CUSTOM_COLOR_ENABLED) { if (SEEKBAR_CUSTOM_COLOR_ENABLED) {
loadCustomSeekbarColor(); loadCustomSeekbarColor();
Arrays.fill(customSeekbarColorInt, seekbarColor);
} }
} }
private static void loadCustomSeekbarColor() { private static void loadCustomSeekbarColor() {
try { try {
seekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_VALUE.get()); customSeekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_PRIMARY.get());
Color.colorToHSV(seekbarColor, customSeekbarColorHSV); Color.colorToHSV(customSeekbarColor, customSeekbarColorHSV);
customSeekbarColorGradient[0] = customSeekbarColor;
customSeekbarColorGradient[1] = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_ACCENT.get());
} catch (Exception ex) { } catch (Exception ex) {
Utils.showToastShort(str("revanced_seekbar_custom_color_invalid")); Utils.showToastShort(str("revanced_seekbar_custom_color_invalid"));
Settings.SEEKBAR_CUSTOM_COLOR_VALUE.resetToDefault(); Settings.SEEKBAR_CUSTOM_COLOR_PRIMARY.resetToDefault();
Settings.SEEKBAR_CUSTOM_COLOR_ACCENT.resetToDefault();
loadCustomSeekbarColor(); loadCustomSeekbarColor();
} }
} }
public static int getSeekbarColor() { public static int getSeekbarColor() {
return seekbarColor; return customSeekbarColor;
} }
/** /**
@ -126,7 +134,7 @@ public final class SeekbarColorPatch {
// Even if the seekbar color xml value is changed to a completely different color (such as green), // Even if the seekbar color xml value is changed to a completely different color (such as green),
// a color filter still cannot be selectively applied when the drawable has more than 1 color. // a color filter still cannot be selectively applied when the drawable has more than 1 color.
try { try {
String seekbarStyle = get9BitStyleIdentifier(seekbarColor); String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor);
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle); Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);
final int styleIdentifierDefault = Utils.getResourceIdentifier( final int styleIdentifierDefault = Utils.getResourceIdentifier(
@ -153,15 +161,6 @@ public final class SeekbarColorPatch {
return !HIDE_SEEKBAR_THUMBNAIL_ENABLED && original; return !HIDE_SEEKBAR_THUMBNAIL_ENABLED && original;
} }
/**
* Injection point.
*/
public static int getSeekbarScrubHandleColor(int colorValue) {
return SEEKBAR_CUSTOM_COLOR_ENABLED
? seekbarColor
: colorValue;
}
/** /**
* Injection point. * Injection point.
* *
@ -173,23 +172,15 @@ public final class SeekbarColorPatch {
public static int getLithoColor(int colorValue) { public static int getLithoColor(int colorValue) {
if (colorValue == ORIGINAL_SEEKBAR_COLOR) { if (colorValue == ORIGINAL_SEEKBAR_COLOR) {
if (HIDE_SEEKBAR_THUMBNAIL_ENABLED) { if (HIDE_SEEKBAR_THUMBNAIL_ENABLED) {
return 0x00000000; return 0x0;
} }
return getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR); return customSeekbarColor;
} }
return colorValue; return colorValue;
} }
/**
* Injection point.
*/
public static int[] getLinearGradient(int[] original) {
return SEEKBAR_CUSTOM_COLOR_ENABLED
? customSeekbarColorInt
: original;
}
private static String colorArrayToHex(int[] colors) { private static String colorArrayToHex(int[] colors) {
final int length = colors.length; final int length = colors.length;
StringBuilder builder = new StringBuilder(length * 12); StringBuilder builder = new StringBuilder(length * 12);
@ -210,21 +201,31 @@ public final class SeekbarColorPatch {
/** /**
* Injection point. * Injection point.
*/ */
public static void setLinearGradient(int[] colors, float[] positions) { public static int[] getPlayerLinearGradient(int[] original) {
return SEEKBAR_CUSTOM_COLOR_ENABLED
? customSeekbarColorGradient
: original;
}
/**
* Injection point.
*/
public static int[] getLithoLinearGradient(int[] colors, float[] positions) {
if (SEEKBAR_CUSTOM_COLOR_ENABLED || HIDE_SEEKBAR_THUMBNAIL_ENABLED) { if (SEEKBAR_CUSTOM_COLOR_ENABLED || HIDE_SEEKBAR_THUMBNAIL_ENABLED) {
// Most litho usage of linear gradients is hooked here, // Most litho usage of linear gradients is hooked here,
// so must only change if the values are those for the seekbar. // so must only change if the values are those for the seekbar.
if ((Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors) if ((Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors)
&& Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions))) { && Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions))) {
Arrays.fill(colors, HIDE_SEEKBAR_THUMBNAIL_ENABLED return HIDE_SEEKBAR_THUMBNAIL_ENABLED
? 0x00000000 ? HIDDEN_SEEKBAR_GRADIENT_COLORS
: seekbarColor); : customSeekbarColorGradient;
return;
} }
Logger.printDebug(() -> "Ignoring gradient colors: " + colorArrayToHex(colors) Logger.printDebug(() -> "Ignoring gradient colors: " + colorArrayToHex(colors)
+ " positions: " + Arrays.toString(positions)); + " positions: " + Arrays.toString(positions));
} }
return colors;
} }
/** /**
@ -238,7 +239,7 @@ public final class SeekbarColorPatch {
} }
return colorValue == ORIGINAL_SEEKBAR_COLOR return colorValue == ORIGINAL_SEEKBAR_COLOR
? getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR) ? customSeekbarColor
: colorValue; : colorValue;
} }
@ -248,11 +249,9 @@ public final class SeekbarColorPatch {
* Overrides color used for the video player seekbar. * Overrides color used for the video player seekbar.
*/ */
public static int getVideoPlayerSeekbarColor(int originalColor) { public static int getVideoPlayerSeekbarColor(int originalColor) {
if (!SEEKBAR_CUSTOM_COLOR_ENABLED) { return SEEKBAR_CUSTOM_COLOR_ENABLED
return originalColor; ? getSeekbarColorValue(originalColor)
} : originalColor;
return getSeekbarColorValue(originalColor);
} }
/** /**
@ -261,10 +260,6 @@ public final class SeekbarColorPatch {
*/ */
private static int getSeekbarColorValue(int originalColor) { private static int getSeekbarColorValue(int originalColor) {
try { try {
if (!SEEKBAR_CUSTOM_COLOR_ENABLED || originalColor == seekbarColor) {
return originalColor; // nothing to do
}
final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR); final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);
// The seekbar uses the same color but different brightness for different situations. // The seekbar uses the same color but different brightness for different situations.
@ -277,7 +272,7 @@ public final class SeekbarColorPatch {
hsv[1] = customSeekbarColorHSV[1]; hsv[1] = customSeekbarColorHSV[1];
hsv[2] = clamp(customSeekbarColorHSV[2] + brightnessDifference, 0, 1); hsv[2] = clamp(customSeekbarColorHSV[2] + brightnessDifference, 0, 1);
final int replacementAlpha = clamp(Color.alpha(seekbarColor) + alphaDifference, 0, 255); final int replacementAlpha = clamp(Color.alpha(customSeekbarColor) + alphaDifference, 0, 255);
final int replacementColor = Color.HSVToColor(replacementAlpha, hsv); final int replacementColor = Color.HSVToColor(replacementAlpha, hsv);
Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X", Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X",
originalColor, replacementColor)); originalColor, replacementColor));

View File

@ -27,6 +27,8 @@ import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehavi
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE;
import android.graphics.Color;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.shared.settings.BooleanSetting;
@ -267,18 +269,19 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE); public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);
// Seekbar // Seekbar
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", FALSE);
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE);
public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true); public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true);
public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE, true); public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE, true);
public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE); public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE); public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true); public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", FALSE);
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true, public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
"revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability()); "revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true); public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
public static final StringSetting SEEKBAR_CUSTOM_COLOR_VALUE = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR)); public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
private static final StringSetting DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033");
public static final StringSetting SEEKBAR_CUSTOM_COLOR_PRIMARY = new StringSetting("revanced_seekbar_custom_color_primary", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR));
public static final StringSetting SEEKBAR_CUSTOM_COLOR_ACCENT = new StringSetting("revanced_seekbar_custom_color_accent", "#FF2791", true, parent(SEEKBAR_CUSTOM_COLOR));
// Misc // Misc
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE); public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
@ -406,6 +409,30 @@ public class Settings extends BaseSettings {
MINIPLAYER_TYPE.save(MINIMAL); MINIPLAYER_TYPE.save(MINIMAL);
} }
// Migrate old single color seekbar with a slightly brighter accent color based on the primary.
// Eventually delete this logic.
if (!DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.isSetToDefault()) {
try {
String oldPrimaryColorString = DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.get();
final int oldPrimaryColor = Color.parseColor(oldPrimaryColorString);
SEEKBAR_CUSTOM_COLOR_PRIMARY.save(oldPrimaryColorString);
final float brightnessScale = 1.3f;
final int accentColor = Color.argb(
0, // Save without alpha channel.
Math.min(255, (int) (brightnessScale * Color.red(oldPrimaryColor))),
Math.min(255, (int) (brightnessScale * Color.green(oldPrimaryColor))),
Math.min(255, (int) (brightnessScale * Color.blue(oldPrimaryColor)))
);
SEEKBAR_CUSTOM_COLOR_ACCENT.save(String.format("#%06X", accentColor));
} catch (Exception ex) {
Logger.printException(() -> "Could not parse old seekbar color", ex);
}
DEPRECATED_SEEKBAR_CUSTOM_COLOR_PRIMARY.resetToDefault();
}
// endregion // endregion
// region SB import/export callbacks // region SB import/export callbacks

View File

@ -200,25 +200,27 @@ val seekbarColorPatch = bytecodePatch(
) )
execute { execute {
fun MutableMethod.addColorChangeInstructions(resourceId: Long) { fun MutableMethod.addColorChangeInstructions(resourceId: Long, methodName: String) {
val registerIndex = indexOfFirstLiteralInstructionOrThrow(resourceId) + 2 val index = indexOfFirstLiteralInstructionOrThrow(resourceId)
val colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(
registerIndex + 1, insertIndex + 1,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$methodName(I)I
move-result v$register
""" """
invoke-static { v$colorRegister }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
move-result v$colorRegister
""",
) )
} }
playerSeekbarColorFingerprint.method.apply { playerSeekbarColorFingerprint.method.apply {
addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId) addColorChangeInstructions(inlineTimeBarColorizedBarPlayedColorDarkId, "getVideoPlayerSeekbarColor")
addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId) addColorChangeInstructions(inlineTimeBarPlayedNotHighlightedColorId, "getVideoPlayerSeekbarColor")
} }
shortsSeekbarColorFingerprint.method.apply { shortsSeekbarColorFingerprint.method.apply {
addColorChangeInstructions(reelTimeBarPlayedColorId) addColorChangeInstructions(reelTimeBarPlayedColorId, "getVideoPlayerSeekbarColor")
} }
setSeekbarClickedColorFingerprint.originalMethod.let { setSeekbarClickedColorFingerprint.originalMethod.let {
@ -245,17 +247,7 @@ val seekbarColorPatch = bytecodePatch(
// 19.25+ changes // 19.25+ changes
playerSeekbarHandleColorFingerprint.method.apply { playerSeekbarHandleColorFingerprint.method.apply {
val index = indexOfFirstLiteralInstructionOrThrow(ytStaticBrandRedId) addColorChangeInstructions(ytStaticBrandRedId, "getVideoPlayerSeekbarColor")
val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions(
insertIndex + 1,
"""
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getSeekbarScrubHandleColor(I)I
move-result v$register
"""
)
} }
// If hiding feed seekbar thumbnails, then turn off the cairo gradient // If hiding feed seekbar thumbnails, then turn off the cairo gradient
@ -280,9 +272,12 @@ val seekbarColorPatch = bytecodePatch(
} }
} }
lithoLinearGradientFingerprint.method.addInstruction( lithoLinearGradientFingerprint.method.addInstructions(
0, 0,
"invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->setLinearGradient([I[F)V" """
invoke-static/range { p4 .. p5 }, $EXTENSION_CLASS_DESCRIPTOR->getLithoLinearGradient([I[F)[I
move-result-object p4
"""
) )
val playerFingerprint = val playerFingerprint =
@ -302,7 +297,7 @@ val seekbarColorPatch = bytecodePatch(
addInstructions( addInstructions(
index + 1, index + 1,
""" """
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getLinearGradient([I)[I invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerLinearGradient([I)[I
move-result-object v$register move-result-object v$register
""" """
) )

View File

@ -13,6 +13,8 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch import app.revanced.patches.youtube.layout.seekbar.seekbarColorPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.settings.settingsPatch
import app.revanced.util.forEachChildElement import app.revanced.util.forEachChildElement
@ -71,6 +73,7 @@ val themePatch = bytecodePatch(
dependsOn( dependsOn(
lithoColorHookPatch, lithoColorHookPatch,
seekbarColorPatch, seekbarColorPatch,
versionCheckPatch,
resourcePatch { resourcePatch {
dependsOn( dependsOn(
settingsPatch, settingsPatch,
@ -83,9 +86,15 @@ val themePatch = bytecodePatch(
PreferenceScreen.SEEKBAR.addPreferences( PreferenceScreen.SEEKBAR.addPreferences(
SwitchPreference("revanced_seekbar_custom_color"), SwitchPreference("revanced_seekbar_custom_color"),
TextPreference("revanced_seekbar_custom_color_value", inputType = InputType.TEXT_CAP_CHARACTERS), TextPreference("revanced_seekbar_custom_color_primary", inputType = InputType.TEXT_CAP_CHARACTERS),
) )
if (is_19_25_or_greater) {
PreferenceScreen.SEEKBAR.addPreferences(
TextPreference("revanced_seekbar_custom_color_accent", inputType = InputType.TEXT_CAP_CHARACTERS),
)
}
// Edit theme colors via resources. // Edit theme colors via resources.
document("res/values/colors.xml").use { document -> document("res/values/colors.xml").use { document ->

View File

@ -1223,8 +1223,10 @@ Swipe to expand or close"</string>
<string name="revanced_seekbar_custom_color_title">Enable custom seekbar color</string> <string name="revanced_seekbar_custom_color_title">Enable custom seekbar color</string>
<string name="revanced_seekbar_custom_color_summary_on">Custom seekbar color is shown</string> <string name="revanced_seekbar_custom_color_summary_on">Custom seekbar color is shown</string>
<string name="revanced_seekbar_custom_color_summary_off">Original seekbar color is shown</string> <string name="revanced_seekbar_custom_color_summary_off">Original seekbar color is shown</string>
<string name="revanced_seekbar_custom_color_value_title">Custom seekbar color</string> <string name="revanced_seekbar_custom_color_primary_title">Custom seekbar color</string>
<string name="revanced_seekbar_custom_color_value_summary">The color of the seekbar</string> <string name="revanced_seekbar_custom_color_primary_summary">The color of the seekbar</string>
<string name="revanced_seekbar_custom_color_accent_title">Custom seekbar accent color</string>
<string name="revanced_seekbar_custom_color_accent_summary">The accent color of the seekbar</string>
<string name="revanced_seekbar_custom_color_invalid">Invalid seekbar color value</string> <string name="revanced_seekbar_custom_color_invalid">Invalid seekbar color value</string>
</patch> </patch>
<patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch"> <patch id="layout.thumbnails.bypassImageRegionRestrictionsPatch">