Merge pull request #358 from bhackel/gestures

Gestures and Loop
This commit is contained in:
Bryce Hackel
2024-08-20 00:52:28 -07:00
committed by GitHub
23 changed files with 681 additions and 33 deletions

3
.gitmodules vendored
View File

@@ -55,3 +55,6 @@
[submodule "Tweaks/YouTimeStamp"] [submodule "Tweaks/YouTimeStamp"]
path = Tweaks/YouTimeStamp path = Tweaks/YouTimeStamp
url = https://github.com/arichornloverALT/YouTimeStamp.git url = https://github.com/arichornloverALT/YouTimeStamp.git
[submodule "Tweaks/YouLoop"]
path = Tweaks/YouLoop
url = https://github.com/bhackel/YouLoop

View File

@@ -15,7 +15,7 @@ EXTRA_CFLAGS := $(addprefix -I,$(shell find Tweaks/FLEX -name '*.h' -exec dirnam
# Allow YouTubeHeader to be accessible using #include <...> # Allow YouTubeHeader to be accessible using #include <...>
export ADDITIONAL_CFLAGS = -I$(THEOS_PROJECT_DIR)/Tweaks 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_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_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) 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)/makefiles/common.mk
include $(THEOS_MAKE_PATH)/tweak.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 include $(THEOS_MAKE_PATH)/aggregate.mk
YTLITE_PATH = Tweaks/YTLite YTLITE_PATH = Tweaks/YTLite
@@ -46,6 +46,7 @@ before-package::
@cp -R Tweaks/YTVideoOverlay/layout/Library/Application\ Support/YTVideoOverlay.bundle Resources/ @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/YouQuality/layout/Library/Application\ Support/YouQuality.bundle Resources/
@cp -R Tweaks/YouTimeStamp/layout/Library/Application\ Support/YouTimeStamp.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/ @cp -R lang/YTLitePlus.bundle Resources/
@echo -e "==> \033[1mChanging the installation path of dylibs...\033[0m" @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 @ldid -r .theos/obj/iSponsorBlock.dylib && install_name_tool -change /usr/lib/libcolorpicker.dylib @rpath/libcolorpicker.dylib .theos/obj/iSponsorBlock.dylib

View File

@@ -1,9 +1,6 @@
#import "../YTLitePlus.h" #import "../YTLitePlus.h"
// // Low Contrast Mode
static BOOL IsEnabled(NSString *key) {
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
}
static int contrastMode() { static int contrastMode() {
return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"];
} }

View File

