diff --git a/.gitmodules b/.gitmodules index e52c366..6d35fdf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ [submodule "Tweaks/YouTimeStamp"] path = Tweaks/YouTimeStamp url = https://github.com/arichornloverALT/YouTimeStamp.git +[submodule "Tweaks/YouLoop"] + path = Tweaks/YouLoop + url = https://github.com/bhackel/YouLoop diff --git a/Makefile b/Makefile index 8400c15..3046c62 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ EXTRA_CFLAGS := $(addprefix -I,$(shell find Tweaks/FLEX -name '*.h' -exec dirnam # Allow YouTubeHeader to be accessible using #include <...> export ADDITIONAL_CFLAGS = -I$(THEOS_PROJECT_DIR)/Tweaks -YTLitePlus_INJECT_DYLIBS = Tweaks/YTLite/var/jb/Library/MobileSubstrate/DynamicLibraries/YTLite.dylib .theos/obj/libcolorpicker.dylib .theos/obj/iSponsorBlock.dylib .theos/obj/YTUHD.dylib .theos/obj/YouPiP.dylib .theos/obj/YouTubeDislikesReturn.dylib .theos/obj/YTABConfig.dylib .theos/obj/YouMute.dylib .theos/obj/DontEatMyContent.dylib .theos/obj/YTHoldForSpeed.dylib .theos/obj/YTVideoOverlay.dylib .theos/obj/YouGroupSettings.dylib .theos/obj/YouQuality.dylib .theos/obj/YouTimeStamp.dylib +YTLitePlus_INJECT_DYLIBS = Tweaks/YTLite/var/jb/Library/MobileSubstrate/DynamicLibraries/YTLite.dylib .theos/obj/libcolorpicker.dylib .theos/obj/iSponsorBlock.dylib .theos/obj/YTUHD.dylib .theos/obj/YouPiP.dylib .theos/obj/YouTubeDislikesReturn.dylib .theos/obj/YTABConfig.dylib .theos/obj/YouMute.dylib .theos/obj/DontEatMyContent.dylib .theos/obj/YTHoldForSpeed.dylib .theos/obj/YTVideoOverlay.dylib .theos/obj/YouGroupSettings.dylib .theos/obj/YouQuality.dylib .theos/obj/YouTimeStamp.dylib .theos/obj/YouLoop.dylib YTLitePlus_FILES = YTLitePlus.xm $(shell find Source -name '*.xm' -o -name '*.x' -o -name '*.m') $(shell find Tweaks/FLEX -type f \( -iname \*.c -o -iname \*.m -o -iname \*.mm \)) YTLitePlus_IPA = ./tmp/Payload/YouTube.app YTLitePlus_CFLAGS = -fobjc-arc -Wno-deprecated-declarations -Wno-unsupported-availability-guard -Wno-unused-but-set-variable -DTWEAK_VERSION=$(PACKAGE_VERSION) $(EXTRA_CFLAGS) @@ -23,7 +23,7 @@ YTLitePlus_FRAMEWORKS = UIKit Security include $(THEOS)/makefiles/common.mk include $(THEOS_MAKE_PATH)/tweak.mk -SUBPROJECTS += Tweaks/Alderis Tweaks/iSponsorBlock Tweaks/YTUHD Tweaks/YouPiP Tweaks/Return-YouTube-Dislikes Tweaks/YTABConfig Tweaks/YouMute Tweaks/DontEatMyContent Tweaks/YTHoldForSpeed Tweaks/YTVideoOverlay Tweaks/YouQuality Tweaks/YouTimeStamp Tweaks/YouGroupSettings +SUBPROJECTS += Tweaks/Alderis Tweaks/iSponsorBlock Tweaks/YTUHD Tweaks/YouPiP Tweaks/Return-YouTube-Dislikes Tweaks/YTABConfig Tweaks/YouMute Tweaks/DontEatMyContent Tweaks/YTHoldForSpeed Tweaks/YTVideoOverlay Tweaks/YouQuality Tweaks/YouTimeStamp Tweaks/YouGroupSettings Tweaks/YouLoop include $(THEOS_MAKE_PATH)/aggregate.mk YTLITE_PATH = Tweaks/YTLite @@ -46,6 +46,7 @@ before-package:: @cp -R Tweaks/YTVideoOverlay/layout/Library/Application\ Support/YTVideoOverlay.bundle Resources/ @cp -R Tweaks/YouQuality/layout/Library/Application\ Support/YouQuality.bundle Resources/ @cp -R Tweaks/YouTimeStamp/layout/Library/Application\ Support/YouTimeStamp.bundle Resources/ + @cp -R Tweaks/YouLoop/layout/Library/Application\ Support/YouLoop.bundle Resources/ @cp -R lang/YTLitePlus.bundle Resources/ @echo -e "==> \033[1mChanging the installation path of dylibs...\033[0m" @ldid -r .theos/obj/iSponsorBlock.dylib && install_name_tool -change /usr/lib/libcolorpicker.dylib @rpath/libcolorpicker.dylib .theos/obj/iSponsorBlock.dylib diff --git a/Source/LowContrastMode.xm b/Source/LowContrastMode.xm index 0b0744e..6948402 100644 --- a/Source/LowContrastMode.xm +++ b/Source/LowContrastMode.xm @@ -1,9 +1,6 @@ #import "../YTLitePlus.h" -// -static BOOL IsEnabled(NSString *key) { - return [[NSUserDefaults standardUserDefaults] boolForKey:key]; -} +// Low Contrast Mode static int contrastMode() { return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; } diff --git a/Source/Settings.xm b/Source/Settings.xm index 13854e5..c25f262 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -32,12 +32,6 @@ settingItemId:0] */ -static BOOL IsEnabled(NSString *key) { - return [[NSUserDefaults standardUserDefaults] boolForKey:key]; -} -static int GetSelection(NSString *key) { - return [[NSUserDefaults standardUserDefaults] integerForKey:key]; -} static int contrastMode() { return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; } @@ -82,7 +76,7 @@ static const NSInteger YTLiteSection = 789; %end -// Settings +// Add YTLitePlus to the settings list %hook YTAppSettingsPresentationData + (NSArray *)settingsCategoryOrder { NSArray *order = %orig; @@ -110,14 +104,15 @@ static const NSInteger YTLiteSection = 789; Class YTSettingsSectionItemClass = %c(YTSettingsSectionItem); YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + // Add item for going to the YTLitePlus GitHub page YTSettingsSectionItem *main = [%c(YTSettingsSectionItem) - itemWithTitle:[NSString stringWithFormat:LOC(@"VERSION"), @(OS_STRINGIFY(TWEAK_VERSION))] - titleDescription:LOC(@"VERSION_CHECK") - accessibilityIdentifier:nil - detailTextBlock:nil - selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/YTLitePlus/YTLitePlus/releases/latest"]]; - }]; + itemWithTitle:[NSString stringWithFormat:LOC(@"VERSION"), @(OS_STRINGIFY(TWEAK_VERSION))] + titleDescription:LOC(@"VERSION_CHECK") + accessibilityIdentifier:nil + detailTextBlock:nil + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/YTLitePlus/YTLitePlus/releases/latest"]]; + }]; [sectionItems addObject:main]; YTSettingsSectionItem *copySettings = [%c(YTSettingsSectionItem) @@ -237,6 +232,179 @@ static const NSInteger YTLiteSection = 789; [sectionItems addObject:appIcon]; */ +# pragma mark - Player Gestures - @bhackel + // Helper to get the selected gesture mode + static NSString* (^sectionGestureSelectedModeToString)(GestureMode) = ^(GestureMode sectionIndex) { + switch (sectionIndex) { + case GestureModeVolume: + return LOC(@"VOLUME"); + case GestureModeBrightness: + return LOC(@"BRIGHTNESS"); + case GestureModeSeek: + return LOC(@"SEEK"); + case GestureModeDisabled: + return LOC(@"DISABLED"); + default: + return @"Invalid index - Report bug"; + } + }; + + // Helper to generate checkmark setting items for selecting gesture modes + static YTSettingsSectionItem* (^gestureCheckmarkSettingItem)(NSInteger, NSString *) = ^(NSInteger idx, NSString *key) { + return [YTSettingsSectionItemClass + checkmarkItemWithTitle:sectionGestureSelectedModeToString(idx) + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:idx forKey:key]; + [settingsViewController reloadData]; + return YES; + } + ]; + }; + + // Helper to generate a section item for selecting a gesture mode + YTSettingsSectionItem *(^createSectionGestureSelector)(NSString *, NSString *) = ^YTSettingsSectionItem *(NSString *sectionLabel, NSString *sectionKey) { + return [YTSettingsSectionItemClass itemWithTitle:LOC(sectionLabel) + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return sectionGestureSelectedModeToString(GetSelection(sectionKey)); + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + gestureCheckmarkSettingItem(0, sectionKey), // Volume + gestureCheckmarkSettingItem(1, sectionKey), // Brightness + gestureCheckmarkSettingItem(2, sectionKey), // Seek + gestureCheckmarkSettingItem(3, sectionKey) // Disabled + ]; + // Present picker when selecting this settings item + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(sectionLabel) + pickerSectionTitle:nil + rows:rows + selectedItemIndex:GetSelection(sectionKey) + parentResponder:[self parentResponder] + ]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + }; + // Configuration picker for deadzone to pick from 0 to 100 pixels with interval of 10 + NSMutableArray *deadzoneValues = [NSMutableArray array]; + for (CGFloat value = 0; value <= 100; value += 10) { + [deadzoneValues addObject:@(value)]; + } + YTSettingsSectionItem *deadzonePicker = [YTSettingsSectionItemClass + itemWithTitle:LOC(@"DEADZONE") + titleDescription:LOC(@"DEADZONE_DESC") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return [NSString stringWithFormat:@"%ld px", (long)GetFloat(@"playerGesturesDeadzone")]; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // Generate rows for deadzone picker using the predefined array + NSMutableArray *deadzoneRows = [NSMutableArray array]; + for (NSNumber *deadzoneValue in deadzoneValues) { + CGFloat deadzone = [deadzoneValue floatValue]; + [deadzoneRows addObject:[YTSettingsSectionItemClass + checkmarkItemWithTitle:[NSString stringWithFormat:@"%ld px", (long)deadzone] + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setFloat:deadzone forKey:@"playerGesturesDeadzone"]; + [settingsViewController reloadData]; + return YES; + } + ]]; + } + // Determine the index of the currently selected deadzone + CGFloat currentDeadzone = GetFloat(@"playerGesturesDeadzone"); + NSUInteger selectedIndex = [deadzoneValues indexOfObject:@(currentDeadzone)]; + if (selectedIndex == NSNotFound) { + selectedIndex = 0; // Default to the first item if the current deadzone is not found + } + // Present deadzone picker when selecting this settings item + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(@"DEADZONE") + pickerSectionTitle:nil + rows:deadzoneRows + selectedItemIndex:selectedIndex + parentResponder:[self parentResponder] + ]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + + // Configuration picker for sensitivity to pick from 0.5 to 2.0 with interval of 0.1 + NSMutableArray *sensitivityValues = [NSMutableArray array]; + for (CGFloat value = 0.5; value <= 2.0; value += 0.1) { + [sensitivityValues addObject:@(value)]; + } + YTSettingsSectionItem *sensitivityPicker = [YTSettingsSectionItemClass + itemWithTitle:LOC(@"SENSITIVITY") + titleDescription:LOC(@"SENSITIVITY_DESC") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return [NSString stringWithFormat:@"%.1f", GetFloat(@"playerGesturesSensitivity")]; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // Generate rows for sensitivity picker using the predefined array + NSMutableArray *sensitivityRows = [NSMutableArray array]; + for (NSNumber *sensitivityValue in sensitivityValues) { + CGFloat sensitivity = [sensitivityValue floatValue]; + [sensitivityRows addObject:[YTSettingsSectionItemClass + checkmarkItemWithTitle:[NSString stringWithFormat:@"%.1f", sensitivity] + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setFloat:sensitivity forKey:@"playerGesturesSensitivity"]; + [settingsViewController reloadData]; + return YES; + } + ]]; + } + // Determine the index of the currently selected sensitivity + CGFloat currentSensitivity = GetFloat(@"playerGesturesSensitivity"); + NSUInteger selectedIndex = [sensitivityValues indexOfObject:@(currentSensitivity)]; + if (selectedIndex == NSNotFound) { + selectedIndex = 0; // Default to the first item if the current sensitivity is not found + } + // Present sensitivity picker + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(@"SENSITIVITY") + pickerSectionTitle:nil + rows:sensitivityRows + selectedItemIndex:selectedIndex + parentResponder:[self parentResponder] + ]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + + // Create and add items to the high level gestures menu + YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"PLAYER_GESTURES_TITLE") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + // Description header item + [YTSettingsSectionItemClass + itemWithTitle:nil + titleDescription:LOC(@"PLAYER_GESTURES_DESC") + accessibilityIdentifier:nil + detailTextBlock:nil + selectBlock:nil + ], + // Toggle for enabling gestures + BASIC_SWITCH(LOC(@"PLAYER_GESTURES_TOGGLE"), nil, @"playerGestures_enabled"), + // Pickers for each gesture section + createSectionGestureSelector(@"TOP_SECTION", @"playerGestureTopSelection"), + createSectionGestureSelector(@"MIDDLE_SECTION", @"playerGestureMiddleSelection"), + createSectionGestureSelector(@"BOTTOM_SECTION", @"playerGestureBottomSelection"), + // Pickers for configuration settings + deadzonePicker, + sensitivityPicker + ]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Player Gestures (Beta)") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + }]; + [sectionItems addObject:playerGesturesGroup]; + # pragma mark - Video Controls Overlay Options YTSettingsSectionItem *videoControlOverlayGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ diff --git a/Source/Themes.xm b/Source/Themes.xm index 4ea44b7..50457ff 100644 --- a/Source/Themes.xm +++ b/Source/Themes.xm @@ -1,8 +1,5 @@ #import "../YTLitePlus.h" -static BOOL IsEnabled(NSString *key) { - return [[NSUserDefaults standardUserDefaults] boolForKey:key]; -} static BOOL isDarkMode() { return ([[NSUserDefaults standardUserDefaults] integerForKey:@"page_style"] == 1); } diff --git a/Source/VersionSpooferLite.xm b/Source/VersionSpooferLite.xm index 7399aec..78f2889 100644 --- a/Source/VersionSpooferLite.xm +++ b/Source/VersionSpooferLite.xm @@ -1,9 +1,6 @@ #import "../YTLitePlus.h" -// -static BOOL IsEnabled(NSString *key) { - return [[NSUserDefaults standardUserDefaults] boolForKey:key]; -} + static int appVersionSpoofer() { return [[NSUserDefaults standardUserDefaults] integerForKey:@"versionSpoofer"]; } diff --git a/Tweaks/YouLoop b/Tweaks/YouLoop new file mode 160000 index 0000000..5a424d7 --- /dev/null +++ b/Tweaks/YouLoop @@ -0,0 +1 @@ +Subproject commit 5a424d7531c0d2f82d258b8e8c580e153a93fcdd diff --git a/YTLitePlus.h b/YTLitePlus.h index f737d46..8a41583 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -6,10 +6,11 @@ #import #import #import +#import +#import #import // For AVPlayer and AVPlayerViewController #import // For kUTTypeMovie and kUTTypeVideo - #import "Tweaks/FLEX/FLEX.h" #import "Tweaks/YouTubeHeader/YTAppDelegate.h" #import "Tweaks/YouTubeHeader/YTPlayerViewController.h" @@ -43,6 +44,8 @@ #import "Tweaks/YouTubeHeader/YTPlayerBarController.h" #import "Tweaks/YouTubeHeader/YTResponder.h" #import "Tweaks/YouTubeHeader/YTMainAppControlsOverlayView.h" +#import "Tweaks/YouTubeHeader/YTMultiSizeViewController.h" +#import "Tweaks/YouTubeHeader/YTWatchLayerViewController.h" #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define YT_BUNDLE_ID @"com.google.ios.youtube" @@ -51,6 +54,30 @@ #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define APP_THEME_IDX [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] +// Avoid issues with multiple includes of this file +#pragma once + +// Helper methods for key retrieval +#define IsEnabled(key) [[NSUserDefaults standardUserDefaults] boolForKey:key] +#define GetSelection(key) [[NSUserDefaults standardUserDefaults] integerForKey:key] +#define GetFloat(key) [[NSUserDefaults standardUserDefaults] floatForKey:key] + + +// Player Gesture selected mode enum +typedef NS_ENUM(NSUInteger, GestureMode) { + GestureModeVolume, + GestureModeBrightness, + GestureModeSeek, + GestureModeDisabled +}; +// Gesture Section Enum +typedef NS_ENUM(NSUInteger, GestureSection) { + GestureSectionTop, + GestureSectionMiddle, + GestureSectionBottom, + GestureSectionInvalid +}; + // YTSpeed @interface YTVarispeedSwitchControllerOption : NSObject - (id)initWithTitle:(id)title rate:(float)rate; @@ -125,6 +152,17 @@ @property id parentResponder; @end +// Player Gestures - @bhackel +@interface YTPlayerViewController (YTLitePlus) +@property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; +@end +@interface YTWatchFullscreenViewController : YTMultiSizeViewController +@end +@interface MPVolumeController : NSObject +@property (nonatomic, assign, readwrite) float volumeValue; +@end + // Hide Collapse Button - @arichornlover @interface YTMainAppControlsOverlayView (YTLitePlus) @property (nonatomic, assign, readwrite) YTQTMButton *watchCollapseButton; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 331d8b8..61b9935 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -33,11 +33,6 @@ static NSString *accessGroupID() { return accessGroup; } -// -static BOOL IsEnabled(NSString *key) { - return [[NSUserDefaults standardUserDefaults] boolForKey:key]; -} - # pragma mark - Tweaks // Activate FLEX @@ -645,6 +640,213 @@ BOOL isTabSelected = NO; } %end +// Gestures - @bhackel +%group playerGestures +%hook YTWatchLayerViewController +// invoked when the player view controller is either created or destroyed +- (void)watchController:(YTWatchController *)watchController didSetPlayerViewController:(YTPlayerViewController *)playerViewController { + if (playerViewController) { + // check to see if the pan gesture is already created + if (!playerViewController.YTLitePlusPanGesture) { + playerViewController.YTLitePlusPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:playerViewController + action:@selector(YTLitePlusHandlePanGesture:)]; + playerViewController.YTLitePlusPanGesture.delegate = playerViewController; + [playerViewController.playerView addGestureRecognizer:playerViewController.YTLitePlusPanGesture]; + } + } + %orig; +} +%end + + +%hook YTPlayerViewController +// the pan gesture that will be created and added to the player view +%property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; +%new +- (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { + // Haptic feedback generator + static UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; + // Variables for storing initial values to be adjusted + static float initialVolume; + static float initialBrightness; + static CGFloat currentTime; + // Flag to determine if the pan gesture is valid + static BOOL isValidHorizontalPan = NO; + // Variable to store the section of the screen the gesture is in + static GestureSection gestureSection = GestureSectionInvalid; + // Variable to track the start location of the whole pan gesture + static CGPoint startLocation; + // Variable to track the X translation when exiting the deadzone + static CGFloat deadzoneStartingXTranslation; + // Constant for the deadzone radius that can be changed in the settings + static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone"); + // Constant for the sensitivity factor that can be changed in the settings + static CGFloat sensitivityFactor = (CGFloat)GetFloat(@"playerGesturesSensitivity"); + +/***** Helper functions *****/ + // Helper function to adjust brightness + void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { + float newBrightness = initialBrightness + ((translationX / 1000.0) * sensitivityFactor); + newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0); + [[UIScreen mainScreen] setBrightness:newBrightness]; + }; + // Helper function to adjust volume + void (^adjustVolume)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialVolume) { + float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor); + newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 + MPVolumeView *volumeView = [[MPVolumeView alloc] init]; + UISlider *volumeViewSlider = nil; + for (UIView *view in volumeView.subviews) { + if ([view isKindOfClass:[UISlider class]]) { + volumeViewSlider = (UISlider *)view; + break; + } + } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + volumeViewSlider.value = newVolume; + }); + }; + // Helper function to adjust seek time + void (^adjustSeek)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat currentTime) { + // Calculate a seek fraction based on the horizontal translation + CGFloat totalDuration = self.currentVideoTotalMediaTime; + CGFloat viewWidth = self.view.bounds.size.width; + CGFloat seekFraction = (translationX / viewWidth); + // Seek to the new time based on the calculated offset + CGFloat sensitivityFactor = 1; // Adjust this value to make seeking less sensitive + seekFraction = sensitivityFactor * seekFraction; + CGFloat seekTime = currentTime + totalDuration * seekFraction; + [self seekToTime:seekTime]; + }; + // Helper function to run the selected gesture action + void (^runSelectedGesture)(NSString*, CGFloat, CGFloat, CGFloat, CGFloat) + = ^(NSString *sectionKey, CGFloat translationX, CGFloat initialBrightness, CGFloat initialVolume, CGFloat currentTime) { + // Determine the selected gesture mode using the section key + GestureMode selectedGestureMode = (GestureMode)GetSelection(sectionKey); + // Handle the gesture action based on the selected mode + switch (selectedGestureMode) { + case GestureModeVolume: + adjustVolume(translationX, initialVolume); + break; + case GestureModeBrightness: + adjustBrightness(translationX, initialBrightness); + break; + case GestureModeSeek: + adjustSeek(translationX, currentTime); + break; + case GestureModeDisabled: + // Do nothing if the gesture is disabled + break; + default: + // Show an alert if the gesture mode is invalid + 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; + } + }; +/***** End of Helper functions *****/ + + // Handle gesture based on current gesture state + if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { + // Get the gesture's start position + startLocation = [panGestureRecognizer locationInView:self.view]; + CGFloat viewHeight = self.view.bounds.size.height; + + // Determine the section based on the start position + // by dividing the view into thirds + if (startLocation.y <= viewHeight / 3.0) { + gestureSection = GestureSectionTop; + // Cancel the gesture if the mode is disabled + if (GetSelection(@"playerGestureTopSelection") == GestureModeDisabled) { + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; + } + } else if (startLocation.y <= 2 * viewHeight / 3.0) { + gestureSection = GestureSectionMiddle; + // Cancel the gesture if the mode is disabled + if (GetSelection(@"playerGestureMiddleSelection") == GestureModeDisabled) { + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; + } + } else if (startLocation.y <= viewHeight) { + gestureSection = GestureSectionBottom; + // Cancel the gesture if the mode is disabled + if (GetSelection(@"playerGestureBottomSelection") == GestureModeDisabled) { + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; + } + } else { + gestureSection = GestureSectionInvalid; + } + // Deactive the activity flag + isValidHorizontalPan = NO; + } + + if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { + // Determine if the gesture is predominantly horizontal + CGPoint translation = [panGestureRecognizer translationInView:self.view]; + if (!isValidHorizontalPan) { + if (fabs(translation.x) > fabs(translation.y)) { + // Check if the touch has moved outside the deadzone + CGFloat distanceFromStart = hypot(translation.x, translation.y); + if (distanceFromStart < deadzoneRadius) { + // If within the deadzone, don't activate the pan gesture + return; + } + // If outside the deadzone, activate the pan gesture and store the initial values + isValidHorizontalPan = YES; + deadzoneStartingXTranslation = translation.x; + initialBrightness = [UIScreen mainScreen].brightness; + initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + currentTime = self.currentVideoMediaTime; + // Provide haptic feedback to indicate a gesture start + [feedbackGenerator prepare]; + [feedbackGenerator impactOccurred]; + } else { + // Cancel the gesture if the translation is not horizontal + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; + } + } + + // Handle the gesture based on the identified section + if (isValidHorizontalPan) { + // Adjust the X translation based on the value hit after + // exiting the deadzone + CGFloat adjustedTranslationX = translation.x - deadzoneStartingXTranslation; + // Pass the adjusted translation to the selected gesture + if (gestureSection == GestureSectionTop) { + runSelectedGesture(@"playerGestureTopSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); + } else if (gestureSection == GestureSectionMiddle) { + runSelectedGesture(@"playerGestureMiddleSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); + } else if (gestureSection == GestureSectionBottom) { + runSelectedGesture(@"playerGestureBottomSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); + } else { + // If the section is invalid, cancel the gesture + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + } + } + } + if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { + if (isValidHorizontalPan) { + // Provide haptic feedback upon successful gesture recognition + [feedbackGenerator prepare]; + [feedbackGenerator impactOccurred]; + } + } + +} +// allow the pan gesture to be recognized simultaneously with other gestures +%new +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + return YES; +} +%end +%end + /* // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main @@ -874,6 +1076,9 @@ BOOL isTabSelected = NO; if (IsEnabled(@"disableEngagementOverlay_enabled")) { %init(gDisableEngagementOverlay); } + if (IsEnabled(@"playerGestures_enabled")) { + %init(playerGestures); + } // Change the default value of some options NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; @@ -889,4 +1094,21 @@ BOOL isTabSelected = NO; if (![allKeys containsObject:@"fixCasting_enabled"]) { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"fixCasting_enabled"]; } + // Default gestures as volume, brightness, seek + if (![allKeys containsObject:@"playerGestureTopSelection"]) { + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeVolume forKey:@"playerGestureTopSelection"]; + } + if (![allKeys containsObject:@"playerGestureMiddleSelection"]) { + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeBrightness forKey:@"playerGestureMiddleSelection"]; + } + if (![allKeys containsObject:@"playerGestureBottomSelection"]) { + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeSeek forKey:@"playerGestureBottomSelection"]; + } + // Default configuration options for gestures + if (![allKeys containsObject:@"playerGesturesDeadzone"]) { + [[NSUserDefaults standardUserDefaults] setFloat:20.0 forKey:@"playerGesturesDeadzone"]; + } + if (![allKeys containsObject:@"playerGesturesSensitivity"]) { + [[NSUserDefaults standardUserDefaults] setFloat:1.0 forKey:@"playerGesturesSensitivity"]; + } } diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index c3d75f6..a577d98 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "خيارات تراكب ضوابط الفيديو"; diff --git a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings index 899a13d..4689437 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Опции за контрол на видеото"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index 3af0bfe..76a63fe 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Overlay-Optionen für Videosteuerungen"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 4c5709e..9801761 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index 9c5d5f6..1cf7433 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opciones de superposición de controles de vídeo"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index 8528ba5..e788b97 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Options de l'overlay des contrôles vidéo"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 2d4998e..2749ff2 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "動画コントロールオーバーレイの設定"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 54e1961..df987ed 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 24c93e1..343c226 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opțiuni Overlay Controale Video"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index de4db99..5e6bb59 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index 51fb259..413a20a 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -31,6 +31,22 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index dbcb7b1..a9b0ea3 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Kontrol Seç."; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 2df3292..dd3fdb0 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -16,6 +16,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video player options "VIDEO_PLAYER_OPTIONS" = "Tùy chọn trình phát video"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index 7d3bffb..aef5cf3 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -17,6 +17,22 @@ "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brightness"; +"SEEK" = "Seek"; +"DISABLED" = "Disabled"; +"DEADZONE" = "Deadzone"; +"DEADZONE_DESC" = "Minimum distance to move before a gesture is recognized"; +"SENSITIVITY" = "Sensitivity"; +"SENSITIVITY_DESC" = "Multiplier on volume and brightness gestures"; +"PLAYER_GESTURES_TITLE" = "Player Gestures"; +"PLAYER_GESTURES_DESC" = "Configure horizontal pan gestures for the player"; +"TOP_SECTION" = "Top Section"; +"MIDDLE_SECTION" = "Middle Section"; +"BOTTOM_SECTION" = "Bottom Section"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定";