diff --git a/Sources/BigYTMiniPlayer.h b/Sources/BigYTMiniPlayer.h index 8e1eef4..d1f0331 100644 --- a/Sources/BigYTMiniPlayer.h +++ b/Sources/BigYTMiniPlayer.h @@ -5,4 +5,4 @@ @end @interface YTWatchMiniBarView : UIView -@end \ No newline at end of file +@end diff --git a/Sources/BigYTMiniPlayer.xm b/Sources/BigYTMiniPlayer.xm index 68b8593..d364521 100644 --- a/Sources/BigYTMiniPlayer.xm +++ b/Sources/BigYTMiniPlayer.xm @@ -28,4 +28,4 @@ if (IS_ENABLED(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) { %init(BigYTMiniPlayer); } -} \ No newline at end of file +} diff --git a/Sources/ColourOptionsController.h b/Sources/ColourOptionsController.h new file mode 100644 index 0000000..6733b9d --- /dev/null +++ b/Sources/ColourOptionsController.h @@ -0,0 +1,6 @@ +#import +#import + +@interface ColourOptionsController : UIColorPickerViewController + +@end diff --git a/Sources/ColourOptionsController.m b/Sources/ColourOptionsController.m new file mode 100644 index 0000000..fc97fcf --- /dev/null +++ b/Sources/ColourOptionsController.m @@ -0,0 +1,77 @@ +#import "ColourOptionsController.h" +#import "../uYouPlus.h" + +@interface ColourOptionsController () +- (void)coloursView; +@end + +@implementation ColourOptionsController + +- (void)loadView { + [super loadView]; + [self coloursView]; + + self.title = @"Theme Custom Color"; + + UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(close)]; + self.navigationItem.rightBarButtonItem = closeButton; + + UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStylePlain target:self action:@selector(save)]; + self.navigationItem.rightBarButtonItem = saveButton; + + UIBarButtonItem *resetButton = [[UIBarButtonItem alloc] initWithTitle:@"Reset" style:UIBarButtonItemStylePlain target:self action:@selector(reset)]; + self.navigationItem.leftBarButtonItem = resetButton; + + self.supportsAlpha = NO; + NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomThemeColor"]; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:colorData error:nil]; + [unarchiver setRequiresSecureCoding:NO]; + UIColor *color = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + self.selectedColor = color; +} + +- (void)coloursView { + if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.view.backgroundColor = [UIColor colorWithRed:0.949 green:0.949 blue:0.969 alpha:1.0]; + [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}]; + self.navigationController.navigationBar.barStyle = UIBarStyleDefault; + } + else { + self.view.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; + [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]; + self.navigationController.navigationBar.barStyle = UIBarStyleBlack; + } +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + [self coloursView]; +} + +@end + +@implementation ColourOptionsController(Privates) + +- (void)close { + [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)save { + NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:self.selectedColor requiringSecureCoding:nil error:nil]; + [[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"kCustomThemeColor"]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + UIAlertController *alertSaved = [UIAlertController alertControllerWithTitle:@"Color Saved" message:nil preferredStyle:UIAlertControllerStyleAlert]; + + [alertSaved addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + }]]; + + [self presentViewController:alertSaved animated:YES completion:nil]; +} + +- (void)reset { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"kCustomThemeColor"]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/Sources/ColourOptionsController2.h b/Sources/ColourOptionsController2.h new file mode 100644 index 0000000..6d2ee16 --- /dev/null +++ b/Sources/ColourOptionsController2.h @@ -0,0 +1,6 @@ +#import +#import + +@interface ColourOptionsController2 : UIColorPickerViewController + +@end diff --git a/Sources/ColourOptionsController2.m b/Sources/ColourOptionsController2.m new file mode 100644 index 0000000..3057cf0 --- /dev/null +++ b/Sources/ColourOptionsController2.m @@ -0,0 +1,77 @@ +#import "ColourOptionsController2.h" +#import "../uYouPlus.h" + +@interface ColourOptionsController2 () +- (void)coloursView; +@end + +@implementation ColourOptionsController2 + +- (void)loadView { + [super loadView]; + [self coloursView]; + + self.title = @"Custom Text/Etc. Color"; + + UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(close)]; + self.navigationItem.rightBarButtonItem = closeButton; + + UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStylePlain target:self action:@selector(save)]; + self.navigationItem.rightBarButtonItem = saveButton; + + UIBarButtonItem *resetButton = [[UIBarButtonItem alloc] initWithTitle:@"Reset" style:UIBarButtonItemStylePlain target:self action:@selector(reset)]; + self.navigationItem.leftBarButtonItem = resetButton; + + self.supportsAlpha = NO; + NSData *lcmColorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomUIColor"]; + NSKeyedUnarchiver *lcmUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:lcmColorData error:nil]; + [lcmUnarchiver setRequiresSecureCoding:NO]; + UIColor *color = [lcmUnarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + self.selectedColor = color; +} + +- (void)coloursView { + if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.view.backgroundColor = [UIColor colorWithRed:0.949 green:0.949 blue:0.969 alpha:1.0]; + [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}]; + self.navigationController.navigationBar.barStyle = UIBarStyleDefault; + } + else { + self.view.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; + [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]; + self.navigationController.navigationBar.barStyle = UIBarStyleBlack; + } +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + [self coloursView]; +} + +@end + +@implementation ColourOptionsController2(Privates) + +- (void)close { + [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)save { + NSData *lcmColorData = [NSKeyedArchiver archivedDataWithRootObject:self.selectedColor requiringSecureCoding:nil error:nil]; + [[NSUserDefaults standardUserDefaults] setObject:lcmColorData forKey:@"kCustomUIColor"]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + UIAlertController *alertSaved = [UIAlertController alertControllerWithTitle:@"Color Saved" message:nil preferredStyle:UIAlertControllerStyleAlert]; + + [alertSaved addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + }]]; + + [self presentViewController:alertSaved animated:YES completion:nil]; +} + +- (void)reset { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"kCustomUIColor"]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +@end diff --git a/Sources/Extractor.h b/Sources/Extractor.h new file mode 100644 index 0000000..9b10634 --- /dev/null +++ b/Sources/Extractor.h @@ -0,0 +1,7 @@ +// Extractor.h was made by @LillieH1000 from https://www.github.com/LillieH1000/YouTube-Reborn + +#import + +@interface Extractor : NSObject ++ (NSDictionary *)youtubePlayerRequest :(NSString *)client :(NSString *)videoID; +@end diff --git a/Sources/Extractor.xm b/Sources/Extractor.xm new file mode 100644 index 0000000..57ead07 --- /dev/null +++ b/Sources/Extractor.xm @@ -0,0 +1,44 @@ +// Extractor.xm was made by @LillieH1000 from https://www.github.com/LillieH1000/YouTube-Reborn + +#import "Extractor.h" + +@implementation Extractor + ++ (NSDictionary *)youtubePlayerRequest :(NSString *)client :(NSString *)videoID { + NSLocale *locale = [NSLocale currentLocale]; + NSString *countryCode = [locale objectForKey:NSLocaleCountryCode]; + + NSURL *requestURL; + if ([client isEqual:@"android"]) { + requestURL = [NSURL URLWithString:@"https://www.youtube.com/youtubei/v1/player?key=AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w&prettyPrint=false"]; + } else if ([client isEqual:@"ios"]) { + requestURL = [NSURL URLWithString:@"https://www.youtube.com/youtubei/v1/player?key=AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc&prettyPrint=false"]; + } + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL]; + [request setHTTPMethod:@"POST"]; + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + if ([client isEqual:@"android"]) { + [request setValue:@"com.google.android.youtube/17.31.35 (Linux; U; Android 11) gzip" forHTTPHeaderField:@"User-Agent"]; + NSString *jsonBody = [NSString stringWithFormat:@"{\"context\":{\"client\":{\"hl\":\"en\",\"gl\":\"%@\",\"clientName\":\"ANDROID\",\"clientVersion\":\"17.31.35\",\"androidSdkVersion\":30,\"playbackContext\":{\"contentPlaybackContext\":{\"vis\":0,\"splay\":false,\"autoCaptionsDefaultOn\":false,\"autonavState\":\"STATE_OFF\",\"signatureTimestamp\":\"sts\",\"html5Preference\":\"HTML5_PREF_WANTS\",\"lactMilliseconds\":\"-1\"}}}},\"contentCheckOk\":true,\"racyCheckOk\":true,\"videoId\":\"%@\"}", countryCode, videoID]; + [request setHTTPBody:[jsonBody dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]]; + } else if ([client isEqual:@"ios"]) { + [request setValue:@"com.google.ios.youtube/17.33.2 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)" forHTTPHeaderField:@"User-Agent"]; + NSString *jsonBody = [NSString stringWithFormat:@"{\"context\":{\"client\":{\"hl\":\"en\",\"gl\":\"%@\",\"clientName\":\"IOS\",\"clientVersion\":\"17.33.2\",\"deviceModel\":\"iPhone14,3\",\"playbackContext\":{\"contentPlaybackContext\":{\"vis\":0,\"splay\":false,\"autoCaptionsDefaultOn\":false,\"autonavState\":\"STATE_OFF\",\"signatureTimestamp\":\"sts\",\"html5Preference\":\"HTML5_PREF_WANTS\",\"lactMilliseconds\":\"-1\"}}}},\"contentCheckOk\":true,\"racyCheckOk\":true,\"videoId\":\"%@\"}", countryCode, videoID]; + [request setHTTPBody:[jsonBody dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]]; + } + + __block NSData *requestData; + __block BOOL requestFinished = NO; + [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + requestData = data; + requestFinished = YES; + }] resume]; + + while (!requestFinished) { + [NSThread sleepForTimeInterval:0.02]; + } + + return [NSJSONSerialization JSONObjectWithData:requestData options:0 error:nil]; +} + +@end diff --git a/Sources/LowContrastMode.xm b/Sources/LowContrastMode.xm new file mode 100644 index 0000000..4b6a6a0 --- /dev/null +++ b/Sources/LowContrastMode.xm @@ -0,0 +1,592 @@ +#import "uYouPlus.h" + +// +static int contrastMode() { + return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; +} +static BOOL lowContrastMode() { + return IS_ENABLED(@"lowContrastMode_enabled") && contrastMode() == 0; +} +static BOOL customContrastMode() { + return IS_ENABLED(@"lowContrastMode_enabled") && contrastMode() == 1; +} + +UIColor *lcmHexColor; + +%group gLowContrastMode // Low Contrast Mode v1.5.1 (Compatible with only YouTube v16.05.7-v17.38.10) +%hook UIColor ++ (UIColor *)whiteColor { // Dark Theme Color + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)lightTextColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)lightGrayColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)ychGrey7 { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)skt_chipBackgroundColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)placeholderTextColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)systemLightGrayColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)systemExtraLightGrayColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)labelColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)secondaryLabelColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)tertiaryLabelColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} ++ (UIColor *)quaternaryLabelColor { + return [UIColor colorWithRed: 0.56 green: 0.56 blue: 0.56 alpha: 1.00]; +} +%end +%hook YTCommonColorPalette +- (UIColor *)textPrimary { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)textSecondary { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)overlayTextPrimary { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)overlayTextSecondary { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)iconActive { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)iconActiveOther { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)brandIconActive { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)staticBrandWhite { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)overlayIconActiveOther { + return self.pageStyle == 1 ? [UIColor whiteColor] : %orig; +} +- (UIColor *)overlayIconInactive { + return self.pageStyle == 1 ? [[UIColor whiteColor] colorWithAlphaComponent:0.7] : %orig; +} +- (UIColor *)overlayIconDisabled { + return self.pageStyle == 1 ? [[UIColor whiteColor] colorWithAlphaComponent:0.3] : %orig; +} +- (UIColor *)overlayFilledButtonActive { + return self.pageStyle == 1 ? [[UIColor whiteColor] colorWithAlphaComponent:0.2] : %orig; +} +%end +%hook YTColor ++ (BOOL)darkerPaletteTextColorEnabled { + return NO; +} ++ (UIColor *)white1 { + return [UIColor whiteColor]; +} ++ (UIColor *)white2 { + return [UIColor whiteColor]; +} ++ (UIColor *)white3 { + return [UIColor whiteColor]; +} ++ (UIColor *)white4 { + return [UIColor whiteColor]; +} ++ (UIColor *)white5 { + return [UIColor whiteColor]; +} ++ (UIColor *)grey1 { + return [UIColor whiteColor]; +} ++ (UIColor *)grey2 { + return [UIColor whiteColor]; +} +%end +%hook QTMColorGroup +- (UIColor *)tint100 { + return [UIColor whiteColor]; +} +- (UIColor *)tint300 { + return [UIColor whiteColor]; +} +- (UIColor *)tint500 { + return [UIColor whiteColor]; +} +- (UIColor *)tint700 { + return [UIColor whiteColor]; +} +- (UIColor *)accent200 { + return [UIColor whiteColor]; +} +- (UIColor *)accent400 { + return [UIColor whiteColor]; +} +- (UIColor *)accentColor { + return [UIColor whiteColor]; +} +- (UIColor *)brightAccentColor { + return [UIColor whiteColor]; +} +- (UIColor *)regularColor { + return [UIColor whiteColor]; +} +- (UIColor *)darkerColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColor { + return [UIColor whiteColor]; +} +- (UIColor *)lightBodyTextColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnRegularColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnLighterColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnDarkerColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnAccentColor { + return [UIColor whiteColor]; +} +- (UIColor *)buttonBackgroundColor { + return [UIColor whiteColor]; +} +%end +%hook YCHLiveChatLabel +- (NSAttributedString *)attributedText { + NSAttributedString *originalAttributedString = %orig; + NSMutableAttributedString *modifiedAttributedString = [originalAttributedString mutableCopy]; + [modifiedAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, modifiedAttributedString.length)]; + return modifiedAttributedString; +} +%end +%hook YTQTMButton +- (void)setImage:(UIImage *)image { + UIImage *currentImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + [self setTintColor:[UIColor whiteColor]]; + %orig(currentImage); +} +%end +%hook UIExtendedSRGColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9]; + %orig(); +} +%end +%hook UIExtendedSRGBColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:1.0]; + %orig(); +} +%end +%hook UIExtendedGrayColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:1.0]; + %orig(); +} +%end +%hook VideoTitleLabel +- (void)setTextColor:(UIColor *)textColor { + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UILabel ++ (void)load { + @autoreleasepool { + [[UILabel appearance] setTextColor:[UIColor whiteColor]]; + } +} +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UITextField +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UITextView +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UISearchBar +- (void)setTextColor:(UIColor *)textColor { + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UISegmentedControl +- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + %orig(modifiedAttributes, state); +} +%end +%hook UIButton +- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state { + color = [UIColor whiteColor]; + %orig(color, state); +} +%end +%hook UIBarButtonItem +- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + %orig(modifiedAttributes, state); +} +%end +%hook NSAttributedString +- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary *)attrs { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attrs]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + return %orig(str, modifiedAttributes); +} +%end +%hook CATextLayer +- (void)setTextColor:(CGColorRef)textColor { + %orig([UIColor whiteColor].CGColor); +} +%end +%hook ASTextNode +- (NSAttributedString *)attributedString { + NSAttributedString *originalAttributedString = %orig; + NSMutableAttributedString *newAttributedString = [originalAttributedString mutableCopy]; + [newAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, newAttributedString.length)]; + return newAttributedString; +} +%end +%hook ASTextFieldNode +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%hook ASTextView +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%hook ASButtonNode +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%end + +%group gCustomContrastMode // Custom Contrast Mode (Hex Color) +%hook UIColor ++ (UIColor *)whiteColor { + return lcmHexColor; +} ++ (UIColor *)lightTextColor { + return lcmHexColor; +} ++ (UIColor *)lightGrayColor { + return lcmHexColor; +} ++ (UIColor *)ychGrey7 { + return lcmHexColor; +} ++ (UIColor *)skt_chipBackgroundColor { + return lcmHexColor; +} ++ (UIColor *)placeholderTextColor { + return lcmHexColor; +} ++ (UIColor *)systemLightGrayColor { + return lcmHexColor; +} ++ (UIColor *)systemExtraLightGrayColor { + return lcmHexColor; +} ++ (UIColor *)labelColor { + return lcmHexColor; +} ++ (UIColor *)secondaryLabelColor { + return lcmHexColor; +} ++ (UIColor *)tertiaryLabelColor { + return lcmHexColor; +} ++ (UIColor *)quaternaryLabelColor { + return lcmHexColor; +} +%end +%hook YTCommonColorPalette +- (UIColor *)textPrimary { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)textSecondary { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)overlayTextPrimary { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)overlayTextSecondary { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)iconActive { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)iconActiveOther { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)brandIconActive { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)staticBrandWhite { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)overlayIconActiveOther { + return self.pageStyle == 1 ? lcmHexColor : %orig; +} +- (UIColor *)overlayIconInactive { + return self.pageStyle == 1 ? [lcmHexColor colorWithAlphaComponent:0.7] : %orig; +} +- (UIColor *)overlayIconDisabled { + return self.pageStyle == 1 ? [lcmHexColor colorWithAlphaComponent:0.3] : %orig; +} +- (UIColor *)overlayFilledButtonActive { + return self.pageStyle == 1 ? [lcmHexColor colorWithAlphaComponent:0.2] : %orig; +} +%end +%hook YTColor ++ (BOOL)darkerPaletteTextColorEnabled { + return NO; +} ++ (UIColor *)white1 { + return lcmHexColor; +} ++ (UIColor *)white2 { + return lcmHexColor; +} ++ (UIColor *)white3 { + return lcmHexColor; +} ++ (UIColor *)white4 { + return lcmHexColor; +} ++ (UIColor *)white5 { + return lcmHexColor; +} ++ (UIColor *)grey1 { + return lcmHexColor; +} ++ (UIColor *)grey2 { + return lcmHexColor; +} +%end +%hook QTMColorGroup +- (UIColor *)tint100 { + return [UIColor whiteColor]; +} +- (UIColor *)tint300 { + return [UIColor whiteColor]; +} +- (UIColor *)tint500 { + return [UIColor whiteColor]; +} +- (UIColor *)tint700 { + return [UIColor whiteColor]; +} +- (UIColor *)accent200 { + return [UIColor whiteColor]; +} +- (UIColor *)accent400 { + return [UIColor whiteColor]; +} +- (UIColor *)accentColor { + return [UIColor whiteColor]; +} +- (UIColor *)brightAccentColor { + return [UIColor whiteColor]; +} +- (UIColor *)regularColor { + return [UIColor whiteColor]; +} +- (UIColor *)darkerColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColor { + return [UIColor whiteColor]; +} +- (UIColor *)lightBodyTextColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnRegularColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnLighterColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnDarkerColor { + return [UIColor whiteColor]; +} +- (UIColor *)bodyTextColorOnAccentColor { + return [UIColor whiteColor]; +} +- (UIColor *)buttonBackgroundColor { + return [UIColor whiteColor]; +} +%end +%hook YTQTMButton +- (void)setImage:(UIImage *)image { + UIImage *currentImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + [self setTintColor:[UIColor whiteColor]]; + %orig(currentImage); +} +%end +%hook UIExtendedSRGColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9]; + %orig(); +} +%end +%hook UIExtendedSRGBColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:1.0]; + %orig(); +} +%end +%hook UIExtendedGrayColorSpace +- (void)setTextColor:(UIColor *)textColor { + textColor = [[UIColor whiteColor] colorWithAlphaComponent:1.0]; + %orig(); +} +%end +%hook VideoTitleLabel +- (void)setTextColor:(UIColor *)textColor { + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UILabel ++ (void)load { + @autoreleasepool { + [[UILabel appearance] setTextColor:[UIColor whiteColor]]; + } +} +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UITextField +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UITextView +- (void)setTextColor:(UIColor *)textColor { + %log; + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UISearchBar +- (void)setTextColor:(UIColor *)textColor { + textColor = [UIColor whiteColor]; + %orig(textColor); +} +%end +%hook UISegmentedControl +- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + %orig(modifiedAttributes, state); +} +%end +%hook UIButton +- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state { + color = [UIColor whiteColor]; + %orig(color, state); +} +%end +%hook UIBarButtonItem +- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + %orig(modifiedAttributes, state); +} +%end +%hook NSAttributedString +- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary *)attrs { + NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attrs]; + [modifiedAttributes setObject:[UIColor whiteColor] forKey:NSForegroundColorAttributeName]; + return %orig(str, modifiedAttributes); +} +%end +%hook CATextLayer +- (void)setTextColor:(CGColorRef)textColor { + %orig([UIColor whiteColor].CGColor); +} +%end +%hook ASTextNode +- (NSAttributedString *)attributedString { + NSAttributedString *originalAttributedString = %orig; + NSMutableAttributedString *newAttributedString = [originalAttributedString mutableCopy]; + [newAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, newAttributedString.length)]; + return newAttributedString; +} +%end +%hook ASTextFieldNode +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%hook ASTextView +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%hook ASButtonNode +- (void)setTextColor:(UIColor *)textColor { + %orig([UIColor whiteColor]); +} +%end +%end + +# pragma mark - ctor +%ctor { + %init; + if (lowContrastMode()) { + %init(gLowContrastMode); + } + if (customContrastMode()) { + NSData *lcmColorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomUIColor"]; + NSKeyedUnarchiver *lcmUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:lcmColorData error:nil]; + [lcmUnarchiver setRequiresSecureCoding:NO]; + NSString *lcmHexString = [lcmUnarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + if (lcmHexString != nil) { + lcmHexColor = [lcmUnarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + %init(gCustomContrastMode); + } + } +} diff --git a/Sources/YTCastConfirm.xm b/Sources/YTCastConfirm.xm index c5d5200..e23c5f8 100644 --- a/Sources/YTCastConfirm.xm +++ b/Sources/YTCastConfirm.xm @@ -18,4 +18,4 @@ extern NSBundle *uYouPlusBundle(); return %orig; } } -%end \ No newline at end of file +%end diff --git a/Sources/YTReExplore.x b/Sources/YTReExplore.x index 275ae8c..4fb8009 100644 --- a/Sources/YTReExplore.x +++ b/Sources/YTReExplore.x @@ -42,4 +42,4 @@ static void replaceTab(YTIGuideResponse *response) { if (IS_ENABLED(@"reExplore_enabled")) { %init(YTReExplore); } -} \ No newline at end of file +} diff --git a/Sources/uYouPlus.h b/Sources/uYouPlus.h index befa6fb..8774343 100644 --- a/Sources/uYouPlus.h +++ b/Sources/uYouPlus.h @@ -6,39 +6,279 @@ #import #import -#import "uYouPlusThemes.h" // Hide "Buy Super Thanks" banner (_ASDisplayView) -#import "../Tweaks/YouTubeHeader/YTAppDelegate.h" // Activate FLEX -#import "../Tweaks/YouTubeHeader/YTIMenuConditionalServiceItemRenderer.h" - -// #import "../Tweaks/YouTubeHeader/YTISectionListRenderer.h" // Hide search ads by @PoomSmart - https://github.com/PoomSmart/YouTube-X +#import "Tweaks/YouTubeHeader/YTAppDelegate.h" +#import "Tweaks/YouTubeHeader/YTPlayerViewController.h" +#import "Tweaks/YouTubeHeader/YTQTMButton.h" +#import "Tweaks/YouTubeHeader/YTVideoQualitySwitchOriginalController.h" +#import "Tweaks/YouTubeHeader/YTPlayerViewController.h" +#import "Tweaks/YouTubeHeader/YTWatchController.h" +#import "Tweaks/YouTubeHeader/YTIGuideResponse.h" +#import "Tweaks/YouTubeHeader/YTIGuideResponseSupportedRenderers.h" +#import "Tweaks/YouTubeHeader/YTIPivotBarSupportedRenderers.h" +#import "Tweaks/YouTubeHeader/YTIPivotBarItemRenderer.h" +#import "Tweaks/YouTubeHeader/YTIPivotBarRenderer.h" +#import "Tweaks/YouTubeHeader/YTIBrowseRequest.h" +#import "Tweaks/YouTubeHeader/YTIButtonRenderer.h" +#import "Tweaks/YouTubeHeader/YTISectionListRenderer.h" +#import "Tweaks/YouTubeHeader/YTColorPalette.h" +#import "Tweaks/YouTubeHeader/YTCommonColorPalette.h" +#import "Tweaks/YouTubeHeader/YTSettingsSectionItemManager.h" +#import "Tweaks/YouTubeHeader/ASCollectionView.h" +#import "Tweaks/YouTubeHeader/YTPlayerOverlay.h" +#import "Tweaks/YouTubeHeader/YTPlayerOverlayProvider.h" +#import "Tweaks/YouTubeHeader/YTReelWatchPlaybackOverlayView.h" +#import "Tweaks/YouTubeHeader/YTReelPlayerBottomButton.h" +#import "Tweaks/YouTubeHeader/YTReelPlayerViewController.h" +#import "Tweaks/YouTubeHeader/YTIMenuConditionalServiceItemRenderer.h" +#import "Tweaks/YouTubeHeader/YTPivotBarItemView.h" +#import "Tweaks/YouTubeHeader/YTVideoWithContextNode.h" // YouTube-X +#import "Tweaks/YouTubeHeader/ELMCellNode.h" // YouTube-X +#import "Tweaks/YouTubeHeader/ELMNodeController.h" // YouTube-X #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define APP_THEME_IDX [[NSUserDefaults standardUserDefaults] integerForKey:@"appTheme"] +#define YT_BUNDLE_ID @"com.google.ios.youtube" +#define YT_NAME @"YouTube" +#define DEFAULT_RATE 1.0f // YTSpeed +#define LOWCONTRASTMODE_CUTOFF_VERSION @"17.38.10" // LowContrastMode + +@interface YTSingleVideoController () +- (float)playbackRate; +- (void)setPlaybackRate:(float)arg1; +@end + +@interface YTPlayerViewController () +- (YTSingleVideoController *)activeVideo; +@end + +// IAmYouTube +@interface SSOConfiguration : NSObject +@end + +// uYouPlus +@interface YTHeaderLogoController : UIView +@property(readonly, nonatomic) long long pageStyle; +@end + +@interface YTNavigationBarTitleView : UIView +@end + +@interface YTChipCloudCell : UIView +@end + +@interface YTPlayabilityResolutionUserActionUIController : NSObject // Skips content warning before playing *some videos - @PoomSmart +- (void)confirmAlertDidPressConfirm; +@end + +@interface YTMainAppControlsOverlayView : UIView +@end + +@interface YTTransportControlsButtonView : UIView +@end + +@interface _ASCollectionViewCell : UICollectionViewCell +- (id)node; +@end + +@interface YTAsyncCollectionView : UICollectionView +@end + +@interface FRPSliderCell : UITableViewCell +@end + +@interface boolSettingsVC : UIViewController +@end + +@interface YTPlaybackButton : UIControl +@end + +@interface PlayerManager : NSObject +- (float)progress; +@end -// Disable snap to chapter @interface YTSegmentableInlinePlayerBarView @property (nonatomic, assign, readwrite) BOOL enableSnapToChapter; @end -// Hide autoplay switch / CC button -@interface YTMainAppControlsOverlayView : UIView +@interface YTPlaylistHeaderViewController: UIViewController +@property UIButton *downloadsButton; @end -// Skips content warning before playing *some videos - @PoomSmart -@interface YTPlayabilityResolutionUserActionUIController : NSObject -- (void)confirmAlertDidPressConfirm; -@end - -// Hide iSponsorBlock +// Buttons @interface YTRightNavigationButtons : UIView -@property (nonatomic, readwrite, strong) UIView *sponsorBlockButton; +@property YTQTMButton *notificationButton; +@property YTQTMButton *sponsorBlockButton; @end -// Hide YouTube annoying banner in Home page? - @MiRO92 - YTNoShorts: https://github.com/MiRO92/YTNoShorts -@interface _ASCollectionViewCell : UICollectionViewCell -- (id)node; +@interface YTISlimMetadataButtonSupportedRenderers : NSObject +- (id)slimButton_buttonRenderer; +- (id)slimMetadataButtonRenderer; @end -@interface YTAsyncCollectionView : UICollectionView -- (void)removeShortsAndFeaturesAdsAtIndexPath:(NSIndexPath *)indexPath; + +// YTSpeed +@interface YTVarispeedSwitchControllerOption : NSObject +- (id)initWithTitle:(id)title rate:(float)rate; +@end + +@interface MLHAMQueuePlayer : NSObject +@property id playerEventCenter; +@property id delegate; +- (void)setRate:(float)rate; +- (void)internalSetRate; +@end + +@interface MLPlayerStickySettings : NSObject +- (void)setRate:(float)rate; +@end + +@interface MLPlayerEventCenter : NSObject +- (void)broadcastRateChange:(float)rate; +@end + +@interface HAMPlayerInternal : NSObject +- (void)setRate:(float)rate; +@end + +// iOS16 fix +@interface OBPrivacyLinkButton : UIButton +- (instancetype)initWithCaption:(NSString *)caption + buttonText:(NSString *)buttonText + image:(UIImage *)image + imageSize:(CGSize)imageSize + useLargeIcon:(BOOL)useLargeIcon + displayLanguage:(NSString *)displayLanguage; +@end + +// Fix uYou's appearance not updating if the app is backgrounded +@interface DownloadsPagerVC : UIViewController +- (NSArray *)viewControllers; +- (void)updatePageStyles; +@end +@interface DownloadingVC : UIViewController +- (void)updatePageStyles; +- (UITableView *)tableView; +@end +@interface DownloadingCell : UITableViewCell +- (void)updatePageStyles; +@end +@interface DownloadedVC : UIViewController +- (void)updatePageStyles; +- (UITableView *)tableView; +@end +@interface DownloadedCell : UITableViewCell +- (void)updatePageStyles; +@end +@interface UILabel (uYou) ++ (id)_defaultColor; +@end + +// YTAutoFullScreen +@interface YTPlayerViewController (YTAFS) +- (void)autoFullscreen; +// YTSpeed +@property id activeVideo; +@property float playbackRate; +- (void)singleVideo:(id)video playbackRateDidChange:(float)rate; +// uYouCrashFix +- (YTSingleVideoController *)activeVideo; +@end + +// App Theme +@interface YTColor : NSObject ++ (UIColor *)white1; ++ (UIColor *)white2; ++ (UIColor *)white3; ++ (UIColor *)white4; ++ (UIColor *)white5; ++ (UIColor *)black0; ++ (UIColor *)black1; ++ (UIColor *)black2; ++ (UIColor *)black3; ++ (UIColor *)black4; ++ (UIColor *)blackPure; ++ (UIColor *)grey1; ++ (UIColor *)grey2; ++ (UIColor *)white1Alpha98; ++ (UIColor *)white1Alpha95; +@end + +@interface YCHLiveChatView : UIView +@end + +@interface YTFullscreenEngagementOverlayView : UIView +@end + +@interface YTRelatedVideosView : UIView +@end + +@interface YTTopAlignedView : UIView +@end + +@interface ELMView : UIView +@end + +@interface ASWAppSwitcherCollectionViewCell : UIView +@end + +@interface ASScrollView : UIView +@end + +@interface UIKeyboardLayoutStar : UIView +@end + +@interface UIKeyboardDockView : UIView +@end + +@interface _ASDisplayView : UIView +@end + +@interface ELMContainerNode : NSObject +@end + +@interface YTAutonavEndscreenView : UIView +@end + +@interface YTPivotBarIndicatorView : UIView +@end + +@interface YTCommentDetailHeaderCell : UIView +@end + +@interface SponsorBlockSettingsController : UITableViewController +@end + +@interface SponsorBlockViewController : UIViewController +@end + +@interface UICandidateViewController : UIViewController +@end + +@interface UIPredictionViewController : UIViewController +@end + +@interface FRPreferences : UITableViewController +@end + +@interface FRPSelectListTable : UITableViewController +@end + +@interface settingsReorderTable : UIViewController +@property(nonatomic, strong) UITableView *tableView; +@end + +// Snack bar +@interface YTHUDMessage : NSObject ++ (id)messageWithText:(id)text; +- (void)setAction:(id)action; +@end + +@interface GOOHUDMessageAction : NSObject +- (void)setTitle:(NSString *)title; +- (void)setHandler:(void (^)(id))handler; +@end + +@interface GOOHUDManagerInternal : NSObject +- (void)showMessageMainThread:(id)message; ++ (id)sharedInstance; @end diff --git a/Sources/uYouPlus.xm b/Sources/uYouPlus.xm index 1f48f0a..9e1bc08 100644 --- a/Sources/uYouPlus.xm +++ b/Sources/uYouPlus.xm @@ -15,11 +15,586 @@ NSBundle *uYouPlusBundle() { } NSBundle *tweakBundle = uYouPlusBundle(); -# pragma mark - App appearance -// See uYouPlusThemes.xm +// Keychain fix +static NSString *accessGroupID() { + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass, + @"bundleSeedID", kSecAttrAccount, + @"", kSecAttrService, + (id)kCFBooleanTrue, kSecReturnAttributes, + nil]; + CFDictionaryRef result = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); + if (status == errSecItemNotFound) + status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); + if (status != errSecSuccess) + return nil; + NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; + + return accessGroup; +} + +# pragma mark - Tweaks + +// Activate FLEX +%hook YTAppDelegate +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + BOOL didFinishLaunching = %orig; + + if (IS_ENABLED(@"flex_enabled")) { + [[%c(FLEXManager) performSelector:@selector(sharedManager)] performSelector:@selector(showExplorer)]; + } + + return didFinishLaunching; +} +- (void)appWillResignActive:(id)arg1 { + %orig; + if (IS_ENABLED(@"flex_enabled")) { + [[%c(FLEXManager) performSelector:@selector(sharedManager)] performSelector:@selector(showExplorer)]; + } +} +%end + +// Hide YouTube Logo - @dayanch96 +%group gHideYouTubeLogo +%hook YTHeaderLogoController +- (YTHeaderLogoController *)init { + return NULL; +} +%end +%hook YTNavigationBarTitleView +- (void)layoutSubviews { + %orig; + if (self.subviews.count > 1 && [self.subviews[1].accessibilityIdentifier isEqualToString:@"id.yoodle.logo"]) { + self.subviews[1].hidden = YES; + } +} +%end +%end + +%group gCenterYouTubeLogo +%hook YTNavigationBarTitleView +- (void)setShouldCenterNavBarTitleView:(BOOL)center { + %orig(YES); +} +- (BOOL)shouldCenterNavBarTitleView { + return YES; +} +- (void)alignCustomViewToCenterOfWindow { +} +%end +%end + +// YouTube Premium Logo - @arichorn - this doesn't always function +%group gPremiumYouTubeLogo +%hook YTHeaderLogoController +- (void)setPremiumLogo:(BOOL)isPremiumLogo { + isPremiumLogo = YES; + %orig; +} +- (BOOL)isPremiumLogo { + return YES; +} +- (void)setTopbarLogoRenderer:(id)renderer { +} +%end + +// Workaround: fix YouTube Premium Logo not working on v18.35.4 or above. +%hook YTVersionUtils // Working Version for Premium Logo ++ (NSString *)appVersion { return @"18.34.5"; } +%end + +%hook YTSettingsCell // Remove v18.34.5 Version Number - @Dayanch96 +- (void)setDetailText:(id)arg1 { + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + NSString *appVersion = infoDictionary[@"CFBundleShortVersionString"]; + + if ([arg1 isEqualToString:@"18.34.5"]) { + arg1 = appVersion; + } %orig(arg1); +} +%end +%end + +// IAmYouTube - https://github.com/PoomSmart/IAmYouTube/ +%hook YTVersionUtils ++ (NSString *)appName { return YT_NAME; } ++ (NSString *)appID { return YT_BUNDLE_ID; } +%end + +%hook GCKBUtils ++ (NSString *)appIdentifier { return YT_BUNDLE_ID; } +%end + +%hook GPCDeviceInfo ++ (NSString *)bundleId { return YT_BUNDLE_ID; } +%end + +%hook OGLBundle ++ (NSString *)shortAppName { return YT_NAME; } +%end + +%hook GVROverlayView ++ (NSString *)appName { return YT_NAME; } +%end + +%hook OGLPhenotypeFlagServiceImpl +- (NSString *)bundleId { return YT_BUNDLE_ID; } +%end + +%hook APMAEU ++ (BOOL)isFAS { return YES; } +%end + +%hook GULAppEnvironmentUtil ++ (BOOL)isFromAppStore { return YES; } +%end + +%hook SSOConfiguration +- (id)initWithClientID:(id)clientID supportedAccountServices:(id)supportedAccountServices { + self = %orig; + [self setValue:YT_NAME forKey:@"_shortAppName"]; + [self setValue:YT_BUNDLE_ID forKey:@"_applicationIdentifier"]; + return self; +} +%end + +%hook NSBundle +- (NSString *)bundleIdentifier { + NSArray *address = [NSThread callStackReturnAddresses]; + Dl_info info = {0}; + if (dladdr((void *)[address[2] longLongValue], &info) == 0) + return %orig; + NSString *path = [NSString stringWithUTF8String:info.dli_fname]; + if ([path hasPrefix:NSBundle.mainBundle.bundlePath]) + return YT_BUNDLE_ID; + return %orig; +} +- (id)objectForInfoDictionaryKey:(NSString *)key { + if ([key isEqualToString:@"CFBundleIdentifier"]) + return YT_BUNDLE_ID; + if ([key isEqualToString:@"CFBundleDisplayName"] || [key isEqualToString:@"CFBundleName"]) + return YT_NAME; + return %orig; +} +// Fix Google Sign in by @PoomSmart & @level3tjg (qnblackcat/uYouPlus#684) +- (NSDictionary *)infoDictionary { + NSMutableDictionary *info = %orig.mutableCopy; + NSString *altBundleIdentifier = info[@"ALTBundleIdentifier"]; + if (altBundleIdentifier) info[@"CFBundleIdentifier"] = altBundleIdentifier; + return info; +} +%end + +// Fix login for YouTube 18.13.2 and higher - @BandarHL +%hook SSOKeychainHelper ++ (NSString *)accessGroup { + return accessGroupID(); +} ++ (NSString *)sharedAccessGroup { + return accessGroupID(); +} +%end + +// Fix login for YouTube 17.33.2 and higher - @BandarHL +// https://gist.github.com/BandarHL/492d50de46875f9ac7a056aad084ac10 +%hook SSOKeychainCore ++ (NSString *)accessGroup { + return accessGroupID(); +} + ++ (NSString *)sharedAccessGroup { + return accessGroupID(); +} +%end + +// Fix App Group Directory by move it to document directory +%hook NSFileManager +- (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier { + if (groupIdentifier != nil) { + NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; + NSURL *documentsURL = [paths lastObject]; + return [documentsURL URLByAppendingPathComponent:@"AppGroup"]; + } + return %orig(groupIdentifier); +} +%end + +// YTMiniPlayerEnabler: https://github.com/level3tjg/YTMiniplayerEnabler/ +%hook YTWatchMiniBarViewController +- (void)updateMiniBarPlayerStateFromRenderer { + if (IS_ENABLED(@"ytMiniPlayer_enabled")) {} + else { return %orig; } +} +%end + +// YTNoHoverCards: https://github.com/level3tjg/YTNoHoverCards +%hook YTCreatorEndscreenView +- (void)setHidden:(BOOL)hidden { + if (IS_ENABLED(@"hideHoverCards_enabled")) + hidden = YES; + %orig; +} +%end + +// YTClassicVideoQuality: https://github.com/PoomSmart/YTClassicVideoQuality +%hook YTIMediaQualitySettingsHotConfig + +%new(B@:) - (BOOL)enableQuickMenuVideoQualitySettings { return NO; } + +%end + +// %hook YTVideoQualitySwitchControllerFactory +// - (id)videoQualitySwitchControllerWithParentResponder:(id)responder { +// Class originalClass = %c(YTVideoQualitySwitchOriginalController); +// return originalClass ? [[originalClass alloc] initWithParentResponder:responder] : %orig; +// } +// %end + +// A/B flags +%hook YTColdConfig +- (BOOL)respectDeviceCaptionSetting { return NO; } // YouRememberCaption: https://poomsmart.github.io/repo/depictions/youremembercaption.html +- (BOOL)isLandscapeEngagementPanelSwipeRightToDismissEnabled { return YES; } // Swipe right to dismiss the right panel in fullscreen mode +%end + +// NOYTPremium - https://github.com/PoomSmart/NoYTPremium/ +%hook YTCommerceEventGroupHandler +- (void)addEventHandlers {} +%end + +%hook YTInterstitialPromoEventGroupHandler +- (void)addEventHandlers {} +%end + +%hook YTPromosheetEventGroupHandler +- (void)addEventHandlers {} +%end + +%hook YTPromoThrottleController +- (BOOL)canShowThrottledPromo { return NO; } +- (BOOL)canShowThrottledPromoWithFrequencyCap:(id)arg1 { return NO; } +- (BOOL)canShowThrottledPromoWithFrequencyCaps:(id)arg1 { return NO; } +%end + +%hook YTIShowFullscreenInterstitialCommand +- (BOOL)shouldThrottleInterstitial { return YES; } +%end + +%hook YTSurveyController +- (void)showSurveyWithRenderer:(id)arg1 surveyParentResponder:(id)arg2 {} +%end + +%hook YTIOfflineabilityFormat +%new +- (int)availabilityType { return 1; } +%new +- (BOOL)savedSettingShouldExpire { return NO; } +%end + +// YTShortsProgress - https://github.com/PoomSmart/YTShortsProgress/ +%hook YTShortsPlayerViewController +- (BOOL)shouldAlwaysEnablePlayerBar { return YES; } +- (BOOL)shouldEnablePlayerBarOnlyOnPause { return NO; } +%end + +%hook YTReelPlayerViewController +- (BOOL)shouldAlwaysEnablePlayerBar { return YES; } +- (BOOL)shouldEnablePlayerBarOnlyOnPause { return NO; } +%end + +%hook YTReelPlayerViewControllerSub +- (BOOL)shouldAlwaysEnablePlayerBar { return YES; } +- (BOOL)shouldEnablePlayerBarOnlyOnPause { return NO; } +%end + +%hook YTColdConfig +- (BOOL)iosEnableVideoPlayerScrubber { return YES; } +- (BOOL)mobileShortsTablnlinedExpandWatchOnDismiss { return YES; } +%end + +%hook YTHotConfig +- (BOOL)enablePlayerBarForVerticalVideoWhenControlsHiddenInFullscreen { return YES; } +%end + +// YTNoTracking - @arichorn - https://github.com/arichorn/YTNoTracking/ +%hook UIApplication +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { + NSString *originalURLString = [url absoluteString]; + NSString *modifiedURLString = originalURLString; + if ([modifiedURLString isEqualToString:originalURLString]) { + modifiedURLString = [modifiedURLString stringByReplacingOccurrencesOfString:@"&si=[a-zA-Z0-9_-]+" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, modifiedURLString.length)]; + } + NSURL *modifiedURL = [NSURL URLWithString:modifiedURLString]; + BOOL result = %orig(application, modifiedURL, options); + return result; +} +%end + +%hook YTICompactLinkRenderer ++ (BOOL)hasTrackingParams { + return NO; +} +%end + +%hook YTIReelPlayerOverlayRenderer ++ (BOOL)hasTrackingParams { + return NO; +} +%end + +%hook YTIShareTargetServiceUpdateRenderer ++ (BOOL)hasTrackingParams { + return NO; +} +%end + +// YTNoPaidPromo: https://github.com/PoomSmart/YTNoPaidPromo +%hook YTMainAppVideoPlayerOverlayViewController +- (void)setPaidContentWithPlayerData:(id)data { + if (IS_ENABLED(@"hidePaidPromotionCard_enabled")) {} + else { return %orig; } +} +- (void)playerOverlayProvider:(YTPlayerOverlayProvider *)provider didInsertPlayerOverlay:(YTPlayerOverlay *)overlay { + if ([[overlay overlayIdentifier] isEqualToString:@"player_overlay_paid_content"] && IS_ENABLED(@"hidePaidPromotionCard_enabled")) return; + %orig; +} +%end + +%hook YTInlineMutedPlaybackPlayerOverlayViewController +- (void)setPaidContentWithPlayerData:(id)data { + if (IS_ENABLED(@"hidePaidPromotionCard_enabled")) {} + else { return %orig; } +} +%end + +// Fix LowContrastMode - @arichorn +%group gFixLowContrastMode +%hook YTVersionUtils // Supported LowContrastMode Version ++ (NSString *)appVersion { return @"17.38.10"; } +%end + +%hook YTSettingsCell // Remove v17.38.10 Version Number - @Dayanch96 +- (void)setDetailText:(id)arg1 { + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + NSString *appVersion = infoDictionary[@"CFBundleShortVersionString"]; + + if ([arg1 isEqualToString:@"17.38.10"]) { + arg1 = appVersion; + } %orig(arg1); +} +%end +%end + +// Disable Modern/Rounded Buttons (_ASDisplayView not included) - @arichorn +%group gDisableModernButtons +%hook YTQTMButton // Disable Modern/Rounded Buttons ++ (BOOL)buttonModernizationEnabled { return NO; } +%end +%end + +// Disable Rounded Hints with no Rounded Corners - @arichorn +%group gDisableRoundedHints +%hook YTBubbleHintView // Disable Modern/Rounded Hints ++ (BOOL)modernRoundedCornersEnabled { return NO; } +%end +%end + +// Disable Modern Flags - @arichorn +%group gDisableModernFlags +%hook YTColdConfig +// Disable Modern Content +- (BOOL)creatorClientConfigEnableStudioModernizedMdeThumbnailPickerForClient { return NO; } +- (BOOL)cxClientEnableModernizedActionSheet { return NO; } +- (BOOL)enableClientShortsSheetsModernization { return NO; } +- (BOOL)enableTimestampModernizationForNative { return NO; } +- (BOOL)modernizeElementsTextColor { return NO; } +- (BOOL)modernizeElementsBgColor { return NO; } +- (BOOL)modernizeCollectionLockups { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableModernButtonsForNative { return NO; } +- (BOOL)uiSystemsClientGlobalConfigIosEnableModernTabsForNative { return NO; } +- (BOOL)uiSystemsClientGlobalConfigIosEnableEpUxUpdates { return NO; } +- (BOOL)uiSystemsClientGlobalConfigIosEnableSheetsUxUpdates { return NO; } +- (BOOL)uiSystemsClientGlobalConfigIosEnableSnackbarModernization { return NO; } +// Disable Rounded Content +- (BOOL)iosDownloadsPageRoundedThumbs { return NO; } +- (BOOL)iosRoundedSearchBarSuggestZeroPadding { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableRoundedDialogForNative { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableRoundedThumbnailsForNative { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableRoundedThumbnailsForNativeLongTail { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableRoundedTimestampForNative { return NO; } +// Disable Optional Content +- (BOOL)elementsClientIosElementsEnableLayoutUpdateForIob { return NO; } +- (BOOL)supportElementsInMenuItemSupportedRenderers { return NO; } +- (BOOL)isNewRadioButtonStyleEnabled { return NO; } +- (BOOL)uiSystemsClientGlobalConfigEnableButtonSentenceCasingForNative { return NO; } +- (BOOL)mainAppCoreClientEnableClientYouTab { return NO; } +- (BOOL)mainAppCoreClientEnableClientYouLatency { return NO; } +- (BOOL)mainAppCoreClientEnableClientYouTabTablet { return NO; } +%end + +%hook YTHotConfig +- (BOOL)liveChatIosUseModernRotationDetection { return NO; } // Disable Modern Content (YTHotConfig) +- (BOOL)liveChatModernizeClassicElementizeTextMessage { return NO; } +- (BOOL)iosShouldRepositionChannelBar { return NO; } +- (BOOL)enableElementRendererOnChannelCreation { return NO; } +%end +%end + +// Disable Ambient Mode in Fullscreen - @arichorn +%group gDisableAmbientMode +%hook YTCinematicContainerView +- (BOOL)watchFullScreenCinematicSupported { + return NO; +} +- (BOOL)watchFullScreenCinematicEnabled { + return NO; +} +%end +%hook YTColdConfig +- (BOOL)disableCinematicForLowPowerMode { return NO; } +- (BOOL)enableCinematicContainer { return NO; } +- (BOOL)enableCinematicContainerOnClient { return NO; } +- (BOOL)enableCinematicContainerOnTablet { return NO; } +- (BOOL)enableTurnOffCinematicForFrameWithBlackBars { return YES; } +- (BOOL)enableTurnOffCinematicForVideoWithBlackBars { return YES; } +- (BOOL)iosCinematicContainerClientImprovement { return NO; } +- (BOOL)iosEnableGhostCardInlineTitleCinematicContainerFix { return NO; } +- (BOOL)iosUseFineScrubberMosaicStoreForCinematic { return NO; } +- (BOOL)mainAppCoreClientEnableClientCinematicPlaylists { return NO; } +- (BOOL)mainAppCoreClientEnableClientCinematicPlaylistsPostMvp { return NO; } +- (BOOL)mainAppCoreClientEnableClientCinematicTablets { return NO; } +- (BOOL)iosEnableFullScreenAmbientMode { return NO; } +%end +%end + +// Hide YouTube Heatwaves in Video Player (YouTube v17.19.2-latest) - @level3tjg - https://www.reddit.com/r/jailbreak/comments/v29yvk/ +%group gHideHeatwaves +%hook YTInlinePlayerBarContainerView +- (BOOL)canShowHeatwave { return NO; } +%end +%end + +// YTNoSuggestedVideo - https://github.com/bhackel/YTNoSuggestedVideo +%hook YTMainAppVideoPlayerOverlayViewController +- (bool)shouldShowAutonavEndscreen { + if (IS_ENABLED(@"noSuggestedVideo_enabled")) { + return false; + } + return %orig; +} +%end + +# pragma mark - Hide Notification Button && SponsorBlock Button +%hook YTRightNavigationButtons +- (void)layoutSubviews { + %orig; + if (IS_ENABLED(@"hideNotificationButton_enabled")) { + self.notificationButton.hidden = YES; + } + if (IS_ENABLED(@"hideSponsorBlockButton_enabled")) { + self.sponsorBlockButton.hidden = YES; + } +} +%end + +// YTSpeed - https://github.com/Lyvendia/YTSpeed +%group gYTSpeed +%hook YTVarispeedSwitchController +- (id)init { + id result = %orig; + + const int size = 17; + float speeds[] = {0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 5.0}; + id varispeedSwitchControllerOptions[size]; + + for (int i = 0; i < size; ++i) { + id title = [NSString stringWithFormat:@"%.2fx", speeds[i]]; + varispeedSwitchControllerOptions[i] = [[%c(YTVarispeedSwitchControllerOption) alloc] initWithTitle:title rate:speeds[i]]; + } + + NSUInteger count = sizeof(varispeedSwitchControllerOptions) / sizeof(id); + NSArray *varispeedArray = [NSArray arrayWithObjects:varispeedSwitchControllerOptions count:count]; + MSHookIvar(self, "_options") = varispeedArray; + + return result; +} +%end + +%hook MLHAMQueuePlayer +- (void)setRate:(float)rate { + MSHookIvar(self, "_rate") = rate; + MSHookIvar(self, "_preferredRate") = rate; + + id player = MSHookIvar(self, "_player"); + [player setRate: rate]; + + id stickySettings = MSHookIvar(self, "_stickySettings"); + [stickySettings setRate: rate]; + + [self.playerEventCenter broadcastRateChange: rate]; + + YTSingleVideoController *singleVideoController = self.delegate; + [singleVideoController playerRateDidChange: rate]; +} +%end + +%hook YTPlayerViewController +%property (nonatomic, assign) float playbackRate; +- (void)singleVideo:(id)video playbackRateDidChange:(float)rate { + %orig; +} +%end +%end + +# pragma mark - uYouPlus +// Video Player Options +// Skips content warning before playing *some videos - @PoomSmart +%hook YTPlayabilityResolutionUserActionUIController +- (void)showConfirmAlert { [self confirmAlertDidPressConfirm]; } +%end + +// Portrait Fullscreen - @Dayanch96 +%group gPortraitFullscreen +%hook YTWatchViewController +- (unsigned long long)allowedFullScreenOrientations { + return UIInterfaceOrientationMaskAllButUpsideDown; +} +%end +%end + +// Disable snap to chapter +%hook YTSegmentableInlinePlayerBarView +- (void)didMoveToWindow { + %orig; + if (IS_ENABLED(@"snapToChapter_enabled")) { + self.enableSnapToChapter = NO; + } +} +%end + +// Disable Pinch to zoom +%hook YTColdConfig +- (BOOL)videoZoomFreeZoomEnabledGlobalConfig { + return IS_ENABLED(@"pinchToZoom_enabled") ? NO : %orig; +} +%end + +// YTStockVolumeHUD - https://github.com/lilacvibes/YTStockVolumeHUD +%group gStockVolumeHUD +%hook YTVolumeBarView +- (void)volumeChanged:(id)arg1 { + %orig(nil); +} +%end + +%hook UIApplication +- (void)setSystemVolumeHUDEnabled:(BOOL)arg1 forAudioCategory:(id)arg2 { + %orig(true, arg2); +} +%end +%end -# pragma mark - Video player options -// Bring back Slide to seek - https://github.com/PoomSmart/YTABConfig/discussions/95#discussioncomment-8166019 %hook YTColdConfig - (BOOL)speedMasterArm2FastForwardWithoutSeekBySliding { return IS_ENABLED(@"slideToSeek_enabled") ? NO : %orig; @@ -33,40 +608,29 @@ NSBundle *tweakBundle = uYouPlusBundle(); } %end -// Disable snap to chapter -%hook YTSegmentableInlinePlayerBarView -- (void)didMoveToWindow { - %orig; - if (IS_ENABLED(@"snapToChapter_enabled")) { - self.enableSnapToChapter = NO; - } -} -%end - -// Disable pinch to zoom -%hook YTColdConfig -- (BOOL)videoZoomFreeZoomEnabledGlobalConfig { - return IS_ENABLED(@"pinchToZoom_enabled") ? NO : %orig; -} -%end - -// Enable miniplayer for all videos -// See YTMiniPlayerEnabler.x - -// Use stock iOS volume HUD -// See YTStockVolumeHUD.xm - -# pragma mark - Video control overlay options - +// Video Controls Overlay Options +// Hide CC / Autoplay switch / Enable Share Button / Enable Save to Playlist Button %hook YTMainAppControlsOverlayView -// Hide autoplay switch +- (void)setClosedCaptionsOrSubtitlesButtonAvailable:(BOOL)arg1 { // hide CC button + return IS_ENABLED(@"hideCC_enabled") ? %orig(NO) : %orig; +} - (void)setAutoplaySwitchButtonRenderer:(id)arg1 { // hide Autoplay if (IS_ENABLED(@"hideAutoplaySwitch_enabled")) {} else { return %orig; } } -// Hide CC button -- (void)setClosedCaptionsOrSubtitlesButtonAvailable:(BOOL)arg1 { - return IS_ENABLED(@"hideCC_enabled") ? %orig(NO) : %orig; +- (void)setShareButtonAvailable:(BOOL)arg1 { + if (IS_ENABLED(@"enableShareButton_enabled")) { + %orig(YES); + } else { + %orig(NO); + } +} +- (void)setAddToButtonAvailable:(BOOL)arg1 { + if (IS_ENABLED(@"enableSaveToButton_enabled")) { + %orig(YES); + } else { + %orig(NO); + } } %end @@ -77,31 +641,51 @@ NSBundle *tweakBundle = uYouPlusBundle(); } %end -// Hide paid promotion banner -// See YTNoPaidPromo.x - -// Hide channel watermark -%hook YTAnnotationsViewController -- (void)loadFeaturedChannelWatermark { - if (IS_ENABLED(@"hideChannelWatermark_enabled")) {} - else { return %orig; } -} -%end +// Hide Channel Watermark %hook YTColdConfig - (BOOL)iosEnableFeaturedChannelWatermarkOverlayFix { return IS_ENABLED(@"hideChannelWatermark_enabled") ? NO : %orig; } %end -// Hide next and previous buttons +// Hide Channel Watermark (for Old YouTube Versions / Backwards Compatibility) +%hook YTAnnotationsViewController +- (void)loadFeaturedChannelWatermark { + if (IS_ENABLED(@"hideChannelWatermark_enabled")) {} + else { return %orig; } +} +%end + +// Hide Next & Previous button %group gHidePreviousAndNextButton %hook YTColdConfig - (BOOL)removeNextPaddleForSingletonVideos { return YES; } - (BOOL)removePreviousPaddleForSingletonVideos { return YES; } %end + +// %hook YTMainAppControlsOverlayView // this is only used for v16.xx.x (issues if using with YouTube v17.xx.x up to latest) +// - (void)layoutSubviews { // hide Next & Previous legacy buttons +// %orig; +// if (IsEnabled(@"hidePreviousAndNextButton_enabled")) { +// MSHookIvar(self, "_nextButton").hidden = YES; +// MSHookIvar(self, "_previousButton").hidden = YES; +// MSHookIvar(self, "_nextButtonView").hidden = YES; +// MSHookIvar(self, "_previousButtonView").hidden = YES; +// } +// } +// %end %end -// Replace next and previous buttons with fast forward and rewind +// Hide Dark Overlay Background +%group gHideOverlayDarkBackground +%hook YTMainAppVideoPlayerOverlayView +- (void)setBackgroundVisible:(BOOL)arg1 isGradientBackground:(BOOL)arg2 { + %orig(NO, arg2); +} +%end +%end + +// Replace Next & Previous button with Fast forward & Rewind button %group gReplacePreviousAndNextButton %hook YTColdConfig - (BOOL)replaceNextPaddleWithFastForwardButtonForSingletonVods { return YES; } @@ -109,68 +693,277 @@ NSBundle *tweakBundle = uYouPlusBundle(); %end %end -// Bring back the red progress bar - Broken?! +// Hide Shadow Overlay Buttons (Play/Pause, Next, previous, Fast forward & Rewind buttons) +%group gHideVideoPlayerShadowOverlayButtons +%hook YTMainAppControlsOverlayView +- (void)layoutSubviews { + %orig(); + MSHookIvar(self, "_previousButtonView").backgroundColor = nil; + MSHookIvar(self, "_nextButtonView").backgroundColor = nil; + MSHookIvar(self, "_seekBackwardAccessibilityButtonView").backgroundColor = nil; + MSHookIvar(self, "_seekForwardAccessibilityButtonView").backgroundColor = nil; + MSHookIvar(self, "_playPauseButton").backgroundColor = nil; +} +%end +%end + +// Bring back the Red Progress Bar and Gray Buffer Progress +%group gRedProgressBar %hook YTInlinePlayerBarContainerView - (id)quietProgressBarColor { - return IS_ENABLED(@"redProgressBar_enabled") ? [UIColor redColor] : %orig; + return [UIColor redColor]; } %end -// Hide videos' end screens -// See YTNoHoverCards.x +%hook YTSegmentableInlinePlayerBarView +- (void)setBufferedProgressBarColor:(id)arg1 { + [UIColor colorWithRed:1.00 green:1.00 blue:1.00 alpha:0.50]; +} +%end +%end -// Hide engagement panels in full screen +// Disable the right panel in fullscreen mode %hook YTColdConfig - (BOOL)isLandscapeEngagementPanelEnabled { return IS_ENABLED(@"hideRightPanel_enabled") ? NO : %orig; } %end -// Skips content warning before playing *some videos - @PoomSmart -%hook YTPlayabilityResolutionUserActionUIController -- (void)showConfirmAlert { [self confirmAlertDidPressConfirm]; } -%end - -# pragma mark - Shorts controls overlay options - -// Hide "Buy Super Thanks" banner +// Shorts Controls Overlay Options %hook _ASDisplayView - (void)didMoveToWindow { %orig; if ((IS_ENABLED(@"hideBuySuperThanks_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.suggested_action"])) { self.hidden = YES; } + +// Hide Header Links under Channel Profile - @arichorn + if ((IS_ENABLED(@"hideChannelHeaderLinks_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"eml.channel_header_links"])) { + self.hidden = YES; + self.opaque = YES; + self.userInteractionEnabled = NO; + [self sizeToFit]; + [self setNeedsLayout]; + [self removeFromSuperview]; + } + +// Hide the Comment Section under the Video Player - @arichorn + if ((IS_ENABLED(@"hideCommentSection_enabled")) && ([self.accessibilityIdentifier isEqualToString:@"id.ui.comments_entry_point_teaser"] + || [self.accessibilityIdentifier isEqualToString:@"id.ui.comments_entry_point_simplebox"] + || [self.accessibilityIdentifier isEqualToString:@"id.ui.video_metadata_carousel"] + || [self.accessibilityIdentifier isEqualToString:@"id.ui.carousel_header"])) { + self.hidden = YES; + self.opaque = YES; + self.userInteractionEnabled = NO; + CGRect bounds = self.frame; + bounds.size.height = 0; + self.frame = bounds; + [self setNeedsLayout]; + [self removeFromSuperview]; + } } %end -// Hide subscriptions button %hook YTReelWatchRootViewController - (void)setPausedStateCarouselView { - if (IS_ENABLED(@"hideSubcriptions_enabled")) {} + if (IS_ENABLED(@"hideSubscriptions_enabled")) {} else { return %orig; } } %end -// Disable resume to Shorts %hook YTShortsStartupCoordinator - (id)evaluateResumeToShorts { - return IS_ENABLED(@"disableResumeToShorts") ? nil : %orig; + return IS_ENABLED(@"disableResumeToShorts_enabled") ? nil : %orig; } %end -# pragma mark - Miscellaneous +// Hide Shorts Cells - @PoomSmart & @iCrazeiOS +%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*"]) { + return nil; + } + } + } +// Hide Community Posts - @michael-winay & @arichorn + if (IS_ENABLED(@"hideCommunityPosts_enabled")) { + if ([description containsString:@"post_base_wrapper.eml"]) { + return nil; + } + } + return %orig; +} +%end -// Hide iSponsorBlock -%hook YTRightNavigationButtons -- (void)didMoveToWindow { +/* Deprecated Code - Loads indefinitely on newer YouTube Versions +// Hide Community Posts - @michael-winay & @arichorn +%hook YTAsyncCollectionView +- (id)cellForItemAtIndexPath:(NSIndexPath *)indexPath { + UICollectionViewCell *cell = %orig; + + if ([cell isKindOfClass:objc_lookUpClass("_ASCollectionViewCell")]) { + _ASCollectionViewCell *cell = %orig; + if ([cell respondsToSelector:@selector(node)]) { + NSString *idToRemove = [[cell node] accessibilityIdentifier]; + if (IsEnabled(@"hideCommunityPosts_enabled")) { + if ([idToRemove rangeOfString:@"id.ui.backstage.post"].location != NSNotFound) { + [self removeShortsAndFeaturesAdsAtIndexPath:indexPath]; + } + } + } + } + return cell; +} +%new +- (void)removeShortsAndFeaturesAdsAtIndexPath:(NSIndexPath *)indexPath { + [self deleteItemsAtIndexPaths:@[indexPath]]; +} +%end +*/ + +// Red Subscribe Button - @arichorn +%hook ELMContainerNode +- (void)setBackgroundColor:(id)color { + NSString *description = [self description]; + if (IS_ENABLED(@"redSubscribeButton_enabled")) { + if ([description containsString:@"eml.compact_subscribe_button"]) { + color = [UIColor redColor]; + } + } +// Hide the Button Containers under the Video Player - 17.x.x and up - @arichorn + 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]; + } + } + %orig(color); +} +%end + +// Hide the (Connect / Share / Remix / Thanks / Download / Clip / Save) Buttons under the Video Player - 17.x.x and up - @arichornlover +%hook _ASDisplayView +- (void)layoutSubviews { %orig; - if (IS_ENABLED(@"hideiSponsorBlockButton_enabled")) - self.sponsorBlockButton.hidden = YES; + BOOL hideConnectButton = IS_ENABLED(@"hideConnectButton_enabled"); + BOOL hideShareButton = IS_ENABLED(@"hideShareButton_enabled"); + BOOL hideRemixButton = IS_ENABLED(@"hideRemixButton_enabled"); + BOOL hideThanksButton = IS_ENABLED(@"hideThanksButton_enabled"); + BOOL hideAddToOfflineButton = IS_ENABLED(@"hideAddToOfflineButton_enabled"); + BOOL hideClipButton = IS_ENABLED(@"hideClipButton_enabled"); + BOOL hideSaveToPlaylistButton = IS_ENABLED(@"hideSaveToPlaylistButton_enabled"); + + for (UIView *subview in self.subviews) { + if ([subview.accessibilityLabel isEqualToString:@"connect account"]) { + subview.hidden = hideConnectButton; + } else if ([subview.accessibilityIdentifier isEqualToString:@"id.video.share.button"] || [subview.accessibilityLabel isEqualToString:@"Share"]) { + subview.hidden = hideShareButton; + } else if ([subview.accessibilityIdentifier isEqualToString:@"id.video.remix.button"] || [subview.accessibilityLabel isEqualToString:@"Create a Short with this video"]) { + subview.hidden = hideRemixButton; + } else if ([subview.accessibilityLabel isEqualToString:@"Thanks"]) { + subview.hidden = hideThanksButton; + } else if ([subview.accessibilityIdentifier isEqualToString:@"id.ui.add_to.offline.button"] || [subview.accessibilityLabel isEqualToString:@"Download"]) { + subview.hidden = hideAddToOfflineButton; + } else if ([subview.accessibilityLabel isEqualToString:@"Clip"]) { + subview.hidden = hideClipButton; + } else if ([subview.accessibilityLabel isEqualToString:@"Save to playlist"]) { + subview.hidden = hideSaveToPlaylistButton; + } + } } %end -// YTCastConfirm -// See YTCastConfirm.xm +// Hide the (Download) Button under the Video Player - Legacy Version - @arichorn +%hook YTISlimMetadataButtonSupportedRenderers +- (BOOL)slimButton_isOfflineButton { + return IS_ENABLED(@"hideAddToOfflineButton_enabled") ? NO : %orig; +} +%end + +// App Settings Overlay Options +%group gDisableAccountSection +%hook YTSettingsSectionItemManager +- (void)updateAccountSwitcherSectionWithEntry:(id)arg1 {} // Account +%end +%end + +%group gDisableAutoplaySection +%hook YTSettingsSectionItemManager +- (void)updateAutoplaySectionWithEntry:(id)arg1 {} // Autoplay +%end +%end + +%group gDisableTryNewFeaturesSection +%hook YTSettingsSectionItemManager +- (void)updatePremiumEarlyAccessSectionWithEntry:(id)arg1 {} // Try new features +%end +%end + +%group gDisableVideoQualityPreferencesSection +%hook YTSettingsSectionItemManager +- (void)updateVideoQualitySectionWithEntry:(id)arg1 {} // Video quality preferences +%end +%end + +%group gDisableNotificationsSection +%hook YTSettingsSectionItemManager +- (void)updateNotificationSectionWithEntry:(id)arg1 {} // Notifications +%end +%end + +%group gDisableManageAllHistorySection +%hook YTSettingsSectionItemManager +- (void)updateHistorySectionWithEntry:(id)arg1 {} // Manage all history +%end +%end + +%group gDisableYourDataInYouTubeSection +%hook YTSettingsSectionItemManager +- (void)updateYourDataSectionWithEntry:(id)arg1 {} // Your data in YouTube +%end +%end + +%group gDisablePrivacySection +%hook YTSettingsSectionItemManager +- (void)updatePrivacySectionWithEntry:(id)arg1 {} // Privacy +%end +%end + +%group gDisableLiveChatSection +%hook YTSettingsSectionItemManager +- (void)updateLiveChatSectionWithEntry:(id)arg1 {} // Live chat +%end +%end + +// Miscellaneous +// YT startup animation +%hook YTColdConfig +- (BOOL)mainAppCoreClientIosEnableStartupAnimation { + return IS_ENABLED(@"ytStartupAnimation_enabled") ? YES : NO; +} +%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 @@ -192,14 +985,14 @@ NSBundle *tweakBundle = uYouPlusBundle(); %end %end -// Enable YouTube startup animation -%hook YTColdConfig -- (BOOL)mainAppCoreClientIosEnableStartupAnimation { - return IS_ENABLED(@"ytStartupAnimation_enabled") ? YES : NO; -} +// Stick Navigation bar +%group gStickNavigationBar +%hook YTHeaderView +- (BOOL)stickyNavHeaderEnabled { return YES; } +%end %end -// Hide upper bar +// Hide the Chip Bar (Upper Bar) in Home feed %group gHideChipBar %hook YTMySubsFilterHeaderView - (void)setChipFilterView:(id)arg1 {} @@ -212,16 +1005,55 @@ NSBundle *tweakBundle = uYouPlusBundle(); %hook YTHeaderContentComboView - (void)setFeedHeaderScrollMode:(int)arg1 { %orig(0); } %end + +// Hide the chip bar under the video player? +// %hook YTChipCloudCell // +// - (void)didMoveToWindow { +// %orig; +// self.hidden = YES; +// } +// %end %end -// Hide "Play next in queue" - qnblackcat/uYouPlus#1138 +// Remove “Play next in queue” from the menu (@PoomSmart) - qnblackcat/uYouPlus#1138 %hook YTMenuItemVisibilityHandler - (BOOL)shouldShowServiceItemRenderer:(YTIMenuConditionalServiceItemRenderer *)renderer { return IS_ENABLED(@"hidePlayNextInQueue_enabled") && renderer.icon.iconType == 251 ? NO : %orig; } %end -// Force iPhone layout +// Hide the Videos under the Video Player - @Dayanch96 +%group gNoRelatedWatchNexts +%hook YTWatchNextResultsViewController +- (void)setVisibleSections:(NSInteger)arg1 { + arg1 = 1; + %orig(arg1); +} +%end +%end + +// Hide Videos in Fullscreen - @arichorn +%group gNoVideosInFullscreen +%hook YTFullScreenEngagementOverlayView +- (void)setRelatedVideosView:(id)view { +} +- (void)updateRelatedVideosViewSafeAreaInsets { +} +- (id)relatedVideosView { + return nil; +} +%end + +%hook YTFullScreenEngagementOverlayController +- (void)setRelatedVideosVisible:(BOOL)visible { +} +- (BOOL)relatedVideosPeekingEnabled { + return NO; +} +%end +%end + +// iPhone Layout - @LillieH1000 & @arichorn %group giPhoneLayout %hook UIDevice - (long long)userInterfaceIdiom { @@ -235,109 +1067,160 @@ NSBundle *tweakBundle = uYouPlusBundle(); %end %hook UIKBTree - (long long)nativeIdiom { - return YES; + return NO; } %end %hook UIKBRenderer - (long long)assetIdiom { - return YES; + return NO; } %end %end -# pragma mark - Other hooks - -// Activate FLEX -%hook YTAppDelegate -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - BOOL didFinishLaunching = %orig; - if (IS_ENABLED(@"flex_enabled")) { - [[%c(FLEXManager) performSelector:@selector(sharedManager)] performSelector:@selector(showExplorer)]; - } - return didFinishLaunching; +// Hide Indicators - @Dayanch96 & @arichorn +%group gHideSubscriptionsNotificationBadge +%hook YTPivotBarIndicatorView +- (void)didMoveToWindow { + [self setHidden:YES]; + %orig(); } -- (void)appWillResignActive:(id)arg1 { - %orig; - if (IS_ENABLED(@"flex_enabled")) { - [[%c(FLEXManager) performSelector:@selector(sharedManager)] performSelector:@selector(showExplorer)]; - } +- (void)setFillColor:(id)arg1 { + %orig([UIColor clearColor]); +} +- (void)setBorderColor:(id)arg1 { + %orig([UIColor clearColor]); } %end - -// Hide YouTube annoying banner in Home page? - @MiRO92 - YTNoShorts: https://github.com/MiRO92/YTNoShorts -%hook YTAsyncCollectionView -- (id)cellForItemAtIndexPath:(NSIndexPath *)indexPath { - UICollectionViewCell *cell = %orig; - if ([cell isKindOfClass:NSClassFromString(@"_ASCollectionViewCell")]) { - _ASCollectionViewCell *cell = %orig; - if ([cell respondsToSelector:@selector(node)]) { - if ([[[cell node] accessibilityIdentifier] isEqualToString:@"statement_banner.view"]) { [self removeShortsAndFeaturesAdsAtIndexPath:indexPath]; } - if ([[[cell node] accessibilityIdentifier] isEqualToString:@"compact.view"]) { [self removeShortsAndFeaturesAdsAtIndexPath:indexPath]; } - // if ([[[cell node] accessibilityIdentifier] isEqualToString:@"id.ui.video_metadata_carousel"]) { [self removeShortsAndFeaturesAdsAtIndexPath:indexPath]; } - } - } - return %orig; -} -%new -- (void)removeShortsAndFeaturesAdsAtIndexPath:(NSIndexPath *)indexPath { - [self deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]]; -} %end -// Hide search ads by @PoomSmart - https://github.com/PoomSmart/YouTube-X -// %hook YTIElementRenderer -// - (NSData *)elementData { -// if (self.hasCompatibilityOptions && self.compatibilityOptions.hasAdLoggingData) -// return nil; -// return %orig; -// } -// %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 - -// A/B flags -%hook YTColdConfig -// YouRememberCaption: https://poomsmart.github.io/repo/depictions/youremembercaption.html -- (BOOL)respectDeviceCaptionSetting { return NO; } -// Swipe right to dismiss the right panel in fullscreen mode -- (BOOL)isLandscapeEngagementPanelSwipeRightToDismissEnabled { return YES; } -%end - -# pragma mark - Constructor - +# pragma mark - ctor %ctor { // Load uYou first so its functions are available for hooks. // dlopen([[NSString stringWithFormat:@"%@/Frameworks/uYou.dylib", [[NSBundle mainBundle] bundlePath]] UTF8String], RTLD_LAZY); %init; + if (IS_ENABLED(@"hideYouTubeLogo_enabled")) { + %init(gHideYouTubeLogo); + } + if (IS_ENABLED(@"centerYouTubeLogo_enabled")) { + %init(gCenterYouTubeLogo); + } + if (IS_ENABLED(@"premiumYouTubeLogo_enabled")) { + %init(gPremiumYouTubeLogo); + } + if (IS_ENABLED(@"hideSubscriptionsNotificationBadge_enabled")) { + %init(gHideSubscriptionsNotificationBadge); + } if (IS_ENABLED(@"hidePreviousAndNextButton_enabled")) { %init(gHidePreviousAndNextButton); } if (IS_ENABLED(@"replacePreviousAndNextButton_enabled")) { %init(gReplacePreviousAndNextButton); } + if (IS_ENABLED(@"hideOverlayDarkBackground_enabled")) { + %init(gHideOverlayDarkBackground); + } + if (IS_ENABLED(@"hideVideoPlayerShadowOverlayButtons_enabled")) { + %init(gHideVideoPlayerShadowOverlayButtons); + } if (IS_ENABLED(@"disableHints_enabled")) { %init(gDisableHints); } + if (IS_ENABLED(@"redProgressBar_enabled")) { + %init(gRedProgressBar); + } + if (IS_ENABLED(@"stickNavigationBar_enabled")) { + %init(gStickNavigationBar); + } if (IS_ENABLED(@"hideChipBar_enabled")) { %init(gHideChipBar); } + if (IS_ENABLED(@"ytSpeed_enabled")) { + %init(gYTSpeed); + } + if (IS_ENABLED(@"portraitFullscreen_enabled")) { + %init(gPortraitFullscreen); + } if (IS_ENABLED(@"iPhoneLayout_enabled") && (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)) { %init(giPhoneLayout); } - + if (IS_ENABLED(@"stockVolumeHUD_enabled")) { + %init(gStockVolumeHUD); + } + if (IS_ENABLED(@"hideHeatwaves_enabled")) { + %init(gHideHeatwaves); + } + if (IS_ENABLED(@"noRelatedWatchNexts_enabled")) { + %init(gNoRelatedWatchNexts); + } + if (IS_ENABLED(@"noVideosInFullscreen_enabled")) { + %init(gNoVideosInFullscreen); + } + if (IS_ENABLED(@"fixLowContrastMode_enabled")) { + %init(gFixLowContrastMode); + } + if (IS_ENABLED(@"disableModernButtons_enabled")) { + %init(gDisableModernButtons); + } + if (IS_ENABLED(@"disableRoundedHints_enabled")) { + %init(gDisableRoundedHints); + } + if (IS_ENABLED(@"disableModernFlags_enabled")) { + %init(gDisableModernFlags); + } + if (IS_ENABLED(@"disableAmbientMode_enabled")) { + %init(gDisableAmbientMode); + } + if (IS_ENABLED(@"disableAccountSection_enabled")) { + %init(gDisableAccountSection); + } + if (IS_ENABLED(@"disableAutoplaySection_enabled")) { + %init(gDisableAutoplaySection); + } + if (IS_ENABLED(@"disableTryNewFeaturesSection_enabled")) { + %init(gDisableTryNewFeaturesSection); + } + if (IS_ENABLED(@"disableVideoQualityPreferencesSection_enabled")) { + %init(gDisableVideoQualityPreferencesSection); + } + if (IS_ENABLED(@"disableNotificationsSection_enabled")) { + %init(gDisableNotificationsSection); + } + if (IS_ENABLED(@"disableManageAllHistorySection_enabled")) { + %init(gDisableManageAllHistorySection); + } + if (IS_ENABLED(@"disableYourDataInYouTubeSection_enabled")) { + %init(gDisableYourDataInYouTubeSection); + } + if (IS_ENABLED(@"disablePrivacySection_enabled")) { + %init(gDisablePrivacySection); + } + if (IS_ENABLED(@"disableLiveChatSection_enabled")) { + %init(gDisableLiveChatSection); + } + + // YTNoModernUI - @arichorn + BOOL ytNoModernUIEnabled = IS_ENABLED(@"ytNoModernUI_enabled"); + if (ytNoModernUIEnabled) { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setBool:NO forKey:@"enableVersionSpoofer_enabled"]; + [userDefaults setBool:NO forKey:@"premiumYouTubeLogo_enabled"]; + } else { + BOOL enableVersionSpooferEnabled = IS_ENABLED(@"enableVersionSpoofer_enabled"); + BOOL premiumYouTubeLogoEnabled = IS_ENABLED(@"premiumYouTubeLogo_enabled"); + + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setBool:enableVersionSpooferEnabled forKey:@"enableVersionSpoofer_enabled"]; + [userDefaults setBool:premiumYouTubeLogoEnabled forKey:@"premiumYouTubeLogo_enabled"]; + } + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"fixLowContrastMode_enabled"] forKey:@"fixLowContrastMode_enabled"]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"disableModernButtons_enabled"] forKey:@"disableModernButtons_enabled"]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"disableRoundedHints_enabled"] forKey:@"disableRoundedHints_enabled"]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"disableModernFlags_enabled"] forKey:@"disableModernFlags_enabled"]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"disableAmbientMode_enabled"] forKey:@"disableAmbientMode_enabled"]; + [userDefaults setBool:ytNoModernUIEnabled ? ytNoModernUIEnabled : [userDefaults boolForKey:@"redProgressBar_enabled"] forKey:@"redProgressBar_enabled"]; + // Change the default value of some options NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]; if (![allKeys containsObject:@"hidePlayNextInQueue_enabled"]) { @@ -347,7 +1230,7 @@ NSBundle *tweakBundle = uYouPlusBundle(); [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"relatedVideosAtTheEndOfYTVideos"]; } if (![allKeys containsObject:@"shortsProgressBar"]) { - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"shortsProgressBar"]; + [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"shortsProgressBar"]; } if (![allKeys containsObject:@"RYD-ENABLED"]) { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"RYD-ENABLED"]; diff --git a/Sources/uYouPlusPatches.xm b/Sources/uYouPlusPatches.xm index 99ec0b1..1fa34b9 100644 --- a/Sources/uYouPlusPatches.xm +++ b/Sources/uYouPlusPatches.xm @@ -1,4 +1,4 @@ -#import "uYouPlusPatches.h" +#import "uYouPlus.h" # pragma mark - YouTube patches @@ -26,6 +26,36 @@ - (BOOL)disableAfmaIdfaCollection { return NO; } %end +// Reposition "Create" Tab to the Center in the Pivot Bar - qnblackcat/uYouPlus#107 +/* +static void repositionCreateTab(YTIGuideResponse *response) { + NSMutableArray *renderers = [response itemsArray]; + for (YTIGuideResponseSupportedRenderers *guideRenderers in renderers) { + YTIPivotBarRenderer *pivotBarRenderer = [guideRenderers pivotBarRenderer]; + NSMutableArray *items = [pivotBarRenderer itemsArray]; + NSUInteger createIndex = [items indexOfObjectPassingTest:^BOOL(YTIPivotBarSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) { + return [[[renderers pivotBarItemRenderer] pivotIdentifier] isEqualToString:@"FEuploads"]; + }]; + if (createIndex != NSNotFound) { + YTIPivotBarSupportedRenderers *createTab = [items objectAtIndex:createIndex]; + [items removeObjectAtIndex:createIndex]; + NSUInteger centerIndex = items.count / 2; + [items insertObject:createTab atIndex:centerIndex]; // Reposition the "Create" tab at the center + } + } +} +%hook YTGuideServiceCoordinator +- (void)handleResponse:(YTIGuideResponse *)response withCompletion:(id)completion { + repositionCreateTab(response); + %orig(response, completion); +} +- (void)handleResponse:(YTIGuideResponse *)response error:(id)error completion:(id)completion { + repositionCreateTab(response); + %orig(response, error, completion); +} +%end +*/ + // https://github.com/PoomSmart/YouTube-X/blob/1e62b68e9027fcb849a75f54a402a530385f2a51/Tweak.x#L27 // %hook YTAdsInnerTubeContextDecorator // - (void)decorateContext:(id)context {} @@ -173,17 +203,14 @@ static void refreshUYouAppearance() { %end // Prevent uYou's playback from colliding with YouTube's -%hook PlayerVC -- (void)close { - %orig; - [[%c(PlayerManager) sharedInstance] setSource:nil]; -} -%end +BOOL isYTPlaybackActive = NO; %hook HAMPlayerInternal +- (void)play { %orig; isYTPlaybackActive = YES; } +- (void)terminate { %orig; isYTPlaybackActive = NO; } +%end +%hook PlayerManager - (void)play { - dispatch_async(dispatch_get_main_queue(), ^{ - [[%c(PlayerManager) sharedInstance] pause]; - }); + if (isYTPlaybackActive) return; %orig; } %end @@ -213,4 +240,4 @@ static void refreshUYouAppearance() { // Disable uYou's playback speed controls (prevent crash on video playback https://github.com/therealFoxster/uYouPlus/issues/2#issuecomment-1894912963) // [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"showPlaybackRate"]; -} \ No newline at end of file +} diff --git a/Sources/uYouPlusSettings.xm b/Sources/uYouPlusSettings.xm index bab01b4..5302c20 100644 --- a/Sources/uYouPlusSettings.xm +++ b/Sources/uYouPlusSettings.xm @@ -1,22 +1,75 @@ -#import "uYouPlusSettings.h" +// Settings.xm made by the @therealFoxster +#import "../Tweaks/YouTubeHeader/YTSettingsGroupData.h" +#import "../Tweaks/YouTubeHeader/YTSettingsViewController.h" +#import "../Tweaks/YouTubeHeader/YTSearchableSettingsViewController.h" +#import "../Tweaks/YouTubeHeader/YTSettingsSectionItem.h" +#import "../Tweaks/YouTubeHeader/YTSettingsSectionItemManager.h" +#import "../Tweaks/YouTubeHeader/YTUIUtils.h" +#import "../Tweaks/YouTubeHeader/YTSettingsPickerViewController.h" +#import "../Tweaks/YouTubeHeader/YTIIcon.h" +#import "ColourOptionsController.h" +#import "ColourOptionsController2.h" +#import "uYouPlus.h" #define VERSION_STRING [[NSString stringWithFormat:@"%@", @(OS_STRINGIFY(TWEAK_VERSION))] stringByReplacingOccurrencesOfString:@"\"" withString:@""] #define SHOW_RELAUNCH_YT_SNACKBAR [[%c(GOOHUDManagerInternal) sharedInstance] showMessageMainThread:[%c(YTHUDMessage) messageWithText:LOC(@"RESTART_YOUTUBE")]] #define SECTION_HEADER(s) [sectionItems addObject:[%c(YTSettingsSectionItem) itemWithTitle:@"\t" titleDescription:[s uppercaseString] accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger sectionItemIndex) { return NO; }]] +/* broken button implementation. I tried. +#define COLOR_BUTTON_ITEM(t, d, ColourOptionsController) [sectionItems addObject:[YTSettingsSectionItemClass buttonItemWithTitle:t titleDescription:d accessibilityIdentifier:nil buttonBlock:^(YTSettingsCell *cell) {\ + UINavigationController *colourOptionsControllerView = [[UINavigationController alloc] initWithRootViewController:[[ColourOptionsController alloc] init]]; \ + [colourOptionsControllerView setModalPresentationStyle:UIModalPresentationFullScreen]; \ + [self._viewControllerForAncestor presentViewController:colourOptionsControllerView animated:YES completion:nil];} settingItemId:0]] + +#define COLOR_BUTTON_ITEM2(t, d, ColourOptionsController2) [sectionItems addObject:[YTSettingsSectionItemClass buttonItemWithTitle:t titleDescription:d accessibilityIdentifier:nil buttonBlock:^(YTSettingsCell *cell) {\ + UINavigationController *colourOptionsController2View = [[UINavigationController alloc] initWithRootViewController:[[ColourOptionsController2 alloc] init]]; \ + [colourOptionsController2View setModalPresentationStyle:UIModalPresentationFullScreen]; \ + [self._viewControllerForAncestor presentViewController:colourOptionsController2View animated:YES completion:nil];} settingItemId:0]] +*/ + #define SWITCH_ITEM(t, d, k) [sectionItems addObject:[YTSettingsSectionItemClass switchItemWithTitle:t titleDescription:d accessibilityIdentifier:nil switchOn:IS_ENABLED(k) switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) {[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:k];return YES;} settingItemId:0]] #define SWITCH_ITEM2(t, d, k) [sectionItems addObject:[YTSettingsSectionItemClass switchItemWithTitle:t titleDescription:d accessibilityIdentifier:nil switchOn:IS_ENABLED(k) switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) {[[NSUserDefaults standardUserDefaults] setBool:enabled forKey:k];SHOW_RELAUNCH_YT_SNACKBAR;return YES;} settingItemId:0]] +static int contrastMode() { + return [[NSUserDefaults standardUserDefaults] integerForKey:@"lcm"]; +} +static int appVersionSpoofer() { + return [[NSUserDefaults standardUserDefaults] integerForKey:@"versionSpoofer"]; +} static const NSInteger uYouPlusSection = 500; +static const NSUInteger GROUP_TYPE = 'psyt'; // PoomSmart/YouGroupSettings + +@interface YTSettingsGroupData (YouGroupSettings) // PoomSmart/YouGroupSettings ++ (NSMutableArray *)tweaks; +@end @interface YTSettingsSectionItemManager (uYouPlus) - (void)updateTweakSectionWithEntry:(id)entry; +- (NSString *)getCacheSize; @end extern NSBundle *uYouPlusBundle(); +// Settings Search Bar +%hook YTSettingsViewController +- (void)loadWithModel:(id)model fromView:(UIView *)view { + %orig; + if ([[self valueForKey:@"_detailsCategoryID"] integerValue] == uYouPlusSection) + MSHookIvar(self, "_shouldShowSearchBar") = YES; +} +- (void)setSectionControllers { + %orig; + if (MSHookIvar(self, "_shouldShowSearchBar")) { + YTSettingsSectionController *settingsSectionController = [self settingsSectionControllers][[self valueForKey:@"_detailsCategoryID"]]; + YTSearchableSettingsViewController *searchableVC = [self valueForKey:@"_searchableSettingsViewController"]; + if (settingsSectionController) + [searchableVC storeCollectionViewSections:@[settingsSectionController]]; + } +} +%end + // Settings %hook YTAppSettingsPresentationData + (NSArray *)settingsCategoryOrder { @@ -29,6 +82,50 @@ extern NSBundle *uYouPlusBundle(); } %end +// PoomSmart/YouGroupSettings +%hook YTSettingsGroupData +%new(@@:) ++ (NSMutableArray *)tweaks { + static NSMutableArray *tweaks = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + tweaks = [NSMutableArray new]; + [tweaks addObjectsFromArray:@[ + @(404), // YTABConfig + @(500), // uYouEnhanced / uYouPlus + @(517), // DontEatMyContent + @(1080), // Return YouTube Dislike + @(200), // YouPiP + @(2168), // YTHoldForSpeed + @(1222), // YTVideoOverlay + ]]; + }); + return tweaks; +} +- (NSString *)titleForSettingGroupType:(NSUInteger)type { + if (type == GROUP_TYPE) { + return @"Tweaks"; + } + return %orig; +} +- (NSArray *)orderedCategoriesForGroupType:(NSUInteger)type { + if (type == GROUP_TYPE) + return [[self class] tweaks]; + return %orig; +} +%end + +%hook YTSettingsViewController +- (void)setSectionItems:(NSMutableArray *)sectionItems forCategory:(NSInteger)category title:(NSString *)title icon:(YTIIcon *)icon titleDescription:(NSString *)titleDescription headerHidden:(BOOL)headerHidden { + if (icon == nil && [[%c(YTSettingsGroupData) tweaks] containsObject:@(category)]) { + icon = [%c(YTIIcon) new]; + icon.iconType = 44; + } + %orig; +} +%end +// + %hook YTSettingsSectionController - (void)setSelectedItem:(NSUInteger)selectedItem { if (selectedItem != NSNotFound) %orig; @@ -36,6 +133,22 @@ extern NSBundle *uYouPlusBundle(); %end %hook YTSettingsSectionItemManager +- (NSString *)getCacheSize { + NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; + NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:cachePath error:nil]; + + unsigned long long int folderSize = 0; + for (NSString *fileName in filesArray) { + NSString *filePath = [cachePath stringByAppendingPathComponent:fileName]; + NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; + folderSize += [fileAttributes fileSize]; + } + + NSByteCountFormatter *formatter = [[NSByteCountFormatter alloc] init]; + formatter.countStyle = NSByteCountFormatterCountStyleFile; + + return [formatter stringFromByteCount:folderSize]; +} %new(v@:@) - (void)updateTweakSectionWithEntry:(id)entry { NSMutableArray *sectionItems = [NSMutableArray array]; @@ -54,7 +167,7 @@ extern NSBundle *uYouPlusBundle(); return VERSION_STRING; } selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/qnblackcat/uYouPlus/releases"]]; + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/arichornlover/uYouEnhanced/releases/latest"]]; } ]; [sectionItems addObject:version]; @@ -65,7 +178,7 @@ extern NSBundle *uYouPlusBundle(); accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { - NSString *url = [NSString stringWithFormat:@"https://github.com/qnblackcat/uYouPlus/issues/new?assignees=&labels=bug&projects=&template=bug.yaml&title=[v%@] %@", VERSION_STRING, LOC(@"ADD_TITLE")]; + NSString *url = [NSString stringWithFormat:@"https://github.com/arichornlover/uYouEnhanced/issues/new?assignees=&labels=bug&projects=&template=bug.yaml&title=[v%@] %@", VERSION_STRING, LOC(@"ADD_TITLE")]; return [%c(YTUIUtils) openURL:[NSURL URLWithString:[url stringByReplacingOccurrencesOfString:@" " withString:@"%20"]]]; } @@ -86,8 +199,36 @@ extern NSBundle *uYouPlusBundle(); ]; [sectionItems addObject:exitYT]; +# pragma mark - Cache + SECTION_HEADER(@"Cache"); + YTSettingsSectionItem *clearCache = [%c(YTSettingsSectionItem) + itemWithTitle:LOC(@"Clear Cache") + titleDescription:[self getCacheSize] + accessibilityIdentifier:nil + detailTextBlock:nil + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]; + activityIndicator.color = [UIColor labelColor]; + [activityIndicator startAnimating]; + cell.accessoryView = activityIndicator; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; + [[NSFileManager defaultManager] removeItemAtPath:cachePath error:nil]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [settingsViewController reloadData]; + }); + }); + + return YES; + } + ]; + [sectionItems addObject:clearCache]; + # pragma mark - App theme - SECTION_HEADER(LOC(@"APP_THEME")); + SECTION_HEADER(LOC(@"THEME_OPTIONS")); +// COLOR_BUTTON_ITEM2(@"Custom Theme Color", @"", ColourOptionsController2); YTSettingsSectionItem *themeGroup = [YTSettingsSectionItemClass itemWithTitle:LOC(@"DARK_THEME") @@ -149,8 +290,8 @@ extern NSBundle *uYouPlusBundle(); ] ]; YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] - initWithNavTitle:LOC(@"DARK_THEME") - pickerSectionTitle:[LOC(@"DARK_THEME") uppercaseString] + initWithNavTitle:LOC(@"THEME_OPTIONS") + pickerSectionTitle:[LOC(@"THEME_OPTIONS") uppercaseString] rows:rows selectedItemIndex:APP_THEME_IDX parentResponder:[self parentResponder] ]; @@ -163,6 +304,7 @@ extern NSBundle *uYouPlusBundle(); # pragma mark - Video player options SECTION_HEADER(LOC(@"VIDEO_PLAYER_OPTIONS")); + SWITCH_ITEM2(LOC(@"Enable Portrait Fullscreen (iPhone-Exclusive)"), LOC(@"Enables Portrait Fullscreen on the YouTube App. App restart is required."), @"portraitFullscreen_enabled"); SWITCH_ITEM2(LOC(@"SLIDE_TO_SEEK"), LOC(@"SLIDE_TO_SEEK_DESC"), @"slideToSeek_enabled"); SWITCH_ITEM(LOC(@"DISABLE_DOUBLE_TAP_TO_SEEK"), LOC(@"DISABLE_DOUBLE_TAP_TO_SEEK_DESC"), @"doubleTapToSeek_disabled"); SWITCH_ITEM2(LOC(@"SNAP_TO_CHAPTER"), LOC(@"SNAP_TO_CHAPTER_DESC"), @"snapToChapter_enabled"); @@ -173,43 +315,874 @@ extern NSBundle *uYouPlusBundle(); # pragma mark - Video controls overlay options SECTION_HEADER(LOC(@"VIDEO_CONTROLS_OVERLAY_OPTIONS")); + SWITCH_ITEM(LOC(@"Enable Share Button"), LOC(@"Enable the Share Button in video controls overlay."), @"enableShareButton_enabled"); + SWITCH_ITEM(LOC(@"Enable 'Save To Playlist' Button"), LOC(@"Enable the 'Save To Playlist' Button in video controls overlay."), @"enableSaveToButton_enabled"); SWITCH_ITEM(LOC(@"HIDE_AUTOPLAY_SWITCH"), LOC(@"HIDE_AUTOPLAY_SWITCH_DESC"), @"hideAutoplaySwitch_enabled"); SWITCH_ITEM(LOC(@"HIDE_SUBTITLES_BUTTON"), LOC(@"HIDE_SUBTITLES_BUTTON_DESC"), @"hideCC_enabled"); SWITCH_ITEM(LOC(@"HIDE_HUD_MESSAGES"), LOC(@"HIDE_HUD_MESSAGES_DESC"), @"hideHUD_enabled"); SWITCH_ITEM(LOC(@"HIDE_PAID_PROMOTION_CARDS"), LOC(@"HIDE_PAID_PROMOTION_CARDS_DESC"), @"hidePaidPromotionCard_enabled"); SWITCH_ITEM2(LOC(@"HIDE_CHANNEL_WATERMARK"), LOC(@"HIDE_CHANNEL_WATERMARK_DESC"), @"hideChannelWatermark_enabled"); + SWITCH_ITEM2(LOC(@"Hide Shadow Overlay Buttons"), LOC(@"Hide the Shadow Overlay on the Play/Pause, Previous, Next, Forward & Rewind Buttons."), @"hideVideoPlayerShadowOverlayButtons_enabled"); SWITCH_ITEM(LOC(@"HIDE_PREVIOUS_AND_NEXT_BUTTON"), LOC(@"HIDE_PREVIOUS_AND_NEXT_BUTTON_DESC"), @"hidePreviousAndNextButton_enabled"); SWITCH_ITEM2(LOC(@"REPLACE_PREVIOUS_NEXT_BUTTON"), LOC(@"REPLACE_PREVIOUS_NEXT_BUTTON_DESC"), @"replacePreviousAndNextButton_enabled"); SWITCH_ITEM2(LOC(@"RED_PROGRESS_BAR"), LOC(@"RED_PROGRESS_BAR_DESC"), @"redProgressBar_enabled"); SWITCH_ITEM(LOC(@"HIDE_HOVER_CARD"), LOC(@"HIDE_HOVER_CARD_DESC"), @"hideHoverCards_enabled"); SWITCH_ITEM2(LOC(@"HIDE_RIGHT_PANEL"), LOC(@"HIDE_RIGHT_PANEL_DESC"), @"hideRightPanel_enabled"); + SWITCH_ITEM2(LOC(@"Hide Suggested Video"), LOC(@"Remove the suggested video popup when finishing a video. Note that this will prevent autoplay from working."), @"noSuggestedVideo_enabled"); + SWITCH_ITEM2(LOC(@"Hide Heatwaves"), LOC(@"Should hide the Heatwaves in the video player. App restart is required."), @"hideHeatwaves_enabled"); + SWITCH_ITEM2(LOC(@"Hide Dark Overlay Background"), LOC(@"Hide video player's dark overlay background. App restart is required."), @"hideOverlayDarkBackground_enabled"); + SWITCH_ITEM2(LOC(@"Disable Ambient Mode in Fullscreen"), LOC(@"When Enabled, this will Disable the functionality of Ambient Mode from being used in the Video Player when in Fullscreen. App restart is required."), @"disableAmbientMode_enabled"); + SWITCH_ITEM2(LOC(@"Hide Suggested Videos in Fullscreen"), LOC(@"Hide video player's suggested videos whenever in fullscreen. App restart is required."), @"noVideosInFullscreen_enabled"); + SWITCH_ITEM2(LOC(@"Enable YTSpeed"), LOC(@"Enable YTSpeed to have more Playback Speed Options. App restart is required."), @"ytSpeed_enabled"); - # pragma mark - Shorts controls overlay options + # pragma mark - Shorts controls overlay options SECTION_HEADER(LOC(@"SHORTS_CONTROLS_OVERLAY_OPTIONS")); SWITCH_ITEM(LOC(@"HIDE_SUPER_THANKS"), LOC(@"HIDE_SUPER_THANKS_DESC"), @"hideBuySuperThanks_enabled"); SWITCH_ITEM(LOC(@"HIDE_SUBCRIPTIONS"), LOC(@"HIDE_SUBCRIPTIONS_DESC"), @"hideSubcriptions_enabled"); - SWITCH_ITEM(LOC(@"DISABLE_RESUME_TO_SHORTS"), LOC(@"DISABLE_RESUME_TO_SHORTS_DESC"), @"disableResumeToShorts"); + SWITCH_ITEM(LOC(@"DISABLE_RESUME_TO_SHORTS"), LOC(@"DISABLE_RESUME_TO_SHORTS_DESC"), @"disableResumeToShorts_enabled"); + + + # 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) +// +// SWITCH_ITEM(LOC(@"Red Subscribe Button"), LOC(@"Replaces the Subscribe Button color from being White to the color Red."), @"redSubscribeButton_enabled"); +// SWITCH_ITEM2(LOC(@"Hide Button Containers under player"), LOC(@"Hides Button Containers under the video player."), @"hideButtonContainers_enabled"); + SWITCH_ITEM(LOC(@"Hide the Connect Button under player"), LOC(@"Hides the Connect Button under the video player."), @"hideConnectButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Share Button under player"), LOC(@"Hides the Share Button under the video player."), @"hideShareButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Remix Button under player"), LOC(@"Hides the Remix Button under the video player."), @"hideRemixButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Thanks Button under player"), LOC(@"Hides the Thanks Button under the video player."), @"hideThanksButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Download Button under player"), LOC(@"Hides the Download Button under the video player."), @"hideAddToOfflineButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Clip Button under player"), LOC(@"Hides the Clip Button under the video player."), @"hideClipButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the Save to playlist Button under player"), LOC(@"Hides the Save to playlist Button under the video player."), @"hideSaveToPlaylistButton_enabled"); + SWITCH_ITEM(LOC(@"Hide the comment section under player"), LOC(@"Hides the Comment Section below the player."), @"hideCommentSection_enabled"); + +# pragma mark - App settings overlay options + SECTION_HEADER(LOC(@"App Settings Overlay Options")); + + SWITCH_ITEM2(LOC(@"Hide `Account` Section"), LOC(@"App restart is required."), @"disableAccountSection_enabled"); +// SWITCH_ITEM2(LOC(@"Hide `DontEatMyContent` Section"), LOC(@"App restart is required."), @"disableDontEatMyContentSection_enabled"); +// SWITCH_ITEM2(LOC(@"Hide `YouTube Return Dislike` Section"), LOC(@"App restart is required."), @"disableReturnYouTubeDislikeSection_enabled"); +// SWITCH_ITEM2(LOC(@"Hide `YouPiP` Section"), LOC(@"App restart is required."), @"disableYouPiPSection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Autoplay` Section"), LOC(@"App restart is required."), @"disableAutoplaySection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Try New Features` Section"), LOC(@"App restart is required."), @"disableTryNewFeaturesSection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Video quality preferences` Section"), LOC(@"App restart is required."), @"disableVideoQualityPreferencesSection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Notifications` Section"), LOC(@"App restart is required."), @"disableNotificationsSection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Manage all history` Section"), LOC(@"App restart is required."), @"disableManageAllHistorySection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Your data in YouTube` Section"), LOC(@"App restart is required."), @"disableYourDataInYouTubeSection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Privacy` Section"), LOC(@"App restart is required."), @"disablePrivacySection_enabled"); + SWITCH_ITEM2(LOC(@"Hide `Live Chat` Section"), LOC(@"App restart is required."), @"disableLiveChatSection_enabled"); + + # pragma mark - UI interface options + SECTION_HEADER(LOC(@"UI Interface Options")); + + SWITCH_ITEM2(LOC(@"Low Contrast Mode"), LOC(@"This will lower the contrast of texts and buttons, similar to the old YouTube Interface. App restart is required."), @"lowContrastMode_enabled"); + YTSettingsSectionItem *lowContrastMode = [%c(YTSettingsSectionItem) + itemWithTitle:@"Low Contrast Mode Selector" + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + switch (contrastMode()) { + case 1: + return LOC(@"Custom Color"); + case 0: + default: + return LOC(@"Default"); + } + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + [YTSettingsSectionItemClass checkmarkItemWithTitle:LOC(@"Default") titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"lcm"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:LOC(@"Custom Color") titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"lcm"]; + [settingsViewController reloadData]; + return YES; + }] + + ]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Low Contrast Mode Selector") pickerSectionTitle:nil rows:rows selectedItemIndex:contrastMode() parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + [sectionItems addObject:lowContrastMode]; +// COLOR_BUTTON_ITEM(@"Custom LowContrastMode Color", @"if you selected Custom Color than use this to modify the color.", ColourOptionsController); + SWITCH_ITEM2(LOC(@"Fix LowContrastMode"), LOC(@"This will fix the LowContrastMode functionality by Spoofing to YouTube v17.38.10. App restart is required."), @"fixLowContrastMode_enabled"); + SWITCH_ITEM2(LOC(@"Disable Modern Buttons"), LOC(@"This will remove the new Modern / Chip Buttons in the YouTube App. but not all of them. App restart is required."), @"disableModernButtons_enabled"); + SWITCH_ITEM2(LOC(@"Disable Rounded Corners on Hints"), LOC(@"This will make the Hints in the App to not have Rounded Corners. App restart is required."), @"disableRoundedHints_enabled"); + SWITCH_ITEM2(LOC(@"Disable Modern A/B Flags"), LOC(@"This will turn off any Modern Flag that was enabled by default. App restart is required."), @"disableModernFlags_enabled"); + SWITCH_ITEM2(LOC(@"Enable Specific UI Related Options (YTNoModernUI)"), LOC(@"When Enabled, this will enable other options to give it a less-modern feeling. App restart is required."), @"ytNoModernUI_enabled"); + SWITCH_ITEM2(LOC(@"Enable App Version Spoofer"), LOC(@"Enable this to use the Version Spoofer and select your perferred version below. App restart is required."), @"enableVersionSpoofer_enabled"); + YTSettingsSectionItem *versionSpoofer = [%c(YTSettingsSectionItem) + itemWithTitle:@"Version spoofer picker" + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + switch (appVersionSpoofer()) { + case 1: + return @"v18.48.3"; + case 2: + return @"v18.46.3"; + case 3: + return @"v18.45.2"; + case 4: + return @"v18.44.3"; + case 5: + return @"v18.43.4"; + case 6: + return @"v18.41.5"; + case 7: + return @"v18.41.3"; + case 8: + return @"v18.41.2"; + case 9: + return @"v18.40.1"; + case 10: + return @"v18.39.1"; + case 11: + return @"v18.38.2"; + case 12: + return @"v18.35.4"; + case 13: + return @"v18.34.5"; + case 14: + return @"v18.33.3"; + case 15: + return @"v18.33.2"; + case 16: + return @"v18.32.2"; + case 17: + return @"v18.31.3"; + case 18: + return @"v18.30.7"; + case 19: + return @"v18.30.6"; + case 20: + return @"v18.29.1"; + case 21: + return @"v18.28.3"; + case 22: + return @"v18.27.3"; + case 23: + return @"v18.25.1"; + case 24: + return @"v18.23.3"; + case 25: + return @"v18.22.9"; + case 26: + return @"v18.21.3"; + case 27: + return @"v18.20.3"; + case 28: + return @"v18.19.1"; + case 29: + return @"v18.18.2"; + case 30: + return @"v18.17.2"; + case 31: + return @"v18.16.2"; + case 32: + return @"v18.15.1"; + case 33: + return @"v18.14.1"; + case 34: + return @"v18.13.4"; + case 35: + return @"v18.12.2"; + case 36: + return @"v18.11.2"; + case 37: + return @"v18.10.1"; + case 38: + return @"v18.09.4"; + case 39: + return @"v18.08.1"; + case 40: + return @"v18.07.5"; + case 41: + return @"v18.05.2"; + case 42: + return @"v18.04.3"; + case 43: + return @"v18.03.3"; + case 44: + return @"v18.02.03"; + case 45: + return @"v18.01.6"; + case 46: + return @"v18.01.4"; + case 47: + return @"v18.01.2"; + case 48: + return @"v17.49.6"; + case 49: + return @"v17.49.4"; + case 50: + return @"v17.46.4"; + case 51: + return @"v17.45.1"; + case 52: + return @"v17.44.4"; + case 53: + return @"v17.43.1"; + case 54: + return @"v17.42.7"; + case 55: + return @"v17.42.6"; + case 56: + return @"v17.41.2"; + case 57: + return @"v17.40.5"; + case 58: + return @"v17.39.4"; + case 59: + return @"v17.38.10"; + case 60: + return @"v17.38.9"; + case 61: + return @"v17.37.2"; + case 62: + return @"v17.36.4"; + case 63: + return @"v17.36.3"; + case 64: + return @"v17.35.3"; + case 65: + return @"v17.34.3"; + case 66: + return @"v17.33.2"; + case 67: + return @"v17.32.2"; + case 68: + return @"v17.31.4"; + case 69: + return @"v17.30.3"; + case 70: + return @"v17.30.1"; + case 71: + return @"v17.29.3"; + case 72: + return @"v17.29.2"; + case 73: + return @"v17.28.2"; + case 74: + return @"v17.26.2"; + case 75: + return @"v17.25.1"; + case 76: + return @"v17.24.4"; + case 77: + return @"v17.23.6"; + case 78: + return @"v17.22.3"; + case 79: + return @"v17.21.3"; + case 80: + return @"v17.20.3"; + case 81: + return @"v17.19.3"; + case 82: + return @"v17.19.2"; + case 83: + return @"v17.18.4"; + case 84: + return @"v17.17.4"; + case 85: + return @"v17.16.4"; + case 86: + return @"v17.15.2"; + case 87: + return @"v17.15.1"; + case 88: + return @"v17.14.2"; + case 89: + return @"v17.13.3"; + case 90: + return @"v17.12.5"; + case 91: + return @"v17.12.4"; + case 92: + return @"v17.11.2"; + case 93: + return @"v17.10.2"; + case 94: + return @"v17.09.1"; + case 95: + return @"v17.08.2"; + case 96: + return @"v17.07.2"; + case 97: + return @"v17.06.3"; + case 98: + return @"v17.05.2"; + case 99: + return @"v17.04.3"; + case 100: + return @"v17.03.3"; + case 101: + return @"v17.03.2"; + case 102: + return @"v17.01.4"; + case 0: + default: + return @"v18.49.3"; + } + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.49.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.48.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.46.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:2 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.45.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:3 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.44.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:4 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.43.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:5 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.41.5" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:6 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.41.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:7 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.41.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:8 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.40.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:9 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.39.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:10 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.38.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:11 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.35.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:12 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.34.5" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:13 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.33.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:14 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.33.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:15 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.32.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:16 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.31.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:17 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.30.7" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:18 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.30.6" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:19 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.29.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:20 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.28.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:21 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.27.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:22 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.25.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:23 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.23.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:24 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.22.9" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:25 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.21.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:26 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.20.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:27 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.19.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:28 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.18.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:29 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.17.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:30 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.16.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:31 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.15.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:32 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.14.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:33 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.13.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:34 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.12.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:35 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.11.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:36 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.10.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:37 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.09.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:38 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.08.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:39 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.07.5" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:40 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.05.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:41 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.04.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:42 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.03.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:43 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.02.03" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:44 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.01.6" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:45 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.01.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:46 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v18.01.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:47 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.49.6" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:48 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.49.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:49 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.46.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:50 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.45.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:51 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.44.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:52 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.43.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:53 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.42.7" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:54 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.42.6" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:55 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.41.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:56 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.40.5" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:57 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.39.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:58 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.38.10" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:59 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.38.9" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:60 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.37.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:61 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.36.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:62 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.36.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:63 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.35.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:64 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.34.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:65 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.33.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:66 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.32.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:67 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.31.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:68 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.30.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:69 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.30.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:70 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.29.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:71 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.29.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:72 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.28.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:73 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.26.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:74 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.25.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:75 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.24.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:76 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.23.6" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:77 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.22.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:78 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.21.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:79 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.20.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:80 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.19.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:81 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.19.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:82 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.18.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:83 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.17.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:84 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.16.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:85 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.15.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:86 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.15.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:87 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.14.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:88 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.13.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:89 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.12.5" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:90 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.12.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:91 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.11.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:92 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.10.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:93 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.09.1" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:94 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.08.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:95 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.07.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:96 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.06.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:97 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.05.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:98 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.04.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:99 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.03.3" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:100 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.03.2" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:101 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }], + [YTSettingsSectionItemClass checkmarkItemWithTitle:@"v17.01.4" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + [[NSUserDefaults standardUserDefaults] setInteger:102 forKey:@"versionSpoofer"]; + [settingsViewController reloadData]; + return YES; + }] + ]; + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Version Spoofer Picker") pickerSectionTitle:nil rows:rows selectedItemIndex:appVersionSpoofer() parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + } + ]; + [sectionItems addObject:versionSpoofer]; # pragma mark - Miscellaneous SECTION_HEADER(LOC(@"MISCELLANEOUS")); - // SWITCH_ITEM2(LOC(@"HIDE_UYOU"), nil, @"hideUYouTab_enabled"); // We stay on 19.02.1 until MiRO92 update uYou? - SWITCH_ITEM2(LOC(@"HIDE_ISPONSORBLOCK"), nil, @"hideiSponsorBlockButton_enabled"); + SWITCH_ITEM(LOC(@"YouTube Premium Logo"), LOC(@"Toggle this to use the official YouTube Premium Logo. App restart is required."), @"premiumYouTubeLogo_enabled"); +// SWITCH_ITEM(LOC(@"Center YouTube Logo"), LOC(@"Toggle this to move the official YouTube Logo to the Center. App restart is required."), @"centerYouTubeLogo_enabled"); + SWITCH_ITEM(LOC(@"Hide YouTube Logo"), LOC(@"Toggle this to hide the YouTube Logo in the YouTube App."), @"hideYouTubeLogo_enabled"); + SWITCH_ITEM(LOC(@"ENABLE_YT_STARTUP_ANIMATION"), LOC(@"ENABLE_YT_STARTUP_ANIMATION_DESC"), @"ytStartupAnimation_enabled"); SWITCH_ITEM(LOC(@"CAST_CONFIRM"), LOC(@"CAST_CONFIRM_DESC"), @"castConfirm_enabled"); SWITCH_ITEM(LOC(@"DISABLE_HINTS"), LOC(@"DISABLE_HINTS_DESC"), @"disableHints_enabled"); - SWITCH_ITEM(LOC(@"ENABLE_YT_STARTUP_ANIMATION"), LOC(@"ENABLE_YT_STARTUP_ANIMATION_DESC"), @"ytStartupAnimation_enabled"); + SWITCH_ITEM(LOC(@"Stick Navigation Bar"), LOC(@"Enable to make the Navigation Bar stay on the App when scrolling."), @"stickNavigationBar_enabled"); + SWITCH_ITEM(LOC(@"Hide iSponsorBlock button in the Navigation bar"), LOC(@""), @"hideSponsorBlockButton_enabled"); SWITCH_ITEM(LOC(@"HIDE_CHIP_BAR"), LOC(@"HIDE_CHIP_BAR_DESC"), @"hideChipBar_enabled"); SWITCH_ITEM(LOC(@"HIDE_PLAY_NEXT_IN_QUEUE"), LOC(@"HIDE_PLAY_NEXT_IN_QUEUE_DESC"), @"hidePlayNextInQueue_enabled"); + SWITCH_ITEM2(LOC(@"Hide Community Posts"), LOC(@"Hides the Community Posts. App restart is required."), @"hideCommunityPosts_enabled"); + SWITCH_ITEM2(LOC(@"Hide Header Links under channel profile"), LOC(@"Hides the Header Links under any channel profile."), @"hideChannelHeaderLinks_enabled"); + SWITCH_ITEM2(LOC(@"Hide all videos under player"), LOC(@"Hides all videos below the player."), @"noRelatedWatchNexts_enabled"); SWITCH_ITEM2(LOC(@"IPHONE_LAYOUT"), LOC(@"IPHONE_LAYOUT_DESC"), @"iPhoneLayout_enabled"); SWITCH_ITEM2(LOC(@"NEW_MINIPLAYER_STYLE"), LOC(@"NEW_MINIPLAYER_STYLE_DESC"), @"bigYTMiniPlayer_enabled"); SWITCH_ITEM2(LOC(@"YT_RE_EXPLORE"), LOC(@"YT_RE_EXPLORE_DESC"), @"reExplore_enabled"); + SWITCH_ITEM2(LOC(@"Hide Indicators"), LOC(@"Hides all Indicators that were in the App."), @"hideSubscriptionsNotificationBadge_enabled"); SWITCH_ITEM(LOC(@"ENABLE_FLEX"), LOC(@"ENABLE_FLEX_DESC"), @"flex_enabled"); if ([settingsViewController respondsToSelector:@selector(setSectionItems:forCategory:title:icon:titleDescription:headerHidden:)]) - [settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouPlus" icon:nil titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES]; + [settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouEnhanced" icon:nil titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES]; else - [settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouPlus" titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES]; + [settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouEnhanced" titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES]; } - (void)updateSectionForCategory:(NSUInteger)category withEntry:(id)entry { diff --git a/Sources/uYouPlusThemes.xm b/Sources/uYouPlusThemes.xm index 233662f..a4ec825 100644 --- a/Sources/uYouPlusThemes.xm +++ b/Sources/uYouPlusThemes.xm @@ -1,12 +1,52 @@ -#import "uYouPlusThemes.h" +#import "uYouPlus.h" #define IS_DARK_APPEARANCE_ENABLED ([[NSUserDefaults standardUserDefaults] integerForKey:@"page_style"] == 1) #define IS_OLD_DARK_THEME_SELECTED (APP_THEME_IDX == 1) #define IS_OLED_DARK_THEME_SELECTED (APP_THEME_IDX == 2) +#define IS_CUSTOM_DARK_THEME_SELECTED (APP_THEME_IDX == 3) # pragma mark - Old dark theme (lighter grey) %group gOldDarkTheme +%hook YTCommonColorPalette +- (UIColor *)background1 { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)background2 { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)background3 { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)baseBackground { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)brandBackgroundSolid { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)brandBackgroundPrimary { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)brandBackgroundSecondary { + return self.pageStyle == 1 ? [[UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] colorWithAlphaComponent:0.9] : %orig; +} +- (UIColor *)raisedBackground { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)staticBrandBlack { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)generalBackgroundA { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)generalBackgroundB { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +- (UIColor *)menuBackground { + return self.pageStyle == 1 ? [UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] : %orig; +} +%end + %hook YTColdConfig - (BOOL)uiSystemsClientGlobalConfigUseDarkerPaletteBgColorForNative { return NO; } - (BOOL)uiSystemsClientGlobalConfigUseDarkerPaletteTextColorForNative { return NO; } @@ -251,20 +291,46 @@ UIColor* raisedColor = [UIColor colorWithRed:0.035 green:0.035 blue:0.035 alpha: // Others %hook _ASDisplayView +- (void)layoutSubviews { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + UIResponder *responder = [self nextResponder]; + while (responder != nil) { + if ([responder isKindOfClass:NSClassFromString(@"YTActionSheetDialogViewController")]) { + self.backgroundColor = [UIColor blackColor]; + } + if ([responder isKindOfClass:NSClassFromString(@"YTPanelLoadingStrategyViewController")]) { + self.backgroundColor = [UIColor blackColor]; + } + if ([responder isKindOfClass:NSClassFromString(@"YTTabHeaderElementsViewController")]) { + self.backgroundColor = [UIColor blackColor]; + } + if ([responder isKindOfClass:NSClassFromString(@"YTEditSheetControllerElementsContentViewController")]) { + self.backgroundColor = [UIColor blackColor]; + } + responder = [responder nextResponder]; + } + } +} - (void)didMoveToWindow { %orig; if (IS_DARK_APPEARANCE_ENABLED) { if ([self.nextResponder isKindOfClass:%c(ASScrollView)]) { self.backgroundColor = [UIColor clearColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"brand_promo.view"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"eml.cvr"]) { self.backgroundColor = [UIColor blackColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"eml.topic_channel_details"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"rich_header"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.ui.comment_cell"]) { self.backgroundColor = [UIColor blackColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"id.ui.comment_thread"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.ui.cancel.button"]) { self.superview.backgroundColor = [UIColor clearColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.comment_composer"]) { self.backgroundColor = [UIColor blackColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.filter_chip_bar"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.video_list_entry"]) { self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.comment.guidelines_text"]) { self.superview.backgroundColor = [UIColor blackColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.timed_comments_welcome"]) { self.superview.backgroundColor = self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.comment.channel_guidelines_bottom_sheet_container"]) { self.backgroundColor = [UIColor blackColor]; } - if ([self.accessibilityIdentifier isEqualToString:@"id.comment.channel_guidelines_entry_banner_container"]) { self.backgroundColor = [UIColor blackColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.channel_guidelines_entry_banner_container"]) { self.superview.backgroundColor = self.backgroundColor = [UIColor blackColor]; } if ([self.accessibilityIdentifier isEqualToString:@"id.comment.comment_group_detail_container"]) { self.backgroundColor = [UIColor clearColor]; } if ([self.accessibilityIdentifier hasPrefix:@"id.elements.components.overflow_menu_item_"]) { self.backgroundColor = [UIColor clearColor]; } } @@ -301,6 +367,291 @@ UIColor* raisedColor = [UIColor colorWithRed:0.035 green:0.035 blue:0.035 alpha: %end %end +# pragma mark - Custom dark mode by BandarHL + +UIColor *customHexColor; + +%group gCustomTheme +%hook YTCommonColorPalette +- (UIColor *)baseBackground { + return self.pageStyle == 1 ? customHexColor : %orig; +} +- (UIColor *)brandBackgroundSolid { + return self.pageStyle == 1 ? customHexColor : %orig; +} +- (UIColor *)brandBackgroundPrimary { + return self.pageStyle == 1 ? customHexColor : %orig; +} +- (UIColor *)brandBackgroundSecondary { + return self.pageStyle == 1 ? [customHexColor colorWithAlphaComponent:0.9] : %orig; +} +- (UIColor *)raisedBackground { + return self.pageStyle == 1 ? customHexColor : %orig; +} +- (UIColor *)staticBrandBlack { + return self.pageStyle == 1 ? customHexColor : %orig; +} +- (UIColor *)generalBackgroundA { + return self.pageStyle == 1 ? customHexColor : %orig; +} +%end + +// uYou settings +%hook UITableViewCell +- (void)_layoutSystemBackgroundView { + %orig; + UIView *systemBackgroundView = [self valueForKey:@"_systemBackgroundView"]; + NSString *backgroundViewKey = class_getInstanceVariable(systemBackgroundView.class, "_colorView") ? @"_colorView" : @"_backgroundView"; + ((UIView *)[systemBackgroundView valueForKey:backgroundViewKey]).backgroundColor = customHexColor; +} +- (void)_layoutSystemBackgroundView:(BOOL)arg1 { + %orig; + ((UIView *)[[self valueForKey:@"_systemBackgroundView"] valueForKey:@"_colorView"]).backgroundColor = customHexColor; +} +%end + +%hook settingsReorderTable +- (void)viewDidLayoutSubviews { + %orig; + self.tableView.backgroundColor = customHexColor; +} +%end + +%hook FRPSelectListTable +- (void)viewDidLayoutSubviews { + %orig; + self.tableView.backgroundColor = customHexColor; +} +%end + +%hook FRPreferences +- (void)viewDidLayoutSubviews { + %orig; + self.tableView.backgroundColor = customHexColor; +} +%end + +%hook YTInnerTubeCollectionViewController +- (UIColor *)backgroundColor:(NSInteger)pageStyle { + return pageStyle == 1 ? customHexColor : %orig; +} +%end + +// Explore +%hook ASScrollView +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + self.backgroundColor = [UIColor clearColor]; + } +} +%end + +// Your videos +%hook ASCollectionView +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED && [self.nextResponder isKindOfClass:%c(_ASDisplayView)]) { + self.superview.backgroundColor = customHexColor; + } +} +%end + +// Sub menu? +%hook ELMView +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + // self.subviews[0].backgroundColor = [UIColor clearColor]; + } +} +%end + +// iSponsorBlock +%hook SponsorBlockSettingsController +- (void)viewDidLoad { + if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { + %orig; + self.tableView.backgroundColor = customHexColor; + } else { return %orig; } +} +%end + +%hook SponsorBlockViewController +- (void)viewDidLoad { + if (self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) { + %orig; + self.view.backgroundColor = customHexColor; + } else { return %orig; } +} +%end + +// Search view +%hook YTSearchBarView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +// History search view +%hook YTSearchBoxView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; + +} +%end + +// Comment view +%hook YTCommentView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +%hook YTCreateCommentAccessoryView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +%hook YTCreateCommentTextView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +- (void)setTextColor:(UIColor *)color { // fix black text in #Shorts video's comment + return IS_DARK_APPEARANCE_ENABLED ? %orig([UIColor whiteColor]) : %orig; +} +%end + +%hook YTCommentDetailHeaderCell +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + // self.subviews[2].backgroundColor = customHexColor; + } +} +%end + +%hook YTFormattedStringLabel // YT is werid... +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig([UIColor clearColor]) : %orig; +} +%end + +// Live chat comment +%hook YCHLiveChatActionPanelView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +%hook YTEmojiTextView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +%hook YCHLiveChatView +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + // self.subviews[1].backgroundColor = customHexColor; + } +} +%end + +%hook YTCollectionView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +// +%hook YTBackstageCreateRepostDetailView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(customHexColor) : %orig; +} +%end + +// Others +%hook _ASDisplayView +- (void)layoutSubviews { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + UIResponder *responder = [self nextResponder]; + while (responder != nil) { + if ([responder isKindOfClass:NSClassFromString(@"YTActionSheetDialogViewController")]) { + self.backgroundColor = customHexColor; + } + if ([responder isKindOfClass:NSClassFromString(@"YTPanelLoadingStrategyViewController")]) { + self.backgroundColor = customHexColor; + } + if ([responder isKindOfClass:NSClassFromString(@"YTTabHeaderElementsViewController")]) { + self.backgroundColor = customHexColor; + } + if ([responder isKindOfClass:NSClassFromString(@"YTEditSheetControllerElementsContentViewController")]) { + self.backgroundColor = customHexColor; + } + responder = [responder nextResponder]; + } + } +} +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + if ([self.nextResponder isKindOfClass:%c(ASScrollView)]) { self.backgroundColor = [UIColor clearColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"brand_promo.view"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"eml.cvr"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"eml.topic_channel_details"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"eml.live_chat_text_message"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"rich_header"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.ui.comment_cell"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.ui.comment_thread"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.ui.cancel.button"]) { self.superview.backgroundColor = [UIColor clearColor]; } + if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.comment_composer"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.filter_chip_bar"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.elements.components.video_list_entry"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.guidelines_text"]) { self.superview.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.timed_comments_welcome"]) { self.superview.backgroundColor = self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.channel_guidelines_bottom_sheet_container"]) { self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.channel_guidelines_entry_banner_container"]) { self.superview.backgroundColor = self.backgroundColor = customHexColor; } + if ([self.accessibilityIdentifier isEqualToString:@"id.comment.comment_group_detail_container"]) { self.backgroundColor = [UIColor clearColor]; } + if ([self.accessibilityIdentifier hasPrefix:@"id.elements.components.overflow_menu_item_"]) { self.backgroundColor = [UIColor clearColor]; } + } +} +%end + +// Open link with... +%hook ASWAppSwitchingSheetHeaderView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(raisedColor) : %orig; +} +%end + +%hook ASWAppSwitchingSheetFooterView +- (void)setBackgroundColor:(UIColor *)color { + return IS_DARK_APPEARANCE_ENABLED ? %orig(raisedColor) : %orig; +} +%end + +%hook ASWAppSwitcherCollectionViewCell +- (void)didMoveToWindow { + %orig; + if (IS_DARK_APPEARANCE_ENABLED) { + self.backgroundColor = raisedColor; + // self.subviews[1].backgroundColor = raisedColor; + self.superview.backgroundColor = raisedColor; + } +} +%end + +// Incompatibility with the new YT Dark theme +%hook YTColdConfig +- (BOOL)uiSystemsClientGlobalConfigUseDarkerPaletteBgColorForNative { return NO; } +%end +%end + + # pragma mark - OLED keyboard by @ichitaso <3 - http://gist.github.com/ichitaso/935100fd53a26f18a9060f7195a1be0e %group gOLEDKB @@ -347,4 +698,14 @@ UIColor* raisedColor = [UIColor colorWithRed:0.035 green:0.035 blue:0.035 alpha: if (IS_ENABLED(@"oledKeyBoard_enabled")) { %init(gOLEDKB); } -} \ No newline at end of file + if (IS_CUSTOM_DARK_THEME_SELECTED) { + NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomThemeColor"]; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:colorData error:nil]; + [unarchiver setRequiresSecureCoding:NO]; + NSString *hexString = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + if (hexString != nil) { + customHexColor = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey]; + %init(gCustomTheme); + } + } +} diff --git a/Sources/uYouPlusVersionSpoofer.xm b/Sources/uYouPlusVersionSpoofer.xm new file mode 100644 index 0000000..e89b251 --- /dev/null +++ b/Sources/uYouPlusVersionSpoofer.xm @@ -0,0 +1,1247 @@ +#import "uYouPlus.h" + +// +static int appVersionSpoofer() { + return [[NSUserDefaults standardUserDefaults] integerForKey:@"versionSpoofer"]; +} +static BOOL version0() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 0; +} +static BOOL version1() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 1; +} +static BOOL version2() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 2; +} +static BOOL version3() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 3; +} +static BOOL version4() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 4; +} +static BOOL version5() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 5; +} +static BOOL version6() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 6; +} +static BOOL version7() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 7; +} +static BOOL version8() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 8; +} +static BOOL version9() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 9; +} +static BOOL version10() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 10; +} +static BOOL version11() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 11; +} +static BOOL version12() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 12; +} +static BOOL version13() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 13; +} +static BOOL version14() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 14; +} +static BOOL version15() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 15; +} +static BOOL version16() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 16; +} +static BOOL version17() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 17; +} +static BOOL version18() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 18; +} +static BOOL version19() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 19; +} +static BOOL version20() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 20; +} +static BOOL version21() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 21; +} +static BOOL version22() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 22; +} +static BOOL version23() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 23; +} +static BOOL version24() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 24; +} +static BOOL version25() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 25; +} +static BOOL version26() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 26; +} +static BOOL version27() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 27; +} +static BOOL version28() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 28; +} +static BOOL version29() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 29; +} +static BOOL version30() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 30; +} +static BOOL version31() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 31; +} +static BOOL version32() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 32; +} +static BOOL version33() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 33; +} +static BOOL version34() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 34; +} +static BOOL version35() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 35; +} +static BOOL version36() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 36; +} +static BOOL version37() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 37; +} +static BOOL version38() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 38; +} +static BOOL version39() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 39; +} +static BOOL version40() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 40; +} +static BOOL version41() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 41; +} +static BOOL version42() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 42; +} +static BOOL version43() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 43; +} +static BOOL version44() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 44; +} +static BOOL version45() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 45; +} +static BOOL version46() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 46; +} +static BOOL version47() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 47; +} +static BOOL version48() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 48; +} +static BOOL version49() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 49; +} +static BOOL version50() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 50; +} +static BOOL version51() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 51; +} +static BOOL version52() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 52; +} +static BOOL version53() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 53; +} +static BOOL version54() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 54; +} +static BOOL version55() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 55; +} +static BOOL version56() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 56; +} +static BOOL version57() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 57; +} +static BOOL version58() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 58; +} +static BOOL version59() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 59; +} +static BOOL version60() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 60; +} +static BOOL version61() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 61; +} +static BOOL version62() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 62; +} +static BOOL version63() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 63; +} +static BOOL version64() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 64; +} +static BOOL version65() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 65; +} +static BOOL version66() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 66; +} +static BOOL version67() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 67; +} +static BOOL version68() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 68; +} +static BOOL version69() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 69; +} +static BOOL version70() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 70; +} +static BOOL version71() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 71; +} +static BOOL version72() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 72; +} +static BOOL version73() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 73; +} +static BOOL version74() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 74; +} +static BOOL version75() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 75; +} +static BOOL version76() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 76; +} +static BOOL version77() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 77; +} +static BOOL version78() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 78; +} +static BOOL version79() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 79; +} +static BOOL version80() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 80; +} +static BOOL version81() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 81; +} +static BOOL version82() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 82; +} +static BOOL version83() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 83; +} +static BOOL version84() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 84; +} +static BOOL version85() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 85; +} +static BOOL version86() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 86; +} +static BOOL version87() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 87; +} +static BOOL version88() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 88; +} +static BOOL version89() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 89; +} +static BOOL version90() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 90; +} +static BOOL version91() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 91; +} +static BOOL version92() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 92; +} +static BOOL version93() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 93; +} +static BOOL version94() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 94; +} +static BOOL version95() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 95; +} +static BOOL version96() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 96; +} +static BOOL version97() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 97; +} +static BOOL version98() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 98; +} +static BOOL version99() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 99; +} +static BOOL version100() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 100; +} +static BOOL version101() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 101; +} +static BOOL version102() { + return IS_ENABLED(@"enableVersionSpoofer_enabled") && appVersionSpoofer() == 102; +} + +%group gVersion0 +%hook YTVersionUtils // 0 ++ (NSString *)appVersion { return @"18.49.3"; } +%end +%end + +%group gVersion1 +%hook YTVersionUtils // 1 ++ (NSString *)appVersion { return @"18.48.3"; } +%end +%end + +%group gVersion2 +%hook YTVersionUtils // 2 ++ (NSString *)appVersion { return @"18.46.3"; } +%end +%end + +%group gVersion3 +%hook YTVersionUtils // 3 ++ (NSString *)appVersion { return @"18.45.2"; } +%end +%end + +%group gVersion4 +%hook YTVersionUtils // 4 ++ (NSString *)appVersion { return @"18.44.3"; } +%end +%end + +%group gVersion5 +%hook YTVersionUtils // 5 ++ (NSString *)appVersion { return @"18.43.4"; } +%end +%end + +%group gVersion6 +%hook YTVersionUtils // 6 ++ (NSString *)appVersion { return @"18.41.5"; } +%end +%end + +%group gVersion7 +%hook YTVersionUtils // 7 ++ (NSString *)appVersion { return @"18.41.3"; } +%end +%end + +%group gVersion8 +%hook YTVersionUtils // 8 ++ (NSString *)appVersion { return @"18.41.2"; } +%end +%end + +%group gVersion9 +%hook YTVersionUtils // 9 ++ (NSString *)appVersion { return @"18.40.1"; } +%end +%end + +%group gVersion10 +%hook YTVersionUtils // 10 ++ (NSString *)appVersion { return @"18.39.1"; } +%end +%end + +%group gVersion11 +%hook YTVersionUtils // 11 ++ (NSString *)appVersion { return @"18.38.2"; } +%end +%end + +%group gVersion12 +%hook YTVersionUtils // 12 ++ (NSString *)appVersion { return @"18.35.4"; } +%end +%end + +%group gVersion13 +%hook YTVersionUtils // 13 ++ (NSString *)appVersion { return @"18.34.5"; } +%end +%end + +%group gVersion14 +%hook YTVersionUtils // 14 ++ (NSString *)appVersion { return @"18.33.3"; } +%end +%end + +%group gVersion15 +%hook YTVersionUtils // 15 ++ (NSString *)appVersion { return @"18.33.2"; } +%end +%end + +%group gVersion16 +%hook YTVersionUtils // 16 ++ (NSString *)appVersion { return @"18.32.2"; } +%end +%end + +%group gVersion17 +%hook YTVersionUtils // 17 ++ (NSString *)appVersion { return @"18.31.3"; } +%end +%end + +%group gVersion18 +%hook YTVersionUtils // 18 ++ (NSString *)appVersion { return @"18.30.7"; } +%end +%end + +%group gVersion19 +%hook YTVersionUtils // 19 ++ (NSString *)appVersion { return @"18.30.6"; } +%end +%end + +%group gVersion20 +%hook YTVersionUtils // 20 ++ (NSString *)appVersion { return @"18.29.1"; } +%end +%end + +%group gVersion21 +%hook YTVersionUtils // 21 ++ (NSString *)appVersion { return @"18.28.3"; } +%end +%end + +%group gVersion22 +%hook YTVersionUtils // 22 ++ (NSString *)appVersion { return @"18.27.3"; } +%end +%end + +%group gVersion23 +%hook YTVersionUtils // 23 ++ (NSString *)appVersion { return @"18.25.1"; } +%end +%end + +%group gVersion24 +%hook YTVersionUtils // 24 ++ (NSString *)appVersion { return @"18.23.3"; } +%end +%end + +%group gVersion25 +%hook YTVersionUtils // 25 ++ (NSString *)appVersion { return @"18.22.9"; } +%end +%end + +%group gVersion26 +%hook YTVersionUtils // 26 ++ (NSString *)appVersion { return @"18.21.3"; } +%end +%end + +%group gVersion27 +%hook YTVersionUtils // 27 ++ (NSString *)appVersion { return @"18.20.3"; } +%end +%end + +%group gVersion28 +%hook YTVersionUtils // 28 ++ (NSString *)appVersion { return @"18.19.1"; } +%end +%end + +%group gVersion29 +%hook YTVersionUtils // 29 ++ (NSString *)appVersion { return @"18.18.2"; } +%end +%end + +%group gVersion30 +%hook YTVersionUtils // 30 ++ (NSString *)appVersion { return @"18.17.2"; } +%end +%end + +%group gVersion31 +%hook YTVersionUtils // 31 ++ (NSString *)appVersion { return @"18.16.2"; } +%end +%end + +%group gVersion32 +%hook YTVersionUtils // 32 ++ (NSString *)appVersion { return @"18.15.1"; } +%end +%end + +%group gVersion33 +%hook YTVersionUtils // 33 ++ (NSString *)appVersion { return @"18.14.1"; } +%end +%end + +%group gVersion34 +%hook YTVersionUtils // 34 ++ (NSString *)appVersion { return @"18.13.4"; } +%end +%end + +%group gVersion35 +%hook YTVersionUtils // 35 ++ (NSString *)appVersion { return @"18.12.2"; } +%end +%end + +%group gVersion36 +%hook YTVersionUtils // 36 ++ (NSString *)appVersion { return @"18.11.2"; } +%end +%end + +%group gVersion37 +%hook YTVersionUtils // 37 ++ (NSString *)appVersion { return @"18.10.1"; } +%end +%end + +%group gVersion38 +%hook YTVersionUtils // 38 ++ (NSString *)appVersion { return @"18.09.4"; } +%end +%end + +%group gVersion39 +%hook YTVersionUtils // 39 ++ (NSString *)appVersion { return @"18.08.1"; } +%end +%end + +%group gVersion40 +%hook YTVersionUtils // 40 ++ (NSString *)appVersion { return @"18.07.5"; } +%end +%end + +%group gVersion41 +%hook YTVersionUtils // 41 ++ (NSString *)appVersion { return @"18.05.2"; } +%end +%end + +%group gVersion42 +%hook YTVersionUtils // 42 ++ (NSString *)appVersion { return @"18.04.3"; } +%end +%end + +%group gVersion43 +%hook YTVersionUtils // 43 ++ (NSString *)appVersion { return @"18.03.3"; } +%end +%end + +%group gVersion44 +%hook YTVersionUtils // 44 ++ (NSString *)appVersion { return @"18.02.03"; } +%end +%end + +%group gVersion45 +%hook YTVersionUtils // 45 ++ (NSString *)appVersion { return @"18.01.6"; } +%end +%end + +%group gVersion46 +%hook YTVersionUtils // 46 ++ (NSString *)appVersion { return @"18.01.4"; } +%end +%end + +%group gVersion47 +%hook YTVersionUtils // 47 ++ (NSString *)appVersion { return @"18.01.2"; } +%end +%end + +%group gVersion48 +%hook YTVersionUtils // 48 ++ (NSString *)appVersion { return @"17.49.6"; } +%end +%end + +%group gVersion49 +%hook YTVersionUtils // 49 ++ (NSString *)appVersion { return @"17.49.4"; } +%end +%end + +%group gVersion50 +%hook YTVersionUtils // 50 ++ (NSString *)appVersion { return @"17.46.4"; } +%end +%end + +%group gVersion51 +%hook YTVersionUtils // 51 ++ (NSString *)appVersion { return @"17.45.1"; } +%end +%end + +%group gVersion52 +%hook YTVersionUtils // 52 ++ (NSString *)appVersion { return @"17.44.4"; } +%end +%end + +%group gVersion53 +%hook YTVersionUtils // 53 ++ (NSString *)appVersion { return @"17.43.1"; } +%end +%end + +%group gVersion54 +%hook YTVersionUtils // 54 ++ (NSString *)appVersion { return @"17.42.7"; } +%end +%end + +%group gVersion55 +%hook YTVersionUtils // 55 ++ (NSString *)appVersion { return @"17.42.6"; } +%end +%end + +%group gVersion56 +%hook YTVersionUtils // 56 ++ (NSString *)appVersion { return @"17.41.2"; } +%end +%end + +%group gVersion57 +%hook YTVersionUtils // 57 ++ (NSString *)appVersion { return @"17.40.5"; } +%end +%end + +%group gVersion58 +%hook YTVersionUtils // 58 ++ (NSString *)appVersion { return @"17.39.4"; } +%end +%end + +%group gVersion59 +%hook YTVersionUtils // 59 ++ (NSString *)appVersion { return @"17.38.10"; } +%end +%end + +%group gVersion60 +%hook YTVersionUtils // 60 ++ (NSString *)appVersion { return @"17.38.9"; } +%end +%end + +%group gVersion61 +%hook YTVersionUtils // 61 ++ (NSString *)appVersion { return @"17.37.3"; } +%end +%end + +%group gVersion62 +%hook YTVersionUtils // 62 ++ (NSString *)appVersion { return @"17.36.4"; } +%end +%end + +%group gVersion63 +%hook YTVersionUtils // 63 ++ (NSString *)appVersion { return @"17.36.3"; } +%end +%end + +%group gVersion64 +%hook YTVersionUtils // 64 ++ (NSString *)appVersion { return @"17.35.3"; } +%end +%end + +%group gVersion65 +%hook YTVersionUtils // 65 ++ (NSString *)appVersion { return @"17.34.3"; } +%end +%end + +%group gVersion66 +%hook YTVersionUtils // 66 ++ (NSString *)appVersion { return @"17.33.2"; } +%end +%end + +%group gVersion67 +%hook YTVersionUtils // 67 ++ (NSString *)appVersion { return @"17.32.2"; } +%end +%end + +%group gVersion68 +%hook YTVersionUtils // 68 ++ (NSString *)appVersion { return @"17.31.4"; } +%end +%end + +%group gVersion69 +%hook YTVersionUtils // 69 ++ (NSString *)appVersion { return @"17.30.3"; } +%end +%end + +%group gVersion70 +%hook YTVersionUtils // 70 ++ (NSString *)appVersion { return @"17.30.1"; } +%end +%end + +%group gVersion71 +%hook YTVersionUtils // 71 ++ (NSString *)appVersion { return @"17.29.3"; } +%end +%end + +%group gVersion72 +%hook YTVersionUtils // 72 ++ (NSString *)appVersion { return @"17.29.2"; } +%end +%end + +%group gVersion73 +%hook YTVersionUtils // 73 ++ (NSString *)appVersion { return @"17.28.2"; } +%end +%end + +%group gVersion74 +%hook YTVersionUtils // 74 ++ (NSString *)appVersion { return @"17.26.2"; } +%end +%end + +%group gVersion75 +%hook YTVersionUtils // 75 ++ (NSString *)appVersion { return @"17.25.1"; } +%end +%end + +%group gVersion76 +%hook YTVersionUtils // 76 ++ (NSString *)appVersion { return @"17.24.4"; } +%end +%end + +%group gVersion77 +%hook YTVersionUtils // 77 ++ (NSString *)appVersion { return @"17.23.6"; } +%end +%end + +%group gVersion78 +%hook YTVersionUtils // 78 ++ (NSString *)appVersion { return @"17.22.3"; } +%end +%end + +%group gVersion79 +%hook YTVersionUtils // 79 ++ (NSString *)appVersion { return @"17.21.3"; } +%end +%end + +%group gVersion80 +%hook YTVersionUtils // 80 ++ (NSString *)appVersion { return @"17.20.3"; } +%end +%end + +%group gVersion81 +%hook YTVersionUtils // 81 ++ (NSString *)appVersion { return @"17.19.3"; } +%end +%end + +%group gVersion82 +%hook YTVersionUtils // 82 ++ (NSString *)appVersion { return @"17.19.2"; } +%end +%end + +%group gVersion83 +%hook YTVersionUtils // 83 ++ (NSString *)appVersion { return @"17.18.4"; } +%end +%end + +%group gVersion84 +%hook YTVersionUtils // 84 ++ (NSString *)appVersion { return @"17.17.4"; } +%end +%end + +%group gVersion85 +%hook YTVersionUtils // 85 ++ (NSString *)appVersion { return @"17.16.4"; } +%end +%end + +%group gVersion86 +%hook YTVersionUtils // 86 ++ (NSString *)appVersion { return @"17.15.2"; } +%end +%end + +%group gVersion87 +%hook YTVersionUtils // 87 ++ (NSString *)appVersion { return @"17.15.1"; } +%end +%end + +%group gVersion88 +%hook YTVersionUtils // 88 ++ (NSString *)appVersion { return @"17.14.2"; } +%end +%end + +%group gVersion89 +%hook YTVersionUtils // 89 ++ (NSString *)appVersion { return @"17.13.3"; } +%end +%end + +%group gVersion90 +%hook YTVersionUtils // 90 ++ (NSString *)appVersion { return @"17.12.5"; } +%end +%end + +%group gVersion91 +%hook YTVersionUtils // 91 ++ (NSString *)appVersion { return @"17.12.4"; } +%end +%end + +%group gVersion92 +%hook YTVersionUtils // 92 ++ (NSString *)appVersion { return @"17.11.2"; } +%end +%end + +%group gVersion93 +%hook YTVersionUtils // 93 ++ (NSString *)appVersion { return @"17.10.2"; } +%end +%end + +%group gVersion94 +%hook YTVersionUtils // 94 ++ (NSString *)appVersion { return @"17.09.1"; } +%end +%end + +%group gVersion95 +%hook YTVersionUtils // 95 ++ (NSString *)appVersion { return @"17.08.2"; } +%end +%end + +%group gVersion96 +%hook YTVersionUtils // 96 ++ (NSString *)appVersion { return @"17.07.2"; } +%end +%end + +%group gVersion97 +%hook YTVersionUtils // 97 ++ (NSString *)appVersion { return @"17.06.3"; } +%end +%end + +%group gVersion98 +%hook YTVersionUtils // 98 ++ (NSString *)appVersion { return @"17.05.2"; } +%end +%end + +%group gVersion99 +%hook YTVersionUtils // 99 ++ (NSString *)appVersion { return @"17.04.3"; } +%end +%end + +%group gVersion100 +%hook YTVersionUtils // 100 ++ (NSString *)appVersion { return @"17.03.3"; } +%end +%end + +%group gVersion101 +%hook YTVersionUtils // 101 ++ (NSString *)appVersion { return @"17.03.2"; } +%end +%end + +%group gVersion102 +%hook YTVersionUtils // 102 ++ (NSString *)appVersion { return @"17.01.4"; } +%end +%end + +# pragma mark - ctor +%ctor { + %init; + if (version0()) { // 0 + %init(gVersion0); + } + if (version1()) { // 1 + %init(gVersion1); + } + if (version2()) { // 2 + %init(gVersion2); + } + if (version3()) { // 3 + %init(gVersion3); + } + if (version4()) { // 4 + %init(gVersion4); + } + if (version5()) { // 5 + %init(gVersion5); + } + if (version6()) { // 6 + %init(gVersion6); + } + if (version7()) { // 7 + %init(gVersion7); + } + if (version8()) { // 8 + %init(gVersion8); + } + if (version9()) { // 9 + %init(gVersion9); + } + if (version10()) { // 10 + %init(gVersion10); + } + if (version11()) { // 11 + %init(gVersion11); + } + if (version12()) { // 12 + %init(gVersion12); + } + if (version13()) { // 13 + %init(gVersion13); + } + if (version14()) { // 14 + %init(gVersion14); + } + if (version15()) { // 15 + %init(gVersion15); + } + if (version16()) { // 16 + %init(gVersion16); + } + if (version17()) { // 17 + %init(gVersion17); + } + if (version18()) { // 18 + %init(gVersion18); + } + if (version19()) { // 19 + %init(gVersion19); + } + if (version20()) { // 20 + %init(gVersion20); + } + if (version21()) { // 21 + %init(gVersion21); + } + if (version22()) { // 22 + %init(gVersion22); + } + if (version23()) { // 23 + %init(gVersion23); + } + if (version24()) { // 24 + %init(gVersion24); + } + if (version25()) { // 25 + %init(gVersion25); + } + if (version26()) { // 26 + %init(gVersion26); + } + if (version27()) { // 27 + %init(gVersion27); + } + if (version28()) { // 28 + %init(gVersion28); + } + if (version29()) { // 29 + %init(gVersion29); + } + if (version30()) { // 30 + %init(gVersion30); + } + if (version31()) { // 31 + %init(gVersion31); + } + if (version32()) { // 32 + %init(gVersion32); + } + if (version33()) { // 33 + %init(gVersion33); + } + if (version34()) { // 34 + %init(gVersion34); + } + if (version35()) { // 35 + %init(gVersion35); + } + if (version36()) { // 36 + %init(gVersion36); + } + if (version37()) { // 37 + %init(gVersion37); + } + if (version38()) { // 38 + %init(gVersion38); + } + if (version39()) { // 39 + %init(gVersion39); + } + if (version40()) { // 40 + %init(gVersion40); + } + if (version41()) { // 41 + %init(gVersion41); + } + if (version42()) { // 42 + %init(gVersion42); + } + if (version43()) { // 43 + %init(gVersion43); + } + if (version44()) { // 44 + %init(gVersion44); + } + if (version45()) { // 45 + %init(gVersion45); + } + if (version46()) { // 46 + %init(gVersion46); + } + if (version47()) { // 47 + %init(gVersion47); + } + if (version48()) { // 48 + %init(gVersion48); + } + if (version49()) { // 49 + %init(gVersion49); + } + if (version50()) { // 50 + %init(gVersion50); + } + if (version51()) { // 51 + %init(gVersion51); + } + if (version52()) { // 52 + %init(gVersion52); + } + if (version53()) { // 53 + %init(gVersion53); + } + if (version54()) { // 54 + %init(gVersion54); + } + if (version55()) { // 55 + %init(gVersion55); + } + if (version56()) { // 56 + %init(gVersion56); + } + if (version57()) { // 57 + %init(gVersion57); + } + if (version58()) { // 58 + %init(gVersion58); + } + if (version59()) { // 59 + %init(gVersion59); + } + if (version60()) { // 60 + %init(gVersion60); + } + if (version61()) { // 61 + %init(gVersion61); + } + if (version62()) { // 62 + %init(gVersion62); + } + if (version63()) { // 63 + %init(gVersion63); + } + if (version64()) { // 64 + %init(gVersion64); + } + if (version65()) { // 65 + %init(gVersion65); + } + if (version66()) { // 66 + %init(gVersion66); + } + if (version67()) { // 67 + %init(gVersion67); + } + if (version68()) { // 68 + %init(gVersion68); + } + if (version69()) { // 69 + %init(gVersion69); + } + if (version70()) { // 70 + %init(gVersion70); + } + if (version71()) { // 71 + %init(gVersion71); + } + if (version72()) { // 72 + %init(gVersion72); + } + if (version73()) { // 73 + %init(gVersion73); + } + if (version74()) { // 74 + %init(gVersion74); + } + if (version75()) { // 75 + %init(gVersion75); + } + if (version76()) { // 76 + %init(gVersion76); + } + if (version77()) { // 77 + %init(gVersion77); + } + if (version78()) { // 78 + %init(gVersion78); + } + if (version79()) { // 79 + %init(gVersion79); + } + if (version80()) { // 80 + %init(gVersion80); + } + if (version81()) { // 81 + %init(gVersion81); + } + if (version82()) { // 82 + %init(gVersion82); + } + if (version83()) { // 83 + %init(gVersion83); + } + if (version84()) { // 84 + %init(gVersion84); + } + if (version85()) { // 85 + %init(gVersion85); + } + if (version86()) { // 86 + %init(gVersion86); + } + if (version87()) { // 87 + %init(gVersion87); + } + if (version88()) { // 88 + %init(gVersion88); + } + if (version89()) { // 89 + %init(gVersion89); + } + if (version90()) { // 90 + %init(gVersion90); + } + if (version91()) { // 91 + %init(gVersion91); + } + if (version92()) { // 92 + %init(gVersion92); + } + if (version93()) { // 93 + %init(gVersion93); + } + if (version94()) { // 94 + %init(gVersion94); + } + if (version95()) { // 95 + %init(gVersion95); + } + if (version96()) { // 96 + %init(gVersion96); + } + if (version97()) { // 97 + %init(gVersion97); + } + if (version98()) { // 98 + %init(gVersion98); + } + if (version99()) { // 99 + %init(gVersion99); + } + if (version100()) { // 100 + %init(gVersion100); + } + if (version101()) { // 101 + %init(gVersion101); + } + if (version102()) { // 102 + %init(gVersion102); + } +} diff --git a/Sources/update-submodules.txt b/Sources/update-submodules.txt new file mode 100644 index 0000000..3912f99 --- /dev/null +++ b/Sources/update-submodules.txt @@ -0,0 +1,90 @@ +// Template for whenever I refresh the main branch. and even need to re-add the submodules afterwards. + +name: Update Submodules + +on: + workflow_dispatch: + +jobs: + update-submodules: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4.1.1 + + - name: Set up Git + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Actions" + + - name: Add uYouEnhanced submodules + run: | + git submodule add https://github.com/PoomSmart/FLEXing.git Tweaks/FLEXing + git submodule add https://github.com/dayanch96/uYouLocalization.git Tweaks/uYouLocalization + git submodule add https://github.com/arichorn/YTHoldForSpeed.git Tweaks/YTHoldForSpeed + git add . + git commit -m "added uYouEnhanced submodules" + git push origin + +# - name: Update submodules +# run: | +# git submodule update --init --recursive --remote +# git add . +# git commit -m "updated submodules" +# git push origin +# continue-on-error: true + + - name: Update submodules + run: | + git submodule update --init --recursive --remote Tweaks/Alderis + git add . + git submodule update --init --recursive --remote Tweaks/DontEatMyContent + git add . + git submodule update --init --recursive --remote Tweaks/YTHoldForSpeed + git add . + git submodule update --init --recursive --remote Tweaks/MrBeastify + git add . + git submodule update --init --recursive --remote Tweaks/PSHeader + git add . + git submodule update --init --recursive --remote Tweaks/Return-YouTube-Dislikes + git add . + git submodule update --init --recursive --remote Tweaks/uYouLocalization + git add . + git submodule update --init --recursive --remote Tweaks/YTABConfig + git add . + git submodule update --init --recursive --remote Tweaks/YTUHD + git add . + git submodule update --init --recursive --remote Tweaks/YTVideoOverlay + git add . + git submodule update --init --recursive --remote Tweaks/YouMute + git add . + git submodule update --init --recursive --remote Tweaks/YouPiP + git add . + git submodule update --init --recursive --remote Tweaks/YouQuality + git add . + git submodule update --init --recursive --remote Tweaks/YouTubeHeader + git add . + git submodule update --init --recursive --remote Tweaks/iSponsorBlock + git add . + git commit -m "updated submodules" + git push origin + continue-on-error: true + + - name: Make .bundle files + run: | + cd Bundles + ln -s ../Tweaks/MrBeastify/layout/Library/Application\ Support/MrBeastify.bundle MrBeastify.bundle + ln -s ../Tweaks/uYouLocalization/layout/Library/Application\ Support/uYouLocalization.bundle uYouLocalization.bundle + ln -s ../Tweaks/YTHoldForSpeed/layout/Library/Application\ Support/YTHoldForSpeed.bundle YTHoldForSpeed.bundle + git add . + git commit -m "Added bundles" + git push origin + + - name: Check exit code + run: | + exit_code=$? + if [ $exit_code -ne 0 ]; then + echo "Submodule update failed with exit code $exit_code" + exit 1 + fi