Skip to content

Commit

Permalink
feat(YouTube - Theme): Add option to use custom seekbar accent color (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
LisoUseInAIKyrios authored Jan 23, 2025
1 parent e69197c commit 952b4fc
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,23 @@
@SuppressWarnings("unused")
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.
*/
public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
if (value && BaseSettings.DEBUG.get()) {
if (LOG_FEATURE_FLAGS && value) {
if (featureFlags.putIfAbsent(flag, true) == null) {
Logger.printDebug(() -> "boolean feature is enabled: " + flag);
}
Expand All @@ -29,7 +38,7 @@ public static boolean isBooleanFeatureFlagEnabled(boolean value, long flag) {
* Injection point.
*/
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) {
// Align the log outputs to make post processing easier.
Logger.printDebug(() -> " double feature is enabled: " + flag
Expand All @@ -44,7 +53,7 @@ public static double isDoubleFeatureFlagEnabled(double value, long flag, double
* Injection point.
*/
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) {
Logger.printDebug(() -> " long feature is enabled: " + flag
+ " value: " + value + (defaultValue == 0 ? "" : " default: " + defaultValue));
Expand All @@ -58,7 +67,7 @@ public static long isLongFeatureFlagEnabled(long value, long flag, long defaultV
* Injection point.
*/
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) {
Logger.printDebug(() -> " string feature is enabled: " + flag
+ " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ public final class SeekbarColorPatch {
*/
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.
*/
private static final float ORIGINAL_SEEKBAR_COLOR_BRIGHTNESS;

/**
* 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}.
*/
private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR;
private static int customSeekbarColor = ORIGINAL_SEEKBAR_COLOR;

/**
* Custom seekbar hue, saturation, and brightness values.
Expand All @@ -56,7 +61,7 @@ public final class SeekbarColorPatch {
/**
* 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 {
float[] hsv = new float[3];
Expand All @@ -65,24 +70,27 @@ public final class SeekbarColorPatch {

if (SEEKBAR_CUSTOM_COLOR_ENABLED) {
loadCustomSeekbarColor();

Arrays.fill(customSeekbarColorInt, seekbarColor);
}
}

private static void loadCustomSeekbarColor() {
try {
seekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_VALUE.get());
Color.colorToHSV(seekbarColor, customSeekbarColorHSV);
customSeekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_PRIMARY.get());
Color.colorToHSV(customSeekbarColor, customSeekbarColorHSV);

customSeekbarColorGradient[0] = customSeekbarColor;
customSeekbarColorGradient[1] = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_ACCENT.get());
} catch (Exception ex) {
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();
}
}

public static int getSeekbarColor() {
return seekbarColor;
return customSeekbarColor;
}

/**
Expand Down Expand Up @@ -126,7 +134,7 @@ public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vector
// 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.
try {
String seekbarStyle = get9BitStyleIdentifier(seekbarColor);
String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor);
Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle);

final int styleIdentifierDefault = Utils.getResourceIdentifier(
Expand All @@ -153,15 +161,6 @@ public static boolean showWatchHistoryProgressDrawable(boolean original) {
return !HIDE_SEEKBAR_THUMBNAIL_ENABLED && original;
}

/**
* Injection point.
*/
public static int getSeekbarScrubHandleColor(int colorValue) {
return SEEKBAR_CUSTOM_COLOR_ENABLED
? seekbarColor
: colorValue;
}

/**
* Injection point.
*
Expand All @@ -173,21 +172,13 @@ public static int getSeekbarScrubHandleColor(int colorValue) {
public static int getLithoColor(int colorValue) {
if (colorValue == ORIGINAL_SEEKBAR_COLOR) {
if (HIDE_SEEKBAR_THUMBNAIL_ENABLED) {
return 0x00000000;
return 0x0;
}

return getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR);
return customSeekbarColor;
}
return colorValue;
}

/**
* Injection point.
*/
public static int[] getLinearGradient(int[] original) {
return SEEKBAR_CUSTOM_COLOR_ENABLED
? customSeekbarColorInt
: original;
return colorValue;
}

private static String colorArrayToHex(int[] colors) {
Expand All @@ -210,21 +201,31 @@ private static String colorArrayToHex(int[] colors) {
/**
* 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) {
// Most litho usage of linear gradients is hooked here,
// so must only change if the values are those for the seekbar.
if ((Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_COLORS, colors)
&& Arrays.equals(FEED_ORIGINAL_SEEKBAR_GRADIENT_POSITIONS, positions))) {
Arrays.fill(colors, HIDE_SEEKBAR_THUMBNAIL_ENABLED
? 0x00000000
: seekbarColor);
return;
return HIDE_SEEKBAR_THUMBNAIL_ENABLED
? HIDDEN_SEEKBAR_GRADIENT_COLORS
: customSeekbarColorGradient;
}

Logger.printDebug(() -> "Ignoring gradient colors: " + colorArrayToHex(colors)
+ " positions: " + Arrays.toString(positions));
}

return colors;
}

/**
Expand All @@ -238,7 +239,7 @@ public static int getVideoPlayerSeekbarClickedColor(int colorValue) {
}

return colorValue == ORIGINAL_SEEKBAR_COLOR
? getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR)
? customSeekbarColor
: colorValue;
}

Expand All @@ -248,11 +249,9 @@ public static int getVideoPlayerSeekbarClickedColor(int colorValue) {
* Overrides color used for the video player seekbar.
*/
public static int getVideoPlayerSeekbarColor(int originalColor) {
if (!SEEKBAR_CUSTOM_COLOR_ENABLED) {
return originalColor;
}

return getSeekbarColorValue(originalColor);
return SEEKBAR_CUSTOM_COLOR_ENABLED
? getSeekbarColorValue(originalColor)
: originalColor;
}

/**
Expand All @@ -261,10 +260,6 @@ public static int getVideoPlayerSeekbarColor(int originalColor) {
*/
private static int getSeekbarColorValue(int originalColor) {
try {
if (!SEEKBAR_CUSTOM_COLOR_ENABLED || originalColor == seekbarColor) {
return originalColor; // nothing to do
}

final int alphaDifference = Color.alpha(originalColor) - Color.alpha(ORIGINAL_SEEKBAR_COLOR);

// The seekbar uses the same color but different brightness for different situations.
Expand All @@ -277,7 +272,7 @@ private static int getSeekbarColorValue(int originalColor) {
hsv[1] = customSeekbarColorHSV[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);
Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X",
originalColor, replacementColor));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
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.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
Expand Down Expand Up @@ -267,18 +269,19 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);

// Seekbar

public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE);
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", FALSE);
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_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 SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", FALSE);
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());
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
public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
Expand Down Expand Up @@ -406,6 +409,30 @@ public class Settings extends BaseSettings {
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

// region SB import/export callbacks
Expand Down
Loading

0 comments on commit 952b4fc

Please sign in to comment.