feat(YouTube - Swipe controls): Add option for vertical progress bar (#4811)

This commit is contained in:
MarcaD 2025-04-23 14:30:41 +03:00 committed by GitHub
parent 81999d8cd5
commit ebee07ec3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 536 additions and 169 deletions

View file

@ -342,9 +342,12 @@ public abstract class Setting<T> {
/** /**
* Identical to calling {@link #save(Object)} using {@link #defaultValue}. * Identical to calling {@link #save(Object)} using {@link #defaultValue}.
*
* @return The newly saved default value.
*/ */
public void resetToDefault() { public T resetToDefault() {
save(defaultValue); save(defaultValue);
return defaultValue;
} }
/** /**

View file

@ -17,8 +17,7 @@ public class CustomPlayerOverlayOpacityPatch {
if (opacity < 0 || opacity > 100) { if (opacity < 0 || opacity > 100) {
Utils.showToastLong(str("revanced_player_overlay_opacity_invalid_toast")); Utils.showToastLong(str("revanced_player_overlay_opacity_invalid_toast"));
Settings.PLAYER_OVERLAY_OPACITY.resetToDefault(); opacity = Settings.PLAYER_OVERLAY_OPACITY.resetToDefault();
opacity = Settings.PLAYER_OVERLAY_OPACITY.defaultValue;
} }
PLAYER_OVERLAY_OPACITY_LEVEL = (opacity * 255) / 100; PLAYER_OVERLAY_OPACITY_LEVEL = (opacity * 255) / 100;

View file

@ -162,8 +162,7 @@ public final class MiniplayerPatch {
if (opacity < 0 || opacity > 100) { if (opacity < 0 || opacity > 100) {
Utils.showToastLong(str("revanced_miniplayer_opacity_invalid_toast")); Utils.showToastLong(str("revanced_miniplayer_opacity_invalid_toast"));
Settings.MINIPLAYER_OPACITY.resetToDefault(); opacity = Settings.MINIPLAYER_OPACITY.resetToDefault();
opacity = Settings.MINIPLAYER_OPACITY.defaultValue;
} }
OPACITY_LEVEL = (opacity * 255) / 100; OPACITY_LEVEL = (opacity * 255) / 100;

View file

@ -54,12 +54,12 @@ public class CustomPlaybackSpeedPatch {
static { static {
final float holdSpeed = Settings.SPEED_TAP_AND_HOLD.get(); final float holdSpeed = Settings.SPEED_TAP_AND_HOLD.get();
if (holdSpeed > 0 && holdSpeed <= PLAYBACK_SPEED_MAXIMUM) { if (holdSpeed > 0 && holdSpeed <= PLAYBACK_SPEED_MAXIMUM) {
TAP_AND_HOLD_SPEED = holdSpeed; TAP_AND_HOLD_SPEED = holdSpeed;
} else { } else {
showInvalidCustomSpeedToast(); showInvalidCustomSpeedToast();
Settings.SPEED_TAP_AND_HOLD.resetToDefault(); TAP_AND_HOLD_SPEED = Settings.SPEED_TAP_AND_HOLD.resetToDefault();
TAP_AND_HOLD_SPEED = Settings.SPEED_TAP_AND_HOLD.get();
} }
loadCustomSpeeds(); loadCustomSpeeds();

View file

@ -25,6 +25,7 @@ import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehavi
import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
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 app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider.SwipeOverlayStyle;
import android.graphics.Color; import android.graphics.Color;
@ -323,12 +324,14 @@ public class Settings extends BaseSettings {
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true, public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_VOLUME_SENSITIVITY = new IntegerSetting("revanced_swipe_volume_sensitivity", 1, true, parent(SWIPE_VOLUME)); public static final IntegerSetting SWIPE_VOLUME_SENSITIVITY = new IntegerSetting("revanced_swipe_volume_sensitivity", 1, true, parent(SWIPE_VOLUME));
public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true, public static final EnumSetting<SwipeOverlayStyle> SWIPE_OVERLAY_STYLE = new EnumSetting<>("revanced_swipe_overlay_style", SwipeOverlayStyle.HORIZONTAL,true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true, public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 14, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_OVERLAY_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 60, true, public static final IntegerSetting SWIPE_OVERLAY_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 60, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final StringSetting SWIPE_OVERLAY_PROGRESS_COLOR = new StringSetting("revanced_swipe_overlay_progress_color", "#FFFFFF", true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true, public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final BooleanSetting SWIPE_SAVE_AND_RESTORE_BRIGHTNESS = new BooleanSetting("revanced_swipe_save_and_restore_brightness", TRUE, true, parent(SWIPE_BRIGHTNESS)); public static final BooleanSetting SWIPE_SAVE_AND_RESTORE_BRIGHTNESS = new BooleanSetting("revanced_swipe_save_and_restore_brightness", TRUE, true, parent(SWIPE_BRIGHTNESS));

View file

@ -1,95 +1,98 @@
package app.revanced.extension.youtube.swipecontrols package app.revanced.extension.youtube.swipecontrols
import android.annotation.SuppressLint
import android.graphics.Color import android.graphics.Color
import app.revanced.extension.shared.Logger
import app.revanced.extension.shared.StringRef.str import app.revanced.extension.shared.StringRef.str
import app.revanced.extension.shared.Utils import app.revanced.extension.shared.Utils
import app.revanced.extension.youtube.settings.Settings import app.revanced.extension.youtube.settings.Settings
import app.revanced.extension.youtube.shared.PlayerType import app.revanced.extension.youtube.shared.PlayerType
/** /**
* provider for configuration for volume and brightness swipe controls * Provides configuration settings for volume and brightness swipe controls in the YouTube player.
* Manages enabling/disabling gestures, overlay appearance, and behavior preferences.
*/ */
class SwipeControlsConfigurationProvider { class SwipeControlsConfigurationProvider {
//region swipe enable //region swipe enable
/** /**
* should swipe controls be enabled? (global setting) * Indicates whether swipe controls are enabled globally.
* Returns true if either volume or brightness controls are enabled and the video is in fullscreen mode.
*/ */
val enableSwipeControls: Boolean val enableSwipeControls: Boolean
get() = (enableVolumeControls || enableBrightnessControl) && isFullscreenVideo get() = (enableVolumeControls || enableBrightnessControl) && isFullscreenVideo
/** /**
* should swipe controls for volume be enabled? * Indicates whether swipe controls for adjusting volume are enabled.
*/ */
val enableVolumeControls = Settings.SWIPE_VOLUME.get() val enableVolumeControls = Settings.SWIPE_VOLUME.get()
/** /**
* should swipe controls for volume be enabled? * Indicates whether swipe controls for adjusting brightness are enabled.
*/ */
val enableBrightnessControl = Settings.SWIPE_BRIGHTNESS.get() val enableBrightnessControl = Settings.SWIPE_BRIGHTNESS.get()
/** /**
* is the video player currently in fullscreen mode? * Checks if the video player is currently in fullscreen mode.
*/ */
private val isFullscreenVideo: Boolean private val isFullscreenVideo: Boolean
get() = PlayerType.current == PlayerType.WATCH_WHILE_FULLSCREEN get() = PlayerType.current == PlayerType.WATCH_WHILE_FULLSCREEN
//endregion //endregion
//region keys enable //region keys enable
/** /**
* should volume key controls be overwritten? (global setting) * Indicates whether volume key controls should be overridden by swipe controls.
* Returns true if volume controls are enabled and the video is in fullscreen mode.
*/ */
val overwriteVolumeKeyControls: Boolean val overwriteVolumeKeyControls: Boolean
get() = enableVolumeControls && isFullscreenVideo get() = enableVolumeControls && isFullscreenVideo
//endregion //endregion
//region gesture adjustments //region gesture adjustments
/** /**
* should press-to-swipe be enabled? * Indicates whether press-to-swipe mode is enabled, requiring a press before swiping to activate controls.
*/ */
val shouldEnablePressToSwipe: Boolean val shouldEnablePressToSwipe: Boolean
get() = Settings.SWIPE_PRESS_TO_ENGAGE.get() get() = Settings.SWIPE_PRESS_TO_ENGAGE.get()
/** /**
* threshold for swipe detection * The threshold for detecting swipe gestures, in pixels.
* this may be called rapidly in onScroll, so we have to load it once and then leave it constant * Loaded once to ensure consistent behavior during rapid scroll events.
*/ */
val swipeMagnitudeThreshold: Int val swipeMagnitudeThreshold: Int
get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get() get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get()
/** /**
* How much volume will change by single swipe. * The sensitivity of volume swipe gestures, determining how much volume changes per swipe.
* If it is set to 0, it will reset to the default value because 0 would disable swiping. * Resets to default if set to 0, as it would disable swiping.
* */ */
val volumeSwipeSensitivity: Int val volumeSwipeSensitivity: Int
get() { get() {
val sensitivity = Settings.SWIPE_VOLUME_SENSITIVITY.get() val sensitivity = Settings.SWIPE_VOLUME_SENSITIVITY.get()
if (sensitivity < 1) { if (sensitivity < 1) {
Settings.SWIPE_VOLUME_SENSITIVITY.resetToDefault() return Settings.SWIPE_VOLUME_SENSITIVITY.resetToDefault()
return Settings.SWIPE_VOLUME_SENSITIVITY.get()
} }
return sensitivity return sensitivity
} }
//endregion //endregion
//region overlay adjustments //region overlay adjustments
/** /**
* should the overlay enable haptic feedback? * Indicates whether haptic feedback should be enabled for swipe control interactions.
*/ */
val shouldEnableHapticFeedback: Boolean val shouldEnableHapticFeedback: Boolean
get() = Settings.SWIPE_HAPTIC_FEEDBACK.get() get() = Settings.SWIPE_HAPTIC_FEEDBACK.get()
/** /**
* how long the overlay should be shown on changes * The duration in milliseconds that the overlay should remain visible after a change.
*/ */
val overlayShowTimeoutMillis: Long val overlayShowTimeoutMillis: Long
get() = Settings.SWIPE_OVERLAY_TIMEOUT.get() get() = Settings.SWIPE_OVERLAY_TIMEOUT.get()
/** /**
* Gets the opacity value (0-100%) is converted to an alpha value (0-255) for transparency. * The background opacity of the overlay, converted from a percentage (0-100) to an alpha value (0-255).
* If the opacity value is out of range, it resets to the default and displays a warning message. * Resets to default and shows a toast if the value is out of range.
*/ */
val overlayBackgroundOpacity: Int val overlayBackgroundOpacity: Int
get() { get() {
@ -97,8 +100,7 @@ class SwipeControlsConfigurationProvider {
if (opacity < 0 || opacity > 100) { if (opacity < 0 || opacity > 100) {
Utils.showToastLong(str("revanced_swipe_overlay_background_opacity_invalid_toast")) Utils.showToastLong(str("revanced_swipe_overlay_background_opacity_invalid_toast"))
Settings.SWIPE_OVERLAY_OPACITY.resetToDefault() opacity = Settings.SWIPE_OVERLAY_OPACITY.resetToDefault()
opacity = Settings.SWIPE_OVERLAY_OPACITY.get()
} }
opacity = opacity * 255 / 100 opacity = opacity * 255 / 100
@ -106,55 +108,125 @@ class SwipeControlsConfigurationProvider {
} }
/** /**
* The color of the progress overlay. * The color of the progress bar in the overlay.
* Resets to default and shows a toast if the color string is invalid or empty.
*/ */
val overlayProgressColor: Int val overlayProgressColor: Int
get() = 0xBFFFFFFF.toInt() get() {
try {
@SuppressLint("UseKtx")
val color = Color.parseColor(Settings.SWIPE_OVERLAY_PROGRESS_COLOR.get())
return (0xBF000000.toInt() or (color and 0xFFFFFF))
} catch (ex: IllegalArgumentException) {
Logger.printDebug({ "Could not parse color" }, ex)
Utils.showToastLong(str("revanced_swipe_overlay_progress_color_invalid_toast"))
Settings.SWIPE_OVERLAY_PROGRESS_COLOR.resetToDefault()
return overlayProgressColor // Recursively return.
}
}
/** /**
* The color used for the background of the progress overlay fill. * The background color used for the filled portion of the progress bar in the overlay.
*/ */
val overlayFillBackgroundPaint: Int val overlayFillBackgroundPaint: Int
get() = 0x80D3D3D3.toInt() get() = 0x80D3D3D3.toInt()
/** /**
* The color used for the text and icons in the overlay. * The color used for text and icons in the overlay.
*/ */
val overlayTextColor: Int val overlayTextColor: Int
get() = Color.WHITE get() = Color.WHITE
/** /**
* A flag that determines if the overlay should only show the icon. * The text size in the overlay, in density-independent pixels (dp).
* Must be between 1 and 30 dp; resets to default and shows a toast if invalid.
*/ */
val overlayShowOverlayMinimalStyle: Boolean val overlayTextSize: Int
get() = Settings.SWIPE_OVERLAY_MINIMAL_STYLE.get() get() {
val size = Settings.SWIPE_OVERLAY_TEXT_SIZE.get()
if (size < 1 || size > 30) {
Utils.showToastLong(str("revanced_swipe_text_overlay_size_invalid_toast"))
return Settings.SWIPE_OVERLAY_TEXT_SIZE.resetToDefault()
}
return size
}
/** /**
* A flag that determines if the progress bar should be circular. * Defines the style of the swipe controls overlay, determining its layout and appearance.
*
* @property isMinimal Indicates whether the style is minimalistic, omitting detailed progress indicators.
* @property isHorizontalMinimalCenter Indicates whether the style is a minimal horizontal bar centered vertically.
* @property isCircular Indicates whether the style uses a circular progress bar.
* @property isVertical Indicates whether the style uses a vertical progress bar.
*/ */
val isCircularProgressBar: Boolean @Suppress("unused")
get() = Settings.SWIPE_SHOW_CIRCULAR_OVERLAY.get() enum class SwipeOverlayStyle(
//endregion val isMinimal: Boolean = false,
val isHorizontalMinimalCenter: Boolean = false,
val isCircular: Boolean = false,
val isVertical: Boolean = false
) {
/**
* A full horizontal progress bar with detailed indicators.
*/
HORIZONTAL,
//region behaviour /**
* A minimal horizontal progress bar positioned at the top.
*/
HORIZONTAL_MINIMAL_TOP(isMinimal = true),
/**
* A minimal horizontal progress bar centered vertically.
*/
HORIZONTAL_MINIMAL_CENTER(isMinimal = true, isHorizontalMinimalCenter = true),
/**
* A full circular progress bar with detailed indicators.
*/
CIRCULAR(isCircular = true),
/**
* A minimal circular progress bar.
*/
CIRCULAR_MINIMAL(isMinimal = true, isCircular = true),
/**
* A full vertical progress bar with detailed indicators.
*/
VERTICAL(isVertical = true),
/**
* A minimal vertical progress bar.
*/
VERTICAL_MINIMAL(isMinimal = true, isVertical = true)
}
/** /**
* should the brightness be saved and restored when exiting or entering fullscreen * The current style of the overlay, determining its layout and appearance.
*/
val overlayStyle: SwipeOverlayStyle
get() = Settings.SWIPE_OVERLAY_STYLE.get()
//endregion
//region behaviour
/**
* Indicates whether the brightness level should be saved and restored when entering or exiting fullscreen mode.
*/ */
val shouldSaveAndRestoreBrightness: Boolean val shouldSaveAndRestoreBrightness: Boolean
get() = Settings.SWIPE_SAVE_AND_RESTORE_BRIGHTNESS.get() get() = Settings.SWIPE_SAVE_AND_RESTORE_BRIGHTNESS.get()
/** /**
* should auto-brightness be enabled at the lowest value of the brightness gesture * Indicates whether auto-brightness should be enabled when the brightness gesture reaches its lowest value.
*/ */
val shouldLowestValueEnableAutoBrightness: Boolean val shouldLowestValueEnableAutoBrightness: Boolean
get() = Settings.SWIPE_LOWEST_VALUE_ENABLE_AUTO_BRIGHTNESS.get() get() = Settings.SWIPE_LOWEST_VALUE_ENABLE_AUTO_BRIGHTNESS.get()
/** /**
* variable that stores the brightness gesture value in the settings * The saved brightness value for the swipe gesture, used to restore brightness in fullscreen mode.
*/ */
var savedScreenBrightnessValue: Float var savedScreenBrightnessValue: Float
get() = Settings.SWIPE_BRIGHTNESS_VALUE.get() get() = Settings.SWIPE_BRIGHTNESS_VALUE.get()
set(value) = Settings.SWIPE_BRIGHTNESS_VALUE.save(value) set(value) = Settings.SWIPE_BRIGHTNESS_VALUE.save(value)
//endregion //endregion
} }

View file

@ -23,9 +23,7 @@ import java.lang.ref.WeakReference
/** /**
* The main controller for volume and brightness swipe controls. * The main controller for volume and brightness swipe controls.
* note that the superclass is overwritten to the superclass of the MainActivity at patch time * note that the superclass is overwritten to the superclass of the MainActivity at patch time.
*
* @smali Lapp/revanced/extension/swipecontrols/SwipeControlsHostActivity;
*/ */
class SwipeControlsHostActivity : Activity() { class SwipeControlsHostActivity : Activity() {
/** /**

View file

@ -1,8 +1,11 @@
package app.revanced.extension.youtube.swipecontrols.views package app.revanced.extension.youtube.swipecontrols.views
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.res.Resources
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.Paint import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF import android.graphics.RectF
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Handler import android.os.Handler
@ -11,14 +14,23 @@ import android.util.AttributeSet
import android.view.HapticFeedbackConstants import android.view.HapticFeedbackConstants
import android.view.View import android.view.View
import android.widget.RelativeLayout import android.widget.RelativeLayout
import app.revanced.extension.shared.StringRef.str
import app.revanced.extension.shared.Utils import app.revanced.extension.shared.Utils
import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider
import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay
import kotlin.math.min import kotlin.math.min
import kotlin.math.max
import kotlin.math.round import kotlin.math.round
/** /**
* Main overlay layout for displaying volume and brightness level with both circular and horizontal progress bars. * Convert dp to pixels based on system display density.
*/
fun Float.toDisplayPixels(): Float {
return this * Resources.getSystem().displayMetrics.density
}
/**
* Main overlay layout for displaying volume and brightness level with circular, horizontal and vertical progress bars.
*/ */
class SwipeControlsOverlayLayout( class SwipeControlsOverlayLayout(
context: Context, context: Context,
@ -51,18 +63,21 @@ class SwipeControlsOverlayLayout(
// Initialize progress bars // Initialize progress bars
private val circularProgressView: CircularProgressView private val circularProgressView: CircularProgressView
private val horizontalProgressView: HorizontalProgressView private val horizontalProgressView: HorizontalProgressView
private val verticalBrightnessProgressView: VerticalProgressView
private val verticalVolumeProgressView: VerticalProgressView
init { init {
// Initialize circular progress bar // Initialize circular progress bar
circularProgressView = CircularProgressView( circularProgressView = CircularProgressView(
context, context,
config.overlayBackgroundOpacity, config.overlayBackgroundOpacity,
config.overlayShowOverlayMinimalStyle, config.overlayStyle.isMinimal,
config.overlayProgressColor, config.overlayProgressColor,
config.overlayFillBackgroundPaint, config.overlayFillBackgroundPaint,
config.overlayTextColor config.overlayTextColor,
config.overlayTextSize
).apply { ).apply {
layoutParams = LayoutParams(300, 300).apply { layoutParams = LayoutParams(100f.toDisplayPixels().toInt(), 100f.toDisplayPixels().toInt()).apply {
addRule(CENTER_IN_PARENT, TRUE) addRule(CENTER_IN_PARENT, TRUE)
} }
visibility = GONE // Initially hidden visibility = GONE // Initially hidden
@ -71,22 +86,65 @@ class SwipeControlsOverlayLayout(
// Initialize horizontal progress bar // Initialize horizontal progress bar
val screenWidth = resources.displayMetrics.widthPixels val screenWidth = resources.displayMetrics.widthPixels
val layoutWidth = (screenWidth * 2 / 3).toInt() // 2/3 of screen width val layoutWidth = (screenWidth * 4 / 5).toInt() // Cap at ~360dp
horizontalProgressView = HorizontalProgressView( horizontalProgressView = HorizontalProgressView(
context, context,
config.overlayBackgroundOpacity, config.overlayBackgroundOpacity,
config.overlayShowOverlayMinimalStyle, config.overlayStyle.isMinimal,
config.overlayProgressColor, config.overlayProgressColor,
config.overlayFillBackgroundPaint, config.overlayFillBackgroundPaint,
config.overlayTextColor config.overlayTextColor,
config.overlayTextSize
).apply { ).apply {
layoutParams = LayoutParams(layoutWidth, 100).apply { layoutParams = LayoutParams(layoutWidth, 32f.toDisplayPixels().toInt()).apply {
addRule(CENTER_HORIZONTAL) addRule(CENTER_HORIZONTAL)
topMargin = 40 // Top margin if (config.overlayStyle.isHorizontalMinimalCenter) {
addRule(CENTER_VERTICAL)
} else {
topMargin = 20f.toDisplayPixels().toInt()
}
} }
visibility = GONE // Initially hidden visibility = GONE // Initially hidden
} }
addView(horizontalProgressView) addView(horizontalProgressView)
// Initialize vertical progress bar for brightness (right side)
verticalBrightnessProgressView = VerticalProgressView(
context,
config.overlayBackgroundOpacity,
config.overlayStyle.isMinimal,
config.overlayProgressColor,
config.overlayFillBackgroundPaint,
config.overlayTextColor,
config.overlayTextSize
).apply {
layoutParams = LayoutParams(40f.toDisplayPixels().toInt(), 150f.toDisplayPixels().toInt()).apply {
addRule(ALIGN_PARENT_RIGHT)
rightMargin = 40f.toDisplayPixels().toInt()
addRule(CENTER_VERTICAL)
}
visibility = GONE // Initially hidden
}
addView(verticalBrightnessProgressView)
// Initialize vertical progress bar for volume (left side)
verticalVolumeProgressView = VerticalProgressView(
context,
config.overlayBackgroundOpacity,
config.overlayStyle.isMinimal,
config.overlayProgressColor,
config.overlayFillBackgroundPaint,
config.overlayTextColor,
config.overlayTextSize
).apply {
layoutParams = LayoutParams(40f.toDisplayPixels().toInt(), 150f.toDisplayPixels().toInt()).apply {
addRule(ALIGN_PARENT_LEFT)
leftMargin = 40f.toDisplayPixels().toInt()
addRule(CENTER_VERTICAL)
}
visibility = GONE // Initially hidden
}
addView(verticalVolumeProgressView)
} }
// Handler and callback for hiding progress bars // Handler and callback for hiding progress bars
@ -94,6 +152,8 @@ class SwipeControlsOverlayLayout(
private val feedbackHideCallback = Runnable { private val feedbackHideCallback = Runnable {
circularProgressView.visibility = GONE circularProgressView.visibility = GONE
horizontalProgressView.visibility = GONE horizontalProgressView.visibility = GONE
verticalBrightnessProgressView.visibility = GONE
verticalVolumeProgressView.visibility = GONE
} }
/** /**
@ -103,7 +163,11 @@ class SwipeControlsOverlayLayout(
feedbackHideHandler.removeCallbacks(feedbackHideCallback) feedbackHideHandler.removeCallbacks(feedbackHideCallback)
feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis) feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis)
val viewToShow = if (config.isCircularProgressBar) circularProgressView else horizontalProgressView val viewToShow = when {
config.overlayStyle.isCircular -> circularProgressView
config.overlayStyle.isVertical -> if (isBrightness) verticalBrightnessProgressView else verticalVolumeProgressView
else -> horizontalProgressView
}
viewToShow.apply { viewToShow.apply {
setProgress(progress, max, value, isBrightness) setProgress(progress, max, value, isBrightness)
this.icon = icon this.icon = icon
@ -126,7 +190,9 @@ class SwipeControlsOverlayLayout(
// Handle brightness change // Handle brightness change
override fun onBrightnessChanged(brightness: Double) { override fun onBrightnessChanged(brightness: Double) {
if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) { if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) {
showFeedbackView("Auto", 0, 100, autoBrightnessIcon, isBrightness = true) val displayText = if (config.overlayStyle.isVertical) "А"
else str("revanced_swipe_lowest_value_enable_auto_brightness_overlay_text")
showFeedbackView(displayText, 0, 100, autoBrightnessIcon, isBrightness = true)
} else { } else {
val brightnessValue = round(brightness).toInt() val brightnessValue = round(brightness).toInt()
val icon = when { val icon = when {
@ -135,7 +201,8 @@ class SwipeControlsOverlayLayout(
brightnessValue < 75 -> highBrightnessIcon brightnessValue < 75 -> highBrightnessIcon
else -> fullBrightnessIcon else -> fullBrightnessIcon
} }
showFeedbackView("$brightnessValue%", brightnessValue, 100, icon, isBrightness = true) val displayText = if (config.overlayStyle.isVertical) "$brightnessValue" else "$brightnessValue%"
showFeedbackView(displayText, brightnessValue, 100, icon, isBrightness = true)
} }
} }
@ -156,11 +223,12 @@ class SwipeControlsOverlayLayout(
*/ */
abstract class AbstractProgressView( abstract class AbstractProgressView(
context: Context, context: Context,
protected val overlayBackgroundOpacity: Int, overlayBackgroundOpacity: Int,
protected val overlayShowOverlayMinimalStyle: Boolean, protected val isMinimalStyle: Boolean,
protected val overlayProgressColor: Int, overlayProgressColor: Int,
protected val overlayFillBackgroundPaint: Int, overlayFillBackgroundPaint: Int,
protected val overlayTextColor: Int, private val overlayTextColor: Int,
protected val overlayTextSize: Int,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) { ) : View(context, attrs, defStyleAttr) {
@ -174,26 +242,25 @@ abstract class AbstractProgressView(
} }
// Initialize paints // Initialize paints
public val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL) val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL)
public val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 20f) val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 6f.toDisplayPixels())
public val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL) val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL)
public val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = overlayTextColor color = overlayTextColor
textAlign = Paint.Align.CENTER textAlign = Paint.Align.CENTER
textSize = 40f // Can adjust based on need textSize = overlayTextSize.toFloat().toDisplayPixels()
} }
// Rect for text measurement
protected val textBounds = Rect()
protected var progress = 0 protected var progress = 0
protected var maxProgress = 100 protected var maxProgress = 100
protected var displayText: String = "0" protected var displayText: String = "0"
protected var isBrightness = true protected var isBrightness = true
public var icon: Drawable? = null var icon: Drawable? = null
init { open fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
// Stroke widths are now set in createPaint for progressPaint and fillBackgroundPaint
}
fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
progress = value progress = value
maxProgress = max maxProgress = max
displayText = text displayText = text
@ -201,6 +268,11 @@ abstract class AbstractProgressView(
invalidate() invalidate()
} }
protected fun measureTextWidth(text: String, paint: Paint): Int {
paint.getTextBounds(text, 0, text.length, textBounds)
return textBounds.width()
}
override fun onDraw(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
// Base class implementation can be empty // Base class implementation can be empty
} }
@ -209,34 +281,36 @@ abstract class AbstractProgressView(
/** /**
* Custom view for rendering a circular progress indicator with icons and text. * Custom view for rendering a circular progress indicator with icons and text.
*/ */
@SuppressLint("ViewConstructor")
class CircularProgressView( class CircularProgressView(
context: Context, context: Context,
overlayBackgroundOpacity: Int, overlayBackgroundOpacity: Int,
overlayShowOverlayMinimalStyle: Boolean, isMinimalStyle: Boolean,
overlayProgressColor: Int, overlayProgressColor: Int,
overlayFillBackgroundPaint: Int, overlayFillBackgroundPaint: Int,
overlayTextColor: Int, overlayTextColor: Int,
overlayTextSize: Int,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : AbstractProgressView( ) : AbstractProgressView(
context, context,
overlayBackgroundOpacity, overlayBackgroundOpacity,
overlayShowOverlayMinimalStyle, isMinimalStyle,
overlayProgressColor, overlayProgressColor,
overlayFillBackgroundPaint, overlayFillBackgroundPaint,
overlayTextColor, overlayTextColor,
overlayTextSize,
attrs, attrs,
defStyleAttr defStyleAttr
) { ) {
private val rectF = RectF() private val rectF = RectF()
init { init {
textPaint.textSize = 40f // Override default text size for circular view progressPaint.strokeWidth = 6f.toDisplayPixels()
progressPaint.strokeWidth = 20f fillBackgroundPaint.strokeWidth = 6f.toDisplayPixels()
fillBackgroundPaint.strokeWidth = 20f progressPaint.strokeCap = Paint.Cap.ROUND
progressPaint.strokeCap = Paint.Cap.ROUND
fillBackgroundPaint.strokeCap = Paint.Cap.BUTT fillBackgroundPaint.strokeCap = Paint.Cap.BUTT
progressPaint.style = Paint.Style.STROKE progressPaint.style = Paint.Style.STROKE
fillBackgroundPaint.style = Paint.Style.STROKE fillBackgroundPaint.style = Paint.Style.STROKE
} }
@ -244,7 +318,8 @@ class CircularProgressView(
super.onDraw(canvas) super.onDraw(canvas)
val size = min(width, height).toFloat() val size = min(width, height).toFloat()
rectF.set(20f, 20f, size - 20f, size - 20f) val inset = 6f.toDisplayPixels()
rectF.set(inset, inset, size - inset, size - inset)
canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring. canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring.
canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle. canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle.
@ -255,124 +330,307 @@ class CircularProgressView(
// Draw the icon in the center. // Draw the icon in the center.
icon?.let { icon?.let {
val iconSize = if (overlayShowOverlayMinimalStyle) 100 else 80 val iconSize = (if (isMinimalStyle) 36f else 24f).toDisplayPixels().toInt()
val iconX = (width - iconSize) / 2 val iconX = (width - iconSize) / 2
val iconY = (height / 2) - if (overlayShowOverlayMinimalStyle) 50 else 80 val iconY = if (isMinimalStyle) {
(height - iconSize) / 2
} else {
(height / 2) - 24f.toDisplayPixels().toInt()
}
it.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize) it.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize)
it.draw(canvas) it.draw(canvas)
} }
// If not a minimal style mode, draw the text inside the ring. // If not a minimal style mode, draw the text inside the ring.
if (!overlayShowOverlayMinimalStyle) { if (!isMinimalStyle) {
canvas.drawText(displayText, width / 2f, height / 2f + 60f, textPaint) canvas.drawText(displayText, width / 2f, height / 2f + 20f.toDisplayPixels(), textPaint)
} }
} }
override fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
super.setProgress(value, max, text, isBrightnessMode)
requestLayout()
}
} }
/** /**
* Custom view for rendering a rectangular progress bar with icons and text. * Custom view for rendering a rectangular progress bar with icons and text.
*/ */
@SuppressLint("ViewConstructor")
class HorizontalProgressView( class HorizontalProgressView(
context: Context, context: Context,
overlayBackgroundOpacity: Int, overlayBackgroundOpacity: Int,
overlayShowOverlayMinimalStyle: Boolean, isMinimalStyle: Boolean,
overlayProgressColor: Int, overlayProgressColor: Int,
overlayFillBackgroundPaint: Int, overlayFillBackgroundPaint: Int,
overlayTextColor: Int, overlayTextColor: Int,
overlayTextSize: Int,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : AbstractProgressView( ) : AbstractProgressView(
context, context,
overlayBackgroundOpacity, overlayBackgroundOpacity,
overlayShowOverlayMinimalStyle, isMinimalStyle,
overlayProgressColor, overlayProgressColor,
overlayFillBackgroundPaint, overlayFillBackgroundPaint,
overlayTextColor, overlayTextColor,
overlayTextSize,
attrs, attrs,
defStyleAttr defStyleAttr
) { ) {
private val iconSize = 60f private val iconSize = 20f.toDisplayPixels()
private val padding = 40f private val padding = 12f.toDisplayPixels()
private var textWidth = 0f
private val progressBarHeight = 3f.toDisplayPixels()
private val progressBarWidth: Float = resources.displayMetrics.widthPixels / 4f
init { init {
textPaint.textSize = 36f // Override default text size for horizontal view
progressPaint.strokeWidth = 0f progressPaint.strokeWidth = 0f
progressPaint.strokeCap = Paint.Cap.BUTT progressPaint.strokeCap = Paint.Cap.BUTT
progressPaint.style = Paint.Style.FILL progressPaint.style = Paint.Style.FILL
fillBackgroundPaint.style = Paint.Style.FILL fillBackgroundPaint.style = Paint.Style.FILL
} }
/**
* Calculate required width based on content
* @return Required width to display all elements
*/
private fun calculateRequiredWidth(): Float {
textWidth = measureTextWidth(displayText, textPaint).toFloat()
return if (!isMinimalStyle) {
padding + iconSize + padding + progressBarWidth + padding + textWidth + padding
} else {
padding + iconSize + padding + textWidth + padding
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val suggestedWidth = MeasureSpec.getSize(widthMeasureSpec)
val suggestedHeight = MeasureSpec.getSize(heightMeasureSpec)
val height = suggestedHeight
val requiredWidth = calculateRequiredWidth().toInt()
val width = min(max(100, requiredWidth), suggestedWidth)
setMeasuredDimension(width, height)
}
override fun onDraw(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
super.onDraw(canvas) super.onDraw(canvas)
val width = width.toFloat() val viewWidth = width.toFloat()
val height = height.toFloat() val viewHeight = height.toFloat()
val viewHeightHalf = viewHeight / 2
// Radius for rounded corners textWidth = measureTextWidth(displayText, textPaint).toFloat()
val cornerRadius = min(width, height) / 2
// Calculate the total width for the elements val cornerRadius = viewHeightHalf
val minimalElementWidth = 5 * padding + iconSize
// Calculate the starting point (X) to center the elements val startX = padding
val minimalStartX = (width - minimalElementWidth) / 2 val iconEndX = startX + iconSize
// Draw the background val textStartX = (viewWidth - 1.5f * padding - textWidth)
if (!overlayShowOverlayMinimalStyle) {
canvas.drawRoundRect(0f, 0f, width, height, cornerRadius, cornerRadius, backgroundPaint)
} else {
canvas.drawRoundRect(minimalStartX, 0f, minimalStartX + minimalElementWidth, height, cornerRadius, cornerRadius, backgroundPaint)
}
if (!overlayShowOverlayMinimalStyle) { canvas.drawRoundRect(
// Draw the fill background 0f, 0f, viewWidth, viewHeight,
val startX = 2 * padding + iconSize cornerRadius, cornerRadius, backgroundPaint
val endX = width - 4 * padding )
val fillWidth = endX - startX
canvas.drawRoundRect(
startX,
height / 2 - 5f,
endX,
height / 2 + 5f,
10f, 10f,
fillBackgroundPaint
)
// Draw the progress
val progressWidth = (progress.toFloat() / maxProgress) * fillWidth
canvas.drawRoundRect(
startX,
height / 2 - 5f,
startX + progressWidth,
height / 2 + 5f,
10f, 10f,
progressPaint
)
}
// Draw the icon
icon?.let { icon?.let {
val iconX = if (!overlayShowOverlayMinimalStyle) { val iconY = viewHeightHalf - iconSize / 2
padding it.setBounds(
} else { startX.toInt(),
padding + minimalStartX iconY.toInt(),
} (startX + iconSize).toInt(),
val iconY = height / 2 - iconSize / 2 (iconY + iconSize).toInt()
it.setBounds(iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt()) )
it.draw(canvas) it.draw(canvas)
} }
// Draw the text on the right val textY = viewHeightHalf + textPaint.textSize / 3
val textX = if (!overlayShowOverlayMinimalStyle) { textPaint.textAlign = Paint.Align.LEFT
width - 2 * padding
} else {
minimalStartX + minimalElementWidth - 2 * padding
}
val textY = height / 2 + textPaint.textSize / 3
// Draw the text if (isMinimalStyle) {
canvas.drawText(displayText, textX, textY, textPaint) canvas.drawText(displayText, textStartX, textY, textPaint)
} else {
val progressStartX = iconEndX + padding
val progressEndX = textStartX - padding
val progressWidth = progressEndX - progressStartX
if (progressWidth > 50) {
val progressBarHeightHalf = progressBarHeight / 2.0f
val viewHeightHalfMinusProgressBarHeightHalf = viewHeightHalf - progressBarHeightHalf
val viewHeightHalfPlusProgressBarHeightHalf = viewHeightHalf + progressBarHeightHalf
canvas.drawRoundRect(
progressStartX,
viewHeightHalfMinusProgressBarHeightHalf,
progressEndX,
viewHeightHalfPlusProgressBarHeightHalf,
progressBarHeightHalf,
progressBarHeightHalf,
fillBackgroundPaint
)
val progressValue = (progress.toFloat() / maxProgress) * progressWidth
canvas.drawRoundRect(
progressStartX,
viewHeightHalfMinusProgressBarHeightHalf,
progressStartX + progressValue,
viewHeightHalfPlusProgressBarHeightHalf,
progressBarHeightHalf,
progressBarHeightHalf,
progressPaint
)
}
canvas.drawText(displayText, textStartX, textY, textPaint)
}
}
override fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
super.setProgress(value, max, text, isBrightnessMode)
requestLayout()
} }
} }
/**
* Custom view for rendering a vertical progress bar with icons and text.
*/
@SuppressLint("ViewConstructor")
class VerticalProgressView(
context: Context,
overlayBackgroundOpacity: Int,
isMinimalStyle: Boolean,
overlayProgressColor: Int,
overlayFillBackgroundPaint: Int,
overlayTextColor: Int,
overlayTextSize: Int,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AbstractProgressView(
context,
overlayBackgroundOpacity,
isMinimalStyle,
overlayProgressColor,
overlayFillBackgroundPaint,
overlayTextColor,
overlayTextSize,
attrs,
defStyleAttr
) {
private val iconSize = 20f.toDisplayPixels()
private val padding = 12f.toDisplayPixels()
private val progressBarWidth = 3f.toDisplayPixels()
private val progressBarHeight: Float = resources.displayMetrics.widthPixels / 3f
init {
progressPaint.strokeWidth = 0f
progressPaint.strokeCap = Paint.Cap.BUTT
progressPaint.style = Paint.Style.FILL
fillBackgroundPaint.style = Paint.Style.FILL
}
/**
* Calculate required height based on content
* @return Required height to display all elements
*/
private fun calculateRequiredHeight(): Float {
return if (!isMinimalStyle) {
padding + iconSize + padding + progressBarHeight + padding + textPaint.textSize + padding
} else {
padding + iconSize + padding + textPaint.textSize + padding
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val suggestedWidth = MeasureSpec.getSize(widthMeasureSpec)
val suggestedHeight = MeasureSpec.getSize(heightMeasureSpec)
val requiredHeight = calculateRequiredHeight().toInt()
val height = min(max(100, requiredHeight), suggestedHeight)
setMeasuredDimension(suggestedWidth, height)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val viewWidth = width.toFloat()
val viewHeight = height.toFloat()
val viewWidthHalf = viewWidth / 2
val cornerRadius = viewWidthHalf
val startY = padding
val iconEndY = startY + iconSize
val textStartY = viewHeight - padding - textPaint.textSize / 2
canvas.drawRoundRect(
0f, 0f, viewWidth, viewHeight,
cornerRadius, cornerRadius, backgroundPaint
)
icon?.let {
val iconX = viewWidthHalf - iconSize / 2
it.setBounds(
iconX.toInt(),
startY.toInt(),
(iconX + iconSize).toInt(),
(startY + iconSize).toInt()
)
it.draw(canvas)
}
val textX = viewWidthHalf
textPaint.textAlign = Paint.Align.CENTER
if (isMinimalStyle) {
canvas.drawText(displayText, textX, textStartY, textPaint)
} else {
val progressStartY = (iconEndY + padding).toFloat()
val progressEndY = textStartY - textPaint.textSize - padding
val progressHeight = progressEndY - progressStartY
if (progressHeight > 50) {
val progressBarWidthHalf = progressBarWidth / 2
val viewHeightHalfMinusProgressBarHeightHalf = viewWidthHalf - progressBarWidthHalf
val viewHeightHalfPlusProgressBarHeightHalf = viewWidthHalf + progressBarWidthHalf
canvas.drawRoundRect(
viewHeightHalfMinusProgressBarHeightHalf,
progressStartY,
viewHeightHalfPlusProgressBarHeightHalf,
progressEndY,
progressBarWidthHalf,
progressBarWidthHalf,
fillBackgroundPaint
)
val progressValue = (progress.toFloat() / maxProgress) * progressHeight
canvas.drawRoundRect(
viewHeightHalfMinusProgressBarHeightHalf,
progressEndY - progressValue,
viewHeightHalfPlusProgressBarHeightHalf,
progressEndY,
progressBarWidthHalf,
progressBarWidthHalf,
progressPaint
)
}
canvas.drawText(displayText, textX, textStartY, textPaint)
}
}
override fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) {
super.setProgress(value, max, text, isBrightnessMode)
requestLayout()
}
}

View file

@ -6,6 +6,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu
import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.InputType import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.ListPreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference 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.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
@ -42,9 +43,13 @@ private val swipeControlsResourcePatch = resourcePatch {
SwitchPreference("revanced_swipe_haptic_feedback"), SwitchPreference("revanced_swipe_haptic_feedback"),
SwitchPreference("revanced_swipe_save_and_restore_brightness"), SwitchPreference("revanced_swipe_save_and_restore_brightness"),
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"), SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
SwitchPreference("revanced_swipe_show_circular_overlay"), ListPreference(
SwitchPreference("revanced_swipe_overlay_minimal_style"), "revanced_swipe_overlay_style",
summaryKey = null,
),
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_progress_color", inputType = InputType.TEXT_CAP_CHARACTERS),
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER), TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER), TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
TextPreference("revanced_swipe_volume_sensitivity", inputType = InputType.NUMBER), TextPreference("revanced_swipe_volume_sensitivity", inputType = InputType.NUMBER),

View file

@ -135,6 +135,27 @@
<item>IOS_UNPLUGGED</item> <item>IOS_UNPLUGGED</item>
</string-array> </string-array>
</patch> </patch>
<patch id="interaction.swipecontrols.swipeControlsResourcePatch">
<string-array name="revanced_swipe_overlay_style_entries">
<item>@string/revanced_swipe_overlay_style_entry_1</item>
<item>@string/revanced_swipe_overlay_style_entry_2</item>
<item>@string/revanced_swipe_overlay_style_entry_3</item>
<item>@string/revanced_swipe_overlay_style_entry_4</item>
<item>@string/revanced_swipe_overlay_style_entry_5</item>
<item>@string/revanced_swipe_overlay_style_entry_6</item>
<item>@string/revanced_swipe_overlay_style_entry_7</item>
</string-array>
<string-array name="revanced_swipe_overlay_style_entry_values">
<!-- Extension enum names. -->
<item>HORIZONTAL</item>
<item>HORIZONTAL_MINIMAL_TOP</item>
<item>HORIZONTAL_MINIMAL_CENTER</item>
<item>CIRCULAR</item>
<item>CIRCULAR_MINIMAL</item>
<item>VERTICAL</item>
<item>VERTICAL_MINIMAL</item>
</string-array>
</patch>
<patch id="layout.spoofappversion.spoofAppVersionPatch"> <patch id="layout.spoofappversion.spoofAppVersionPatch">
<string-array name="revanced_spoof_app_version_target_entries"> <string-array name="revanced_spoof_app_version_target_entries">
<item>@string/revanced_spoof_app_version_target_entry_1</item> <item>@string/revanced_spoof_app_version_target_entry_1</item>

View file

@ -520,21 +520,30 @@ Adjust volume by swiping vertically on the right side of the screen"</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">Enable auto-brightness gesture</string> <string name="revanced_swipe_lowest_value_enable_auto_brightness_title">Enable auto-brightness gesture</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">Swiping down to the lowest value of the brightness gesture enable auto-brightness</string> <string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">Swiping down to the lowest value of the brightness gesture enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">Swiping down to the lowest value does not enable auto-brightness</string> <string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">Swiping down to the lowest value does not enable auto-brightness</string>
<string name="revanced_swipe_lowest_value_enable_auto_brightness_overlay_text">Auto</string>
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string> <string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string> <string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string>
<string name="revanced_swipe_overlay_background_opacity_title">Swipe overlay background opacity</string> <string name="revanced_swipe_overlay_background_opacity_title">Swipe overlay background opacity</string>
<string name="revanced_swipe_overlay_background_opacity_summary">Opacity value between 0-100</string> <string name="revanced_swipe_overlay_background_opacity_summary">Opacity value between 0-100</string>
<string name="revanced_swipe_overlay_background_opacity_invalid_toast">Swipe opacity must be between 0-100</string> <string name="revanced_swipe_overlay_background_opacity_invalid_toast">Swipe opacity must be between 0-100</string>
<string name="revanced_swipe_overlay_progress_color_title">Swipe overlay progress bar color</string>
<string name="revanced_swipe_overlay_progress_color_summary">The color of the progress bar for volume and brightness controls</string>
<string name="revanced_swipe_overlay_progress_color_invalid_toast">Invalid progress bar color</string>
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
<string name="revanced_swipe_text_overlay_size_summary">The text size for swipe overlay between 1-30</string>
<string name="revanced_swipe_text_overlay_size_invalid_toast">The text size must be between 1-30</string>
<string name="revanced_swipe_threshold_title">Swipe magnitude threshold</string> <string name="revanced_swipe_threshold_title">Swipe magnitude threshold</string>
<string name="revanced_swipe_threshold_summary">The amount of threshold for swipe to occur</string> <string name="revanced_swipe_threshold_summary">The amount of threshold for swipe to occur</string>
<string name="revanced_swipe_volume_sensitivity_title">Volume swipe sensitivity</string> <string name="revanced_swipe_volume_sensitivity_title">Volume swipe sensitivity</string>
<string name="revanced_swipe_volume_sensitivity_summary">How much the volume changes per swipe</string> <string name="revanced_swipe_volume_sensitivity_summary">How much the volume changes per swipe</string>
<string name="revanced_swipe_show_circular_overlay_title">Show circular overlay</string> <string name="revanced_swipe_overlay_style_title">Swipe overlay style</string>
<string name="revanced_swipe_show_circular_overlay_summary_on">Circular overlay is shown</string> <string name="revanced_swipe_overlay_style_entry_1">Horizontal overlay</string>
<string name="revanced_swipe_show_circular_overlay_summary_off">Horizontal overlay is shown</string> <string name="revanced_swipe_overlay_style_entry_2">Horizontal overlay (minimal - top)</string>
<string name="revanced_swipe_overlay_minimal_style_title">Enable minimal style</string> <string name="revanced_swipe_overlay_style_entry_3">Horizontal overlay (minimal - center)</string>
<string name="revanced_swipe_overlay_minimal_style_summary_on">Minimal overlay style is enabled</string> <string name="revanced_swipe_overlay_style_entry_4">Circular overlay</string>
<string name="revanced_swipe_overlay_minimal_style_summary_off">Minimal overlay style is disabled</string> <string name="revanced_swipe_overlay_style_entry_5">Circular overlay (minimal)</string>
<string name="revanced_swipe_overlay_style_entry_6">Vertical overlay</string>
<string name="revanced_swipe_overlay_style_entry_7">Vertical overlay (minimal)</string>
<string name="revanced_swipe_change_video_title">Enable swipe to change videos</string> <string name="revanced_swipe_change_video_title">Enable swipe to change videos</string>
<string name="revanced_swipe_change_video_summary_on">Swiping in fullscreen mode will change to the next/previous video</string> <string name="revanced_swipe_change_video_summary_on">Swiping in fullscreen mode will change to the next/previous video</string>
<string name="revanced_swipe_change_video_summary_off">Swiping in fullscreen mode will not change to the next/previous video</string> <string name="revanced_swipe_change_video_summary_off">Swiping in fullscreen mode will not change to the next/previous video</string>