Compare commits

...

4 commits

Author SHA1 Message Date
Bryce Hackel
dc9ede68eb
Debug gesture not recognizing 2024-09-07 02:27:42 -07:00
Bryce Hackel
0d3dfbe2c7
Switch gesture placement location 2024-09-04 00:50:25 -07:00
Bryce Hackel
b9edf2bccd
Cancel gesture after 1 second timeout; cleanup 2024-09-04 00:19:40 -07:00
Bryce Hackel
bbee22218a
Add alternate seek; Improve smoothing hopefully 2024-09-04 00:09:51 -07:00
17 changed files with 91 additions and 67 deletions

View file

@ -395,6 +395,8 @@ static const NSInteger YTLiteSection = 789;
sensitivityPicker, sensitivityPicker,
// Toggle for haptic feedback // Toggle for haptic feedback
BASIC_SWITCH(LOC(@"PLAYER_GESTURES_HAPTIC_FEEDBACK"), nil, @"playerGesturesHapticFeedback_enabled"), BASIC_SWITCH(LOC(@"PLAYER_GESTURES_HAPTIC_FEEDBACK"), nil, @"playerGesturesHapticFeedback_enabled"),
// Toggle for alternate seek method
BASIC_SWITCH(LOC(@"PLAYER_GESTURES_SEEK_ALTERNATE"), LOC(@"PLAYER_GESTURES_SEEK_ALTERNATE_DESC"), @"gestureSeekAlternate_enabled"),
]; ];
YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"PLAYER_GESTURES_TITLE") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"PLAYER_GESTURES_TITLE") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]];
[settingsViewController pushViewController:picker]; [settingsViewController pushViewController:picker];

View file

