From 00bb15a868b506af3ec6daff3d5885f9efee2797 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 7 Aug 2024 00:45:08 +0000 Subject: [PATCH 001/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 1492fa9..2f8472a 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 1492fa9598a79461a79f371c64a22888a6ed6fa0 +Subproject commit 2f8472adc1cbf5d0b86d9ca52671f51363b41011 From d731dbddeca24a6e70764fb8433f75088e5cb88c Mon Sep 17 00:00:00 2001 From: arichornlover <78001398+arichornlover@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:06:02 -0500 Subject: [PATCH 002/102] Fix LowContrastMode description also added Version compatibility, LowContrastMode will not work once v17.38.10 is gone in the future. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e512e0..5277147 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ 20. **OLDDarkmode**: Replace new official Youtube darkmode with old (grey) Youtube darkmode. -21. **LowContrastMode**: Makes the YouTube Interface Low Contrast as possible to make it easier on the eyes. +21. **LowContrastMode**: Makes the UI interface look dimmer to make it easier on the eyes. (App Compatibility: v17.33.2-v17.38.10) # AltStore From df3d09e81d21e67b9d87505155f97071e5fd6201 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Tue, 6 Aug 2024 22:36:59 -0700 Subject: [PATCH 003/102] Gesture test using YTHFS code --- Source/Settings.xm | 3 ++- YTLitePlus.xm | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index ca3518d..aad8fde 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -114,7 +114,7 @@ static const NSInteger YTLiteSection = 789; accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/Balackburn/YTLitePlus/releases/latest"]]; + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/YTLitePlus/YTLitePlus/releases/latest"]]; }]; [sectionItems addObject:main]; @@ -231,6 +231,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"ALWAYS_USE_REMAINING_TIME"), LOC(@"ALWAYS_USE_REMAINING_TIME_DESC"), @"alwaysShowRemainingTime_enabled"), BASIC_SWITCH(LOC(@"DISABLE_TOGGLE_TIME_REMAINING"), LOC(@"DISABLE_TOGGLE_TIME_REMAINING_DESC"), @"disableRemainingTime_enabled"), BASIC_SWITCH(LOC(@"DISABLE_ENGAGEMENT_OVERLAY"), LOC(@"DISABLE_ENGAGEMENT_OVERLAY_DESC"), @"disableEngagementOverlay_enabled"), + BASIC_SWITCH(LOC(@"ENABLE_UYOU_GESTURES"), LOC(@"ENABLE_UYOU_GESTURES_DESC"), @"uYouGestures_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index b9d5a9e..8032c1f 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -542,6 +542,52 @@ BOOL isTabSelected = NO; } %end +@interface YTPlayerViewController (YTLitePlus) +// the long press gesture that will be created and added to the player view +@property (nonatomic, retain) UILongPressGestureRecognizer *YTLitePlusLongPressGesture; +@end + +// Gestures - @bhackel +%group uYouGestures +%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 long press gesture is already created + if (!playerViewController.YTLitePlusLongPressGesture) { + playerViewController.YTLitePlusLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:playerViewController + action:@selector(YTLitePlusHandleLongPressGesture:)]; + playerViewController.YTLitePlusLongPressGesture.numberOfTouchesRequired = 1; + playerViewController.YTLitePlusLongPressGesture.allowableMovement = 50; + playerViewController.YTLitePlusLongPressGesture.minimumPressDuration = 0.5; + [playerViewController.playerView addGestureRecognizer:playerViewController.YTLitePlusLongPressGesture]; + } + } + %orig; +} +%end + +%hook YTPlayerViewController +// the long press gesture that will be created and added to the player view +%property (nonatomic, retain) UILongPressGestureRecognizer *YTLitePlusLongPressGesture; +%new +- (void)YTLitePlusHandleLongPressGesture:(UILongPressGestureRecognizer *)longPressGestureRecognizer +{ + if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) { + UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; + [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; + feedbackGenerator = nil; + } + // create a popup for debugging + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Long Press Gesture" message:@"Long Press Gesture Detected" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; + [alert addAction:okAction]; + [self presentViewController:alert animated:YES completion:nil]; + +} +%end +%end + // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main %hook YTWatchMiniBarView @@ -756,6 +802,9 @@ BOOL isTabSelected = NO; if (IsEnabled(@"disableEngagementOverlay_enabled")) { %init(gDisableEngagementOverlay); } + if (IsEnabled(@"uYouGestures_enabled")) { + %init(uYouGestures); + } // Change the default value of some options NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; From d4679b8414cfa6d5949f117d4bff7e441537b64e Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Tue, 6 Aug 2024 23:49:31 -0700 Subject: [PATCH 004/102] Attempt Volume Sliding --- YTLitePlus.h | 4 +++ YTLitePlus.xm | 90 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index f2de2c4..dcd9435 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -6,6 +6,8 @@ #import #import #import +#import +#import #import "Tweaks/FLEX/FLEX.h" #import "Tweaks/YouTubeHeader/YTAppDelegate.h" @@ -39,6 +41,8 @@ #import "Tweaks/YouTubeHeader/YTWatchPullToFullController.h" #import "Tweaks/YouTubeHeader/YTPlayerBarController.h" #import "Tweaks/YouTubeHeader/YTResponder.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" diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 8032c1f..95393e4 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -544,7 +544,12 @@ BOOL isTabSelected = NO; @interface YTPlayerViewController (YTLitePlus) // the long press gesture that will be created and added to the player view -@property (nonatomic, retain) UILongPressGestureRecognizer *YTLitePlusLongPressGesture; +@property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; +@end +@interface YTWatchFullscreenViewController : YTMultiSizeViewController +@end +@interface MPVolumeController : NSObject +@property (nonatomic, assign, readwrite) float volumeValue; @end // Gestures - @bhackel @@ -553,14 +558,11 @@ BOOL isTabSelected = NO; // 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 long press gesture is already created - if (!playerViewController.YTLitePlusLongPressGesture) { - playerViewController.YTLitePlusLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:playerViewController - action:@selector(YTLitePlusHandleLongPressGesture:)]; - playerViewController.YTLitePlusLongPressGesture.numberOfTouchesRequired = 1; - playerViewController.YTLitePlusLongPressGesture.allowableMovement = 50; - playerViewController.YTLitePlusLongPressGesture.minimumPressDuration = 0.5; - [playerViewController.playerView addGestureRecognizer:playerViewController.YTLitePlusLongPressGesture]; + // check to see if the pan gesture is already created + if (!playerViewController.YTLitePlusPanGesture) { + playerViewController.YTLitePlusPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:playerViewController + action:@selector(YTLitePlusHandlePanGesture:)]; + [playerViewController.playerView addGestureRecognizer:playerViewController.YTLitePlusPanGesture]; } } %orig; @@ -568,26 +570,74 @@ BOOL isTabSelected = NO; %end %hook YTPlayerViewController -// the long press gesture that will be created and added to the player view -%property (nonatomic, retain) UILongPressGestureRecognizer *YTLitePlusLongPressGesture; +// the pan gesture that will be created and added to the player view +%property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; %new -- (void)YTLitePlusHandleLongPressGesture:(UILongPressGestureRecognizer *)longPressGestureRecognizer -{ - if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) { +- (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { + static float initialVolume; + + if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { + // Store the initial volume at the beginning of the pan gesture + initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + } + + if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { + // Calculate the horizontal translation + CGPoint translation = [panGestureRecognizer translationInView:self.view]; + float newVolume = initialVolume + (translation.x / 1000.0); // Adjust the divisor to control the sensitivity + + // Clamp the volume between 0 and 1 + newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + + /* + // Navigate to existing volume slider view + YTWatchViewController *watchViewController = (YTWatchViewController *)[self valueForKey:@"_parentViewController"]; + YTWatchLayerViewController *watchLayerViewController = (YTWatchLayerViewController *)[watchViewController valueForKey:@"_watchLayerViewController"]; + YTWatchFullscreenViewController *watchFullscreenViewController = (YTWatchFullscreenViewController *)[watchLayerViewController valueForKey:@"_fullscreenViewController"]; + MPVolumeView *volumeView = (MPVolumeView *)[watchFullscreenViewController valueForKey:@"_hiddenVolumeView"]; + + // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4/50740074#50740074 + UISlider *volumeViewSlider = nil; + for (UIView *view in volumeView.subviews) { + if ([view isKindOfClass:[UISlider class]]) { + volumeViewSlider = (UISlider *)view; + break; + } + } + // Get the controller from this view + MPVolumeController *volumeController = [volumeViewSlider valueForKey:@"volumeController"]; + // Set the volume + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + volumeController.volumeValue = newVolume; + }); + */ + + 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; + }); + } + + if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { + // Haptic feedback UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; feedbackGenerator = nil; } - // create a popup for debugging - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Long Press Gesture" message:@"Long Press Gesture Detected" preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; - [alert addAction:okAction]; - [self presentViewController:alert animated:YES completion:nil]; - } %end %end + // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main %hook YTWatchMiniBarView From 09ddc42e32b6f9c734f78f7f45f4a3c8c2d0b31e Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 7 Aug 2024 12:11:03 -0700 Subject: [PATCH 005/102] Add reporting option --- .github/ISSUE_TEMPLATE/bug.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index 904179d..fb904ed 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -77,6 +77,7 @@ body: options: - buildapp.yml (GitHub Actions) - build.sh (Shell script) + - Downloaded from third party validations: required: true From e7523dc08dec20db31c82af020ad72e28b201362 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 8 Aug 2024 00:44:57 +0000 Subject: [PATCH 006/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 2f8472a..2ed410a 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 2f8472adc1cbf5d0b86d9ca52671f51363b41011 +Subproject commit 2ed410a9ca29085078a19172707a05980c4c7529 From f2e7c234eb499fd2434b607cbfdc3ce508266680 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 9 Aug 2024 00:45:23 +0000 Subject: [PATCH 007/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 2ed410a..903c3f1 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 2ed410a9ca29085078a19172707a05980c4c7529 +Subproject commit 903c3f15b04d99ab88cee53e4cec9464ef292bce From 91290efdfe7394aa78871aa10f2aec160d6cbf79 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 7 Aug 2024 13:24:51 -0700 Subject: [PATCH 008/102] Allow other gestures --- YTLitePlus.xm | 89 ++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 95393e4..5c9c210 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -542,9 +542,10 @@ BOOL isTabSelected = NO; } %end -@interface YTPlayerViewController (YTLitePlus) +@interface YTPlayerViewController (YTLitePlus) // the long press gesture that will be created and added to the player view @property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; @end @interface YTWatchFullscreenViewController : YTMultiSizeViewController @end @@ -562,78 +563,80 @@ BOOL isTabSelected = NO; 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 { static float initialVolume; + static BOOL isHorizontalPan = NO; if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { // Store the initial volume at the beginning of the pan gesture initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + // Reset the horizontal pan flag + isHorizontalPan = NO; } if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { - // Calculate the horizontal translation + // Calculate the translation CGPoint translation = [panGestureRecognizer translationInView:self.view]; - float newVolume = initialVolume + (translation.x / 1000.0); // Adjust the divisor to control the sensitivity - // Clamp the volume between 0 and 1 - newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); - - /* - // Navigate to existing volume slider view - YTWatchViewController *watchViewController = (YTWatchViewController *)[self valueForKey:@"_parentViewController"]; - YTWatchLayerViewController *watchLayerViewController = (YTWatchLayerViewController *)[watchViewController valueForKey:@"_watchLayerViewController"]; - YTWatchFullscreenViewController *watchFullscreenViewController = (YTWatchFullscreenViewController *)[watchLayerViewController valueForKey:@"_fullscreenViewController"]; - MPVolumeView *volumeView = (MPVolumeView *)[watchFullscreenViewController valueForKey:@"_hiddenVolumeView"]; - - // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4/50740074#50740074 - UISlider *volumeViewSlider = nil; - for (UIView *view in volumeView.subviews) { - if ([view isKindOfClass:[UISlider class]]) { - volumeViewSlider = (UISlider *)view; - break; + // Determine if the gesture is predominantly horizontal + if (!isHorizontalPan) { + if (fabs(translation.x) > fabs(translation.y)) { + isHorizontalPan = YES; + } else { + // If vertical movement is greater, cancel the gesture recognizer + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; } } - // Get the controller from this view - MPVolumeController *volumeController = [volumeViewSlider valueForKey:@"volumeController"]; - // Set the volume - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - volumeController.volumeValue = newVolume; - }); - */ - - MPVolumeView *volumeView = [[MPVolumeView alloc] init]; - UISlider *volumeViewSlider = nil; - - for (UIView *view in volumeView.subviews) { - if ([view isKindOfClass:[UISlider class]]) { - volumeViewSlider = (UISlider *)view; - break; + + if (isHorizontalPan) { + float newVolume = initialVolume + (translation.x / 1000.0); // Adjust the divisor to control the sensitivity + + // Clamp the volume between 0 and 1 + newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + + // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4/50740074#50740074 + 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; + }); } - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - volumeViewSlider.value = newVolume; - }); } if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { - // Haptic feedback - UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; - [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; - feedbackGenerator = nil; + if (isHorizontalPan) { + // Haptic feedback + UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; + [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; + feedbackGenerator = nil; + } } } + +// allow the pan gesture to be recognized simultaneously with other gestures +%new +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + return YES; +} + %end %end From 64c712d630c7125b3ae41daec7c1b86a3778cc4c Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:51:12 -0700 Subject: [PATCH 009/102] Attempt brightness and volume gestures --- YTLitePlus.xm | 65 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 5c9c210..4c49cee 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -576,17 +576,32 @@ BOOL isTabSelected = NO; %new - (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { static float initialVolume; + static float initialBrightness; static BOOL isHorizontalPan = NO; + static NSInteger gestureSection = 0; // 1 for brightness, 2 for volume, 3 for seeking if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { - // Store the initial volume at the beginning of the pan gesture - initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + // Get the gesture's start position + CGPoint startLocation = [panGestureRecognizer locationInView:self.view]; + CGFloat viewHeight = self.view.bounds.size.height; + + // Determine the section based on the start position + if (startLocation.y <= viewHeight / 3.0) { + gestureSection = 1; // Top third: Brightness + initialBrightness = [UIScreen mainScreen].brightness; + } else if (startLocation.y <= 2 * viewHeight / 3.0) { + gestureSection = 2; // Middle third: Volume + initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + } else { + gestureSection = 3; // Bottom third: Seeking + } + // Reset the horizontal pan flag isHorizontalPan = NO; } if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { - // Calculate the translation + // Calculate the translation of the gesture CGPoint translation = [panGestureRecognizer translationInView:self.view]; // Determine if the gesture is predominantly horizontal @@ -600,30 +615,42 @@ BOOL isTabSelected = NO; } } + // Handle the gesture based on the identified section if (isHorizontalPan) { - float newVolume = initialVolume + (translation.x / 1000.0); // Adjust the divisor to control the sensitivity - - // Clamp the volume between 0 and 1 - newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); - - // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4/50740074#50740074 - MPVolumeView *volumeView = [[MPVolumeView alloc] init]; - UISlider *volumeViewSlider = nil; - for (UIView *view in volumeView.subviews) { - if ([view isKindOfClass:[UISlider class]]) { - volumeViewSlider = (UISlider *)view; - break; + if (gestureSection == 1) { + // Top third: Adjust brightness + float newBrightness = initialBrightness + (translation.x / 1000.0); + newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0); + [[UIScreen mainScreen] setBrightness:newBrightness]; + + } else if (gestureSection == 2) { + // Middle third: Adjust volume + float newVolume = initialVolume + (translation.x / 1000.0); + newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + + 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; + }); + + } else if (gestureSection == 3) { + // Bottom third: Seek functionality (implement your seeking logic here) + // Example: Adjust playback position based on horizontal swipe + // (Add your media player's seeking logic here) } - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - volumeViewSlider.value = newVolume; - }); } } if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { if (isHorizontalPan) { - // Haptic feedback + // Provide haptic feedback upon successful gesture recognition UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; feedbackGenerator = nil; From 37582ecbf88040dcddf73ae15e68024b2128d845 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 10 Aug 2024 00:44:53 +0000 Subject: [PATCH 010/102] updated submodules --- Tweaks/Return-YouTube-Dislikes | 2 +- Tweaks/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tweaks/Return-YouTube-Dislikes b/Tweaks/Return-YouTube-Dislikes index 12c4c05..0f4c6b7 160000 --- a/Tweaks/Return-YouTube-Dislikes +++ b/Tweaks/Return-YouTube-Dislikes @@ -1 +1 @@ -Subproject commit 12c4c05aec6e10c618b7fb175bd903c6c4227e7f +Subproject commit 0f4c6b7f5960308161c870d9aab30905fe8145cc diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 903c3f1..b9d1cff 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 903c3f15b04d99ab88cee53e4cec9464ef292bce +Subproject commit b9d1cfff8ca6814723889bade011f3fa4675d46d From 948ea5ff2906aec19c83727d5f5b16d1cc81a0ad Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 10 Aug 2024 00:53:31 +0000 Subject: [PATCH 011/102] updated submodules --- Tweaks/Return-YouTube-Dislikes | 2 +- Tweaks/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tweaks/Return-YouTube-Dislikes b/Tweaks/Return-YouTube-Dislikes index 12c4c05..0f4c6b7 160000 --- a/Tweaks/Return-YouTube-Dislikes +++ b/Tweaks/Return-YouTube-Dislikes @@ -1 +1 @@ -Subproject commit 12c4c05aec6e10c618b7fb175bd903c6c4227e7f +Subproject commit 0f4c6b7f5960308161c870d9aab30905fe8145cc diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 903c3f1..b9d1cff 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 903c3f15b04d99ab88cee53e4cec9464ef292bce +Subproject commit b9d1cfff8ca6814723889bade011f3fa4675d46d From 4f2b55a897f03e166103c0823e54935554c32dfa Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:34:57 -0700 Subject: [PATCH 012/102] Hide comment previews by @arichornlover --- Source/Settings.xm | 1 + YTLitePlus.xm | 19 +++++++++++++++++++ .../ar.lproj/Localizable.strings | 3 +++ .../de.lproj/Localizable.strings | 3 +++ .../en.lproj/Localizable.strings | 3 +++ .../es.lproj/Localizable.strings | 3 +++ .../fr.lproj/Localizable.strings | 3 +++ .../ja.lproj/Localizable.strings | 3 +++ .../pt.lproj/Localizable.strings | 3 +++ .../ro.lproj/Localizable.strings | 3 +++ .../ru.lproj/Localizable.strings | 3 +++ .../template.lproj/Localizable.strings | 3 +++ .../tr.lproj/Localizable.strings | 3 +++ .../vi.lproj/Localizable.strings | 3 +++ .../zh_TW.lproj/Localizable.strings | 18 ++++++++++++++++++ 15 files changed, 74 insertions(+) diff --git a/Source/Settings.xm b/Source/Settings.xm index ca3518d..d809a9e 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -231,6 +231,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"ALWAYS_USE_REMAINING_TIME"), LOC(@"ALWAYS_USE_REMAINING_TIME_DESC"), @"alwaysShowRemainingTime_enabled"), BASIC_SWITCH(LOC(@"DISABLE_TOGGLE_TIME_REMAINING"), LOC(@"DISABLE_TOGGLE_TIME_REMAINING_DESC"), @"disableRemainingTime_enabled"), BASIC_SWITCH(LOC(@"DISABLE_ENGAGEMENT_OVERLAY"), LOC(@"DISABLE_ENGAGEMENT_OVERLAY_DESC"), @"disableEngagementOverlay_enabled"), + BASIC_SWITCH(LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER"), LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC"), @"hidePreviewCommentSection_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index b9d5a9e..d666a27 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -542,6 +542,25 @@ BOOL isTabSelected = NO; } %end + +// Hide the Comment Section Previews under the Video Player - @arichornlover +%hook _ASDisplayView +- (void)didMoveToWindow { + %orig; + if ((IsEnabled(@"hidePreviewCommentSection_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"id.ui.comments_entry_point_teaser"])) { + self.hidden = YES; + self.opaque = YES; + self.userInteractionEnabled = NO; + CGRect bounds = self.frame; + bounds.size.height = 0; + self.frame = bounds; + [self.superview layoutIfNeeded]; + [self setNeedsLayout]; + [self removeFromSuperview]; + } +} +%end + // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main %hook YTWatchMiniBarView diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index 65033e0..d431cf6 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index 6a646dc..165978f 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Overlay-Optionen für App-Einstellungen"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index abb87ee..29ee33c 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index 5487a67..a2c2da3 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Desactivar la superposición de compromiso a pantalla completa"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desactivar el gesto de deslizar hacia arriba y la lista de vídeos sugeridos en pantalla completa"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opciones de superposición de los ajustes de la aplicación"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index edbf12b..49bb669 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Paramètres des options d'overlay de l'application"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 17bb1c4..794038b 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "プレーヤー下のコメントプレビューを隠す"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "プレーヤーの下にあるコメントのプレビューを非表示にします。"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "アプリの設定オーバーレイの設定"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index e829c49..f4014f7 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Desativar sobreposição de engajamento em tela cheia"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desativa o gesto de deslizar para cima e a lista de vídeos sugeridos em tela cheia"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 018886c..fde5937 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opțiuni Overlay Setări Aplicație"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index f2245c6..32b201c 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index b0ba5c7..de571b5 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -62,6 +62,9 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index 5220806..3b58ba0 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -47,6 +47,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Tam ekranda kaplamayı kapat"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Tam ekranda yukarı kaydırma hareketini ve önerilen videoları kapat"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Oynatıcının Altındaki Yorum Önizlemelerini Gizle"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Video oynatıcının altındaki yorum önizlemelerini gizler."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Uyg. Ayarları Kaplama Seç."; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 12f1e32..5050e13 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -56,6 +56,9 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // Shorts controls overlay options "SHORTS_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển quần short"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index 001af33..8176bc0 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -33,6 +33,24 @@ "SEEK_ANYWHERE" = "Seek Anywhere Gesture"; "SEEK_ANYWHERE_DESC" = "Hold and drag on the video player to seek. You must disable YTLite - Hold to speed"; +"ENABLE_TAP_TO_SEEK" = "Enable Tap To Seek"; +"ENABLE_TAP_TO_SEEK_DESC" = "Jump to anywhere in a video by single-tapping the seek bar"; + +"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Disable pull-to-fullscreen gesture"; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Disable the drag gesture to enter vertical fullscreen. Only applies to landscape videos."; + +"ALWAYS_USE_REMAINING_TIME" = "Always use remaining time"; +"ALWAYS_USE_REMAINING_TIME_DESC" = "Change the default to show time remaining in the player bar."; + +"DISABLE_TOGGLE_TIME_REMAINING" = "Disable toggle time remaining"; +"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Disables changing time elapsed to time remaining. Use with other setting to always show remaining time."; + +"DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; +"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; + +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "應用程式設定隱藏項目"; From 794fb561c9d256dca532b6a6b07525479d672114 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:29:34 -0700 Subject: [PATCH 013/102] Fix import export settings localization --- lang/YTLitePlus.bundle/ar.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/de.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/en.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/es.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/fr.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/ja.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/pt.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/ro.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/ru.lproj/Localizable.strings | 11 +++++++++++ .../template.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/tr.lproj/Localizable.strings | 11 +++++++++++ lang/YTLitePlus.bundle/vi.lproj/Localizable.strings | 11 +++++++++++ .../YTLitePlus.bundle/zh_TW.lproj/Localizable.strings | 11 +++++++++++ 13 files changed, 143 insertions(+) diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index d431cf6..9669e33 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "نسخة YTLitePlus: %@"; "VERSION_CHECK" = "انقر للتحقق من وجود تحديث"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 165978f..41c62eb 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tippe hier, um nach Updates zu suchen!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 29ee33c..1964212 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 a2c2da3..b5d54cd 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "Versión de YTLitePlus: %@"; "VERSION_CHECK" = "Pulse para comprobar si hay actualizaciones."; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 49bb669..22fda27 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlus version : %@"; "VERSION_CHECK" = "Appuyez pour vérifier les mises à jour !"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 794038b..9782bf5 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlusのバージョン: %@"; "VERSION_CHECK" = "タップして更新をチェック!"; +"COPY_SETTINGS" = "設定をコピー"; +"COPY_SETTINGS_DESC" = "現在のすべての設定をクリップボードにコピーします"; +"PASTE_SETTINGS" = "設定を貼り付け"; +"PASTE_SETTINGS_DESC" = "クリップボードから設定を貼り付けて適用します"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 f4014f7..210e80d 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "Versão do YTLitePlus: %@"; "VERSION_CHECK" = "Toque para verificar se há atualização!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 fde5937..52e72e6 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "Versiune YTLitePlus: %@"; "VERSION_CHECK" = "Căutați actualizări"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 32b201c..c49d2b1 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 de571b5..ddb0f44 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -17,6 +17,17 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 3b58ba0..fe4b8b6 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "YTLitePlus'ın sürümü: %@"; "VERSION_CHECK" = "Güncelleme için dokunun!"; +"COPY_SETTINGS" = "Ayarları Kopyala"; +"COPY_SETTINGS_DESC" = "Tüm mevcut ayarları panoya kopyala"; +"PASTE_SETTINGS" = "Ayarları Yapıştır"; +"PASTE_SETTINGS_DESC" = "Panodaki ayarları yapıştır ve uygula"; +"EXPORT_SETTINGS" = "Ayarları Dışa Aktar"; +"EXPORT_SETTINGS_DESC" = "Tüm mevcut ayarları bir .txt dosyasına dışa aktarır"; +"IMPORT_SETTINGS" = "Ayarları İçe Aktar"; +"IMPORT_SETTINGS_DESC" = "Ayarları içe aktarmak için basın (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "'Ayarları Kopyala' ve 'Ayarları Yapıştır' Düğmelerini Değiştir"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Düğmeleri 'Ayarları Dışa Aktar' ve 'Ayarları İçe Aktar' ile değiştirir"; + // 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 5050e13..995ee22 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -2,6 +2,17 @@ "VERSION" = "Phiên bản của CercubePlus: %@"; "VERSION_CHECK" = "Nhấn để kiểm tra cập nhật!"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // 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 8176bc0..b78242d 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -3,6 +3,17 @@ "VERSION" = "YTLitePlus 版本:%@"; "VERSION_CHECK" = "檢查更新"; +"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; +"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; +"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定"; From 11a3e75b0de971727d6b085e3fd99a94c364e199 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 16:44:59 -0700 Subject: [PATCH 014/102] Default disable big mini player --- YTLitePlus.xm | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index d666a27..1c6e9af 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -561,6 +561,7 @@ BOOL isTabSelected = NO; } %end +/* // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main %hook YTWatchMiniBarView @@ -585,6 +586,20 @@ BOOL isTabSelected = NO; } %end %end +*/ +// New Big YT Mini Player - @bhackel +%hook YTColdConfig +- (BOOL)enableIosFloatingMiniplayer { + // Modify if not on iPad + return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; +} +- (BOOL)enableIosFloatingMiniplayerRepositioning { + return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; +} +- (BOOL)enableIosFloatingMiniplayerResizing { + return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; +} +%end // App Settings Overlay Options %group gDisableAccountSection @@ -718,9 +733,9 @@ BOOL isTabSelected = NO; if (IsEnabled(@"iPhoneLayout_enabled")) { %init(giPhoneLayout); } - if (IsEnabled(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) { - %init(Main); - } + // if (IsEnabled(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) { + // %init(Main); + // } if (IsEnabled(@"hideVideoPlayerShadowOverlayButtons_enabled")) { %init(gHideVideoPlayerShadowOverlayButtons); } From c9875ec8b70a0863cbb958e0a580d893bb90ec55 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:26:19 -0700 Subject: [PATCH 015/102] Fix localization, fix copy/paste switch --- Source/Settings.xm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index d809a9e..bb28324 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -114,7 +114,7 @@ static const NSInteger YTLiteSection = 789; accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/Balackburn/YTLitePlus/releases/latest"]]; + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/YTLitePlus/YTLitePlus/releases/latest"]]; }]; [sectionItems addObject:main]; @@ -197,8 +197,6 @@ static const NSInteger YTLiteSection = 789; ]; [sectionItems addObject:pasteSettings]; - BASIC_SWITCH(LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS"), LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS_DESC"), @"switchCopyandPasteFunctionality_enabled"); - /* YTSettingsSectionItem *appIcon = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"CHANGE_APP_ICON") @@ -252,14 +250,14 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"HIDE_PRIVACY_SECTION"), LOC(@"APP_RESTART_DESC"), @"disablePrivacySection_enabled"), BASIC_SWITCH(LOC(@"HIDE_LIVECHAT_SECTION"), LOC(@"APP_RESTART_DESC"), @"disableLiveChatSection_enabled") ]; - YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"App Settings Overlay Options") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"APP_SETTINGS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; return YES; }]; [sectionItems addObject:appSettingsOverlayGroup]; # pragma mark - LowContrastMode - YTSettingsSectionItem *lowContrastModeSection = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Low Contrast Mode") + YTSettingsSectionItem *lowContrastModeSection = [YTSettingsSectionItemClass itemWithTitle:LOC(@"LOW_CONTRAST_MODE") accessibilityIdentifier:nil detailTextBlock:^NSString *() { switch (contrastMode()) { @@ -283,7 +281,7 @@ static const NSInteger YTLiteSection = 789; return YES; }] ]; - YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Low Contrast Mode") pickerSectionTitle:nil rows:rows selectedItemIndex:contrastMode() parentResponder:[self parentResponder]]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"LOW_CONTRAST_MODE") pickerSectionTitle:nil rows:rows selectedItemIndex:contrastMode() parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; return YES; }]; @@ -355,7 +353,7 @@ static const NSInteger YTLiteSection = 789; return YES; }] ]; - YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:@"Version Spoofer Picker" pickerSectionTitle:nil rows:rows selectedItemIndex:appVersionSpoofer() parentResponder:[self parentResponder]]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:@"VERSION_SPOOFER_TITLE" pickerSectionTitle:nil rows:rows selectedItemIndex:appVersionSpoofer() parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; return YES; }]; @@ -461,6 +459,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"HIDE_SPONSORBLOCK_BUTTON"), LOC(@"HIDE_SPONSORBLOCK_BUTTON_DESC"), @"hideSponsorBlockButton_enabled"), BASIC_SWITCH(LOC(@"HIDE_HOME_TAB"), LOC(@"HIDE_HOME_TAB_DESC"), @"hideHomeTab_enabled"), BASIC_SWITCH(LOC(@"FIX_CASTING"), LOC(@"FIX_CASTING_DESC"), @"fixCasting_enabled"), + BASIC_SWITCH(LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS"), LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS_DESC"), @"switchCopyandPasteFunctionality_enabled"), BASIC_SWITCH(LOC(@"ENABLE_FLEX"), LOC(@"ENABLE_FLEX_DESC"), @"flex_enabled"), BASIC_SWITCH(LOC(@"APP_VERSION_SPOOFER_LITE"), LOC(@"APP_VERSION_SPOOFER_LITE_DESC"), @"enableVersionSpoofer_enabled"), versionSpooferSection From 753d690b78f09654cdb25621c3f9001cafbb1abf Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:38:19 -0700 Subject: [PATCH 016/102] Hide autoplay mini preview --- Source/Settings.xm | 1 + YTLitePlus.xm | 10 ++++++++++ lang/YTLitePlus.bundle/ar.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/de.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/en.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/es.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/fr.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ja.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/pt.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ro.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ru.lproj/Localizable.strings | 3 +++ .../template.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/tr.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/vi.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings | 3 +++ 15 files changed, 50 insertions(+) diff --git a/Source/Settings.xm b/Source/Settings.xm index bb28324..ffbe941 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -230,6 +230,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"DISABLE_TOGGLE_TIME_REMAINING"), LOC(@"DISABLE_TOGGLE_TIME_REMAINING_DESC"), @"disableRemainingTime_enabled"), BASIC_SWITCH(LOC(@"DISABLE_ENGAGEMENT_OVERLAY"), LOC(@"DISABLE_ENGAGEMENT_OVERLAY_DESC"), @"disableEngagementOverlay_enabled"), BASIC_SWITCH(LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER"), LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC"), @"hidePreviewCommentSection_enabled"), + BASIC_SWITCH(LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW"), LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW_DESC"), @"hideAutoplayMiniPreview_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 1c6e9af..0798571 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -561,6 +561,16 @@ BOOL isTabSelected = NO; } %end +// Hide Autoplay Mini Preview - @bhackel +%hook YTAutonavPreviewView +- (void)didMoveToWindow { + %orig; + if (IsEnabled(@"hideAutoplayMiniPreview_enabled")) { + self.hidden = YES; + } +} +%end + /* // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index 9669e33..041d6a6 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index 41c62eb..eedad7c 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Overlay-Optionen für App-Einstellungen"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 1964212..ffbe59a 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index b5d54cd..ff13867 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opciones de superposición de los ajustes de la aplicación"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index 22fda27..a784e9b 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Paramètres des options d'overlay de l'application"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 9782bf5..6b67d73 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "プレーヤー下のコメントプレビューを隠す"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "プレーヤーの下にあるコメントのプレビューを非表示にします。"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "アプリの設定オーバーレイの設定"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 210e80d..30133a2 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 52e72e6..49d413f 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opțiuni Overlay Setări Aplicație"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index c49d2b1..f29c9b2 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index ddb0f44..0d1e58d 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -76,6 +76,9 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index fe4b8b6..8db663c 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -61,6 +61,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Oynatıcının Altındaki Yorum Önizlemelerini Gizle"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Video oynatıcının altındaki yorum önizlemelerini gizler."; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Uyg. Ayarları Kaplama Seç."; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 995ee22..27fa187 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // Shorts controls overlay options "SHORTS_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển quần short"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index b78242d..bca5cf7 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -62,6 +62,9 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "應用程式設定隱藏項目"; From ba13d1b987938bd47faecbc0c185a121958bcdc1 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:44:51 -0700 Subject: [PATCH 017/102] Live Chat OLED dark mode --- YTLitePlus.h | 8 ++++++++ YTLitePlus.xm | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index f2de2c4..90611be 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -96,6 +96,14 @@ @property (nonatomic, assign, readwrite) BOOL enableSnapToChapter; @end +// Hide Autoplay Mini Preview - @bhackel +@interface YTAutonavPreviewView : UIView +@end + +// OLED Live Chat - @bhackel +@interface YTLUserDefaults : NSUserDefaults +@end + // Hide Home Tab - @bhackel @interface YTPivotBarViewController : UIViewController @property NSString *selectedPivotIdentifier; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 0798571..74c36b3 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -542,11 +542,10 @@ BOOL isTabSelected = NO; } %end - -// Hide the Comment Section Previews under the Video Player - @arichornlover %hook _ASDisplayView - (void)didMoveToWindow { %orig; + // Hide the Comment Section Previews under the Video Player - @arichornlover if ((IsEnabled(@"hidePreviewCommentSection_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"id.ui.comments_entry_point_teaser"])) { self.hidden = YES; self.opaque = YES; @@ -558,6 +557,12 @@ BOOL isTabSelected = NO; [self setNeedsLayout]; [self removeFromSuperview]; } + // Live chat OLED dark mode - @bhackel + if (([[YTLUserDefaults standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme + || [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 1 // YTLitePlus OLED Theme + ) && [self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"]) { + self.backgroundColor = [UIColor blackColor]; + } } %end From 762cd8f61807bf41ebae90f60a1880ccb15cc268 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 10 Aug 2024 00:47:05 -0700 Subject: [PATCH 018/102] Remove YTLitePlus OLED Theme --- Source/Settings.xm | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index ffbe941..93125ee 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -365,8 +365,6 @@ static const NSInteger YTLiteSection = 789; detailTextBlock:^NSString *() { switch (GetSelection(@"appTheme")) { case 1: - return LOC(@"OLED_DARK_THEME_2"); - case 2: return LOC(@"OLD_DARK_THEME"); case 0: default: @@ -380,13 +378,8 @@ static const NSInteger YTLiteSection = 789; [settingsViewController reloadData]; return YES; }], - [YTSettingsSectionItemClass checkmarkItemWithTitle:LOC(@"OLED_DARK_THEME") titleDescription:LOC(@"OLED_DARK_THEME_DESC") selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"appTheme"]; - [settingsViewController reloadData]; - return YES; - }], [YTSettingsSectionItemClass checkmarkItemWithTitle:LOC(@"OLD_DARK_THEME") titleDescription:LOC(@"OLD_DARK_THEME_DESC") selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - [[NSUserDefaults standardUserDefaults] setInteger:2 forKey:@"appTheme"]; + [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"appTheme"]; [settingsViewController reloadData]; return YES; }], From f64aab1b586f17cebab545ba2826735e0300ba73 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 10 Aug 2024 02:19:23 -0700 Subject: [PATCH 019/102] Fix build error --- YTLitePlus.xm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 74c36b3..a799e20 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -558,7 +558,7 @@ BOOL isTabSelected = NO; [self removeFromSuperview]; } // Live chat OLED dark mode - @bhackel - if (([[YTLUserDefaults standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme + if (([[%c(YTLUserDefaults) standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme || [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 1 // YTLitePlus OLED Theme ) && [self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"]) { self.backgroundColor = [UIColor blackColor]; From 1a9758770dc5c1946bfef4dd5969e5c3d6e3973b Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 10 Aug 2024 02:34:42 -0700 Subject: [PATCH 020/102] Fix bugs --- Source/Themes.xm | 11 +++-------- YTLitePlus.xm | 9 ++++++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Source/Themes.xm b/Source/Themes.xm index 75123db..4ea44b7 100644 --- a/Source/Themes.xm +++ b/Source/Themes.xm @@ -6,11 +6,8 @@ static BOOL IsEnabled(NSString *key) { static BOOL isDarkMode() { return ([[NSUserDefaults standardUserDefaults] integerForKey:@"page_style"] == 1); } -static BOOL oledDarkTheme() { - return ([[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 1); -} static BOOL oldDarkTheme() { - return ([[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 2); + return ([[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 1); } // Themes.xm - Theme Options @@ -402,7 +399,7 @@ UIColor *customColor = [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha: %end // OLED dark mode by @BandarHL and modified by @arichorn -UIColor* raisedColor = [UIColor blackColor]; +/* %group gOLED %hook YTCommonColorPalette - (UIColor *)background1 { @@ -788,6 +785,7 @@ UIColor* raisedColor = [UIColor blackColor]; } %end %end +*/ // OLED keyboard by @ichitaso <3 - http://gist.github.com/ichitaso/935100fd53a26f18a9060f7195a1be0e %group gOLEDKB @@ -837,9 +835,6 @@ UIColor* raisedColor = [UIColor blackColor]; if (IsEnabled(@"oledKeyBoard_enabled")) { %init(gOLEDKB); } - if (oledDarkTheme()) { - %init(gOLED); - } if (oldDarkTheme()) { %init(gOldDarkTheme); } diff --git a/YTLitePlus.xm b/YTLitePlus.xm index a799e20..bd0938b 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -568,12 +568,19 @@ BOOL isTabSelected = NO; // Hide Autoplay Mini Preview - @bhackel %hook YTAutonavPreviewView -- (void)didMoveToWindow { +- (void)layoutSubviews { %orig; if (IsEnabled(@"hideAutoplayMiniPreview_enabled")) { self.hidden = YES; } } +- (void)setHidden:(BOOL)arg1 { + if (IsEnabled(@"hideAutoplayMiniPreview_enabled")) { + %orig(YES); + } else { + %orig(arg1); + } +} %end /* From 08c263fdf01a53c382f2028bc849fee403b8783a Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 10 Aug 2024 04:07:47 -0700 Subject: [PATCH 021/102] Copy Hide HUD and Hide Collapse Button --- Source/Settings.xm | 3 ++ YTLitePlus.h | 5 +++ YTLitePlus.xm | 32 +++++++++++++++++++ .../ar.lproj/Localizable.strings | 6 ++++ .../de.lproj/Localizable.strings | 6 ++++ .../en.lproj/Localizable.strings | 6 ++++ .../es.lproj/Localizable.strings | 6 ++++ .../fr.lproj/Localizable.strings | 6 ++++ .../ja.lproj/Localizable.strings | 6 ++++ .../pt.lproj/Localizable.strings | 6 ++++ .../ro.lproj/Localizable.strings | 6 ++++ .../ru.lproj/Localizable.strings | 6 ++++ .../template.lproj/Localizable.strings | 6 ++++ .../tr.lproj/Localizable.strings | 6 ++++ .../vi.lproj/Localizable.strings | 6 ++++ .../zh_TW.lproj/Localizable.strings | 6 ++++ 16 files changed, 118 insertions(+) diff --git a/Source/Settings.xm b/Source/Settings.xm index 93125ee..331c9bf 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -231,6 +231,9 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"DISABLE_ENGAGEMENT_OVERLAY"), LOC(@"DISABLE_ENGAGEMENT_OVERLAY_DESC"), @"disableEngagementOverlay_enabled"), BASIC_SWITCH(LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER"), LOC(@"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC"), @"hidePreviewCommentSection_enabled"), BASIC_SWITCH(LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW"), LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW_DESC"), @"hideAutoplayMiniPreview_enabled"), + BASIC_SWITCH(LOC(@"HIDE_HUD_MESSAGES"), LOC(@"HIDE_HUD_MESSAGES_DESC"), @"hideHUD_enabled"), + BASIC_SWITCH(LOC(@"HIDE_COLLAPSE_BUTTON"), LOC(@"HIDE_COLLAPSE_BUTTON_DESC"), @"disableCollapseButton_enabled"), + ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.h b/YTLitePlus.h index 90611be..82d6ac1 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -39,6 +39,7 @@ #import "Tweaks/YouTubeHeader/YTWatchPullToFullController.h" #import "Tweaks/YouTubeHeader/YTPlayerBarController.h" #import "Tweaks/YouTubeHeader/YTResponder.h" +#import "Tweaks/YouTubeHeader/YTMainAppControlsOverlayView.h" #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define YT_BUNDLE_ID @"com.google.ios.youtube" @@ -121,6 +122,10 @@ @property id parentResponder; @end +// Hide Collapse Button - @arichornlover +@interface YTMainAppControlsOverlayView (YTLitePlus) +@property (nonatomic, assign, readwrite) YTQTMButton *watchCollapseButton; +@end // SponsorBlock button in Nav bar @interface MDCButton : UIButton diff --git a/YTLitePlus.xm b/YTLitePlus.xm index bd0938b..c4248cb 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -583,6 +583,38 @@ BOOL isTabSelected = NO; } %end +// Hide HUD Messages - @qnblackcat +%hook YTHUDMessageView +- (id)initWithMessage:(id)arg1 dismissHandler:(id)arg2 { + return IsEnabled(@"hideHUD_enabled") ? nil : %orig; +} +%end + +// Hide Video Player Collapse Button - @arichornlover +%hook YTMainAppControlsOverlayView +- (void)layoutSubviews { + %orig; + if (IsEnabled(@"disableCollapseButton_enabled")) { + if (self.watchCollapseButton) { + [self.watchCollapseButton removeFromSuperview]; + } + } +} +- (BOOL)watchCollapseButtonHidden { + if (IsEnabled(@"disableCollapseButton_enabled")) { + return YES; + } else { + return %orig; + } +} +- (void)setWatchCollapseButtonAvailable:(BOOL)available { + if (IsEnabled(@"disableCollapseButton_enabled")) { + } else { + %orig(available); + } +} +%end + /* // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index 041d6a6..496cfb4 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "إخفاء رسائل المعلومات"; +"HIDE_HUD_MESSAGES_DESC" = "مثلاً: تم إيقاف الترجمة..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index eedad7c..8d1dee7 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "HUD-Nachrichten ausblenden"; +"HIDE_HUD_MESSAGES_DESC" = "z.B.: Untertitel sind aktiviert/deaktiviert, Videoschleife ist an, ..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Overlay-Optionen für App-Einstellungen"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index ffbe59a..6c805d4 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Hide HUD messages"; +"HIDE_HUD_MESSAGES_DESC" = "Hides snackbars that display for certain actions (e.g., CC turned on/off)"; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index ff13867..6b1d700 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Ocultar mensajes HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Ejemplo: CC está activado/desactivado, Vídeo en bucle está activado,..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opciones de superposición de los ajustes de la aplicación"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index a784e9b..ec9a68c 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Masquer les messages de l'ATH"; +"HIDE_HUD_MESSAGES_DESC" = "Exemple : Les sous-titres sont activés/désactivés, la boucle vidéo est activée,..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Paramètres des options d'overlay de l'application"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 6b67d73..1550594 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "HUDメッセージを非表示"; +"HIDE_HUD_MESSAGES_DESC" = "特定のアクション後に表示されるスナックバーを非表示にします。(例: 字幕がオン/オフになりました など)"; + +"HIDE_COLLAPSE_BUTTON" = "折りたたみボタンを隠す"; +"HIDE_COLLAPSE_BUTTON_DESC" = "プレーヤー左上の折りたたみボタンを非表示にします。"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "アプリの設定オーバーレイの設定"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 30133a2..2c580f6 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Ocultar Mensagens do HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Exemplo: Legendas/CC ativadas/desativadas, A repetição do vídeo está ativada,..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 49d413f..6bec7d1 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Ascundere Mesaje HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Exemplu: Subtitrările sunt activate/dezactivate, Redarea în buclă este activată,..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opțiuni Overlay Setări Aplicație"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index f29c9b2..f7f6443 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Скрыть сообщения плеера"; +"HIDE_HUD_MESSAGES_DESC" = "Скрывает надписи YouTube, появляющиеся поверх видео."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index 0d1e58d..5e6f94d 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -79,6 +79,12 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Hide HUD messages"; +"HIDE_HUD_MESSAGES_DESC" = "Hides snackbars that display for certain actions (e.g., CC turned on/off)"; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index 8db663c..e1d707f 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -64,6 +64,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "HUD mesajlarını gizle"; +"HIDE_HUD_MESSAGES_DESC" = "Belirli işlemler için görüntülenen bildirim çubuklarını gizler (ör. CC açıldı/kapandı)"; + +"HIDE_COLLAPSE_BUTTON" = "Daraltma Düğmesini Gizle"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Video oynatıcıda sol üstte görünen ok ile daraltma düğmesini gizler."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Uyg. Ayarları Kaplama Seç."; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 27fa187..49194cd 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -73,6 +73,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "Ẩn thông báo HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Ví dụ: Đã bật/tắt phụ đề, Tính năng phát video lặp lại đang bật,..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // Shorts controls overlay options "SHORTS_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển quần short"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index bca5cf7..f4d3dfa 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -65,6 +65,12 @@ "HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; "HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_HUD_MESSAGES" = "隱藏 HUD 訊息"; +"HIDE_HUD_MESSAGES_DESC" = "例如:CC字幕、開啟/關閉、影片循環開啟等..."; + +"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "應用程式設定隱藏項目"; From f384a00e041590089d03a7cae4e11505852f58d7 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 12 Aug 2024 00:46:59 +0000 Subject: [PATCH 022/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b9d1cff..a10b619 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b9d1cfff8ca6814723889bade011f3fa4675d46d +Subproject commit a10b619ed91b6bb970e4b33a1901d61c94e97ef4 From 21df218f2ff0fac8afd0431e94ae4081dbae3715 Mon Sep 17 00:00:00 2001 From: Balackburn <93828569+Balackburn@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:42:23 +0200 Subject: [PATCH 023/102] Updated Credits --- README.md | 159 +++++++++++++++--------------------------------------- 1 file changed, 43 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 5277147..64d84a8 100644 --- a/README.md +++ b/README.md @@ -26,122 +26,49 @@ # Credits - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - +
- - - - - - - - - - - - - - - - - - -
-
- - - - -
-
- - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
dayanch96BalackburnarichornloverALTPoomSmartqnblackcat
SKEIDsasdfzxcvbnmatt911bhackelAlexInABox
GlentagototheskinnyMrAlucardDanteGalactic-DevAhmedBafkir
MiRO92ichitasoDeci8BelioSjuliovernetherealFoxster
Lyvendiassuesskindhbanglevel3tjgzSaaiq
ISnackableVictorxD70MacleykunBandarHLCokePokes
# Features From 9d0fb160753c6aedcec1b7d3a3b8c78521b3ee41 Mon Sep 17 00:00:00 2001 From: Victor Alves Date: Mon, 12 Aug 2024 17:12:18 -0300 Subject: [PATCH 024/102] Update Portuguese localization (#326) * Update Portuguese Localization --- .../pt.lproj/Localizable.strings | 326 +++++++++--------- 1 file changed, 163 insertions(+), 163 deletions(-) diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 2c580f6..494d45b 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -1,163 +1,163 @@ -// Settings -"VERSION" = "Versão do YTLitePlus: %@"; -"VERSION_CHECK" = "Toque para verificar se há atualização!"; - -"COPY_SETTINGS" = "Copy Settings"; -"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; -"PASTE_SETTINGS" = "Paste Settings"; -"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; -"EXPORT_SETTINGS" = "Export Settings"; -"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; -"IMPORT_SETTINGS" = "Import Settings"; -"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; - -// Video controls overlay options -"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; - -"ENABLE_SHARE_BUTTON" = "Ativar o botão 'Compartilhar'"; -"ENABLE_SHARE_BUTTON_DESC" = "Ativa o botão Compartilhar na sobreposição de controles de vídeo."; - -"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Ativar o botão 'Salvar'"; -"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Ativa o botão 'Salvar' na sobreposição de controles de vídeo."; - -"HIDE_SHADOW_OVERLAY_BUTTONS" = "Ocultar Sombras nos Botões de Sobreposição"; -"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Oculta as sombras nos botões de sobreposição Reproduzir/Pausar, Anterior, Próximo, Avançar e Retroceder."; - -"HIDE_RIGHT_PANEL" = "Ocultar o painel direito no modo de tela cheia"; -"HIDE_RIGHT_PANEL_DESC" = "A reinicialização do app é necessária."; - -"HIDE_HEATWAVES" = "Ocultar Ondas de calor"; -"HIDE_HEATWAVES_DESC" = "Oculta as Ondas de calor no player de vídeo. A reinicialização do app é necessária."; - -"DISABLE_AMBIENT_PORTRAIT" = "Desativar Iluminação cinematográfica (Retrato)"; -"DISABLE_AMBIENT_PORTRAIT_DESC" = "Desativa a iluminação ao redor do título do vídeo"; - -"DISABLE_AMBIENT_FULLSCREEN" = "Desativar Iluminação cinematográfica (Tela cheia)"; -"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Desativa a iluminação ao redor do player de vídeo"; - -"FULLSCREEN_TO_THE_RIGHT" = "Fullscreen to the Right"; -"FULLSCREEN_TO_THE_RIGHT_DESC" = "Always enter fullscreen with home button on the right side."; - -"SEEK_ANYWHERE" = "Gesto de Busca em qualquer lugar"; -"SEEK_ANYWHERE_DESC" = "Segure e arraste o player de vídeo para buscar. Você deve desativar o YTLite - Segurar para velocidade (Hold for speed)"; - -"ENABLE_TAP_TO_SEEK" = "Ativar Toque para Buscar"; -"ENABLE_TAP_TO_SEEK_DESC" = "Vá para qualquer lugar em um vídeo tocando uma vez na barra de busca"; - -"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Desativar gesto de puxar para tela cheia"; -"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Desativa o gesto de arrastar para entrar em tela cheia vertical. Aplica-se apenas a vídeos em paisagem."; - -"ALWAYS_USE_REMAINING_TIME" = "Sempre usar o tempo restante"; -"ALWAYS_USE_REMAINING_TIME_DESC" = "Altera o padrão para mostrar o tempo restante na barra do player."; - -"DISABLE_TOGGLE_TIME_REMAINING" = "Desativar alternar tempo restante"; -"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Desativa a alteração do tempo decorrido para o tempo restante. Use com outra configuração para mostrar sempre o tempo restante."; - -"DISABLE_ENGAGEMENT_OVERLAY" = "Desativar sobreposição de engajamento em tela cheia"; -"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desativa o gesto de deslizar para cima e a lista de vídeos sugeridos em tela cheia"; - -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; - -"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; -"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; - -"HIDE_HUD_MESSAGES" = "Ocultar Mensagens do HUD"; -"HIDE_HUD_MESSAGES_DESC" = "Exemplo: Legendas/CC ativadas/desativadas, A repetição do vídeo está ativada,..."; - -"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; -"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; - -// App settings overlay options -"APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; - -"HIDE_ACCOUNT_SECTION" = "Ocultar a sessão \"Conta\""; -"HIDE_AUTOPLAY_SECTION" = "Ocultar a sessão \"Reprodução automática\""; -"HIDE_TRYNEWFEATURES_SECTION" = "Ocultar a sessão \"Experimente novos recursos\""; -"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Ocultar a sessão \"Preferências de qualidade de vídeo\""; -"HIDE_NOTIFICATIONS_SECTION" = "Ocultar a sessão \"Notificações\""; -"HIDE_MANAGEALLHISTORY_SECTION" = "Ocultar a sessão \"Gerencie todo o histórico\""; -"HIDE_YOURDATAINYOUTUBE_SECTION" = "Ocultar a sessão \"Seus dados no YouTube\""; -"HIDE_PRIVACY_SECTION" = "Ocultar a sessão \"Privacidade\""; -"HIDE_LIVECHAT_SECTION" = "Ocultar a sessão \"Chat ao vivo\""; - -// Theme -"THEME_OPTIONS" = "Opções de Temas"; - -"OLED_DARK_THEME" = "Modo escuro OLED"; -"OLED_DARK_THEME_2" = "Modo escuro OLED"; -"OLED_DARK_THEME_DESC" = "Verdadeiro tema escuro. Pode não funcionar corretamente em alguns casos. App restart is required after you enable/disable this option."; - -"OLD_DARK_THEME" = "Antigo tema escuro"; -"OLD_DARK_THEME_DESC" = "Tema escuro do YouTube antigo (tema cinza). A reinicialização do app é necessária."; - -"DEFAULT_THEME" = "Padrão"; -"DEFAULT_THEME_DESC" = "Tema escuro padrão do YouTube. A reinicialização do app é necessária."; - -"OLED_KEYBOARD" = "Teclado OLED"; -"OLED_KEYBOARD_DESC" = "Pode não funcionar corretamente em alguns casos. A reinicialização do app é necessária."; - -"LOW_CONTRAST_MODE" = "Modo de Baixo Contraste"; -"LOW_CONTRAST_MODE_DESC" = "Esta opção terá baixo contraste dos textos e botões, assim como era a antiga interface do YouTube. A reinicialização do app é necessária."; -"LCM_SELECTOR" = "Seleção do modo de baixo contraste"; -"DEFAULT_LOWCONTRASTMODE" = "(Padrão) LowContrastMode"; -"CUSTOM_LOWCONTRASTMODE" = "(Cor Personalizada) LowContrastMode"; - -// Miscellaneous -"MISCELLANEOUS" = "Diversos"; - -"PLAYBACK_IN_FEEDS" = "Reprodução nos feeds"; -"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Sempre ativada"; -"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Somente Wi-Fi"; -"PLAYBACK_IN_FEEDS_OFF" = "Desativada"; - -"NEW_SETTINGS_UI" = "Nova Interface de Configurações"; -"NEW_SETTINGS_UI_DESC" = "Usa a nova Interface de configurações agrupadas. Pode ocultar algumas configurações"; - -"ENABLE_YT_STARTUP_ANIMATION" = "Ative a animação de inicialização do YouTube"; -"ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; - -"HIDE_MODERN_INTERFACE" = "Ocultar Interface Moderna (YTNoModernUI)"; -"HIDE_MODERN_INTERFACE_DESC" = "Ative esta opção para ocultar qualquer elemento moderno adicionado pelo YouTube. Remove a iluminação cinematogrática, design arredondado e muito mais. A reinicialização do app é necessária."; - -"IPAD_LAYOUT" = "Layout do iPad"; -"IPAD_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPad no seu iPhone/iPod atual. A reinicialização do app é necessária."; - -"IPHONE_LAYOUT" = "Layout do iPhone"; -"IPHONE_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPhone no seu iPad atual. A reinicialização do app é necessária."; - -"CAST_CONFIRM" = "Alerta de confirmação antes de transmitir (YTCastConfirm)"; -"CAST_CONFIRM_DESC" = "Mostra um alerta de confirmação antes da transmissão para evitar o sequestro acidental da TV."; -"CASTING" = "Transmissão"; -"MSG_ARE_YOU_SURE" = "Tem certeza de que deseja começar a transmitir?"; -"MSG_YES" = "Sim"; -"MSG_CANCEL" = "Cancelar"; - -"NEW_MINIPLAYER_STYLE" = "Novo estilo de barra de miniplayer (BigYTMiniPlayer)"; -"NEW_MINIPLAYER_STYLE_DESC" = "A reinicialização do app é necessária."; - -"HIDE_CAST_BUTTON" = "Ocultar o botão Transmitir"; -"HIDE_CAST_BUTTON_DESC" = "A reinicialização do app é necessária."; - -"HIDE_SPONSORBLOCK_BUTTON" = "Ocultar o botão iSponsorBlock na barra de navegação"; -"HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; - -"HIDE_HOME_TAB" = "Ocultar guia Início"; -"HIDE_HOME_TAB_DESC" = "Tenha cuidado ao ocultar todas as guias"; - -"FIX_CASTING" = "Corrigir Transmissão"; -"FIX_CASTING_DESC" = "Altera alguns sinalizadores AB para corrigir a transmissão"; - -"ENABLE_FLEX" = "Ativar FLEX"; -"ENABLE_FLEX_DESC" = "Ativa o FLEX para depuração (não recomendado). Deixe isso desligado, a menos que você saiba o que está fazendo."; - -// Version Spoofer -"APP_VERSION_SPOOFER_LITE" = "Ativar Falsificação da Versão do App (Lite)"; -"APP_VERSION_SPOOFER_LITE_DESC" = "Ative isto para usar a Falsificação de Versão (Lite) e selecione sua versão preferida abaixo. A reinicialização do app é necessária."; -"VERSION_SPOOFER_TITLE" = "Selecionar Versão Falsa"; - -// Other Localization -"APP_RESTART_DESC" = "A reinicialização do app é necessária."; -"CHANGE_APP_ICON" = "Mudar o Ícone do Aplicativo"; +// Settings +"VERSION" = "Versão do YTLitePlus: %@"; +"VERSION_CHECK" = "Toque para verificar se há atualização!"; + +"COPY_SETTINGS" = "Copiar Configurações"; +"COPY_SETTINGS_DESC" = "Copia todas as configurações atuais para a área de transferência"; +"PASTE_SETTINGS" = "Colar Configurações"; +"PASTE_SETTINGS_DESC" = "Cola as configurações da área de transferência e aplica"; +"EXPORT_SETTINGS" = "Exportar Configurações"; +"EXPORT_SETTINGS_DESC" = "Exporta todas as configurações atuais para um arquivo .txt"; +"IMPORT_SETTINGS" = "Importar Configurações"; +"IMPORT_SETTINGS_DESC" = "Pressione para importar as configurações (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Substituir os Botões 'Copiar Configurações' e 'Colar Configurações'"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Substitui os Botões 'Exportar Configurações' e 'Importar Configurações'"; + +// Video controls overlay options +"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; + +"ENABLE_SHARE_BUTTON" = "Ativar o botão 'Compartilhar'"; +"ENABLE_SHARE_BUTTON_DESC" = "Ativa o botão Compartilhar na sobreposição de controles de vídeo."; + +"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Ativar o botão 'Salvar'"; +"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Ativa o botão 'Salvar' na sobreposição de controles de vídeo."; + +"HIDE_SHADOW_OVERLAY_BUTTONS" = "Ocultar Sombras nos Botões de Sobreposição"; +"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Oculta as sombras nos botões de sobreposição Reproduzir/Pausar, Anterior, Próximo, Avançar e Retroceder."; + +"HIDE_RIGHT_PANEL" = "Ocultar o painel direito no modo de tela cheia"; +"HIDE_RIGHT_PANEL_DESC" = "A reinicialização do app é necessária."; + +"HIDE_HEATWAVES" = "Ocultar Ondas de calor"; +"HIDE_HEATWAVES_DESC" = "Oculta as Ondas de calor no player de vídeo. A reinicialização do app é necessária."; + +"DISABLE_AMBIENT_PORTRAIT" = "Desativar Iluminação cinematográfica (Retrato)"; +"DISABLE_AMBIENT_PORTRAIT_DESC" = "Desativa a iluminação ao redor do título do vídeo"; + +"DISABLE_AMBIENT_FULLSCREEN" = "Desativar Iluminação cinematográfica (Tela cheia)"; +"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Desativa a iluminação ao redor do player de vídeo"; + +"FULLSCREEN_TO_THE_RIGHT" = "Tela cheia para a direita"; +"FULLSCREEN_TO_THE_RIGHT_DESC" = "Sempre entre em tela cheia com o botão home no lado direito."; + +"SEEK_ANYWHERE" = "Gesto de Busca em qualquer lugar"; +"SEEK_ANYWHERE_DESC" = "Segure e arraste o player de vídeo para buscar. Você deve desativar o YTLite - Segurar para velocidade (Hold for speed)"; + +"ENABLE_TAP_TO_SEEK" = "Ativar Toque para Buscar"; +"ENABLE_TAP_TO_SEEK_DESC" = "Vá para qualquer lugar em um vídeo tocando uma vez na barra de busca"; + +"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Desativar gesto de puxar para tela cheia"; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Desativa o gesto de arrastar para entrar em tela cheia vertical. Aplica-se apenas a vídeos em paisagem."; + +"ALWAYS_USE_REMAINING_TIME" = "Sempre usar o tempo restante"; +"ALWAYS_USE_REMAINING_TIME_DESC" = "Altera o padrão para mostrar o tempo restante na barra do player."; + +"DISABLE_TOGGLE_TIME_REMAINING" = "Desativar alternar tempo restante"; +"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Desativa a alteração do tempo decorrido para o tempo restante. Use com outra configuração para mostrar sempre o tempo restante."; + +"DISABLE_ENGAGEMENT_OVERLAY" = "Desativar sobreposição de engajamento em tela cheia"; +"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desativa o gesto de deslizar para cima e a lista de vídeos sugeridos em tela cheia"; + +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Ocultar Visualizações de comentários sob o player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Oculta a Prévia de comentário no botão de comentários"; + +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Ocultar mini visualização de reprodução automática"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Oculta a pequena caixa de vídeo sugerida perto do título em tela cheia"; + +"HIDE_HUD_MESSAGES" = "Ocultar Mensagens do HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Exemplo: Legendas/CC ativadas/desativadas, A repetição do vídeo está ativada,..."; + +"HIDE_COLLAPSE_BUTTON" = "Ocultar Botão de Recolhimento"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Oculta o botão de seta para recolher que era exibido no canto superior esquerdo do player de vídeo."; + +// App settings overlay options +"APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; + +"HIDE_ACCOUNT_SECTION" = "Ocultar a sessão \"Conta\""; +"HIDE_AUTOPLAY_SECTION" = "Ocultar a sessão \"Reprodução automática\""; +"HIDE_TRYNEWFEATURES_SECTION" = "Ocultar a sessão \"Experimente novos recursos\""; +"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Ocultar a sessão \"Preferências de qualidade de vídeo\""; +"HIDE_NOTIFICATIONS_SECTION" = "Ocultar a sessão \"Notificações\""; +"HIDE_MANAGEALLHISTORY_SECTION" = "Ocultar a sessão \"Gerencie todo o histórico\""; +"HIDE_YOURDATAINYOUTUBE_SECTION" = "Ocultar a sessão \"Seus dados no YouTube\""; +"HIDE_PRIVACY_SECTION" = "Ocultar a sessão \"Privacidade\""; +"HIDE_LIVECHAT_SECTION" = "Ocultar a sessão \"Chat ao vivo\""; + +// Theme +"THEME_OPTIONS" = "Opções de Temas"; + +"OLED_DARK_THEME" = "Modo escuro OLED"; +"OLED_DARK_THEME_2" = "Modo escuro OLED"; +"OLED_DARK_THEME_DESC" = "Verdadeiro tema escuro. Pode não funcionar corretamente em alguns casos. App restart is required after you enable/disable this option."; + +"OLD_DARK_THEME" = "Antigo tema escuro"; +"OLD_DARK_THEME_DESC" = "Tema escuro do YouTube antigo (tema cinza). A reinicialização do app é necessária."; + +"DEFAULT_THEME" = "Padrão"; +"DEFAULT_THEME_DESC" = "Tema escuro padrão do YouTube. A reinicialização do app é necessária."; + +"OLED_KEYBOARD" = "Teclado OLED"; +"OLED_KEYBOARD_DESC" = "Pode não funcionar corretamente em alguns casos. A reinicialização do app é necessária."; + +"LOW_CONTRAST_MODE" = "Modo de Baixo Contraste"; +"LOW_CONTRAST_MODE_DESC" = "Esta opção terá baixo contraste dos textos e botões, assim como era a antiga interface do YouTube. A reinicialização do app é necessária."; +"LCM_SELECTOR" = "Seleção do modo de baixo contraste"; +"DEFAULT_LOWCONTRASTMODE" = "(Padrão) LowContrastMode"; +"CUSTOM_LOWCONTRASTMODE" = "(Cor Personalizada) LowContrastMode"; + +// Miscellaneous +"MISCELLANEOUS" = "Diversos"; + +"PLAYBACK_IN_FEEDS" = "Reprodução nos feeds"; +"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Sempre ativada"; +"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Somente Wi-Fi"; +"PLAYBACK_IN_FEEDS_OFF" = "Desativada"; + +"NEW_SETTINGS_UI" = "Nova Interface de Configurações"; +"NEW_SETTINGS_UI_DESC" = "Usa a nova Interface de configurações agrupadas. Pode ocultar algumas configurações"; + +"ENABLE_YT_STARTUP_ANIMATION" = "Ative a animação de inicialização do YouTube"; +"ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; + +"HIDE_MODERN_INTERFACE" = "Ocultar Interface Moderna (YTNoModernUI)"; +"HIDE_MODERN_INTERFACE_DESC" = "Ative esta opção para ocultar qualquer elemento moderno adicionado pelo YouTube. Remove a iluminação cinematogrática, design arredondado e muito mais. A reinicialização do app é necessária."; + +"IPAD_LAYOUT" = "Layout do iPad"; +"IPAD_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPad no seu iPhone/iPod atual. A reinicialização do app é necessária."; + +"IPHONE_LAYOUT" = "Layout do iPhone"; +"IPHONE_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPhone no seu iPad atual. A reinicialização do app é necessária."; + +"CAST_CONFIRM" = "Alerta de confirmação antes de transmitir (YTCastConfirm)"; +"CAST_CONFIRM_DESC" = "Mostra um alerta de confirmação antes da transmissão para evitar o sequestro acidental da TV."; +"CASTING" = "Transmissão"; +"MSG_ARE_YOU_SURE" = "Tem certeza de que deseja começar a transmitir?"; +"MSG_YES" = "Sim"; +"MSG_CANCEL" = "Cancelar"; + +"NEW_MINIPLAYER_STYLE" = "Novo estilo de barra de miniplayer (BigYTMiniPlayer)"; +"NEW_MINIPLAYER_STYLE_DESC" = "A reinicialização do app é necessária."; + +"HIDE_CAST_BUTTON" = "Ocultar o botão Transmitir"; +"HIDE_CAST_BUTTON_DESC" = "A reinicialização do app é necessária."; + +"HIDE_SPONSORBLOCK_BUTTON" = "Ocultar o botão iSponsorBlock na barra de navegação"; +"HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; + +"HIDE_HOME_TAB" = "Ocultar guia Início"; +"HIDE_HOME_TAB_DESC" = "Tenha cuidado ao ocultar todas as guias"; + +"FIX_CASTING" = "Corrigir Transmissão"; +"FIX_CASTING_DESC" = "Altera alguns sinalizadores AB para corrigir a transmissão"; + +"ENABLE_FLEX" = "Ativar FLEX"; +"ENABLE_FLEX_DESC" = "Ativa o FLEX para depuração (não recomendado). Deixe isso desligado, a menos que você saiba o que está fazendo."; + +// Version Spoofer +"APP_VERSION_SPOOFER_LITE" = "Ativar Falsificação da Versão do App (Lite)"; +"APP_VERSION_SPOOFER_LITE_DESC" = "Ative isto para usar a Falsificação de Versão (Lite) e selecione sua versão preferida abaixo. A reinicialização do app é necessária."; +"VERSION_SPOOFER_TITLE" = "Selecionar Versão Falsa"; + +// Other Localization +"APP_RESTART_DESC" = "A reinicialização do app é necessária."; +"CHANGE_APP_ICON" = "Mudar o Ícone do Aplicativo"; From 916bcf33ff4e27a87fb2d60e3358a84e9267479a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 13 Aug 2024 00:46:14 +0000 Subject: [PATCH 025/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index a10b619..b71e5ee 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit a10b619ed91b6bb970e4b33a1901d61c94e97ef4 +Subproject commit b71e5ee2d5d91b101fbb49038af66d0fd0d7be6a From 82e4f21d24474c721d218830dcbbe2b3d9deeda6 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:33:53 -0700 Subject: [PATCH 026/102] Add Hide Speed Toast --- Source/Settings.xm | 2 +- YTLitePlus.xm | 25 +++++++++++++++++++ .../ar.lproj/Localizable.strings | 3 +++ .../de.lproj/Localizable.strings | 3 +++ .../en.lproj/Localizable.strings | 3 +++ .../es.lproj/Localizable.strings | 3 +++ .../fr.lproj/Localizable.strings | 3 +++ .../ja.lproj/Localizable.strings | 3 +++ .../pt.lproj/Localizable.strings | 3 +++ .../ro.lproj/Localizable.strings | 3 +++ .../ru.lproj/Localizable.strings | 3 +++ .../template.lproj/Localizable.strings | 3 +++ .../tr.lproj/Localizable.strings | 3 +++ .../vi.lproj/Localizable.strings | 3 +++ .../zh_TW.lproj/Localizable.strings | 3 +++ 15 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 331c9bf..3d7293f 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -233,7 +233,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW"), LOC(@"HIDE_AUTOPLAY_MINI_PREVIEW_DESC"), @"hideAutoplayMiniPreview_enabled"), BASIC_SWITCH(LOC(@"HIDE_HUD_MESSAGES"), LOC(@"HIDE_HUD_MESSAGES_DESC"), @"hideHUD_enabled"), BASIC_SWITCH(LOC(@"HIDE_COLLAPSE_BUTTON"), LOC(@"HIDE_COLLAPSE_BUTTON_DESC"), @"disableCollapseButton_enabled"), - + BASIC_SWITCH(LOC(@"HIDE_SPEED_TOAST"), LOC(@"HIDE_SPEED_TOAST_DESC"), @"hideSpeedToast_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index c4248cb..2078fd3 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -179,6 +179,7 @@ BOOL isSelf() { %end %end + // A/B flags %hook YTColdConfig - (BOOL)respectDeviceCaptionSetting { return NO; } // YouRememberCaption: https://poomsmart.github.io/repo/depictions/youremembercaption.html @@ -194,6 +195,30 @@ BOOL isSelf() { - (BOOL)shouldShowUpgradeDialog { return NO;} %end +// Hide Speed Toast - @bhackel +// YTLite Speed Toast +%hook PlayerToast +- (void)showPlayerToastWithText:(id)text + value:(CGFloat)value + style:(NSInteger)style + onView:(id)view +{ + if (IsEnabled(@"hideSpeedToast_enabled")) { + return; + } + %orig; +} +%end +// Default YouTube Speed Toast +%hook YTInlinePlayerScrubUserEducationView +- (void)setVisible:(BOOL)visible { + if (IsEnabled(@"hideSpeedToast_enabled")) { + return; + } + %orig; +} +%end + // Hide Home Tab - @bhackel %group gHideHomeTab %hook YTPivotBarView diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index 496cfb4..ce93d10 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index 8d1dee7..da044fe 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Overlay-Optionen für App-Einstellungen"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 6c805d4..4af6499 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index 6b1d700..83a74d7 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opciones de superposición de los ajustes de la aplicación"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index ec9a68c..74e2201 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Paramètres des options d'overlay de l'application"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 1550594..6400844 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "折りたたみボタンを隠す"; "HIDE_COLLAPSE_BUTTON_DESC" = "プレーヤー左上の折りたたみボタンを非表示にします。"; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "アプリの設定オーバーレイの設定"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 2c580f6..e1b23f7 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 6bec7d1..fac3b20 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opțiuni Overlay Setări Aplicație"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index f7f6443..11889b4 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index 5e6f94d..473514e 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -85,6 +85,9 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "App Settings Overlay Options"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index e1d707f..186c680 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -70,6 +70,9 @@ "HIDE_COLLAPSE_BUTTON" = "Daraltma Düğmesini Gizle"; "HIDE_COLLAPSE_BUTTON_DESC" = "Video oynatıcıda sol üstte görünen ok ile daraltma düğmesini gizler."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Uyg. Ayarları Kaplama Seç."; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 49194cd..d8dea0e 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -79,6 +79,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // Shorts controls overlay options "SHORTS_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển quần short"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index f4d3dfa..7fd520a 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -71,6 +71,9 @@ "HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; "HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_SPEED_TOAST" = "Hide Speed Toast"; +"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; + // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "應用程式設定隱藏項目"; From e067e8dec5ba012cb9422b1730c6ffb51a659f37 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:50:33 -0700 Subject: [PATCH 027/102] Fix OLED live chat --- YTLitePlus.xm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index c4248cb..a9da363 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -545,6 +545,7 @@ BOOL isTabSelected = NO; %hook _ASDisplayView - (void)didMoveToWindow { %orig; + // Hide the Comment Section Previews under the Video Player - @arichornlover if ((IsEnabled(@"hidePreviewCommentSection_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"id.ui.comments_entry_point_teaser"])) { self.hidden = YES; @@ -557,10 +558,14 @@ BOOL isTabSelected = NO; [self setNeedsLayout]; [self removeFromSuperview]; } + // Live chat OLED dark mode - @bhackel - if (([[%c(YTLUserDefaults) standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme - || [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] == 1 // YTLitePlus OLED Theme - ) && [self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"]) { + CGFloat alpha; + if ([[%c(YTLUserDefaults) standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme + && [self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"] // Live chat text message + && [self.backgroundColor getWhite:nil alpha:&alpha] // Check if color is grayscale and get alpha + && alpha != 0.0) // Ignore shorts live chat + { self.backgroundColor = [UIColor blackColor]; } } From 4c24c0c3365f64e07e362a40f9abe1bd1707483a Mon Sep 17 00:00:00 2001 From: gototheskinny <51786709+gototheskinny@users.noreply.github.com> Date: Wed, 14 Aug 2024 02:33:12 +0300 Subject: [PATCH 028/102] Turkish loc updated (#336) --- .../tr.lproj/Localizable.strings | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index 186c680..62afeea 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -1,6 +1,6 @@ // Settings "VERSION" = "YTLitePlus'ın sürümü: %@"; -"VERSION_CHECK" = "Güncelleme için dokunun!"; +"VERSION_CHECK" = "Güncelleme kontrolü için dokun!"; "COPY_SETTINGS" = "Ayarları Kopyala"; "COPY_SETTINGS_DESC" = "Tüm mevcut ayarları panoya kopyala"; @@ -61,8 +61,8 @@ "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Oynatıcının Altındaki Yorum Önizlemelerini Gizle"; "HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Video oynatıcının altındaki yorum önizlemelerini gizler."; -"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; -"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Otomatik Oynatma Mini Önizlemesini Gizle"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Tam ekranda başlık yakınındaki küçük önerilen video kutusunu gizle"; "HIDE_HUD_MESSAGES" = "HUD mesajlarını gizle"; "HIDE_HUD_MESSAGES_DESC" = "Belirli işlemler için görüntülenen bildirim çubuklarını gizler (ör. CC açıldı/kapandı)"; @@ -70,8 +70,8 @@ "HIDE_COLLAPSE_BUTTON" = "Daraltma Düğmesini Gizle"; "HIDE_COLLAPSE_BUTTON_DESC" = "Video oynatıcıda sol üstte görünen ok ile daraltma düğmesini gizler."; -"HIDE_SPEED_TOAST" = "Hide Speed Toast"; -"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; +"HIDE_SPEED_TOAST" = "Hız Bildirimini Gizle"; +"HIDE_SPEED_TOAST_DESC" = "Oynatıcıya basılı tutarken 2X Hız bildirimini gizle"; // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Uyg. Ayarları Kaplama Seç."; @@ -87,7 +87,7 @@ "HIDE_LIVECHAT_SECTION" = "\"Canlı Sohbet\" Bölümünü Gizle"; // Theme -"THEME_OPTIONS" = "Tema Seç."; +"THEME_OPTIONS" = "Tema Seç"; "OLED_DARK_THEME" = "OLED koyu tema"; "OLED_DARK_THEME_2" = "OLED koyu tema"; @@ -109,9 +109,9 @@ "CUSTOM_LOWCONTRASTMODE" = "(Özel Renk) DüşükKontrastModu"; // Miscellaneous -"MISCELLANEOUS" = "Çeşitli"; +"MISCELLANEOUS" = "Diğer"; -"PLAYBACK_IN_FEEDS" = "Akışlarda Oynatma"; +"PLAYBACK_IN_FEEDS" = "Akışlarda Oto Oynatma"; "PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Her zaman açık"; "PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Yalnızca Wi-Fi"; "PLAYBACK_IN_FEEDS_OFF" = "Kapalı"; From 45b7cd948e1c0350090afefc4a4e70b56514fa67 Mon Sep 17 00:00:00 2001 From: schweppes Date: Wed, 14 Aug 2024 01:33:23 +0200 Subject: [PATCH 029/102] Bulgarian translations (#332) Co-authored-by: tonydalov --- .../bg.lproj/Localizable.strings | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 lang/YTLitePlus.bundle/bg.lproj/Localizable.strings diff --git a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings new file mode 100644 index 0000000..076d430 --- /dev/null +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -0,0 +1,166 @@ +// Settings +"VERSION" = "Версия на YTLitePlus: %@"; +"VERSION_CHECK" = "Докоснете, за да проверите за актуализация!"; + +"COPY_SETTINGS" = "Копиране на настройки"; +"COPY_SETTINGS_DESC" = "Копиране на всички текущи настройки в клипборда"; +"PASTE_SETTINGS" = "Поставяне на настройки"; +"PASTE_SETTINGS_DESC" = "Поставяне на настройки от клипборда и прилагане"; +"EXPORT_SETTINGS" = "Експортиране на настройки"; +"EXPORT_SETTINGS_DESC" = "Експортиране на всички текущи настройки в .txt файл"; +"IMPORT_SETTINGS" = "Импортиране на настройки"; +"IMPORT_SETTINGS_DESC" = "Натиснете, за да импортирате настройки (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Заменете бутоните 'Копиране на настройки' и 'Поставяне на настройки'"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Заменете бутоните с 'Експортиране на настройки' и 'Импортиране на настройки'"; + +// Video controls overlay options +"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Опции за контрол на видеото"; + +"ENABLE_SHARE_BUTTON" = "Активирайте бутона за споделяне"; +"ENABLE_SHARE_BUTTON_DESC" = "Активирайте бутона за споделяне в контролите на видеото."; + +"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Активирайте бутона 'Запази в плейлист'"; +"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Активирайте бутона 'Запази в плейлист' в контролите на видеото."; + +"HIDE_SHADOW_OVERLAY_BUTTONS" = "Скрийте бутоните с сенчест слой"; +"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Скрийте сенчестия слой на бутоните за възпроизвеждане/пауза, предишен, следващ, напред и въртене назад."; + +"HIDE_RIGHT_PANEL" = "Скрийте дясната панел в режим на цял екран"; +"HIDE_RIGHT_PANEL_DESC" = "Необходим е рестарт на приложението."; + +"HIDE_HEATWAVES" = "Скрийте топлинните вълни"; +"HIDE_HEATWAVES_DESC" = "Скрийте топлинните вълни в видеоплеъра. Необходим е рестарт на приложението."; + +"DISABLE_AMBIENT_PORTRAIT" = "Деактивирайте Ambient Mode (Портрет)"; +"DISABLE_AMBIENT_PORTRAIT_DESC" = "Деактивирайте осветлението около заглавието на видеото"; + +"DISABLE_AMBIENT_FULLSCREEN" = "Деактивирайте Ambient Mode (Цял екран)"; +"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Деактивирайте осветлението около видеоплеъра"; + +"FULLSCREEN_TO_THE_RIGHT" = "Цял екран вдясно"; +"FULLSCREEN_TO_THE_RIGHT_DESC" = "Винаги влизайте в режим на цял екран с бутона за начало от дясната страна."; + +"SEEK_ANYWHERE" = "Търсене навсякъде жест"; +"SEEK_ANYWHERE_DESC" = "Задръжте и плъзнете върху видеоплеъра, за да търсите. Трябва да деактивирате YTLite - Задръжте, за да увеличите скоростта"; + +"ENABLE_TAP_TO_SEEK" = "Активирайте докосване за търсене"; +"ENABLE_TAP_TO_SEEK_DESC" = "Скочете навсякъде в видео, като докоснете един път лентата за търсене"; + +"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Деактивирайте жеста за плъзгане до цял екран"; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Деактивирайте жеста за плъзгане, за да влезете в вертикален режим на цял екран. Приложимо само за видеа в ландшафтен режим."; + +"ALWAYS_USE_REMAINING_TIME" = "Винаги използвайте оставащото време"; +"ALWAYS_USE_REMAINING_TIME_DESC" = "Променете настройката по подразбиране да показва оставащото време в лентата на плейъра."; + +"DISABLE_TOGGLE_TIME_REMAINING" = "Деактивирайте превключването на оставащото време"; +"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Деактивирайте променянето на изминалото време на оставащото време. Използвайте с друга настройка, за да показвате винаги оставащото време."; + +"DISABLE_ENGAGEMENT_OVERLAY" = "Деактивирайте ангажиращия слой в режим на цял екран"; +"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Деактивирайте жеста за плъзгане нагоре и списъка с предложени видеа в режим на цял екран"; + +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Скрийте прегледите на коментари под плейъра"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Скрийте спойлера на коментарите в бутона за коментари"; + +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Скрийте мини прегледа за автоматично възпроизвеждане"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Скрийте малкия прозорец с предложени видеа близо до заглавието в режим на цял екран"; + +"HIDE_HUD_MESSAGES" = "Скрийте съобщенията на HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Скрийте съобщенията, които се показват за определени действия (напр. CC включен/изключен)"; + +"HIDE_COLLAPSE_BUTTON" = "Скрийте бутона за свиване"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Скрийте бутона за свиване на стрелка, който беше показан в горния ляв ъгъл на видеоплеъра."; + +"HIDE_SPEED_TOAST" = "Скрийте съобщението за скорост"; +"HIDE_SPEED_TOAST_DESC" = "Скрийте изскачащото съобщение за 2X скорост при задържане на плейъра"; + +// App settings overlay options +"APP_SETTINGS_OVERLAY_OPTIONS" = "Опции за настройки на приложението"; + +"HIDE_ACCOUNT_SECTION" = "Скрийте секцията \"Акаунт\""; +"HIDE_AUTOPLAY_SECTION" = "Скрийте секцията \"Автоматично възпроизвеждане\""; +"HIDE_TRYNEWFEATURES_SECTION" = "Скрийте секцията \"Опитайте нови функции\""; +"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Скрийте секцията \"Предпочитания за качество на видеото\""; +"HIDE_NOTIFICATIONS_SECTION" = "Скрийте секцията \"Уведомления\""; +"HIDE_MANAGEALLHISTORY_SECTION" = "Скрийте секцията \"Управление на цялата история\""; +"HIDE_YOURDATAINYOUTUBE_SECTION" = "Скрийте секцията \"Вашите данни в YouTube\""; +"HIDE_PRIVACY_SECTION" = "Скрийте секцията \"Поверителност\""; +"HIDE_LIVECHAT_SECTION" = "Скрийте секцията \"Жив чат\""; + +// Theme +"THEME_OPTIONS" = "Опции за тема"; + +"OLED_DARK_THEME" = "OLED тъмен режим"; +"OLED_DARK_THEME_2" = "OLED тъмен режим"; +"OLED_DARK_THEME_DESC" = "Истински тъмен режим. Може да не работи правилно в някои случаи. Необходим е рестарт на приложението след включване/изключване на тази опция."; + +"OLD_DARK_THEME" = "Стар тъмен режим"; +"OLD_DARK_THEME_DESC" = "Старият тъмен режим на YouTube (сив режим). Необходим е рестарт на приложението."; + +"DEFAULT_THEME" = "По подразбиране"; +"DEFAULT_THEME_DESC" = "Тъмен(и) режим(и) по подразбиране на YouTube. Необходим е рестарт на приложението."; + +"OLED_KEYBOARD" = "OLED клавиатура"; +"OLED_KEYBOARD_DESC" = "Може да не работи правилно в някои случаи. Необходим е рестарт на приложението."; + +"LOW_CONTRAST_MODE" = "Режим с нисък контраст"; +"LOW_CONTRAST_MODE_DESC" = "Тази опция ще намали контраста на текстовете и бутоните, както беше в стария интерфейс на YouTube. Необходим е рестарт на приложението."; +"LCM_SELECTOR" = "Избор на режим с нисък контраст"; +"DEFAULT_LOWCONTRASTMODE" = "(По подразбиране) Режим с нисък контраст"; +"CUSTOM_LOWCONTRASTMODE" = "(Персонализиран цвят) Режим с нисък контраст"; + +// Miscellaneous +"MISCELLANEOUS" = "Разни"; + +"PLAYBACK_IN_FEEDS" = "Възпроизвеждане в новините"; +"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Винаги включено"; +"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Само Wi-Fi"; +"PLAYBACK_IN_FEEDS_OFF" = "Изключено"; + +"NEW_SETTINGS_UI" = "Нов потребителски интерфейс на настройките"; +"NEW_SETTINGS_UI_DESC" = "Използвайте новия групиран потребителски интерфейс за настройки. Може да скрие някои настройки"; + +"ENABLE_YT_STARTUP_ANIMATION" = "Активирайте анимацията при стартиране на YouTube"; +"ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; + +"HIDE_MODERN_INTERFACE" = "Скрийте съвременния интерфейс (YTNoModernUI)"; +"HIDE_MODERN_INTERFACE_DESC" = "Включете това, за да скриете съвременните елементи, добавени от YouTube. Премахва Ambient Mode, закръглен дизайн и други. Необходим е рестарт на приложението."; + +"IPAD_LAYOUT" = "Оформление за iPad"; +"IPAD_LAYOUT_DESC" = "Използвайте това, само ако искате да имате оформлението за iPad на текущия си iPhone/iPod. Необходим е рестарт на приложението."; + +"IPHONE_LAYOUT" = "Оформление за iPhone"; +"IPHONE_LAYOUT_DESC" = "Използвайте това, само ако искате да имате оформлението за iPhone на текущия си iPad. Необходим е рестарт на приложението."; + +"CAST_CONFIRM" = "Потвърдете предупреждението преди стрийминг (YTCastConfirm)"; +"CAST_CONFIRM_DESC" = "Показвайте потвърдително предупреждение преди стрийминг, за да предотвратите случайно преекспониране на TV."; +"CASTING" = "Стрийминг"; +"MSG_ARE_YOU_SURE" = "Сигурни ли сте, че искате да започнете стрийминг?"; +"MSG_YES" = "Да"; +"MSG_CANCEL" = "Отказ"; + +"NEW_MINIPLAYER_STYLE" = "Нов стил на мини плейъра (BigYTMiniPlayer)"; +"NEW_MINIPLAYER_STYLE_DESC" = "Необходим е рестарт на приложението."; + +"HIDE_CAST_BUTTON" = "Скрийте бутона за стрийминг"; +"HIDE_CAST_BUTTON_DESC" = "Необходим е рестарт на приложението."; + +"HIDE_SPONSORBLOCK_BUTTON" = "Скрийте бутона за iSponsorBlock в навигационната лента"; +"HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; + +"HIDE_HOME_TAB" = "Скрийте таба \"Начало\""; +"HIDE_HOME_TAB_DESC" = "Бъдете внимателни при скриване на всички табове"; + +"FIX_CASTING" = "Поправете стрийминг"; +"FIX_CASTING_DESC" = "Променя някои AB флагове, за да поправи стрийминг"; + +"ENABLE_FLEX" = "Активирайте FLEX"; +"ENABLE_FLEX_DESC" = "Активирайте FLEX за отстраняване на проблеми (не се препоръчва). Оставете това изключено, освен ако не знаете какво правите."; + +// Version Spoofer +"APP_VERSION_SPOOFER_LITE" = "Активирайте Промяна на версията на приложението (Lite)"; +"APP_VERSION_SPOOFER_LITE_DESC" = "Активирайте това, за да използвате Промяната на версията (Lite) и изберете предпочитаната версия по-долу. Необходим е рестарт на приложението."; +"VERSION_SPOOFER_TITLE" = "Избор на Промяна на версията"; + +// Other Localization +"APP_RESTART_DESC" = "Необходим е рестарт на приложението."; +"CHANGE_APP_ICON" = "Промяна на иконата на приложението"; From 76f48a2700a33d04c10cccc8bee92f4089df2726 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 14 Aug 2024 00:45:08 +0000 Subject: [PATCH 030/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b71e5ee..b9f46b8 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b71e5ee2d5d91b101fbb49038af66d0fd0d7be6a +Subproject commit b9f46b822ec0d29bf22f80abde5c1e0036ec59fc From 9aa33a676d2c04f6de1c107be2e7f6af1b54bb25 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 14 Aug 2024 00:53:53 +0000 Subject: [PATCH 031/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b71e5ee..b9f46b8 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b71e5ee2d5d91b101fbb49038af66d0fd0d7be6a +Subproject commit b9f46b822ec0d29bf22f80abde5c1e0036ec59fc From b588b7f6d0af074f2850187f4bb7c51ee71db010 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:02:23 -0700 Subject: [PATCH 032/102] Attempt seek gesture --- YTLitePlus.xm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 4c49cee..dcd30b4 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -579,6 +579,7 @@ BOOL isTabSelected = NO; static float initialBrightness; static BOOL isHorizontalPan = NO; static NSInteger gestureSection = 0; // 1 for brightness, 2 for volume, 3 for seeking + static CGFloat currentTime; if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { // Get the gesture's start position @@ -594,6 +595,7 @@ BOOL isTabSelected = NO; initialVolume = [[AVAudioSession sharedInstance] outputVolume]; } else { gestureSection = 3; // Bottom third: Seeking + currentTime = self.currentVideoMediaTime; } // Reset the horizontal pan flag @@ -641,9 +643,16 @@ BOOL isTabSelected = NO; }); } else if (gestureSection == 3) { - // Bottom third: Seek functionality (implement your seeking logic here) - // Example: Adjust playback position based on horizontal swipe - // (Add your media player's seeking logic here) + // Bottom third: Seek functionality + // Calculate a seek fraction based on the horizontal translation + CGFloat totalDuration = self.currentVideoTotalMediaTime; + CGFloat viewWidth = self.view.bounds.size.width; + CGFloat seekFraction = (translation.x / 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]; } } } From b963c807bbf5fad0e1c3299312191f8c7b26d62e Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:15:43 -0700 Subject: [PATCH 033/102] Video player prototype --- Source/Settings.xm | 52 ++++++++++++++++++++++++++++++++++++++++++++++ YTLitePlus.h | 3 +++ 2 files changed, 55 insertions(+) diff --git a/Source/Settings.xm b/Source/Settings.xm index 3d7293f..8be7b15 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -47,6 +47,8 @@ static int appVersionSpoofer() { @interface YTSettingsSectionItemManager (YTLitePlus) - (void)updateYTLitePlusSectionWithEntry:(id)entry; +- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls; +- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller; @end extern NSBundle *YTLitePlusBundle(); @@ -197,6 +199,29 @@ static const NSInteger YTLiteSection = 789; ]; [sectionItems addObject:pasteSettings]; + YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) + itemWithTitle:LOC(@"VIDEO_PICKER") + titleDescription:LOC(@"VIDEO_PICKER_DESC") + accessibilityIdentifier:nil + detailTextBlock:nil + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // Access the current view controller + UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + if (settingsViewController) { + // Present the video picker + UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo] inMode:UIDocumentPickerModeImport]; + documentPicker.delegate = (id)self; + documentPicker.allowsMultipleSelection = NO; + [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; + } else { + NSLog(@"settingsViewController is nil"); + } + + return YES; // Return YES to indicate that the action was handled + } + ]; + [sectionItems addObject:videoPlayer]; + /* YTSettingsSectionItem *appIcon = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"CHANGE_APP_ICON") @@ -479,4 +504,31 @@ static const NSInteger YTLiteSection = 789; } %orig; } + +// Implement the delegate method for document picker +%new +- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls { + NSURL *pickedURL = [urls firstObject]; + + if (pickedURL) { + // Use AVPlayerViewController to play the video + AVPlayer *player = [AVPlayer playerWithURL:pickedURL]; + AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; + playerViewController.player = player; + + UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + if (settingsViewController) { + [settingsViewController presentViewController:playerViewController animated:YES completion:^{ + [player play]; + }]; + } + } +} + +%new +- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { + // Handle cancellation if needed + NSLog(@"Document picker was cancelled"); +} + %end diff --git a/YTLitePlus.h b/YTLitePlus.h index 82d6ac1..f737d46 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -6,6 +6,9 @@ #import #import #import +#import // For AVPlayer and AVPlayerViewController +#import // For kUTTypeMovie and kUTTypeVideo + #import "Tweaks/FLEX/FLEX.h" #import "Tweaks/YouTubeHeader/YTAppDelegate.h" From 2d82e0b5329c579252ad886336240a79b04eadc8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 15 Aug 2024 00:43:33 +0000 Subject: [PATCH 034/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b9f46b8..b2a38a7 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b9f46b822ec0d29bf22f80abde5c1e0036ec59fc +Subproject commit b2a38a7b9764a0b55887ea1fa3cd958df9d6a111 From 8f578bb741f6d1c9f39dedf0dfa24c686a75ae66 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:28:42 -0700 Subject: [PATCH 035/102] Prototype 2 --- Source/Settings.xm | 14 ++++++++++---- YTLitePlus.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 8be7b15..2a1469f 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -200,18 +200,24 @@ static const NSInteger YTLiteSection = 789; [sectionItems addObject:pasteSettings]; YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"VIDEO_PICKER") - titleDescription:LOC(@"VIDEO_PICKER_DESC") + itemWithTitle:LOC(@"VIDEO_PLAYER") + titleDescription:LOC(@"VIDEO_PLAYER_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { // Access the current view controller UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; if (settingsViewController) { - // Present the video picker - UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo] inMode:UIDocumentPickerModeImport]; + // Define the content types for movies and videos using UTType + NSArray *contentTypes = @[[UTType typeWithIdentifier:@"public.movie"], + [UTType typeWithIdentifier:@"public.video"]]; + + // Initialize the document picker for opening content types + UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypes]; documentPicker.delegate = (id)self; documentPicker.allowsMultipleSelection = NO; + + // Present the document picker [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; } else { NSLog(@"settingsViewController is nil"); diff --git a/YTLitePlus.h b/YTLitePlus.h index f737d46..ade859b 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -7,7 +7,7 @@ #import #import #import // For AVPlayer and AVPlayerViewController -#import // For kUTTypeMovie and kUTTypeVideo +#import // Required for UTType #import "Tweaks/FLEX/FLEX.h" From e92ada842799d3049994c8d57ea90ddb1dc8d3b8 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:20:36 -0700 Subject: [PATCH 036/102] Gesture settings --- Source/Settings.xm | 69 +++++++++++++++++++++++++++++++++++++++++++++- YTLitePlus.h | 8 ++++++ YTLitePlus.xm | 6 ++-- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 8a59e05..f91c786 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -212,6 +212,73 @@ static const NSInteger YTLiteSection = 789; [sectionItems addObject:appIcon]; */ +# pragma mark - Player Gestures - @bhackel + // Helper to get the selected gesture mode + static NSString* (^sectionGestureSelectedMode)(GestureMode) = ^(GestureMode sectionIndex) { + switch (sectionIndex) { + case GestureModeVolume: + return LOC(@"Volume (Beta)"); + case GestureModeBrightness: + return LOC(@"Brightness (Beta)"); + case GestureModeSeek: + return LOC(@"Seek (Beta)"); + 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:sectionGestureSelectedMode(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 sectionGestureSelectedMode(GetSelection(sectionKey)); + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + gestureCheckmarkSettingItem(0, sectionKey), + gestureCheckmarkSettingItem(1, sectionKey), + gestureCheckmarkSettingItem(2, sectionKey) + ]; + + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(sectionLabel) + pickerSectionTitle:nil + rows:rows + selectedItemIndex:GetSelection(sectionKey) + parentResponder:[self parentResponder] + ]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + }; + // High level gestures menu + YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + createSectionGestureSelector(@"Top Section (Beta)", @"playerGestureTopSelection"), + createSectionGestureSelector(@"Middle Section (Beta)", @"playerGestureMiddleSelection"), + createSectionGestureSelector(@"Bottom Section (Beta)", @"playerGestureBottomSelection") + ]; + 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 = @[ @@ -234,7 +301,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"HIDE_HUD_MESSAGES"), LOC(@"HIDE_HUD_MESSAGES_DESC"), @"hideHUD_enabled"), BASIC_SWITCH(LOC(@"HIDE_COLLAPSE_BUTTON"), LOC(@"HIDE_COLLAPSE_BUTTON_DESC"), @"disableCollapseButton_enabled"), BASIC_SWITCH(LOC(@"HIDE_SPEED_TOAST"), LOC(@"HIDE_SPEED_TOAST_DESC"), @"hideSpeedToast_enabled"), - BASIC_SWITCH(LOC(@"ENABLE_UYOU_GESTURES"), LOC(@"ENABLE_UYOU_GESTURES_DESC"), @"uYouGestures_enabled"), + BASIC_SWITCH(LOC(@"ENABLE_UYOU_GESTURES"), LOC(@"ENABLE_UYOU_GESTURES_DESC"), @"playerGestures_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.h b/YTLitePlus.h index 16f63f9..63ae3af 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -52,6 +52,14 @@ #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define APP_THEME_IDX [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] +// Enum for Player Gesture selected modes +typedef NS_ENUM(NSUInteger, GestureMode) { + GestureModeVolume, + GestureModeBrightness, + GestureModeSeek, + GestureModeInvalid +}; + // YTSpeed @interface YTVarispeedSwitchControllerOption : NSObject - (id)initWithTitle:(id)title rate:(float)rate; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 32a058c..712c7c3 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -657,7 +657,7 @@ BOOL isTabSelected = NO; @end // Gestures - @bhackel -%group uYouGestures +%group playerGestures %hook YTWatchLayerViewController // invoked when the player view controller is either created or destroyed - (void)watchController:(YTWatchController *)watchController didSetPlayerViewController:(YTPlayerViewController *)playerViewController { @@ -1008,8 +1008,8 @@ BOOL isTabSelected = NO; if (IsEnabled(@"disableEngagementOverlay_enabled")) { %init(gDisableEngagementOverlay); } - if (IsEnabled(@"uYouGestures_enabled")) { - %init(uYouGestures); + if (IsEnabled(@"playerGestures_enabled")) { + %init(playerGestures); } // Change the default value of some options From 8ed3d97d2debf5b69c1a5d9da494086a668fd5f4 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 14 Aug 2024 23:56:27 -0700 Subject: [PATCH 037/102] Gesture refactor for settings --- YTLitePlus.xm | 119 ++++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 52 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 712c7c3..42db9bf 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -673,6 +673,14 @@ BOOL isTabSelected = NO; %orig; } %end +// Gesture Section Enum +typedef NS_ENUM(NSInteger, GestureSection) { + GestureSectionTop, + GestureSectionMiddle, + GestureSectionBottom, + GestureSectionInvalid +}; + %hook YTPlayerViewController // the pan gesture that will be created and added to the player view %property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; @@ -680,39 +688,74 @@ BOOL isTabSelected = NO; - (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { static float initialVolume; static float initialBrightness; - static BOOL isHorizontalPan = NO; - static NSInteger gestureSection = 0; // 1 for brightness, 2 for volume, 3 for seeking + static BOOL isValidHorizontalPan = NO; + static GestureSection gestureSection = GestureSectionInvalid; static CGFloat currentTime; + // Helper function to adjust brightness + void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { + float newBrightness = initialBrightness + (translationX / 1000.0); + 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); + 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 translationX) { + // 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]; + }; + // Handle gesture based on current gesture state if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { // Get the gesture's start position CGPoint 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 = 1; // Top third: Brightness - initialBrightness = [UIScreen mainScreen].brightness; + gestureSection = GestureSectionTop; } else if (startLocation.y <= 2 * viewHeight / 3.0) { - gestureSection = 2; // Middle third: Volume - initialVolume = [[AVAudioSession sharedInstance] outputVolume]; - } else { - gestureSection = 3; // Bottom third: Seeking - currentTime = self.currentVideoMediaTime; + gestureSection = GestureSectionMiddle; + } else if (startLocation.y <= viewHeight) { + gestureSection = GestureSectionBottom; } - // Reset the horizontal pan flag - isHorizontalPan = NO; + // Reset all starting values + isValidHorizontalPan = NO; + initialBrightness = [UIScreen mainScreen].brightness; + initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + currentTime = self.currentVideoMediaTime; } if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { - // Calculate the translation of the gesture - CGPoint translation = [panGestureRecognizer translationInView:self.view]; - // Determine if the gesture is predominantly horizontal - if (!isHorizontalPan) { + CGPoint translation = [panGestureRecognizer translationInView:self.view]; + if (!isValidHorizontalPan) { if (fabs(translation.x) > fabs(translation.y)) { - isHorizontalPan = YES; + isValidHorizontalPan = YES; } else { // If vertical movement is greater, cancel the gesture recognizer panGestureRecognizer.state = UIGestureRecognizerStateCancelled; @@ -721,47 +764,19 @@ BOOL isTabSelected = NO; } // Handle the gesture based on the identified section - if (isHorizontalPan) { - if (gestureSection == 1) { - // Top third: Adjust brightness - float newBrightness = initialBrightness + (translation.x / 1000.0); - newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0); - [[UIScreen mainScreen] setBrightness:newBrightness]; - - } else if (gestureSection == 2) { - // Middle third: Adjust volume - float newVolume = initialVolume + (translation.x / 1000.0); - newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); - - 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; - }); - - } else if (gestureSection == 3) { - // Bottom third: Seek functionality - // Calculate a seek fraction based on the horizontal translation - CGFloat totalDuration = self.currentVideoTotalMediaTime; - CGFloat viewWidth = self.view.bounds.size.width; - CGFloat seekFraction = (translation.x / 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]; + if (isValidHorizontalPan) { + if (gestureSection == GestureSectionTop) { + adjustBrightness(translation.x, initialBrightness); + } else if (gestureSection == GestureSectionMiddle) { + adjustVolume(translation.x, initialVolume); + } else if (gestureSection == GestureSectionBottom) { + adjustSeek(translation.x); } } } if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { - if (isHorizontalPan) { + if (isValidHorizontalPan) { // Provide haptic feedback upon successful gesture recognition UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; From b081d5b52e5f87112283e415089227227c21a166 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 16 Aug 2024 00:44:28 +0000 Subject: [PATCH 038/102] updated submodules --- Tweaks/YouTubeHeader | 2 +- Tweaks/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tweaks/YouTubeHeader b/Tweaks/YouTubeHeader index 171f681..a1d9216 160000 --- a/Tweaks/YouTubeHeader +++ b/Tweaks/YouTubeHeader @@ -1 +1 @@ -Subproject commit 171f681e235a1f7176cde31a95e6454fc00418c3 +Subproject commit a1d9216d1f42f54bf9fff3ba22e7fbcaaf43e72a diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b2a38a7..546c8e0 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b2a38a7b9764a0b55887ea1fa3cd958df9d6a111 +Subproject commit 546c8e0a258c21258a7ce3f8af15bbb6348bb2c9 From 6854f91c1e640613a2158aa5c26962ea41112a4a Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:45:27 -0700 Subject: [PATCH 039/102] Implement gesture selection --- Source/LowContrastMode.xm | 5 +--- Source/Settings.xm | 14 +++------ Source/Themes.xm | 3 -- Source/VersionSpooferLite.xm | 5 +--- YTLitePlus.h | 17 ++++++++++- YTLitePlus.xm | 57 ++++++++++++++++++++++++++---------- 6 files changed, 63 insertions(+), 38 deletions(-) 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 f91c786..b1b1fb8 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"]; } @@ -214,7 +208,7 @@ static const NSInteger YTLiteSection = 789; # pragma mark - Player Gestures - @bhackel // Helper to get the selected gesture mode - static NSString* (^sectionGestureSelectedMode)(GestureMode) = ^(GestureMode sectionIndex) { + static NSString* (^sectionGestureSelectedModeToString)(GestureMode) = ^(GestureMode sectionIndex) { switch (sectionIndex) { case GestureModeVolume: return LOC(@"Volume (Beta)"); @@ -231,7 +225,7 @@ static const NSInteger YTLiteSection = 789; // Helper to generate checkmark setting items for selecting gesture modes static YTSettingsSectionItem* (^gestureCheckmarkSettingItem)(NSInteger, NSString *) = ^(NSInteger idx, NSString *key) { return [YTSettingsSectionItemClass - checkmarkItemWithTitle:sectionGestureSelectedMode(idx) + checkmarkItemWithTitle:sectionGestureSelectedModeToString(idx) selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { [[NSUserDefaults standardUserDefaults] setInteger:idx forKey:key]; [settingsViewController reloadData]; @@ -245,7 +239,7 @@ static const NSInteger YTLiteSection = 789; return [YTSettingsSectionItemClass itemWithTitle:LOC(sectionLabel) accessibilityIdentifier:nil detailTextBlock:^NSString *() { - return sectionGestureSelectedMode(GetSelection(sectionKey)); + return sectionGestureSelectedModeToString(GetSelection(sectionKey)); } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ @@ -269,7 +263,7 @@ static const NSInteger YTLiteSection = 789; // High level gestures menu YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ - createSectionGestureSelector(@"Top Section (Beta)", @"playerGestureTopSelection"), + createSectionGestureSelector(@"Top Section (Beta)", @"playerGestureTopSelection"), createSectionGestureSelector(@"Middle Section (Beta)", @"playerGestureMiddleSelection"), createSectionGestureSelector(@"Bottom Section (Beta)", @"playerGestureBottomSelection") ]; 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/YTLitePlus.h b/YTLitePlus.h index 63ae3af..9261cfe 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -52,13 +52,28 @@ #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define APP_THEME_IDX [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] -// Enum for Player Gesture selected modes +// 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] + + +// Player Gesture selected mode enum typedef NS_ENUM(NSUInteger, GestureMode) { GestureModeVolume, GestureModeBrightness, GestureModeSeek, GestureModeInvalid }; +// Gesture Section Enum +typedef NS_ENUM(NSUInteger, GestureSection) { + GestureSectionTop, + GestureSectionMiddle, + GestureSectionBottom, + GestureSectionInvalid +}; // YTSpeed @interface YTVarispeedSwitchControllerOption : NSObject diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 42db9bf..41710c9 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 @@ -673,13 +668,7 @@ BOOL isTabSelected = NO; %orig; } %end -// Gesture Section Enum -typedef NS_ENUM(NSInteger, GestureSection) { - GestureSectionTop, - GestureSectionMiddle, - GestureSectionBottom, - GestureSectionInvalid -}; + %hook YTPlayerViewController // the pan gesture that will be created and added to the player view @@ -715,7 +704,7 @@ typedef NS_ENUM(NSInteger, GestureSection) { }); }; // Helper function to adjust seek time - void (^adjustSeek)(CGFloat) = ^(CGFloat translationX) { + 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; @@ -726,6 +715,32 @@ typedef NS_ENUM(NSInteger, GestureSection) { 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; + default: + 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; + } + }; + // Handle gesture based on current gesture state if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { @@ -766,11 +781,11 @@ typedef NS_ENUM(NSInteger, GestureSection) { // Handle the gesture based on the identified section if (isValidHorizontalPan) { if (gestureSection == GestureSectionTop) { - adjustBrightness(translation.x, initialBrightness); + runSelectedGesture(@"playerGestureTopSelection", translation.x, initialBrightness, initialVolume, currentTime); } else if (gestureSection == GestureSectionMiddle) { - adjustVolume(translation.x, initialVolume); + runSelectedGesture(@"playerGestureMiddleSelection", translation.x, initialBrightness, initialVolume, currentTime); } else if (gestureSection == GestureSectionBottom) { - adjustSeek(translation.x); + runSelectedGesture(@"playerGestureBottomSelection", translation.x, initialBrightness, initialVolume, currentTime); } } } @@ -1041,4 +1056,14 @@ typedef NS_ENUM(NSInteger, GestureSection) { 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"]; + } } From 4602b74e6fc3d1026813a176a967fe98741fdd3b Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Thu, 15 Aug 2024 23:15:18 -0700 Subject: [PATCH 040/102] Add deadzone --- YTLitePlus.xm | 64 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 41710c9..2055fea 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -675,11 +675,24 @@ BOOL isTabSelected = NO; %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 BOOL isValidHorizontalPan = NO; - static GestureSection gestureSection = GestureSectionInvalid; 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; + // Constants for the deadzone radius that can be changed in the settings + static CGFloat deadzoneRadius = 20.0; + +/***** Helper functions *****/ // Helper function to adjust brightness void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { float newBrightness = initialBrightness + (translationX / 1000.0); @@ -716,9 +729,8 @@ BOOL isTabSelected = NO; [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) { - + 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 @@ -740,12 +752,12 @@ BOOL isTabSelected = NO; break; } }; +/***** End of Helper functions *****/ - // Handle gesture based on current gesture state if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { // Get the gesture's start position - CGPoint startLocation = [panGestureRecognizer locationInView:self.view]; + startLocation = [panGestureRecognizer locationInView:self.view]; CGFloat viewHeight = self.view.bounds.size.height; // Determine the section based on the start position @@ -758,21 +770,29 @@ BOOL isTabSelected = NO; gestureSection = GestureSectionBottom; } - // Reset all starting values + // Deactive the flag isValidHorizontalPan = NO; - initialBrightness = [UIScreen mainScreen].brightness; - initialVolume = [[AVAudioSession sharedInstance] outputVolume]; - currentTime = self.currentVideoMediaTime; } - + 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; } else { - // If vertical movement is greater, cancel the gesture recognizer + // Cancel the gesture if the translation is not horizontal panGestureRecognizer.state = UIGestureRecognizerStateCancelled; return; } @@ -780,24 +800,28 @@ BOOL isTabSelected = NO; // 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", translation.x, initialBrightness, initialVolume, currentTime); + runSelectedGesture(@"playerGestureTopSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); } else if (gestureSection == GestureSectionMiddle) { - runSelectedGesture(@"playerGestureMiddleSelection", translation.x, initialBrightness, initialVolume, currentTime); + runSelectedGesture(@"playerGestureMiddleSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); } else if (gestureSection == GestureSectionBottom) { - runSelectedGesture(@"playerGestureBottomSelection", translation.x, initialBrightness, initialVolume, currentTime); + runSelectedGesture(@"playerGestureBottomSelection", adjustedTranslationX, initialBrightness, initialVolume, currentTime); } } } - + if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { if (isValidHorizontalPan) { // Provide haptic feedback upon successful gesture recognition - UINotificationFeedbackGenerator *feedbackGenerator = [[UINotificationFeedbackGenerator alloc] init]; - [feedbackGenerator notificationOccurred:UINotificationFeedbackTypeSuccess]; - feedbackGenerator = nil; + [feedbackGenerator prepare]; + [feedbackGenerator impactOccurred]; } } + } // allow the pan gesture to be recognized simultaneously with other gestures From e62699749d303b5d70519041d88e26188498051c Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:25:24 -0700 Subject: [PATCH 041/102] Sensitivity and Deadzone settings --- Source/Settings.xm | 82 ++++++++++++++++++++++++++++++++++++++++++++-- YTLitePlus.h | 12 +++++++ YTLitePlus.xm | 37 ++++++++++----------- 3 files changed, 108 insertions(+), 23 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index b1b1fb8..5e0cd76 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -221,7 +221,6 @@ static const NSInteger YTLiteSection = 789; } }; - // Helper to generate checkmark setting items for selecting gesture modes static YTSettingsSectionItem* (^gestureCheckmarkSettingItem)(NSInteger, NSString *) = ^(NSInteger idx, NSString *key) { return [YTSettingsSectionItemClass @@ -247,7 +246,7 @@ static const NSInteger YTLiteSection = 789; gestureCheckmarkSettingItem(1, sectionKey), gestureCheckmarkSettingItem(2, sectionKey) ]; - + // Present picker when selecting this settings item YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(sectionLabel) pickerSectionTitle:nil @@ -260,12 +259,89 @@ static const NSInteger YTLiteSection = 789; } ]; }; + // Configuration picker for deadzone to pick from 0 to 100 pixels with interval of 10 + YTSettingsSectionItem *deadzonePicker = [YTSettingsSectionItemClass + itemWithTitle:LOC(@"Deadzone (Beta)") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return [NSString stringWithFormat:@"%ld px", (long)GetFloat(@"playerGestureDeadzone") * 10]; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // Generate rows for deadzone picker + NSMutableArray *deadzoneRows = [NSMutableArray array]; + for (int i = 0; i <= 10; i++) { + [deadzoneRows addObject:[YTSettingsSectionItemClass + checkmarkItemWithTitle:[NSString stringWithFormat:@"%ld px", (long)i * 10] + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:i forKey:@"playerGestureDeadzone"]; + [settingsViewController reloadData]; + return YES; + } + ]]; + } + // Present deadzone picker when selecting this settings item + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(@"Deadzone (Beta)") + pickerSectionTitle:nil + rows:deadzoneRows + selectedItemIndex:GetFloat(@"playerGestureDeadzone") + 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 + YTSettingsSectionItem *sensitivtyPicker = [YTSettingsSectionItemClass + itemWithTitle:LOC(@"Sensitivity (Beta)") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return [NSString stringWithFormat:@"%.1f", GetFloat(@"playerGestureSensitivity") * 0.1 + 0.5]; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // Generate rows for sensitivity picker + NSMutableArray *sensitivityRows = [NSMutableArray array]; + for (int i = 5; i <= 20; i++) { + [sensitivityRows addObject:[YTSettingsSectionItemClass + checkmarkItemWithTitle:[NSString stringWithFormat:@"%.1f", i * 0.1] + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:i forKey:@"playerGestureSensitivity"]; + [settingsViewController reloadData]; + return YES; + } + ]]; + } + // Present sensitivity picker + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] + initWithNavTitle:LOC(@"Sensitivity (Beta)") + pickerSectionTitle:nil + rows:sensitivityRows + selectedItemIndex:GetFloat(@"playerGestureSensitivity") + parentResponder:[self parentResponder] + ]; + [settingsViewController pushViewController:picker]; + return YES; + } + ] + + // High level gestures menu YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ + // Description header item + [YTSettingsSectionItemClass + itemWithTitle:nil + accessibilityIdentifier:nil + detailTextBlock:LOC(@"Configure horizontal pan gestures for the player.") + selectBlock:nil + ], + // Pickers for each gesture section createSectionGestureSelector(@"Top Section (Beta)", @"playerGestureTopSelection"), createSectionGestureSelector(@"Middle Section (Beta)", @"playerGestureMiddleSelection"), - createSectionGestureSelector(@"Bottom Section (Beta)", @"playerGestureBottomSelection") + createSectionGestureSelector(@"Bottom Section (Beta)", @"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]; diff --git a/YTLitePlus.h b/YTLitePlus.h index 9261cfe..52ac085 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -58,6 +58,7 @@ // 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 @@ -149,6 +150,17 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @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 2055fea..fed5597 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -640,17 +640,6 @@ BOOL isTabSelected = NO; } %end -@interface YTPlayerViewController (YTLitePlus) -// the long press gesture that will be created and added to the player view -@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 - // Gestures - @bhackel %group playerGestures %hook YTWatchLayerViewController @@ -689,19 +678,21 @@ BOOL isTabSelected = NO; static CGPoint startLocation; // Variable to track the X translation when exiting the deadzone static CGFloat deadzoneStartingXTranslation; - // Constants for the deadzone radius that can be changed in the settings - static CGFloat deadzoneRadius = 20.0; + // 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(@"playerGestureSensitivity"); /***** Helper functions *****/ // Helper function to adjust brightness void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { - float newBrightness = initialBrightness + (translationX / 1000.0); + 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); + 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]; @@ -769,8 +760,7 @@ BOOL isTabSelected = NO; } else if (startLocation.y <= viewHeight) { gestureSection = GestureSectionBottom; } - - // Deactive the flag + // Deactive the activity flag isValidHorizontalPan = NO; } @@ -791,6 +781,9 @@ BOOL isTabSelected = NO; 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; @@ -813,7 +806,6 @@ BOOL isTabSelected = NO; } } } - if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { if (isValidHorizontalPan) { // Provide haptic feedback upon successful gesture recognition @@ -823,13 +815,11 @@ BOOL isTabSelected = NO; } } - // allow the pan gesture to be recognized simultaneously with other gestures %new - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } - %end %end @@ -1090,4 +1080,11 @@ BOOL isTabSelected = NO; 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:@"playerGestureSensitivity"]) { + [[NSUserDefaults standardUserDefaults] setFloat:1.0 forKey:@"playerGestureSensitivity"]; + } } From feaaa07e9e30d2cf52103b0a90ff8b19762556ec Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:33:37 -0700 Subject: [PATCH 042/102] Revert "Prototype 2" This reverts commit 8f578bb741f6d1c9f39dedf0dfa24c686a75ae66. --- Source/Settings.xm | 14 ++++---------- YTLitePlus.h | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 2a1469f..8be7b15 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -200,24 +200,18 @@ static const NSInteger YTLiteSection = 789; [sectionItems addObject:pasteSettings]; YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"VIDEO_PLAYER") - titleDescription:LOC(@"VIDEO_PLAYER_DESC") + itemWithTitle:LOC(@"VIDEO_PICKER") + titleDescription:LOC(@"VIDEO_PICKER_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { // Access the current view controller UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; if (settingsViewController) { - // Define the content types for movies and videos using UTType - NSArray *contentTypes = @[[UTType typeWithIdentifier:@"public.movie"], - [UTType typeWithIdentifier:@"public.video"]]; - - // Initialize the document picker for opening content types - UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:contentTypes]; + // Present the video picker + UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo] inMode:UIDocumentPickerModeImport]; documentPicker.delegate = (id)self; documentPicker.allowsMultipleSelection = NO; - - // Present the document picker [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; } else { NSLog(@"settingsViewController is nil"); diff --git a/YTLitePlus.h b/YTLitePlus.h index ade859b..f737d46 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -7,7 +7,7 @@ #import #import #import // For AVPlayer and AVPlayerViewController -#import // Required for UTType +#import // For kUTTypeMovie and kUTTypeVideo #import "Tweaks/FLEX/FLEX.h" From e21e026c30041317f329acdce88173dc0ee1e97b Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:32:22 -0700 Subject: [PATCH 043/102] Fix compile --- Source/Settings.xm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 5e0cd76..a974503 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -292,7 +292,7 @@ static const NSInteger YTLiteSection = 789; } ]; // Configuration picker for sensitivity to pick from 0.5 to 2.0 with interval of 0.1 - YTSettingsSectionItem *sensitivtyPicker = [YTSettingsSectionItemClass + YTSettingsSectionItem *sensitivityPicker = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Sensitivity (Beta)") accessibilityIdentifier:nil detailTextBlock:^NSString *() { @@ -322,8 +322,7 @@ static const NSInteger YTLiteSection = 789; [settingsViewController pushViewController:picker]; return YES; } - ] - + ]; // High level gestures menu YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { @@ -332,7 +331,9 @@ static const NSInteger YTLiteSection = 789; [YTSettingsSectionItemClass itemWithTitle:nil accessibilityIdentifier:nil - detailTextBlock:LOC(@"Configure horizontal pan gestures for the player.") + detailTextBlock:^NSString *() { + return LOC(@"Configure horizontal pan gestures for the player."); + } selectBlock:nil ], // Pickers for each gesture section From 6e8bbcb49e99c4e2adee9e7951c22610c3c2bf1d Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:01:33 -0700 Subject: [PATCH 044/102] Add localization --- Source/Settings.xm | 4 ++-- lang/YTLitePlus.bundle/ar.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/bg.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/de.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/en.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/es.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/fr.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ja.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/pt.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ro.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/ru.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/template.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/tr.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/vi.lproj/Localizable.strings | 3 +++ lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings | 3 +++ 15 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 8be7b15..13854e5 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -200,8 +200,8 @@ static const NSInteger YTLiteSection = 789; [sectionItems addObject:pasteSettings]; YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"VIDEO_PICKER") - titleDescription:LOC(@"VIDEO_PICKER_DESC") + itemWithTitle:LOC(@"VIDEO_PLAYER") + titleDescription:LOC(@"VIDEO_PLAYER_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index ce93d10..c3d75f6 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 076d430..899a13d 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Заменете бутоните 'Копиране на настройки' и 'Поставяне на настройки'"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Заменете бутоните с 'Експортиране на настройки' и 'Импортиране на настройки'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 da044fe..3af0bfe 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 4af6499..4c5709e 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 83a74d7..9c5d5f6 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 74e2201..8528ba5 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 6400844..2d4998e 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 f9200e3..54e1961 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Substituir os Botões 'Copiar Configurações' e 'Colar Configurações'"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Substitui os Botões 'Exportar Configurações' e 'Importar Configurações'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 fac3b20..24c93e1 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 11889b4..de4db99 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 473514e..51fb259 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -28,6 +28,9 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 62afeea..dbcb7b1 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "'Ayarları Kopyala' ve 'Ayarları Yapıştır' Düğmelerini Değiştir"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Düğmeleri 'Ayarları Dışa Aktar' ve 'Ayarları İçe Aktar' ile değiştirir"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 d8dea0e..2df3292 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // 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 7fd520a..7d3bffb 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -14,6 +14,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"VIDEO_PLAYER" = "Video Player (Beta)"; +"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定"; From e63bc374cf8ed56641f4584e11b18d5a66e97b21 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 01:13:22 -0700 Subject: [PATCH 045/102] Fix defaults and text descriptions --- Source/Settings.xm | 83 ++++++++++++------- YTLitePlus.xm | 6 +- .../ar.lproj/Localizable.strings | 3 + .../bg.lproj/Localizable.strings | 3 + .../de.lproj/Localizable.strings | 3 + .../en.lproj/Localizable.strings | 3 + .../es.lproj/Localizable.strings | 3 + .../fr.lproj/Localizable.strings | 3 + .../ja.lproj/Localizable.strings | 3 + .../pt.lproj/Localizable.strings | 3 + .../ro.lproj/Localizable.strings | 3 + .../ru.lproj/Localizable.strings | 3 + .../template.lproj/Localizable.strings | 3 + .../tr.lproj/Localizable.strings | 3 + .../vi.lproj/Localizable.strings | 3 + .../zh_TW.lproj/Localizable.strings | 3 + 16 files changed, 100 insertions(+), 31 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index a974503..2c0e14b 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -211,11 +211,11 @@ static const NSInteger YTLiteSection = 789; static NSString* (^sectionGestureSelectedModeToString)(GestureMode) = ^(GestureMode sectionIndex) { switch (sectionIndex) { case GestureModeVolume: - return LOC(@"Volume (Beta)"); + return LOC(@"Volume"); case GestureModeBrightness: - return LOC(@"Brightness (Beta)"); + return LOC(@"Brightness"); case GestureModeSeek: - return LOC(@"Seek (Beta)"); + return LOC(@"Seek"); default: return @"Invalid index - Report bug"; } @@ -260,86 +260,114 @@ static const NSInteger YTLiteSection = 789; ]; }; // 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 (Beta)") + itemWithTitle:LOC(@"Deadzone") + titleDescription:LOC(@"Minimum distance to move before a gesture is recognized") accessibilityIdentifier:nil detailTextBlock:^NSString *() { - return [NSString stringWithFormat:@"%ld px", (long)GetFloat(@"playerGestureDeadzone") * 10]; + return [NSString stringWithFormat:@"%ld px", (long)GetFloat(@"playerGesturesDeadzone")]; } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - // Generate rows for deadzone picker + // Generate rows for deadzone picker using the predefined array NSMutableArray *deadzoneRows = [NSMutableArray array]; - for (int i = 0; i <= 10; i++) { + for (NSNumber *deadzoneValue in deadzoneValues) { + CGFloat deadzone = [deadzoneValue floatValue]; [deadzoneRows addObject:[YTSettingsSectionItemClass - checkmarkItemWithTitle:[NSString stringWithFormat:@"%ld px", (long)i * 10] + checkmarkItemWithTitle:[NSString stringWithFormat:@"%ld px", (long)deadzone] selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - [[NSUserDefaults standardUserDefaults] setInteger:i forKey:@"playerGestureDeadzone"]; + [[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 (Beta)") + initWithNavTitle:LOC(@"Deadzone") pickerSectionTitle:nil rows:deadzoneRows - selectedItemIndex:GetFloat(@"playerGestureDeadzone") + selectedItemIndex:selectedIndex parentResponder:[self parentResponder] ]; [settingsViewController pushViewController:picker]; return YES; } ]; + [sectionItems addObject:deadzonePicker]; + // 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 (Beta)") + itemWithTitle:LOC(@"Sensitivity") + titleDescription:LOC(@"Multiplier on volume and brightness gestures") accessibilityIdentifier:nil detailTextBlock:^NSString *() { - return [NSString stringWithFormat:@"%.1f", GetFloat(@"playerGestureSensitivity") * 0.1 + 0.5]; + return [NSString stringWithFormat:@"%.1f", GetFloat(@"playerGesturesSensitivity")]; } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - // Generate rows for sensitivity picker + // Generate rows for sensitivity picker using the predefined array NSMutableArray *sensitivityRows = [NSMutableArray array]; - for (int i = 5; i <= 20; i++) { + for (NSNumber *sensitivityValue in sensitivityValues) { + CGFloat sensitivity = [sensitivityValue floatValue]; [sensitivityRows addObject:[YTSettingsSectionItemClass - checkmarkItemWithTitle:[NSString stringWithFormat:@"%.1f", i * 0.1] + checkmarkItemWithTitle:[NSString stringWithFormat:@"%.1f", sensitivity] selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - [[NSUserDefaults standardUserDefaults] setInteger:i forKey:@"playerGestureSensitivity"]; + [[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 (Beta)") + initWithNavTitle:LOC(@"Sensitivity") pickerSectionTitle:nil rows:sensitivityRows - selectedItemIndex:GetFloat(@"playerGestureSensitivity") + selectedItemIndex:selectedIndex parentResponder:[self parentResponder] ]; [settingsViewController pushViewController:picker]; return YES; } ]; + [sectionItems addObject:sensitivityPicker]; // High level gestures menu YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ // Description header item [YTSettingsSectionItemClass - itemWithTitle:nil - accessibilityIdentifier:nil - detailTextBlock:^NSString *() { - return LOC(@"Configure horizontal pan gestures for the player."); - } + itemWithTitle:nil + titleDescription:LOC(@"Configure horizontal pan gestures for the player.") + 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 (Beta)", @"playerGestureTopSelection"), - createSectionGestureSelector(@"Middle Section (Beta)", @"playerGestureMiddleSelection"), - createSectionGestureSelector(@"Bottom Section (Beta)", @"playerGestureBottomSelection"), + createSectionGestureSelector(@"Top Section", @"playerGestureTopSelection"), + createSectionGestureSelector(@"Middle Section", @"playerGestureMiddleSelection"), + createSectionGestureSelector(@"Bottom Section", @"playerGestureBottomSelection"), // Pickers for configuration settings deadzonePicker, sensitivityPicker @@ -372,7 +400,6 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"HIDE_HUD_MESSAGES"), LOC(@"HIDE_HUD_MESSAGES_DESC"), @"hideHUD_enabled"), BASIC_SWITCH(LOC(@"HIDE_COLLAPSE_BUTTON"), LOC(@"HIDE_COLLAPSE_BUTTON_DESC"), @"disableCollapseButton_enabled"), BASIC_SWITCH(LOC(@"HIDE_SPEED_TOAST"), LOC(@"HIDE_SPEED_TOAST_DESC"), @"hideSpeedToast_enabled"), - BASIC_SWITCH(LOC(@"ENABLE_UYOU_GESTURES"), LOC(@"ENABLE_UYOU_GESTURES_DESC"), @"playerGestures_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index fed5597..fc8e947 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -681,7 +681,7 @@ BOOL isTabSelected = NO; // 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(@"playerGestureSensitivity"); + static CGFloat sensitivityFactor = (CGFloat)GetFloat(@"playerGesturesSensitivity"); /***** Helper functions *****/ // Helper function to adjust brightness @@ -1084,7 +1084,7 @@ BOOL isTabSelected = NO; if (![allKeys containsObject:@"playerGesturesDeadzone"]) { [[NSUserDefaults standardUserDefaults] setFloat:20.0 forKey:@"playerGesturesDeadzone"]; } - if (![allKeys containsObject:@"playerGestureSensitivity"]) { - [[NSUserDefaults standardUserDefaults] setFloat:1.0 forKey:@"playerGestureSensitivity"]; + 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 ce93d10..88493c7 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 076d430..a5dbeda 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Заменете бутоните 'Копиране на настройки' и 'Поставяне на настройки'"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Заменете бутоните с 'Експортиране на настройки' и 'Импортиране на настройки'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 da044fe..07b2ada 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 4af6499..618bcb2 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 83a74d7..69d06dd 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 74e2201..f5b24b8 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 6400844..5dd4f3c 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 f9200e3..c8e734d 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Substituir os Botões 'Copiar Configurações' e 'Colar Configurações'"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Substitui os Botões 'Exportar Configurações' e 'Importar Configurações'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 fac3b20..3be083e 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 11889b4..0efbea6 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 473514e..5efa1cd 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -28,6 +28,9 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 62afeea..815d24a 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "'Ayarları Kopyala' ve 'Ayarları Yapıştır' Düğmelerini Değiştir"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Düğmeleri 'Ayarları Dışa Aktar' ve 'Ayarları İçe Aktar' ile değiştirir"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 d8dea0e..af9750c 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -13,6 +13,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // 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 7fd520a..47ef9c2 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -14,6 +14,9 @@ "REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; "REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Enable Player Gestures"; + // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定"; From 36f9da844b230f76f5400b49f4ac46c95bb77d93 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Fri, 16 Aug 2024 09:27:09 -0700 Subject: [PATCH 046/102] Add disable option --- Source/Settings.xm | 11 ++++++----- YTLitePlus.h | 2 +- YTLitePlus.xm | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 2c0e14b..f45faef 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -216,6 +216,8 @@ static const NSInteger YTLiteSection = 789; return LOC(@"Brightness"); case GestureModeSeek: return LOC(@"Seek"); + case GestureModeDisabled: + return LOC(@"Disabled"); default: return @"Invalid index - Report bug"; } @@ -242,9 +244,10 @@ static const NSInteger YTLiteSection = 789; } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ - gestureCheckmarkSettingItem(0, sectionKey), - gestureCheckmarkSettingItem(1, sectionKey), - gestureCheckmarkSettingItem(2, sectionKey) + 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] @@ -303,7 +306,6 @@ static const NSInteger YTLiteSection = 789; return YES; } ]; - [sectionItems addObject:deadzonePicker]; // Configuration picker for sensitivity to pick from 0.5 to 2.0 with interval of 0.1 NSMutableArray *sensitivityValues = [NSMutableArray array]; @@ -349,7 +351,6 @@ static const NSInteger YTLiteSection = 789; return YES; } ]; - [sectionItems addObject:sensitivityPicker]; // High level gestures menu YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { diff --git a/YTLitePlus.h b/YTLitePlus.h index 52ac085..07f416f 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -66,7 +66,7 @@ typedef NS_ENUM(NSUInteger, GestureMode) { GestureModeVolume, GestureModeBrightness, GestureModeSeek, - GestureModeInvalid + GestureModeDisabled }; // Gesture Section Enum typedef NS_ENUM(NSUInteger, GestureSection) { diff --git a/YTLitePlus.xm b/YTLitePlus.xm index fc8e947..61b9935 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -735,7 +735,11 @@ BOOL isTabSelected = NO; 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]; @@ -755,10 +759,27 @@ BOOL isTabSelected = NO; // 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; @@ -803,6 +824,9 @@ BOOL isTabSelected = NO; 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; } } } From de89f7aca8ee5fbb9fae857b61418c4c0c8c4021 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 17 Aug 2024 00:43:19 +0000 Subject: [PATCH 047/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 546c8e0..4e362b6 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 546c8e0a258c21258a7ce3f8af15bbb6348bb2c9 +Subproject commit 4e362b66bf524ff2dfb08db6533f4de0e2b089a3 From 4c5e2ee0e8673285a3c3e10d7eaaf3b3d5647970 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 18 Aug 2024 00:49:27 +0000 Subject: [PATCH 048/102] updated submodules --- Tweaks/Return-YouTube-Dislikes | 2 +- Tweaks/YTUHD | 2 +- Tweaks/YouTubeHeader | 2 +- Tweaks/protobuf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tweaks/Return-YouTube-Dislikes b/Tweaks/Return-YouTube-Dislikes index 0f4c6b7..0a223d3 160000 --- a/Tweaks/Return-YouTube-Dislikes +++ b/Tweaks/Return-YouTube-Dislikes @@ -1 +1 @@ -Subproject commit 0f4c6b7f5960308161c870d9aab30905fe8145cc +Subproject commit 0a223d326c3d79aef9a73085c25e125e1f9b512b diff --git a/Tweaks/YTUHD b/Tweaks/YTUHD index 17c2035..02a5c91 160000 --- a/Tweaks/YTUHD +++ b/Tweaks/YTUHD @@ -1 +1 @@ -Subproject commit 17c2035ea9c8334f2d9154f114b6590928e93521 +Subproject commit 02a5c915a7f4183307812a94759d73f25e7fdba6 diff --git a/Tweaks/YouTubeHeader b/Tweaks/YouTubeHeader index a1d9216..ccee5a1 160000 --- a/Tweaks/YouTubeHeader +++ b/Tweaks/YouTubeHeader @@ -1 +1 @@ -Subproject commit a1d9216d1f42f54bf9fff3ba22e7fbcaaf43e72a +Subproject commit ccee5a1f236ad589f76e065541a8f188b0a900e8 diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 4e362b6..025909c 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 4e362b66bf524ff2dfb08db6533f4de0e2b089a3 +Subproject commit 025909cb539359c8001cf69707229587d430adff From 023fafae15be7b13a28b78dfd78c625db729afe8 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 18 Aug 2024 18:17:32 -0700 Subject: [PATCH 049/102] Added YouLoop submodule to Tweaks/ folder --- .gitmodules | 3 +++ Makefile | 5 +++-- Tweaks/YouLoop | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 160000 Tweaks/YouLoop 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/Tweaks/YouLoop b/Tweaks/YouLoop new file mode 160000 index 0000000..4cd5d01 --- /dev/null +++ b/Tweaks/YouLoop @@ -0,0 +1 @@ +Subproject commit 4cd5d01d3c6a1c7c1725c89208a5cc8cedad962f From 44d6ffe781045bdf9103a630f9caad1008f215bf Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:08:08 -0700 Subject: [PATCH 050/102] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4df64a9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 YTLitePlus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From f652976a536b813b4176f7126f44bd9e8d962ccb Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 20 Aug 2024 00:44:56 +0000 Subject: [PATCH 051/102] updated submodules --- Tweaks/Return-YouTube-Dislikes | 2 +- Tweaks/YouTubeHeader | 2 +- Tweaks/protobuf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tweaks/Return-YouTube-Dislikes b/Tweaks/Return-YouTube-Dislikes index 0a223d3..8578263 160000 --- a/Tweaks/Return-YouTube-Dislikes +++ b/Tweaks/Return-YouTube-Dislikes @@ -1 +1 @@ -Subproject commit 0a223d326c3d79aef9a73085c25e125e1f9b512b +Subproject commit 8578263c9f7caf7a22bd9364648e218974ee543c diff --git a/Tweaks/YouTubeHeader b/Tweaks/YouTubeHeader index ccee5a1..850e939 160000 --- a/Tweaks/YouTubeHeader +++ b/Tweaks/YouTubeHeader @@ -1 +1 @@ -Subproject commit ccee5a1f236ad589f76e065541a8f188b0a900e8 +Subproject commit 850e939ce7053f593ed477e83ec914c98669be46 diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 025909c..57ba428 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 025909cb539359c8001cf69707229587d430adff +Subproject commit 57ba42815efe292b3c9c99e8afadf13bbb13fff1 From 87d7b576ddf7e41d1bc733a37c6ccd63023ed12a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 20 Aug 2024 00:53:21 +0000 Subject: [PATCH 052/102] updated submodules --- Tweaks/Return-YouTube-Dislikes | 2 +- Tweaks/YouTubeHeader | 2 +- Tweaks/protobuf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tweaks/Return-YouTube-Dislikes b/Tweaks/Return-YouTube-Dislikes index 0a223d3..8578263 160000 --- a/Tweaks/Return-YouTube-Dislikes +++ b/Tweaks/Return-YouTube-Dislikes @@ -1 +1 @@ -Subproject commit 0a223d326c3d79aef9a73085c25e125e1f9b512b +Subproject commit 8578263c9f7caf7a22bd9364648e218974ee543c diff --git a/Tweaks/YouTubeHeader b/Tweaks/YouTubeHeader index ccee5a1..850e939 160000 --- a/Tweaks/YouTubeHeader +++ b/Tweaks/YouTubeHeader @@ -1 +1 @@ -Subproject commit ccee5a1f236ad589f76e065541a8f188b0a900e8 +Subproject commit 850e939ce7053f593ed477e83ec914c98669be46 diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 025909c..57ba428 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 025909cb539359c8001cf69707229587d430adff +Subproject commit 57ba42815efe292b3c9c99e8afadf13bbb13fff1 From bed87298f614ad8ecdb2ab6df06dc3c7e4e506f7 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 18 Aug 2024 22:25:52 -0700 Subject: [PATCH 053/102] Update Submodule --- Tweaks/YouLoop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/YouLoop b/Tweaks/YouLoop index 4cd5d01..5a424d7 160000 --- a/Tweaks/YouLoop +++ b/Tweaks/YouLoop @@ -1 +1 @@ -Subproject commit 4cd5d01d3c6a1c7c1725c89208a5cc8cedad962f +Subproject commit 5a424d7531c0d2f82d258b8e8c580e153a93fcdd From 5066716f7f531fd1da22327bd06340498d4ac906 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 19 Aug 2024 23:53:21 -0700 Subject: [PATCH 054/102] Localizations for Gestures --- Source/Settings.xm | 49 ++++++++++--------- .../ar.lproj/Localizable.strings | 13 +++++ .../bg.lproj/Localizable.strings | 13 +++++ .../de.lproj/Localizable.strings | 13 +++++ .../en.lproj/Localizable.strings | 13 +++++ .../es.lproj/Localizable.strings | 13 +++++ .../fr.lproj/Localizable.strings | 13 +++++ .../ja.lproj/Localizable.strings | 13 +++++ .../pt.lproj/Localizable.strings | 13 +++++ .../ro.lproj/Localizable.strings | 13 +++++ .../ru.lproj/Localizable.strings | 13 +++++ .../template.lproj/Localizable.strings | 13 +++++ .../tr.lproj/Localizable.strings | 13 +++++ .../vi.lproj/Localizable.strings | 13 +++++ .../zh_TW.lproj/Localizable.strings | 13 +++++ 15 files changed, 207 insertions(+), 24 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index f45faef..8a8aaeb 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -74,7 +74,7 @@ static const NSInteger YTLiteSection = 789; %end -// Settings +// Add YTLitePlus to the settings list %hook YTAppSettingsPresentationData + (NSArray *)settingsCategoryOrder { NSArray *order = %orig; @@ -102,14 +102,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) @@ -211,13 +212,13 @@ static const NSInteger YTLiteSection = 789; static NSString* (^sectionGestureSelectedModeToString)(GestureMode) = ^(GestureMode sectionIndex) { switch (sectionIndex) { case GestureModeVolume: - return LOC(@"Volume"); + return LOC(@"VOLUME"); case GestureModeBrightness: - return LOC(@"Brightness"); + return LOC(@"BRIGHTNESS"); case GestureModeSeek: - return LOC(@"Seek"); + return LOC(@"SEEK"); case GestureModeDisabled: - return LOC(@"Disabled"); + return LOC(@"DISABLED"); default: return @"Invalid index - Report bug"; } @@ -268,8 +269,8 @@ static const NSInteger YTLiteSection = 789; [deadzoneValues addObject:@(value)]; } YTSettingsSectionItem *deadzonePicker = [YTSettingsSectionItemClass - itemWithTitle:LOC(@"Deadzone") - titleDescription:LOC(@"Minimum distance to move before a gesture is recognized") + itemWithTitle:LOC(@"DEADZONE") + titleDescription:LOC(@"DEADZONE_DESC") accessibilityIdentifier:nil detailTextBlock:^NSString *() { return [NSString stringWithFormat:@"%ld px", (long)GetFloat(@"playerGesturesDeadzone")]; @@ -296,7 +297,7 @@ static const NSInteger YTLiteSection = 789; } // Present deadzone picker when selecting this settings item YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] - initWithNavTitle:LOC(@"Deadzone") + initWithNavTitle:LOC(@"DEADZONE") pickerSectionTitle:nil rows:deadzoneRows selectedItemIndex:selectedIndex @@ -313,8 +314,8 @@ static const NSInteger YTLiteSection = 789; [sensitivityValues addObject:@(value)]; } YTSettingsSectionItem *sensitivityPicker = [YTSettingsSectionItemClass - itemWithTitle:LOC(@"Sensitivity") - titleDescription:LOC(@"Multiplier on volume and brightness gestures") + itemWithTitle:LOC(@"SENSITIVITY") + titleDescription:LOC(@"SENSITIVITY_DESC") accessibilityIdentifier:nil detailTextBlock:^NSString *() { return [NSString stringWithFormat:@"%.1f", GetFloat(@"playerGesturesSensitivity")]; @@ -341,7 +342,7 @@ static const NSInteger YTLiteSection = 789; } // Present sensitivity picker YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] - initWithNavTitle:LOC(@"Sensitivity") + initWithNavTitle:LOC(@"SENSITIVITY") pickerSectionTitle:nil rows:sensitivityRows selectedItemIndex:selectedIndex @@ -352,13 +353,13 @@ static const NSInteger YTLiteSection = 789; } ]; - // High level gestures menu - YTSettingsSectionItem *playerGesturesGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Player Gestures (Beta)") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + // 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(@"Configure horizontal pan gestures for the player.") + titleDescription:LOC(@"PLAYER_GESTURES_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:nil @@ -366,9 +367,9 @@ static const NSInteger YTLiteSection = 789; // 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"), + createSectionGestureSelector(@"TOP_SECTION", @"playerGestureTopSelection"), + createSectionGestureSelector(@"MIDDLE_SECTION", @"playerGestureMiddleSelection"), + createSectionGestureSelector(@"BOTTOM_SECTION", @"playerGestureBottomSelection"), // Pickers for configuration settings deadzonePicker, sensitivityPicker diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index 88493c7..2820e92 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 a5dbeda..5d2c48a 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 07b2ada..3671c43 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 618bcb2..80781ce 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 69d06dd..8a7817b 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 f5b24b8..284a08e 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 5dd4f3c..931e0bf 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 c8e734d..ff49e3a 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 3be083e..c11bba9 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 0efbea6..ce1184e 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 5efa1cd..1b60f3e 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -30,6 +30,19 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap // 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 815d24a..f7c8b9f 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 af9750c..5094da9 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -15,6 +15,19 @@ // 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 47ef9c2..08796a9 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -16,6 +16,19 @@ // 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" = "影片區覆蓋按鈕設定"; From 4f890f4e0d8588a887f44229984b7d16800fec67 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 21 Aug 2024 00:44:32 +0000 Subject: [PATCH 055/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 57ba428..9a24fc9 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 57ba42815efe292b3c9c99e8afadf13bbb13fff1 +Subproject commit 9a24fc999d094c98395c1f371e498b160afa3de5 From 7797875a8742987b9ed17d896cd629c6817d17bf Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 22 Aug 2024 00:46:07 +0000 Subject: [PATCH 056/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 9a24fc9..eca12ff 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 9a24fc999d094c98395c1f371e498b160afa3de5 +Subproject commit eca12ff466e05f8c563d714caaba11f5a5ee7123 From c0a2ec26ed1bddef3317c5cc421bd2a01f086c95 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:34:37 -0700 Subject: [PATCH 057/102] Revert bigytminiplayer --- YTLitePlus.xm | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 61b9935..e32c7ff 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -847,7 +847,6 @@ BOOL isTabSelected = NO; %end %end -/* // BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer %group Main %hook YTWatchMiniBarView @@ -872,20 +871,6 @@ BOOL isTabSelected = NO; } %end %end -*/ -// New Big YT Mini Player - @bhackel -%hook YTColdConfig -- (BOOL)enableIosFloatingMiniplayer { - // Modify if not on iPad - return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; -} -- (BOOL)enableIosFloatingMiniplayerRepositioning { - return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; -} -- (BOOL)enableIosFloatingMiniplayerResizing { - return (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) ? IsEnabled(@"bigYTMiniPlayer_enabled") : %orig; -} -%end // App Settings Overlay Options %group gDisableAccountSection @@ -1019,9 +1004,9 @@ BOOL isTabSelected = NO; if (IsEnabled(@"iPhoneLayout_enabled")) { %init(giPhoneLayout); } - // if (IsEnabled(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) { - // %init(Main); - // } + if (IsEnabled(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) { + %init(Main); + } if (IsEnabled(@"hideVideoPlayerShadowOverlayButtons_enabled")) { %init(gHideVideoPlayerShadowOverlayButtons); } From 8eed3ce8bc7d3214df72e4e4e68d3c6dfbe1f3c4 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:14:02 -0700 Subject: [PATCH 058/102] Fix playback in feeds on iPad --- Source/Settings.xm | 22 ++++++++++++++-------- YTLitePlus.h | 4 ++-- YTLitePlus.xm | 8 ++++---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index c25f262..5bfd862 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -266,7 +266,7 @@ static const NSInteger YTLiteSection = 789; return [YTSettingsSectionItemClass itemWithTitle:LOC(sectionLabel) accessibilityIdentifier:nil detailTextBlock:^NSString *() { - return sectionGestureSelectedModeToString(GetSelection(sectionKey)); + return sectionGestureSelectedModeToString(GetInteger(sectionKey)); } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { NSArray *rows = @[ @@ -280,7 +280,7 @@ static const NSInteger YTLiteSection = 789; initWithNavTitle:LOC(sectionLabel) pickerSectionTitle:nil rows:rows - selectedItemIndex:GetSelection(sectionKey) + selectedItemIndex:GetInteger(sectionKey) parentResponder:[self parentResponder] ]; [settingsViewController pushViewController:picker]; @@ -559,7 +559,7 @@ static const NSInteger YTLiteSection = 789; YTSettingsSectionItem *themeGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"THEME_OPTIONS") accessibilityIdentifier:nil detailTextBlock:^NSString *() { - switch (GetSelection(@"appTheme")) { + switch (GetInteger(@"appTheme")) { case 1: return LOC(@"OLD_DARK_THEME"); case 0: @@ -583,7 +583,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"LOW_CONTRAST_MODE"), LOC(@"LOW_CONTRAST_MODE_DESC"), @"lowContrastMode_enabled"), lowContrastModeSection ]; - YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"THEME_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:GetSelection(@"appTheme") parentResponder:[self parentResponder]]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"THEME_OPTIONS") pickerSectionTitle:nil rows:rows selectedItemIndex:GetInteger(@"appTheme") parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; return YES; }]; @@ -595,7 +595,8 @@ static const NSInteger YTLiteSection = 789; YTSettingsSectionItem *playbackInFeedsGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"PLAYBACK_IN_FEEDS") accessibilityIdentifier:nil detailTextBlock:^NSString *() { - switch (GetSelection(@"inline_muted_playback_enabled")) { + // The specific values were gathered by checking the value for each setting + switch (GetInteger(@"inline_muted_playback_enabled")) { case 3: return LOC(@"PLAYBACK_IN_FEEDS_WIFI_ONLY"); case 1: @@ -624,9 +625,14 @@ static const NSInteger YTLiteSection = 789; }], ]; // It seems values greater than 3 act the same as Always On (Index 1) - int (^getInlineSelection)() = ^int() { - int selection = GetSelection(@"inline_muted_playback_enabled") - 1; - return selection > 3 ? 1 : selection; + // Convert the stored value to an index for a picker (0 to 2) + NSInteger (^getInlineSelection)(void) = ^NSInteger(void) { + NSInteger selection = GetInteger(@"inline_muted_playback_enabled") - 1; + // Check if selection is within the valid bounds [0, 1, 2] + if (selection < 0 || selection > 2) { + return 1; + } + return selection; }; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"PLAYBACK_IN_FEEDS") pickerSectionTitle:nil rows:rows selectedItemIndex:getInlineSelection() parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.h b/YTLitePlus.h index 8a41583..34c0deb 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -59,8 +59,8 @@ // 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] +#define GetInteger(key) [[NSUserDefaults standardUserDefaults] integerForKey:key] // NSInteger type +#define GetFloat(key) [[NSUserDefaults standardUserDefaults] floatForKey:key] // float type // Player Gesture selected mode enum diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 61b9935..2df89b2 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -723,7 +723,7 @@ BOOL isTabSelected = NO; 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); + GestureMode selectedGestureMode = (GestureMode)GetInteger(sectionKey); // Handle the gesture action based on the selected mode switch (selectedGestureMode) { case GestureModeVolume: @@ -760,21 +760,21 @@ BOOL isTabSelected = NO; if (startLocation.y <= viewHeight / 3.0) { gestureSection = GestureSectionTop; // Cancel the gesture if the mode is disabled - if (GetSelection(@"playerGestureTopSelection") == GestureModeDisabled) { + if (GetInteger(@"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) { + if (GetInteger(@"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) { + if (GetInteger(@"playerGestureBottomSelection") == GestureModeDisabled) { panGestureRecognizer.state = UIGestureRecognizerStateCancelled; return; } From 0d72c03167ae605aaa30905c120f0855e65ac8de Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:23:02 -0700 Subject: [PATCH 059/102] Add keys to Copy Settings --- Source/Settings.xm | 18 +++----- Source/SettingsKeys.h | 42 +++++++++++++++++++ Source/get_keys.py | 96 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 Source/SettingsKeys.h create mode 100644 Source/get_keys.py diff --git a/Source/Settings.xm b/Source/Settings.xm index c25f262..00e49e7 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -5,6 +5,7 @@ #import "../Tweaks/YouTubeHeader/YTSettingsSectionItemManager.h" #import "../Tweaks/YouTubeHeader/YTUIUtils.h" #import "../Tweaks/YouTubeHeader/YTSettingsPickerViewController.h" +#import "SettingsKeys.h" // #import "AppIconOptionsController.h" // Basic switch item @@ -47,17 +48,6 @@ static int appVersionSpoofer() { extern NSBundle *YTLitePlusBundle(); -// Keys for "Copy Settings" button (for: YTLitePlus) -NSArray *copyKeys = @[ -/* MAIN Controls Keys 1/2 */ @"enableShareButton_enabled", @"enableSaveToButton_enabled", @"hideVideoPlayerShadowOverlayButtons_enabled", @"hideRightPanel_enabled", @"hideHeatwaves_enabled", @"disableAmbientModePortrait_enabled", -/* MAIN Controls Keys 2/2 */ @"disableAmbientModeFullscreen_enabled", @"fullscreenToTheRight_enabled", @"seekAnywhere_enabled", @"YTTapToSeek_enabled", @"disablePullToFull_enabled", @"alwaysShowRemainingTime_enabled", @"disableRemainingTime_enabled", @"disableEngagementOverlay_enabled", -/* MAIN App Overlay Keys 1/2 */ @"disableAccountSection_enabled", @"disableAutoplaySection_enabled", @"disableTryNewFeaturesSection_enabled", @"disableVideoQualityPreferencesSection_enabled", @"disableNotificationsSection_enabled", -/* MAIN App Overlay Keys 2/2 */ @"disableManageAllHistorySection_enabled", @"disableYourDataInYouTubeSection_enabled", @"disablePrivacySection_enabled", @"disableLiveChatSection_enabled", -/* MAIN Playback Keys */ @"inline_muted_playback_enabled", -/* MAIN Misc Keys */ @"newSettingsUI_enabled", @"ytStartupAnimation_enabled", @"ytNoModernUI_enabled", @"iPadLayout_enabled", @"iPhoneLayout_enabled", @"castConfirm_enabled", @"bigYTMiniPlayer_enabled", @"hideCastButton_enabled", @"hideSponsorBlockButton_enabled", @"hideHomeTab_enabled", @"fixCasting_enabled", @"flex_enabled", @"enableVersionSpoofer_enabled", -/* TWEAK YTUHD Keys */ @"EnableVP9", @"AllVP9" -]; - // Add both YTLite and YTLitePlus to YouGroupSettings static const NSInteger YTLitePlusSection = 788; static const NSInteger YTLiteSection = 789; @@ -115,6 +105,7 @@ static const NSInteger YTLiteSection = 789; }]; [sectionItems addObject:main]; +# pragma mark - Copy and Paste Settings YTSettingsSectionItem *copySettings = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"COPY_SETTINGS") titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"COPY_SETTINGS_DESC_2") : LOC(@"COPY_SETTINGS_DESC") @@ -125,7 +116,7 @@ static const NSInteger YTLiteSection = 789; // Export Settings functionality NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"exported_settings.txt"]]; NSMutableString *settingsString = [NSMutableString string]; - for (NSString *key in copyKeys) { + for (NSString *key in NSUserDefaultsCopyKeys) { id value = [[NSUserDefaults standardUserDefaults] objectForKey:key]; if (value) { [settingsString appendFormat:@"%@: %@\n", key, value]; @@ -140,7 +131,7 @@ static const NSInteger YTLiteSection = 789; // Copy Settings functionality (DEFAULT - Copies to Clipboard) NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSMutableString *settingsString = [NSMutableString string]; - for (NSString *key in copyKeys) { + for (NSString *key in NSUserDefaultsCopyKeys) { if ([userDefaults objectForKey:key]) { NSString *value = [userDefaults objectForKey:key]; [settingsString appendFormat:@"%@: %@\n", key, value]; @@ -194,6 +185,7 @@ static const NSInteger YTLiteSection = 789; ]; [sectionItems addObject:pasteSettings]; +# pragma mark - Video Player YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"VIDEO_PLAYER") titleDescription:LOC(@"VIDEO_PLAYER_DESC") diff --git a/Source/SettingsKeys.h b/Source/SettingsKeys.h new file mode 100644 index 0000000..96a5bfb --- /dev/null +++ b/Source/SettingsKeys.h @@ -0,0 +1,42 @@ +#import "../YTLitePlus.h" + +// Keys for "Copy Settings" button (for: YTLitePlus) +// In alphabetical order for tweaks after YTLitePlus +NSArray *NSUserDefaultsCopyKeys = @[ + // YTLitePlus - gathered using get_keys.py + @"YTTapToSeek_enabled", @"alwaysShowRemainingTime_enabled", @"bigYTMiniPlayer_enabled", @"castConfirm_enabled", + @"disableAccountSection_enabled", @"disableAmbientModeFullscreen_enabled", + @"disableAmbientModePortrait_enabled", @"disableAutoplaySection_enabled", @"disableCollapseButton_enabled", + @"disableEngagementOverlay_enabled", @"disableLiveChatSection_enabled", + @"disableManageAllHistorySection_enabled", @"disableNotificationsSection_enabled", + @"disablePrivacySection_enabled", @"disablePullToFull_enabled", @"disableRemainingTime_enabled", + @"disableTryNewFeaturesSection_enabled", @"disableVideoQualityPreferencesSection_enabled", + @"disableYourDataInYouTubeSection_enabled", @"enableSaveToButton_enabled", @"enableShareButton_enabled", + @"enableVersionSpoofer_enabled", @"fixCasting_enabled", @"flex_enabled", @"fullscreenToTheRight_enabled", + @"hideAutoplayMiniPreview_enabled", @"hideCastButton_enabled", @"hideHUD_enabled", @"hideHeatwaves_enabled", + @"hideHomeTab_enabled", @"hidePreviewCommentSection_enabled", @"hideRightPanel_enabled", + @"hideSpeedToast_enabled", @"hideSponsorBlockButton_enabled", @"hideVideoPlayerShadowOverlayButtons_enabled", + @"iPadLayout_enabled", @"iPhoneLayout_enabled", @"inline_muted_playback_enabled", @"lowContrastMode_enabled", + @"newSettingsUI_enabled", @"oledKeyBoard_enabled", @"playerGestures_enabled", @"seekAnywhere_enabled", + @"switchCopyandPasteFunctionality_enabled", @"ytNoModernUI_enabled", @"ytStartupAnimation_enabled", + // DEMC - https://github.com/therealFoxster/DontEatMyContent/blob/master/Tweak.h + @"DEMC_enabled", @"DEMC_colorViewsEnabled", @"DEMC_safeAreaConstant", @"DEMC_disableAmbientMode", + @"DEMC_limitZoomToFill", @"DEMC_enableForAllVideos", + // iSponsorBlock cannot be exported using this method - it is also being removed in v5 + // Return-YouTube-Dislike - https://github.com/PoomSmart/Return-YouTube-Dislikes/blob/main/TweakSettings.h + @"RYD-ENABLED", @"RYD-VOTE-SUBMISSION", @"RYD-EXACT-LIKE-NUMBER", @"RYD-EXACT-NUMBER", + // All YTVideoOverlay Tweaks - https://github.com/PoomSmart/YTVideoOverlay/blob/0fc6d29d1aa9e75f8c13d675daec9365f753d45e/Tweak.x#L28C1-L41C84 + @"YTVideoOverlay-YouLoop-Enabled", @"YTVideoOverlay-YouTimeStamp-Enabled", @"YTVideoOverlay-YouMute-Enabled", + @"YTVideoOverlay-YouQuality-Enabled", @"YTVideoOverlay-YouLoop-Position", @"YTVideoOverlay-YouTimeStamp-Position", + @"YTVideoOverlay-YouMute-Position", @"YTVideoOverlay-YouQuality-Position", + // YouPiP - https://github.com/PoomSmart/YouPiP/blob/main/Header.h + @"YouPiPPosition", @"CompatibilityModeKey", @"PiPActivationMethodKey", @"PiPActivationMethod2Key", + @"NoMiniPlayerPiPKey", @"NonBackgroundableKey", + // YTABConfig cannot be reasonably exported using this method + // YTHoldForSpeed will be removed in v5 + // YouTube Plus / YTLite cannot be exported using this method + // YTUHD - https://github.com/PoomSmart/YTUHD/blob/master/Header.h + @"EnableVP9", @"AllVP9", + // Useful YouTube Keys + @"inline_muted_playback_enabled", +]; diff --git a/Source/get_keys.py b/Source/get_keys.py new file mode 100644 index 0000000..e763e3a --- /dev/null +++ b/Source/get_keys.py @@ -0,0 +1,96 @@ +import re +import os + +def extract_values_from_file(file_path): + """ + Extracts keys that match the pattern @\"_enabled\" from the given file. + + Args: + file_path (str): The path to the file to be searched. + + Returns: + list: A list of matching keys found in the file. + """ + # Define the regex pattern to match the strings that resemble the given examples + pattern = r'@\"[a-zA-Z0-9_]+_enabled\"' + matches = [] + + try: + # Read the content of the file + with open(file_path, 'r') as file: + file_content = file.read() + + # Find all matches + matches = re.findall(pattern, file_content) + except Exception as e: + print(f"Error reading {file_path}: {e}") + + return matches + +def format_output(keys): + """ + Formats the keys with indentation and line breaks if the segment exceeds 120 characters (116 excluding indentation). + + Args: + keys (list): The list of keys to be formatted. + + Returns: + str: A formatted string with the keys. + """ + indent = " " * 4 + line_length_limit = 116 # Limit excluding indentation + current_line = indent + formatted_output = "" + + for key in keys: + # Check if adding the next key would exceed the line length limit + if len(current_line) + len(key) + 2 > line_length_limit: # +2 accounts for the comma and space + # Add the current line to the formatted output and start a new line + formatted_output += current_line.rstrip(", ") + ",\n" + current_line = indent # Start a new indented line + + # Add the key to the current line + current_line += key + ", " + + # Add the last line to the output + formatted_output += current_line.rstrip(", ") # Remove trailing comma and space from the final line + return formatted_output + +def find_and_extract_keys(): + """ + Recursively searches for .xm and .h files in the parent directory and extracts keys + that match the pattern @\"_enabled\". The matching keys are then printed + with indentation and line breaks if the line exceeds 120 characters. + + Usage: + 1. Place this script in the desired directory. + 2. Run the script with the command: python extract_keys.py + 3. The script will search for all .xm and .h files in the parent directory and + print any matching keys it finds. + + Note: + - The script searches the directory where it is located (the parent directory). + - It only looks for files with extensions .xm and .h. + """ + # Get the parent directory + parent_directory = os.path.dirname(os.path.abspath(__file__)) + + # Store the found keys + found_keys = set() # Use a set to automatically remove duplicates + + # Walk through the parent directory and find all .xm and .h files + for root, dirs, files in os.walk(parent_directory): + for file in files: + if file.endswith(('.xm', '.h')): + file_path = os.path.join(root, file) + found_keys.update(extract_values_from_file(file_path)) + + # Print the found keys with formatting + if found_keys: + sorted_keys = sorted(found_keys) + print(format_output(sorted_keys)) + else: + print("No keys found.") + +if __name__ == "__main__": + find_and_extract_keys() From beeb9eb19fb6b185b6d369484eecda3c4cc77d5c Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:46:32 -0700 Subject: [PATCH 060/102] Add default value ignore --- Source/Settings.xm | 10 ++++++++-- Source/SettingsKeys.h | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 00e49e7..eff47c3 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -132,13 +132,18 @@ static const NSInteger YTLiteSection = 789; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSMutableString *settingsString = [NSMutableString string]; for (NSString *key in NSUserDefaultsCopyKeys) { - if ([userDefaults objectForKey:key]) { - NSString *value = [userDefaults objectForKey:key]; + id value = [userDefaults objectForKey:key]; + id defaultValue = NSUserDefaultsCopyKeysDefaults[key]; + + // Only include the setting if it is different from the default value + // If no default value is found, include it by default + if (value && (!defaultValue || ![value isEqual:defaultValue])) { [settingsString appendFormat:@"%@: %@\n", key, value]; } } [[UIPasteboard generalPasteboard] setString:settingsString]; // Show a confirmation message or perform some other action here + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings copied"]]; } return YES; } @@ -176,6 +181,7 @@ static const NSInteger YTLiteSection = 789; } [settingsViewController reloadData]; // Show a confirmation message or perform some other action here + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings applied"]]; } }]]; [settingsViewController presentViewController:confirmPasteAlert animated:YES completion:nil]; diff --git a/Source/SettingsKeys.h b/Source/SettingsKeys.h index 96a5bfb..384f08b 100644 --- a/Source/SettingsKeys.h +++ b/Source/SettingsKeys.h @@ -40,3 +40,15 @@ NSArray *NSUserDefaultsCopyKeys = @[ // Useful YouTube Keys @"inline_muted_playback_enabled", ]; + + +// Some default values to ignore when exporting settings +NSDictionary *NSUserDefaultsCopyKeysDefaults = @{ + @"fixCasting_enabled": @1, + @"inline_muted_playback_enabled": @5, + @"newSettingsUI_enabled": @1, + @"DEMC_safeAreaConstant": @21.5, + @"RYD-ENABLED": @1, + @"RYD-VOTE-SUBMISSION": @1, + // Duplicate keys are not allowed in NSDictionary. If present, only the last one will be kept. +}; \ No newline at end of file From 2e6f678f34aae71a3a7eb30292b996084d61e94f Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 23 Aug 2024 00:44:53 +0000 Subject: [PATCH 061/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index eca12ff..170cbc3 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit eca12ff466e05f8c563d714caaba11f5a5ee7123 +Subproject commit 170cbc3eb0502b62e9ecb780e202862325d5910b From 525f10dcda1cd94cc28479995be44bf3821ecc34 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 24 Aug 2024 00:43:58 +0000 Subject: [PATCH 062/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 170cbc3..86dab71 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 170cbc3eb0502b62e9ecb780e202862325d5910b +Subproject commit 86dab71245ade3f2c8e46ac642489fd70f6a81b3 From 6e9ec38c4a235ef0ee03d065b0e5247271baacf7 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 24 Aug 2024 16:30:30 -0700 Subject: [PATCH 063/102] Add reminder for YouTube Plus --- Source/Settings.xm | 15 +++++++++++++++ YTLitePlus.h | 1 + 2 files changed, 16 insertions(+) diff --git a/Source/Settings.xm b/Source/Settings.xm index eff47c3..94bccaf 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -145,6 +145,14 @@ static const NSInteger YTLiteSection = 789; // Show a confirmation message or perform some other action here [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings copied"]]; } + // Prompt to export YouTube Plus settings + UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" message:@"Note: This cannot save iSponsorBlock and most YouTube settings.\nWould you like to also export your YouTube Plus Settings?" preferredStyle:UIAlertControllerStyleAlert]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + // Export YouTube Plus Settings functionality + [%c(YTLUserDefaults) exportYtlSettings]; + }]]; + [settingsViewController presentViewController:exportAlert animated:YES completion:nil]; return YES; } ]; @@ -186,6 +194,13 @@ static const NSInteger YTLiteSection = 789; }]]; [settingsViewController presentViewController:confirmPasteAlert animated:YES completion:nil]; } + // Reminder to import YouTube Plus settings + UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" + message:@"Remember to import your YouTube Plus settings as well." + preferredStyle:UIAlertControllerStyleAlert]; + [reminderAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + [settingsViewController presentViewController:reminderAlert animated:YES completion:nil]; + return YES; } ]; diff --git a/YTLitePlus.h b/YTLitePlus.h index 8a41583..062a504 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -133,6 +133,7 @@ typedef NS_ENUM(NSUInteger, GestureSection) { // OLED Live Chat - @bhackel @interface YTLUserDefaults : NSUserDefaults ++ (void)exportYtlSettings; @end // Hide Home Tab - @bhackel From cba079cefa2a2140a5680e46bee86c2428317671 Mon Sep 17 00:00:00 2001 From: arichornlover <78001398+arichornlover@users.noreply.github.com> Date: Sat, 24 Aug 2024 21:06:02 -0500 Subject: [PATCH 064/102] Update template localization --- .../template.lproj/Localizable.strings | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index 413a20a..982d0e2 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -17,16 +17,16 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; -"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS" = "Copy settings"; "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; -"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS" = "Paste settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; -"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS" = "Export settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; -"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS" = "Import settings"; "IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy settings' & 'Paste settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export settings' and 'Import settings'"; "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; @@ -156,8 +156,8 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "ENABLE_YT_STARTUP_ANIMATION" = "Enable YouTube startup animation"; "ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; -"HIDE_MODERN_INTERFACE" = "Hide Modern Interface (YTNoModernUI)"; -"HIDE_MODERN_INTERFACE_DESC" = "Toggle this on to hide any Modern Element added by YouTube. Removes Ambient Mode, Rounded Design & More. App restart is required."; +"HIDE_MODERN_INTERFACE" = "Disable Modern YouTube Interface (YTNoModernUI)"; +"HIDE_MODERN_INTERFACE_DESC" = "This reverts the YouTube app to go back to a more traditional design from v17.38.10. This also removes some rounded elements, ambient mode, and other modern features. App restart is required."; "IPAD_LAYOUT" = "iPad Layout"; "IPAD_LAYOUT_DESC" = "only use this if you want to have the iPad Layout on your current iPhone/iPod. App restart is required."; From a8c21a202a7242e6c2188565c79f32d7d175844f Mon Sep 17 00:00:00 2001 From: arichornlover <78001398+arichornlover@users.noreply.github.com> Date: Sat, 24 Aug 2024 21:06:34 -0500 Subject: [PATCH 065/102] Update English localization --- .../en.lproj/Localizable.strings | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 9801761..982d0e2 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -1,17 +1,32 @@ +/* Read me: +- How to translate YTLitePlus (if your language already exists then feel free to check it and/or improve it): +1. Fork YTLitePlus repo +2. Duplicate the template.lproj folder, and edit the duplicated folder's name to your .lproj id. +For example: for Russia. For more details, visit: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes +3. Translate each line below after each = +4. Open a Pull Request + +- You can also add your localization to YTABConfig, YouPiP, YTUHD, Return YouTube Dislike. The process is the same: +https://github.com/PoomSmart/YTABConfig/tree/main/layout/Library/Application%20Support/YTABC.bundle +https://github.com/PoomSmart/YouPiP/tree/main/layout/Library/Application%20Support/YouPiP.bundle +https://github.com/PoomSmart/YTUHD/tree/master/layout/Library/Application%20Support/YTUHD.bundle +https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Application%20Support/RYD.bundle +*/ + // Settings "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; -"COPY_SETTINGS" = "Copy Settings"; +"COPY_SETTINGS" = "Copy settings"; "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; -"PASTE_SETTINGS" = "Paste Settings"; +"PASTE_SETTINGS" = "Paste settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; -"EXPORT_SETTINGS" = "Export Settings"; +"EXPORT_SETTINGS" = "Export settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; -"IMPORT_SETTINGS" = "Import Settings"; +"IMPORT_SETTINGS" = "Import settings"; "IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy settings' & 'Paste settings' Buttons"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export settings' and 'Import settings'"; "VIDEO_PLAYER" = "Video Player (Beta)"; "VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; @@ -141,8 +156,8 @@ "ENABLE_YT_STARTUP_ANIMATION" = "Enable YouTube startup animation"; "ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; -"HIDE_MODERN_INTERFACE" = "Hide Modern Interface (YTNoModernUI)"; -"HIDE_MODERN_INTERFACE_DESC" = "Toggle this on to hide any Modern Element added by YouTube. Removes Ambient Mode, Rounded Design & More. App restart is required."; +"HIDE_MODERN_INTERFACE" = "Disable Modern YouTube Interface (YTNoModernUI)"; +"HIDE_MODERN_INTERFACE_DESC" = "This reverts the YouTube app to go back to a more traditional design from v17.38.10. This also removes some rounded elements, ambient mode, and other modern features. App restart is required."; "IPAD_LAYOUT" = "iPad Layout"; "IPAD_LAYOUT_DESC" = "only use this if you want to have the iPad Layout on your current iPhone/iPod. App restart is required."; From 7083d30d9cf70bc5004c3abf5c24b46a11637420 Mon Sep 17 00:00:00 2001 From: arichornlover <78001398+arichornlover@users.noreply.github.com> Date: Sat, 24 Aug 2024 21:36:44 -0500 Subject: [PATCH 066/102] Update Localizable.strings --- .../en.lproj/Localizable.strings | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 982d0e2..57fd3dc 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -1,18 +1,3 @@ -/* Read me: -- How to translate YTLitePlus (if your language already exists then feel free to check it and/or improve it): -1. Fork YTLitePlus repo -2. Duplicate the template.lproj folder, and edit the duplicated folder's name to your .lproj id. -For example: for Russia. For more details, visit: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes -3. Translate each line below after each = -4. Open a Pull Request - -- You can also add your localization to YTABConfig, YouPiP, YTUHD, Return YouTube Dislike. The process is the same: -https://github.com/PoomSmart/YTABConfig/tree/main/layout/Library/Application%20Support/YTABC.bundle -https://github.com/PoomSmart/YouPiP/tree/main/layout/Library/Application%20Support/YouPiP.bundle -https://github.com/PoomSmart/YTUHD/tree/master/layout/Library/Application%20Support/YTUHD.bundle -https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Application%20Support/RYD.bundle -*/ - // Settings "VERSION" = "YTLitePlus's version: %@"; "VERSION_CHECK" = "Tap to check for update!"; From 3795d543ada49abec9e6bc1602459781dceb4878 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:51:34 -0700 Subject: [PATCH 067/102] Update LICENSE --- LICENSE | 687 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 670 insertions(+), 17 deletions(-) diff --git a/LICENSE b/LICENSE index 4df64a9..f288702 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,674 @@ -MIT License + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -Copyright (c) 2024 YTLitePlus + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + Preamble -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 2097308a8321e27d68c4bfe774fa3abd77000a15 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sat, 24 Aug 2024 16:57:38 -0700 Subject: [PATCH 068/102] Improve localizations, fix bugs --- Source/Settings.xm | 57 +++++++++++++------ .../ar.lproj/Localizable.strings | 1 + .../bg.lproj/Localizable.strings | 1 + .../de.lproj/Localizable.strings | 1 + .../en.lproj/Localizable.strings | 1 + .../es.lproj/Localizable.strings | 1 + .../fr.lproj/Localizable.strings | 1 + .../ja.lproj/Localizable.strings | 1 + .../pt.lproj/Localizable.strings | 1 + .../ro.lproj/Localizable.strings | 1 + .../ru.lproj/Localizable.strings | 1 + .../template.lproj/Localizable.strings | 2 + .../tr.lproj/Localizable.strings | 1 + .../vi.lproj/Localizable.strings | 1 + .../zh_TW.lproj/Localizable.strings | 1 + 15 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 94bccaf..7861547 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -108,13 +108,13 @@ static const NSInteger YTLiteSection = 789; # pragma mark - Copy and Paste Settings YTSettingsSectionItem *copySettings = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"COPY_SETTINGS") - titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"COPY_SETTINGS_DESC_2") : LOC(@"COPY_SETTINGS_DESC") + titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"EXPORT_SETTINGS_DESC") : LOC(@"COPY_SETTINGS_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { if (IS_ENABLED(@"switchCopyandPasteFunctionality_enabled")) { // Export Settings functionality - NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"exported_settings.txt"]]; + NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"YTLitePlusSettings.txt"]]; NSMutableString *settingsString = [NSMutableString string]; for (NSString *key in NSUserDefaultsCopyKeys) { id value = [[NSUserDefaults standardUserDefaults] objectForKey:key]; @@ -146,7 +146,7 @@ static const NSInteger YTLiteSection = 789; [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings copied"]]; } // Prompt to export YouTube Plus settings - UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" message:@"Note: This cannot save iSponsorBlock and most YouTube settings.\nWould you like to also export your YouTube Plus Settings?" preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" message:@"Note: This feature cannot save iSponsorBlock and most YouTube settings.\n\nWould you like to also export your YouTube Plus Settings?" preferredStyle:UIAlertControllerStyleAlert]; [exportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; [exportAlert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // Export YouTube Plus Settings functionality @@ -160,7 +160,7 @@ static const NSInteger YTLiteSection = 789; YTSettingsSectionItem *pasteSettings = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"PASTE_SETTINGS") - titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"PASTE_SETTINGS_DESC_2") : LOC(@"PASTE_SETTINGS_DESC") + titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"IMPORT_SETTINGS_DESC") : LOC(@"PASTE_SETTINGS_DESC") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { @@ -170,7 +170,6 @@ static const NSInteger YTLiteSection = 789; documentPicker.delegate = (id)self; documentPicker.allowsMultipleSelection = NO; [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; - return YES; } else { // Paste Settings functionality (DEFAULT - Pastes from Clipboard) UIAlertController *confirmPasteAlert = [UIAlertController alertControllerWithTitle:LOC(@"PASTE_SETTINGS_ALERT") message:nil preferredStyle:UIAlertControllerStyleAlert]; @@ -194,6 +193,8 @@ static const NSInteger YTLiteSection = 789; }]]; [settingsViewController presentViewController:confirmPasteAlert animated:YES completion:nil]; } + // Show a toast message to confirm the action + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings pasted"]]; // Reminder to import YouTube Plus settings UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" message:@"Remember to import your YouTube Plus settings as well." @@ -689,23 +690,45 @@ static const NSInteger YTLiteSection = 789; // Implement the delegate method for document picker %new - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls { - NSURL *pickedURL = [urls firstObject]; - - if (pickedURL) { - // Use AVPlayerViewController to play the video - AVPlayer *player = [AVPlayer playerWithURL:pickedURL]; - AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; - playerViewController.player = player; - + if (urls.count > 0) { + NSURL *pickedURL = [urls firstObject]; + NSError *error; + NSString *fileType = [pickedURL resourceValuesForKeys:@[NSURLTypeIdentifierKey] error:&error][NSURLTypeIdentifierKey]; + UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; - if (settingsViewController) { - [settingsViewController presentViewController:playerViewController animated:YES completion:^{ - [player play]; - }]; + + if (UTTypeConformsTo((__bridge CFStringRef)fileType, kUTTypePlainText)) { + // This block handles the import of settings from a text file. + NSString *fileContents = [NSString stringWithContentsOfURL:pickedURL encoding:NSUTF8StringEncoding error:nil]; + NSArray *lines = [fileContents componentsSeparatedByString:@"\n"]; + for (NSString *line in lines) { + NSArray *components = [line componentsSeparatedByString:@": "]; + if (components.count == 2) { + NSString *key = components[0]; + NSString *value = components[1]; + [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; + } + } + if ([settingsViewController respondsToSelector:@selector(reloadData)]) { + // Call a custom reloadData method if it exists + [settingsViewController performSelector:@selector(reloadData)]; + } + } else if (UTTypeConformsTo((__bridge CFStringRef)fileType, kUTTypeMovie)) { + // This block handles video playback using AVPlayer and AVPlayerViewController. + AVPlayer *player = [AVPlayer playerWithURL:pickedURL]; + AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; + playerViewController.player = player; + + if (settingsViewController) { + [settingsViewController presentViewController:playerViewController animated:YES completion:^{ + [player play]; + }]; + } } } } + %new - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { // Handle cancellation if needed diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index a577d98..bbca947 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings index 4689437..1bf547f 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Копиране на всички текущи настройки в клипборда"; "PASTE_SETTINGS" = "Поставяне на настройки"; "PASTE_SETTINGS_DESC" = "Поставяне на настройки от клипборда и прилагане"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Експортиране на настройки"; "EXPORT_SETTINGS_DESC" = "Експортиране на всички текущи настройки в .txt файл"; "IMPORT_SETTINGS" = "Импортиране на настройки"; diff --git a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings index 76a63fe..18e8820 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings index 9801761..a892a2f 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index 1cf7433..739f5dd 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings index e788b97..b493803 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings index 2749ff2..ea2c349 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "現在のすべての設定をクリップボードにコピーします"; "PASTE_SETTINGS" = "設定を貼り付け"; "PASTE_SETTINGS_DESC" = "クリップボードから設定を貼り付けて適用します"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index df987ed..db9ffcb 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copia todas as configurações atuais para a área de transferência"; "PASTE_SETTINGS" = "Colar Configurações"; "PASTE_SETTINGS_DESC" = "Cola as configurações da área de transferência e aplica"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Exportar Configurações"; "EXPORT_SETTINGS_DESC" = "Exporta todas as configurações atuais para um arquivo .txt"; "IMPORT_SETTINGS" = "Importar Configurações"; diff --git a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings index 343c226..86905e3 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings index 5e6bb59..b09cc70 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings index 413a20a..308b84c 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -21,6 +21,8 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; + "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings index a9b0ea3..a845fe7 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Tüm mevcut ayarları panoya kopyala"; "PASTE_SETTINGS" = "Ayarları Yapıştır"; "PASTE_SETTINGS_DESC" = "Panodaki ayarları yapıştır ve uygula"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Ayarları Dışa Aktar"; "EXPORT_SETTINGS_DESC" = "Tüm mevcut ayarları bir .txt dosyasına dışa aktarır"; "IMPORT_SETTINGS" = "Ayarları İçe Aktar"; diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index dd3fdb0..d2c81b3 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -6,6 +6,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; diff --git a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings index aef5cf3..e48afb9 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -7,6 +7,7 @@ "COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; "PASTE_SETTINGS" = "Paste Settings"; "PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; +"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; "EXPORT_SETTINGS" = "Export Settings"; "EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; "IMPORT_SETTINGS" = "Import Settings"; From aa5300f54f2b6eada861b82ff9ebad0c2da93139 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 15:01:03 -0700 Subject: [PATCH 069/102] Refactor, update seek implementation, improve speed --- YTLitePlus.h | 10 ++ YTLitePlus.xm | 247 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 188 insertions(+), 69 deletions(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index 34c0deb..5bb9961 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -162,6 +162,16 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @interface MPVolumeController : NSObject @property (nonatomic, assign, readwrite) float volumeValue; @end +@interface YTPlayerBarController (YTLitePlus) +- (void)inlinePlayerBarContainerViewDidStartFineScrub:(YTInlinePlayerBarContainerView *)playerBar; +- (void)inlinePlayerBarContainerView:(YTInlinePlayerBarContainerView *)playerBar didFineScrubToTime:(CGFloat)time; +- (void)inlinePlayerBarContainerViewDidEndFineScrub:(YTInlinePlayerBarContainerView *)playerBar seekSource:(int)source; +- (void)didScrub:(UIPanGestureRecognizer *)gestureRecognizer; +- (void)seekAnywhereDidScrubWithRecognizer:(UIPanGestureRecognizer *)recognizer; +@end +@interface YTMainAppVideoPlayerOverlayViewController (YTLitePlus) +@property (nonatomic, strong, readwrite) YTPlayerBarController *playerBarController; +@end // Hide Collapse Button - @arichornlover @interface YTMainAppControlsOverlayView (YTLitePlus) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index eac6062..ba0da3e 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -641,7 +641,7 @@ BOOL isTabSelected = NO; %end // Gestures - @bhackel -%group playerGestures +%group gPlayerGestures %hook YTWatchLayerViewController // invoked when the player view controller is either created or destroyed - (void)watchController:(YTWatchController *)watchController didSetPlayerViewController:(YTPlayerViewController *)playerViewController { @@ -662,10 +662,17 @@ BOOL isTabSelected = NO; %hook YTPlayerViewController // the pan gesture that will be created and added to the player view %property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; +/** + * This method is called when the pan gesture is started, changed, or ended. It handles + * 12 different possible cases depending on the configuration: 3 zones with 4 choices + * for each zone. The zones are horizontal sections that divide the player into + * 3 equal parts. The choices are volume, brightness, seek, and disabled. + * There is also a deadzone that can be configured in the settings. + */ %new - (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { // Haptic feedback generator - static UIImpactFeedbackGenerator *feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; + static UIImpactFeedbackGenerator *feedbackGenerator; // Variables for storing initial values to be adjusted static float initialVolume; static float initialBrightness; @@ -678,62 +685,116 @@ BOOL isTabSelected = NO; static CGPoint startLocation; // Variable to track the X translation when exiting the deadzone static CGFloat deadzoneStartingXTranslation; + // Variable to track the X translation of the pan gesture after exiting the deadzone + static CGFloat adjustedTranslationX; // 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; + // Objects for modifying the system volume + static MPVolumeView *volumeView; + static UISlider *volumeViewSlider; + // Get objects that should only be initialized once + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + volumeView = [[MPVolumeView alloc] init]; for (UIView *view in volumeView.subviews) { if ([view isKindOfClass:[UISlider class]]) { volumeViewSlider = (UISlider *)view; break; } } + feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; + }); + // Get objects used to seek nicely in the video player + static YTMainAppVideoPlayerOverlayViewController *mainVideoPlayerController = (YTMainAppVideoPlayerOverlayViewController *)self.childViewControllers.firstObject; + static YTPlayerBarController *playerBarController = mainVideoPlayerController.playerBarController; + // static YTInlinePlayerBarContainerView *playerBar = playerBarController.playerBar; + +/***** Helper functions for adjusting player state *****/ + // Helper function to adjust brightness + void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { + float brightnessSensitivityFactor = 2.0; + float newBrightness = initialBrightness + ((translationX / 1000.0) * sensitivityFactor * brightnessSensitivityFactor); + 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 volumeSensitivityFactor = 2.0; + float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor); + newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 + 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]; + // 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); + // // Calculate the new seek time based on the calculated offset + // CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive + // seekFraction = sensitivityFactor * seekFraction; + // CGFloat seekTime = currentTime + totalDuration * seekFraction; + // // Seek to the new time + // [playerBarController inlinePlayerBarContainerView:playerBar didFineScrubToTime:seekTime]; + // }; + +/***** Helper functions for running the selected gesture *****/ + // Helper function to run any setup for the selected gesture mode + void (^runSelectedGestureSetup)(NSString*) = ^(NSString *sectionKey) { + // Determine the selected gesture mode using the section key + GestureMode selectedGestureMode = (GestureMode)GetInteger(sectionKey); + // Handle the setup based on the selected mode + switch (selectedGestureMode) { + case GestureModeVolume: + // Store initial volume value + initialVolume = [[AVAudioSession sharedInstance] outputVolume]; + break; + case GestureModeBrightness: + // Store the initial brightness value + initialBrightness = [UIScreen mainScreen].brightness; + break; + case GestureModeSeek: + // Store the current time value + currentTime = self.currentVideoMediaTime; + // Start a seek action + [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; + 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; + } }; - // 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) { + + // Helper function to run the selected gesture action when the gesture changes + void (^runSelectedGestureChanged)(NSString*) = ^(NSString *sectionKey) { // Determine the selected gesture mode using the section key GestureMode selectedGestureMode = (GestureMode)GetInteger(sectionKey); // Handle the gesture action based on the selected mode switch (selectedGestureMode) { case GestureModeVolume: - adjustVolume(translationX, initialVolume); + adjustVolume(adjustedTranslationX, initialVolume); break; case GestureModeBrightness: - adjustBrightness(translationX, initialBrightness); + adjustBrightness(adjustedTranslationX, initialBrightness); break; case GestureModeSeek: - adjustSeek(translationX, currentTime); + // adjustSeek(adjustedTranslationX, currentTime); + [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; break; case GestureModeDisabled: // Do nothing if the gesture is disabled @@ -747,6 +808,31 @@ BOOL isTabSelected = NO; break; } }; + + // Helper function to run the selected gesture action when the gesture ends + void (^runSelectedGestureEnded)(NSString*) = ^(NSString *sectionKey) { + // Determine the selected gesture mode using the section key + GestureMode selectedGestureMode = (GestureMode)GetInteger(sectionKey); + // Handle the gesture action based on the selected mode + switch (selectedGestureMode) { + case GestureModeVolume: + break; + case GestureModeBrightness: + break; + case GestureModeSeek: + [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; + break; + case GestureModeDisabled: + 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 @@ -754,37 +840,29 @@ BOOL isTabSelected = NO; // 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 + // 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 (GetInteger(@"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 (GetInteger(@"playerGestureMiddleSelection") == GestureModeDisabled) { - panGestureRecognizer.state = UIGestureRecognizerStateCancelled; - return; - } } else if (startLocation.y <= viewHeight) { gestureSection = GestureSectionBottom; - // Cancel the gesture if the mode is disabled - if (GetInteger(@"playerGestureBottomSelection") == GestureModeDisabled) { - panGestureRecognizer.state = UIGestureRecognizerStateCancelled; - return; - } } else { gestureSection = GestureSectionInvalid; } + // Cancel the gesture if the chosen mode for this section is disabled + if ( ((gestureSection == GestureSectionTop) && (GetInteger(@"playerGestureTopSelection") == GestureModeDisabled)) + || ((gestureSection == GestureSectionMiddle) && (GetInteger(@"playerGestureMiddleSelection") == GestureModeDisabled)) + || ((gestureSection == GestureSectionBottom) && (GetInteger(@"playerGestureBottomSelection") == GestureModeDisabled))) { + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + return; + } // Deactive the activity flag isValidHorizontalPan = NO; } + // 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 if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { // Determine if the gesture is predominantly horizontal CGPoint translation = [panGestureRecognizer translationInView:self.view]; @@ -799,9 +877,22 @@ BOOL isTabSelected = NO; // 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; + // Run the setup for the selected gesture mode + switch (gestureSection) { + case GestureSectionTop: + runSelectedGestureSetup(@"playerGestureTopSelection"); + break; + case GestureSectionMiddle: + runSelectedGestureSetup(@"playerGestureMiddleSelection"); + break; + case GestureSectionBottom: + runSelectedGestureSetup(@"playerGestureBottomSelection"); + break; + default: + // If the section is invalid, cancel the gesture + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + break; + } // Provide haptic feedback to indicate a gesture start [feedbackGenerator prepare]; [feedbackGenerator impactOccurred]; @@ -814,27 +905,45 @@ BOOL isTabSelected = NO; // 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; + // Adjust the X translation based on the value hit after exiting the deadzone + 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; + switch (gestureSection) { + case GestureSectionTop: + runSelectedGestureChanged(@"playerGestureTopSelection"); + break; + case GestureSectionMiddle: + runSelectedGestureChanged(@"playerGestureMiddleSelection"); + break; + case GestureSectionBottom: + runSelectedGestureChanged(@"playerGestureBottomSelection"); + break; + default: + // If the section is invalid, cancel the gesture + panGestureRecognizer.state = UIGestureRecognizerStateCancelled; + break; } } } if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { if (isValidHorizontalPan) { + // Handle the gesture based on the identified section + switch (gestureSection) { + case GestureSectionTop: + runSelectedGestureEnded(@"playerGestureTopSelection"); + break; + case GestureSectionMiddle: + runSelectedGestureEnded(@"playerGestureMiddleSelection"); + break; + case GestureSectionBottom: + runSelectedGestureEnded(@"playerGestureBottomSelection"); + break; + default: + break; + } // Provide haptic feedback upon successful gesture recognition - [feedbackGenerator prepare]; - [feedbackGenerator impactOccurred]; + // [feedbackGenerator prepare]; + // [feedbackGenerator impactOccurred]; } } @@ -1062,7 +1171,7 @@ BOOL isTabSelected = NO; %init(gDisableEngagementOverlay); } if (IsEnabled(@"playerGestures_enabled")) { - %init(playerGestures); + %init(gPlayerGestures); } // Change the default value of some options From fa922a1acd48d1d48b67b838ee454534495db465 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 14:04:32 -0700 Subject: [PATCH 070/102] Add player button in navbar --- Source/Settings.xm | 53 +--------- YTLitePlus.h | 5 +- YTLitePlus.xm | 100 ++++++++++++++++++ .../YTLitePlusColored-1024.png | Bin 0 -> 10981 bytes .../YTLitePlusDarkMode-1024.png | Bin 0 -> 11289 bytes .../YTLitePlusLightMode-1024.png | Bin 0 -> 14797 bytes .../ar.lproj/Localizable.strings | 3 + .../bg.lproj/Localizable.strings | 3 + .../de.lproj/Localizable.strings | 3 + .../en.lproj/Localizable.strings | 3 + .../es.lproj/Localizable.strings | 3 + .../fr.lproj/Localizable.strings | 3 + .../ja.lproj/Localizable.strings | 3 + .../pt.lproj/Localizable.strings | 3 + .../ro.lproj/Localizable.strings | 3 + .../ru.lproj/Localizable.strings | 3 + .../template.lproj/Localizable.strings | 3 + .../tr.lproj/Localizable.strings | 3 + .../vi.lproj/Localizable.strings | 3 + .../zh_TW.lproj/Localizable.strings | 3 + 20 files changed, 148 insertions(+), 52 deletions(-) create mode 100644 lang/YTLitePlus.bundle/YTLitePlusColored-1024.png create mode 100644 lang/YTLitePlus.bundle/YTLitePlusDarkMode-1024.png create mode 100644 lang/YTLitePlus.bundle/YTLitePlusLightMode-1024.png diff --git a/Source/Settings.xm b/Source/Settings.xm index 5bfd862..c182f43 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -41,8 +41,6 @@ static int appVersionSpoofer() { @interface YTSettingsSectionItemManager (YTLitePlus) - (void)updateYTLitePlusSectionWithEntry:(id)entry; -- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls; -- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller; @end extern NSBundle *YTLitePlusBundle(); @@ -194,29 +192,6 @@ static const NSInteger YTLiteSection = 789; ]; [sectionItems addObject:pasteSettings]; - YTSettingsSectionItem *videoPlayer = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"VIDEO_PLAYER") - titleDescription:LOC(@"VIDEO_PLAYER_DESC") - accessibilityIdentifier:nil - detailTextBlock:nil - selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - // Access the current view controller - UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; - if (settingsViewController) { - // Present the video picker - UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo] inMode:UIDocumentPickerModeImport]; - documentPicker.delegate = (id)self; - documentPicker.allowsMultipleSelection = NO; - [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; - } else { - NSLog(@"settingsViewController is nil"); - } - - return YES; // Return YES to indicate that the action was handled - } - ]; - [sectionItems addObject:videoPlayer]; - /* YTSettingsSectionItem *appIcon = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"CHANGE_APP_ICON") @@ -652,6 +627,7 @@ static const NSInteger YTLiteSection = 789; BASIC_SWITCH(LOC(@"CAST_CONFIRM"), LOC(@"CAST_CONFIRM_DESC"), @"castConfirm_enabled"), BASIC_SWITCH(LOC(@"NEW_MINIPLAYER_STYLE"), LOC(@"NEW_MINIPLAYER_STYLE_DESC"), @"bigYTMiniPlayer_enabled"), BASIC_SWITCH(LOC(@"HIDE_CAST_BUTTON"), LOC(@"HIDE_CAST_BUTTON_DESC"), @"hideCastButton_enabled"), + BASIC_SWITCH(LOC(@"VIDEO_PLAYER_BUTTON"), LOC(@"VIDEO_PLAYER_BUTTON_DESC"), @"videoPlayerButton_enabled"), BASIC_SWITCH(LOC(@"HIDE_SPONSORBLOCK_BUTTON"), LOC(@"HIDE_SPONSORBLOCK_BUTTON_DESC"), @"hideSponsorBlockButton_enabled"), BASIC_SWITCH(LOC(@"HIDE_HOME_TAB"), LOC(@"HIDE_HOME_TAB_DESC"), @"hideHomeTab_enabled"), BASIC_SWITCH(LOC(@"FIX_CASTING"), LOC(@"FIX_CASTING_DESC"), @"fixCasting_enabled"), @@ -679,30 +655,5 @@ static const NSInteger YTLiteSection = 789; %orig; } -// Implement the delegate method for document picker -%new -- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls { - NSURL *pickedURL = [urls firstObject]; - - if (pickedURL) { - // Use AVPlayerViewController to play the video - AVPlayer *player = [AVPlayer playerWithURL:pickedURL]; - AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; - playerViewController.player = player; - - UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; - if (settingsViewController) { - [settingsViewController presentViewController:playerViewController animated:YES completion:^{ - [player play]; - }]; - } - } -} - -%new -- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller { - // Handle cancellation if needed - NSLog(@"Document picker was cancelled"); -} - %end + diff --git a/YTLitePlus.h b/YTLitePlus.h index 34c0deb..57184f1 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -46,6 +46,8 @@ #import "Tweaks/YouTubeHeader/YTMainAppControlsOverlayView.h" #import "Tweaks/YouTubeHeader/YTMultiSizeViewController.h" #import "Tweaks/YouTubeHeader/YTWatchLayerViewController.h" +#import "Tweaks/YouTubeHeader/YTPageStyleController.h" +#import "Tweaks/YouTubeHeader/YTRightNavigationButtons.h" #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define YT_BUNDLE_ID @"com.google.ios.youtube" @@ -172,9 +174,10 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @interface MDCButton : UIButton @end -@interface YTRightNavigationButtons : UIView +@interface YTRightNavigationButtons (YTLitePlus) @property YTQTMButton *notificationButton; @property YTQTMButton *sponsorBlockButton; +@property YTQTMButton *videoPlayerButton; @end // BigYTMiniPlayer diff --git a/YTLitePlus.xm b/YTLitePlus.xm index eac6062..9214f64 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -872,6 +872,100 @@ BOOL isTabSelected = NO; %end %end +// Video player button in the navigation bar - @bhackel +// This code is based on the iSponsorBlock button code +%group gVideoPlayerButton +NSInteger pageStyle = 0; +%hook YTRightNavigationButtons +%property (retain, nonatomic) YTQTMButton *videoPlayerButton; +- (NSMutableArray *)buttons { + NSMutableArray *retVal = %orig.mutableCopy; + [self.videoPlayerButton removeFromSuperview]; + [self addSubview:self.videoPlayerButton]; + if (!self.videoPlayerButton || pageStyle != [%c(YTPageStyleController) pageStyle]) { + self.videoPlayerButton = [%c(YTQTMButton) iconButton]; + [self.videoPlayerButton enableNewTouchFeedback]; + self.videoPlayerButton.frame = CGRectMake(0, 0, 40, 40); + + if ([%c(YTPageStyleController) pageStyle]) { //dark mode + [self.videoPlayerButton setImage:[UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-1024" ofType:@"png"]] forState:UIControlStateNormal]; + } + else { // light mode + UIImage *image = [UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-1024" ofType:@"png"]]; + image = [image imageWithTintColor:UIColor.blackColor renderingMode:UIImageRenderingModeAlwaysTemplate]; + [self.videoPlayerButton setImage:image forState:UIControlStateNormal]; + [self.videoPlayerButton setTintColor:UIColor.blackColor]; + } + pageStyle = [%c(YTPageStyleController) pageStyle]; + + [self.videoPlayerButton addTarget:self action:@selector(videoPlayerButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; + [retVal insertObject:self.videoPlayerButton atIndex:0]; + } + return retVal; +} +- (NSMutableArray *)visibleButtons { + NSMutableArray *retVal = %orig.mutableCopy; + + // fixes button overlapping yt logo on smaller devices + [self setLeadingPadding:-10]; + if (self.videoPlayerButton) { + [self.videoPlayerButton removeFromSuperview]; + [self addSubview:self.videoPlayerButton]; + [retVal insertObject:self.videoPlayerButton atIndex:0]; + } + return retVal; +} +// Method to handle the video player button press by showing a document picker +%new +- (void)videoPlayerButtonPressed:(UIButton *)sender { + // Traversing the responder chain to find the nearest UIViewController + UIResponder *responder = sender; + UIViewController *settingsViewController = nil; + while (responder) { + if ([responder isKindOfClass:[UIViewController class]]) { + settingsViewController = (UIViewController *)responder; + break; + } + responder = responder.nextResponder; + } + + if (settingsViewController) { + // Present the video picker + UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[(NSString *)kUTTypeMovie, (NSString *)kUTTypeVideo] inMode:UIDocumentPickerModeImport]; + documentPicker.delegate = (id)self; + documentPicker.allowsMultipleSelection = NO; + [settingsViewController presentViewController:documentPicker animated:YES completion:nil]; + } else { + NSLog(@"No view controller found for the sender button."); + } +} +// Delegate method to handle the picked video by showing the apple player +%new +- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls { + NSURL *pickedURL = [urls firstObject]; + + if (pickedURL) { + // Use AVPlayerViewController to play the video + AVPlayer *player = [AVPlayer playerWithURL:pickedURL]; + AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; + playerViewController.player = player; + + // Get the root view controller + UIViewController *presentingViewController = [UIApplication sharedApplication].keyWindow.rootViewController; + // Present the Video Player + if (presentingViewController) { + [presentingViewController presentViewController:playerViewController animated:YES completion:^{ + [player play]; + }]; + } else { + // Handle case where no view controller was found + NSLog(@"Error: No view controller found to present AVPlayerViewController."); + } + } +} +%end +%end + // App Settings Overlay Options %group gDisableAccountSection %hook YTSettingsSectionItemManager @@ -1064,6 +1158,9 @@ BOOL isTabSelected = NO; if (IsEnabled(@"playerGestures_enabled")) { %init(playerGestures); } + if (IsEnabled(@"videoPlayerButton_enabled")) { + %init(gVideoPlayerButton); + } // Change the default value of some options NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; @@ -1079,6 +1176,9 @@ BOOL isTabSelected = NO; if (![allKeys containsObject:@"fixCasting_enabled"]) { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"fixCasting_enabled"]; } + if (![allKeys containsObject:@"videoPlayerButton_enabled"]) { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"videoPlayerButton_enabled"]; + } // Default gestures as volume, brightness, seek if (![allKeys containsObject:@"playerGestureTopSelection"]) { [[NSUserDefaults standardUserDefaults] setInteger:GestureModeVolume forKey:@"playerGestureTopSelection"]; diff --git a/lang/YTLitePlus.bundle/YTLitePlusColored-1024.png b/lang/YTLitePlus.bundle/YTLitePlusColored-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..879a0b1ba3605bdc16226f7d7a53fee9c0dfabe7 GIT binary patch literal 10981 zcmeHsdsvKX*Z6wo(77g5A~c~SrI6Z@W>R!eN@|x)8XKvEgvzOT*gGMIBBi1Uo!ONw ziO>*oC{a<78abq+()lnmzxA~De!us3UEg2d-+Qi$?!#L5z0UVq>pAAS(oR`nvH}1o zJJ{R00WfgL067`_!=F0mH~b?XWWQz?fZ_z|9|4IMG;xvG zKdm^rfeB!+&%xH(J&fr1;JjU{E^by=$s?`avVAuaElk_$Zg@slDm-6roo4E%3JA^lHXhlOi{?RR`=RDHPv}_tgWN<{LXvD+N$in zk7bdvTTD8o$-A~w#QyvHR|5Y^;9m*+UnCIpVJ485ooA?AF7B*eqM1*CngamWtkdhM znO3+oN3i60(Zuq$x!00v%ibyWE9GBL2q|wIu`Jp?G8DgGGSvT-Q}APpVAd_^4uV{z z3XoUXJA8T1-c|c*D$bVf^uF;#u(of1bdrZo$(_cL{3qY@Z;4L@s6d=N!2Cb+^^04? zO^5gGow&byi|nmYC4HBou5b%iuhD(C_g(h>B)FtNW7BCs8hIIb?1)=GvC(+$D^GF4 zmjT##OH(Odv2n-5aLMMD(0KaM-0vRqKxqY1zmGjy`zCHEG(NNQ`wd=RP&JFCEzP#F228u zAH{r_e}-0oa5n#q`UO%WXZ|pSDBT4w^}^(VUH?s zANbxIwtH>dU$qtAw3?gUOH>Q1tzh$b;96@uAClfFN{(Q1Ac&LYDEhNVGUXuql}t2B zZPWIGZ!S^d;$z=!h5?T3uJbOAFo8eyfOK*mIU~u(O@353@I2=hwcXmTvvV5vX9h&a z)NPl(=v*XE?G(Eu373Ul%u*mN<$z5O86n7+A|(&PWFHMQuh%`4?&-}1*jTgNXI#)U z;Ws(p{cbo)kYzV@G?fWBAq*_^dDqQBef(G#QlnTx z+fW>?z{^b+yGt8Onh>&PRj9aO$-v!~96j=$D*^j2*K0$jyVg4z&)6M=)0{?vrKdM^ zv!FVoCC4X2{DzUYzyNrWzS_axuQZBfA=6tco8WCh*i&Wu#8o-Pk2%22J$8S*$QjmV z(4ZjD>?7x3rg%I+eQHO}##u~ZKaw8ht1H!B%GUznA}c%oI?*!tt%?R~=Xc1Crk#=M z0eIPEUpT(O_$0 zUqad?KE>7fyR8~#JLrYy0N$Fc9nJV8K^NhjsC)+TM7=%0*7N;Q(kr-ht+u`gU+!m{th+4}JQDjC zOYI1RQn@T(GCjtD>zooFfY$yR;v7z{qM%cJ?N(R(?!Fwjdwk7@(H=8Dtl}pqd7A5+oUOoO3`(Wym=@kZ?8x1KizD9d?uu9qHwSM}8PO>|{Xf zb7d_cBmHO!NR<0?DFI<}vk2EI1f;nke?ptEYA=Zl7_q-+oS>Hwy-I#fV{j;VuH}jlwjgD3=|y*J5OCwq1X3ZjCpqjDC3Ap{~A<{#8(o{v|Nk<#` zrw6~p1F5`_n1pv6)&sMc!=w+t!+0A3*D9V&Sc9uH^It{bZtC1@8G8@nFhJ+qv2)}T zA?&E>M0UCCD-9IDG$wVpygNP%<~tPa)d@Qc7IQ}Du{WZ&*r>P#93$ZY^xpkbqUWJx z{b)SDo*~Hf37vQ4!Z%D%}=9RjGvKvaNY5ISqt-ZRxS zDVIgE@Yw1{H)hq1hv7%ujelo*tn2I%f|pPgAMFZ$2_uog$HC!7L{wE zwMi1kpe_PDEq!(jNgL`JbwJWS=g5;63}4EI{g??)PXQT-7Ru9hQ|;=$LII6~Xd?n{ zFNjco`u>2Gu&svRYA|5a3N(w2LHk;3xula*1Z;8yZf7FsKR#f^4Nyj9nD`=*Gm*&a z4kg6ug(M!eQ5V=NXb@b(;AXik<}NaObpW^Vd|kA+6Kk>og~$s`B$betx78;nW0IXhw!CN$jHNC4VWsf+@iu8Tw=P)*uKdbuprrt7h7(988-Hyt2n zxzK^d>LoF*3$IhqJO?57Iep2xiM68zP-R+nB#8 zEId7QfUKU3M2f8bCbHTdB&YGYHYfl#IVJ++GMpafeBFWu6tlCd>vP(AP>^ z)Ymrm)VWgHn_&7(L=Jw#fRR1>CU;Xt!TkdbzzzZH8=J-`F$q9yT^Ut_P31}T#6u%dsVW3X}6M9PGJnocnplNHw*Uqvu?=%8*z z=JZLNip;WTsBYfP-^dekIDb12MJc&g0KCps+~ueQ`$`3&#B#qc-o6H-;tV`;1aCm6 zA)P3M&aMA(>l5dx126rM$C^AEu z$AllU9H)84c6Mm%c?+ns4z8fC7k!=yytNeU#%Kd*xI0f9Esi4P1V%D6OOV0$6Ev?3 zT|bm%z*PkyjKRizrTNJN5BSLFla?Rzo7%7OnWQYGtrO1g`xT`cQrD|>Rp6Xws-|L_#$?tMOCA1&YAu$;^<2YKi zNm^nP#n-QjCr@PJDYZwCkd-cdLpF61-M=KNlXg*(-^Smg4knmZ1F7?^N0#@QqLLMZ zB-}3EDAs)U%;C`k>rFc14=z$=xIzh}Ft?}YetqLZ!M3oW`Ir5tD`wG9z*m~pAo%la zMN;gzSyEbh@EKK~CSYVaW$91kY4>atSH9%HCWM5bi3cUZ00HGPc$%}pfJ>Srt8@~~ z_mx4*H1PC1DB#~Qln`U4$a{UaLfTRlj@5|5B_=t=|2~7a*i9g9$+F@DrnzjpW@y z*~%9S&i5DMsco{*h$<(8QHG=zzK9<0y`6!Jia=Gq8tP?o%j_~#b6knhSyMg>+2KeM3IS`lvJ3Dq6=kn?64Aob{vvRRKf%7ZJuNMQ3$ z!-Zpy!uxqXgKa&s&wGuDG1^NUzetSN>-Wi$F_CfyFz+8{$XS4$=*SSI=C$62K9VF~P8d+XGQG%p)zEF-e#AGf-Bdea{ zJmA^N>T(@R%Gg`B--WjG+HKAD9P(0_itdUdaAtw|dh$Km2aAP)wl4FS#f z{v(>MlR#eBo6Yo!qb#I&DxcgIK%YMot#o{ zcq`^6dt}?Pg|=t$KgN9xGt!p~;9f+w+t+GE>!6@MPe;ul&pr6?;Jhwz_p>%rFi5G; z<^{eROAEdCjkl7+cX_^aqA?-@tA91OAuxj2eCN*bpR78KQ8w4Rl^o;H#7y*1#2GHi zLv&4JV(d{VG6Tn$VPtS*Js*~DZJHG8lt6GhQ**fz>a4|7&g?^Dd-^{RXh_i3gDYh= zIij0ji{tYwbd!sHUnFQVx4SWIc8BQ2<~+7>R)w@TpGCma7_Fb`(Eag_;OM`l13VX` zBhNXjf-|)(6yGE@wD?#c>u(Y!%g3aXF+&_XLXUl<8i4scJ2W}_Q1?IH?>fCgfJrvD zvz|QE{i>Pe`kNVhHJTo#9{oGQulZm!PuZQ!p$d*`&UduBOrhUaz~P>(?;5K?@;|&` z2t^e79S9S zh3a85I3n`mKnf3S+x}(6NHAZK4=Jvvh*WG6*LxcDxY!M+o#A7HB86uF`qo;I=OafltGfdi^! zI=-OAg~0X(fFbHT+YAST%YmCUg^BN09#WpAL_^BFup!}2$(M>AZdo`OTe4qCVGhQi zxNcJ7^5o0udoGd}IbgQ2bC3GY5RJfRFXG3^%Em-g2xc_gQRz z)LzabtD7o5^vwtIQa<$Pw{&F5|Yam)9 zldm4c_kR%ctnt!|&f#YAus@Na5s&gVA9+tw1UyU?jM>7qkV&q1<-(y|D3v`Ok9^0e zqf#f}47|R~PoW_n!I&HbU36T9uT0A1vqvj*K46RP&I?jO4l+-+xiz3{Q$pei zb*ibmHJJt;DZ_cgH)fD@b*<{Mw zyo@{uKLmOj|A3DU33HrgJ^`>;Y(B`!nSfE@4(sHt*SAoe(WlJrOpJ7FzcQbHW+el;)!Z;&L>BkZ#@SK#yzb(WS`VCfm^J^3aw0lk-Zm#w9LQJ#j zgHP8*TtXus3Gw}=9k?7V?bX5B3z60faOua(CT+7>*s)2BfGzlaWUkn(C2|2By+=qd zJF`Ux&1*Zh1C5D#l;kvfDpX9+kalsYFFuA06HQg%EjE;F0G!(oTC}`%{@NU6U5-;IR z*cLjq!eGuJ0y$dYCilv_qC_59YP-{(lX2s?BacUe+CSH{{Gvd^SSZrVYUFf`YGo>| zoet#G^SysSmab?%xHR<&_;JuQ1Y7 zUp*OKBei|TX~#xPKksMd=%u8m4zk+%YmIh4>Ue+k!LEBJ?;DA3p>e$5T-z6U59O0w zo=t?eG*~IW0pKRAFVh?Kk;yYhK^)uN&~eR3v`h|rRl%v{r+T0tJA^aNTCthPhwv53 z!0j;d&$CD1+YxLbMqi*lheaPVHQi!nXc9rR3|^oD^jrKeURJhJ`KLA63PG_d=+IX= zjOah=RxN5d?*Hhs;TIS#^JfOlx!0O|=c^GNTiEazKe$HdiREc6ch2*7yz^w1*&IqQlBhKn%VK{C z2|uu~#btcqi3rC-w_65WdExT7P9@l)mEJ!Esf+iN_m=Y5-lw+Bj*hG%nJ!-o`hLIkrXh26A2C_1N9@q0WUE27G|cVC9K#ZT;w ziW;uCZWI|wn9Rg7>f*E0ET64O5>2(4Q9c=MtJbkt8hmZCJBh!1W=Ca>VEfQe$iyC) z!3M~lS7&14RWP0Fr9R#=`JR~~KYva45(ux(3FGiDeis^t@32rRAY}`GLtQzulvTf` z*IZTowM88Kw9D`Dz>eXAN6cY4-WGuj$~M8qVl0!%E^glA~Yt`D^6hABpQ( zYClIXLYazD#RGVar?~UreO9RdjzLNGvVm>IQvdSCZQq9noI(a07f_$e!Q^PY#;mIM zC5QGHOi3(!pMGw5n_p<3f`ohX)$^_J>O9Uz)+f1P1!BvCHMrxNQFS z9O*=1gBZ&#pgwQm&lO`G{@l6L|A3DQ{-_UR`1^Z{8vgtHR|5Y^;9m*+ZxV3-QVdh{ WtMh+$eCSK6_uPzhk3AN%b`t0WSdE) z98wXILxWw&p&^t+gAS5Iny98}=3P(h@B3cY`}^zn_nzyb=YH<{UiVt-{;cD(TR3Ni zp}v_u02q4BoHh@DfsYK()xkgFVdHk-AHB$#{u=<;1F3%m96dG|UlJSU&2WcvkIY-B z^{b}(Oa&-RVyl-i0mhy4nl{xhium-ZaKCx=voUQ|33Qf@!y|^1aO{Sr#{-LxIQQg^ zF&gAzImr2Go8GjW96`I@G?xIEH?cC?0+OCIg8tps&%nT`Cqbq&^z7r9{1VUAjxoQL ztU7(Q^>t4VVfyM=Xl;V!qUzpi=Vni2;NRcB8u(WO|7zfWrGYQ$Ob}iyTfXjK(40%% zAHy75>5zL6fLva8{=lcr>hAE;9?OV&hqYG=KQEuWWNi&wekVdTp1;NUYVu&w82@99?R`JFAJlzV$@?TfWC2hJZlV z98<9H^y|Fq=WYbQlCD*`w0`+83L zbT9DlxmO#|YXI+F7#nxoZcV>f+0iPVv56)_A#L+I_WxZ2;m?C?4rl{HeQXod`z<=RkC)g83$IpU$G&wAYfDEf^a!YHcb!6%$kBz zrCaSwRmwAqfOpR&L)NDG)VB4TGH4SK8A1cmMvv~e*ViQFSBLi4zMgQEMIQQAI6(hz zdtUJ$T=(s6;AsW0`O>AEm0$P)J->k6akqF~Jxz(K+1O|)Lw1M(GEa})@uv5EdM7M; z9kZ1KRqGc_{4=)cM1D6q3VLirCSr%CUcfoIR;~?bmf{TJ6?UCS}G`S7|eqryQN$#w_APK$-5EabjGic4VEa@B?R|-QBY@QN8me_I)1E2#%7PE_ zU6wG~19#dPbl&$>OBf)CdsL;WD-bxH<1!=tLY0ynm3XM576jLuLgUgu$K3Ef!&dP8 zKz4xF$pW)yyDou~{ve2C;L`iO+5yzkn3AI7IXxN8rwK&?t|SbD*VkulG6U$yFoS-c zOfbJIZdF=V?e&;Gyu6#5TyH>6-gZC_M4W_pt-3)w5}@YUkt<;5 zHXiKG4=;3M1AK0^%JY55B-iPJXj-@HOS_L85Y3Jo+)p>t2xPhmUfTMsNgTYG=evyH zvkyS0LzremsWud#U_zWOp$K9?BnL$V)-!6wY+Ugtjf{ODdB_LZn~vcO(q)~2W!+=D zw#p_hC<;o7f^uRCZOOlKfpi)CC_8QdfcY%R^D!4*e6%O?@a?edhuXu-lpKf*3$*cF zM!Pf;-(@}2zUx?T0x$<(7K8E`#-V&=_8f4O)1dl(wl)wzc(l1?+5Y5o(LMmjnZbjTp4`s_ zkWLG<;WojzB9NJ7fPbcxMS|*eX=~1AaB}rQEHRgb~`{G7+HfNW-Q$O!N3SQ5qex7{`ex%Y#~69 zXU?9f^aDYZiUV@p1>oSrgonxw+&ttogdEieWEfeP??=dO27$xFDzu5FT$ejq<<4Ax*dZj4zh$v| zLen%HRB#a?XCT!hEP!jiL&3)g&b6wLUIoQ`N7b1eJ|>%?l%kJL_F#}4IrZP zKAEToAvawC6q}WO&)Y_t0vV1xy0`M44FLIeRD*1@0WB+l2B!}VsH2A88Q?by1fQ15 z2&gG@mCmEV>T2XRtWwQ8Jqo0oZ503?Z&?cZ29(gRLPlhJBZ1U|OH3osZg0hnTrdEH z7i>{eTWV*XItb)ZuLuH)*_{Xcyg=|Ueh`}IRa>b$lKyS$IDjqd&M&qpAuDt-UPW%) z^JF|ysklD!S$`0YGY!K*COda8kO5=0EKs-|V+b}e;Hft<1)Xo=4}QRHsehXQ+4G)e zJp!Z)(FSC%ob|}QiGvie`%^|OKw^KTJS`E@!7jm8YK3PvP{mNWoau)U*yo4O|4ckZ z(sh#L?A$~k&93}EJAS3=rp!oV%SlLW#4k7)yeDSXX~cr{fB*o`lO-vuksBWblbyvN z@bdscINCe;HP%R|N5I7vyqNM#8c8kMHv$M4Jm0i$Vqz8($cca1n6Nw3{HFfgwN4Lm z5fil=34nL@EYccxl`k)(Znr##);IK`PP$<$rJ*=hN0=buy6NX4{EohVh(VcKLh9q5 z-BkVeJ%imhp|;0siM4Q;%S5UmdpO5r&rT!qEgrRd2)_6@%T(w@z@!5eG<2hZf;R|< zWrd3=7JA+-8(20FgnOuq6_=2=aL>+ZsP{M(Pa25~JVv#BtgNKzk3nByjl^ok3<6_c z5R9jE(EC-kn>yylmJdHx4e&?KDjrv*%)wQd1ca-W5#WFz!7au9lIJ^$ZuEoVbX%#2 z28ov!+qm|!F4?C)R23c1y3EC}3!=$^f}4m2DVrQ-Fjbb>@m(o5K@_`2oxrqYwZh$? z&P$&N%1S*$+|Zp0aJiMHKN_Sufl%k6PaH2>??zriV`-n-M@7Jd$hG6bi7QqLS5U<9 z*}ODFfG&`a4WDZwKZsIbHXQRI?fx#~-V#%D)Kplu`n}&LNDwtqWFnKJ)Y1RbE z@7(~pz&nP!i;d_p7ah4$4g_pMnAgS3vqAkv_SfmRT$i?9SL6nQt3O}9rzyzxSaR_t zrmGDJBLbgn`iHo1uQAP)tt7y^S(Ch64|sv5!1Pb&MD~XiPY@KM zMMW|^jM}`?I3P45pp4>a{^D&X@*c3F%pgVZV~rhwYGU8fp&28#bO|212s}f$8>P82 z2{m=n8w3ZCmfgg$jN-wyv5mS9S7g_AuK zZHxERdx_wjZqy(!NBg%zA^lBZDU*nHM5vIryDX&wT$MYmPd^PS=sf_7(F6P%2yMsT z^l|k)ht2yFwQODF$W>TjFhd$g-i(9GgSV5ux9|!lZX%c{i#;X?hn_dlu{%SJsumHO z9UidmP9+gNTbidDQ}WuI29Yj{k8u86LRW!k(PxjbnAU??syn$SV>|_iVdG8M!=Vfv zlD%ml*}tJ13SAxBT0ykr^YpR%fjoHSJ#Fu=A?&CDc#z;Cr3X~(dDKiT4I-L?Qr;p^ zkLx8mZa#0%RfGl{Cgh_zSv+K8-X=meH`_>Ib3K+~BpgLEN2e0G zYK@Xm0gR?lS@+V2(O`r^Ne5ZOKbsmTiNe^3o=rWLQae<=$PZCr-b8Om1cZRdiefeB zEGljW>pLMlEMXcW6i=0aR2NY;nG3mpnn2`8xOg4{VX*pXi9j<$KI0cFVOd~;f%#~~TLyNNKD2Cv`Jl)7pHw@9}YEKmbwEguH z_L$R>+bQpWB>HVo8#-~RQF|iR+XU#Z-zU{o3q7}#~)a-1T+@!7VY+q`6Aet5WD#)Y=&6Zab zZVUe163G6#I2>)W6Dr-&jz)B?LksuXQ?~qg(2dz^EFjXC5^OgXleUM3YG)8IqL1{n z+Ac}f;X9#?Re-gyCv~f7WKp*`Er=={p@!~(8OnZMXLruG|6K1K9i|~_Mqug&Gwf1& zn%%Tm-molj=u}YDU0U1Ks$5&Q$8^Hmhv}2&UPw+(j#48VcQ6&0c9;OB+5T@a7T&!> zuEloSKdP+E{4KB=%Re;TJ`K%HSkc>FE=EpACLjtwdVN;WySukT-ZuM`WU=|V!V8@HL42|r6DU3`7u?L{IA6P0?~nrlC>sL;7x7=PtyDI0ic zLvV6v);?{Eyjily6sVjEWQj{ZOBQ}sYG(x~f%Fa`q|;E^0@KiUk{)%XyMzye&?_Ql zA@fNyr|v+{JoE`@X{nByK%2=LCDi-{lRR>Hi;}hf zET_*Fcuy$psIcg(L+=N|l%lVEpK*s(&Ci%nfUTzN^$q%h6$x(I{3kC!CQl_J;uGPm^dBSu~JZUa92gRkwVaOcnk!GHB#HJ#6MsCP0XNX;Rz$ z*(WhhfM^0%rmNrOS8{V7BRV~i{k^N5o_~qvePfYc=$KBsL0Zb2#iiH2N?3y4*9_xw zBLOIa)=R_z(dV_7DeB4DNPP%R*NzB%r**o1451EbuE;uCyZK{8l0+rZ5u~fgTa>7I zsCaTcrWUFC=t_Rxq|0-T=w2_6N(ZuDgl#?&;YlZZXH~zPQE1b7`75hy8v?=!^Yoe@ zW_@Us7CR&qI!CqA$;XXu+M@Q8{I!~9LN=NT!5ASFE(op7=-H@f*mQzzcMx5~;QMY` zTOh4N3F)siw6=g2rIvCKmmD!UCvW9qI)txX%qn_I_pZFc2RV9@Q87c|qfNLb-%*1U zKbP;|C5}WfJR8<)7hAMojoFD=6eeKaO}E$uJ7doV_hDXSK&3px$&?2>O%*yEId9S%P<{`mOgGHT%EOosLcZk&ulCK^5NPT$}s7*efjFiRlw|KS!gcol4yL@;=_* z2=N{@mkF}{RGx{AiI(4-V0BIut;oqts}^IQeL{Jk#e0WCpf$mw5A*y@E*yVwJT8uOwqikDqs+# zJYo*!RmhvgCj0G}ywo1wL@Mo%17lI2i8T|Lw7GvB?@=8d-Zq z+gG_DNNlV2Z2|KgZensY(!z~q9T}A-P6Zit+UQ~p6j8-Qys^;DbeTf*q+IKO78o8B z2y(N|cIVBH)38)~ z&5&7SKNNpf^4W13hxgCUEc)8rEMe6xsPBxfG9MH@tf~#0j5P@$5$#Cylq7<7TM?sEN{H*bC#w1_#hm02j=Z?gU@JNoI9$< zgW_~CNCT_^bqOwJ2*|?tBw8`X#$=}{lSXU^MxGBoXjY1rcI!S`xIeMM4vR?Hg8nr} z-Nb_{Z|~x~>sB@sfz@TL)$^T)OvsrqP|{-IbNMTxud({y{AR-+>(W^dsj-( zT?00{glxRZ^k}E&=>5}%lTY2ljnT8A7*9`N77FL^+D+DC#X+vYT6{VeUtt?kFdkEI zP+%Kq^)g+{|8G52%R_`ENcAtgIQtKk(Q){)0F`z$1j#{h0zRoH;Zw~_5cp8-6j+M= z4uu z)i}X;2P7p?xxqhA*r!IW(XdxnVVe!UpdM0RgdJJ}Mbx2ZahQo2Cq(VSJMN{J?0X8O zCKqF!?TPu%&nN1EoP>n1BZJ)R!|oaeP`BT4KqbqLRShX z|LI2Rf#jl|ULjrqb+~mc#Y+wdr))q*Eav$7zPnu78(zSj5PV~=xVJTU?gfdaBj;;+ zy?V6wSDgA(s(r%|cX21iX~&3WAmdvw+Wr;S^=8-C)?n>_YLfVxuSq@(7}e|2p_FLV zR!q>2Kj{myM@1lzLj+oJ6?E3^nRz{uz+2-cMu= zD)nu}JlDn9*?D)c`mO2Bcy+@V{_fh|t~-3&xAhrfZBKnKC76G7Va=L-xgm6G8&{JngeS$WANYOzrRI z3xYNHQ3BM8m4Xora41_xA~u~lA-`k)#w(hDyN`xxXUw9y&eM@R%fkV^;D&^hPHf?Z zyo&DYM_2gg1BAz9s3p(wv}b#Y%sXiyw{6rq%m6`h!iAu~4gzYQ=JecDlI6JK#RUNA zbYD8wY*POOY&ScM<@bvF%Pk4WOV-e!X!=mzLu>^XWpuVu$CT|MJ@r6eVJTCJ97vbyXm4UiDaKZ{cby0HC?j_yHFjbLr|;{JL9nf) z+&)wX6vgdw{vF5Lhfoih9iuk%PoUAj{N;QPt!Oe0ig$FZR9YDvCBW%Wez;~CW}n5G z!x`Ar0P`pJH*&v^B>&Pw<4kDqM^_R#I9jRYkuIo^DcClKez%&qpS`fK8|)4{2m-#} zZsK~PMh|37$VR0ay#GUhJ!aR7-MjiemfaS~SfSsrw-o36frDioc_4ejsXa!B(z+Sv za@BQB-11RaUd{|&7-!=_)xk1bRgr~3YO3rHWPXe@V`ghrBuXi}gr66G&CO+aj>hFf zy{p$7$x$QK_j)zm_e!@_6pW#P6WKBS&=O+(EE#&6g40PW?`i!Z2FcTh1YmblItsmD zOY7o8Y6*)Dv^P)5F>4kO`=8(iM0C7^#7XAa$&0WXva4lOesDHcG$7N*kIPm&iTo$C zf}9P~at>dMpL7k?ybnJ}?_4;Je*U6B;gE;N!BHz9b;5KRC5v^4=)j8xR6iYkAsANd zV62Evl$|*v$rf5JVlLfD3k<-NIa?NryRh31^Cx}u3zlD zxD-98)|pekL$*y9$m?bSY}<&Qx=B-~j-X#UsJo6k8JC&t zGm;+B?aIk<-);H3UUpQgW2;W~oUAN;(SD&fTsvjOg5iYR7H=k#7rx>A@Pfq`eRg`7 zUVeFT-rEwzibX3Hge<-M;?*-%a&w_3W^GShUTNpAL&-xA5H3!Ks&Y%SKWI;WL#02L9E+|D*w*ZtbC~1^HDb S2X;}@Ueo7HJLfLi{(k`6T*EH_ literal 0 HcmV?d00001 diff --git a/lang/YTLitePlus.bundle/YTLitePlusLightMode-1024.png b/lang/YTLitePlus.bundle/YTLitePlusLightMode-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..3c5093849840d6110723f4d1a8fc1c0d9ba8020c GIT binary patch literal 14797 zcmeHtc|25W{Qom!>}h1bTE;C~qEt#DGl~`=x|EXTs_a{(D9fDGZI6mn6cdS1*^&s; z;tE#?*_X0s-^0wD-{(yC`+fcX`u*|y`_Aj$SI#-l`8=QX{aK!K)zV^@gqWfjLP%oI zZsYw3QQ%Js5)p!bn9J8(fPX~&b{{&0khnDQKMBP=RDheLQ~P&qM=w4v8z9!Z8krj* zlo=t;`BM;~t3YR9 zOP2rQ;Ue9Ey>asm2OX0LcK`eRr-A=8@Sg_$e>A{JxreaSo26aDWfe0Tqr=nZ5-G@f z4?>Lf(PqaMbl(;YwI4Wa=XLWd&D&M-&5aGv-#amRGHDaG&OD+;Nmk>bA{C_Iz-K4_=+s8uD2Z9qZ{ zqh8gX>!ERvEUR8RSGBkJyb-Q*)tQ_OW@#@h1W$i-`>S||EQLV=n45KaVO>a{)mxYx zqHLRW?PUrz`e(mmyYI&wL>w4Qa#^4)MrO^vfglSYpmCx4FA}3rDc>cX{W%~6?Z|+=E{JLXQEv4?YV4|qx z&Vf?QC=gkjAmsJ-fz4d#e9^;D&)#!Bo8roY7iNY%x;10EbIn87tzGLgU6o%J6wP(b ztLU%`ixm<}D`Ex(EqJu{@VzhGCL_Pj?HS;3D=I2zs?XnC9nC6!JzTYY&&hY}RMLCSLa)Ge8{Q3%@LkjP z>e}47lk?3-XwTN76)_0e7P!xa7(5txI;u9qojTgIO;=lgb=;#ZRSxlwu2k)N;mY(a z0Nrkuyib*MVa6BFP7Ty1F)wF)v)JjbDzm%6=-t`*Rm#BBrX>jJZq|Jl5g-4V+kW;< z+1${pr&GZ-7lY4i_f=V@Ugo86YvJtXEpG4sI)eW6ED6{-5OJ$>a%eOX>og#x??&jD z`QE98fphzDuim~N2S;N?XE~leUslY@nYWT`BUBAO35r#EN~``OEU{cvD(2exz(TiB z`Ne3Gf~rr{Ugi1BA5G{;|1QtX(a}HatJ-hw&f#3+aExi#yp9n&n4!H?>7UC&cfGu? zNIFHmSR-r^=`C38PDcH=297ary-@o}Pugxeu2Fv6P^l-~`$|*U{M_7JK-%QwOJsSc2~!I73GEom zaEjuIP%OM@n4TzNt=!ndVLrIQo!TwUYq}beeYnG{Ki2cW0Lf`0sjy%nNWGfVN)fCa zjZiL1*{9ak;J;kthLk0^yNr+CKtvg@Vro}pQBZyQKc#M}v)LcISD>%SqU0ElFxRTM zZ95r$dcPGb|A}PG5&A2}j3Yd7?h7pv51N~aDB}za4A`6vO>fmrn=PLpIc@w$NMMPG zf#nwB9kVd(14Ra$Rq(-!nc@dGF68{Zhq-;d7^ zz8v`Zv+*JgHZ#{WJjiaa(Hy>q}DyL`X< z5(4ck>$wgKgINbK9ZKfi_5uwd3fq$*yeg6D8eSRrHxu$7JW%$7% z3CU!&X=&sYGcH!i^Z&`0_CwwZD~UH@>$byNfB(#{#mlmM*QwxqwiP-eWM5N6NKO*x zMDrr=bM`q{s2&Zd3EG)xb#DB-i5{K4520XRDe{xV#KfF}f|i-wnqx!L=L)UJKH#ze z89%z2zP_VBWD!=fm`bg!xVNsQeS_(Cl=q6R(z*7q8lL$bJo!{46JfG%&rNF-GV!8e zEpFMC%;g9Z-sJFQY_z|BcQ&0b_zk-oU_mv6V*i}@Yx42%($(Rw_WTu6qsZsg>x=Dr z%9Y{!$d9h-s55HD`=zZBX1XN#p)$&&My`9HtNO28RNVt2Bruk3a@oDT%ne0r=X#zAyQAcQaQDRi)b`if@Skf{9ku?gAx(~MQX?Wzyl(gq1w&1UQJERaAoE`5fo$9TO z&3*lG97`6p1&myCe`MX#?vWBg=qf8Fq_?5|e)Zwe(RKOD*Q~En`<<;$Iz&dc&Ku^K zx@Uju9VxlSOy|UM1W;=+1c(30lXuPp1jrZm_)DQ76{W#_qPA`u=4ej@Bk{5MX-`5+ z!cy1Qt#f$m7Q|C@6BD^Eik!|56yfpmZA_dOqGxDmfsnz&`<&91X4fwatXz!JT_#G# zClfYjtEs6iZCl;&OT3vAety+wG}!mb8ZFoXQwY0JCjWO@j?=VbEgfN%l3XNo;ax%t zEvT@)g~9=vr=pk7$uE44;t3#wqR`@a@T?ax0&6?n8229wBaZsw`@?-c!ShpP-8AI1 zBfXl+*a1(-$i?g+UJM$MH(NF*-{wj}jmv2CP&425w}<=}LS8m3Rb?QQtx94yb*ltr zcnvMkw`~K2^onjIkM&gCGqEE%PrJBEk!?#JPkNECXYO6aL*4k;ST%nilfQafUW+eq zO*EX=AZ1xJRhT%g;5-#sUQ$UWyNT@Xdxo&7g&$0Mz$kZNRuu)8-z3Fh92@CG!I)0yO=Dzxvu572qBsD=fAPMk^fbMSv&}3yG8_W<$GP7 z>z<8lE@k=eh~=5pgBSDW2kYep5ITLWuTb!z5W^K@h%p*Ts0RV^UoD$%rA3s&awWvt zs7f0uh`bj%64wRR`Qfq@!P010Is%t%V=cbLTKUJ9qDQcFZ)mx_*W5}3*;-2$6^QCF z5aZq=kP{a`{yPk2wcI#ETNrvqh@qyb$MY?7&_+n(RA^{Xf3yZlRYR;bS+ssFN2sZ- zKb^q*A0X_-rxDzDjtmsHgK0L9kp22k_SR7DR%`8@MEOaEH43w_>YMB66)2M`k{NE`Bj8FDefjf=39}-biPPvb;wVzbqXuyW~ z&yI^TmV`isDC91y&CLWo2y)ekUwKD>QqLlDu{KaiRvc{`?Nh>qGYcO*B4q% z7H|^EH($lb-;EfrRLi_)F6bK$*}x(etXYLvF5FfVa849vi2QFNEarG*OI17_05(Gq zd$9yrX2+kDCzeY#E0R=GZV@XAUK4CHuJpa{r{2xnwjyFdR0AlP)+X9zCD{>zx-|+h z?g8KR@5}J8D0ze}_86en@3Z_3_%4se3D?rD*u!_A!&^boSdtfswU>hGG-4Z@aVlbK zs*$Qy$jGC<%HAIggR&n|_yq65tOnU$1>gG%Y+`n&c}V!QazP9tBkd}n2R9Xu??V|7 z`wWY{f(*Km2@qAcBl(>@`vAI!I54&(vP=ZCf$yV}hvTH)|kOVwvwn8FyJyAWLl(->Dc&0TRxGL61eC9Gr%*&Ee!H;;^e~%M%kp z;L7_j85|(h-Q8g z8Pfoc_s|1s09;U7waBezQMlgxpz!TmGcc^#UNoj-BnVq77wD$-Tv&!sXhYWNoOl)) z*u3)`NdozdYthdWxfEGoA=35Db;1Y-YW9;@qI|BlCG(dA`WzV>$^#Gh3(4$54D%_3 zzKo3coSXh(L&jRFg|Qge`05J8Xl`$}pyQlV^AkOLn>#x8AwOx5+67dp4es-1upEC} zFwYIu)6>fr6Zr0mY)jymV3&)C;`&uTU$@Ts3~Pb6L9-*NdI&W)k{OjC!O8{emt^F& z=<)~uGiRQHxX%yE-HKCHe~7TdQ>O^e&30bHsHL%U33J0EW&WdMYtZ2tKhko!NL++8 zC5)Wfp*KhX-&F?}Azt(*q2`ZgutqsaE(s~+7|=bGcZ?JJ#eQlgBTea>q(nNyn$k~2 zm?~Chh8S8pB+AH>0jl50lg@UCak*r&E5Y@X$*z4nRuiu+MJWjRcxWrY8`US|Zl~P+ zwT~cTdzYNSQiQf_*|Hn?@2%K)jBfOff@FLRR;MHx3d20GzzF3%#pA>opxFH~m*cYy70Ie&j2;i>}V&*yQ&5ADwB;0>w$CTg|9?BI& zbnbtUF|E5#3_Di?PAVRob#8(;FMad74+R3KR{j1Th>(^b z=oQt(XCNwB3n@gDZb#PuwS>sXX;n!#eLDhGmmghXT`D9-Mw@r+H5sU-`~}?P z^MjCOY%b{pguAknq7+4ux_vHXaAINuDM}+1B`9`&xJ(U0*sd>9Xi8ef6fp+CBT`TM z`LXDTy~_P;T%7>sOuR)8utKQLIhW3cP$75z=|KsTrSYYO0!DH1%E0Q(P2lm^bS=a_ zV8I=P`tP_cR;WjyF#`n>GWl012u*o#zb%_B!N}7Pu&^2us}+f0`dp6n-5F^aP;Tbm zT_@-PZ9nL28kZCv9_}TM@{(YdL4lcq<%Xn#Xz$SI=pYsO?TtbEmy(c5Md(;6LO-p3 zd1yVLz)b)Qy@Vz?u$t9xh@lT*4ew@wVhazW;gup++6m9h@f1b5QpA?0i$b|E$aZb6 zfbk~AvZd-G2%85H4}ta|W-32so(EAlDM_!b=|<;4eaT7I;+UYzg22$oh$>C?ua5ZQsxCd#aaxjo-Syxw_WFU!1@7b}k)eh9rT82}fq%6ZvyuS)Fig9~ZABO-C@9JdU|^SI3+a0!`@)3_6w89> zANxtDgisC%jDJ-OqtXn4JQ5^sJzK+GDn+r zfNC0aa>N-&-a&IF7BJeLH0&+z!q^ndvRXz$Nk96C$|K{=r4N7V>Fd|hkh*EbWD<^?|1oCgyN2Hs(5gWe&vzs<|rjiS8ypy+iY`VRyVxCJ%^ zIQU;kWVeC2u$!{7h-MfJVg>40kXWkl{#`EHdkzy~Ihiw23mLl%Mkj8ofUC1o$X7ft zzAo97;LzB2V@Ir?3bBjQEkI3K_6H#``0vWrQqmxQ??%`{^+_=(7XAcNmdhdZ!dOz0 zA1Z{KB1`ZAc0s_X6dGGaT;BcW*WbwKG`dlGRE=aQ1L~akQ=Gj$n@fVQ7)ec{Vy^qI z5sGS}wnS51k)FCLzJyFzA4FpbIP0^UnjU~+h@JxVUmPCxhJf$a0XioaDWTV2ri8cX z>1Aml+dUPVYeU1r!0vZJ2K}avjs_Z3+%U#NkK|fN78Vw;A?qALby&HP3(1_#9|3()Z%Ejw=aUdUY6CNl5ZhF6A%cjq`j2Kpwxth1>cT zno~f4E{X3?Xw4O+&Y>YQ0)j!eDDON#I72sQD&~ipI#fpOosc+?Cdlo?Ny)}tIg;q;d7XI{gg1oDOS1?-Vao& z%*9efu7FAccN6;y%Na4Igox*tiTwhVVgFPjUWdIaKa%nsi8Z_AN`>McJsN=evkUh6vb4V*bIw58I1Ef?h%WoK{Vd zL@cGuVwhvBD-0Ze-%Z1oS`q$_sgFm5@T^9t=r!RkjeeCMI}GvpkGF4fL+SOJyh7O{ z?_3BS4AoZEChwDmGP9fuGr;F{#m?&-i_9*(Q-W1os8)zoD=TQoT1(Yz{dfcr`)VT1 z05vU1`cl)xbagH5rfvQ-Gc%K5cTZF-0mOC^fC0m5iOV|{IDZPfq98|UzD>riI498$ zaI31Sq*1FHFv(t(QAHy#0Zh%X`cCWNg-;)S@N@P_6mwUCF|RUKSG3WKP^0k4z`#J8 z5#R4s8Y`7GdPF{j7Oz7Xd5a(>bv!;M&fx4F(^w<#-zUM~V_bd_?$t=`_= z0D8)mnW32z)Tp!`8Kiyu>e1&QEg_=wu&RF*32B0kd&kjb%hkTNTBu1+>X~d z2Ck;~ugy%>e~Y+Uyr0=G2g#`#I&G(`>f^)|sJW?W{hTn%Rs(iC+}KBDXaThC1_&Cl zPoFAHEtX{xvCi63=rGz6Xu$iH52`qQC4_e(y<>d*1X;w+&hEO;YKa7OLP!3ERrGQ$ zOjuJ|X+OiE+}#dT{oB8N`)2c|_$U{pKx>8iHG$E7sZz8*)oR4K7)tyMv#6iNp~zR4PbWVF3)!QHQ4G!mLR}aGbqRA8FLYIr1?-(Kg&8D z3refLB1KHxp7vG6xAak4_f)LMEM@Ef7H`HPO_>GG@hO$FE&lXKR-T`SGF>b?4D?r&X z1aAq(5AcQA(Yp%*Yze45?yf*+x%2|3%eJ_ytBW#bY2dgYvUCz4h5tp^{;0>$GsYesp?>0-DXo;yBrkuoV{PX8<@LL0zM1d}ha#S7*{$Ei<>RdwP7qwkj z*hf=l`h0wRyc%{VM^pQz6rYLKrC?U4Q^XoAC@wUCVrxfcC}ZGojM;);B4q1pb%WDI zaL!0!_ii;Xc&jn1J1*>zQCL{mA5GnQtxE=_)=vB`!QOUl0}eOS?hvD}Mgz#yo6GHG zU{aax63;Z_4NnVuB$Bb1MsT>+Yau*_Jd~|4UxGr+A98goq4Ts5UgkX2a${9=-A4!$ z2<||qN<&Oz@v=*rmTiRf^7&;09S)s{7~T9yrCmYRj5e|{vq~DKe%xm{H;GG zw73{JG`^+`s?JJirROiKnHK(e9`P&bLo*j%t2`5Q5`_2;pAyLbEQ;!ON;6D*FUULH zj0xevz!2hh4`PH^LlHY9Jjw?;-ANb<>MUD446X;`A@v8z){yx49{!y=mKgm!DUl)w zmG>jHeR0aDxx|p~)r2=8{|g{181r>*t`s`^FJcMUzDOc>t|aQ)D9wfL<}c}jtXi0% zzbxl29~4GyFyc8zhN(FOxS#$xWC@jbJyZuru1n#KeY7<=QE^zFkq82jb0ptc7UIObVbS#;2ycY87cMit@qSsy`l8H^b z!6{hMRcJH#-NZGQcpS!Do8|-p2_GPcCAON7P_u8<4SDNZzIs*NYMU^ZI8~bn`cOmU0I16^U zX2QT7rhSKB`xh)YZx-GLyFQoFn_eZ;~JgamBBK; z2>}hcI-a>~FaYuz3N(O(t#0%fw)TlC=$An(9ln}RJc&Qa#7Y|`44#Q@Dgo>0ZG(bw z`HB?|cNg@(QduJV4-;J~R52{unK=QkwE%I%t`$NEW(u(o5l7=;f-jKqAU8Kxt_`@% z@MNShx*dvRL~d1%Mn;BiWRR)5_s-Y8?$i$eti zaVA!?-|7b`(iz53Lh}%9ga4QQPo^N&PH14>y*EVTof2aTF(>gYU#X^Yk*v11wvXKY z@~{#({7Z75!_8sDI9uDL@7uCid@Hofezyx!$S6>g$oC(eEXD<^T%+ zYP~fX>VcEsa4%bF{9-S4y1Oir;^+9wQO!9dZ2uOaTZ%XMbHv%-%Q;=Ui`D0J=Y)}I z0vRLjPebBgJu_Fz&!tDMOPbYIEc|i!Qwp_wzGTV6IQK)4(l>ny)&KkUMig*7p00T& zI5^lwLSV_Aou_36r+X^oNyrmy6!M%3q1- z{44jFxnh1ngHkTR6sA!KwH~rw1m`dSL&pV?$5C}SG&6;!jnoEYnAN=ftX{{#d<`P-@do2|{wrYQS=v4W8d29yI> z-W&2i6$}Zp0C&4?HIjgkNah#F7=3+xa0;D942%jMLLm6ZhCrjhtQNpDrr}@;O9_N z_WxYMkdUYk5d$huBIh38j)|a)K#9>n^!kzT7uo<+R9l4ktpwyq$X3lqde_4A3@#oK z^UpQV@4-brv}E2eIYj6a)Pu2Jg6wS9D#)sgdqApEJ-`ae7CukbNezP~au_X_WQ?4a z!p-XAz?lx{A4&)Q28tn{?OWU0;PeRDgFozSiUb+|rDQduj6Hw;oR9!&WREBbINve? zX8H+dF83kve346YN=7;{|K@oSQK3vK&rGv8mZ1vVc=7mZVZIfB4A# z`E&f}{LHYOhLQE570Z?>e_g{H6&nO}b*T~V?BSR|Ah6FFBUaW3Z`q0!a9n<#@|D1Jf= zy{ecY{TxV+mqHn>0|V~oxbvsKhZ^^Bnj_T1BNsti5WBgu1Lt-m7cUePFMOM4^7@#( zS^Q@N{*&hZfjd{lM|m z?FBwq%p07e^SbD~*Ew?()OueFS$kWpVsA_ThFp*sQDfCtv z2-*Mi$Yim$DB>Obb#znPTH=-`T}V8MhEo!JxPv!*ig=Xb@Ur2$Dwfz<$mMb&;RJka z$4yA=VopUdgs?|A>B*YVM>ljQ8B$Ve}-VK8K`_!oPKI!4>~voAZ~P&y=rB>?4zd2T^k z7aVc?_?k65>7Q>&sR#0#F2A{cTf|dH1X;d}zE8(3&ek$M@Nds&Q`WqF$#9zY(7ik;reJoYtpJp<&3S_M zJDUvL8pA2&@v3t-#jxmgP<4ydX0cDDaN^eYt0dAG` zYKR+AkAI*n2ipv04ZI|7o-Fx+ryYDL*OogQ|5*xEyVn*vCcg>dlh5gP>x0!Q2tg5w z>fzH2Z#!3V=W4RQxaFtGm}GRK^A4}At-H&*t8 zZm)*0ItM{XN97CeK$wg-&fhz}&e59|sAP11{9Mh=cqR{w4EG0JDt_QWX}A)?I?Rh@ z40}dO?v?p%0SkM@1s?EpZ#RfB=v%JJfaCZ}1Nlb(P!pbL=9iOUdJW^CW}o8SY*`Ze z=l+uq>*rnru&^XEch~NprlUd>mpjTihY}!*5*D}XBP8i zM>k0% zB;ynV5>^QK9#Om6SmbKYUETx>V$6!744)4EjdjQsx@s%9Efztyc#We>zYKqUJSdWB zO9dU)=(K!fe zDZ~)I@#SDL| z7;in~M379k&Y|hcyFeMcHa`~%+%z|S_V8mxCFle+NGnC$6ovji0W_BWn9lityOUSk zgkin$!vOs@xiP)x3Y3fQocwGg#-;}w{Qdov7r{ew%`?kXJ8QsMKYWz$_720KfX9Or zB=3?=Jn1CLJ2-2BkLRAa?+@LwBEr$!p~HM9y^Ucl^id?SM*UHId@}J_-;e33DHt=O zwv{kq)0L(yQhoVSwd;8P+-g>AASjZZ2sx^gJ!M*NrM8UiO{v?!CZ0>6_nmjwoeOa^%x z&B!R_qw=CHac@8Ft}VwD=;n^2=F7I;7Z-BbL^8V3=umx8u+no8e1suV*Hv(8Mz-_u zl$2%R8-~(n!MBrV&YzBz5R8e3GN4#o#AQ@~{q%l(U1{L_)W9fRch^L_e^zmJ_8(@u zSKw_$!E;&tGj8WTt{?kk4G!~faeL)yA6X!RAQ)0dYR$1GR^J!K_NU>Y+-|bnL|%sljs7+l*0)k zq)50ZJ`k47^xvARIO4a*1E>l)}Gw}1Je(_09z2C8iMzimVzX_VOqc!u^c7Che z7w0=4r1Pwz&2FYIFWa~Fgki|?CyPU={CrtZchl0f2HkOA z=NL-zE4yD*9?;JzTsK>lH+*u+}X_?=M-x z7rd_X8TAIi&%K&ovP1>n4~?$R{Sxu*-O$3bEA`eX2PT&<*?FqiF{ib7^4JQeT2UBf ze!A<>Zmi1q^cTh4+n3oJF|)A&{cKmCJT=*z&aQHZrCu=aBt-*Ur}w`gZ9nQFzN5dY z)gv^H`djXX2Kho-r(xxbxXV_(^FznDEnyHyr&Na#br<9zwo9(|MXSTv?n&Dd=>Y}9 z?Ov`~M^dUCPtpQyCnLwTJ>D=MOhnGMj&^XjsSY4Ga6r~BFZTZ#wc^u}G0Bs^zsqv^ zb0);@!Qh+O_Fg^BjfefV=??e=;U(8bmuoHbrKgFBVk6L#WXL6%TWmOAl5V51Y~KA% z>;Y3vF+(2@ds)Tnss*~6iYMN_V2)(XY8Cn(Uy7{-)x%URuFV>cPQ~?q!#9#5M)pCX zKq=sQ@PiMrh#!2;1wU*tFa>3%Fu*GS36z-s{r=Oye;W8t1OE>VRIkQqtj6L4nfDIE QffPb}Oe~CFY Date: Mon, 26 Aug 2024 00:46:08 +0000 Subject: [PATCH 071/102] updated submodules --- Tweaks/YouTimeStamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/YouTimeStamp b/Tweaks/YouTimeStamp index 4cd5d01..d122e96 160000 --- a/Tweaks/YouTimeStamp +++ b/Tweaks/YouTimeStamp @@ -1 +1 @@ -Subproject commit 4cd5d01d3c6a1c7c1725c89208a5cc8cedad962f +Subproject commit d122e96df8dd4df9d09618a630db81df960c2390 From 6aa1f6214062190f9ba6b340e18d1b56e9989133 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 20:38:59 -0700 Subject: [PATCH 072/102] Add smoothing, improve seek, adjust sensitivity --- YTLitePlus.xm | 93 ++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index ba0da3e..742b7bf 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -668,6 +668,7 @@ BOOL isTabSelected = NO; * for each zone. The zones are horizontal sections that divide the player into * 3 equal parts. The choices are volume, brightness, seek, and disabled. * There is also a deadzone that can be configured in the settings. + * There are 4 logical states: initial, changed in deadzone, changed, end. */ %new - (void)YTLitePlusHandlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer { @@ -676,7 +677,7 @@ BOOL isTabSelected = NO; // Variables for storing initial values to be adjusted static float initialVolume; static float initialBrightness; - static CGFloat currentTime; + static CGFloat initialTime; // 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 @@ -687,6 +688,10 @@ BOOL isTabSelected = NO; static CGFloat deadzoneStartingXTranslation; // Variable to track the X translation of the pan gesture after exiting the deadzone static CGFloat adjustedTranslationX; + // Variable used to smooth out the X translation + static CGFloat smoothedTranslationX = 0; + // 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 static CGFloat deadzoneRadius = (CGFloat)GetFloat(@"playerGesturesDeadzone"); // Constant for the sensitivity factor that can be changed in the settings @@ -714,7 +719,7 @@ BOOL isTabSelected = NO; /***** Helper functions for adjusting player state *****/ // Helper function to adjust brightness void (^adjustBrightness)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialBrightness) { - float brightnessSensitivityFactor = 2.0; + float brightnessSensitivityFactor = 3; float newBrightness = initialBrightness + ((translationX / 1000.0) * sensitivityFactor * brightnessSensitivityFactor); newBrightness = fmaxf(fminf(newBrightness, 1.0), 0.0); [[UIScreen mainScreen] setBrightness:newBrightness]; @@ -722,7 +727,7 @@ BOOL isTabSelected = NO; // Helper function to adjust volume void (^adjustVolume)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialVolume) { - float volumeSensitivityFactor = 2.0; + float volumeSensitivityFactor = 3.0; float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor); newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 @@ -733,18 +738,25 @@ BOOL isTabSelected = NO; }; // 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); - // // Calculate the new seek time based on the calculated offset - // CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive - // seekFraction = sensitivityFactor * seekFraction; - // CGFloat seekTime = currentTime + totalDuration * seekFraction; - // // Seek to the new time - // [playerBarController inlinePlayerBarContainerView:playerBar didFineScrubToTime:seekTime]; - // }; + void (^adjustSeek)(CGFloat, CGFloat) = ^(CGFloat translationX, CGFloat initialTime) { + // Get the location in view for the current video time + CGFloat totalTime = self.currentVideoTotalMediaTime; + CGFloat videoFraction = initialTime / totalTime; + CGFloat initialTimeXPosition = scrubXForScrubRange(videoFraction); + // Calculate the new seek X position + CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive + CGFloat newSeekXPosition = initialTimeXPosition + translationX * sensitivityFactor; + // 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 didScrbToPoint: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 function to run any setup for the selected gesture mode @@ -754,18 +766,15 @@ BOOL isTabSelected = NO; // Handle the setup based on the selected mode switch (selectedGestureMode) { case GestureModeVolume: - // Store initial volume value initialVolume = [[AVAudioSession sharedInstance] outputVolume]; break; case GestureModeBrightness: - // Store the initial brightness value initialBrightness = [UIScreen mainScreen].brightness; break; case GestureModeSeek: - // Store the current time value - currentTime = self.currentVideoMediaTime; + initialTime = self.currentVideoMediaTime; // Start a seek action - [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; + [playerBarController startScrubbing]; break; case GestureModeDisabled: // Do nothing if the gesture is disabled @@ -793,8 +802,7 @@ BOOL isTabSelected = NO; adjustBrightness(adjustedTranslationX, initialBrightness); break; case GestureModeSeek: - // adjustSeek(adjustedTranslationX, currentTime); - [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; + adjustSeek(adjustedTranslationX, initialTime); break; case GestureModeDisabled: // Do nothing if the gesture is disabled @@ -820,7 +828,7 @@ BOOL isTabSelected = NO; case GestureModeBrightness: break; case GestureModeSeek: - [playerBarController seekAnywhereDidScrubWithRecognizer:panGestureRecognizer]; + [playerBarController endScrubbingForSeekSource:0]; break; case GestureModeDisabled: break; @@ -907,6 +915,8 @@ BOOL isTabSelected = NO; if (isValidHorizontalPan) { // Adjust the X translation based on the value hit after exiting the deadzone adjustedTranslationX = translation.x - deadzoneStartingXTranslation; + // Smooth the translation value + adjustedTranslationX = applyLowPassFilter(adjustedTranslationX); // Pass the adjusted translation to the selected gesture switch (gestureSection) { case GestureSectionTop: @@ -925,26 +935,25 @@ BOOL isTabSelected = NO; } } } - if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) { - if (isValidHorizontalPan) { - // Handle the gesture based on the identified section - switch (gestureSection) { - case GestureSectionTop: - runSelectedGestureEnded(@"playerGestureTopSelection"); - break; - case GestureSectionMiddle: - runSelectedGestureEnded(@"playerGestureMiddleSelection"); - break; - case GestureSectionBottom: - runSelectedGestureEnded(@"playerGestureBottomSelection"); - break; - default: - break; - } - // Provide haptic feedback upon successful gesture recognition - // [feedbackGenerator prepare]; - // [feedbackGenerator impactOccurred]; + + // Handle the gesture end state by running the selected gesture mode's end action + if (panGestureRecognizer.state == UIGestureRecognizerStateEnded && isValidHorizontalPan) { + switch (gestureSection) { + case GestureSectionTop: + runSelectedGestureEnded(@"playerGestureTopSelection"); + break; + case GestureSectionMiddle: + runSelectedGestureEnded(@"playerGestureMiddleSelection"); + break; + case GestureSectionBottom: + runSelectedGestureEnded(@"playerGestureBottomSelection"); + break; + default: + break; } + // Provide haptic feedback upon successful gesture recognition + // [feedbackGenerator prepare]; + // [feedbackGenerator impactOccurred]; } } From 235e2966bce945af169851d58fcffde8fc38c709 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:10:27 -0700 Subject: [PATCH 073/102] Fix bugs, only allow one seek gesture --- YTLitePlus.h | 13 +++++++++---- YTLitePlus.xm | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index 5bb9961..41c1562 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -46,6 +46,7 @@ #import "Tweaks/YouTubeHeader/YTMainAppControlsOverlayView.h" #import "Tweaks/YouTubeHeader/YTMultiSizeViewController.h" #import "Tweaks/YouTubeHeader/YTWatchLayerViewController.h" +#import "Tweaks/YouTubeHeader/YTInlinePlayerBarView.h" #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define YT_BUNDLE_ID @"com.google.ios.youtube" @@ -163,15 +164,19 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @property (nonatomic, assign, readwrite) float volumeValue; @end @interface YTPlayerBarController (YTLitePlus) -- (void)inlinePlayerBarContainerViewDidStartFineScrub:(YTInlinePlayerBarContainerView *)playerBar; -- (void)inlinePlayerBarContainerView:(YTInlinePlayerBarContainerView *)playerBar didFineScrubToTime:(CGFloat)time; -- (void)inlinePlayerBarContainerViewDidEndFineScrub:(YTInlinePlayerBarContainerView *)playerBar seekSource:(int)source; - (void)didScrub:(UIPanGestureRecognizer *)gestureRecognizer; -- (void)seekAnywhereDidScrubWithRecognizer:(UIPanGestureRecognizer *)recognizer; +- (void)startScrubbing; +- (void)didScrubToPoint:(CGPoint)point; +- (void)endScrubbingForSeekSource:(int)seekSource; @end @interface YTMainAppVideoPlayerOverlayViewController (YTLitePlus) @property (nonatomic, strong, readwrite) YTPlayerBarController *playerBarController; @end +@interface YTInlinePlayerBarContainerView (YTLitePlus) +@property UIPanGestureRecognizer *scrubGestureRecognizer; +- (CGFloat)scrubXForScrubRange:(CGFloat)scrubRange; +@end + // Hide Collapse Button - @arichornlover @interface YTMainAppControlsOverlayView (YTLitePlus) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 742b7bf..8cf80d6 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -714,7 +714,7 @@ BOOL isTabSelected = NO; // Get objects used to seek nicely in the video player static YTMainAppVideoPlayerOverlayViewController *mainVideoPlayerController = (YTMainAppVideoPlayerOverlayViewController *)self.childViewControllers.firstObject; static YTPlayerBarController *playerBarController = mainVideoPlayerController.playerBarController; - // static YTInlinePlayerBarContainerView *playerBar = playerBarController.playerBar; + static YTInlinePlayerBarContainerView *playerBar = playerBarController.playerBar; /***** Helper functions for adjusting player state *****/ // Helper function to adjust brightness @@ -742,14 +742,14 @@ BOOL isTabSelected = NO; // Get the location in view for the current video time CGFloat totalTime = self.currentVideoTotalMediaTime; CGFloat videoFraction = initialTime / totalTime; - CGFloat initialTimeXPosition = scrubXForScrubRange(videoFraction); + CGFloat initialTimeXPosition = [playerBar scrubXForScrubRange:videoFraction]; // Calculate the new seek X position CGFloat sensitivityFactor = 1; // Adjust this value to make seeking more/less sensitive CGFloat newSeekXPosition = initialTimeXPosition + translationX * sensitivityFactor; // 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 didScrbToPoint:newSeekPoint]; + [playerBarController didScrubToPoint:newSeekPoint]; }; // Helper function to smooth out the X translation @@ -885,6 +885,8 @@ BOOL isTabSelected = NO; // If outside the deadzone, activate the pan gesture and store the initial values isValidHorizontalPan = YES; deadzoneStartingXTranslation = translation.x; + adjustedTranslationX = 0; + smoothedTranslationX = 0; // Run the setup for the selected gesture mode switch (gestureSection) { case GestureSectionTop: @@ -960,6 +962,15 @@ BOOL isTabSelected = NO; // allow the pan gesture to be recognized simultaneously with other gestures %new - (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; + } + } return YES; } %end From 268568b106fb55d96218cf2c9ef16646f4ec8d76 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 25 Aug 2024 23:46:29 -0700 Subject: [PATCH 074/102] Improve audio smoothness visuals --- YTLitePlus.xm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 8cf80d6..125d30a 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -730,6 +730,11 @@ BOOL isTabSelected = NO; float volumeSensitivityFactor = 3.0; float newVolume = initialVolume + ((translationX / 1000.0) * sensitivityFactor * volumeSensitivityFactor); newVolume = fmaxf(fminf(newVolume, 1.0), 0.0); + // Improve smoothness - ignore if the volume is within 0.01 of the current volume + CGFloat currentVolume = [[AVAudioSession sharedInstance] outputVolume]; + if (fabs(newVolume - currentVolume) < 0.01 && currentVolume > 0.01 && currentVolume < 0.99) { + return; + } // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ From 573c2d2f433067a350d31a878d89bfdfb44785cf Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 00:06:39 -0700 Subject: [PATCH 075/102] Add setting for haptic feedback --- Source/Settings.xm | 4 +++- YTLitePlus.xm | 9 +++++++-- lang/YTLitePlus.bundle/ar.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/bg.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/de.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/en.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/es.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/fr.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/ja.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/pt.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/ro.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/ru.lproj/Localizable.strings | 1 + .../YTLitePlus.bundle/template.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/tr.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/vi.lproj/Localizable.strings | 1 + lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings | 1 + 16 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 5bfd862..21d6374 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -397,7 +397,9 @@ static const NSInteger YTLiteSection = 789; createSectionGestureSelector(@"BOTTOM_SECTION", @"playerGestureBottomSelection"), // Pickers for configuration settings deadzonePicker, - sensitivityPicker + sensitivityPicker, + // Toggle for haptic feedback + BASIC_SWITCH(LOC(@"PLAYER_GESTURES_HAPTIC_FEEDBACK"), nil, @"playerGesturesHapticFeedback_enabled"), ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Player Gestures (Beta)") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; [settingsViewController pushViewController:picker]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 125d30a..bb6c372 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -909,8 +909,10 @@ BOOL isTabSelected = NO; break; } // Provide haptic feedback to indicate a gesture start - [feedbackGenerator prepare]; - [feedbackGenerator impactOccurred]; + if (IS_ENABLED(@"playerGesturesHapticFeedback_enabled")) { + [feedbackGenerator prepare]; + [feedbackGenerator impactOccurred]; + } } else { // Cancel the gesture if the translation is not horizontal panGestureRecognizer.state = UIGestureRecognizerStateCancelled; @@ -1230,4 +1232,7 @@ BOOL isTabSelected = NO; if (![allKeys containsObject:@"playerGesturesSensitivity"]) { [[NSUserDefaults standardUserDefaults] setFloat:1.0 forKey:@"playerGesturesSensitivity"]; } + if (![allKeys containsObject:@"playerGesturesHapticFeedback_enabled"]) { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"playerGesturesHapticFeedback_enabled"]; + } } diff --git a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings index a577d98..8890c45 100644 --- a/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ar.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 4689437..214f171 100644 --- a/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/bg.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 76a63fe..755b54d 100644 --- a/lang/YTLitePlus.bundle/de.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/de.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 57fd3dc..37f9e2e 100644 --- a/lang/YTLitePlus.bundle/en.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/en.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 1cf7433..a6ea96d 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 e788b97..7e2102f 100644 --- a/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/fr.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 2749ff2..7c7fc64 100644 --- a/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ja.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 df987ed..02de1f8 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 343c226..f12659a 100644 --- a/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ro.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 5e6bb59..bfe751a 100644 --- a/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/ru.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 982d0e2..4bf0f2a 100644 --- a/lang/YTLitePlus.bundle/template.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/template.lproj/Localizable.strings @@ -46,6 +46,7 @@ https://github.com/PoomSmart/Return-YouTube-Dislikes/tree/main/layout/Library/Ap "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 a9b0ea3..2dad47f 100644 --- a/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/tr.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 dd3fdb0..6724afc 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -31,6 +31,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // 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 aef5cf3..8470f3f 100644 --- a/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/zh_TW.lproj/Localizable.strings @@ -32,6 +32,7 @@ "TOP_SECTION" = "Top Section"; "MIDDLE_SECTION" = "Middle Section"; "BOTTOM_SECTION" = "Bottom Section"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "影片區覆蓋按鈕設定"; From 963b9d5fd32195143addfff2fee9926760dec892 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 00:41:55 -0700 Subject: [PATCH 076/102] Ignore fine scrubber gesture overlap --- YTLitePlus.h | 6 +++++- YTLitePlus.xm | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index 41c1562..cc7bb43 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -154,6 +154,10 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @end // Player Gestures - @bhackel +@interface YTFineScrubberFilmstripView : UIView +@end +@interface YTFineScrubberFilmstripCollectionView : UICollectionView +@end @interface YTPlayerViewController (YTLitePlus) @property (nonatomic, retain) UIPanGestureRecognizer *YTLitePlusPanGesture; - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; @@ -174,10 +178,10 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @end @interface YTInlinePlayerBarContainerView (YTLitePlus) @property UIPanGestureRecognizer *scrubGestureRecognizer; +@property (nonatomic, strong, readwrite) YTFineScrubberFilmstripView *fineScrubberFilmstrip; - (CGFloat)scrubXForScrubRange:(CGFloat)scrubRange; @end - // Hide Collapse Button - @arichornlover @interface YTMainAppControlsOverlayView (YTLitePlus) @property (nonatomic, assign, readwrite) YTQTMButton *watchCollapseButton; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index bb6c372..57ff99b 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -977,6 +977,16 @@ BOOL isTabSelected = NO; 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; } From 6996c0ed66543c17df8bb012e0c8c8321cb3360b Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 01:46:52 -0700 Subject: [PATCH 077/102] Add keys, fix toasts --- Source/Settings.xm | 13 +++++-------- Source/SettingsKeys.h | 5 +++-- Source/get_keys.py | 4 ++++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 456959f..00e78c0 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -191,11 +191,9 @@ static const NSInteger YTLiteSection = 789; }]]; [settingsViewController presentViewController:confirmPasteAlert animated:YES completion:nil]; } - // Show a toast message to confirm the action - [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings pasted"]]; // Reminder to import YouTube Plus settings UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" - message:@"Remember to import your YouTube Plus settings as well." + message:@"Remember to import your YouTube Plus settings as well" preferredStyle:UIAlertControllerStyleAlert]; [reminderAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; [settingsViewController presentViewController:reminderAlert animated:YES completion:nil]; @@ -678,7 +676,7 @@ static const NSInteger YTLiteSection = 789; NSError *error; NSString *fileType = [pickedURL resourceValuesForKeys:@[NSURLTypeIdentifierKey] error:&error][NSURLTypeIdentifierKey]; - UIViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; if (UTTypeConformsTo((__bridge CFStringRef)fileType, kUTTypePlainText)) { // This block handles the import of settings from a text file. @@ -692,10 +690,9 @@ static const NSInteger YTLiteSection = 789; [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; } } - if ([settingsViewController respondsToSelector:@selector(reloadData)]) { - // Call a custom reloadData method if it exists - [settingsViewController performSelector:@selector(reloadData)]; - } + [settingsViewController reloadData]; + // Show a toast message to confirm the action + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings applied"]]; } } } diff --git a/Source/SettingsKeys.h b/Source/SettingsKeys.h index 384f08b..d18b4e8 100644 --- a/Source/SettingsKeys.h +++ b/Source/SettingsKeys.h @@ -17,8 +17,9 @@ NSArray *NSUserDefaultsCopyKeys = @[ @"hideHomeTab_enabled", @"hidePreviewCommentSection_enabled", @"hideRightPanel_enabled", @"hideSpeedToast_enabled", @"hideSponsorBlockButton_enabled", @"hideVideoPlayerShadowOverlayButtons_enabled", @"iPadLayout_enabled", @"iPhoneLayout_enabled", @"inline_muted_playback_enabled", @"lowContrastMode_enabled", - @"newSettingsUI_enabled", @"oledKeyBoard_enabled", @"playerGestures_enabled", @"seekAnywhere_enabled", - @"switchCopyandPasteFunctionality_enabled", @"ytNoModernUI_enabled", @"ytStartupAnimation_enabled", + @"newSettingsUI_enabled", @"oledKeyBoard_enabled", @"playerGesturesHapticFeedback_enabled", + @"playerGestures_enabled", @"seekAnywhere_enabled", @"switchCopyandPasteFunctionality_enabled", + @"videoPlayerButton_enabled", @"ytNoModernUI_enabled", @"ytStartupAnimation_enabled", // DEMC - https://github.com/therealFoxster/DontEatMyContent/blob/master/Tweak.h @"DEMC_enabled", @"DEMC_colorViewsEnabled", @"DEMC_safeAreaConstant", @"DEMC_disableAmbientMode", @"DEMC_limitZoomToFill", @"DEMC_enableForAllVideos", diff --git a/Source/get_keys.py b/Source/get_keys.py index e763e3a..dd6f221 100644 --- a/Source/get_keys.py +++ b/Source/get_keys.py @@ -61,6 +61,7 @@ def find_and_extract_keys(): Recursively searches for .xm and .h files in the parent directory and extracts keys that match the pattern @\"_enabled\". The matching keys are then printed with indentation and line breaks if the line exceeds 120 characters. + Ignores SettingsKeys.h Usage: 1. Place this script in the desired directory. @@ -82,6 +83,9 @@ def find_and_extract_keys(): for root, dirs, files in os.walk(parent_directory): for file in files: if file.endswith(('.xm', '.h')): + # Skip SettingsKeys.h + if file == "SettingsKeys.h": + continue file_path = os.path.join(root, file) found_keys.update(extract_values_from_file(file_path)) From 969efaaf4dcbb5fe59495ebebe6bdf8082a3b88e Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:36:26 -0700 Subject: [PATCH 078/102] Revert default Player Button, reduce image size --- YTLitePlus.xm | 7 ++----- lang/YTLitePlus.bundle/YTLitePlusColored-128.png | Bin 0 -> 1241 bytes 2 files changed, 2 insertions(+), 5 deletions(-) create mode 100644 lang/YTLitePlus.bundle/YTLitePlusColored-128.png diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 3bb632e..a857011 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -1034,10 +1034,10 @@ NSInteger pageStyle = 0; self.videoPlayerButton.frame = CGRectMake(0, 0, 40, 40); if ([%c(YTPageStyleController) pageStyle]) { //dark mode - [self.videoPlayerButton setImage:[UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-1024" ofType:@"png"]] forState:UIControlStateNormal]; + [self.videoPlayerButton setImage:[UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]] forState:UIControlStateNormal]; } else { // light mode - UIImage *image = [UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-1024" ofType:@"png"]]; + UIImage *image = [UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]]; image = [image imageWithTintColor:UIColor.blackColor renderingMode:UIImageRenderingModeAlwaysTemplate]; [self.videoPlayerButton setImage:image forState:UIControlStateNormal]; [self.videoPlayerButton setTintColor:UIColor.blackColor]; @@ -1322,9 +1322,6 @@ NSInteger pageStyle = 0; if (![allKeys containsObject:@"fixCasting_enabled"]) { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"fixCasting_enabled"]; } - if (![allKeys containsObject:@"videoPlayerButton_enabled"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"videoPlayerButton_enabled"]; - } // Default gestures as volume, brightness, seek if (![allKeys containsObject:@"playerGestureTopSelection"]) { [[NSUserDefaults standardUserDefaults] setInteger:GestureModeVolume forKey:@"playerGestureTopSelection"]; diff --git a/lang/YTLitePlus.bundle/YTLitePlusColored-128.png b/lang/YTLitePlus.bundle/YTLitePlusColored-128.png new file mode 100644 index 0000000000000000000000000000000000000000..de19892cc98e78c7125dd2e11349cdb0852b5877 GIT binary patch literal 1241 zcmV;~1Sb25P)r@oS@m~=GX0J#fAtsm=yh<#9cEq$3#-szrv@2*UF<|(*f@TBgbpt42j?^sRNp&R# z43HWm21xud_dGkVY3f97?PL2o-;Z?F)^^e)_xRjD{u2oR00000000000000000000 z000000000$f9)s&nY63Cm}F^Hva)GX^6(c+kA13nD1WS3K41DfEm=3;dALn4bshkr za`%)MtE88@uk1t*D?V0>fJlqK?dNSMvts!yhCpdlsPw~7CZXJgl2P7%79$N^c$52~ z+(c3-U6h-_210ma-$hgrU6)f03633cse=J* zhJe-_ST;C4jU^D`34o}aoyF2Wh$;Z$ng(9(AMEvZ0+Rr6XMu2iJ%nLnWi$b0miq?- zM*wVM{R0bxe)JFM1a@N4Kd`2u+h&0P=+tngl^-Ago@!v7!}o=1W;5yJM4C=jn`M*T zm5e^0=l^2}viu^@?k}$zjk4PA?y~IoxY^e=nLPeKwrum`j^%(1u*tdwyI}Iq+-(QuXP~pg7w3P3QwW z+tpRx&fDG}ufvtBdey}J1&5shtir9GZ(~?zXBt;Mo2cw~f-SR2r}Zx1{bm6@o27ET ze^4zUTF0GF1-Dto`+aG_cxNV|52-ZE%uPe*`3l;x`^mWPRZ`1(q0Qgy35CESPrLK>P zvf?K>HmBYvg-(UKuH?uy0E&CuPKD=6!)G{_qc%881vg33OK$%uA4YQOM%IC@hVY_Au ztGOz&WotS)A*5*A>~OKo5-z?tGEsha(II_lp6FV;L=m7q#Dth29?op0EFzEbQ1US4ktfB0Mas^qy9mjC#v^u1ct`v4fAMC*g_ zcRijB1^@s60000000000000000000000000z&86Iv3mFYN+*+_00000NkvXXu0mjf DV!tr# literal 0 HcmV?d00001 From 5741d7c900d12b5d706534cc9597b9acc35a3940 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:40:39 -0700 Subject: [PATCH 079/102] Fix black tinting in light mode --- YTLitePlus.xm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index a857011..093b70d 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -1037,10 +1037,11 @@ NSInteger pageStyle = 0; [self.videoPlayerButton setImage:[UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]] forState:UIControlStateNormal]; } else { // light mode - UIImage *image = [UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]]; - image = [image imageWithTintColor:UIColor.blackColor renderingMode:UIImageRenderingModeAlwaysTemplate]; - [self.videoPlayerButton setImage:image forState:UIControlStateNormal]; - [self.videoPlayerButton setTintColor:UIColor.blackColor]; + [self.videoPlayerButton setImage:[UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]] forState:UIControlStateNormal]; + // UIImage *image = [UIImage imageWithContentsOfFile:[tweakBundle pathForResource:@"YTLitePlusColored-128" ofType:@"png"]]; + // image = [image imageWithTintColor:UIColor.blackColor renderingMode:UIImageRenderingModeAlwaysTemplate]; + // [self.videoPlayerButton setImage:image forState:UIControlStateNormal]; + // [self.videoPlayerButton setTintColor:UIColor.blackColor]; } pageStyle = [%c(YTPageStyleController) pageStyle]; From a46b3b4e201c1736a412d72f04491f744b25559d Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 27 Aug 2024 00:46:19 +0000 Subject: [PATCH 080/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 86dab71..6e2fe5b 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 86dab71245ade3f2c8e46ac642489fd70f6a81b3 +Subproject commit 6e2fe5b8c96ff6fb38ca887055453d09b30b6689 From 09721d4b3a37792f4d25cc3c44ca3a610f83f07a Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:31:00 -0700 Subject: [PATCH 081/102] Fix reminder popups --- Source/Settings.xm | 107 ++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 00e78c0..d6212fb 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -105,7 +105,7 @@ static const NSInteger YTLiteSection = 789; # pragma mark - Copy and Paste Settings YTSettingsSectionItem *copySettings = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"COPY_SETTINGS") + itemWithTitle:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"EXPORT_SETTINGS") : LOC(@"COPY_SETTINGS") titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"EXPORT_SETTINGS_DESC") : LOC(@"COPY_SETTINGS_DESC") accessibilityIdentifier:nil detailTextBlock:nil @@ -116,7 +116,11 @@ static const NSInteger YTLiteSection = 789; NSMutableString *settingsString = [NSMutableString string]; for (NSString *key in NSUserDefaultsCopyKeys) { id value = [[NSUserDefaults standardUserDefaults] objectForKey:key]; - if (value) { + id defaultValue = NSUserDefaultsCopyKeysDefaults[key]; + + // Only include the setting if it is different from the default value + // If no default value is found, include it by default + if (value && (!defaultValue || ![value isEqual:defaultValue])) { [settingsString appendFormat:@"%@: %@\n", key, value]; } } @@ -142,22 +146,31 @@ static const NSInteger YTLiteSection = 789; [[UIPasteboard generalPasteboard] setString:settingsString]; // Show a confirmation message or perform some other action here [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings copied"]]; + + // Show an option to export YouTube Plus settings + UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" + message:@"Note: This feature cannot save iSponsorBlock and most YouTube settings.\n\nWould you like to also export your YouTube Plus Settings?" + preferredStyle:UIAlertControllerStyleAlert]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + // Export YouTube Plus Settings functionality + [%c(YTLUserDefaults) exportYtlSettings]; + }]]; + + // Get the root view controller + UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; + + // Present the alert from the root view controller + [rootViewController presentViewController:exportAlert animated:YES completion:nil]; } - // Prompt to export YouTube Plus settings - UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" message:@"Note: This feature cannot save iSponsorBlock and most YouTube settings.\n\nWould you like to also export your YouTube Plus Settings?" preferredStyle:UIAlertControllerStyleAlert]; - [exportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; - [exportAlert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - // Export YouTube Plus Settings functionality - [%c(YTLUserDefaults) exportYtlSettings]; - }]]; - [settingsViewController presentViewController:exportAlert animated:YES completion:nil]; + return YES; } ]; [sectionItems addObject:copySettings]; YTSettingsSectionItem *pasteSettings = [%c(YTSettingsSectionItem) - itemWithTitle:LOC(@"PASTE_SETTINGS") + itemWithTitle:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"IMPORT_SETTINGS") : LOC(@"PASTE_SETTINGS") titleDescription:IS_ENABLED(@"switchCopyandPasteFunctionality_enabled") ? LOC(@"IMPORT_SETTINGS_DESC") : LOC(@"PASTE_SETTINGS_DESC") accessibilityIdentifier:nil detailTextBlock:nil @@ -183,20 +196,20 @@ static const NSInteger YTLiteSection = 789; NSString *value = components[1]; [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; } - } + } [settingsViewController reloadData]; - // Show a confirmation message or perform some other action here + // Show a confirmation toast [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings applied"]]; + // Show a reminder to import YouTube Plus settings as well + UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" + message:@"Remember to import your YouTube Plus settings as well" + preferredStyle:UIAlertControllerStyleAlert]; + [reminderAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + [settingsViewController presentViewController:reminderAlert animated:YES completion:nil]; } }]]; [settingsViewController presentViewController:confirmPasteAlert animated:YES completion:nil]; } - // Reminder to import YouTube Plus settings - UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" - message:@"Remember to import your YouTube Plus settings as well" - preferredStyle:UIAlertControllerStyleAlert]; - [reminderAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; - [settingsViewController presentViewController:reminderAlert animated:YES completion:nil]; return YES; } @@ -674,25 +687,49 @@ static const NSInteger YTLiteSection = 789; if (urls.count > 0) { NSURL *pickedURL = [urls firstObject]; NSError *error; - NSString *fileType = [pickedURL resourceValuesForKeys:@[NSURLTypeIdentifierKey] error:&error][NSURLTypeIdentifierKey]; + // Check which mode the document picker is in + if (controller.documentPickerMode == UIDocumentPickerModeImport) { + // Import mode: Handle the import of settings from a text file + NSString *fileType = [pickedURL resourceValuesForKeys:@[NSURLTypeIdentifierKey] error:&error][NSURLTypeIdentifierKey]; - YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; - - if (UTTypeConformsTo((__bridge CFStringRef)fileType, kUTTypePlainText)) { - // This block handles the import of settings from a text file. - NSString *fileContents = [NSString stringWithContentsOfURL:pickedURL encoding:NSUTF8StringEncoding error:nil]; - NSArray *lines = [fileContents componentsSeparatedByString:@"\n"]; - for (NSString *line in lines) { - NSArray *components = [line componentsSeparatedByString:@": "]; - if (components.count == 2) { - NSString *key = components[0]; - NSString *value = components[1]; - [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; + if (UTTypeConformsTo((__bridge CFStringRef)fileType, kUTTypePlainText)) { + NSString *fileContents = [NSString stringWithContentsOfURL:pickedURL encoding:NSUTF8StringEncoding error:nil]; + NSArray *lines = [fileContents componentsSeparatedByString:@"\n"]; + for (NSString *line in lines) { + NSArray *components = [line componentsSeparatedByString:@": "]; + if (components.count == 2) { + NSString *key = components[0]; + NSString *value = components[1]; + [[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; + } } + // Reload settings view after importing + YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + [settingsViewController reloadData]; + // Show a confirmation message or perform some other action here + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings applied"]]; + // Show a reminder to import YouTube Plus settings as well + UIAlertController *reminderAlert = [UIAlertController alertControllerWithTitle:@"Reminder" + message:@"Remember to import your YouTube Plus settings as well" + preferredStyle:UIAlertControllerStyleAlert]; + [reminderAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]]; + [settingsViewController presentViewController:reminderAlert animated:YES completion:nil]; } - [settingsViewController reloadData]; - // Show a toast message to confirm the action - [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings applied"]]; + + } else if (controller.documentPickerMode == UIDocumentPickerModeExportToService || controller.documentPickerMode == UIDocumentPickerModeMoveToService) { + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Settings saved"]]; + // Export mode: Display a reminder to save YouTube Plus settings + UIAlertController *exportAlert = [UIAlertController alertControllerWithTitle:@"Export Settings" + message:@"Note: This feature cannot save iSponsorBlock and most YouTube settings.\n\nWould you like to also export your YouTube Plus Settings?" + preferredStyle:UIAlertControllerStyleAlert]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]]; + [exportAlert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + // Export YouTube Plus Settings functionality + [%c(YTLUserDefaults) exportYtlSettings]; + }]]; + YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + // Present the alert from the root view controller + [settingsViewController presentViewController:exportAlert animated:YES completion:nil]; } } } From 5fb849297adcb1e60f9f078e00b5b7cbf5f8531d Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 26 Aug 2024 23:12:24 -0700 Subject: [PATCH 082/102] Fix bug with reminder again --- Source/Settings.xm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index d6212fb..418d6f4 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -156,12 +156,8 @@ static const NSInteger YTLiteSection = 789; // Export YouTube Plus Settings functionality [%c(YTLUserDefaults) exportYtlSettings]; }]]; - - // Get the root view controller - UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; - // Present the alert from the root view controller - [rootViewController presentViewController:exportAlert animated:YES completion:nil]; + [settingsViewController presentViewController:exportAlert animated:YES completion:nil]; } return YES; From f17bb793d4a5559afa038dad204004228df3c833 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 28 Aug 2024 00:46:43 +0000 Subject: [PATCH 083/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 6e2fe5b..807ecfd 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 6e2fe5b8c96ff6fb38ca887055453d09b30b6689 +Subproject commit 807ecfd0faf20b8bb5246675d15ac952901cd5d1 From 4a9237893961b244ce0e97d9e69fc39d3b4ea24f Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 29 Aug 2024 00:47:16 +0000 Subject: [PATCH 084/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 807ecfd..1b44ce0 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 807ecfd0faf20b8bb5246675d15ac952901cd5d1 +Subproject commit 1b44ce0feef45a78ba99d09bd2e5ff5052a6541b From b5a45c15ac48e5931025271b86fa117e8f4b731c Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 30 Aug 2024 00:47:31 +0000 Subject: [PATCH 085/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 1b44ce0..890dd25 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 1b44ce0feef45a78ba99d09bd2e5ff5052a6541b +Subproject commit 890dd25c7f6fbe9680b5467497235796bd4dcc9e From 197f31edf47f96ef0dda5fc7cdee7beeee64678d Mon Sep 17 00:00:00 2001 From: Victor Alves Date: Fri, 30 Aug 2024 15:44:40 -0300 Subject: [PATCH 086/102] Update Portuguese Localization (#389) * Update Portuguese Localization * Update Portuguese Localization * Update Portuguese localization * Update Portuguese Localization --- .../pt.lproj/Localizable.strings | 382 +++++++++--------- 1 file changed, 191 insertions(+), 191 deletions(-) diff --git a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings index 26835d4..eb1e6b4 100644 --- a/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/pt.lproj/Localizable.strings @@ -1,191 +1,191 @@ -// Settings -"VERSION" = "Versão do YTLitePlus: %@"; -"VERSION_CHECK" = "Toque para verificar se há atualização!"; - -"COPY_SETTINGS" = "Copiar Configurações"; -"COPY_SETTINGS_DESC" = "Copia todas as configurações atuais para a área de transferência"; -"PASTE_SETTINGS" = "Colar Configurações"; -"PASTE_SETTINGS_DESC" = "Cola as configurações da área de transferência e aplica"; -"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; -"EXPORT_SETTINGS" = "Exportar Configurações"; -"EXPORT_SETTINGS_DESC" = "Exporta todas as configurações atuais para um arquivo .txt"; -"IMPORT_SETTINGS" = "Importar Configurações"; -"IMPORT_SETTINGS_DESC" = "Pressione para importar as configurações (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Substituir os Botões 'Copiar Configurações' e 'Colar Configurações'"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Substitui os Botões 'Exportar Configurações' e 'Importar Configurações'"; - -"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"; -"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; - -// Video controls overlay options -"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; - -"ENABLE_SHARE_BUTTON" = "Ativar o botão 'Compartilhar'"; -"ENABLE_SHARE_BUTTON_DESC" = "Ativa o botão Compartilhar na sobreposição de controles de vídeo."; - -"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Ativar o botão 'Salvar'"; -"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Ativa o botão 'Salvar' na sobreposição de controles de vídeo."; - -"HIDE_SHADOW_OVERLAY_BUTTONS" = "Ocultar Sombras nos Botões de Sobreposição"; -"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Oculta as sombras nos botões de sobreposição Reproduzir/Pausar, Anterior, Próximo, Avançar e Retroceder."; - -"HIDE_RIGHT_PANEL" = "Ocultar o painel direito no modo de tela cheia"; -"HIDE_RIGHT_PANEL_DESC" = "A reinicialização do app é necessária."; - -"HIDE_HEATWAVES" = "Ocultar Ondas de calor"; -"HIDE_HEATWAVES_DESC" = "Oculta as Ondas de calor no player de vídeo. A reinicialização do app é necessária."; - -"DISABLE_AMBIENT_PORTRAIT" = "Desativar Iluminação cinematográfica (Retrato)"; -"DISABLE_AMBIENT_PORTRAIT_DESC" = "Desativa a iluminação ao redor do título do vídeo"; - -"DISABLE_AMBIENT_FULLSCREEN" = "Desativar Iluminação cinematográfica (Tela cheia)"; -"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Desativa a iluminação ao redor do player de vídeo"; - -"FULLSCREEN_TO_THE_RIGHT" = "Tela cheia para a direita"; -"FULLSCREEN_TO_THE_RIGHT_DESC" = "Sempre entre em tela cheia com o botão home no lado direito."; - -"SEEK_ANYWHERE" = "Gesto de Busca em qualquer lugar"; -"SEEK_ANYWHERE_DESC" = "Segure e arraste o player de vídeo para buscar. Você deve desativar o YTLite - Segurar para velocidade (Hold for speed)"; - -"ENABLE_TAP_TO_SEEK" = "Ativar Toque para Buscar"; -"ENABLE_TAP_TO_SEEK_DESC" = "Vá para qualquer lugar em um vídeo tocando uma vez na barra de busca"; - -"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Desativar gesto de puxar para tela cheia"; -"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Desativa o gesto de arrastar para entrar em tela cheia vertical. Aplica-se apenas a vídeos em paisagem."; - -"ALWAYS_USE_REMAINING_TIME" = "Sempre usar o tempo restante"; -"ALWAYS_USE_REMAINING_TIME_DESC" = "Altera o padrão para mostrar o tempo restante na barra do player."; - -"DISABLE_TOGGLE_TIME_REMAINING" = "Desativar alternar tempo restante"; -"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Desativa a alteração do tempo decorrido para o tempo restante. Use com outra configuração para mostrar sempre o tempo restante."; - -"DISABLE_ENGAGEMENT_OVERLAY" = "Desativar sobreposição de engajamento em tela cheia"; -"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desativa o gesto de deslizar para cima e a lista de vídeos sugeridos em tela cheia"; - -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Ocultar Visualizações de comentários sob o player"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Oculta a Prévia de comentário no botão de comentários"; - -"HIDE_AUTOPLAY_MINI_PREVIEW" = "Ocultar mini visualização de reprodução automática"; -"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Oculta a pequena caixa de vídeo sugerida perto do título em tela cheia"; - -"HIDE_HUD_MESSAGES" = "Ocultar Mensagens do HUD"; -"HIDE_HUD_MESSAGES_DESC" = "Exemplo: Legendas/CC ativadas/desativadas, A repetição do vídeo está ativada,..."; - -"HIDE_COLLAPSE_BUTTON" = "Ocultar Botão de Recolhimento"; -"HIDE_COLLAPSE_BUTTON_DESC" = "Oculta o botão de seta para recolher que era exibido no canto superior esquerdo do player de vídeo."; - -"HIDE_SPEED_TOAST" = "Ocultar Toast de Velocidade"; -"HIDE_SPEED_TOAST_DESC" = "Ocultar o popup de Velocidade 2X ao segurar o player"; - - -// App settings overlay options -"APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; - -"HIDE_ACCOUNT_SECTION" = "Ocultar a sessão \"Conta\""; -"HIDE_AUTOPLAY_SECTION" = "Ocultar a sessão \"Reprodução automática\""; -"HIDE_TRYNEWFEATURES_SECTION" = "Ocultar a sessão \"Experimente novos recursos\""; -"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Ocultar a sessão \"Preferências de qualidade de vídeo\""; -"HIDE_NOTIFICATIONS_SECTION" = "Ocultar a sessão \"Notificações\""; -"HIDE_MANAGEALLHISTORY_SECTION" = "Ocultar a sessão \"Gerencie todo o histórico\""; -"HIDE_YOURDATAINYOUTUBE_SECTION" = "Ocultar a sessão \"Seus dados no YouTube\""; -"HIDE_PRIVACY_SECTION" = "Ocultar a sessão \"Privacidade\""; -"HIDE_LIVECHAT_SECTION" = "Ocultar a sessão \"Chat ao vivo\""; - -// Theme -"THEME_OPTIONS" = "Opções de Temas"; - -"OLED_DARK_THEME" = "Modo escuro OLED"; -"OLED_DARK_THEME_2" = "Modo escuro OLED"; -"OLED_DARK_THEME_DESC" = "Verdadeiro tema escuro. Pode não funcionar corretamente em alguns casos. App restart is required after you enable/disable this option."; - -"OLD_DARK_THEME" = "Antigo tema escuro"; -"OLD_DARK_THEME_DESC" = "Tema escuro do YouTube antigo (tema cinza). A reinicialização do app é necessária."; - -"DEFAULT_THEME" = "Padrão"; -"DEFAULT_THEME_DESC" = "Tema escuro padrão do YouTube. A reinicialização do app é necessária."; - -"OLED_KEYBOARD" = "Teclado OLED"; -"OLED_KEYBOARD_DESC" = "Pode não funcionar corretamente em alguns casos. A reinicialização do app é necessária."; - -"LOW_CONTRAST_MODE" = "Modo de Baixo Contraste"; -"LOW_CONTRAST_MODE_DESC" = "Esta opção terá baixo contraste dos textos e botões, assim como era a antiga interface do YouTube. A reinicialização do app é necessária."; -"LCM_SELECTOR" = "Seleção do modo de baixo contraste"; -"DEFAULT_LOWCONTRASTMODE" = "(Padrão) LowContrastMode"; -"CUSTOM_LOWCONTRASTMODE" = "(Cor Personalizada) LowContrastMode"; - -// Miscellaneous -"MISCELLANEOUS" = "Diversos"; - -"PLAYBACK_IN_FEEDS" = "Reprodução nos feeds"; -"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Sempre ativada"; -"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Somente Wi-Fi"; -"PLAYBACK_IN_FEEDS_OFF" = "Desativada"; - -"NEW_SETTINGS_UI" = "Nova Interface de Configurações"; -"NEW_SETTINGS_UI_DESC" = "Usa a nova Interface de configurações agrupadas. Pode ocultar algumas configurações"; - -"ENABLE_YT_STARTUP_ANIMATION" = "Ative a animação de inicialização do YouTube"; -"ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; - -"HIDE_MODERN_INTERFACE" = "Ocultar Interface Moderna (YTNoModernUI)"; -"HIDE_MODERN_INTERFACE_DESC" = "Ative esta opção para ocultar qualquer elemento moderno adicionado pelo YouTube. Remove a iluminação cinematogrática, design arredondado e muito mais. A reinicialização do app é necessária."; - -"IPAD_LAYOUT" = "Layout do iPad"; -"IPAD_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPad no seu iPhone/iPod atual. A reinicialização do app é necessária."; - -"IPHONE_LAYOUT" = "Layout do iPhone"; -"IPHONE_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPhone no seu iPad atual. A reinicialização do app é necessária."; - -"CAST_CONFIRM" = "Alerta de confirmação antes de transmitir (YTCastConfirm)"; -"CAST_CONFIRM_DESC" = "Mostra um alerta de confirmação antes da transmissão para evitar o sequestro acidental da TV."; -"CASTING" = "Transmissão"; -"MSG_ARE_YOU_SURE" = "Tem certeza de que deseja começar a transmitir?"; -"MSG_YES" = "Sim"; -"MSG_CANCEL" = "Cancelar"; - -"NEW_MINIPLAYER_STYLE" = "Novo estilo de barra de miniplayer (BigYTMiniPlayer)"; -"NEW_MINIPLAYER_STYLE_DESC" = "A reinicialização do app é necessária."; - -"HIDE_CAST_BUTTON" = "Ocultar o botão Transmitir"; -"HIDE_CAST_BUTTON_DESC" = "A reinicialização do app é necessária."; - -"VIDEO_PLAYER_BUTTON" = "Video Player Button"; -"VIDEO_PLAYER_BUTTON_DESC" = "Show a button in the navigation bar to open downloaded videos in the Apple player"; - -"HIDE_SPONSORBLOCK_BUTTON" = "Ocultar o botão iSponsorBlock na barra de navegação"; -"HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; - -"HIDE_HOME_TAB" = "Ocultar guia Início"; -"HIDE_HOME_TAB_DESC" = "Tenha cuidado ao ocultar todas as guias"; - -"FIX_CASTING" = "Corrigir Transmissão"; -"FIX_CASTING_DESC" = "Altera alguns sinalizadores AB para corrigir a transmissão"; - -"ENABLE_FLEX" = "Ativar FLEX"; -"ENABLE_FLEX_DESC" = "Ativa o FLEX para depuração (não recomendado). Deixe isso desligado, a menos que você saiba o que está fazendo."; - -// Version Spoofer -"APP_VERSION_SPOOFER_LITE" = "Ativar Falsificação da Versão do App (Lite)"; -"APP_VERSION_SPOOFER_LITE_DESC" = "Ative isto para usar a Falsificação de Versão (Lite) e selecione sua versão preferida abaixo. A reinicialização do app é necessária."; -"VERSION_SPOOFER_TITLE" = "Selecionar Versão Falsa"; - -// Other Localization -"APP_RESTART_DESC" = "A reinicialização do app é necessária."; -"CHANGE_APP_ICON" = "Mudar o Ícone do Aplicativo"; +// Settings +"VERSION" = "Versão do YTLitePlus: %@"; +"VERSION_CHECK" = "Toque para verificar se há atualização!"; + +"COPY_SETTINGS" = "Copiar Configurações"; +"COPY_SETTINGS_DESC" = "Copia todas as configurações atuais para a área de transferência"; +"PASTE_SETTINGS" = "Colar Configurações"; +"PASTE_SETTINGS_DESC" = "Cola as configurações da área de transferência e aplica"; +"PASTE_SETTINGS_ALERT" = "Aplicar configurações da área de transferência?"; +"EXPORT_SETTINGS" = "Exportar Configurações"; +"EXPORT_SETTINGS_DESC" = "Exporta todas as configurações atuais para um arquivo .txt"; +"IMPORT_SETTINGS" = "Importar Configurações"; +"IMPORT_SETTINGS_DESC" = "Pressione para importar as configurações (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Substituir os Botões 'Copiar Configurações' e 'Colar Configurações'"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Substitui os Botões 'Exportar Configurações' e 'Importar Configurações'"; + +"VIDEO_PLAYER" = "Reprodutor de Vídeo (Beta)"; +"VIDEO_PLAYER_DESC" = "Abra um vídeo baixado no Reprodutor de video da Apple"; + +// Player Gestures +"PLAYER_GESTURES_TOGGLE" = "Habilitar Gestos no Reprodutor de video"; +"VOLUME" = "Volume"; +"BRIGHTNESS" = "Brilho"; +"SEEK" = "Busca"; +"DISABLED" = "Desabilitado"; +"DEADZONE" = "Zona morta"; +"DEADZONE_DESC" = "Distância mínima a percorrer antes de um gesto ser reconhecido"; +"SENSITIVITY" = "Sensibilidade"; +"SENSITIVITY_DESC" = "Multiplicador em gestos de volume e brilho"; +"PLAYER_GESTURES_TITLE" = "Gestos do Reprodutor de video"; +"PLAYER_GESTURES_DESC" = "Configurar gestos panorâmicos horizontal para o player"; +"TOP_SECTION" = "Seção Superior"; +"MIDDLE_SECTION" = "Seção do Meio"; +"BOTTOM_SECTION" = "Seção Inferior"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Feedback Tátil"; + +// Video controls overlay options +"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opções de Sobreposição de Controles de Vídeo"; + +"ENABLE_SHARE_BUTTON" = "Ativar o botão 'Compartilhar'"; +"ENABLE_SHARE_BUTTON_DESC" = "Ativa o botão Compartilhar na sobreposição de controles de vídeo."; + +"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Ativar o botão 'Salvar'"; +"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Ativa o botão 'Salvar' na sobreposição de controles de vídeo."; + +"HIDE_SHADOW_OVERLAY_BUTTONS" = "Ocultar Sombras nos Botões de Sobreposição"; +"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Oculta as sombras nos botões de sobreposição Reproduzir/Pausar, Anterior, Próximo, Avançar e Retroceder."; + +"HIDE_RIGHT_PANEL" = "Ocultar o painel direito no modo de tela cheia"; +"HIDE_RIGHT_PANEL_DESC" = "A reinicialização do app é necessária."; + +"HIDE_HEATWAVES" = "Ocultar Ondas de calor"; +"HIDE_HEATWAVES_DESC" = "Oculta as Ondas de calor no player de vídeo. A reinicialização do app é necessária."; + +"DISABLE_AMBIENT_PORTRAIT" = "Desativar Iluminação cinematográfica (Retrato)"; +"DISABLE_AMBIENT_PORTRAIT_DESC" = "Desativa a iluminação ao redor do título do vídeo"; + +"DISABLE_AMBIENT_FULLSCREEN" = "Desativar Iluminação cinematográfica (Tela cheia)"; +"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Desativa a iluminação ao redor do player de vídeo"; + +"FULLSCREEN_TO_THE_RIGHT" = "Tela cheia para a direita"; +"FULLSCREEN_TO_THE_RIGHT_DESC" = "Sempre entre em tela cheia com o botão home no lado direito."; + +"SEEK_ANYWHERE" = "Gesto de Busca em qualquer lugar"; +"SEEK_ANYWHERE_DESC" = "Segure e arraste o player de vídeo para buscar. Você deve desativar o YTLite - Segurar para velocidade (Hold for speed)"; + +"ENABLE_TAP_TO_SEEK" = "Ativar Toque para Buscar"; +"ENABLE_TAP_TO_SEEK_DESC" = "Vá para qualquer lugar em um vídeo tocando uma vez na barra de busca"; + +"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Desativar gesto de puxar para tela cheia"; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Desativa o gesto de arrastar para entrar em tela cheia vertical. Aplica-se apenas a vídeos em paisagem."; + +"ALWAYS_USE_REMAINING_TIME" = "Sempre usar o tempo restante"; +"ALWAYS_USE_REMAINING_TIME_DESC" = "Altera o padrão para mostrar o tempo restante na barra do player."; + +"DISABLE_TOGGLE_TIME_REMAINING" = "Desativar alternar tempo restante"; +"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Desativa a alteração do tempo decorrido para o tempo restante. Use com outra configuração para mostrar sempre o tempo restante."; + +"DISABLE_ENGAGEMENT_OVERLAY" = "Desativar sobreposição de engajamento em tela cheia"; +"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desativa o gesto de deslizar para cima e a lista de vídeos sugeridos em tela cheia"; + +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Ocultar Visualizações de comentários sob o player"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Oculta a Prévia de comentário no botão de comentários"; + +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Ocultar mini visualização de reprodução automática"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Oculta a pequena caixa de vídeo sugerida perto do título em tela cheia"; + +"HIDE_HUD_MESSAGES" = "Ocultar Mensagens do HUD"; +"HIDE_HUD_MESSAGES_DESC" = "Exemplo: Legendas/CC ativadas/desativadas, A repetição do vídeo está ativada,..."; + +"HIDE_COLLAPSE_BUTTON" = "Ocultar Botão de Recolhimento"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Oculta o botão de seta para recolher que era exibido no canto superior esquerdo do player de vídeo."; + +"HIDE_SPEED_TOAST" = "Ocultar Toast de Velocidade"; +"HIDE_SPEED_TOAST_DESC" = "Ocultar o popup de Velocidade 2X ao segurar o player"; + + +// App settings overlay options +"APP_SETTINGS_OVERLAY_OPTIONS" = "Configurações do Aplicativo"; + +"HIDE_ACCOUNT_SECTION" = "Ocultar a sessão \"Conta\""; +"HIDE_AUTOPLAY_SECTION" = "Ocultar a sessão \"Reprodução automática\""; +"HIDE_TRYNEWFEATURES_SECTION" = "Ocultar a sessão \"Experimente novos recursos\""; +"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Ocultar a sessão \"Preferências de qualidade de vídeo\""; +"HIDE_NOTIFICATIONS_SECTION" = "Ocultar a sessão \"Notificações\""; +"HIDE_MANAGEALLHISTORY_SECTION" = "Ocultar a sessão \"Gerencie todo o histórico\""; +"HIDE_YOURDATAINYOUTUBE_SECTION" = "Ocultar a sessão \"Seus dados no YouTube\""; +"HIDE_PRIVACY_SECTION" = "Ocultar a sessão \"Privacidade\""; +"HIDE_LIVECHAT_SECTION" = "Ocultar a sessão \"Chat ao vivo\""; + +// Theme +"THEME_OPTIONS" = "Opções de Temas"; + +"OLED_DARK_THEME" = "Modo escuro OLED"; +"OLED_DARK_THEME_2" = "Modo escuro OLED"; +"OLED_DARK_THEME_DESC" = "Verdadeiro tema escuro. Pode não funcionar corretamente em alguns casos. App restart is required after you enable/disable this option."; + +"OLD_DARK_THEME" = "Antigo tema escuro"; +"OLD_DARK_THEME_DESC" = "Tema escuro do YouTube antigo (tema cinza). A reinicialização do app é necessária."; + +"DEFAULT_THEME" = "Padrão"; +"DEFAULT_THEME_DESC" = "Tema escuro padrão do YouTube. A reinicialização do app é necessária."; + +"OLED_KEYBOARD" = "Teclado OLED"; +"OLED_KEYBOARD_DESC" = "Pode não funcionar corretamente em alguns casos. A reinicialização do app é necessária."; + +"LOW_CONTRAST_MODE" = "Modo de Baixo Contraste"; +"LOW_CONTRAST_MODE_DESC" = "Esta opção terá baixo contraste dos textos e botões, assim como era a antiga interface do YouTube. A reinicialização do app é necessária."; +"LCM_SELECTOR" = "Seleção do modo de baixo contraste"; +"DEFAULT_LOWCONTRASTMODE" = "(Padrão) LowContrastMode"; +"CUSTOM_LOWCONTRASTMODE" = "(Cor Personalizada) LowContrastMode"; + +// Miscellaneous +"MISCELLANEOUS" = "Diversos"; + +"PLAYBACK_IN_FEEDS" = "Reprodução nos feeds"; +"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Sempre ativada"; +"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Somente Wi-Fi"; +"PLAYBACK_IN_FEEDS_OFF" = "Desativada"; + +"NEW_SETTINGS_UI" = "Nova Interface de Configurações"; +"NEW_SETTINGS_UI_DESC" = "Usa a nova Interface de configurações agrupadas. Pode ocultar algumas configurações"; + +"ENABLE_YT_STARTUP_ANIMATION" = "Ative a animação de inicialização do YouTube"; +"ENABLE_YT_STARTUP_ANIMATION_DESC" = ""; + +"HIDE_MODERN_INTERFACE" = "Ocultar Interface Moderna (YTNoModernUI)"; +"HIDE_MODERN_INTERFACE_DESC" = "Ative esta opção para ocultar qualquer elemento moderno adicionado pelo YouTube. Remove a iluminação cinematogrática, design arredondado e muito mais. A reinicialização do app é necessária."; + +"IPAD_LAYOUT" = "Layout do iPad"; +"IPAD_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPad no seu iPhone/iPod atual. A reinicialização do app é necessária."; + +"IPHONE_LAYOUT" = "Layout do iPhone"; +"IPHONE_LAYOUT_DESC" = "Use isso apenas se quiser ter o layout do iPhone no seu iPad atual. A reinicialização do app é necessária."; + +"CAST_CONFIRM" = "Alerta de confirmação antes de transmitir (YTCastConfirm)"; +"CAST_CONFIRM_DESC" = "Mostra um alerta de confirmação antes da transmissão para evitar o sequestro acidental da TV."; +"CASTING" = "Transmissão"; +"MSG_ARE_YOU_SURE" = "Tem certeza de que deseja começar a transmitir?"; +"MSG_YES" = "Sim"; +"MSG_CANCEL" = "Cancelar"; + +"NEW_MINIPLAYER_STYLE" = "Novo estilo de barra de miniplayer (BigYTMiniPlayer)"; +"NEW_MINIPLAYER_STYLE_DESC" = "A reinicialização do app é necessária."; + +"HIDE_CAST_BUTTON" = "Ocultar o botão Transmitir"; +"HIDE_CAST_BUTTON_DESC" = "A reinicialização do app é necessária."; + +"VIDEO_PLAYER_BUTTON" = "Botão do Reprodutor de Vídeo"; +"VIDEO_PLAYER_BUTTON_DESC" = "Mostra um botão na barra de navegação para abrir vídeos baixados no Reprodutor de video da Apple"; + +"HIDE_SPONSORBLOCK_BUTTON" = "Ocultar o botão iSponsorBlock na barra de navegação"; +"HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; + +"HIDE_HOME_TAB" = "Ocultar guia Início"; +"HIDE_HOME_TAB_DESC" = "Tenha cuidado ao ocultar todas as guias"; + +"FIX_CASTING" = "Corrigir Transmissão"; +"FIX_CASTING_DESC" = "Altera alguns sinalizadores AB para corrigir a transmissão"; + +"ENABLE_FLEX" = "Ativar FLEX"; +"ENABLE_FLEX_DESC" = "Ativa o FLEX para depuração (não recomendado). Deixe isso desligado, a menos que você saiba o que está fazendo."; + +// Version Spoofer +"APP_VERSION_SPOOFER_LITE" = "Ativar Falsificação da Versão do App (Lite)"; +"APP_VERSION_SPOOFER_LITE_DESC" = "Ative isto para usar a Falsificação de Versão (Lite) e selecione sua versão preferida abaixo. A reinicialização do app é necessária."; +"VERSION_SPOOFER_TITLE" = "Selecionar Versão Falsa"; + +// Other Localization +"APP_RESTART_DESC" = "A reinicialização do app é necessária."; +"CHANGE_APP_ICON" = "Mudar o Ícone do Aplicativo"; From 108deb8d6b1e812e7d0cac9e4c3c43a19fba8994 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 31 Aug 2024 00:47:00 +0000 Subject: [PATCH 087/102] updated submodules --- Tweaks/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/protobuf b/Tweaks/protobuf index 890dd25..e4449ba 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit 890dd25c7f6fbe9680b5467497235796bd4dcc9e +Subproject commit e4449ba24809b2043932edd0f7504dbdc0239e52 From 0d87774cd7b61a94f040ec9860c4e5db462e0a48 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 1 Sep 2024 00:56:34 +0000 Subject: [PATCH 088/102] updated submodules --- Tweaks/iSponsorBlock | 2 +- Tweaks/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tweaks/iSponsorBlock b/Tweaks/iSponsorBlock index e3b2c44..5c0dcc3 160000 --- a/Tweaks/iSponsorBlock +++ b/Tweaks/iSponsorBlock @@ -1 +1 @@ -Subproject commit e3b2c4429099699b5a508bd2aa1c074efb34d866 +Subproject commit 5c0dcc3df0eba9f1f9028e1183f41e5b6e9a6434 diff --git a/Tweaks/protobuf b/Tweaks/protobuf index e4449ba..b915e9f 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit e4449ba24809b2043932edd0f7504dbdc0239e52 +Subproject commit b915e9f44e9d979617d7738f7ddd7dd02ccd7c76 From d9a9ef556342b86c41b7bd61e45c4b545d078e60 Mon Sep 17 00:00:00 2001 From: DeciBelioS <96150975+Deci8BelioS@users.noreply.github.com> Date: Sun, 1 Sep 2024 18:41:09 +0200 Subject: [PATCH 089/102] Update Localizable.strings Spanish (#391) --- .../es.lproj/Localizable.strings | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings index d00268d..5f206cb 100644 --- a/lang/YTLitePlus.bundle/es.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/es.lproj/Localizable.strings @@ -2,37 +2,37 @@ "VERSION" = "Versión de YTLitePlus: %@"; "VERSION_CHECK" = "Pulse para comprobar si hay actualizaciones."; -"COPY_SETTINGS" = "Copy Settings"; -"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; -"PASTE_SETTINGS" = "Paste Settings"; -"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; -"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; -"EXPORT_SETTINGS" = "Export Settings"; -"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; -"IMPORT_SETTINGS" = "Import Settings"; -"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"COPY_SETTINGS" = "Copiar Configuraciones"; +"COPY_SETTINGS_DESC" = "Copiar todas las configuraciones actuales al portapapeles"; +"PASTE_SETTINGS" = "Pegar Configuraciones"; +"PASTE_SETTINGS_DESC" = "Pegar configuraciones desde el portapapeles y aplicar"; +"PASTE_SETTINGS_ALERT" = "¿Aplicar configuraciones desde el portapapeles?"; +"EXPORT_SETTINGS" = "Exportar Configuraciones"; +"EXPORT_SETTINGS_DESC" = "Exportar todas las configuraciones actuales a un archivo .txt"; +"IMPORT_SETTINGS" = "Importar Configuraciones"; +"IMPORT_SETTINGS_DESC" = "Presiona para importar configuraciones (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Reemplazar Botones de 'Copiar Configuraciones' y 'Pegar Configuraciones'"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Reemplaza los botones con 'Exportar Configuraciones' e 'Importar Configuraciones'"; -"VIDEO_PLAYER" = "Video Player (Beta)"; -"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +"VIDEO_PLAYER" = "Reproductor de vídeo (Beta)"; +"VIDEO_PLAYER_DESC" = "Abrir un vídeo descargado en el reproductor de Apple"; // 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"; -"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; +"PLAYER_GESTURES_TOGGLE" = "Habilitar Gestos del Reproductor"; +"VOLUME" = "Volumen"; +"BRIGHTNESS" = "Brillo"; +"SEEK" = "Buscar"; +"DISABLED" = "Deshabilitado"; +"DEADZONE" = "Zona Muerta"; +"DEADZONE_DESC" = "Distancia mínima a mover antes de que se reconozca un gesto"; +"SENSITIVITY" = "Sensibilidad"; +"SENSITIVITY_DESC" = "Multiplicador en gestos de volumen y brillo"; +"PLAYER_GESTURES_TITLE" = "Gestos del Reproductor"; +"PLAYER_GESTURES_DESC" = "Configura los gestos de desplazamiento horizontal para el reproductor"; +"TOP_SECTION" = "Sección Superior"; +"MIDDLE_SECTION" = "Sección Media"; +"BOTTOM_SECTION" = "Sección Inferior"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Habilitar Retroalimentación Háptica"; // Video controls overlay options "VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Opciones de superposición de controles de vídeo"; @@ -79,20 +79,20 @@ "DISABLE_ENGAGEMENT_OVERLAY" = "Desactivar la superposición de compromiso a pantalla completa"; "DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Desactivar el gesto de deslizar hacia arriba y la lista de vídeos sugeridos en pantalla completa"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Ocultar vistas previas de comentarios debajo del reproductor"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Ocultar spoilers de comentarios en el botón de comentarios"; -"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; -"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Ocultar mini vista previa de reproducción automática"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Ocultar la pequeña caja de vídeo sugerido cerca del título en pantalla completa"; "HIDE_HUD_MESSAGES" = "Ocultar mensajes HUD"; -"HIDE_HUD_MESSAGES_DESC" = "Ejemplo: CC está activado/desactivado, Vídeo en bucle está activado,..."; +"HIDE_HUD_MESSAGES_DESC" = "Ejemplo: CC está activado/desactivado, vídeo en bucle está activado,..."; -"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; -"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_COLLAPSE_BUTTON" = "Ocultar botón de colapso"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Oculta el botón de colapso en forma de flecha que se mostraba en la parte superior izquierda del reproductor de vídeo."; -"HIDE_SPEED_TOAST" = "Hide Speed Toast"; -"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; +"HIDE_SPEED_TOAST" = "Ocultar notificación de velocidad"; +"HIDE_SPEED_TOAST_DESC" = "Oculta la notificación de velocidad 2X cuando se mantiene presionado el reproductor"; // App settings overlay options "APP_SETTINGS_OVERLAY_OPTIONS" = "Opciones de superposición de los ajustes de la aplicación"; @@ -165,8 +165,8 @@ "HIDE_CAST_BUTTON" = "Ocultar botón Emitir"; "HIDE_CAST_BUTTON_DESC" = "Es necesario reiniciar la aplicación"; -"VIDEO_PLAYER_BUTTON" = "Video Player Button"; -"VIDEO_PLAYER_BUTTON_DESC" = "Show a button in the navigation bar to open downloaded videos in the Apple player"; +"VIDEO_PLAYER_BUTTON" = "Botón del reproductor de vídeo"; +"VIDEO_PLAYER_BUTTON_DESC" = "Mostrar un botón en la barra de navegación para abrir vídeo descargados en el reproductor de Apple"; "HIDE_SPONSORBLOCK_BUTTON" = "Ocultar el botón iSponsorBlock en la barra de navegación"; "HIDE_SPONSORBLOCK_BUTTON_DESC" = ""; From 2134ae02d208a734ab0794a2e6dc5028b5d13610 Mon Sep 17 00:00:00 2001 From: ChuTuanVu <148454063+ChuTuanVu@users.noreply.github.com> Date: Sun, 1 Sep 2024 23:41:20 +0700 Subject: [PATCH 090/102] Update Vietnamese localization (#392) --- .../vi.lproj/Localizable.strings | 389 +++++++----------- 1 file changed, 140 insertions(+), 249 deletions(-) diff --git a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings index 2f678de..538ba40 100644 --- a/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings +++ b/lang/YTLitePlus.bundle/vi.lproj/Localizable.strings @@ -1,299 +1,190 @@ // Settings -"VERSION" = "Phiên bản của CercubePlus: %@"; +"VERSION" = "Phiên bản YTLitePlus: %@"; "VERSION_CHECK" = "Nhấn để kiểm tra cập nhật!"; -"COPY_SETTINGS" = "Copy Settings"; -"COPY_SETTINGS_DESC" = "Copy all current settings to the clipboard"; -"PASTE_SETTINGS" = "Paste Settings"; -"PASTE_SETTINGS_DESC" = "Paste settings from clipboard and apply"; -"PASTE_SETTINGS_ALERT" = "Apply settings from clipboard?"; -"EXPORT_SETTINGS" = "Export Settings"; -"EXPORT_SETTINGS_DESC" = "Exports all current settings into a .txt file"; -"IMPORT_SETTINGS" = "Import Settings"; -"IMPORT_SETTINGS_DESC" = "Press to import settings (.txt)"; -"REPLACE_COPY_AND_PASTE_BUTTONS" = "Replace 'Copy Settings' & 'Paste Settings' Buttons"; -"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Replaces the Buttons to 'Export Settings' and 'Import Settings'"; +"COPY_SETTINGS" = "Sao chép cài đặt"; +"COPY_SETTINGS_DESC" = "Sao chép cài đặt hiện tại vào bảng nhớ tạm"; +"PASTE_SETTINGS" = "Dán cài đặt"; +"PASTE_SETTINGS_DESC" = "Dán cài đặt từ bảng nhớ tạm và áp dụng"; +"PASTE_SETTINGS_ALERT" = "Áp dụng các cài đặt?"; +"EXPORT_SETTINGS" = "Xuất cài đặt"; +"EXPORT_SETTINGS_DESC" = "Xuất tất cài đặt hiện tại vào tệp .txt"; +"IMPORT_SETTINGS" = "Nhập cài đặt"; +"IMPORT_SETTINGS_DESC" = "Nhấn để nhập cài đặt (.txt)"; +"REPLACE_COPY_AND_PASTE_BUTTONS" = "Thay thế nút 'Sao chép cài đặt' và 'Dán cài đặt'"; +"REPLACE_COPY_AND_PASTE_BUTTONS_DESC" = "Thay thế các nút thành 'Xuất cài đặt' và 'Nhập cài đặt'"; -"VIDEO_PLAYER" = "Video Player (Beta)"; -"VIDEO_PLAYER_DESC" = "Open a downloaded video in the Apple player"; +"VIDEO_PLAYER" = "Trình phát video (Beta)"; +"VIDEO_PLAYER_DESC" = "Mở video đã tải xuống trong trình phát Apple"; // 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"; -"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Enable Haptic Feedback"; - -// Video player options -"VIDEO_PLAYER_OPTIONS" = "Tùy chọn trình phát video"; - -"SNAP_TO_CHAPTER" = "Vô hiệu hóa đính vào chương"; -"SNAP_TO_CHAPTER_DESC" = "Tắt tính năng tự động chuyển sang chương khi tìm kiếm trong video. Khởi động lại ứng dụng là bắt buộc."; - -"PINCH_TO_ZOOM" = "Vô hiệu hóa chụm để thu phóng"; -"PINCH_TO_ZOOM_DESC" = "Khởi động lại ứng dụng là bắt buộc."; - -"YT_MINIPLAYER" = "Bật trình phát mini cho tất cả các video trên YouTube"; -"YT_MINIPLAYER_DESC" = "Ví dụ: video dành cho trẻ em"; +"PLAYER_GESTURES_TOGGLE" = "Bật cử chỉ trình phát"; +"VOLUME" = "Âm lượng"; +"BRIGHTNESS" = "Độ sáng"; +"SEEK" = "Tua"; +"DISABLED" = "Vô hiệu hóa"; +"DEADZONE" = "Vùng chết"; +"DEADZONE_DESC" = "Khoảng cách tối thiểu để nhận diện cử chỉ"; +"SENSITIVITY" = "Độ nhạy"; +"SENSITIVITY_DESC" = "Hệ số nhân cho cử chỉ âm lượng và độ sáng"; +"PLAYER_GESTURES_TITLE" = "Cử chỉ trình phát"; +"PLAYER_GESTURES_DESC" = "Cấu hình cử chỉ vuốt ngang cho trình phát"; +"TOP_SECTION" = "Phần trên"; +"MIDDLE_SECTION" = "Phần giữa"; +"BOTTOM_SECTION" = "Phần dưới"; +"PLAYER_GESTURES_HAPTIC_FEEDBACK" = "Bật phản hồi xúc giác"; // Video controls overlay options -"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển video"; +"VIDEO_CONTROLS_OVERLAY_OPTIONS" = "Lớp phủ video"; -"HIDE_CHANNEL_WATERMARK" = "Ẩn hình mờ kênh"; -"HIDE_CHANNEL_WATERMARK_DESC" = "Ẩn hình mờ của kênh trong lớp phủ điều khiển video. Khởi động lại ứng dụng là bắt buộc."; +"ENABLE_SHARE_BUTTON" = "Bật nút chia sẻ"; +"ENABLE_SHARE_BUTTON_DESC" = "Thêm nút chia sẻ trong trình phát video."; -"RED_PROGRESS_BAR" = "Thanh tiến trình màu đỏ"; -"RED_PROGRESS_BAR_DESC" = "Mang lại thanh tiến trình màu đỏ. Khởi động lại ứng dụng là bắt buộc."; +"ENABLE_SAVE_TO_PLAYLIST_BUTTON" = "Bật nút 'Lưu vào danh sách phát'"; +"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC" = "Thêm nút 'Lưu vào danh sách phát' trong trình phát video."; -"DONT_EAT_MY_CONTENT" = "Ngăn Notch/Đảo trên nội dung video 2:1 (DontEatMyContent)"; -"DONT_EAT_MY_CONTENT_DESC" = "Ngăn notch/Dynamic Island nghiền ngẫm nội dung video 2:1 trên YouTube. Khởi động lại ứng dụng là bắt buộc."; +"HIDE_SHADOW_OVERLAY_BUTTONS" = "Ẩn bóng các nút"; +"HIDE_SHADOW_OVERLAY_BUTTONS_DESC" = "Ẩn bóng các nút Phát/Tạm dừng, Trước/Tiếp theo, Tua tới/Tua lại."; + +"HIDE_RIGHT_PANEL" = "Ẩn bảng bên phải ở chế độ toàn màn hình"; +"HIDE_RIGHT_PANEL_DESC" = "Điều nãy sẽ khiến bạn không thể xem nội dung mô tả, bình luận, v.v ở chế độ toàn màn hình. Cần khởi động lại ứng dụng."; "HIDE_HEATWAVES" = "Ẩn sóng nhiệt"; -"HIDE_HEATWAVES_DESC" = "Ẩn Sóng nhiệt trong trình phát video. Khởi động lại ứng dụng là bắt buộc."; +"HIDE_HEATWAVES_DESC" = "Ẩn sóng nhiệt khỏi trình phát video. Cần khởi động lại ứng dụng."; -"DISABLE_AMBIENT_PORTRAIT" = "Disable Ambient Mode (Portrait)"; -"DISABLE_AMBIENT_PORTRAIT_DESC" = "Disable lighting surrounding video title"; +"DISABLE_AMBIENT_PORTRAIT" = "Tắt chế độ môi trường (Chân dung)"; +"DISABLE_AMBIENT_PORTRAIT_DESC" = "Tắt ánh sáng xung quanh tiêu đề video"; -"DISABLE_AMBIENT_FULLSCREEN" = "Disable Ambient Mode (Fullscreen)"; -"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Disable lighting surrouding video player"; +"DISABLE_AMBIENT_FULLSCREEN" = "Tắt chế độ môi trường (Toàn màn hình)"; +"DISABLE_AMBIENT_FULLSCREEN_DESC" = "Tắt ánh sáng xung quanh trình phát video"; -"FULLSCREEN_TO_THE_RIGHT" = "Fullscreen to the Right"; -"FULLSCREEN_TO_THE_RIGHT_DESC" = "Always enter fullscreen with home button on the right side."; +"FULLSCREEN_TO_THE_RIGHT" = "Toàn màn hình bên phải"; +"FULLSCREEN_TO_THE_RIGHT_DESC" = "Luôn vào chế độ toàn màn hình với nút home ở bên phải."; -"SEEK_ANYWHERE" = "Seek Anywhere Gesture"; -"SEEK_ANYWHERE_DESC" = "Hold and drag on the video player to seek. You must disable YTLite - Hold to speed"; +"SEEK_ANYWHERE" = "Tua ở mọi nơi"; +"SEEK_ANYWHERE_DESC" = "Giữ và kéo bất kỳ đâu trên trình phát video để tua. Bạn phải tắt tùy chỉnh YTLite - Giữ để tua"; -"ENABLE_TAP_TO_SEEK" = "Enable Tap To Seek"; -"ENABLE_TAP_TO_SEEK_DESC" = "Jump to anywhere in a video by single-tapping the seek bar"; +"ENABLE_TAP_TO_SEEK" = "Nhấn để tua"; +"ENABLE_TAP_TO_SEEK_DESC" = "Nhấn một lần vào thanh tua để tua đến bất kỳ vị trí nào trong video"; -"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Disable pull-to-fullscreen gesture"; -"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Disable the drag gesture to enter vertical fullscreen. Only applies to landscape videos."; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE" = "Tắt cử chỉ kéo để vào toàn màn hình"; +"DISABLE_PULL_TO_FULLSCREEN_GESTURE_DESC" = "Tắt cử chỉ kéo để vào toàn màn hình dọc. Chỉ áp dụng cho video ngang."; -"ALWAYS_USE_REMAINING_TIME" = "Always use remaining time"; -"ALWAYS_USE_REMAINING_TIME_DESC" = "Change the default to show time remaining in the player bar."; +"ALWAYS_USE_REMAINING_TIME" = "Hiển thị thời gian còn lại"; +"ALWAYS_USE_REMAINING_TIME_DESC" = "Luôn hiển thị thời gian còn lại trên thanh trình phát video."; -"DISABLE_TOGGLE_TIME_REMAINING" = "Disable toggle time remaining"; -"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Disables changing time elapsed to time remaining. Use with other setting to always show remaining time."; +"DISABLE_TOGGLE_TIME_REMAINING" = "Tắt chuyển đổi thời gian còn lại"; +"DISABLE_TOGGLE_TIME_REMAINING_DESC" = "Tắt chức năng chuyển đổi từ thời gian đã phát sang thời gian còn lại. Sử dụng với cài đặt khác để luôn hiển thị thời gian còn lại."; -"DISABLE_ENGAGEMENT_OVERLAY" = "Disable fullscreen engagement overlay"; -"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Disable the swipe-up gesture and suggested videos list in fullscreen"; +"DISABLE_ENGAGEMENT_OVERLAY" = "Tắt lớp phủ tương tác toàn màn hình"; +"DISABLE_ENGAGEMENT_OVERLAY_DESC" = "Tắt cử chỉ vuốt lên để xem video gợi ý ở chế độ toàn màn hình"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Hide Comment previews under player"; -"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Hide comment spoiler in comments button"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER" = "Ẩn bản xem trước bình luận dưới trình phát"; +"HIDE_COMMENT_PREVIEWS_UNDER_PLAYER_DESC" = "Ngăn tiết lộ nội dung bình luận trong nút bình luận"; -"HIDE_AUTOPLAY_MINI_PREVIEW" = "Hide autoplay mini preview"; -"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Hide the small suggested video box near the title in fullscreen"; +"HIDE_AUTOPLAY_MINI_PREVIEW" = "Ẩn bản xem trước tự động phát nhỏ"; +"HIDE_AUTOPLAY_MINI_PREVIEW_DESC" = "Ẩn hộp gợi ý video nhỏ gần tiêu đề ở chế độ toàn màn hình"; "HIDE_HUD_MESSAGES" = "Ẩn thông báo HUD"; -"HIDE_HUD_MESSAGES_DESC" = "Ví dụ: Đã bật/tắt phụ đề, Tính năng phát video lặp lại đang bật,..."; +"HIDE_HUD_MESSAGES_DESC" = "Ẩn các thông báo xuất hiện khi thực hiện các hành động (ví dụ: bật/tắt CC)"; -"HIDE_COLLAPSE_BUTTON" = "Hide Collapse Button"; -"HIDE_COLLAPSE_BUTTON_DESC" = "Hides the Arrow Collapse Button that was shown in the Top Left of the Video Player."; +"HIDE_COLLAPSE_BUTTON" = "Ẩn nút thu gọn"; +"HIDE_COLLAPSE_BUTTON_DESC" = "Ẩn nút thu gọn (mũi tên) xuất hiện ở góc trái trên của trình phát Video."; -"HIDE_SPEED_TOAST" = "Hide Speed Toast"; -"HIDE_SPEED_TOAST_DESC" = "Hide the 2X Speed popup when holding the player"; +"HIDE_SPEED_TOAST" = "Ẩn thông báo tốc độ"; +"HIDE_SPEED_TOAST_DESC" = "Ẩn thông báo tốc độ 2X khi giữ trình phát video"; -// Shorts controls overlay options -"SHORTS_CONTROLS_OVERLAY_OPTIONS" = "Tùy chọn lớp phủ điều khiển quần short"; +// App settings overlay options +"APP_SETTINGS_OVERLAY_OPTIONS" = "Lớp phủ cài đặt"; -"HIDE_SHORTS_CHANNEL_AVATAR" = "Ẩn hình đại diện của kênh Shorts"; -"HIDE_SHORTS_CHANNEL_AVATAR_DESC" = ""; - -"HIDE_SHORTS_LIKE_BUTTON" = "Ẩn nút thích Shorts"; -"HIDE_SHORTS_LIKE_BUTTON_DESC" = ""; - -"HIDE_SHORTS_DISLIKE_BUTTON" = "Ẩn nút không thích Shorts"; -"HIDE_SHORTS_DISLIKE_BUTTON_DESC" = ""; - -"HIDE_SHORTS_COMMENT_BUTTON" = "Ẩn nút bình luận Shorts"; -"HIDE_SHORTS_COMMENT_BUTTON_DESC" = ""; - -"HIDE_SHORTS_REMIX_BUTTON" = "Ẩn nút phối lại video ngắn"; -"HIDE_SHORTS_REMIX_BUTTON_DESC" = ""; - -"HIDE_SHORTS_SHARE_BUTTON" = "Ẩn nút chia sẻ Shorts"; -"HIDE_SHORTS_SHARE_BUTTON_DESC" = ""; - -"HIDE_SUBSCRIPTIONS" = "Hide Subscriptions button"; -"HIDE_SUBSCRIPTIONS_DESC" = "Hide Subscriptions button which shows up when paused."; - -"HIDE_SUPER_THANKS" = "Ẩn biểu ngữ Mua hàng Vô cùng cảm ơn"; -"HIDE_SUPER_THANKS_DESC" = "Ẩn biểu ngữ Mua hàng Vô cùng cảm ơn trong Shorts."; - -"DISABLE_RESUME_TO_SHORTS" = "Vô hiệu hóa sơ yếu lý lịch cho Shorts"; -"DISABLE_RESUME_TO_SHORTS_DESC" = "Nếu bạn đóng YouTube khi đang xem các video ngắn, thì các video ngắn đó sẽ không tự động phát vào lần tới khi bạn mở YouTube."; +"HIDE_ACCOUNT_SECTION" = "Ẩn cài đặt \"Chuyển đổi tài khoản\""; +"HIDE_AUTOPLAY_SECTION" = "Ẩn cài đặt \"Tự động phát\""; +"HIDE_TRYNEWFEATURES_SECTION" = "Ẩn cài đặt \"Thử các tính năng mới\""; +"HIDE_VIDEOQUALITYPREFERENCES_SECTION" = "Ẩn cài đặt \"Lựa chọn ưu tiên về chất lượng video\""; +"HIDE_NOTIFICATIONS_SECTION" = "Ẩn cài đặt \"Thông báo\""; +"HIDE_MANAGEALLHISTORY_SECTION" = "Ẩn cài đặt \"Quản lý toàn bộ nhật ký hoạt động\""; +"HIDE_YOURDATAINYOUTUBE_SECTION" = "Ẩn cài đặt \"Dữ liệu của bạn trong YouTube\""; +"HIDE_PRIVACY_SECTION" = "Ẩn cài đặt \"Quyền riêng tư\""; +"HIDE_LIVECHAT_SECTION" = "Ẩn cài đặt \"Trò chuyện trực tiếp\""; // Theme -"THEME_OPTIONS" = "Tùy chọn chủ đề"; +"THEME_OPTIONS" = "Tùy chọn giao diện"; -"OLED_DARK_THEME" = "Chủ đề tối OLED (Thử nghiệm)"; -"OLED_DARK_THEME_2" = "chủ đề tối OLED"; -"OLED_DARK_THEME_DESC" = "Chủ đề tối thực sự. Có thể không hoạt động chính xác trong một số trường hợp. Cần phải khởi động lại ứng dụng sau khi bạn bật/tắt tùy chọn này."; +"OLED_DARK_THEME" = "Giao diện tối OLED"; +"OLED_DARK_THEME_2" = "Giao diện tối OLED"; +"OLED_DARK_THEME_DESC" = "Giao diện tối thực sự. Có thể không hoạt động đúng trong một số trường hợp. Cần khởi động lại ứng dụng sau khi bạn bật/tắt tùy chọn này."; -"OLD_DARK_THEME" = "Chủ đề tối cũ"; -"OLD_DARK_THEME_DESC" = "Chủ đề tối cũ của YouTube (chủ đề màu xám). Khởi động lại ứng dụng là bắt buộc."; +"OLD_DARK_THEME" = "Giao diện tối cũ"; +"OLD_DARK_THEME_DESC" = "Giao diện tối cũ của YouTube (giao diện xám). Cần khởi động lại ứng dụng."; -"DEFAULT_THEME" = "Vỡ nợ"; -"DEFAULT_THEME_DESC" = "Chủ đề (er) tối mặc định của YouTube. Khởi động lại ứng dụng là bắt buộc."; +"DEFAULT_THEME" = "Mặc định"; +"DEFAULT_THEME_DESC" = "Giao diện mặc định của YouTube. Cần khởi động lại ứng dụng."; -"OLED_KEYBOARD" = "Bàn phím OLED (Thử nghiệm)"; -"OLED_KEYBOARD_DESC" = "Có thể không hoạt động chính xác trong một số trường hợp. Khởi động lại ứng dụng là bắt buộc."; - -// Customization Options -"CUSTOMIZATION_OPTIONS" = "Tùy chọn tùy chỉnh"; - -"HIDE_MODERN_INTERFACE" = "Ẩn giao diện hiện đại (YTNoModernUI)"; -"HIDE_MODERN_INTERFACE_DESC" = "Bật tính năng này để ẩn mọi Thành phần hiện đại do YouTube thêm vào. Loại bỏ Chế độ môi trường xung quanh, Thiết kế bo tròn và hơn thế nữa. Khởi động lại ứng dụng là bắt buộc."; - -"HIDE_YOUTUBE_LOGO" = "Ẩn biểu trưng YouTube"; -"HIDE_YOUTUBE_LOGO_DESC" = "thao tác này sẽ Ẩn Logo YouTube ở trên cùng bên trái của Giao diện. Khởi động lại ứng dụng là bắt buộc."; - -"HIDE_TAB_BAR_LABELS" = "Ẩn Nhãn trong Thanh Tab"; -"HIDE_TAB_BAR_LABELS_DESC" = "điều này sẽ Ẩn tất cả các nhãn trong Thanh tab. Khởi động lại ứng dụng là bắt buộc."; +"OLED_KEYBOARD" = "Bàn phím OLED"; +"OLED_KEYBOARD_DESC" = "Có thể hoạt động không đúng trong một số trường hợp. Cần khởi động lại ứng dụng."; "LOW_CONTRAST_MODE" = "Chế độ tương phản thấp"; -"LOW_CONTRAST_MODE_DESC" = "điều này sẽ tạo ra các văn bản và nút có độ tương phản thấp giống như Giao diện YouTube cũ. Khởi động lại ứng dụng là bắt buộc."; - -"RED_UI" = "Màu đỏ"; -"RED_UI_DESC" = "Giao diện người dùng màu đỏ (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"BLUE_UI" = "Giao diện người dùng màu xanh lam"; -"BLUE_UI_DESC" = "Giao diện người dùng màu xanh lam (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"GREEN_UI" = "Giao diện xanh"; -"GREEN_UI_DESC" = "Giao diện người dùng xanh (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"YELLOW_UI" = "Giao diện người dùng màu vàng"; -"YELLOW_UI_DESC" = "Giao diện người dùng màu vàng (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"ORANGE_UI" = "Giao diện người dùng màu cam"; -"ORANGE_UI_DESC" = "Giao diện người dùng màu cam (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"PURPLE_UI" = "Giao diện người dùng màu tím"; -"PURPLE_UI_DESC" = "Giao diện người dùng màu tím (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; - -"PINK_UI" = "Giao diện người dùng màu hồng"; -"PINK_UI_DESC" = "Giao diện người dùng màu hồng (tắt mọi màu giao diện người dùng khác) Khởi động lại ứng dụng là bắt buộc."; +"LOW_CONTRAST_MODE_DESC" = "Tùy chọn này sẽ giảm tương phản của văn bản và nút giống như giao diện YouTube cũ. Cần khởi động lại ứng dụng."; +"LCM_SELECTOR" = "Chọn chế độ tương phản thấp"; +"DEFAULT_LOWCONTRASTMODE" = "(Mặc định) Chế độ tương phản thấp"; +"CUSTOM_LOWCONTRASTMODE" = "(Màu tùy chỉnh) Chế độ tương phản thấp"; // Miscellaneous -"MISCELLANEOUS" = "Điều khoản khác"; +"MISCELLANEOUS" = "Tùy chọn khác"; -"CAST_CONFIRM" = "Xác nhận cảnh báo trước khi truyền (YTCastConfirm)"; -"CAST_CONFIRM_DESC" = "Hiển thị cảnh báo xác nhận trước khi truyền để tránh vô tình chiếm quyền điều khiển TV."; -"CASTING" = "Đúc"; -"MSG_ARE_YOU_SURE" = "Bạn có chắc chắn muốn bắt đầu truyền không?"; -"MSG_YES" = "Đúng"; -"MSG_CANCEL" = "Hủy bỏ"; +"PLAYBACK_IN_FEEDS" = "Phát trong các trang danh sách video"; +"PLAYBACK_IN_FEEDS_ALWAYS_ON" = "Luôn bật"; +"PLAYBACK_IN_FEEDS_WIFI_ONLY" = "Chỉ Wi-Fi"; +"PLAYBACK_IN_FEEDS_OFF" = "Tắt"; -"DISABLE_HINTS" = "Tắt gợi ý"; -"DISABLE_HINTS_DESC" = "Tắt gợi ý tính năng từ YouTube thường hiển thị khi ứng dụng mới được cài đặt."; +"NEW_SETTINGS_UI" = "Giao diện cài đặt mới"; +"NEW_SETTINGS_UI_DESC" = "Nhóm các giao diện cài đặt. Một số cài đặt có thể bị ẩn"; -"ENABLE_FLEX" = "Kích hoạt FLEX"; -"ENABLE_FLEX_DESC" = "Bật FLEX để gỡ lỗi (không khuyến nghị). Bỏ qua điều này trừ khi bạn biết những gì bạn đang làm."; +"ENABLE_YT_STARTUP_ANIMATION" = "Hoạt ảnh khởi động YouTube"; +"ENABLE_YT_STARTUP_ANIMATION_DESC" = "Hiển thị hoạt ảnh khi mở YouTube"; -"FIX_GOOGLE_SIGNIN" = "Sửa lỗi Đăng nhập bằng Google (chỉ dành cho người dùng TrollStore)"; -"FIX_GOOGLE_SIGNIN_DESC" = "Chỉ bật tùy chọn này khi bạn không thể đăng nhập bằng tài khoản Google của mình và ứng dụng đã được cài đặt qua TrollStore. Nếu bạn có thể đăng nhập bình thường, hãy tắt nó đi. Khởi động lại ứng dụng là bắt buộc."; - -"HIDE_CHIP_BAR" = "Ẩn thanh trên"; -"HIDE_CHIP_BAR_DESC" = "Ẩn thanh trên trong nguồn cấp dữ liệu Trang chủ (Xu hướng, Âm nhạc, Trò chơi...) và nguồn cấp dữ liệu Đăng ký (Tất cả video, Tiếp tục xem...)."; - -"NEW_MINIPLAYER_STYLE" = "Phong cách thanh người chơi mini mới (BigYTMiniPlayer)"; -"NEW_MINIPLAYER_STYLE_DESC" = ""; - -"REPLACE_PREVIOUS_NEXT_BUTTON" = "Thay nút Previous và Next"; -"REPLACE_PREVIOUS_NEXT_BUTTON_DESC" = "Thay thế nút Trước và Tiếp theo bằng nút Tua đi và Tua lại. Khởi động lại ứng dụng là bắt buộc."; - -"HIDE_PREVIOUS_AND_NEXT_BUTTON" = "Ẩn nút Trước và Tiếp theo"; -"HIDE_PREVIOUS_AND_NEXT_BUTTON_DESC" = "Ẩn nút Trước đó và Tiếp theo trong lớp phủ điều khiển video."; - -"HIDE_SHORTS_VIDEOS" = "Ẩn video ngắn"; -"HIDE_SHORTS_VIDEOS_DESC" = "Ẩn video ngắn trong Trang chủ, được đề xuất..."; - -"HIDE_CERCUBE_BUTTON" = "Ẩn nút Cercube trong thanh Điều hướng"; -"HIDE_CERCUBE_BUTTON_DESC" = ""; - -"HIDE_CERCUBE_PIP_BUTTON" = "Ẩn nút PiP của Cercube"; -"HIDE_CERCUBE_PIP_BUTTON_DESC" = "Ẩn nút PiP của Cercube trong lớp phủ điều khiển video."; - -"HIDE_CERCUBE_DOWNLOAD_BUTTON" = "Ẩn nút Tải xuống của Cercube"; -"HIDE_CERCUBE_DOWNLOAD_BUTTON_DESC" = "Tùy chọn ẩn nút Tải xuống của Cercube đã được bật theo mặc định. bởi vì hiện tại bạn không thể tải xuống bất kỳ thứ gì vì Máy chủ tải xuống của Cercube đã biến mất."; - -"HIDE_CAST_BUTTON" = "Ẩn nút Truyền"; -"HIDE_CAST_BUTTON_DESC" = "Khởi động lại ứng dụng là bắt buộc."; - -"VIDEO_PLAYER_BUTTON" = "Video Player Button"; -"VIDEO_PLAYER_BUTTON_DESC" = "Show a button in the navigation bar to open downloaded videos in the Apple player"; - -"HIDE_HOVER_CARD" = "Ẩn thẻ di chuột trên Màn hình kết thúc (YTNoHoverCards)"; -"HIDE_HOVER_CARD_DESC" = "Ẩn màn hình kết thúc (hình thu nhỏ) của người tạo ở cuối video."; - -"HIDE_RIGHT_PANEL" = "Ẩn bảng điều khiển bên phải ở chế độ toàn màn hình"; -"HIDE_RIGHT_PANEL_DESC" = "Khởi động lại ứng dụng là bắt buộc."; - -"HIDE_SUBTITLES_BUTTON" = "Ẩn nút phụ đề"; -"HIDE_SUBTITLES_BUTTON_DESC" = "Ẩn nút Phụ đề trong lớp phủ điều khiển video."; - -"HIDE_AUTOPLAY_SWITCH" = "Ẩn công tắc Tự động phát"; -"HIDE_AUTOPLAY_SWITCH_DESC" = "Ẩn công tắc Tự động phát trong lớp phủ điều khiển video."; - -"AUTO_FULLSCREEN" = "Tự động toàn màn hình(YTAutoFullScreen)"; -"AUTO_FULLSCREEN_DESC" = "Tự động phát video ở chế độ toàn màn hình."; - -"HIDE_HUD_MESSAGES" = "Ẩn tin nhắn HUD"; -"HIDE_HUD_MESSAGES_DESC" = "Ví dụ: Bật/tắt CC, Bật vòng lặp video,..."; - -"HIDE_PAID_PROMOTION_CARDS" = "Ẩn thẻ Khuyến mại trả phí"; -"HIDE_PAID_PROMOTION_CARDS_DESC" = "Ẩn thẻ Bao gồm quảng cáo trả phí trong một số video."; - -"HIDE_NOTIFICATION_BUTTON" = "Ẩn nút Thông báo trong thanh Điều hướng"; -"HIDE_NOTIFICATION_BUTTON_DESC" = ""; - -"YT_RE_EXPLORE" = "Thay thế tab Shorts bằng tab Khám phá (YTReExplore)"; -"YT_RE_EXPLORE_DESC" = "Khởi động lại ứng dụng là bắt buộc."; +"HIDE_MODERN_INTERFACE" = "Giao diện YouTube cũ"; +"HIDE_MODERN_INTERFACE_DESC" = "Đưa giao diện cũ của YouTube trở lại từ phiên bản v17.38.10. Loại bỏ một số yếu tố bo tròn, chế độ môi trường, và các tính năng hiện đại khác. Cần khởi động lại ứng dụng."; "IPAD_LAYOUT" = "Bố cục iPad"; -"IPAD_LAYOUT_DESC" = "Chỉ sử dụng tùy chọn này nếu bạn muốn tải Bố cục iPad trên iPhone/iPod hiện tại của mình. Khởi động lại ứng dụng là bắt buộc."; +"IPAD_LAYOUT_DESC" = "Chỉ sử dụng nếu muốn có bố cục iPad trên iPhone/iPod của mình. Cần khởi động lại ứng dụng."; "IPHONE_LAYOUT" = "Bố cục iPhone"; -"IPHONE_LAYOUT_DESC" = "Chỉ sử dụng tùy chọn này nếu bạn muốn tải Bố cục iPhone trên iPad hiện tại của mình. Khởi động lại ứng dụng là bắt buộc."; +"IPHONE_LAYOUT_DESC" = "Chỉ sử dụng nếu muốn có bố cục iPhone trên iPad của mình. Cần khởi động lại ứng dụng."; -"CHANGE_APP_ICON" = "Change App Icon"; +"CAST_CONFIRM" = "Xác nhận trước khi truyền"; +"CAST_CONFIRM_DESC" = "Hiển thị thông báo xác nhận trước khi truyền."; +"CASTING" = "Truyền"; +"MSG_ARE_YOU_SURE" = "Bạn có chắc chắn muốn bắt đầu truyền không?"; +"MSG_YES" = "Có"; +"MSG_CANCEL" = "Không"; -// Newly added strings -"APP_RESTART_DESC": "Mô tả khi khởi động lại ứng dụng", -"CUSTOM_LOWCONTRASTMODE": "Chế độ độ tương phản thấp tùy chỉnh", -"APP_VERSION_SPOOFER_LITE": "Phiên bản giả lập ứng dụng nhẹ", -"PLAYBACK_IN_FEEDS_OFF": "Tắt phát trong các trang danh sách video", -"PLAYBACK_IN_FEEDS": "Phát trong các trang danh sách video", -"ENABLE_SHARE_BUTTON_DESC": "Mô tả nút chia sẻ", -"ENABLE_SAVE_TO_PLAYLIST_BUTTON": "Bật nút lưu vào danh sách phát", -"LCM_SELECTOR": "Trình chọn chế độ độ tương phản thấp", -"NEW_SETTINGS_UI_DESC": "Mô tả giao diện cài đặt mới", -"VERSION_SPOOFER_TITLE": "Tiêu đề giả lập phiên bản", -"HIDE_SPONSORBLOCK_BUTTON": "Ẩn nút SponsorBlock", -"ENABLE_SHARE_BUTTON": "Bật nút chia sẻ", -"ENABLE_SAVE_TO_PLAYLIST_BUTTON_DESC": "Mô tả nút lưu vào danh sách phát", -"HIDE_SHADOW_OVERLAY_BUTTONS": "Ẩn các nút lớp phủ bóng", -"APP_VERSION_SPOOFER_LITE_DESC": "Mô tả phiên bản giả lập ứng dụng nhẹ", -"DEFAULT_LOWCONTRASTMODE": "Chế độ độ tương phản thấp mặc định", -"APP_SETTINGS_OVERLAY_OPTIONS": "Tùy chọn lớp phủ cài đặt ứng dụng", -"HIDE_HOME_TAB_DESC": "Mô tả ẩn tab Trang chủ", -"PLAYBACK_IN_FEEDS_ALWAYS_ON": "Luôn bật phát trong các trang danh sách video", -"FIX_CASTING": "Sửa lỗi truyền phát", -"FIX_CASTING_DESC": "Mô tả sửa lỗi truyền phát", -"PLAYBACK_IN_FEEDS_WIFI_ONLY": "Phát trong các trang danh sách video chỉ qua WiFi", -"NEW_MINIPLAYER_STYLE_DESC": "Mô tả kiểu trình phát nhỏ mới", -"NEW_SETTINGS_UI": "Giao diện cài đặt mới", -"HIDE_HOME_TAB": "Ẩn tab Trang chủ", -"HIDE_SHADOW_OVERLAY_BUTTONS_DESC": "Mô tả ẩn các nút lớp phủ bóng", -"ENABLE_YT_STARTUP_ANIMATION": "Bật hoạt ảnh khởi động YouTube" +"NEW_MINIPLAYER_STYLE" = Trình phát thu nhỏ kiểu mới"; +"NEW_MINIPLAYER_STYLE_DESC" = "Thay thế trình phát thu nhỏ mặc định thành (BigYTMiniPlayer). Cần khởi động lại ứng dụng."; + +"HIDE_CAST_BUTTON" = "Ẩn nút truyền"; +"HIDE_CAST_BUTTON_DESC" = "Cần khởi động lại ứng dụng."; + +"VIDEO_PLAYER_BUTTON" = "Nút Trình phát video"; +"VIDEO_PLAYER_BUTTON_DESC" = "Hiển thị nút trong thanh điều hướng để mở video đã tải xuống trong trình phát Apple"; + +"HIDE_SPONSORBLOCK_BUTTON" = "Ẩn nút iSponsorBlock"; +"HIDE_SPONSORBLOCK_BUTTON_DESC" = "Ẩn cài đặt iSponsorBlock trên thanh điều hướng"; + +"HIDE_HOME_TAB" = "Ẩn tab Trang chủ"; +"HIDE_HOME_TAB_DESC" = "Hãy cẩn thận khi ẩn tất cả các tab"; + +"FIX_CASTING" = "Sửa truyền"; +"FIX_CASTING_DESC" = "Thay đổi một số cờ AB để sửa truyền"; + +"ENABLE_FLEX" = "Bật FLEX"; +"ENABLE_FLEX_DESC" = "Bật FLEX để gỡ lỗi (không khuyến khích). Để tùy chọn này tắt trừ khi bạn biết rõ bạn đang làm gì."; + +// Version Spoofer +"APP_VERSION_SPOOFER_LITE" = "Giả mạo phiên bản ứng dụng (Lite)"; +"APP_VERSION_SPOOFER_LITE_DESC" = "Bật tính năng này để làm giả phiên bản YouTube (Lite). Chọn phiên bản bạn ưa thích bên dưới. Cần khởi động lại ứng dụng."; +"VERSION_SPOOFER_TITLE" = "Chọn phiên bản giả mạo"; + +// Other Localization +"APP_RESTART_DESC" = "Cần khởi động lại ứng dụng."; +"CHANGE_APP_ICON" = "Đổi biểu tượng ứng dụng"; From 810aca2f162b13f764c20e58e8b122dacf474ebd Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 11:06:07 -0700 Subject: [PATCH 091/102] Disable warning popup --- YTLitePlus.h | 4 ++++ YTLitePlus.xm | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/YTLitePlus.h b/YTLitePlus.h index 247af9e..1c3ead2 100644 --- a/YTLitePlus.h +++ b/YTLitePlus.h @@ -130,6 +130,10 @@ typedef NS_ENUM(NSUInteger, GestureSection) { @property (nonatomic, assign, readwrite) BOOL enableSnapToChapter; @end +// Hide YouTube Plus incompatibility warning popup - @bhackel +@interface HelperVC : UIViewController +@end + // Hide Autoplay Mini Preview - @bhackel @interface YTAutonavPreviewView : UIView @end diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 093b70d..aa8b0bc 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -110,12 +110,8 @@ BOOL isSelf() { } %end -# pragma mark - Hide SponsorBlock Button +// Hide SponsorBlock Button in navigation bar %hook YTRightNavigationButtons -- (void)didMoveToWindow { - %orig; -} - - (void)layoutSubviews { %orig; if (IsEnabled(@"hideSponsorBlockButton_enabled")) { @@ -174,6 +170,18 @@ BOOL isSelf() { %end %end +// Disable YouTube Plus incompatibility warning popup - @bhackel +%hook HelperVC +- (void)viewDidLoad { + %orig; + // Check if it responds to the selector riskButtonTapped + if ([self respondsToSelector:@selector(riskButtonTapped)]) { + // Call the selector riskButtonTapped + [self performSelector:@selector(riskButtonTapped)]; + } +} +%end + // A/B flags %hook YTColdConfig From a3ac8e973584860a0ed643a52e710ae1973726b1 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 11:19:09 -0700 Subject: [PATCH 092/102] Default disable iSponsorBlock --- YTLitePlus.xm | 54 ++++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index aa8b0bc..4dd9a90 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -1319,36 +1319,28 @@ NSInteger pageStyle = 0; // Change the default value of some options NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; - if (![allKeys containsObject:@"RYD-ENABLED"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"RYD-ENABLED"]; - } - if (![allKeys containsObject:@"YouPiPEnabled"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"YouPiPEnabled"]; - } - if (![allKeys containsObject:@"newSettingsUI_enabled"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"newSettingsUI_enabled"]; - } - 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"]; - } - if (![allKeys containsObject:@"playerGesturesHapticFeedback_enabled"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"playerGesturesHapticFeedback_enabled"]; + if (![allKeys containsObject:@"YTLPDidPerformFirstRunSetup"]) { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"YTLPDidPerformFirstRunSetup"]; + // Set iSponsorBlock to default disabled + NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; + NSString *settingsPath = [documentsDirectory stringByAppendingPathComponent:@"iSponsorBlock.plist"]; + NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + NSDictionary *existingSettings = [NSDictionary dictionaryWithContentsOfFile:settingsPath]; + [settings addEntriesFromDictionary:existingSettings]; + [settings setObject:@(NO) forKey:@"enabled"]; + [settings writeToFile:settingsPath atomically:YES]; + // Set miscellaneous YTLitePlus features to enabled + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"RYD-ENABLED"]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"YouPiPEnabled"]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"newSettingsUI_enabled"]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"fixCasting_enabled"]; + // Default gestures as volume, brightness, seek + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeVolume forKey:@"playerGestureTopSelection"]; + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeBrightness forKey:@"playerGestureMiddleSelection"]; + [[NSUserDefaults standardUserDefaults] setInteger:GestureModeSeek forKey:@"playerGestureBottomSelection"]; + // Default gestures options + [[NSUserDefaults standardUserDefaults] setFloat:20.0 forKey:@"playerGesturesDeadzone"]; + [[NSUserDefaults standardUserDefaults] setFloat:1.0 forKey:@"playerGesturesSensitivity"]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"playerGesturesHapticFeedback_enabled"]; } } From 861a9fd30b2a32e34af08122af72f8a0c3ed28e0 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:27:07 -0700 Subject: [PATCH 093/102] Remove OLED live chat fix --- YTLitePlus.xm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 4dd9a90..aa57691 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -586,16 +586,6 @@ BOOL isTabSelected = NO; [self setNeedsLayout]; [self removeFromSuperview]; } - - // Live chat OLED dark mode - @bhackel - CGFloat alpha; - if ([[%c(YTLUserDefaults) standardUserDefaults] boolForKey:@"oledTheme"] // YTLite OLED Theme - && [self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"] // Live chat text message - && [self.backgroundColor getWhite:nil alpha:&alpha] // Check if color is grayscale and get alpha - && alpha != 0.0) // Ignore shorts live chat - { - self.backgroundColor = [UIColor blackColor]; - } } %end From d4f8a41ff2920e146d00e2fa731506c4875738b3 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:10:51 -0700 Subject: [PATCH 094/102] Fix smoothing for player gestures --- YTLitePlus.xm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index aa57691..bfc82c8 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -689,7 +689,7 @@ BOOL isTabSelected = NO; // Variable used to smooth out the X translation static CGFloat smoothedTranslationX = 0; // Constant for the filter constant to change responsiveness - static const CGFloat filterConstant = 0.1; + // static const CGFloat filterConstant = 0.1; // 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 @@ -756,10 +756,10 @@ BOOL isTabSelected = NO; }; // Helper function to smooth out the X translation - CGFloat (^applyLowPassFilter)(CGFloat) = ^(CGFloat newTranslation) { - smoothedTranslationX = filterConstant * newTranslation + (1 - filterConstant) * smoothedTranslationX; - return smoothedTranslationX; - }; + // CGFloat (^applyLowPassFilter)(CGFloat) = ^(CGFloat newTranslation) { + // smoothedTranslationX = filterConstant * newTranslation + (1 - filterConstant) * smoothedTranslationX; + // return smoothedTranslationX; + // }; /***** Helper functions for running the selected gesture *****/ // Helper function to run any setup for the selected gesture mode @@ -923,7 +923,7 @@ BOOL isTabSelected = NO; // Adjust the X translation based on the value hit after exiting the deadzone adjustedTranslationX = translation.x - deadzoneStartingXTranslation; // Smooth the translation value - adjustedTranslationX = applyLowPassFilter(adjustedTranslationX); + // adjustedTranslationX = applyLowPassFilter(adjustedTranslationX); // Pass the adjusted translation to the selected gesture switch (gestureSection) { case GestureSectionTop: From c73cd63db47b0f9d0d1d3133cf35788853ccce7d Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 12:50:04 -0700 Subject: [PATCH 095/102] Cancel gesture after 1 second of inactivity --- YTLitePlus.xm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index bfc82c8..ae9a152 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -870,6 +870,13 @@ BOOL isTabSelected = NO; } // Deactive the activity flag isValidHorizontalPan = NO; + // Cancel this gesture if it has not activated after 1 second + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + 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, From e66f68ebc676e3685d8c30d314701a7754e54197 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 2 Sep 2024 00:49:42 +0000 Subject: [PATCH 096/102] updated submodules --- Tweaks/YTABConfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tweaks/YTABConfig b/Tweaks/YTABConfig index 184f678..a22ef4d 160000 --- a/Tweaks/YTABConfig +++ b/Tweaks/YTABConfig @@ -1 +1 @@ -Subproject commit 184f67837f48b3efd3c35ac88eb0d56f5e735d36 +Subproject commit a22ef4deb929c6622069290bb340d21b280f300e From 9d62ce75ce58b5ee4bf01022b7342bb679bf2b73 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 14:45:20 -0700 Subject: [PATCH 097/102] Fix bugs --- Source/Settings.xm | 2 +- YTLitePlus.xm | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Source/Settings.xm b/Source/Settings.xm index 418d6f4..864275b 100644 --- a/Source/Settings.xm +++ b/Source/Settings.xm @@ -396,7 +396,7 @@ static const NSInteger YTLiteSection = 789; // Toggle for haptic feedback BASIC_SWITCH(LOC(@"PLAYER_GESTURES_HAPTIC_FEEDBACK"), nil, @"playerGesturesHapticFeedback_enabled"), ]; - YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Player Gestures (Beta)") 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]; return YES; }]; diff --git a/YTLitePlus.xm b/YTLitePlus.xm index ae9a152..766395a 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -172,14 +172,17 @@ BOOL isSelf() { // Disable YouTube Plus incompatibility warning popup - @bhackel %hook HelperVC -- (void)viewDidLoad { - %orig; - // Check if it responds to the selector riskButtonTapped - if ([self respondsToSelector:@selector(riskButtonTapped)]) { - // Call the selector riskButtonTapped - [self performSelector:@selector(riskButtonTapped)]; - } + +- (void)viewWillAppear:(BOOL)animated { + %orig; // Call the original implementation + + // // Hide the view before it appears + // self.view.hidden = YES; + + // // Optionally, you can remove the view from the superview to ensure it's gone + // [self.view removeFromSuperview]; } + %end @@ -1240,6 +1243,8 @@ NSInteger pageStyle = 0; %init; // Access YouGroupSettings methods dlopen([[NSString stringWithFormat:@"%@/Frameworks/YouGroupSettings.dylib", [[NSBundle mainBundle] bundlePath]] UTF8String], RTLD_LAZY); + // Access YouTube Plus methods + dlopen([[NSString stringWithFormat:@"%@/Frameworks/YTLite.dylib", [[NSBundle mainBundle] bundlePath]] UTF8String], RTLD_LAZY); if (IsEnabled(@"hideCastButton_enabled")) { %init(gHideCastButton); @@ -1322,8 +1327,6 @@ NSInteger pageStyle = 0; NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *settingsPath = [documentsDirectory stringByAppendingPathComponent:@"iSponsorBlock.plist"]; NSMutableDictionary *settings = [NSMutableDictionary dictionary]; - NSDictionary *existingSettings = [NSDictionary dictionaryWithContentsOfFile:settingsPath]; - [settings addEntriesFromDictionary:existingSettings]; [settings setObject:@(NO) forKey:@"enabled"]; [settings writeToFile:settingsPath atomically:YES]; // Set miscellaneous YTLitePlus features to enabled From df0be8c66eb36872d2306d12ce51e7d355b5409a Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 19:31:28 -0700 Subject: [PATCH 098/102] Change hiding method --- YTLitePlus.xm | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 766395a..517fdd4 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -171,21 +171,53 @@ BOOL isSelf() { %end // Disable YouTube Plus incompatibility warning popup - @bhackel -%hook HelperVC +%hook UIView -- (void)viewWillAppear:(BOOL)animated { - %orig; // Call the original implementation +- (void)willMoveToWindow:(UIWindow *)newWindow { + UIResponder *responder = self; + while (responder) { + responder = [responder nextResponder]; + if ([responder isKindOfClass:NSClassFromString(@"HelperVC")]) { + // View belongs to HelperVC, now proceed with getting the UIButton - // // Hide the view before it appears - // self.view.hidden = YES; + if ([self.subviews count] > 4 && [[self.subviews objectAtIndex:4] isKindOfClass:[UIButton class]]) { + UIButton *button = [self.subviews objectAtIndex:4]; - // // Optionally, you can remove the view from the superview to ensure it's gone - // [self.view removeFromSuperview]; + // Access the _targetActions ivar using KVC (Key-Value Coding) + NSArray *targetActions = [button valueForKey:@"_targetActions"]; + + if ([targetActions count] > 0) { + id controlTargetAction = [targetActions objectAtIndex:0]; + + // Use KVC to get the _actionHandler (which is of type UIAction) + UIAction *actionHandler = [controlTargetAction valueForKey:@"_actionHandler"]; + + if (actionHandler && [actionHandler isKindOfClass:[UIAction class]]) { + // Access the handler property of UIAction + void (^handlerBlock)(void) = [actionHandler valueForKey:@"handler"]; + + // Invoke the handler block + if (handlerBlock) { + handlerBlock(); // Call the block + } + } + } + } + + // Prevent the view from being added to the window + [self removeFromSuperview]; + return; // Exit early to prevent further processing + } + } + + %orig(newWindow); // Call the original method if the view doesn't belong to HelperVC } %end + + // A/B flags %hook YTColdConfig - (BOOL)respectDeviceCaptionSetting { return NO; } // YouRememberCaption: https://poomsmart.github.io/repo/depictions/youremembercaption.html From d6c995b1be172143f82985a78284a931e9bc2eae Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Sun, 1 Sep 2024 22:43:42 -0700 Subject: [PATCH 099/102] Improve hiding warning --- Makefile | 2 +- YTLitePlus.xm | 142 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 3046c62..ebb5990 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ SUBPROJECTS += Tweaks/Alderis Tweaks/iSponsorBlock Tweaks/YTUHD Tweaks/YouPiP Tw include $(THEOS_MAKE_PATH)/aggregate.mk YTLITE_PATH = Tweaks/YTLite -YTLITE_VERSION := $(shell wget -qO- "https://github.com/dayanch96/YTLite/releases/latest" | grep -o -E '/tag/v[^"]+' | head -n 1 | sed 's/\/tag\/v//') +YTLITE_VERSION := 5.0.1 YTLITE_DEB = $(YTLITE_PATH)/com.dvntm.ytlite_$(YTLITE_VERSION)_iphoneos-arm64.deb YTLITE_DYLIB = $(YTLITE_PATH)/var/jb/Library/MobileSubstrate/DynamicLibraries/YTLite.dylib YTLITE_BUNDLE = $(YTLITE_PATH)/var/jb/Library/Application\ Support/YTLite.bundle diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 517fdd4..07e99b2 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -171,52 +171,124 @@ BOOL isSelf() { %end // Disable YouTube Plus incompatibility warning popup - @bhackel -%hook UIView +%hook HelperVC +- (void)viewDidAppear:(BOOL)animated { + %orig; + // Start from the current view and traverse up to find the UITransitionView + UIView *currentView = self.view; + while (currentView != nil && ![NSStringFromClass([currentView class]) isEqualToString:@"UITransitionView"]) { + currentView = currentView.superview; + } + // If UITransitionView is found, hide it + if (currentView) { + NSLog(@"bhackel Found and hiding UITransitionView: %@", currentView); + currentView.hidden = YES; + currentView.userInteractionEnabled = NO; + // Print the subview structure for debugging + NSLog(@"bhackel Subviews of UITransitionView: %@", currentView.subviews); + NSLog(@"bhackel Superview of UITransitionView: %@", currentView.superview); + [currentView removeFromSuperview]; + } +} +%end -- (void)willMoveToWindow:(UIWindow *)newWindow { - UIResponder *responder = self; +%hook UIWindow + +- (void)addSubview:(UIView *)view { + // Check if the view's view controller is HelperVC using the responder chain + UIResponder *responder = view.nextResponder; while (responder) { - responder = [responder nextResponder]; - if ([responder isKindOfClass:NSClassFromString(@"HelperVC")]) { - // View belongs to HelperVC, now proceed with getting the UIButton - - if ([self.subviews count] > 4 && [[self.subviews objectAtIndex:4] isKindOfClass:[UIButton class]]) { - UIButton *button = [self.subviews objectAtIndex:4]; - - // Access the _targetActions ivar using KVC (Key-Value Coding) - NSArray *targetActions = [button valueForKey:@"_targetActions"]; - - if ([targetActions count] > 0) { - id controlTargetAction = [targetActions objectAtIndex:0]; - - // Use KVC to get the _actionHandler (which is of type UIAction) - UIAction *actionHandler = [controlTargetAction valueForKey:@"_actionHandler"]; - - if (actionHandler && [actionHandler isKindOfClass:[UIAction class]]) { - // Access the handler property of UIAction - void (^handlerBlock)(void) = [actionHandler valueForKey:@"handler"]; - - // Invoke the handler block - if (handlerBlock) { - handlerBlock(); // Call the block - } - } - } - } - - // Prevent the view from being added to the window - [self removeFromSuperview]; - return; // Exit early to prevent further processing + if ([responder isKindOfClass:[UIViewController class]] && + [NSStringFromClass([responder class]) isEqualToString:@"HelperVC"]) { + // Block the view from being added to the window + NSLog(@"bhackel Blocked HelperVC's view from being added to UIWindow"); + return; } + responder = [responder nextResponder]; } - %orig(newWindow); // Call the original method if the view doesn't belong to HelperVC + // Call the original method for other views + %orig(view); +} + +- (void)setRootViewController:(UIViewController *)rootViewController { + // Check if the rootViewController is HelperVC + if ([NSStringFromClass([rootViewController class]) isEqualToString:@"HelperVC"]) { + // Block setting HelperVC as the root view controller + NSLog(@"bhackel Blocked HelperVC from being set as UIWindow's root view controller"); + return; + } + + // Call the original method for other view controllers + %orig(rootViewController); +} + +%end + + +%hook UIViewController + +- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { + // Check if the view controller being presented is HelperVC using string comparison + if ([NSStringFromClass([viewControllerToPresent class]) isEqualToString:@"HelperVC"]) { + // Block the presentation by not calling the original method + NSLog(@"bhackel Blocked presentation of HelperVC"); + return; + } + + // Call the original method for other view controllers + %orig(viewControllerToPresent, flag, completion); } %end +%hook UIView + +// - (void)layoutSubviews { +// // Check if the view's view controller is HelperVC +// UIResponder *responder = self; +// while (responder) { +// responder = [responder nextResponder]; +// if ([responder isKindOfClass:[UIViewController class]]) { +// if ([NSStringFromClass([responder class]) isEqualToString:@"HelperVC"] +// && self.hidden == NO) { +// // If it's HelperVC, neutralize the view +// NSLog(@"bhackel Neutralizing HelperVC"); +// self.bounds = CGRectZero; +// self.hidden = YES; +// self.userInteractionEnabled = NO; +// // [self removeFromSuperview]; +// // Go ahead and set its superview to also be hidden +// UIView *superview = self.superview; +// if (superview) { +// superview.hidden = YES; +// superview.userInteractionEnabled = NO; +// } +// break; +// } +// } +// } + +// %orig; // Call the original method +// } + +- (void)didMoveToSuperview { + %orig; + + // Consolidate the log statements into one + NSLog(@"bhackel UIView added to hierarchy: %@ | View class: %@ | Frame: %@ | Background Color: %@ | Alpha: %f", + self, + NSStringFromClass([self class]), + NSStringFromCGRect(self.frame), + self.backgroundColor, + self.alpha); +} + + + +%end // A/B flags %hook YTColdConfig From 5b554ecc0aaa675f956aa2f561ce830291584b64 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 3 Sep 2024 00:47:07 +0000 Subject: [PATCH 100/102] updated submodules --- Tweaks/YTHeaders | 2 +- Tweaks/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tweaks/YTHeaders b/Tweaks/YTHeaders index a642767..cbe3d5c 160000 --- a/Tweaks/YTHeaders +++ b/Tweaks/YTHeaders @@ -1 +1 @@ -Subproject commit a64276723da57312c6a8e24bf73060810f64604a +Subproject commit cbe3d5c384ad0e0b61d44ec1ebf23211b4baa2bb diff --git a/Tweaks/protobuf b/Tweaks/protobuf index b915e9f..6ed0b9f 160000 --- a/Tweaks/protobuf +++ b/Tweaks/protobuf @@ -1 +1 @@ -Subproject commit b915e9f44e9d979617d7738f7ddd7dd02ccd7c76 +Subproject commit 6ed0b9f28d28127f0394cf70cb543a3b32de0ed2 From 7674805f756adca06a2861e6b1462ae33829fe98 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 2 Sep 2024 15:40:12 -0700 Subject: [PATCH 101/102] ee --- YTLitePlus.xm | 154 ++++++++++++++++++-------------------------------- 1 file changed, 55 insertions(+), 99 deletions(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 07e99b2..39c0a7d 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -171,123 +171,79 @@ BOOL isSelf() { %end // Disable YouTube Plus incompatibility warning popup - @bhackel -%hook HelperVC -- (void)viewDidAppear:(BOOL)animated { - %orig; - // Start from the current view and traverse up to find the UITransitionView - UIView *currentView = self.view; - while (currentView != nil && ![NSStringFromClass([currentView class]) isEqualToString:@"UITransitionView"]) { - currentView = currentView.superview; - } - // If UITransitionView is found, hide it - if (currentView) { - NSLog(@"bhackel Found and hiding UITransitionView: %@", currentView); - currentView.hidden = YES; - currentView.userInteractionEnabled = NO; - // Print the subview structure for debugging - NSLog(@"bhackel Subviews of UITransitionView: %@", currentView.subviews); - NSLog(@"bhackel Superview of UITransitionView: %@", currentView.superview); - [currentView removeFromSuperview]; - } -} -%end - -%hook UIWindow - -- (void)addSubview:(UIView *)view { - // Check if the view's view controller is HelperVC using the responder chain - UIResponder *responder = view.nextResponder; - while (responder) { - if ([responder isKindOfClass:[UIViewController class]] && - [NSStringFromClass([responder class]) isEqualToString:@"HelperVC"]) { - // Block the view from being added to the window - NSLog(@"bhackel Blocked HelperVC's view from being added to UIWindow"); - return; - } - responder = [responder nextResponder]; - } - - // Call the original method for other views - %orig(view); -} - -- (void)setRootViewController:(UIViewController *)rootViewController { - // Check if the rootViewController is HelperVC - if ([NSStringFromClass([rootViewController class]) isEqualToString:@"HelperVC"]) { - // Block setting HelperVC as the root view controller - NSLog(@"bhackel Blocked HelperVC from being set as UIWindow's root view controller"); - return; - } - - // Call the original method for other view controllers - %orig(rootViewController); -} - -%end - - %hook UIViewController - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { - // Check if the view controller being presented is HelperVC using string comparison if ([NSStringFromClass([viewControllerToPresent class]) isEqualToString:@"HelperVC"]) { - // Block the presentation by not calling the original method - NSLog(@"bhackel Blocked presentation of HelperVC"); - return; + // show a toast + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Bypassing Popup"] animated:YES]; + // look for UIWindows of the sus type and hide them + NSArray *windows = [UIApplication sharedApplication].windows; + for (UIWindow *window in windows) { + // Check the class name of the window + if ([NSStringFromClass([window class]) isEqualToString:@"YTMainWindow"]) { + NSLog(@"bhackel Skipping UIWindow with class YTMainWindow: %@", window); + window.userInteractionEnabled = YES; + continue; + } + NSLog(@"bhackel Yeeting UIWindow %@", window); + window.hidden = YES; + window.userInteractionEnabled = NO; + } } - // Call the original method for other view controllers %orig(viewControllerToPresent, flag, completion); } %end - %hook UIView +- (void)willMoveToWindow:(UIWindow *)newWindow { + // yeet yeet + UIResponder *responder = self; + while (responder) { + responder = [responder nextResponder]; + if ([responder isKindOfClass:NSClassFromString(@"HelperVC")]) { + // View belongs to HelperVC, now proceed with getting the UIButton + NSLog(@"bhackel Found HelperVC (1/5): %@", responder); -// - (void)layoutSubviews { -// // Check if the view's view controller is HelperVC -// UIResponder *responder = self; -// while (responder) { -// responder = [responder nextResponder]; -// if ([responder isKindOfClass:[UIViewController class]]) { -// if ([NSStringFromClass([responder class]) isEqualToString:@"HelperVC"] -// && self.hidden == NO) { -// // If it's HelperVC, neutralize the view -// NSLog(@"bhackel Neutralizing HelperVC"); -// self.bounds = CGRectZero; -// self.hidden = YES; -// self.userInteractionEnabled = NO; -// // [self removeFromSuperview]; -// // Go ahead and set its superview to also be hidden -// UIView *superview = self.superview; -// if (superview) { -// superview.hidden = YES; -// superview.userInteractionEnabled = NO; -// } -// break; -// } -// } -// } + if ([self.subviews count] > 4 && [[self.subviews objectAtIndex:4] isKindOfClass:[UIButton class]]) { + NSLog(@"bhackel Found UIButton (2/5): %@", [self.subviews objectAtIndex:4]); + UIButton *button = [self.subviews objectAtIndex:4]; -// %orig; // Call the original method -// } + // Access the _targetActions ivar using KVC (Key-Value Coding) + NSArray *targetActions = [button valueForKey:@"_targetActions"]; -- (void)didMoveToSuperview { - %orig; + if ([targetActions count] > 0) { + NSLog(@"bhackel Found targetActions (3/5): %@", targetActions); + id controlTargetAction = [targetActions objectAtIndex:0]; - // Consolidate the log statements into one - NSLog(@"bhackel UIView added to hierarchy: %@ | View class: %@ | Frame: %@ | Background Color: %@ | Alpha: %f", - self, - NSStringFromClass([self class]), - NSStringFromCGRect(self.frame), - self.backgroundColor, - self.alpha); + // Use KVC to get the _actionHandler (which is of type UIAction) + UIAction *actionHandler = [controlTargetAction valueForKey:@"_actionHandler"]; + + if (actionHandler && [actionHandler isKindOfClass:[UIAction class]]) { + NSLog(@"bhackel Found actionHandler (4/5): %@", actionHandler); + // Access the handler property of UIAction + void (^handlerBlock)(void) = [actionHandler valueForKey:@"handler"]; + + // Invoke the handler block + if (handlerBlock) { + NSLog(@"bhackel Found handlerBlock (5/5): %@", handlerBlock); + handlerBlock(); // Call the block + } + } + } + } + + // Prevent the view from being added to the window + [self removeFromSuperview]; + return; // Exit early to prevent further processing + } + } + + %orig(newWindow); // Call the original method if the view doesn't belong to HelperVC } - - - %end // A/B flags From 55494e2e91cd12017939a7426ee8045be0a46b92 Mon Sep 17 00:00:00 2001 From: Bryce Hackel <34104885+bhackel@users.noreply.github.com> Date: Mon, 2 Sep 2024 20:27:38 -0700 Subject: [PATCH 102/102] coding on my phone --- YTLitePlus.xm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YTLitePlus.xm b/YTLitePlus.xm index 39c0a7d..9670a34 100644 --- a/YTLitePlus.xm +++ b/YTLitePlus.xm @@ -176,7 +176,7 @@ BOOL isSelf() { - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { if ([NSStringFromClass([viewControllerToPresent class]) isEqualToString:@"HelperVC"]) { // show a toast - [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Bypassing Popup"] animated:YES]; + [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:@"Bypassing Popup"]]; // look for UIWindows of the sus type and hide them NSArray *windows = [UIApplication sharedApplication].windows; for (UIWindow *window in windows) {