@@ -32,12 +32,6 @@
settingItemId:0] 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() { static int contrastMode() {
return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"];
} }
@@ -82,7 +76,7 @@ static const NSInteger YTLiteSection = 789;
%end %end
// Settings // Add YTLitePlus to the settings list
%hook YTAppSettingsPresentationData %hook YTAppSettingsPresentationData
+ (NSArray *)settingsCategoryOrder { + (NSArray *)settingsCategoryOrder {
NSArray *order = %orig; NSArray *order = %orig;
@@ -110,6 +104,7 @@ static const NSInteger YTLiteSection = 789;
Class YTSettingsSectionItemClass = %c(YTSettingsSectionItem); Class YTSettingsSectionItemClass = %c(YTSettingsSectionItem);
YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"];
// Add item for going to the YTLitePlus GitHub page
YTSettingsSectionItem *main = [%c(YTSettingsSectionItem) YTSettingsSectionItem *main = [%c(YTSettingsSectionItem)
itemWithTitle:[NSString stringWithFormat:LOC(@"VERSION"), @(OS_STRINGIFY(TWEAK_VERSION))] itemWithTitle:[NSString stringWithFormat:LOC(@"VERSION"), @(OS_STRINGIFY(TWEAK_VERSION))]
titleDescription:LOC(@"VERSION_CHECK") titleDescription:LOC(@"VERSION_CHECK")
@@ -237,6 +232,179 @@ static const NSInteger YTLiteSection = 789;
[sectionItems addObject:appIcon]; [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 <YTSettingsSectionItem *> *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<NSNumber *> *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 <YTSettingsSectionItem *> *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<NSNumber *> *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 <YTSettingsSectionItem *> *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 <YTSettingsSectionItem *> *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 # 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) { YTSettingsSectionItem *videoControlOverlayGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
NSArray <YTSettingsSectionItem *> *rows = @[ NSArray <YTSettingsSectionItem *> *rows = @[

View File

@@ -1,8 +1,5 @@
#import "../YTLitePlus.h" #import "../YTLitePlus.h"
static BOOL IsEnabled(NSString *key) {
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
}
static BOOL isDarkMode() { static BOOL isDarkMode() {
return ([[NSUserDefaults standardUserDefaults] integerForKey:@"page_style"] == 1); return ([[NSUserDefaults standardUserDefaults] integerForKey:@"page_style"] == 1);
} }

View File

@@ -1,9 +1,6 @@
#import "../YTLitePlus.h" #import "../YTLitePlus.h"
//
static BOOL IsEnabled(NSString *key) {
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
}
static int appVersionSpoofer() { static int appVersionSpoofer() {
return [[NSUserDefaults standardUserDefaults] integerForKey:@"versionSpoofer"]; return [[NSUserDefaults standardUserDefaults] integerForKey:@"versionSpoofer"];
} }

1
Tweaks/YouLoop Submodule

Submodule Tweaks/YouLoop added at 5a424d7531

View File

@@ -6,10 +6,11 @@
#import <sys/utsname.h> #import <sys/utsname.h>
#import <substrate.h> #import <substrate.h>
#import <rootless.h> #import <rootless.h>
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>
#import <AVKit/AVKit.h> // For AVPlayer and AVPlayerViewController #import <AVKit/AVKit.h> // For AVPlayer and AVPlayerViewController
#import <MobileCoreServices/MobileCoreServices.h> // For kUTTypeMovie and kUTTypeVideo #import <MobileCoreServices/MobileCoreServices.h> // For kUTTypeMovie and kUTTypeVideo
#import "Tweaks/FLEX/FLEX.h" #import "Tweaks/FLEX/FLEX.h"
#import "Tweaks/YouTubeHeader/YTAppDelegate.h" #import "Tweaks/YouTubeHeader/YTAppDelegate.h"
#import "Tweaks/YouTubeHeader/YTPlayerViewController.h" #import "Tweaks/YouTubeHeader/YTPlayerViewController.h"
@@ -43,6 +44,8 @@
#import "Tweaks/YouTubeHeader/YTPlayerBarController.h" #import "Tweaks/YouTubeHeader/YTPlayerBarController.h"
#import "Tweaks/YouTubeHeader/YTResponder.h" #import "Tweaks/YouTubeHeader/YTResponder.h"
#import "Tweaks/YouTubeHeader/YTMainAppControlsOverlayView.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 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"
@@ -51,6 +54,30 @@
#define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k]
#define APP_THEME_IDX [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] #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 // YTSpeed
@interface YTVarispeedSwitchControllerOption : NSObject @interface YTVarispeedSwitchControllerOption : NSObject
- (id)initWithTitle:(id)title rate:(float)rate; - (id)initWithTitle:(id)title rate:(float)rate;
@@ -125,6 +152,17 @@
@property id <YTResponder> parentResponder; @property id <YTResponder> parentResponder;
@end @end
// Player Gestures - @bhackel
@interface YTPlayerViewController (YTLitePlus) <UIGestureRecognizerDelegate>
@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 // Hide Collapse Button - @arichornlover
@interface YTMainAppControlsOverlayView (YTLitePlus) @interface YTMainAppControlsOverlayView (YTLitePlus)
@property (nonatomic, assign, readwrite) YTQTMButton *watchCollapseButton; @property (nonatomic, assign, readwrite) YTQTMButton *watchCollapseButton;

View File

@@ -33,11 +33,6 @@ static NSString *accessGroupID() {
return accessGroup; return accessGroup;
} }
//
static BOOL IsEnabled(NSString *key) {
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
}
# pragma mark - Tweaks # pragma mark - Tweaks
// Activate FLEX // Activate FLEX
@@ -645,6 +640,213 @@ BOOL isTabSelected = NO;
} }
%end %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 // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer
%group Main %group Main
@@ -874,6 +1076,9 @@ BOOL isTabSelected = NO;
if (IsEnabled(@"disableEngagementOverlay_enabled")) { if (IsEnabled(@"disableEngagementOverlay_enabled")) {
%init(gDisableEngagementOverlay); %init(gDisableEngagementOverlay);
} }
if (IsEnabled(@"playerGestures_enabled")) {
%init(playerGestures);
}
// Change the default value of some options // Change the default value of some options
NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys];
@@ -889,4 +1094,21 @@ BOOL isTabSelected = NO;
if (![allKeys containsObject:@"fixCasting_enabled"]) { if (![allKeys containsObject:@"fixCasting_enabled"]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"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"];
}
} }

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "خيارات تراكب ضوابط الفيديو"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "خيارات تراكب ضوابط الفيديو";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Опции за контрол на видеото"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Опции за контрол на видеото";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Overlay-Optionen für Videosteuerungen"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Overlay-Optionen für Videosteuerungen";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Opciones de superposición de controles de vídeo"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opciones de superposición de controles de vídeo";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Options de l'overlay des contrôles vidéo"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Options de l'overlay des contrôles vidéo";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "動画コントロールオーバーレイの設定"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "動画コントロールオーバーレイの設定";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "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

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Opțiuni Overlay Controale Video"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opțiuni Overlay Controale Video";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View File

@@ -31,6 +31,22 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Video Controls Overlay Options"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Controls Overlay Options";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "Video Kontrol Seç."; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Video Kontrol Seç.";

View File

@@ -16,6 +16,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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
"VIDEO_PLAYER_OPTIONS" = "Tùy chọn trình phát video"; "VIDEO_PLAYER_OPTIONS" = "Tùy chọn trình phát video";

View File

@@ -17,6 +17,22 @@
"VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER" = "Video Player (Beta)";
"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; "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" = "影片區覆蓋按鈕設定"; "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定";