@ -49,6 +49,7 @@
#import "Tweaks/YouTubeHeader/YTPageStyleController.h" #import "Tweaks/YouTubeHeader/YTPageStyleController.h"
#import "Tweaks/YouTubeHeader/YTRightNavigationButtons.h" #import "Tweaks/YouTubeHeader/YTRightNavigationButtons.h"
#import "Tweaks/YouTubeHeader/YTInlinePlayerBarView.h" #import "Tweaks/YouTubeHeader/YTInlinePlayerBarView.h"
#import "Tweaks/YouTubeHeader/YTMainAppVideoPlayerOverlayView.h"
#define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil]
#define YT_BUNDLE_ID @"com.google.ios.youtube" #define YT_BUNDLE_ID @"com.google.ios.youtube"
@ -165,7 +166,7 @@ typedef NS_ENUM(NSUInteger, GestureSection) {
@end @end
@interface YTFineScrubberFilmstripCollectionView : UICollectionView @interface YTFineScrubberFilmstripCollectionView : UICollectionView
@end @end
@interface YTPlayerViewController (YTLitePlus) <UIGestureRecognizerDelegate> @interface YTPlayerViewController (YTLitePlusGestures) <UIGestureRecognizerDelegate>
@property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; @property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
@end @end
@ -174,19 +175,24 @@ typedef NS_ENUM(NSUInteger, GestureSection) {
@interface MPVolumeController : NSObject @interface MPVolumeController : NSObject
@property (nonatomic, assign, readwrite) float volumeValue; @property (nonatomic, assign, readwrite) float volumeValue;
@end @end
@interface YTPlayerBarController (YTLitePlus) @interface YTPlayerBarController (YTLitePlusGestures)
- (void)didScrub:(UIPanGestureRecognizer *)gestureRecognizer; - (void)didScrub:(UIPanGestureRecognizer *)gestureRecognizer;
- (void)startScrubbing; - (void)startScrubbing;
- (void)didScrubToPoint:(CGPoint)point; - (void)didScrubToPoint:(CGPoint)point;
- (void)endScrubbingForSeekSource:(int)seekSource; - (void)endScrubbingForSeekSource:(int)seekSource;
@end @end
@interface YTMainAppVideoPlayerOverlayViewController (YTLitePlus) @interface YTMainAppVideoPlayerOverlayViewController (YTLitePlusGestures)
@property (nonatomic, strong, readwrite) YTPlayerBarController *playerBarController; @property (nonatomic, strong, readwrite) YTPlayerBarController *playerBarController;
@property YTMainAppVideoPlayerOverlayView *videoPlayerOverlayView;
@end @end
@interface YTInlinePlayerBarContainerView (YTLitePlus) @interface YTMainAppVideoPlayerOverlayView (YTLitePlusGestures)
@property YTMainAppControlsOverlayView *controlsOverlayView;
@end
@interface YTInlinePlayerBarContainerView (YTLitePlusGestures)
@property UIPanGestureRecognizer *scrubGestureRecognizer; @property UIPanGestureRecognizer *scrubGestureRecognizer;
@property (nonatomic, strong, readwrite) YTFineScrubberFilmstripView *fineScrubberFilmstrip; @property (nonatomic, strong, readwrite) YTFineScrubberFilmstripView *fineScrubberFilmstrip;
- (CGFloat)scrubXForScrubRange:(CGFloat)scrubRange; - (CGFloat)scrubXForScrubRange:(CGFloat)scrubRange;
- (CGFloat)scrubRangeForScrubX:(CGFloat)scrubX;
@end @end
// Hide Collapse Button - @arichornlover // Hide Collapse Button - @arichornlover

View file

@ -712,7 +712,12 @@ BOOL isTabSelected = NO;
playerViewController.YTLitePlusPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:playerViewController playerViewController.YTLitePlusPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:playerViewController
action:@selector(YTLitePlusHandlePanGesture:)]; action:@selector(YTLitePlusHandlePanGesture:)];
playerViewController.YTLitePlusPanGesture.delegate = playerViewController; playerViewController.YTLitePlusPanGesture.delegate = playerViewController;
[playerViewController.playerView addGestureRecognizer:playerViewController.YTLitePlusPanGesture]; // Place the gesture on the Main App Controls Overlay View, which scales with the video player
// when, for instance, opening the Live Chat side panel in fullscreen
YTMainAppVideoPlayerOverlayViewController *mainVideoPlayerController = (YTMainAppVideoPlayerOverlayViewController *)playerViewController.childViewControllers.firstObject;
YTMainAppVideoPlayerOverlayView *mainVideoPlayerView = mainVideoPlayerController.videoPlayerOverlayView;
YTMainAppControlsOverlayView *controlsOverlayView = mainVideoPlayerView.controlsOverlayView;
[controlsOverlayView addGestureRecognizer:playerViewController.YTLitePlusPanGesture];
} }
} }
%orig; %orig;
@ -749,10 +754,8 @@ BOOL isTabSelected = NO;
static CGFloat deadzoneStartingXTranslation; static CGFloat deadzoneStartingXTranslation;
// Variable to track the X translation of the pan gesture after exiting the deadzone // Variable to track the X translation of the pan gesture after exiting the deadzone
static CGFloat adjustedTranslationX; static CGFloat adjustedTranslationX;
// Variable used to smooth out the X translation // Variable to cancel gesture if deadzone is not exited after a certain time
static CGFloat smoothedTranslationX = 0; static NSDate *gestureStartTime;
// Constant for the filter constant to change responsiveness
// static const CGFloat filterConstant = 0.1;
// Constant for the deadzone radius that can be changed in the settings // Constant for the deadzone radius that can be changed in the settings
static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone"); static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone");
// Constant for the sensitivity factor that can be changed in the settings // Constant for the sensitivity factor that can be changed in the settings
@ -763,6 +766,7 @@ BOOL isTabSelected = NO;
// Get objects that should only be initialized once // Get objects that should only be initialized once
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
// Get objects for adjusting Volume
volumeView = [[MPVolumeView alloc] init]; volumeView = [[MPVolumeView alloc] init];
for (UIView *view in volumeView.subviews) { for (UIView *view in volumeView.subviews) {
if ([view isKindOfClass:[UISlider class]]) { if ([view isKindOfClass:[UISlider class]]) {
@ -770,6 +774,7 @@ BOOL isTabSelected = NO;
break; break;
} }
} }
// Initialize the haptic feedback generator
feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
}); });
// Get objects used to seek nicely in the video player // Get objects used to seek nicely in the video player
@ -791,9 +796,11 @@ BOOL isTabSelected = NO;
float volumeSensitivityFactor = 3.0; float volumeSensitivityFactor = 3.0;
float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor); float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor);
newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); newVolume = fmaxf(fminf(newVolume, 1.0), 0.0);
// Improve smoothness - ignore if the volume is within 0.01 of the current volume // Improve smoothness - ignore if the volume is within a certain distance of the current volume,
// but also allow it to change to 100% or to 0% when close to the edges
CGFloat currentVolume = [[AVAudioSession sharedInstance] outputVolume]; CGFloat currentVolume = [[AVAudioSession sharedInstance] outputVolume];
if (fabs(newVolume - currentVolume) < 0.01 && currentVolume > 0.01 && currentVolume < 0.99) { CGFloat changeThresh = 0.02;
if ((fabs(newVolume - currentVolume) < changeThresh) && (currentVolume > changeThresh) && (currentVolume < (1-changeThresh))) {
return; return;
} }
// https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4
@ -812,18 +819,23 @@ BOOL isTabSelected = NO;
// Calculate the new seek X position // Calculate the new seek X position
CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive
CGFloat newSeekXPosition = initialTimeXPosition + translationX * sensitivityFactor; CGFloat newSeekXPosition = initialTimeXPosition + translationX * sensitivityFactor;
// Create a CGPoint using this new X position // Decide between seek methods
CGPoint newSeekPoint = CGPointMake(newSeekXPosition, 0); if (IS_ENABLED(@"gestureSeekAlternate_enabled")) {
// Send this to a seek method in the player bar controller // Alternate seek method used by uYou
[playerBarController didScrubToPoint:newSeekPoint]; // Convert the new X position back to a fraction of the total time
CGFloat newVideoFraction = [playerBar scrubRangeForScrubX:newSeekXPosition];
// Calculate the new video time based on this fraction
CGFloat newVideoTime = newVideoFraction * totalTime;
[self seekToTime:newVideoTime];
} else {
// Vanilla YouTube seek method used when dragging the seek bar
// Create a CGPoint using this new X position
CGPoint newSeekPoint = CGPointMake(newSeekXPosition, 0);
// Send this to a seek method in the player bar controller
[playerBarController didScrubToPoint:newSeekPoint];
}
}; };
// Helper function to smooth out the X translation
// CGFloat (^applyLowPassFilter)(CGFloat) = ^(CGFloat newTranslation) {
// smoothedTranslationX = filterConstant * newTranslation + (1 - filterConstant) * smoothedTranslationX;
// return smoothedTranslationX;
// };
/***** Helper functions for running the selected gesture *****/ /***** Helper functions for running the selected gesture *****/
// Helper function to run any setup for the selected gesture mode // Helper function to run any setup for the selected gesture mode
void (^runSelectedGestureSetup)(NSString*) = ^(NSString *sectionKey) { void (^runSelectedGestureSetup)(NSString*) = ^(NSString *sectionKey) {
@ -843,14 +855,9 @@ BOOL isTabSelected = NO;
[playerBarController startScrubbing]; [playerBarController startScrubbing];
break; break;
case GestureModeDisabled: case GestureModeDisabled:
// Do nothing if the gesture is disabled // Fall through
break;
default: default:
// Show an alert if the gesture mode is invalid // Do nothing
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Invalid Gesture Mode" message:@"Please report this bug." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
break; break;
} }
}; };
@ -871,14 +878,10 @@ BOOL isTabSelected = NO;
adjustSeek(adjustedTranslationX, initialTime); adjustSeek(adjustedTranslationX, initialTime);
break; break;
case GestureModeDisabled: case GestureModeDisabled:
// Do nothing if the gesture is disabled // Fall through
break; break;
default: default:
// Show an alert if the gesture mode is invalid // Do nothing
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Invalid Gesture Mode" message:@"Please report this bug." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
break; break;
} }
}; };
@ -897,13 +900,9 @@ BOOL isTabSelected = NO;
[playerBarController endScrubbingForSeekSource:0]; [playerBarController endScrubbingForSeekSource:0];
break; break;
case GestureModeDisabled: case GestureModeDisabled:
break; // Fall through
default: default:
// Show an alert if the gesture mode is invalid // Do nothing
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Invalid Gesture Mode" message:@"Please report this bug." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:okAction];
[self presentViewController:alertController animated:YES completion:nil];
break; break;
} }
}; };
@ -911,6 +910,7 @@ BOOL isTabSelected = NO;
// Handle gesture based on current gesture state // Handle gesture based on current gesture state
if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSLog(@"bhackel - Gesture began");
// Get the gesture's start position // Get the gesture's start position
startLocation = [panGestureRecognizer locationInView:self.view]; startLocation = [panGestureRecognizer locationInView:self.view];
CGFloat viewHeight = self.view.bounds.size.height; CGFloat viewHeight = self.view.bounds.size.height;
@ -933,25 +933,32 @@ BOOL isTabSelected = NO;
} }
// Deactive the activity flag // Deactive the activity flag
isValidHorizontalPan = NO; isValidHorizontalPan = NO;
// Cancel this gesture if it has not activated after 1 second // Store current time for gesture timeout
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ gestureStartTime = [NSDate date];
if (!isValidHorizontalPan && panGestureRecognizer.state != UIGestureRecognizerStateEnded) {
// Cancel the gesture by setting its state to UIGestureRecognizerStateCancelled
panGestureRecognizer.state = UIGestureRecognizerStateCancelled;
}
});
} }
// Handle changed gesture state by activating the gesture once it has exited the deadzone, // Handle changed gesture state by activating the gesture once it has exited the deadzone,
// and then adjusting the player based on the selected gesture mode // and then adjusting the player based on the selected gesture mode
if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
NSLog(@"bhackel - Gesture changed");
// Determine if the gesture is predominantly horizontal // Determine if the gesture is predominantly horizontal
CGPoint translation = [panGestureRecognizer translationInView:self.view]; CGPoint translation = [panGestureRecognizer translationInView:self.view];
if (!isValidHorizontalPan) { if (!isValidHorizontalPan) {
NSLog(@"bhackel - Gesture not yet valid");
// Timeout
// Check how much time has passed since the gesture started
NSTimeInterval timeElapsed = [[NSDate date] timeIntervalSinceDate:gestureStartTime];
// If more than 1 second has passed and the gesture hasn't activated, cancel the gesture
if (timeElapsed >= 1.0 && !isValidHorizontalPan) {
panGestureRecognizer.state = UIGestureRecognizerStateCancelled;
}
// Horizontal and deadzone check
if (fabs(translation.x) > fabs(translation.y)) { if (fabs(translation.x) > fabs(translation.y)) {
// Check if the touch has moved outside the deadzone // Check if the touch has moved outside the deadzone
CGFloat distanceFromStart = hypot(translation.x, translation.y); CGFloat distanceFromStart = hypot(translation.x, translation.y);
if (distanceFromStart < deadzoneRadius) { if (distanceFromStart < deadzoneRadius) {
NSLog(@"bhackel - Gesture within deadzone");
// If within the deadzone, don't activate the pan gesture // If within the deadzone, don't activate the pan gesture
return; return;
} }
@ -959,7 +966,6 @@ BOOL isTabSelected = NO;
isValidHorizontalPan = YES; isValidHorizontalPan = YES;
deadzoneStartingXTranslation = translation.x; deadzoneStartingXTranslation = translation.x;
adjustedTranslationX = 0; adjustedTranslationX = 0;
smoothedTranslationX = 0;
// Run the setup for the selected gesture mode // Run the setup for the selected gesture mode
switch (gestureSection) { switch (gestureSection) {
case GestureSectionTop: case GestureSectionTop:
@ -990,6 +996,7 @@ BOOL isTabSelected = NO;
// Handle the gesture based on the identified section // Handle the gesture based on the identified section
if (isValidHorizontalPan) { if (isValidHorizontalPan) {
NSLog(@"bhackel - Gesture valid");
// Adjust the X translation based on the value hit after exiting the deadzone // Adjust the X translation based on the value hit after exiting the deadzone
adjustedTranslationX = translation.x - deadzoneStartingXTranslation; adjustedTranslationX = translation.x - deadzoneStartingXTranslation;
// Smooth the translation value // Smooth the translation value
@ -1037,25 +1044,6 @@ BOOL isTabSelected = NO;
// allow the pan gesture to be recognized simultaneously with other gestures // allow the pan gesture to be recognized simultaneously with other gestures
%new %new
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
// Do not allow this gesture to activate with the normal seek bar gesture
YTMainAppVideoPlayerOverlayViewController *mainVideoPlayerController = (YTMainAppVideoPlayerOverlayViewController *)self.childViewControllers.firstObject;
YTPlayerBarController *playerBarController = mainVideoPlayerController.playerBarController;
YTInlinePlayerBarContainerView *playerBar = playerBarController.playerBar;
if (otherGestureRecognizer == playerBar.scrubGestureRecognizer) {
return NO;
}
// Do not allow this gesture to activate with the fine scrubber gesture
YTFineScrubberFilmstripView *fineScrubberFilmstrip = playerBar.fineScrubberFilmstrip;
if (!fineScrubberFilmstrip) {
return YES;
}
YTFineScrubberFilmstripCollectionView *filmstripCollectionView = [fineScrubberFilmstrip valueForKey:@"_filmstripCollectionView"];
if (filmstripCollectionView && otherGestureRecognizer == filmstripCollectionView.panGestureRecognizer) {
return NO;
}
}
return YES; return YES;
} }
%end %end

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "خيارات تراكب ضوابط الفيديو"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "خيارات تراكب ضوابط الفيديو";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Опции за контрол на видеото"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Опции за контрол на видеото";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Overlay-Optionen für Videosteuerungen"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Overlay-Optionen für Videosteuerungen";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Sección Media"; "MIDDLE_SECTION" = "Sección Media";
"BOTTOM_SECTION" = "Sección Inferior"; "BOTTOM_SECTION" = "Sección Inferior";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Retroalimentación Háptica"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Retroalimentación Háptica";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opciones de superposición de controles de vídeo"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opciones de superposición de controles de vídeo";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Options de l'overlay des contrôles vidéo"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Options de l'overlay des contrôles vidéo";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "動画コントロールオーバーレイの設定"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "動画コントロールオーバーレイの設定";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Seção do Meio"; "MIDDLE_SECTION" = "Seção do Meio";
"BOTTOM_SECTION" = "Seção Inferior"; "BOTTOM_SECTION" = "Seção Inferior";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Feedback Tátil"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Feedback Tátil";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opțiuni Overlay Controale Video"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opțiuni Overlay Controale Video";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View file

@ -48,6 +48,8 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Kontrol Seç."; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Kontrol Seç.";

View file

@ -33,6 +33,8 @@
"MIDDLE_SECTION" = "Phần giữa"; "MIDDLE_SECTION" = "Phần giữa";
"BOTTOM_SECTION" = "Phần dưới"; "BOTTOM_SECTION" = "Phần dưới";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Bật phản hồi xúc giác"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Bật phản hồi xúc giác";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Lớp phủ video"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Lớp phủ video";

View file

@ -34,6 +34,8 @@
"MIDDLE_SECTION" = "Middle Section"; "MIDDLE_SECTION" = "Middle Section";
"BOTTOM_SECTION" = "Bottom Section"; "BOTTOM_SECTION" = "Bottom Section";
"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; "PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback";
"PLAYER_GESTURES_SEEK_ALTERNATE" = "Alternate seek method";
"PLAYER_GESTURES_SEEK_ALTERNATE_DESC" = "Use a different method that increases content visibility";
// Video controls overlay options // Video controls overlay options
"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定";