diff --git a/Localizations/uYouPlus.bundle/AppIcons/2013/2013@2x.png b/Localizations/uYouPlus.bundle/AppIcons/2013/2013@2x.png
new file mode 100644
index 0000000000..2a755c24dc
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/2013/2013@2x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/2013/2013@3x.png b/Localizations/uYouPlus.bundle/AppIcons/2013/2013@3x.png
new file mode 100644
index 0000000000..40e9950c73
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/2013/2013@3x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@2x.png b/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@2x.png
new file mode 100644
index 0000000000..ca248ad7de
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@2x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@3x.png b/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@3x.png
new file mode 100644
index 0000000000..ef77a45bc3
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/2017_Gold/2017_Gold@3x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@2x.png b/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@2x.png
new file mode 100644
index 0000000000..15aed68189
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@2x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@3x.png b/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@3x.png
new file mode 100644
index 0000000000..1a37a4958e
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/Gold/Gold@3x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@2x.png b/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@2x.png
new file mode 100644
index 0000000000..54858bafd4
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@2x.png differ
diff --git a/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@3x.png b/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@3x.png
new file mode 100644
index 0000000000..61b8670a12
Binary files /dev/null and b/Localizations/uYouPlus.bundle/AppIcons/Shorts/Shorts@3x.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/explore_24pt.png b/Localizations/uYouPlus.bundle/UI/explore_24pt.png
new file mode 100644
index 0000000000..eae709a406
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/explore_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/explore_selected_24pt.png b/Localizations/uYouPlus.bundle/UI/explore_selected_24pt.png
new file mode 100644
index 0000000000..2a699fb154
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/explore_selected_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/home_24pt.png b/Localizations/uYouPlus.bundle/UI/home_24pt.png
new file mode 100644
index 0000000000..c67a4e0a04
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/home_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/home_selected_24pt.png b/Localizations/uYouPlus.bundle/UI/home_selected_24pt.png
new file mode 100644
index 0000000000..2ad001cea8
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/home_selected_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/notifications_24pt.png b/Localizations/uYouPlus.bundle/UI/notifications_24pt.png
new file mode 100644
index 0000000000..fe5ae23074
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/notifications_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/notifications_selected_24pt.png b/Localizations/uYouPlus.bundle/UI/notifications_selected_24pt.png
new file mode 100644
index 0000000000..b1ed4c9f5c
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/notifications_selected_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/subscriptions_24pt.png b/Localizations/uYouPlus.bundle/UI/subscriptions_24pt.png
new file mode 100644
index 0000000000..8bc36876a8
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/subscriptions_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/subscriptions_selected_24pt.png b/Localizations/uYouPlus.bundle/UI/subscriptions_selected_24pt.png
new file mode 100644
index 0000000000..69f1059962
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/subscriptions_selected_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_bar_graph_box_vertical_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_bar_graph_box_vertical_24pt.png
new file mode 100644
index 0000000000..1dce28fd76
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_bar_graph_box_vertical_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_clapperboard_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_clapperboard_24pt.png
new file mode 100644
index 0000000000..a86e37d472
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_clapperboard_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_download_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_download_24pt.png
new file mode 100644
index 0000000000..79f0123a2f
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_download_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_gear_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_gear_24pt.png
new file mode 100644
index 0000000000..f11c8b3797
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_gear_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_my_videos_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_my_videos_24pt.png
new file mode 100644
index 0000000000..59ec1224bc
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_my_videos_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_question_circle_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_question_circle_24pt.png
new file mode 100644
index 0000000000..d6568b867c
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_question_circle_24pt.png differ
diff --git a/Localizations/uYouPlus.bundle/UI/yt_outline_search_24pt.png b/Localizations/uYouPlus.bundle/UI/yt_outline_search_24pt.png
new file mode 100644
index 0000000000..4932327b39
Binary files /dev/null and b/Localizations/uYouPlus.bundle/UI/yt_outline_search_24pt.png differ
diff --git a/Makefile b/Makefile
index 604b19eb15..f089ea2c89 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-export TARGET = iphone:clang:16.4:14.0
+export TARGET = iphone:clang:16.5:14.0
export ARCHS = arm64
export libcolorpicker_ARCHS = arm64
diff --git a/README.md b/README.md
index df6fbf10e8..6fa61145ba 100644
--- a/README.md
+++ b/README.md
@@ -40,8 +40,6 @@
[![Wiki](https://img.shields.io/badge/Wiki-blue?style=flat)](#wiki)
# Credits
-- Special thanks to all the developers who have worked on uYouPlus/uYouEnhanced!
-
@@ -337,14 +344,29 @@ or [qnblackcat/Building - Wiki](https://github.com/qnblackcat/uYouPlus/wiki/Buil
See [Installation - Wiki](https://github.com/qnblackcat/uYouPlus/wiki/Installation).
# Support the developers
-- [**MiRO92**](https://twitter.com/miro92): https://github.com/MiRO92/uYou-for-YouTube#support
-- [**PoomSmart**](https://github.com/PoomSmart): https://poomsmart.github.io
-- [**level3tjg**](https://twitter.com/level3tjg): https://ko-fi.com/level3tjg
-- [**BandarHL**](https://twitter.com/bandarhl): https://www.paypal.com/paypalme/BandarHL
-- [**julioverne**](https://twitter.com/ijulioverne): https://www.patreon.com/julioverne
-- [**Galactic-dev**](https://twitter.com/dev_galactic):
- - Paypal: https://www.paypal.com/paypalme/DBrett684
- - Venmo: https://venmo.com/u/DavidBrett
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Wiki
@@ -371,9 +393,9 @@ https://github.com/Balackburn/YTLitePlus/releases
- YTLitePlus does not cause your device to overheat, unlike uYouEnhanced.
-**Cons**
+- YTLitePlus provides faster video & audio downloading than uYouPlus/uYouEnhanced.
-- No custom video downloading feature in YTLitePlus.
+**Cons**
- Video quality on WiFi option is not available in YTLitePlus.
diff --git a/Sources/AppIconOptionsController.m b/Sources/AppIconOptionsController.m
index 1de53edf9a..d09c3698f9 100644
--- a/Sources/AppIconOptionsController.m
+++ b/Sources/AppIconOptionsController.m
@@ -24,8 +24,6 @@ - (void)viewDidLoad {
self.tableView.delegate = self;
[self.view addSubview:self.tableView];
- self.appIcons = @[@"White", @"YTLitePlus", @"Blue", @"Outline", @"2012", @"2013", @"2007", @"Black", @"Oreo", @"uYou", @"2012_Cyan", @"uYouPlus"];
-
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
NSBundle *backIcon = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"uYouPlus" ofType:@"bundle"]];
UIImage *backImage = [UIImage imageNamed:@"Back.png" inBundle:backIcon compatibleWithTraitCollection:nil];
@@ -72,18 +70,22 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
- NSString *iconName = self.appIcons[indexPath.row];
- cell.textLabel.text = iconName;
-
- UIImage *iconImage = [UIImage imageNamed:iconName];
- cell.imageView.image = [self createRoundedImage:iconImage size:CGSizeMake(40, 40)];
-
+ NSString *iconPath = self.appIcons[indexPath.row];
+ cell.textLabel.text = [iconPath.lastPathComponent stringByDeletingPathExtension];
+
+ UIImage *iconImage = [UIImage imageWithContentsOfFile:iconPath];
+ cell.imageView.image = iconImage;
+ cell.imageView.layer.cornerRadius = 10.0;
+ cell.imageView.clipsToBounds = YES;
+ cell.imageView.frame = CGRectMake(10, 10, 40, 40);
+ cell.textLabel.frame = CGRectMake(60, 10, self.view.frame.size.width - 70, 40);
+
if (indexPath.row == self.selectedIconIndex) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
-
+
return cell;
}
@@ -95,6 +97,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
}
- (void)resetIcon {
+ NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
+ NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
+ [infoDict removeObjectForKey:@"ALTAppIcon"];
+ [infoDict writeToFile:plistPath atomically:YES];
+
[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error resetting icon: %@", error.localizedDescription);
@@ -102,7 +109,9 @@ - (void)resetIcon {
} else {
NSLog(@"Icon reset successfully");
[self showAlertWithTitle:@"Success" message:@"Icon reset successfully"];
- [self.tableView reloadData];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.tableView reloadData];
+ });
}
}];
}
@@ -112,55 +121,50 @@ - (void)saveIcon {
NSLog(@"Alternate icons are not supported on this device.");
return;
}
-
- NSString *iconName = self.appIcons[self.selectedIconIndex];
-
- NSString *path = [[NSBundle mainBundle] pathForResource:@"uYouPlus" ofType:@"bundle"];
- NSBundle *bundle = [NSBundle bundleWithPath:path];
- NSString *imagePath = [bundle pathForResource:iconName ofType:@"png"];
- UIImage *iconImage = [UIImage imageWithContentsOfFile:imagePath];
-
- if (!iconImage) {
- NSLog(@"Failed to load custom icon image");
- return;
- }
-
- UIImage *roundedIconImage = [self createRoundedImage:iconImage size:CGSizeMake(120, 120)]; // Adjust size as needed
-
- NSData *imageData = UIImagePNGRepresentation(roundedIconImage);
- NSString *newIconPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@_custom", iconName] ofType:@"png"];
- [imageData writeToFile:newIconPath atomically:YES];
-
- [[UIApplication sharedApplication] setAlternateIconName:[NSString stringWithFormat:@"%@_custom", iconName] completionHandler:^(NSError * _Nullable error) {
- if (error) {
- NSLog(@"Error setting alternate icon: %@", error.localizedDescription);
- [self showAlertWithTitle:@"Error" message:@"Failed to set alternate icon"];
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ NSString *selectedIcon = self.selectedIconIndex >= 0 ? self.appIcons[self.selectedIconIndex] : nil;
+ if (selectedIcon) {
+ NSString *iconName = [selectedIcon.lastPathComponent stringByDeletingPathExtension];
+
+ NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
+ NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithContentsOfFile:plistPath];
+ [infoDict setObject:iconName forKey:@"ALTAppIcon"];
+ [infoDict writeToFile:plistPath atomically:YES];
+
+ [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
+ if (error) {
+ NSLog(@"Error setting alternate icon: %@", error.localizedDescription);
+ [self showAlertWithTitle:@"Error" message:@"Failed to set alternate icon"];
+ } else {
+ NSLog(@"Alternate icon set successfully");
+ [self showAlertWithTitle:@"Success" message:@"Alternate icon set successfully"];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.tableView reloadData];
+ });
+ }
+ }];
} else {
- NSLog(@"Alternate icon set successfully");
- [self showAlertWithTitle:@"Success" message:@"Alternate icon set successfully"];
- [self.tableView reloadData];
+ NSLog(@"Selected icon path is nil");
}
- }];
+ });
}
-- (UIImage *)createRoundedImage:(UIImage *)image size:(CGSize)size {
+- (UIImage *)resizeImage:(UIImage *)image toSize:(CGSize)size {
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
- UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:size.width * 0.1]; // Adjust the corner radius as needed
- [path addClip];
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
- UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
+ UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
- return roundedImage;
+ return resizedImage;
}
-- (UIImage *)resizeImage:(UIImage *)image newSize:(CGSize)newSize { // Back Button
+- (UIImage *)resizeImage:(UIImage *)image newSize:(CGSize)newSize {
UIGraphicsBeginImageContextWithOptions(newSize, NO, [UIScreen mainScreen].scale);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
- }
+}
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
dispatch_async(dispatch_get_main_queue(), ^{
diff --git a/Sources/uYouPlus.h b/Sources/uYouPlus.h
index 96cf63a69d..ff041701ad 100644
--- a/Sources/uYouPlus.h
+++ b/Sources/uYouPlus.h
@@ -1,53 +1,48 @@
#import
-#import
-#import
#import
-#import
+#import
#import
-#import
-#import
+#import
+#import
#import
-
-#import "uYouPlusThemes.h" // Hide "Buy Super Thanks" banner (_ASDisplayView)
-#import // Activate FLEX
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
#import
#import
#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import
#import
-#import
-#import
-#import
+#import
+#import
+#import
+#import
+#import
+#import
#import
-#import // Fixes uYou crash when trying to play video (#1422)
-
-// Hide buttons under the video player by @PoomSmart
-#import
-#import
-#import
-
-// YouTube-X
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
#import
+#import
+#import
+#import
#import
-#import
+#import
+#import
+#import
+#import "uYouPlusThemes.h" // uYouPlus Themes
#define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil]
#define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k]
@@ -58,12 +53,8 @@
#define LOWCONTRASTMODE_CUTOFF_VERSION @"17.38.10" // LowContrastMode (v17.33.2-17.38.10)
// Always show remaining time in video player - @bhackel
-@interface YTPlayerBarController : NSObject
-@property(nonatomic, strong) YTInlinePlayerBarContainerView *playerBar;
-@end
-@interface YTInlinePlayerBarContainerView (uYouEnhanced)
-@property(nonatomic, assign) BOOL shouldDisplayTimeRemaining;
-@end
+// Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTPlayerBarController.h
+// Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTInlinePlayerBarContainerView.h
// IAmYouTube
@interface SSOConfiguration : NSObject
@@ -90,7 +81,7 @@
@end
// YTTapToSeek - https://github.com/bhackel/YTTapToSeek
-// Header has been moved to https://github.com/arichornlover/YouTubeHeader/blob/main/YTMainAppVideoPlayerOverlayViewController.h
+// Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTMainAppVideoPlayerOverlayViewController.h
// Enable Premium logo - @bhackel
@interface YTITopbarLogoRenderer : NSObject
@@ -136,12 +127,13 @@
@end
// Disable Pull to Full for landscape videos - @bhackel
-@interface YTWatchPullToFullController : NSObject
-@property(nonatomic, strong) YTWatchViewController *playerViewSource;
-@end
+// Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTWatchPullToFullController.h
+
+// Fullscreen to the Right (uYouEnhanced Version) - @arichornlover
@interface YTWatchViewController (uYouEnhanced)
-@property(nonatomic, strong) YTWatchPullToFullController *pullToFullController;
-- (NSUInteger)allowedFullScreenOrientations;
+- (UIInterfaceOrientationMask) supportedInterfaceOrientations;
+- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;
+- (void)forceRightFullscreenOrientation;
@end
// uYouPlus
@@ -191,12 +183,16 @@
// Buttons
@interface YTRightNavigationButtons : UIView
- (id)_viewControllerForAncestor;
-@property(readonly, nonatomic) YTQTMButton *searchButton;
-@property(readonly, nonatomic) YTQTMButton *notificationButton;
-@property(strong, nonatomic) YTQTMButton *sponsorBlockButton;
-@property(strong, nonatomic) YTQTMButton *uYouPlusButton;
+@property (readonly, nonatomic) NSArray *dynamicButtons;
+@property (readonly, nonatomic) NSArray *visibleButtons;
+@property (readonly, nonatomic) NSArray *buttons;
+@property (readonly, nonatomic) YTQTMButton *searchButton;
+@property (readonly, nonatomic) YTQTMButton *notificationButton;
+@property (strong, nonatomic) YTQTMButton *sponsorBlockButton;
+@property (strong, nonatomic) YTQTMButton *settingsButton;
+- (void)setDynamicButtons:(NSArray *)buttons;
- (void)setLeadingPadding:(CGFloat)arg1;
-- (void)uYouPlusRootOptionsAction;
+- (void)settingsAction;
@end
@interface YTISlimMetadataButtonSupportedRenderers : NSObject
diff --git a/Sources/uYouPlus.xm b/Sources/uYouPlus.xm
index f566aa8966..0c0534f779 100644
--- a/Sources/uYouPlus.xm
+++ b/Sources/uYouPlus.xm
@@ -70,6 +70,11 @@ NSBundle *tweakBundle = uYouPlusBundle();
- (BOOL)isMonetized { return NO; }
%end
+%hook YTAdShieldUtils
++ (id)spamSignalsDictionary { return @{}; }
++ (id)spamSignalsDictionaryWithoutIDFA { return @{}; }
+%end
+
%hook YTDataUtils
+ (id)spamSignalsDictionary { return @{}; }
+ (id)spamSignalsDictionaryWithoutIDFA { return @{}; }
@@ -102,6 +107,10 @@ NSBundle *tweakBundle = uYouPlusBundle();
%hook YTIPlayerResponse
- (BOOL)isMonetized { return NO; }
%end
+%hook YTAdShieldUtils
++ (id)spamSignalsDictionary { return @{}; }
++ (id)spamSignalsDictionaryWithoutIDFA { return @{}; }
+%end
%hook YTDataUtils
+ (id)spamSignalsDictionary { return @{}; }
+ (id)spamSignalsDictionaryWithoutIDFA { return @{}; }
@@ -120,29 +129,44 @@ NSBundle *tweakBundle = uYouPlusBundle();
%orig;
}
%end
-BOOL isAdString(NSString *description) {
- if ([description containsString:@"brand_promo"]
- || [description containsString:@"carousel_footered_layout"]
- || [description containsString:@"carousel_headered_layout"]
- || [description containsString:@"feed_ad_metadata"]
- || [description containsString:@"full_width_portrait_image_layout"]
- || [description containsString:@"full_width_square_image_layout"]
- || [description containsString:@"home_video_with_context"]
- || [description containsString:@"landscape_image_wide_button_layout"]
- || [description containsString:@"product_engagement_panel"]
- || [description containsString:@"product_item"]
- || [description containsString:@"shelf_header"]
- || [description containsString:@"square_image_layout"]
- || [description containsString:@"text_image_button_layout"]
- || [description containsString:@"text_search_ad"]
- || [description containsString:@"expandable_list"]
- || [description containsString:@"expandable_metadata"]
- || [description containsString:@"video_display_full_layout"]
- || [description containsString:@"video_display_full_buttoned_layout"])
- return YES;
- return NO;
+NSString *getAdString(NSString *description) {
+ if ([description containsString:@"brand_promo"])
+ return @"brand_promo";
+ if ([description containsString:@"carousel_footered_layout"])
+ return @"carousel_footered_layout";
+ if ([description containsString:@"carousel_headered_layout"])
+ return @"carousel_headered_layout";
+ if ([description containsString:@"feed_ad_metadata"])
+ return @"feed_ad_metadata";
+ if ([description containsString:@"full_width_portrait_image_layout"])
+ return @"full_width_portrait_image_layout";
+ if ([description containsString:@"full_width_square_image_layout"])
+ return @"full_width_square_image_layout";
+ if ([description containsString:@"landscape_image_wide_button_layout"])
+ return @"landscape_image_wide_button_layout";
+ if ([description containsString:@"post_shelf"])
+ return @"post_shelf";
+ if ([description containsString:@"product_carousel"])
+ return @"product_carousel";
+ if ([description containsString:@"product_engagement_panel"])
+ return @"product_engagement_panel";
+ if ([description containsString:@"product_item"])
+ return @"product_item";
+ if ([description containsString:@"statement_banner"])
+ return @"statement_banner";
+ if ([description containsString:@"square_image_layout"])
+ return @"square_image_layout";
+ if ([description containsString:@"text_image_button_layout"])
+ return @"text_image_button_layout";
+ if ([description containsString:@"text_search_ad"])
+ return @"text_search_ad";
+ if ([description containsString:@"video_display_full_layout"])
+ return @"video_display_full_layout";
+ if ([description containsString:@"video_display_full_buttoned_layout"])
+ return @"video_display_full_buttoned_layout";
+ return nil;
}
-NSData *cellDividerData;
+static __strong NSData *cellDividerData;
%hook YTIElementRenderer
- (NSData *)elementData {
NSString *description = [self description];
@@ -150,7 +174,16 @@ NSData *cellDividerData;
if (!cellDividerData) cellDividerData = %orig;
return cellDividerData;
}
- if ([self respondsToSelector:@selector(hasCompatibilityOptions)] && self.hasCompatibilityOptions && self.compatibilityOptions.hasAdLoggingData) return cellDividerData;
+ if (!cellDividerData) return %orig;
+ if ([self respondsToSelector:@selector(hasCompatibilityOptions)] && self.hasCompatibilityOptions && self.compatibilityOptions.hasAdLoggingData) {
+ // HBLogInfo(@"YTX adLogging 1 %@", cellDividerData);
+ return cellDividerData;
+ }
+ NSString *adString = getAdString(description);
+ if (adString) {
+ // HBLogInfo(@"YTX getAdString 1 %@ %@", adString, cellDividerData);
+ return cellDividerData;
+ }
return %orig;
}
%end
@@ -164,41 +197,23 @@ NSData *cellDividerData;
YTIItemSectionRenderer *sectionRenderer = renderers.itemSectionRenderer;
YTIItemSectionSupportedRenderers *firstObject = [sectionRenderer.contentsArray firstObject];
YTIElementRenderer *elementRenderer = firstObject.elementRenderer;
+ if ([elementRenderer respondsToSelector:@selector(hasCompatibilityOptions)] && elementRenderer.hasCompatibilityOptions && elementRenderer.compatibilityOptions.hasAdLoggingData) {
+ // HBLogInfo(@"YTX adLogging 2 %@", elementRenderer);
+ return YES;
+ }
NSString *description = [elementRenderer description];
- return isAdString(description)
- || [description containsString:@"post_shelf"]
- || [description containsString:@"product_carousel"]
- || [description containsString:@"statement_banner"];
- }];
- [contentsArray removeObjectsAtIndexes:removeIndexes];
- }
- %orig;
-}
-%end
-%hook YTWatchNextResultsViewController
-- (void)loadWithModel:(YTISectionListRenderer *)watchNextResults {
- if ([watchNextResults isKindOfClass:%c(YTISectionListRenderer)]) {
- NSMutableArray *contentsArray = watchNextResults.contentsArray;
- NSIndexSet *removeIndexes = [contentsArray indexesOfObjectsPassingTest:^BOOL(YTISectionListSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
- if (![renderers isKindOfClass:%c(YTISectionListSupportedRenderers)])
- return NO;
- YTIItemSectionRenderer *sectionRenderer = renderers.itemSectionRenderer;
- YTIItemSectionSupportedRenderers *firstObject = [sectionRenderer.contentsArray firstObject];
- YTIElementRenderer *elementRenderer = firstObject.elementRenderer;
- NSString *description = [elementRenderer description];
- return isAdString(description);
+ NSString *adString = getAdString(description);
+ if (adString) {
+ // HBLogInfo(@"YTX getAdString 2 %@ %@", adString, elementRenderer);
+ return YES;
+ }
+ return NO;
}];
[contentsArray removeObjectsAtIndexes:removeIndexes];
}
%orig;
}
%end
-%hook _ASDisplayView
-- (void)didMoveToWindow {
- %orig();
- if ([self.accessibilityIdentifier isEqualToString:@"id.products_in_video_with_preview_overlay_badge.view"]) self.hidden = YES;
-}
-%end
%end
// Hide YouTube Logo - @dayanch96
@@ -231,7 +246,6 @@ NSData *cellDividerData;
%end
%end
-
// Fix App Group Directory by move it to document directory
%hook NSFileManager
- (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier {
@@ -286,6 +300,9 @@ NSData *cellDividerData;
- (BOOL)isLandscapeEngagementPanelSwipeRightToDismissEnabled { return YES; } // Swipe right to dismiss the right panel in fullscreen mode
- (BOOL)enableModularPlayerBarController { return NO; } // fixes some of the iSponorBlock problems
- (BOOL)mainAppCoreClientEnableCairoSettings { return IS_ENABLED(@"newSettingsUI_enabled"); } // New grouped settings UI
+- (BOOL)enableIosFloatingMiniplayer { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer
+- (BOOL)enableIosFloatingMiniplayerSwipeUpToExpand { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer
+- (BOOL)enableIosFloatingMiniplayerRepositioning { return IS_ENABLED(@"floatingMiniplayer2_enabled"); } // Floating Miniplayer (Repositioning Support, Removes Swiping Up Gesture)
%end
// Fix Casting: https://github.com/arichornlover/uYouEnhanced/issues/606#issuecomment-2098289942
@@ -334,6 +351,21 @@ NSData *cellDividerData;
- (BOOL)savedSettingShouldExpire { return NO; }
%end
+// Restore Settings Button in Navigaton Bar - @arichornlover & @bhackel - https://github.com/arichornlover/uYouEnhanced/issues/178
+/* WILL RESULT IN LOSING THE SETTINGS BUTTON!
+%hook YTRightNavigationButtons
+- (id)visibleButtons {
+ Class YTVersionUtilsClass = %c(YTVersionUtils);
+ NSString *appVersion = [YTVersionUtilsClass performSelector:@selector(appVersion)];
+ NSComparisonResult result = [appVersion compare:@"18.35.4" options:NSNumericSearch];
+ if (result == NSOrderedAscending) {
+ return %orig;
+ }
+ return [self dynamicButtons];
+}
+%end
+*/
+
// Hide "Get Youtube Premium" in "You" tab - @bhackel
%group gHidePremiumPromos
%hook YTAppCollectionViewController
@@ -546,6 +578,18 @@ NSData *cellDividerData;
}
%end
+// Classic Video Player (Restores the v16.xx.x Video Player Functionality) - @arichornlover
+// To-do: disabling "Precise Video Scrubbing" https://9to5google.com/2022/06/29/youtube-precise-video-scrubbing/
+%group gClassicVideoPlayer
+%hook YTColdConfig
+- (BOOL)isPinchToEnterFullscreenEnabled { return YES; } // Restore Pinch-to-fullscreen
+- (BOOL)deprecateTabletPinchFullscreenGestures { return NO; } // Restore Pinch-to-fullscreen
+%end
+%hook YTHotConfig
+- (BOOL)isTabletFullscreenSwipeGesturesEnabled { return NO; } // Disable Swipe-to-fullscreen (iPad)
+%end
+%end
+
// Fix LowContrastMode - @arichornlover
static int contrastMode() {
NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
@@ -598,7 +642,7 @@ static int contrastMode() {
*/
%end
-// Disable Modern/Rounded Buttons (_ASDisplayView Version's not included) - @arichornlover
+// Disable Modern/Rounded Buttons (_ASDisplayView Version's not supported) - @arichornlover
%group gDisableModernButtons
%hook YTQTMButton // Disable Modern/Rounded Buttons
+ (BOOL)buttonModernizationEnabled { return NO; }
@@ -620,15 +664,29 @@ static int contrastMode() {
- (BOOL)cxClientEnableModernizedActionSheet { return NO; }
- (BOOL)enableClientShortsSheetsModernization { return NO; }
- (BOOL)enableTimestampModernizationForNative { return NO; }
-- (BOOL)modernizeElementsTextColor { return NO; }
-- (BOOL)modernizeElementsBgColor { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaFeedStretchBottom { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaFrostedBottomBar { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaFrostedPivotBar { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaFrostedPivotBarUpdatedBackdrop { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaFrostedTopBar { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaOpacityPivotBar { return NO; }
+- (BOOL)mainAppCoreClientEnableModernIaTopAndBottomBarIconRefresh { return NO; }
+- (BOOL)mainAppCoreClientEnableModernizedBedtimeReminderU18DefaultSettings { return NO; }
+- (BOOL)modernizeCameoNavbar { return NO; }
- (BOOL)modernizeCollectionLockups { return NO; }
+- (BOOL)modernizeCollectionLockupsShowVideoCount { return NO; }
+- (BOOL)modernizeElementsBgColor { return NO; }
+- (BOOL)modernizeElementsTextColor { return NO; }
+- (BOOL)postsCreatorClientEnableModernButtonsUi { return NO; }
+- (BOOL)pullToFullModernEdu { return NO; }
+- (BOOL)showModernMiniplayerRedesign { return NO; }
- (BOOL)uiSystemsClientGlobalConfigEnableModernButtonsForNative { return NO; }
- (BOOL)uiSystemsClientGlobalConfigIosEnableModernTabsForNative { return NO; }
-- (BOOL)uiSystemsClientGlobalConfigIosEnableEpUxUpdates { return NO; }
-- (BOOL)uiSystemsClientGlobalConfigIosEnableSheetsUxUpdates { return NO; }
- (BOOL)uiSystemsClientGlobalConfigIosEnableSnackbarModernization { return NO; }
+- (BOOL)uiSystemsClientGlobalConfigModernizeNativeBgColor { return NO; }
+- (BOOL)uiSystemsClientGlobalConfigModernizeNativeTextColor { return NO; }
// Disable Rounded Content
+- (BOOL)enableIosFloatingMiniplayerRoundedCornerRadius { return YES; }
- (BOOL)iosDownloadsPageRoundedThumbs { return NO; }
- (BOOL)iosRoundedSearchBarSuggestZeroPadding { return NO; }
- (BOOL)uiSystemsClientGlobalConfigEnableRoundedDialogForNative { return NO; }
@@ -680,11 +738,21 @@ static int contrastMode() {
%end
%end
-// Hide YouTube Heatwaves in Video Player (YouTube v17.19.2-latest) - @level3tjg - https://www.reddit.com/r/jailbreak/comments/v29yvk/
+// Hide YouTube Heatwaves in Video Player - v17.33.2+ - @arichornlover
%group gHideHeatwaves
%hook YTInlinePlayerBarContainerView
- (BOOL)canShowHeatwave { return NO; }
%end
+%hook YTPlayerBarHeatwaveView
+- (id)initWithFrame:(CGRect)frame heatmap:(id)heat {
+ return NULL;
+}
+%end
+%hook YTPlayerBarController
+- (void)setHeatmap:(id)arg1 {
+ %orig(NULL);
+}
+%end
%end
// YTNoSuggestedVideo - https://github.com/bhackel/YTNoSuggestedVideo
@@ -783,6 +851,31 @@ static int contrastMode() {
%end
%end
+// Fullscreen to the Right - @arichornlover
+%group gFullscreenToTheRight
+%hook YTWatchViewController
+- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
+ if ([self fullscreen] && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+ return UIInterfaceOrientationLandscapeRight;
+ }
+ return %orig;
+}
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
+ if ([self fullscreen] && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+ return UIInterfaceOrientationMaskLandscape;
+ }
+ return %orig;
+}
+%new
+- (void)forceRightFullscreenOrientation {
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+ NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
+ [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
+ }
+}
+%end
+%end
+
// Disable Double tap to skip chapter - @bhackel
%hook YTDoubleTapToSeekController
- (void)didTwoFingerDoubleTap:(id)arg1 {
@@ -793,7 +886,6 @@ static int contrastMode() {
}
%end
-
// Disable snap to chapter
%hook YTSegmentableInlinePlayerBarView
- (void)didMoveToWindow {
@@ -804,7 +896,6 @@ static int contrastMode() {
}
%end
-
// Disable Pinch to zoom
%hook YTColdConfig
- (BOOL)videoZoomFreeZoomEnabledGlobalConfig {
@@ -973,7 +1064,9 @@ static int contrastMode() {
}
%end
-// Hide Fullscreen Button - @arichornlover - PoomSmart's Newer Version of the *YouQuality* tweak breaks when enabling this
+/*
+// LEGACY VERSION ⚠️
+// Hide Fullscreen Button - @arichornlover - PoomSmart's 1.2.0+ Versions of the *YouQuality* tweak makes the button invisible when enabling this
%hook YTInlinePlayerBarContainerView
- (void)layoutSubviews {
%orig;
@@ -990,6 +1083,18 @@ static int contrastMode() {
}
}
%end
+*/
+
+// NEW VERSION
+// Hide Fullscreen Button - @arichornlover
+%group gHideFullscreenButton
+%hook YTInlinePlayerBarContainerView
+- (BOOL)fullscreenButtonDisabled { return YES; }
+- (BOOL)canShowFullscreenButton { return NO; }
+- (BOOL)canShowFullscreenButtonExperimental { return NO; }
+// - (void)setFullscreenButtonDisabled:(BOOL) // Uncomment and might implement this if needed - @arichornlover
+%end
+%end
// Hide HUD Messages
%hook YTHUDMessageView
@@ -1004,7 +1109,7 @@ static int contrastMode() {
return IS_ENABLED(@"hideChannelWatermark_enabled") ? NO : %orig;
}
%end
-// Hide Channel Watermark (for Old YouTube Versions / Backwards Compatibility)
+// Hide Channel Watermark (for Backwards Compatibility)
%hook YTAnnotationsViewController
- (void)loadFeaturedChannelWatermark {
if (IS_ENABLED(@"hideChannelWatermark_enabled")) {}
@@ -1186,31 +1291,17 @@ static int contrastMode() {
}
%end
-/*
-// Hide Shorts Cells - @PoomSmart, @iCrazeiOS & @Dayanch96
+/* DISABLED DUE TO CONFLICTS
+// Hide Community Posts - @michael-winay, @arichornlover, @iCrazeiOS @PoomSmart & @Dayanch96
%hook YTIElementRenderer
- (NSData *)elementData {
NSString *description = [self description];
- if ([NSUserDefaults.standardUserDefaults boolForKey:@"removeShortsCell"]) { // uYou (Hide Shorts Cells)
- if ([description containsString:@"shorts_shelf.eml"] || [description containsString:@"#shorts"] || [description containsString:@"shorts_video_cell.eml"] || [description containsString:@"6Shorts"]) {
- if (![description containsString:@"history*"]) {
- if (!cellDividerData) cellDividerData = %orig;
- return cellDividerData;
- }
- }
- }
-// Hide Community Posts @michael-winay & @arichornlover
if (IS_ENABLED(@"hideCommunityPosts_enabled")) {
if ([description containsString:@"post_base_wrapper.eml"]) {
- if (!cellDividerData) cellDividerData = %orig;
+ if (!cellDividerData) cellDividerData = [NSData dataWithBytes:cellDividerDataBytes length:cellDividerDataBytesLength];
return cellDividerData;
}
}
-// etc. - @Dayanch96
- BOOL hasShorts = ([description containsString:@"shorts_shelf.eml"] || [description containsString:@"shorts_video_cell.eml"] || [description containsString:@"6Shorts"]) && ![description containsString:@"history*"];
- BOOL hasShortsInHistory = [description containsString:@"compact_video.eml"] && [description containsString:@"youtube_shorts_"];
-
- if (hasShorts || hasShortsInHistory) return cellDividerData;
return %orig;
}
%end
@@ -1225,21 +1316,22 @@ static int contrastMode() {
color = [UIColor redColor];
}
}
-// Hide the Button Containers under the Video Player - 17.33.2 and up - @arichornlover
+ // Hide the Button Containers under the Video Player - 17.33.2 and up - @arichornlover
if (IS_ENABLED(@"hideButtonContainers_enabled")) {
if ([description containsString:@"id.video.like.button"] ||
[description containsString:@"id.video.dislike.button"] ||
[description containsString:@"id.video.share.button"] ||
[description containsString:@"id.video.remix.button"] ||
[description containsString:@"id.ui.add_to.offline.button"]) {
- color = [UIColor clearColor];
+// self.hidden = YES;
}
}
%orig(color);
}
%end
-// Hide the (Connect / Thanks / Save / Report) Buttons under the Video Player - 17.33.2 and up - @arichornlover (inspired by @PoomSmart's version) LEGACY METHOD ⚠️
+// LEGACY VERSION ⚠️
+// Hide the (Connect / Thanks / Save / Report) Buttons under the Video Player - 17.33.2 and up - @arichornlover (inspired by @PoomSmart's version)
%hook _ASDisplayView
- (void)layoutSubviews {
%orig;
@@ -1262,11 +1354,12 @@ static int contrastMode() {
}
%end
+// UPDATED VERSION
// Hide the (Connect / Share / Remix / Thanks / Download / Clip / Save / Report) Buttons under the Video Player - 17.33.2 and up - @PoomSmart (inspired by @arichornlover) - METHOD BROKE Server-Side on May 14th 2024
static BOOL findCell(ASNodeController *nodeController, NSArray *identifiers) {
for (id child in [nodeController children]) {
if ([child isKindOfClass:%c(ELMNodeController)]) {
- NSArray *elmChildren = [(ELMNodeController *)child children];
+ NSArray *elmChildren = [(ELMNodeController * _Nullable)child children];
for (ELMComponent *elmChild in elmChildren) {
for (NSString *identifier in identifiers) {
if ([[elmChild description] containsString:identifier])
@@ -1276,8 +1369,8 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
}
if ([child isKindOfClass:%c(ASNodeController)]) {
- ASDisplayNode *childNode = ((ASNodeController *)child).node; // ELMContainerNode
- NSArray *yogaChildren = childNode.yogaChildren;
+ ASDisplayNode *childNode = ((ASNodeController * _Nullable)child).node; // ELMContainerNode
+ NSArray *yogaChildren = childNode.yogaChildren;
for (ASDisplayNode *displayNode in yogaChildren) {
if ([identifiers containsObject:displayNode.accessibilityIdentifier])
return YES;
@@ -1293,7 +1386,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
%hook ASCollectionView // This stopped working on May 14th 2024 due to a Server-Side Change from YouTube.
-- (CGSize)sizeForElement:(ASCollectionElement *)element {
+- (CGSize)sizeForElement:(ASCollectionElement * _Nullable)element {
if ([self.accessibilityIdentifier isEqualToString:@"id.video.scrollable_action_bar"]) {
ASCellNode *node = [element node];
ASNodeController *nodeController = [node controller];
@@ -1430,19 +1523,6 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
}
%end
-// %hook YTSectionListViewController
-// - (void)loadWithModel:(YTISectionListRenderer *)model {
-// NSMutableArray *contentsArray = model.contentsArray;
-// NSIndexSet *removeIndexes = [contentsArray indexesOfObjectsPassingTest:^BOOL(YTISectionListSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
-// YTIItemSectionRenderer *sectionRenderer = renderers.itemSectionRenderer;
-// YTIItemSectionSupportedRenderers *firstObject = [sectionRenderer.contentsArray firstObject];
-// return firstObject.hasPromotedVideoRenderer || firstObject.hasCompactPromotedVideoRenderer || firstObject.hasPromotedVideoInlineMutedRenderer;
-// }];
-// [contentsArray removeObjectsAtIndexes:removeIndexes];
-// %orig;
-// }
-// %end
-
// Disable hints - https://github.com/LillieH001/YouTube-Reborn/blob/v4/
%group gDisableHints
%hook YTSettings
@@ -1485,7 +1565,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
%end
// Hide the chip bar under the video player?
-// %hook YTChipCloudCell //
+// %hook YTChipCloudCell
// - (void)didMoveToWindow {
// %orig;
// self.hidden = YES;
@@ -1550,7 +1630,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
%end
%hook UIKBTree
- (long long)nativeIdiom {
- return NO;
+ return YES;
}
%end
%hook UIKBRenderer
@@ -1621,6 +1701,9 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
if (IS_ENABLED(@"portraitFullscreen_enabled")) {
%init(gPortraitFullscreen);
}
+ if (IS_ENABLED(@"fullscreenToTheRight_enabled")) {
+ %init(gFullscreenToTheRight);
+ }
if (IS_ENABLED(@"hideFullscreenActions_enabled")) {
%init(hideFullscreenActions);
}
@@ -1639,6 +1722,9 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
if (IS_ENABLED(@"noVideosInFullscreen_enabled")) {
%init(gNoVideosInFullscreen);
}
+ if (IS_ENABLED(@"classicVideoPlayer_enabled")) {
+ %init(gClassicVideoPlayer);
+ }
if (IS_ENABLED(@"fixLowContrastMode_enabled")) {
%init(gFixLowContrastMode);
}
@@ -1757,6 +1843,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray *ide
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"removeYouTubeAds"];
}
if (![allKeys containsObject:@"uYouAdBlockingWorkaround_enabled"]) {
+ [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"uYouAdBlockingWorkaroundLite_enabled"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"uYouAdBlockingWorkaround_enabled"];
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"removeYouTubeAds"];
}
diff --git a/Sources/uYouPlusPatches.h b/Sources/uYouPlusPatches.h
index b88f7d3484..e9b74f6414 100644
--- a/Sources/uYouPlusPatches.h
+++ b/Sources/uYouPlusPatches.h
@@ -84,3 +84,13 @@
@interface YTIInnertubeCommandExtensionRoot
+ (GPBExtensionDescriptor*)innertubeCommand;
@end
+
+@interface YTAccountScopedCommandResponderEvent
+@property (nonatomic, strong, readwrite) YTICommand *command;
+@end
+
+@interface YTIShareEntityEndpoint
+@property (nonatomic, assign, readwrite) BOOL hasSerializedShareEntity;
+@property (nonatomic, copy, readwrite) NSString *serializedShareEntity;
++ (GPBExtensionDescriptor*)shareEntityEndpoint;
+@end
diff --git a/Sources/uYouPlusPatches.xm b/Sources/uYouPlusPatches.xm
index dd9f015ed3..b617753143 100644
--- a/Sources/uYouPlusPatches.xm
+++ b/Sources/uYouPlusPatches.xm
@@ -109,29 +109,15 @@ static inline NSString* extractIdWithFormat(GPBUnknownFieldSet *fields, NSIntege
return [NSString stringWithFormat:format, id];
}
-%hook ELMPBShowActionSheetCommand
-- (void)executeWithCommandContext:(id)_context handler:(id)_handler {
- if (!self.hasOnAppear)
- return %orig;
- GPBExtensionDescriptor *innertubeCommandDescriptor = [%c(YTIInnertubeCommandExtensionRoot) innertubeCommand];
- if (![self.onAppear hasExtension:innertubeCommandDescriptor])
- return %orig;
- YTICommand *innertubeCommand = [self.onAppear getExtension:innertubeCommandDescriptor];
- GPBExtensionDescriptor *updateShareSheetCommandDescriptor = [%c(YTIUpdateShareSheetCommand) updateShareSheetCommand];
- if(![innertubeCommand hasExtension:updateShareSheetCommandDescriptor])
- return %orig;
- YTIUpdateShareSheetCommand *updateShareSheetCommand = [innertubeCommand getExtension:updateShareSheetCommandDescriptor];
- if (!updateShareSheetCommand.hasSerializedShareEntity)
- return %orig;
-
- GPBMessage *shareEntity = [%c(GPBMessage) deserializeFromString:updateShareSheetCommand.serializedShareEntity];
+static BOOL showNativeShareSheet(NSString *serializedShareEntity) {
+ GPBMessage *shareEntity = [%c(GPBMessage) deserializeFromString:serializedShareEntity];
GPBUnknownFieldSet *fields = shareEntity.unknownFields;
NSString *shareUrl;
if ([fields hasField:ShareEntityFieldClip]) {
GPBUnknownField *shareEntityClip = [fields getField:ShareEntityFieldClip];
if ([shareEntityClip.lengthDelimitedList count] != 1)
- return %orig;
+ return FALSE;
GPBMessage *clipMessage = [%c(GPBMessage) parseFromData:[shareEntityClip.lengthDelimitedList firstObject] error:nil];
shareUrl = extractIdWithFormat(clipMessage.unknownFields, 1, @"https://youtube.com/clip/%@");
}
@@ -152,10 +138,90 @@ static inline NSString* extractIdWithFormat(GPBUnknownFieldSet *fields, NSIntege
shareUrl = extractIdWithFormat(fields, ShareEntityFieldVideo, @"https://youtube.com/watch?v=%@");
if (!shareUrl)
- return %orig;
+ return FALSE;
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[shareUrl] applicationActivities:nil];
[[%c(YTUIUtils) topViewControllerForPresenting] presentViewController:activityViewController animated:YES completion:^{}];
+ return TRUE;
+}
+
+
+/* -------------------- iPad Layout -------------------- */
+
+%hook YTAccountScopedCommandResponderEvent
+- (void)send {
+ GPBExtensionDescriptor *shareEntityEndpointDescriptor = [%c(YTIShareEntityEndpoint) shareEntityEndpoint];
+ if (![self.command hasExtension:shareEntityEndpointDescriptor])
+ return %orig;
+ YTIShareEntityEndpoint *shareEntityEndpoint = [self.command getExtension:shareEntityEndpointDescriptor];
+ if (!showNativeShareSheet(shareEntityEndpoint.serializedShareEntity))
+ return %orig;
+}
+%end
+
+/* OLD
+%hook YTShareRequestViewController
+- (id)initWithService:(id)_service parentResponder:(id)_parentResponder {
+ id result = %orig;
+ // disable the default share sheet behavior and force the app to call [YTAccountScopedCommandRouter handleCommand] if available
+ if ([_parentResponder respondsToSelector:@selector(handleCommand:entry:fromView:sender:completionBlock:)]) {
+ [_parentResponder handleCommand:nil entry:nil fromView:nil sender:nil completionBlock:nil];
+ }
+ return result;
+}
+%end
+
+%hook YTAccountScopedCommandRouter
+- (BOOL)handleCommand:(id)command entry:(id)_entry fromView:(id)_fromView sender:(id)_sender completionBlock:(id)_completionBlock {
+ GPBExtensionDescriptor *shareEntityEndpointDescriptor = [%c(YTIShareEntityEndpoint) shareEntityEndpoint];
+ if (![command hasExtension:shareEntityEndpointDescriptor])
+ return %orig;
+ YTIShareEntityEndpoint *shareEntityEndpoint = [command getExtension:shareEntityEndpointDescriptor];
+ if(!shareEntityEndpoint.hasSerializedShareEntity)
+ return %orig;
+ if (!showNativeShareSheet(shareEntityEndpoint.serializedShareEntity))
+ return %orig;
+ return TRUE;
+}
+%end
+*/
+
+/* EXPERIMENTAL
+%hook YTAccountScopedCommandRouter
+- (BOOL)handleCommand:(id)command entry:(id)_entry fromView:(id)_fromView sender:(id)_sender completionBlock:(id)_completionBlock {
+ GPBExtensionDescriptor *shareEntityEndpointDescriptor = [%c(YTIShareEntityEndpoint) shareEntityEndpoint];
+ if (![command hasExtension:shareEntityEndpointDescriptor])
+ return %orig;
+ YTIShareEntityEndpoint *shareEntityEndpoint = [command getExtension:shareEntityEndpointDescriptor];
+ if(!shareEntityEndpoint || !shareEntityEndpoint.hasSerializedShareEntity || !shareEntityEndpoint.serializedShareEntity) {
+ return %orig;
+ }
+ if (!showNativeShareSheet(shareEntityEndpoint.serializedShareEntity)) {
+ return %orig;
+ }
+ return TRUE;
+}
+%end
+*/
+
+/* ------------------- iPhone Layout ------------------- */
+
+%hook ELMPBShowActionSheetCommand
+- (void)executeWithCommandContext:(id)_context handler:(id)_handler {
+ if (!self.hasOnAppear)
+ return %orig;
+ GPBExtensionDescriptor *innertubeCommandDescriptor = [%c(YTIInnertubeCommandExtensionRoot) innertubeCommand];
+ if (![self.onAppear hasExtension:innertubeCommandDescriptor])
+ return %orig;
+ YTICommand *innertubeCommand = [self.onAppear getExtension:innertubeCommandDescriptor];
+ GPBExtensionDescriptor *updateShareSheetCommandDescriptor = [%c(YTIUpdateShareSheetCommand) updateShareSheetCommand];
+ if(![innertubeCommand hasExtension:updateShareSheetCommandDescriptor])
+ return %orig;
+ YTIUpdateShareSheetCommand *updateShareSheetCommand = [innertubeCommand getExtension:updateShareSheetCommandDescriptor];
+ if (!updateShareSheetCommand.hasSerializedShareEntity)
+ return %orig;
+ if (!showNativeShareSheet(updateShareSheetCommand.serializedShareEntity))
+ return %orig;
}
%end
diff --git a/Sources/uYouPlusSettings.xm b/Sources/uYouPlusSettings.xm
index 2e878ef772..ffad5a60de 100644
--- a/Sources/uYouPlusSettings.xm
+++ b/Sources/uYouPlusSettings.xm
@@ -78,7 +78,7 @@ NSArray *copyKeys = @[
/* MAIN Shorts Keys */ @"hideBuySuperThanks_enabled", @"hideSubcriptions_enabled", @"disableResumeToShorts_enabled", @"shortsQualityPicker_enabled",
/* MAIN Player UI Keys */ @"redSubscribeButton_enabled", @"hideButtonContainers_enabled", @"hideConnectButton_enabled", @"hideShareButton_enabled", @"hideRemixButton_enabled", @"hideThanksButton_enabled", @"hideDownloadButton_enabled", @"hideClipButton_enabled", @"hideSaveToPlaylistButton_enabled", @"hideReportButton_enabled", @"hidePreviewCommentSection_enabled", @"hideCommentSection_enabled",
/* MAIN Overlay Keys */ @"disableAccountSection_enabled", @"disableAutoplaySection_enabled", @"disableTryNewFeaturesSection_enabled", @"disableVideoQualityPreferencesSection_enabled", @"disableNotificationsSection_enabled", @"disableManageAllHistorySection_enabled", @"disableYourDataInYouTubeSection_enabled", @"disablePrivacySection_enabled", @"disableLiveChatSection_enabled", @"hidePremiumPromos_enabled",
-/* MAIN App UI Keys */ @"hideHomeTab_enabled", @"lowContrastMode_enabled", @"fixLowContrastMode_enabled", @"disableModernButtons_enabled", @"disableRoundedHints_enabled", @"disableModernFlags_enabled", @"ytNoModernUI_enabled", @"enableVersionSpoofer_enabled",
+/* MAIN App UI Keys */ @"hideHomeTab_enabled", @"lowContrastMode_enabled", @"classicVideoPlayer_enabled", @"fixLowContrastMode_enabled", @"disableModernButtons_enabled", @"disableRoundedHints_enabled", @"disableModernFlags_enabled", @"ytNoModernUI_enabled", @"enableVersionSpoofer_enabled",
/* MAIN Misc Keys */ @"uYouAdBlockingWorkaroundLite_enabled", @"uYouAdBlockingWorkaround_enabled", @"disableAnimatedYouTubeLogo_enabled", @"centerYouTubeLogo_enabled", @"hideYouTubeLogo_enabled", @"ytStartupAnimation_enabled", @"disableHints_enabled", @"stickNavigationBar_enabled", @"hideSponsorBlockButton_enabled", @"hideChipBar_enabled", @"hidePlayNextInQueue_enabled", @"hideCommunityPosts_enabled", @"hideChannelHeaderLinks_enabled", @"iPhoneLayout_enabled", @"bigYTMiniPlayer_enabled", @"reExplore_enabled", @"autoHideHomeBar_enabled", @"hideSubscriptionsNotificationBadge_enabled", @"fixCasting_enabled", @"newSettingsUI_enabled", @"flex_enabled",
/* TWEAK uYou Keys */ @"showedWelcomeVC", @"hideShortsTab", @"hideCreateTab", @"hideCastButton", @"relatedVideosAtTheEndOfYTVideos", @"removeYouTubeAds", @"backgroundPlayback", @"disableAgeRestriction", @"iPadLayout", @"noSuggestedVideoAtEnd", @"shortsProgressBar", @"hideShortsCells", @"removeShortsCell", @"startupPage",
/* TWEAK iSB Keys */ @"userID", @"apiInstance", @"minimumDuration", @"skipNoticeDuration", @"kShowModifiedTime", @"showSkipNotice", @"showButtonsInPlayer", @"hideStartEndButtonInPlayer", @"showModifiedTime", @"skipAudioNotification", @"enableSkipCountTracking",
@@ -202,7 +202,7 @@ extern NSBundle *uYouPlusBundle();
if (IS_ENABLED(@"replaceCopyandPasteButtons_enabled")) {
// Export Settings functionality
NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"exported_settings.txt"]];
- NSMutableString *settingsString = [NSMutableNSMutableString string];
+ NSMutableString *settingsString = [NSMutableString string];
for (NSString *key in copyKeys) {
id value = [[NSUserDefaults standardUserDefaults] objectForKey:key];
if (value) {
@@ -213,9 +213,7 @@ extern NSBundle *uYouPlusBundle();
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:tempFileURL inMode:UIDocumentPickerModeExportToService];
documentPicker.delegate = (id)self;
documentPicker.allowsMultipleSelection = NO;
- [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPicker animated:YES completion:nil];
- }
- return YES;
+ [settingsViewController presentViewController:documentPicker animated:YES completion:nil];
} else {
// Copy Settings functionality (default behavior)
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
@@ -245,7 +243,7 @@ extern NSBundle *uYouPlusBundle();
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.text"] inMode:UIDocumentPickerModeImport];
documentPicker.delegate = (id)self;
documentPicker.allowsMultipleSelection = NO;
- [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPicker animated:YES completion:nil];
+ [settingsViewController presentViewController:documentPicker animated:YES completion:nil];
return YES;
} else {
// Paste Settings functionality (default behavior)
@@ -262,7 +260,7 @@ extern NSBundle *uYouPlusBundle();
NSString *value = components[1];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
}
- }
+ }
[settingsViewController reloadData];
SHOW_RELAUNCH_YT_SNACKBAR;
}
@@ -274,7 +272,7 @@ extern NSBundle *uYouPlusBundle();
];
[sectionItems addObject:pasteSettings];
- SWITCH_ITEM(LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS"), LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS"), @"replaceCopyandPasteButtons_enabled");
+ SWITCH_ITEM(LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS"), LOC(@"REPLACE_COPY_AND_PASTE_BUTTONS_DESC"), @"replaceCopyandPasteButtons_enabled");
YTSettingsSectionItem *exitYT = [%c(YTSettingsSectionItem)
itemWithTitle:LOC(@"QUIT_YOUTUBE")
@@ -294,7 +292,7 @@ extern NSBundle *uYouPlusBundle();
# pragma mark - uYouEnhanced Essential Menu
YTSettingsSectionItem *customAppMenu = [%c(YTSettingsSectionItem)
itemWithTitle:LOC(@"UYOUENHANCED_ESSENTIAL_MENU")
- titleDescription:LOC(@"This menu includes App Color Customization & Ability to Clear the Cache 🗑️")
+ titleDescription:LOC(@"This menu includes App Color Customization 🎨 & Ability to Clear the Cache 🗑️")
accessibilityIdentifier:nil
detailTextBlock:nil
selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
@@ -436,6 +434,24 @@ extern NSBundle *uYouPlusBundle();
}
});
);
+ SWITCH_ITEM3(
+ LOC(@"FULLSCREEN_TO_THE_RIGHT"),
+ LOC(@"FULLSCREEN_TO_THE_RIGHT_DESC"),
+ @"fullscreenToTheRight_enabled",
+ ({
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+ [[NSUserDefaults standardUserDefaults] setBool:enable forKey:@"fullscreenToTheRight_enabled"];
+ SHOW_RELAUNCH_YT_SNACKBAR;
+ return YES;
+ } else {
+ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Incompatibile" message:@"This Option is Incompatible on an iPad Device." preferredStyle:UIAlertControllerStyleAlert];
+ UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
+ [alert addAction:okAction];
+ [settingsViewController presentViewController:alert animated:YES completion:nil];
+ return NO;
+ }
+ });
+ );
SWITCH_ITEM2(LOC(@"SLIDE_TO_SEEK"), LOC(@"SLIDE_TO_SEEK_DESC"), @"slideToSeek_enabled");
SWITCH_ITEM2(LOC(@"ENABLE_TAP_TO_SEEK"), LOC(@"ENABLE_TAP_TO_SEEK_DESC"), @"YTTapToSeek_enabled");
SWITCH_ITEM(LOC(@"DISABLE_DOUBLE_TAP_TO_SEEK"), LOC(@"DISABLE_DOUBLE_TAP_TO_SEEK_DESC"), @"doubleTapToSeek_disabled");
@@ -529,7 +545,7 @@ extern NSBundle *uYouPlusBundle();
# pragma mark - Video player button options
SECTION_HEADER(LOC(@"VIDEO_PLAYER_BUTTON_OPTIONS"));
-// (the options "Red Subscribe Button" and "Hide Button Containers under player" are currently not working)
+// (the options "Red Subscribe Button" and "Hide Button Containers under player" are currently not working, would most likely result in effecting the whole entire app.)
//
// SWITCH_ITEM(LOC(@"RED_SUBSCRIBE_BUTTON"), LOC(@"RED_SUBSCRIBE_BUTTON_DESC"), @"redSubscribeButton_enabled");
// SWITCH_ITEM2(LOC(@"HIDE_BUTTON_CONTAINERS_UNDER_PLAYER"), LOC(@"HIDE_BUTTON_CONTAINERS_UNDER_PLAYER_DESC"), @"hideButtonContainers_enabled");
@@ -639,6 +655,7 @@ extern NSBundle *uYouPlusBundle();
}
];
[sectionItems addObject:lowContrastModeButton];
+ SWITCH_ITEM2(LOC(@"CLASSIC_VIDEO_PLAYER"), LOC(@"CLASSIC_VIDEO_PLAYER_DESC"), @"classicVideoPlayer_enabled");
SWITCH_ITEM2(LOC(@"FIX_LOWCONTRASTMODE"), LOC(@"FIX_LOWCONTRASTMODE_DESC"), @"fixLowContrastMode_enabled");
SWITCH_ITEM2(LOC(@"DISABLE_MODERN_BUTTONS"), LOC(@"DISABLE_MODERN_BUTTONS_DESC"), @"disableModernButtons_enabled");
SWITCH_ITEM2(LOC(@"DISABLE_ROUNDED_CORNERS_ON_HINTS"), LOC(@"DISABLE_ROUNDED_CORNERS_ON_HINTS_DESC"), @"disableRoundedHints_enabled");
@@ -1394,22 +1411,24 @@ extern NSBundle *uYouPlusBundle();
[settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouEnhanced" titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES];
}
-// File Manager (Paste Settings)
+// File Manager (Import Settings .txt)
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls {
if (urls.count > 0) {
NSURL *fileURL = urls.firstObject;
NSString *fileContents = [NSString stringWithContentsOfURL:fileURL 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 (fileContents.length > 0) {
+ 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];
+ }
}
+ YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"];
+ [settingsViewController reloadData];
}
- [settingsViewController reloadData];
- SHOW_RELAUNCH_YT_SNACKBAR;
}
}