mirror of
https://github.com/arichornlover/uYouEnhanced.git
synced 2026-03-11 13:05:31 +00:00
uYouEnhanced v20.44.2: QOL UPDATE
This commit is contained in:
parent
8aca84cc4f
commit
c56628e3f8
30 changed files with 1152 additions and 1106 deletions
2
.github/workflows/update-submodules.yml
vendored
2
.github/workflows/update-submodules.yml
vendored
|
|
@ -62,6 +62,8 @@ jobs:
|
|||
git add .
|
||||
git submodule update --init --recursive --remote Tweaks/YTVideoOverlay
|
||||
git add .
|
||||
git submodule update --init --recursive --remote Tweaks/YTweaks
|
||||
git add .
|
||||
git submodule update --init --recursive
|
||||
git commit -m "updated submodules"
|
||||
git push
|
||||
|
|
|
|||
9
.gitmodules
vendored
9
.gitmodules
vendored
|
|
@ -76,8 +76,7 @@
|
|||
url = https://github.com/PoomSmart/YTIcons.git
|
||||
[submodule "Tweaks/YTUHD"]
|
||||
path = Tweaks/YTUHD
|
||||
url = https://github.com/aricloverEXTRA/YTUHD.git
|
||||
branch = master
|
||||
url = https://github.com/Tonwalter888/YTUHD.git
|
||||
[submodule "Tweaks/YTVideoOverlay"]
|
||||
path = Tweaks/YTVideoOverlay
|
||||
url = https://github.com/PoomSmart/YTVideoOverlay.git
|
||||
|
|
@ -92,3 +91,9 @@
|
|||
[submodule "Tweaks/uYouLocalization"]
|
||||
path = Tweaks/uYouLocalization
|
||||
url = https://github.com/dayanch96/uYouLocalization.git
|
||||
[submodule "Tweaks/libundirect"]
|
||||
path = Tweaks/libundirect
|
||||
url = https://github.com/opa334/libundirect.git
|
||||
[submodule "Tweaks/YTweaks"]
|
||||
path = Tweaks/YTweaks
|
||||
url = https://github.com/fosterbarnes/YTweaks.git
|
||||
|
|
|
|||
1
Bundles/YTWKS.bundle
Symbolic link
1
Bundles/YTWKS.bundle
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../Tweaks/YTweaks/layout/Library/Application Support/YTWKS.bundle
|
||||
BIN
Localizations/uYouPlus.bundle/UI/notifications_selected_2025.png
Normal file
BIN
Localizations/uYouPlus.bundle/UI/notifications_selected_2025.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 825 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
28
Makefile
28
Makefile
|
|
@ -16,7 +16,7 @@ MODULES = jailed
|
|||
endif
|
||||
|
||||
ifndef YOUTUBE_VERSION
|
||||
YOUTUBE_VERSION = 20.50.9
|
||||
YOUTUBE_VERSION = 20.44.2
|
||||
endif
|
||||
ifndef UYOU_VERSION
|
||||
UYOU_VERSION = 3.0.4
|
||||
|
|
@ -33,8 +33,27 @@ $(TWEAK_NAME)_FILES := $(wildcard Sources/*.xm) $(wildcard Sources/*.x) $(wildca
|
|||
$(TWEAK_NAME)_FRAMEWORKS = UIKit Foundation AVFoundation AVKit Photos Accelerate CoreMotion GameController VideoToolbox Security
|
||||
$(TWEAK_NAME)_LIBRARIES = bz2 c++ iconv z
|
||||
$(TWEAK_NAME)_CFLAGS = -fobjc-arc -Wno-deprecated-declarations -Wno-unused-but-set-variable -DTWEAK_VERSION=\"$(PACKAGE_VERSION)\"
|
||||
#uYouLocalization $(TWEAK_NAME)_INJECT_DYLIBS = Tweaks/uYou/Library/MobileSubstrate/DynamicLibraries/uYou.dylib $(THEOS_OBJ_DIR)/uYouLocalization.dylib
|
||||
$(TWEAK_NAME)_INJECT_DYLIBS = Tweaks/uYou/Library/MobileSubstrate/DynamicLibraries/uYou.dylib $(THEOS_OBJ_DIR)/libFLEX.dylib $(THEOS_OBJ_DIR)/iSponsorBlock.dylib $(THEOS_OBJ_DIR)/YTABConfig.dylib $(THEOS_OBJ_DIR)/YTIcons.dylib $(THEOS_OBJ_DIR)/YouGroupSettings.dylib $(THEOS_OBJ_DIR)/YouLoop.dylib $(THEOS_OBJ_DIR)/YouMute.dylib $(THEOS_OBJ_DIR)/YouPiP.dylib $(THEOS_OBJ_DIR)/YouQuality.dylib $(THEOS_OBJ_DIR)/YouSlider.dylib $(THEOS_OBJ_DIR)/YouSpeed.dylib $(THEOS_OBJ_DIR)/YouTimeStamp.dylib $(THEOS_OBJ_DIR)/YouTubeDislikesReturn.dylib $(THEOS_OBJ_DIR)/DontEatMyContent.dylib $(THEOS_OBJ_DIR)/YTHoldForSpeed.dylib $(THEOS_OBJ_DIR)/YTUHD.dylib $(THEOS_OBJ_DIR)/YTVideoOverlay.dylib
|
||||
$(TWEAK_NAME)_INJECT_DYLIBS = \
|
||||
Tweaks/uYou/Library/MobileSubstrate/DynamicLibraries/uYou.dylib \
|
||||
$(THEOS_OBJ_DIR)/libFLEX.dylib \
|
||||
$(THEOS_OBJ_DIR)/iSponsorBlock.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTABConfig.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTIcons.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouGroupSettings.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouLoop.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouMute.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouPiP.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouQuality.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouSlider.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouSpeed.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouTimeStamp.dylib \
|
||||
$(THEOS_OBJ_DIR)/YouTubeDislikesReturn.dylib \
|
||||
$(THEOS_OBJ_DIR)/DontEatMyContent.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTHoldForSpeed.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTUHD.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTVideoOverlay.dylib \
|
||||
$(THEOS_OBJ_DIR)/YTweaks.dylib
|
||||
|
||||
$(TWEAK_NAME)_EMBED_LIBRARIES = $(THEOS_OBJ_DIR)/libcolorpicker.dylib
|
||||
$(TWEAK_NAME)_EMBED_FRAMEWORKS = $(_THEOS_LOCAL_DATA_DIR)/$(THEOS_OBJ_DIR_NAME)/install_Alderis.xcarchive/Products/var/jb/Library/Frameworks/Alderis.framework
|
||||
$(TWEAK_NAME)_EMBED_BUNDLES = $(wildcard Bundles/*.bundle)
|
||||
|
|
@ -42,8 +61,7 @@ $(TWEAK_NAME)_EMBED_EXTENSIONS = $(wildcard Extensions/*.appex)
|
|||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
ifneq ($(JAILBROKEN),1)
|
||||
#uYouLocalization SUBPROJECTS += Tweaks/Alderis Tweaks/uYouLocalization
|
||||
SUBPROJECTS += Tweaks/Alderis Tweaks/DontEatMyContent Tweaks/FLEXing/libflex Tweaks/iSponsorBlock Tweaks/Return-YouTube-Dislikes Tweaks/YTABConfig Tweaks/YouGroupSettings Tweaks/YTIcons Tweaks/YouLoop Tweaks/YouMute Tweaks/YouPiP Tweaks/YouQuality Tweaks/YouSlider Tweaks/YouSpeed Tweaks/YouTimeStamp Tweaks/YTHoldForSpeed Tweaks/YTUHD Tweaks/YTVideoOverlay
|
||||
SUBPROJECTS += Tweaks/Alderis Tweaks/DontEatMyContent Tweaks/FLEXing/libflex Tweaks/iSponsorBlock Tweaks/Return-YouTube-Dislikes Tweaks/YTABConfig Tweaks/YouGroupSettings Tweaks/YTIcons Tweaks/YouLoop Tweaks/YouMute Tweaks/YouPiP Tweaks/YouQuality Tweaks/YouSlider Tweaks/YouSpeed Tweaks/YouTimeStamp Tweaks/YTHoldForSpeed Tweaks/YTUHD Tweaks/YTVideoOverlay Tweaks/YTweaks
|
||||
include $(THEOS_MAKE_PATH)/aggregate.mk
|
||||
endif
|
||||
include $(THEOS_MAKE_PATH)/tweak.mk
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppIconOptionsController : UIViewController
|
||||
@interface AppIconOptionsController : UIViewController <UITableViewDataSource, UITableViewDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIButton *backButton;
|
||||
|
||||
|
|
@ -11,12 +11,3 @@
|
|||
+ (UIImage *)customBackButtonImage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIImage (CustomImages)
|
||||
|
||||
+ (UIImage *)customBackButtonImage {
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"uYouPlus" ofType:@"bundle"]];
|
||||
return [UIImage imageNamed:@"Back.png" inBundle:bundle compatibleWithTraitCollection:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -1,10 +1,32 @@
|
|||
#import "AppIconOptionsController.h"
|
||||
#import <YouTubeHeader/YTAssetLoader.h>
|
||||
#import <notify.h>
|
||||
|
||||
static NSString *const kPrefDomain = @"com.arichornlover.uYouEnhanced";
|
||||
static NSString *const kPrefEnableIconOverride = @"appIconCustomization_enabled";
|
||||
static NSString *const kPrefIconName = @"customAppIcon_name";
|
||||
static NSString *const kPrefNotifyName = @"com.arichornlover.uYouEnhanced.prefschanged";
|
||||
|
||||
static NSString *BundlePath(void) {
|
||||
NSString *path = [[NSBundle mainBundle] pathForResource:@"uYouPlus" ofType:@"bundle"];
|
||||
if (path) return path;
|
||||
return @"/Library/Application Support/uYouEnhanced";
|
||||
}
|
||||
|
||||
@interface AppIconOptionsController ()
|
||||
|
||||
@interface AppIconOptionsController () <UITableViewDataSource, UITableViewDelegate>
|
||||
@property (strong, nonatomic) UITableView *tableView;
|
||||
@property (strong, nonatomic) NSArray<NSString *> *appIcons;
|
||||
@property (assign, nonatomic) NSInteger selectedIconIndex;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIImage (CustomImages)
|
||||
|
||||
+ (UIImage *)customBackButtonImage {
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:BundlePath()];
|
||||
return [UIImage imageNamed:@"Back.png" inBundle:bundle compatibleWithTraitCollection:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppIconOptionsController
|
||||
|
|
@ -14,102 +36,266 @@
|
|||
|
||||
self.title = @"Change App Icon";
|
||||
self.selectedIconIndex = -1;
|
||||
self.view.backgroundColor = [UIColor systemBackgroundColor];
|
||||
|
||||
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
|
||||
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleInsetGrouped];
|
||||
self.tableView.dataSource = self;
|
||||
self.tableView.delegate = self;
|
||||
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
if (@available(iOS 15.0, *)) {
|
||||
self.tableView.sectionHeaderTopPadding = 0;
|
||||
}
|
||||
|
||||
[self.view addSubview:self.tableView];
|
||||
|
||||
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[self.tableView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
|
||||
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
|
||||
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
||||
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
|
||||
]];
|
||||
|
||||
self.navigationItem.hidesBackButton = YES;
|
||||
if (@available(iOS 14.0, *)) {
|
||||
self.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeMinimal;
|
||||
}
|
||||
|
||||
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[self.backButton setImage:[UIImage customBackButtonImage] forState:UIControlStateNormal];
|
||||
[self.backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithCustomView:self.backButton];
|
||||
self.navigationItem.leftBarButtonItem = customBackButton;
|
||||
|
||||
NSString *path = [[NSBundle mainBundle] pathForResource:@"uYouPlus" ofType:@"bundle"];
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:path];
|
||||
self.appIcons = [bundle pathsForResourcesOfType:@"png" inDirectory:@"AppIcons"];
|
||||
NSMutableSet<NSString *> *iconNames = [NSMutableSet set];
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
if (![UIApplication sharedApplication].supportsAlternateIcons) {
|
||||
NSLog(@"Alternate icons are not supported on this device.");
|
||||
NSString *bundlePath = BundlePath();
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
|
||||
|
||||
if (bundle) {
|
||||
NSString *appIconsDir = [bundle.bundlePath stringByAppendingPathComponent:@"AppIcons"];
|
||||
BOOL isDir = NO;
|
||||
if ([fm fileExistsAtPath:appIconsDir isDirectory:&isDir] && isDir) {
|
||||
NSArray *contents = [fm contentsOfDirectoryAtPath:appIconsDir error:nil] ?: @[];
|
||||
for (NSString *entry in contents) {
|
||||
NSString *full = [appIconsDir stringByAppendingPathComponent:entry];
|
||||
BOOL entryIsDir = NO;
|
||||
if ([fm fileExistsAtPath:full isDirectory:&entryIsDir]) {
|
||||
if (entryIsDir) {
|
||||
[iconNames addObject:entry];
|
||||
} else {
|
||||
NSString *ext = entry.pathExtension.lowercaseString;
|
||||
if ([ext isEqualToString:@"png"]) {
|
||||
NSString *name = [entry stringByDeletingPathExtension];
|
||||
if (name.length > 0) {
|
||||
[iconNames addObject:name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSString *supportBase = @"/Library/Application Support/uYouEnhanced/AppIcons";
|
||||
BOOL supportIsDir = NO;
|
||||
|
||||
if ([fm fileExistsAtPath:supportBase isDirectory:&supportIsDir] && supportIsDir) {
|
||||
NSArray *contents = [fm contentsOfDirectoryAtPath:supportBase error:nil] ?: @[];
|
||||
for (NSString *entry in contents) {
|
||||
NSString *full = [supportBase stringByAppendingPathComponent:entry];
|
||||
BOOL isDir = NO;
|
||||
if ([fm fileExistsAtPath:full isDirectory:&isDir]) {
|
||||
if (isDir) {
|
||||
[iconNames addObject:entry];
|
||||
} else {
|
||||
NSString *ext = entry.pathExtension.lowercaseString;
|
||||
if ([ext isEqualToString:@"png"]) {
|
||||
NSString *name = [entry stringByDeletingPathExtension];
|
||||
if (name.length > 0) {
|
||||
[iconNames addObject:name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.appIcons = [[iconNames allObjects] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
|
||||
|
||||
NSDictionary *prefs = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", kPrefDomain]] ?: @{};
|
||||
NSString *savedIcon = prefs[kPrefIconName];
|
||||
|
||||
if (savedIcon) {
|
||||
NSInteger idx = [self.appIcons indexOfObject:savedIcon];
|
||||
if (idx != NSNotFound) self.selectedIconIndex = idx;
|
||||
}
|
||||
|
||||
if (self.appIcons.count == 0) {
|
||||
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectInset(self.view.bounds, 20, 20)];
|
||||
lbl.text = @"No custom icons found. Place PNGs or icon folders in uYouPlus.bundle/AppIcons/ or /Library/Application Support/uYouEnhanced/AppIcons/";
|
||||
lbl.numberOfLines = 0;
|
||||
lbl.textAlignment = NSTextAlignmentCenter;
|
||||
lbl.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[self.view addSubview:lbl];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.appIcons.count;
|
||||
return self.appIcons.count + 1;
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
return 80.0;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
|
||||
if (!cell) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
static NSString *CellId = @"AppIconCell";
|
||||
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellId];
|
||||
if (!cell) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellId];
|
||||
|
||||
if (indexPath.row == 0) {
|
||||
cell.textLabel.text = @"Reset to default";
|
||||
cell.detailTextLabel.text = @"Restore the original app icon";
|
||||
cell.imageView.image = nil;
|
||||
cell.accessoryType = (self.selectedIconIndex == -1) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
return cell;
|
||||
}
|
||||
|
||||
NSString *iconPath = self.appIcons[indexPath.row];
|
||||
cell.textLabel.text = [iconPath.lastPathComponent stringByDeletingPathExtension];
|
||||
NSString *iconName = self.appIcons[indexPath.row - 1];
|
||||
cell.textLabel.text = iconName;
|
||||
cell.detailTextLabel.text = @"Tap to apply this icon";
|
||||
|
||||
UIImage *iconImage = [UIImage imageWithContentsOfFile:iconPath];
|
||||
cell.imageView.image = iconImage;
|
||||
cell.imageView.layer.cornerRadius = 16.0;
|
||||
UIImage *preview = nil;
|
||||
NSArray<NSString *> *candidates = @[
|
||||
@"AppIcon60x60@3x.png",
|
||||
@"AppIcon60x60@2x.png",
|
||||
@"Icon@3x.png",
|
||||
@"Icon@2x.png",
|
||||
@"Icon.png"
|
||||
];
|
||||
|
||||
NSString *bundlePath = BundlePath();
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
|
||||
NSString *supportBase = @"/Library/Application Support/uYouEnhanced/AppIcons";
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
BOOL found = NO;
|
||||
|
||||
if (bundle) {
|
||||
NSString *dir = [bundle.bundlePath stringByAppendingPathComponent:[NSString stringWithFormat:@"AppIcons/%@", iconName]];
|
||||
BOOL isDir = NO;
|
||||
if ([fm fileExistsAtPath:dir isDirectory:&isDir] && isDir) {
|
||||
for (NSString *c in candidates) {
|
||||
NSString *imagePath = [dir stringByAppendingPathComponent:c];
|
||||
if ([fm fileExistsAtPath:imagePath]) {
|
||||
preview = [UIImage imageWithContentsOfFile:imagePath];
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
NSArray *files = [fm contentsOfDirectoryAtPath:dir error:nil];
|
||||
for (NSString *file in files) {
|
||||
NSString *ext = file.pathExtension.lowercaseString;
|
||||
if ([ext isEqualToString:@"png"]) {
|
||||
NSString *path = [dir stringByAppendingPathComponent:file];
|
||||
preview = [UIImage imageWithContentsOfFile:path];
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSString *pngPath = [[bundle.bundlePath stringByAppendingPathComponent:@"AppIcons"] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", iconName]];
|
||||
if ([fm fileExistsAtPath:pngPath]) {
|
||||
preview = [UIImage imageWithContentsOfFile:pngPath];
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
NSString *dir = [supportBase stringByAppendingPathComponent:iconName];
|
||||
BOOL isDir = NO;
|
||||
if ([fm fileExistsAtPath:dir isDirectory:&isDir] && isDir) {
|
||||
for (NSString *c in candidates) {
|
||||
NSString *imagePath = [dir stringByAppendingPathComponent:c];
|
||||
if ([fm fileExistsAtPath:imagePath]) {
|
||||
preview = [UIImage imageWithContentsOfFile:imagePath];
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
NSArray *files = [fm contentsOfDirectoryAtPath:dir error:nil];
|
||||
for (NSString *file in files) {
|
||||
NSString *ext = file.pathExtension.lowercaseString;
|
||||
if ([ext isEqualToString:@"png"]) {
|
||||
NSString *path = [dir stringByAppendingPathComponent:file];
|
||||
preview = [UIImage imageWithContentsOfFile:path];
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSString *pngPath = [supportBase stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", iconName]];
|
||||
if ([fm fileExistsAtPath:pngPath]) {
|
||||
preview = [UIImage imageWithContentsOfFile:pngPath];
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cell.imageView.image = preview;
|
||||
cell.imageView.layer.cornerRadius = 12.0;
|
||||
cell.imageView.clipsToBounds = YES;
|
||||
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
|
||||
cell.accessoryType = (indexPath.row == self.selectedIconIndex) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
cell.accessoryType = ((indexPath.row - 1) == self.selectedIconIndex) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tv deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
self.selectedIconIndex = indexPath.row;
|
||||
[self saveIcon];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
NSString *prefsPath = [NSString stringWithFormat:@"/var/mobile/Library/Preferences/%@.plist", kPrefDomain];
|
||||
NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:prefsPath] ?: [NSMutableDictionary dictionary];
|
||||
|
||||
- (void)resetIcon {
|
||||
[[UIApplication sharedApplication] setAlternateIconName:nil completionHandler:^(NSError * _Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"Error resetting icon: %@", error.localizedDescription);
|
||||
[self showAlertWithTitle:@"Error" message:@"Failed to reset icon"];
|
||||
} else {
|
||||
NSLog(@"Icon reset successfully");
|
||||
[self showAlertWithTitle:@"Success" message:@"Icon reset successfully"];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)saveIcon {
|
||||
if (self.selectedIconIndex < 0) {
|
||||
[self showAlertWithTitle:@"Error" message:@"No icon selected"];
|
||||
if (indexPath.row == 0) {
|
||||
self.selectedIconIndex = -1;
|
||||
prefs[kPrefEnableIconOverride] = @NO;
|
||||
[prefs writeToFile:prefsPath atomically:YES];
|
||||
notify_post([kPrefNotifyName UTF8String]);
|
||||
[self.tableView reloadData];
|
||||
[self showAlertWithTitle:@"Requested" message:@"Icon reset requested."];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *selectedIcon = self.appIcons[self.selectedIconIndex];
|
||||
NSString *iconName = [selectedIcon.lastPathComponent stringByDeletingPathExtension];
|
||||
self.selectedIconIndex = indexPath.row - 1;
|
||||
NSString *iconName = self.appIcons[self.selectedIconIndex];
|
||||
|
||||
[[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
|
||||
if (error) {
|
||||
NSLog(@"Error setting alternate icon: %@", error.localizedDescription);
|
||||
[self showAlertWithTitle:@"Error" message:@"Failed to set alternate icon"];
|
||||
} else {
|
||||
NSLog(@"Alternate icon set successfully");
|
||||
[self showAlertWithTitle:@"Success" message:@"Alternate icon set successfully"];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}];
|
||||
prefs[kPrefEnableIconOverride] = @YES;
|
||||
prefs[kPrefIconName] = iconName;
|
||||
|
||||
BOOL ok = [prefs writeToFile:prefsPath atomically:YES];
|
||||
if (!ok) {
|
||||
[self showAlertWithTitle:@"Error" message:@"Failed to save preference"];
|
||||
return;
|
||||
}
|
||||
|
||||
notify_post([kPrefNotifyName UTF8String]);
|
||||
[self.tableView reloadData];
|
||||
[self showAlertWithTitle:@"Requested" message:@"Icon change requested."];
|
||||
}
|
||||
|
||||
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
|
||||
[alert addAction:okAction];
|
||||
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
|
||||
[alert addAction:ok];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,19 @@ static inline BOOL customContrastMode() {
|
|||
return IS_ENABLED(@"lowContrastMode_enabled") && contrastMode() == 1;
|
||||
}
|
||||
|
||||
// static inline UIColor *activeColor() {
|
||||
// return customContrastMode() && lcmHexColor ? lcmHexColor : kLowContrastColor;
|
||||
// }
|
||||
// Helper to get active contrast color
|
||||
static inline UIColor *activeContrastColor() {
|
||||
return customContrastMode() && lcmHexColor ? lcmHexColor : kLowContrastColor;
|
||||
}
|
||||
|
||||
// Helper to check if dark mode is enabled
|
||||
static inline BOOL isDarkMode() {
|
||||
return UIScreen.mainScreen.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark;
|
||||
}
|
||||
|
||||
// Low Contrast Mode v1.8.0 (Compatible with YouTube v19.21.2-v20.44.2)
|
||||
%group gContrastModeShared
|
||||
|
||||
// Low Contrast Mode v1.7.1.1 (Compatible with only YouTube v19.01.1-v20.21.6)
|
||||
%group gLowContrastMode
|
||||
%hook UIColor
|
||||
+ (UIColor *)colorNamed:(NSString *)name {
|
||||
NSArray<NSString *> *targetColors = @[
|
||||
|
|
@ -32,478 +39,294 @@ static inline BOOL customContrastMode() {
|
|||
@"systemExtraLightGrayColor", @"labelColor", @"secondaryLabelColor",
|
||||
@"tertiaryLabelColor", @"quaternaryLabelColor"
|
||||
];
|
||||
return [targetColors containsObject:name] ? kLowContrastColor : %orig;
|
||||
return [targetColors containsObject:name] ? activeContrastColor() : %orig;
|
||||
}
|
||||
|
||||
+ (UIColor *)whiteColor { return kLowContrastColor; }
|
||||
+ (UIColor *)lightTextColor { return kLowContrastColor; }
|
||||
+ (UIColor *)lightGrayColor { return kLowContrastColor; }
|
||||
+ (UIColor *)whiteColor { return activeContrastColor(); }
|
||||
+ (UIColor *)lightTextColor { return activeContrastColor(); }
|
||||
+ (UIColor *)lightGrayColor { return activeContrastColor(); }
|
||||
%end
|
||||
|
||||
%hook YTCommonColorPalette
|
||||
+ (id)darkPalette {
|
||||
id palette = %orig;
|
||||
if (isDarkMode()) {
|
||||
UIColor *contrastColor = activeContrastColor();
|
||||
[palette setValue:contrastColor forKey:@"textPrimary"];
|
||||
[palette setValue:contrastColor forKey:@"textSecondary"];
|
||||
[palette setValue:contrastColor forKey:@"overlayTextPrimary"];
|
||||
[palette setValue:contrastColor forKey:@"overlayTextSecondary"];
|
||||
[palette setValue:contrastColor forKey:@"iconActive"];
|
||||
[palette setValue:contrastColor forKey:@"iconActiveOther"];
|
||||
[palette setValue:contrastColor forKey:@"brandIconActive"];
|
||||
[palette setValue:contrastColor forKey:@"staticBrandWhite"];
|
||||
[palette setValue:contrastColor forKey:@"overlayIconActiveOther"];
|
||||
[palette setValue:[contrastColor colorWithAlphaComponent:0.7] forKey:@"overlayIconInactive"];
|
||||
[palette setValue:[contrastColor colorWithAlphaComponent:0.3] forKey:@"overlayIconDisabled"];
|
||||
[palette setValue:[contrastColor colorWithAlphaComponent:0.2] forKey:@"overlayFilledButtonActive"];
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
+ (id)lightPalette {
|
||||
return %orig;
|
||||
}
|
||||
|
||||
- (UIColor *)textPrimary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)textSecondary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)overlayTextPrimary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)overlayTextSecondary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)iconActive {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)iconActiveOther {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)brandIconActive {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)staticBrandWhite {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconActiveOther {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
return isDarkMode() ? activeContrastColor() : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconInactive {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor colorWithAlphaComponent:0.7] : %orig;
|
||||
return isDarkMode() ? [activeContrastColor() colorWithAlphaComponent:0.7] : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconDisabled {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor colorWithAlphaComponent:0.3] : %orig;
|
||||
return isDarkMode() ? [activeContrastColor() colorWithAlphaComponent:0.3] : %orig;
|
||||
}
|
||||
- (UIColor *)overlayFilledButtonActive {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor colorWithAlphaComponent:0.2] : %orig;
|
||||
return isDarkMode() ? [activeContrastColor() colorWithAlphaComponent:0.2] : %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook YTColor
|
||||
+ (BOOL)darkerPaletteTextColorEnabled { return NO; }
|
||||
+ (UIColor *)white1 { return kLowContrastColor; }
|
||||
+ (UIColor *)white2 { return kLowContrastColor; }
|
||||
+ (UIColor *)white3 { return kLowContrastColor; }
|
||||
+ (UIColor *)white4 { return kLowContrastColor; }
|
||||
+ (UIColor *)white5 { return kLowContrastColor; }
|
||||
+ (UIColor *)grey1 { return kLowContrastColor; }
|
||||
+ (UIColor *)grey2 { return kLowContrastColor; }
|
||||
+ (UIColor *)white1 { return activeContrastColor(); }
|
||||
+ (UIColor *)white2 { return activeContrastColor(); }
|
||||
+ (UIColor *)white3 { return activeContrastColor(); }
|
||||
+ (UIColor *)white4 { return activeContrastColor(); }
|
||||
+ (UIColor *)white5 { return activeContrastColor(); }
|
||||
+ (UIColor *)grey1 { return activeContrastColor(); }
|
||||
+ (UIColor *)grey2 { return activeContrastColor(); }
|
||||
%end
|
||||
|
||||
%hook _ASDisplayView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
NSArray<NSString *> *targetLabels = @[@"connect account", @"Thanks", @"Save to playlist", @"Report"];
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([targetLabels containsObject:subview.accessibilityLabel]) {
|
||||
subview.backgroundColor = kLowContrastColor;
|
||||
if ([subview isKindOfClass:[UILabel class]]) {
|
||||
((UILabel *)subview).textColor = [UIColor blackColor];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook QTMColorGroup
|
||||
- (UIColor *)tint100 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint300 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint500 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint700 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent200 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent400 { return kDefaultTextColor; }
|
||||
- (UIColor *)accentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)brightAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)regularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)darkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)lightBodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnRegularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnLighterColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnDarkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)buttonBackgroundColor { return kDefaultTextColor; }
|
||||
- (UIColor *)Color { return kDefaultTextColor; }
|
||||
%end
|
||||
|
||||
%hook YTQTMButton
|
||||
- (void)setImage:(UIImage *)image {
|
||||
UIImage *tintedImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
[self setTintColor:kDefaultTextColor];
|
||||
%orig(tintedImage);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:0.9]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGBColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedGrayColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook VideoTitleLabel
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UILabel
|
||||
+ (void)load {
|
||||
[[UILabel appearance] setTextColor:kDefaultTextColor];
|
||||
}
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextField
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISearchBar
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISegmentedControl
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIButton
|
||||
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
|
||||
%orig(kDefaultTextColor, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIBarButtonItem
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook NSAttributedString
|
||||
- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary<NSAttributedStringKey, id> *)attrs {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attrs];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
return %orig(str, modifiedAttributes);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook CATextLayer
|
||||
- (void)setTextColor:(CGColorRef)textColor {
|
||||
%orig(kDefaultTextColor.CGColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextNode
|
||||
- (NSAttributedString *)attributedString {
|
||||
NSAttributedString *original = %orig;
|
||||
NSMutableAttributedString *modified = [original mutableCopy];
|
||||
[modified addAttribute:NSForegroundColorAttributeName value:kDefaultTextColor range:NSMakeRange(0, modified.length)];
|
||||
return modified;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextFieldNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASButtonNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIControl
|
||||
- (UIColor *)backgroundColor {
|
||||
return [UIColor blackColor];
|
||||
}
|
||||
%end
|
||||
%end
|
||||
|
||||
// Custom Contrast Mode
|
||||
%group gCustomContrastMode
|
||||
%hook UIColor
|
||||
+ (UIColor *)colorNamed:(NSString *)name {
|
||||
NSArray<NSString *> *targetColors = @[
|
||||
@"whiteColor", @"lightTextColor", @"lightGrayColor", @"ychGrey7",
|
||||
@"skt_chipBackgroundColor", @"placeholderTextColor", @"systemLightGrayColor",
|
||||
@"systemExtraLightGrayColor", @"labelColor", @"secondaryLabelColor",
|
||||
@"tertiaryLabelColor", @"quaternaryLabelColor"
|
||||
];
|
||||
return [targetColors containsObject:name] ? lcmHexColor : %orig;
|
||||
}
|
||||
|
||||
+ (UIColor *)whiteColor { return lcmHexColor; }
|
||||
+ (UIColor *)lightTextColor { return lcmHexColor; }
|
||||
+ (UIColor *)lightGrayColor { return lcmHexColor; }
|
||||
%end
|
||||
|
||||
%hook YTCommonColorPalette
|
||||
- (UIColor *)textPrimary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)textSecondary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)overlayTextPrimary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)overlayTextSecondary {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)iconActive {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)iconActiveOther {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)brandIconActive {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)staticBrandWhite {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconActiveOther {
|
||||
return self.pageStyle == 1 ? kDefaultTextColor : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconInactive {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor colorWithAlphaComponent:0.7] : %orig;
|
||||
}
|
||||
- (UIColor *)overlayIconDisabled {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor colorWithAlphaComponent:0.3] : %orig;
|
||||
}
|
||||
- (UIColor *)overlayFilledButtonActive {
|
||||
return self.pageStyle == 1 ? [kDefaultTextColor 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 _ASDisplayView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
NSArray<NSString *> *targetLabels = @[@"connect account", @"Thanks", @"Save to playlist", @"Report"];
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([targetLabels containsObject:subview.accessibilityLabel]) {
|
||||
subview.backgroundColor = lcmHexColor;
|
||||
if ([subview isKindOfClass:[UILabel class]]) {
|
||||
((UILabel *)subview).textColor = [UIColor blackColor];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook QTMColorGroup
|
||||
- (UIColor *)tint100 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint300 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint500 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint700 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent200 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent400 { return kDefaultTextColor; }
|
||||
- (UIColor *)accentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)brightAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)regularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)darkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)lightBodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnRegularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnLighterColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnDarkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)buttonBackgroundColor { return kDefaultTextColor; }
|
||||
- (UIColor *)Color { return kDefaultTextColor; }
|
||||
%end
|
||||
|
||||
%hook YTQTMButton
|
||||
- (void)setImage:(UIImage *)image {
|
||||
UIImage *tintedImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
[self setTintColor:kDefaultTextColor];
|
||||
%orig(tintedImage);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:0.9]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGBColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedGrayColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook VideoTitleLabel
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UILabel
|
||||
+ (void)load {
|
||||
[[UILabel appearance] setTextColor:kDefaultTextColor];
|
||||
}
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextField
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISearchBar
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISegmentedControl
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIButton
|
||||
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
|
||||
%orig(kDefaultTextColor, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIBarButtonItem
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook NSAttributedString
|
||||
- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary<NSAttributedStringKey, id> *)attrs {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attrs];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
return %orig(str, modifiedAttributes);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook CATextLayer
|
||||
- (void)setTextColor:(CGColorRef)color {
|
||||
%orig(kDefaultTextColor.CGColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextNode
|
||||
- (NSAttributedString *)attributedString {
|
||||
NSAttributedString *original = %orig;
|
||||
NSMutableAttributedString *modified = [original mutableCopy];
|
||||
[modified addAttribute:NSForegroundColorAttributeName value:kDefaultTextColor range:NSMakeRange(0, modified.length)];
|
||||
return modified;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextFieldNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASButtonNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIControl
|
||||
- (UIColor *)backgroundColor {
|
||||
return [UIColor blackColor];
|
||||
}
|
||||
%end
|
||||
%end
|
||||
|
||||
// Constructor
|
||||
%ctor {
|
||||
%init;
|
||||
if (lowContrastMode()) {
|
||||
%init(gLowContrastMode);
|
||||
}
|
||||
if (customContrastMode()) {
|
||||
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomUIColor"];
|
||||
if (colorData) {
|
||||
NSError *error = nil;
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:colorData error:&error];
|
||||
if (!error) {
|
||||
[unarchiver setRequiresSecureCoding:NO];
|
||||
lcmHexColor = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
|
||||
if (lcmHexColor) {
|
||||
%init(gCustomContrastMode);
|
||||
if (isDarkMode()) {
|
||||
NSArray<NSString *> *targetLabels = @[@"connect account", @"Thanks", @"Save to playlist", @"Report", @"Share", @"Like", @"Dislike"];
|
||||
UIColor *contrastColor = activeContrastColor();
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([targetLabels containsObject:subview.accessibilityLabel]) {
|
||||
subview.backgroundColor = contrastColor;
|
||||
if ([subview isKindOfClass:[UILabel class]]) {
|
||||
((UILabel *)subview).textColor = [UIColor blackColor];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook QTMColorGroup
|
||||
- (UIColor *)tint100 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint300 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint500 { return kDefaultTextColor; }
|
||||
- (UIColor *)tint700 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent200 { return kDefaultTextColor; }
|
||||
- (UIColor *)accent400 { return kDefaultTextColor; }
|
||||
- (UIColor *)accentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)brightAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)regularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)darkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)lightBodyTextColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnRegularColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnLighterColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnDarkerColor { return kDefaultTextColor; }
|
||||
- (UIColor *)bodyTextColorOnAccentColor { return kDefaultTextColor; }
|
||||
- (UIColor *)buttonBackgroundColor { return kDefaultTextColor; }
|
||||
- (UIColor *)Color { return kDefaultTextColor; }
|
||||
%end
|
||||
|
||||
%hook YTQTMButton
|
||||
- (void)setImage:(UIImage *)image {
|
||||
if (isDarkMode()) {
|
||||
UIImage *tintedImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
[self setTintColor:kDefaultTextColor];
|
||||
%orig(tintedImage);
|
||||
} else {
|
||||
%orig;
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:0.9]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedSRGBColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIExtendedGrayColorSpace
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig([kDefaultTextColor colorWithAlphaComponent:1.0]);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook VideoTitleLabel
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(kDefaultTextColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UILabel
|
||||
+ (void)load {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
[[UILabel appearance] setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
|
||||
[[UILabel appearance] setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
|
||||
}
|
||||
if (isDarkMode()) {
|
||||
[[UILabel appearance] setTextColor:kDefaultTextColor];
|
||||
}
|
||||
}
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextField
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UITextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISearchBar
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UISegmentedControl
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
if (isDarkMode()) {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
} else {
|
||||
%orig;
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIButton
|
||||
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : color, state);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIBarButtonItem
|
||||
- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state {
|
||||
if (isDarkMode()) {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
%orig(modifiedAttributes, state);
|
||||
} else {
|
||||
%orig;
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook NSAttributedString
|
||||
- (instancetype)initWithString:(NSString *)str attributes:(NSDictionary<NSAttributedStringKey, id> *)attrs {
|
||||
if (isDarkMode()) {
|
||||
NSMutableDictionary *modifiedAttributes = [NSMutableDictionary dictionaryWithDictionary:attrs];
|
||||
modifiedAttributes[NSForegroundColorAttributeName] = kDefaultTextColor;
|
||||
return %orig(str, modifiedAttributes);
|
||||
}
|
||||
return %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook CATextLayer
|
||||
- (void)setTextColor:(CGColorRef)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor.CGColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextNode
|
||||
- (NSAttributedString *)attributedString {
|
||||
NSAttributedString *original = %orig;
|
||||
if (isDarkMode()) {
|
||||
NSMutableAttributedString *modified = [original mutableCopy];
|
||||
[modified addAttribute:NSForegroundColorAttributeName value:kDefaultTextColor range:NSMakeRange(0, modified.length)];
|
||||
return modified;
|
||||
}
|
||||
return original;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextFieldNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASTextView
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook ASButtonNode
|
||||
- (void)setTextColor:(UIColor *)textColor {
|
||||
%orig(isDarkMode() ? kDefaultTextColor : textColor);
|
||||
}
|
||||
%end
|
||||
|
||||
%hook UIControl
|
||||
- (UIColor *)backgroundColor {
|
||||
return isDarkMode() ? [UIColor blackColor] : %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
%end
|
||||
|
||||
// Constructor
|
||||
%ctor {
|
||||
%init;
|
||||
if (lowContrastMode() || customContrastMode()) {
|
||||
%init(gContrastModeShared);
|
||||
if (customContrastMode()) {
|
||||
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"kCustomUIColor"];
|
||||
if (colorData) {
|
||||
NSError *error = nil;
|
||||
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:colorData error:&error];
|
||||
if (!error) {
|
||||
[unarchiver setRequiresSecureCoding:NO];
|
||||
lcmHexColor = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,20 +37,24 @@ static int getNotificationIconStyle() {
|
|||
NSString *imageName;
|
||||
UIColor *iconColor;
|
||||
switch (getNotificationIconStyle()) {
|
||||
case 1: // Thin outline style (2020+)
|
||||
case 1: // Bold outline style (2024+)
|
||||
imageName = isSelected ? @"notifications_selected" : @"notifications_unselected";
|
||||
iconColor = [%c(YTColor) white1];
|
||||
break;
|
||||
case 2: // Thin outline style (2020+)
|
||||
imageName = isSelected ? @"notifications_selected" : @"notifications_24pt";
|
||||
iconColor = [%c(YTColor) white1];
|
||||
break;
|
||||
case 2: // Filled style (2018+)
|
||||
case 3: // Filled style (2018+)
|
||||
imageName = @"notifications_selected";
|
||||
iconColor = isSelected ? [%c(YTColor) white1] : [UIColor grayColor];
|
||||
break;
|
||||
case 3: // Inbox style (2014+)
|
||||
case 4: // Inbox style (2014+)
|
||||
imageName = @"inbox_selected";
|
||||
iconColor = isSelected ? [%c(YTColor) white1] : [UIColor grayColor];
|
||||
break;
|
||||
default: // Default style
|
||||
imageName = isSelected ? @"notifications_selected" : @"notifications_unselected";
|
||||
default: // Default style (2025+)
|
||||
imageName = isSelected ? @"notifications_selected_2025" : @"notifications_unselected_2025";
|
||||
iconColor = [%c(YTColor) white1];
|
||||
break;
|
||||
}
|
||||
|
|
@ -115,99 +119,178 @@ static int getNotificationIconStyle() {
|
|||
%end
|
||||
%end
|
||||
|
||||
// LEGACY VERSION ⚠️
|
||||
// Hide the (Connect / Thanks / Save / Report) Buttons under the Video Player - 17.33.2 and up - @arichornlover (inspired by @PoomSmart's version)
|
||||
%hook _ASDisplayView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
BOOL hideConnectButton = IS_ENABLED(@"hideConnectButton_enabled");
|
||||
BOOL hideThanksButton = IS_ENABLED(@"hideThanksButton_enabled");
|
||||
BOOL hideSaveToPlaylistButton = IS_ENABLED(@"hideSaveToPlaylistButton_enabled");
|
||||
BOOL hideReportButton = IS_ENABLED(@"hideReportButton_enabled");
|
||||
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([subview.accessibilityLabel isEqualToString:@"connect account"]) {
|
||||
subview.hidden = hideConnectButton;
|
||||
} else if ([subview.accessibilityLabel isEqualToString:@"Thanks"]) {
|
||||
subview.hidden = hideThanksButton;
|
||||
} else if ([subview.accessibilityLabel isEqualToString:@"Save to playlist"]) {
|
||||
subview.hidden = hideSaveToPlaylistButton;
|
||||
} else if ([subview.accessibilityLabel isEqualToString:@"Report"]) {
|
||||
subview.hidden = hideReportButton;
|
||||
}
|
||||
}
|
||||
// YTHidePlayerButtons 1.0.0 - made by @aricloverEXTRA
|
||||
static NSDictionary<NSString *, NSString *> *HideToggleMap(void) {
|
||||
static NSDictionary<NSString *, NSString *> *map = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
map = @{
|
||||
// identifiers
|
||||
@"id.video.share.button": @"hideShareButton_enabled",
|
||||
@"id.ui.add_to.offline.button": @"hideDownloadButton_enabled",
|
||||
@"id.video.remix.button": @"hideRemixButton_enabled",
|
||||
@"clip_button.eml": @"hideClipButton_enabled",
|
||||
@"id.ui.carousel_header": @"hideCommentSection_enabled",
|
||||
// fallbacks
|
||||
@"Like": @"hideLikeButton_enabled", // unidentified identifier
|
||||
@"Dislike": @"hideDislikeButton_enabled", // unidentified identifier
|
||||
@"Share": @"hideShareButton_enabled", // Share Button
|
||||
@"Ask": @"hideAskButton_enabled", // unidentified identifier
|
||||
@"Download": @"hideDownloadButton_enabled", // Download Button
|
||||
@"Hype": @"hideHypeButton_enabled", // unidentified identifier
|
||||
@"Thanks": @"hideThanksButton_enabled", // unidentified identifier
|
||||
@"Remix": @"hideRemixButton_enabled", // Remix Button
|
||||
@"Clip": @"hideClipButton_enabled", // Clip Button
|
||||
@"Save to playlist": @"hideSaveToPlaylistButton_enabled", // unidentified identifier
|
||||
@"Report": @"hideReportButton_enabled", // unidentified identifier
|
||||
@"connect account": @"hideConnectButton_enabled" // unidentified identifier
|
||||
};
|
||||
});
|
||||
return map;
|
||||
}
|
||||
%end
|
||||
|
||||
// UPDATED VERSION
|
||||
// Hide the (Connect / Share / Remix / Thanks / Download / Clip / Save / Report) Buttons under the Video Player - 17.33.2 and up - @PoomSmart (inspired by @arichornlover) - METHOD BROKE Server-Side on May 14th 2024
|
||||
static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *identifiers) {
|
||||
for (id child in [nodeController children]) {
|
||||
NSLog(@"Child: %@", [child description]);
|
||||
|
||||
if ([child isKindOfClass:%c(ELMNodeController)]) {
|
||||
NSArray <ELMComponent *> *elmChildren = [(ELMNodeController * _Nullable)child children];
|
||||
for (ELMComponent *elmChild in elmChildren) {
|
||||
for (NSString *identifier in identifiers) {
|
||||
if ([[elmChild description] containsString:identifier]) {
|
||||
NSLog(@"Found identifier: %@", identifier);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
static BOOL shouldHideForKey(NSString *key) {
|
||||
if (!key) return NO;
|
||||
NSString *pref = HideToggleMap()[key];
|
||||
if (!pref) return NO;
|
||||
return IS_ENABLED(pref);
|
||||
}
|
||||
static void safeHideView(id view) {
|
||||
if (!view) return;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@try {
|
||||
if ([view respondsToSelector:@selector(setHidden:)]) {
|
||||
[view setHidden:YES];
|
||||
return;
|
||||
}
|
||||
if ([view isKindOfClass:[UIView class]]) {
|
||||
((UIView *)view).hidden = YES;
|
||||
return;
|
||||
}
|
||||
} @catch (NSException *ex) {
|
||||
NSLog(@"[HidePlayerButtons] safeHideView exception: %@", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
static BOOL inspectAndHideIfMatch(id view) {
|
||||
if (!view) return NO;
|
||||
@try {
|
||||
NSString *accId = nil;
|
||||
if ([view respondsToSelector:@selector(accessibilityIdentifier)]) {
|
||||
@try { accId = [view accessibilityIdentifier]; } @catch (NSException *e) { accId = nil; }
|
||||
if (accId && shouldHideForKey(accId)) {
|
||||
safeHideView(view);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
if ([child isKindOfClass:%c(ASNodeController)]) {
|
||||
ASDisplayNode *childNode = ((ASNodeController * _Nullable)child).node; // ELMContainerNode
|
||||
NSArray<id> *yogaChildren = childNode.yogaChildren;
|
||||
for (ASDisplayNode *displayNode in yogaChildren) {
|
||||
NSLog(@"Yoga Child: %@", displayNode.accessibilityIdentifier);
|
||||
|
||||
if ([identifiers containsObject:displayNode.accessibilityIdentifier]) {
|
||||
NSLog(@"Found identifier: %@", displayNode.accessibilityIdentifier);
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (findCell(child, identifiers)) {
|
||||
NSString *accLabel = nil;
|
||||
if ([view respondsToSelector:@selector(accessibilityLabel)]) {
|
||||
@try { accLabel = [view accessibilityLabel]; } @catch (NSException *e) { accLabel = nil; }
|
||||
if (accLabel && shouldHideForKey(accLabel)) {
|
||||
safeHideView(view);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
NSString *desc = nil;
|
||||
@try { desc = [[view description] copy]; } @catch (NSException *e) { desc = nil; }
|
||||
if (desc) {
|
||||
for (NSString *key in HideToggleMap().allKeys) {
|
||||
if ([desc containsString:key] && shouldHideForKey(key)) {
|
||||
safeHideView(view);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
} @catch (NSException *ex) {
|
||||
NSLog(@"[HidePlayerButtons] inspectAndHideIfMatch exception: %@", ex);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
%hook ASCollectionView // This stopped working on May 14th 2024 due to a Server-Side Change from YouTube.
|
||||
- (CGSize)sizeForElement:(ASCollectionElement * _Nullable)element {
|
||||
if ([self.accessibilityIdentifier isEqualToString:@"id.video.scrollable_action_bar"]) {
|
||||
ASCellNode *node = [element node];
|
||||
ASNodeController *nodeController = [node controller];
|
||||
|
||||
if (IS_ENABLED(@"hideShareButton_enabled") && findCell(nodeController, @[@"id.video.share.button"])) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(@"hideRemixButton_enabled") && findCell(nodeController, @[@"id.video.remix.button"])) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(@"hideThanksButton_enabled") && findCell(nodeController, @[@"Thanks"])) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(@"hideClipButton_enabled") && findCell(nodeController, @[@"clip_button.eml"])) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(@"hideDownloadButton_enabled") && findCell(nodeController, @[@"id.ui.add_to.offline.button"])) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(@"hideCommentSection_enabled") && findCell(nodeController, @[@"id.ui.carousel_header"])) {
|
||||
return CGSizeZero;
|
||||
static void traverseAndHideViews(UIView *root) {
|
||||
if (!root) return;
|
||||
@try {
|
||||
inspectAndHideIfMatch(root);
|
||||
NSArray<UIView *> *subs = nil;
|
||||
@try { subs = root.subviews; } @catch (NSException *e) { subs = nil; }
|
||||
if (subs && subs.count) {
|
||||
for (UIView *sv in subs) {
|
||||
if ([sv isKindOfClass:[UIView class]]) {
|
||||
traverseAndHideViews(sv);
|
||||
}
|
||||
}
|
||||
}
|
||||
} @catch (NSException *ex) {
|
||||
NSLog(@"[HidePlayerButtons] traverseAndHideViews exception: %@", ex);
|
||||
}
|
||||
return %orig;
|
||||
}
|
||||
static void hideButtonsInActionBarIfNeeded(id collectionView) {
|
||||
if (!collectionView) return;
|
||||
@try {
|
||||
// Ensure the collectionView has accessibilityIdentifier and we only operate on the action bar
|
||||
NSString *accId = nil;
|
||||
if ([collectionView respondsToSelector:@selector(accessibilityIdentifier)]) {
|
||||
@try { accId = [collectionView accessibilityIdentifier]; } @catch (NSException *e) { accId = nil; }
|
||||
}
|
||||
if (!accId) return;
|
||||
if (![accId isEqualToString:@"id.video.scrollable_action_bar"]) return;
|
||||
NSArray *cells = nil;
|
||||
if ([collectionView respondsToSelector:@selector(visibleCells)]) {
|
||||
@try { cells = [collectionView visibleCells]; } @catch (NSException *e) { cells = nil; }
|
||||
}
|
||||
if (!cells || cells.count == 0) {
|
||||
@try { cells = [collectionView subviews]; } @catch (NSException *e) { cells = nil; }
|
||||
}
|
||||
if (!cells || cells.count == 0) return;
|
||||
for (id cell in cells) {
|
||||
if ([cell isKindOfClass:[UIView class]]) {
|
||||
traverseAndHideViews((UIView *)cell);
|
||||
} else {
|
||||
@try {
|
||||
if ([cell respondsToSelector:@selector(view)]) {
|
||||
id view = [cell performSelector:@selector(view)];
|
||||
if ([view isKindOfClass:[UIView class]]) {
|
||||
traverseAndHideViews((UIView *)view);
|
||||
}
|
||||
} else if ([cell respondsToSelector:@selector(node)]) {
|
||||
NSString *desc = nil;
|
||||
@try { desc = [cell description]; } @catch (NSException *e) { desc = nil; }
|
||||
if (desc) {
|
||||
// Not ideal to act on description, but we keep this non-destructive: only log for debugging
|
||||
// Uncomment logging for debug builds if needed.
|
||||
// NSLog(@"[HidePlayerButtons] Non-UIView cell description: %@", desc);
|
||||
}
|
||||
}
|
||||
} @catch (NSException *ex) {
|
||||
NSLog(@"[HidePlayerButtons] Exception handling non-UIView cell: %@", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"[HidePlayerButtons] hideButtonsInActionBarIfNeeded exception: %@", exception);
|
||||
}
|
||||
}
|
||||
%hook ASCollectionView
|
||||
- (id)nodeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
id node = %orig;
|
||||
id weakSelf = (id)self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@try {
|
||||
hideButtonsInActionBarIfNeeded(weakSelf);
|
||||
} @catch (NSException *e) {
|
||||
NSLog(@"[HidePlayerButtons] async hide exception: %@", e);
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
- (void)nodesDidRelayout:(NSArray *)nodes {
|
||||
%orig;
|
||||
id weakSelf = (id)self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@try {
|
||||
hideButtonsInActionBarIfNeeded(weakSelf);
|
||||
} @catch (NSException *e) {
|
||||
NSLog(@"[HidePlayerButtons] relayout hide exception: %@", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
%end
|
||||
|
||||
|
|
@ -873,13 +956,6 @@ static NSMutableArray <YTIItemSectionRenderer *> *filteredArray(NSArray <YTIItem
|
|||
%end
|
||||
%end
|
||||
|
||||
// Disable Modern/Rounded Buttons (_ASDisplayView Version's not supported) - @arichornlover
|
||||
%group gDisableModernButtons
|
||||
%hook YTQTMButton // Disable Modern/Rounded Buttons
|
||||
+ (BOOL)buttonModernizationEnabled { return NO; }
|
||||
%end
|
||||
%end
|
||||
|
||||
// Disable Rounded Hints with no Rounded Corners - @arichornlover
|
||||
%group gDisableRoundedHints
|
||||
%hook YTBubbleHintView // Disable Modern/Rounded Hints
|
||||
|
|
@ -887,61 +963,6 @@ static NSMutableArray <YTIItemSectionRenderer *> *filteredArray(NSArray <YTIItem
|
|||
%end
|
||||
%end
|
||||
|
||||
// Disable Modern Flags - @arichornlover
|
||||
%group gDisableModernFlags
|
||||
%hook YTColdConfig
|
||||
// Disable Modern Content
|
||||
- (BOOL)creatorClientConfigEnableStudioModernizedMdeThumbnailPickerForClient { return NO; }
|
||||
- (BOOL)cxClientEnableModernizedActionSheet { return NO; }
|
||||
- (BOOL)enableClientShortsSheetsModernization { return NO; }
|
||||
- (BOOL)enableTimestampModernizationForNative { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaFeedStretchBottom { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaFrostedBottomBar { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaFrostedPivotBar { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaFrostedPivotBarUpdatedBackdrop { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaFrostedTopBar { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaOpacityPivotBar { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernIaTopAndBottomBarIconRefresh { return NO; }
|
||||
- (BOOL)mainAppCoreClientEnableModernizedBedtimeReminderU18DefaultSettings { return NO; }
|
||||
- (BOOL)modernizeCameoNavbar { return NO; }
|
||||
- (BOOL)modernizeCollectionLockups { return NO; }
|
||||
- (BOOL)modernizeCollectionLockupsShowVideoCount { return NO; }
|
||||
- (BOOL)modernizeElementsBgColor { return NO; }
|
||||
- (BOOL)modernizeElementsTextColor { return NO; }
|
||||
- (BOOL)postsCreatorClientEnableModernButtonsUi { return NO; }
|
||||
- (BOOL)pullToFullModernEdu { return NO; }
|
||||
- (BOOL)showModernMiniplayerRedesign { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigEnableModernButtonsForNative { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigIosEnableModernTabsForNative { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigIosEnableSnackbarModernization { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigModernizeNativeBgColor { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigModernizeNativeTextColor { return NO; }
|
||||
// Disable Rounded Content
|
||||
- (BOOL)enableIosFloatingMiniplayerRoundedCornerRadius { return YES; }
|
||||
- (BOOL)iosDownloadsPageRoundedThumbs { return NO; }
|
||||
- (BOOL)iosRoundedSearchBarSuggestZeroPadding { return NO; }
|
||||
- (BOOL)uiSystemsClientGlobalConfigEnableRoundedDialogForNative { return NO; }
|
||||
- (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 - @arichornlover
|
||||
%group gDisableAmbientMode
|
||||
%hook YTCinematicContainerView
|
||||
|
|
@ -1943,15 +1964,9 @@ static NSMutableArray <YTIItemSectionRenderer *> *filteredArray(NSArray <YTIItem
|
|||
if (IS_ENABLED(kClassicVideoPlayer)) {
|
||||
%init(gClassicVideoPlayer);
|
||||
}
|
||||
if (IS_ENABLED(kDisableModernButtons)) {
|
||||
%init(gDisableModernButtons);
|
||||
}
|
||||
if (IS_ENABLED(kDisableRoundedHints)) {
|
||||
%init(gDisableRoundedHints);
|
||||
}
|
||||
if (IS_ENABLED(kDisableModernFlags)) {
|
||||
%init(gDisableModernFlags);
|
||||
}
|
||||
if (IS_ENABLED(kDisableAmbientMode)) {
|
||||
%init(gDisableAmbientMode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,8 @@
|
|||
- (NSDictionary *)infoDictionary {
|
||||
NSDictionary *orig = %orig;
|
||||
if ([self isEqual:NSBundle.mainBundle]) {
|
||||
NSArray<NSString *> *stack = [NSThread callStackSymbols];
|
||||
BOOL needsSpoof = NO;
|
||||
for (NSString *frame in stack) {
|
||||
if ([frame containsString:@"GIDSignIn"] ||
|
||||
[frame containsString:@"GTMSessionFetcher"] ||
|
||||
[frame containsString:@"GoogleSignIn"]) {
|
||||
needsSpoof = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needsSpoof) {
|
||||
NSMutableDictionary *patched = [orig mutableCopy];
|
||||
NSMutableDictionary *patched = [orig mutableCopy];
|
||||
if (patched) {
|
||||
patched[@"CFBundleIdentifier"] = @"com.google.ios.youtube";
|
||||
return [patched copy];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -565,12 +565,26 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
kLowContrastMode,
|
||||
({
|
||||
if (enable) {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
} else {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Outdated iOS Version" message:@"LowContrastMode is designed for iOS 16 or higher. You are running an older iOS version. Enable anyway?" preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Enable" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[NSUserDefaults standardUserDefaults] setBool:enable forKey:kLowContrastMode];
|
||||
[settingsViewController reloadData];
|
||||
SHOW_RELAUNCH_YT_SNACKBAR;
|
||||
}];
|
||||
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||
[alert addAction:okAction];
|
||||
[alert addAction:cancelAction];
|
||||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
return NO;
|
||||
}
|
||||
Class YTVersionUtilsClass = %c(YTVersionUtils);
|
||||
NSString *appVersion = [YTVersionUtilsClass performSelector:@selector(appVersion)];
|
||||
NSComparisonResult result1 = [appVersion compare:@"17.33.2" options:NSNumericSearch];
|
||||
NSComparisonResult result2 = [appVersion compare:@"17.38.10" options:NSNumericSearch];
|
||||
NSComparisonResult result1 = [appVersion compare:@"19.01.1" options:NSNumericSearch];
|
||||
NSComparisonResult result2 = [appVersion compare:@"20.33.2" options:NSNumericSearch];
|
||||
if (result1 == NSOrderedAscending) {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Discontinued Version" message:[NSString stringWithFormat:@"You are using v%@, a discontinued version of YouTube that may not work with LowContrastMode. Supported versions are v17.33.2-v17.38.10. Enable anyway?", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Discontinued YouTube Version" message:[NSString stringWithFormat:@"You are using v%@, a discontinued version of YouTube that may not work with LowContrastMode. Supported versions are v19.01.1-v20.33.2. Enable anyway?", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Enable" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[NSUserDefaults standardUserDefaults] setBool:enable forKey:kLowContrastMode];
|
||||
[settingsViewController reloadData];
|
||||
|
|
@ -582,7 +596,7 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
return NO;
|
||||
} else if (result2 == NSOrderedDescending) {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Incompatible Version" message:[NSString stringWithFormat:@"LowContrastMode is only available for app versions v17.33.2-v17.38.10. You are using v%@. Enable anyway?", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Incompatible YouTube Version" message:[NSString stringWithFormat:@"LowContrastMode is only available for app versions v19.01.1-v20.33.2. You are using v%@. Enable anyway?", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Enable" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
||||
[[NSUserDefaults standardUserDefaults] setBool:enable forKey:kLowContrastMode];
|
||||
[settingsViewController reloadData];
|
||||
|
|
@ -594,7 +608,7 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
return NO;
|
||||
} else if (UIScreen.mainScreen.traitCollection.userInterfaceStyle != UIUserInterfaceStyleDark) {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Light Mode Detected" message:@"LowContrastMode is only available in Dark Mode. Please switch to Dark Mode to be able to use LowContrastMode." preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Light Mode Detected" message:@"LowContrastMode is only designed for Dark Mode in mind. Please enable Dark Mode to be able to use LowContrastMode." preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
|
||||
[alert addAction:okAction];
|
||||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
|
|
@ -625,7 +639,7 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
Class YTVersionUtilsClass = %c(YTVersionUtils);
|
||||
NSString *appVersion = [YTVersionUtilsClass performSelector:@selector(appVersion)];
|
||||
// Alert the user that they need to enable the fix
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Incompatibile" message:[NSString stringWithFormat:@"LowContrastMode is only available for app versions v17.33.2-v17.38.10. \nYou are currently using v%@. \n\nWorkaround: if you want to use this then I recommend enabling \"Fix LowContrastMode\" Option.", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Incompatible YouTube Version" message:[NSString stringWithFormat:@"LowContrastMode is only available for app versions v19.01.1-v20.33.2. You are using v%@. Enable anyway?", appVersion] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
|
||||
[alert addAction:okAction];
|
||||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
|
|
@ -642,7 +656,6 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
[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];
|
||||
|
|
@ -652,16 +665,14 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
];
|
||||
[sectionItems addObject:lowContrastModeButton];
|
||||
SWITCH2(LOC(@"CLASSIC_VIDEO_PLAYER"), LOC(@"CLASSIC_VIDEO_PLAYER_DESC"), kClassicVideoPlayer);
|
||||
SWITCH2(LOC(@"DISABLE_MODERN_BUTTONS"), LOC(@"DISABLE_MODERN_BUTTONS_DESC"), kDisableModernButtons);
|
||||
SWITCH2(LOC(@"DISABLE_ROUNDED_CORNERS_ON_HINTS"), LOC(@"DISABLE_ROUNDED_CORNERS_ON_HINTS_DESC"), kDisableRoundedHints);
|
||||
SWITCH2(LOC(@"DISABLE_MODERN_FLAGS"), LOC(@"DISABLE_MODERN_FLAGS_DESC"), kDisableModernFlags);
|
||||
SWITCH3(
|
||||
LOC(@"YTNOMODERNUI"),
|
||||
LOC(@"YTNOMODERNUI_DESC"),
|
||||
kYTNoModernUI,
|
||||
({
|
||||
if (enable) {
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Warning" message:@"This will force-enable other settings on restart. To disable them, you must turn this setting off." preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Warning" message:@"This will force-enable other settings on restart. To disable them, you must turn this setting off. (YTNoModernUI is Deprecated)" preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
|
||||
[alert addAction:okAction];
|
||||
[settingsViewController presentViewController:alert animated:YES completion:nil];
|
||||
|
|
@ -678,303 +689,267 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
accessibilityIdentifier:nil
|
||||
detailTextBlock:^NSString *() {
|
||||
switch (appVersionSpoofer()) {
|
||||
case 0:
|
||||
return @"v20.33.2";
|
||||
case 1:
|
||||
return @"v20.32.5";
|
||||
case 2:
|
||||
return @"v20.32.4";
|
||||
case 3:
|
||||
return @"v20.31.6";
|
||||
case 4:
|
||||
return @"v20.31.5";
|
||||
case 5:
|
||||
return @"v20.30.5";
|
||||
case 6:
|
||||
return @"v20.29.3";
|
||||
case 7:
|
||||
return @"v20.28.2";
|
||||
case 8:
|
||||
return @"v20.26.7";
|
||||
case 9:
|
||||
return @"v20.25.4";
|
||||
case 10:
|
||||
return @"v20.24.5";
|
||||
case 11:
|
||||
return @"v20.24.4";
|
||||
case 12:
|
||||
return @"v20.23.3";
|
||||
case 13:
|
||||
return @"v20.22.1";
|
||||
case 14:
|
||||
return @"v20.21.6";
|
||||
case 15:
|
||||
return @"v20.20.7";
|
||||
case 16:
|
||||
return @"v20.20.5";
|
||||
case 17:
|
||||
return @"v20.19.3";
|
||||
case 18:
|
||||
return @"v20.19.2";
|
||||
case 19:
|
||||
return @"v20.18.5";
|
||||
case 20:
|
||||
return @"v20.18.4";
|
||||
case 21:
|
||||
return @"v20.16.7";
|
||||
case 22:
|
||||
return @"v20.15.1";
|
||||
case 23:
|
||||
return @"v20.14.2";
|
||||
case 24:
|
||||
return @"v20.13.5";
|
||||
case 25:
|
||||
return @"v20.12.4";
|
||||
case 26:
|
||||
return @"v20.11.6";
|
||||
case 27:
|
||||
return @"v20.10.4";
|
||||
case 28:
|
||||
return @"v20.10.3";
|
||||
case 29:
|
||||
return @"v20.09.3";
|
||||
case 30:
|
||||
return @"v20.08.3";
|
||||
case 31:
|
||||
return @"v20.07.6";
|
||||
case 32:
|
||||
return @"v20.06.03";
|
||||
case 33:
|
||||
return @"v20.05.4";
|
||||
case 34:
|
||||
return @"v20.03.1";
|
||||
case 35:
|
||||
return @"v20.03.02";
|
||||
case 36:
|
||||
return @"v20.02.3";
|
||||
case 37:
|
||||
return @"v19.49.7";
|
||||
case 38:
|
||||
return @"v19.49.5";
|
||||
case 39:
|
||||
return @"v19.49.3";
|
||||
case 40:
|
||||
return @"v19.47.7";
|
||||
case 41:
|
||||
return @"v19.46.3";
|
||||
case 42:
|
||||
return @"v19.45.4";
|
||||
case 43:
|
||||
return @"v19.44.4";
|
||||
case 44:
|
||||
return @"v19.43.2";
|
||||
case 45:
|
||||
return @"v19.42.1";
|
||||
case 46:
|
||||
return @"v19.41.3";
|
||||
case 47:
|
||||
return @"v19.40.4";
|
||||
case 48:
|
||||
return @"v19.39.1";
|
||||
case 49:
|
||||
return @"v19.38.2";
|
||||
case 50:
|
||||
return @"v19.37.2";
|
||||
case 51:
|
||||
return @"v19.36.1";
|
||||
case 52:
|
||||
return @"v19.35.3";
|
||||
case 53:
|
||||
return @"v19.34.2";
|
||||
case 54:
|
||||
return @"v19.33.2";
|
||||
case 55:
|
||||
return @"v19.32.8";
|
||||
case 56:
|
||||
return @"v19.32.6";
|
||||
case 57:
|
||||
return @"v19.31.4";
|
||||
case 58:
|
||||
return @"v19.30.2";
|
||||
case 59:
|
||||
return @"v19.29.1";
|
||||
case 60:
|
||||
return @"v19.28.1";
|
||||
case 61:
|
||||
return @"v19.26.5";
|
||||
case 62:
|
||||
return @"v19.25.4";
|
||||
case 63:
|
||||
return @"v19.25.3";
|
||||
case 64:
|
||||
return @"v19.24.3";
|
||||
case 65:
|
||||
return @"v19.24.2";
|
||||
case 66:
|
||||
return @"v19.23.3";
|
||||
case 67:
|
||||
return @"v19.22.6";
|
||||
case 68:
|
||||
return @"v19.22.3";
|
||||
case 69:
|
||||
return @"v19.21.3";
|
||||
case 70:
|
||||
return @"v19.21.2";
|
||||
case 71:
|
||||
return @"v19.20.2";
|
||||
case 72:
|
||||
return @"v19.19.7";
|
||||
case 73:
|
||||
return @"v19.19.5";
|
||||
case 74:
|
||||
return @"v19.18.2";
|
||||
case 75:
|
||||
return @"v19.17.2";
|
||||
case 76:
|
||||
return @"v19.16.3";
|
||||
case 77:
|
||||
return @"v19.15.1";
|
||||
case 78:
|
||||
return @"v19.14.3";
|
||||
case 79:
|
||||
return @"v19.14.2";
|
||||
case 80:
|
||||
return @"v19.13.1";
|
||||
case 81:
|
||||
return @"v19.12.3";
|
||||
case 82:
|
||||
return @"v19.10.7";
|
||||
case 83:
|
||||
return @"v19.10.6";
|
||||
case 84:
|
||||
return @"v19.10.5";
|
||||
case 85:
|
||||
return @"v19.09.4";
|
||||
case 86:
|
||||
return @"v19.09.3";
|
||||
case 87:
|
||||
return @"v19.08.2";
|
||||
case 88:
|
||||
return @"v19.07.5";
|
||||
case 89:
|
||||
return @"v19.07.4";
|
||||
case 90:
|
||||
return @"v19.06.2";
|
||||
case 91:
|
||||
return @"v19.05.5";
|
||||
case 92:
|
||||
return @"v19.05.3";
|
||||
case 93:
|
||||
return @"v19.04.3";
|
||||
case 94:
|
||||
return @"v19.03.2";
|
||||
case 95:
|
||||
return @"v19.02.1";
|
||||
case 96:
|
||||
return @"v19.01.1";
|
||||
default:
|
||||
return @"v20.33.2";
|
||||
case 0: return @"v21.08.3";
|
||||
case 1: return @"v21.07.4";
|
||||
case 2: return @"v21.06.2";
|
||||
case 3: return @"v21.05.3";
|
||||
case 4: return @"v21.04.2";
|
||||
case 5: return @"v21.03.2";
|
||||
case 6: return @"v21.02.3";
|
||||
case 7: return @"v20.50.10";
|
||||
case 8: return @"v20.50.9";
|
||||
case 9: return @"v20.50.6";
|
||||
case 10: return @"v20.49.5";
|
||||
case 11: return @"v20.47.3";
|
||||
case 12: return @"v20.46.3";
|
||||
case 13: return @"v20.46.2";
|
||||
case 14: return @"v20.45.3";
|
||||
case 15: return @"v20.44.2";
|
||||
case 16: return @"v20.43.3";
|
||||
case 17: return @"v20.42.3";
|
||||
case 18: return @"v20.41.5";
|
||||
case 19: return @"v20.41.4";
|
||||
case 20: return @"v20.40.4";
|
||||
case 21: return @"v20.39.6";
|
||||
case 22: return @"v20.39.5";
|
||||
case 23: return @"v20.39.4";
|
||||
case 24: return @"v20.38.4";
|
||||
case 25: return @"v20.38.3";
|
||||
case 26: return @"v20.37.5";
|
||||
case 27: return @"v20.37.3";
|
||||
case 28: return @"v20.36.3";
|
||||
case 29: return @"v20.35.2";
|
||||
case 30: return @"v20.34.2";
|
||||
case 31: return @"v20.33.2";
|
||||
case 32: return @"v20.32.5";
|
||||
case 33: return @"v20.32.4";
|
||||
case 34: return @"v20.31.6";
|
||||
case 35: return @"v20.31.5";
|
||||
case 36: return @"v20.30.5";
|
||||
case 37: return @"v20.29.3";
|
||||
case 38: return @"v20.28.2";
|
||||
case 39: return @"v20.26.7";
|
||||
case 40: return @"v20.25.4";
|
||||
case 41: return @"v20.24.5";
|
||||
case 42: return @"v20.24.4";
|
||||
case 43: return @"v20.23.3";
|
||||
case 44: return @"v20.22.1";
|
||||
case 45: return @"v20.21.6";
|
||||
case 46: return @"v20.20.7";
|
||||
case 47: return @"v20.20.5";
|
||||
case 48: return @"v20.19.3";
|
||||
case 49: return @"v20.19.2";
|
||||
case 50: return @"v20.18.5";
|
||||
case 51: return @"v20.18.4";
|
||||
case 52: return @"v20.16.7";
|
||||
case 53: return @"v20.15.1";
|
||||
case 54: return @"v20.14.2";
|
||||
case 55: return @"v20.13.5";
|
||||
case 56: return @"v20.12.4";
|
||||
case 57: return @"v20.11.6";
|
||||
case 58: return @"v20.10.4";
|
||||
case 59: return @"v20.10.3";
|
||||
case 60: return @"v20.09.3";
|
||||
case 61: return @"v20.08.3";
|
||||
case 62: return @"v20.07.6";
|
||||
case 63: return @"v20.06.03";
|
||||
case 64: return @"v20.05.4";
|
||||
case 65: return @"v20.03.1";
|
||||
case 66: return @"v20.03.02";
|
||||
case 67: return @"v20.02.3";
|
||||
case 68: return @"v19.49.7";
|
||||
case 69: return @"v19.49.5";
|
||||
case 70: return @"v19.49.3";
|
||||
case 71: return @"v19.47.7";
|
||||
case 72: return @"v19.46.3";
|
||||
case 73: return @"v19.45.4";
|
||||
case 74: return @"v19.44.4";
|
||||
case 75: return @"v19.43.2";
|
||||
case 76: return @"v19.42.1";
|
||||
case 77: return @"v19.41.3";
|
||||
case 78: return @"v19.40.4";
|
||||
case 79: return @"v19.39.1";
|
||||
case 80: return @"v19.38.2";
|
||||
case 81: return @"v19.37.2";
|
||||
case 82: return @"v19.36.1";
|
||||
case 83: return @"v19.35.3";
|
||||
case 84: return @"v19.34.2";
|
||||
case 85: return @"v19.33.2";
|
||||
case 86: return @"v19.32.8";
|
||||
case 87: return @"v19.32.6";
|
||||
case 88: return @"v19.31.4";
|
||||
case 89: return @"v19.30.2";
|
||||
case 90: return @"v19.29.1";
|
||||
case 91: return @"v19.28.1";
|
||||
case 92: return @"v19.26.5";
|
||||
case 93: return @"v19.25.4";
|
||||
case 94: return @"v19.25.3";
|
||||
case 95: return @"v19.24.3";
|
||||
case 96: return @"v19.24.2";
|
||||
case 97: return @"v19.23.3";
|
||||
case 98: return @"v19.22.6";
|
||||
case 99: return @"v19.22.3";
|
||||
case 100: return @"v19.21.3";
|
||||
case 101: return @"v19.21.2";
|
||||
case 102: return @"v19.20.2 (Deprecated)";
|
||||
case 103: return @"v19.19.7 (Deprecated)";
|
||||
case 104: return @"v19.19.5 (Deprecated)";
|
||||
case 105: return @"v19.18.2 (Deprecated)";
|
||||
case 106: return @"v19.17.2 (Deprecated)";
|
||||
case 107: return @"v19.16.3 (Deprecated)";
|
||||
case 108: return @"v19.15.1 (Deprecated)";
|
||||
case 109: return @"v19.14.3 (Deprecated)";
|
||||
case 110: return @"v19.14.2 (Deprecated)";
|
||||
case 111: return @"v19.13.1 (Deprecated)";
|
||||
case 112: return @"v19.12.3 (Deprecated)";
|
||||
case 113: return @"v19.10.7 (Deprecated)";
|
||||
case 114: return @"v19.10.6 (Deprecated)";
|
||||
case 115: return @"v19.10.5 (Deprecated)";
|
||||
case 116: return @"v19.09.4 (Deprecated)";
|
||||
case 117: return @"v19.09.3 (Deprecated)";
|
||||
case 118: return @"v19.08.2 (Deprecated)";
|
||||
case 119: return @"v19.07.5 (Deprecated)";
|
||||
case 120: return @"v19.07.4 (Deprecated)";
|
||||
case 121: return @"v19.06.2 (Deprecated)";
|
||||
case 122: return @"v19.05.5 (Deprecated)";
|
||||
case 123: return @"v19.05.3 (Deprecated)";
|
||||
case 124: return @"v19.04.3 (Deprecated)";
|
||||
case 125: return @"v19.03.2 (Deprecated)";
|
||||
case 126: return @"v19.02.1 (Deprecated)";
|
||||
case 127: return @"v19.01.1 (Deprecated)";
|
||||
default: return @"v21.08.3";
|
||||
}
|
||||
}
|
||||
selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
NSArray <YTSettingsSectionItem *> *rows = @[
|
||||
SPOOFER_VERSION(@"v20.33.2", 0),
|
||||
SPOOFER_VERSION(@"v20.32.5", 1),
|
||||
SPOOFER_VERSION(@"v20.32.4", 2),
|
||||
SPOOFER_VERSION(@"v20.31.6", 3),
|
||||
SPOOFER_VERSION(@"v20.31.5", 4),
|
||||
SPOOFER_VERSION(@"v20.30.5", 5),
|
||||
SPOOFER_VERSION(@"v20.29.3", 6),
|
||||
SPOOFER_VERSION(@"v20.28.2", 7),
|
||||
SPOOFER_VERSION(@"v20.26.7", 8),
|
||||
SPOOFER_VERSION(@"v20.25.4", 9),
|
||||
SPOOFER_VERSION(@"v20.24.5", 10),
|
||||
SPOOFER_VERSION(@"v20.24.4", 11),
|
||||
SPOOFER_VERSION(@"v20.23.3", 12),
|
||||
SPOOFER_VERSION(@"v20.22.1", 13),
|
||||
SPOOFER_VERSION(@"v20.21.6", 14),
|
||||
SPOOFER_VERSION(@"v20.20.7", 15),
|
||||
SPOOFER_VERSION(@"v20.20.5", 16),
|
||||
SPOOFER_VERSION(@"v20.19.3", 17),
|
||||
SPOOFER_VERSION(@"v20.19.2", 18),
|
||||
SPOOFER_VERSION(@"v20.18.5", 19),
|
||||
SPOOFER_VERSION(@"v20.18.4", 20),
|
||||
SPOOFER_VERSION(@"v20.16.7", 21),
|
||||
SPOOFER_VERSION(@"v20.15.1", 22),
|
||||
SPOOFER_VERSION(@"v20.14.2", 23),
|
||||
SPOOFER_VERSION(@"v20.13.5", 24),
|
||||
SPOOFER_VERSION(@"v20.12.4", 25),
|
||||
SPOOFER_VERSION(@"v20.11.6", 26),
|
||||
SPOOFER_VERSION(@"v20.10.4", 27),
|
||||
SPOOFER_VERSION(@"v20.10.3", 28),
|
||||
SPOOFER_VERSION(@"v20.09.3", 29),
|
||||
SPOOFER_VERSION(@"v20.08.3", 30),
|
||||
SPOOFER_VERSION(@"v20.07.6", 31),
|
||||
SPOOFER_VERSION(@"v20.06.03", 32),
|
||||
SPOOFER_VERSION(@"v20.05.4", 33),
|
||||
SPOOFER_VERSION(@"v20.03.1", 34),
|
||||
SPOOFER_VERSION(@"v20.03.02", 35),
|
||||
SPOOFER_VERSION(@"v20.02.3", 36),
|
||||
SPOOFER_VERSION(@"v19.49.7", 37),
|
||||
SPOOFER_VERSION(@"v19.49.5", 38),
|
||||
SPOOFER_VERSION(@"v19.49.3", 39),
|
||||
SPOOFER_VERSION(@"v19.47.7", 40),
|
||||
SPOOFER_VERSION(@"v19.46.3", 41),
|
||||
SPOOFER_VERSION(@"v19.45.4", 42),
|
||||
SPOOFER_VERSION(@"v19.44.4", 43),
|
||||
SPOOFER_VERSION(@"v19.43.2", 44),
|
||||
SPOOFER_VERSION(@"v19.42.1", 45),
|
||||
SPOOFER_VERSION(@"v19.41.3", 46),
|
||||
SPOOFER_VERSION(@"v19.40.4", 47),
|
||||
SPOOFER_VERSION(@"v19.39.1", 48),
|
||||
SPOOFER_VERSION(@"v19.38.2", 49),
|
||||
SPOOFER_VERSION(@"v19.37.2", 50),
|
||||
SPOOFER_VERSION(@"v19.36.1", 51),
|
||||
SPOOFER_VERSION(@"v19.35.3", 52),
|
||||
SPOOFER_VERSION(@"v19.34.2", 53),
|
||||
SPOOFER_VERSION(@"v19.33.2", 54),
|
||||
SPOOFER_VERSION(@"v19.32.8", 55),
|
||||
SPOOFER_VERSION(@"v19.32.6", 56),
|
||||
SPOOFER_VERSION(@"v19.31.4", 57),
|
||||
SPOOFER_VERSION(@"v19.30.2", 58),
|
||||
SPOOFER_VERSION(@"v19.29.1", 59),
|
||||
SPOOFER_VERSION(@"v19.28.1", 60),
|
||||
SPOOFER_VERSION(@"v19.26.5", 61),
|
||||
SPOOFER_VERSION(@"v19.25.4", 62),
|
||||
SPOOFER_VERSION(@"v19.25.3", 63),
|
||||
SPOOFER_VERSION(@"v19.24.3", 64),
|
||||
SPOOFER_VERSION(@"v19.24.2", 65),
|
||||
SPOOFER_VERSION(@"v19.23.3", 66),
|
||||
SPOOFER_VERSION(@"v19.22.6", 67),
|
||||
SPOOFER_VERSION(@"v19.22.3", 68),
|
||||
SPOOFER_VERSION(@"v19.21.3", 69),
|
||||
SPOOFER_VERSION(@"v19.21.2", 70),
|
||||
SPOOFER_VERSION(@"v19.20.2", 71),
|
||||
SPOOFER_VERSION(@"v19.19.7", 72),
|
||||
SPOOFER_VERSION(@"v19.19.5", 73),
|
||||
SPOOFER_VERSION(@"v19.18.2", 74),
|
||||
SPOOFER_VERSION(@"v19.17.2", 75),
|
||||
SPOOFER_VERSION(@"v19.16.3", 76),
|
||||
SPOOFER_VERSION(@"v19.15.1", 77),
|
||||
SPOOFER_VERSION(@"v19.14.3", 78),
|
||||
SPOOFER_VERSION(@"v19.14.2", 79),
|
||||
SPOOFER_VERSION(@"v19.13.1", 80),
|
||||
SPOOFER_VERSION(@"v19.12.3", 81),
|
||||
SPOOFER_VERSION(@"v19.10.7", 82),
|
||||
SPOOFER_VERSION(@"v19.10.6", 83),
|
||||
SPOOFER_VERSION(@"v19.10.5", 84),
|
||||
SPOOFER_VERSION(@"v19.09.4", 85),
|
||||
SPOOFER_VERSION(@"v19.09.3", 86),
|
||||
SPOOFER_VERSION(@"v19.08.2", 87),
|
||||
SPOOFER_VERSION(@"v19.07.5", 88),
|
||||
SPOOFER_VERSION(@"v19.07.4", 89),
|
||||
SPOOFER_VERSION(@"v19.06.2", 90),
|
||||
SPOOFER_VERSION(@"v19.05.5", 91),
|
||||
SPOOFER_VERSION(@"v19.05.3", 92),
|
||||
SPOOFER_VERSION(@"v19.04.3", 93),
|
||||
SPOOFER_VERSION(@"v19.03.2", 94),
|
||||
SPOOFER_VERSION(@"v19.02.1", 95),
|
||||
SPOOFER_VERSION(@"v19.01.1", 96)
|
||||
SPOOFER_VERSION(@"v21.08.3", 0),
|
||||
SPOOFER_VERSION(@"v21.07.4", 1),
|
||||
SPOOFER_VERSION(@"v21.06.2", 2),
|
||||
SPOOFER_VERSION(@"v21.05.3", 3),
|
||||
SPOOFER_VERSION(@"v21.04.2", 4),
|
||||
SPOOFER_VERSION(@"v21.03.2", 5),
|
||||
SPOOFER_VERSION(@"v21.02.3", 6),
|
||||
SPOOFER_VERSION(@"v20.50.10", 7),
|
||||
SPOOFER_VERSION(@"v20.50.9", 8),
|
||||
SPOOFER_VERSION(@"v20.50.6", 9),
|
||||
SPOOFER_VERSION(@"v20.49.5", 10),
|
||||
SPOOFER_VERSION(@"v20.47.3", 11),
|
||||
SPOOFER_VERSION(@"v20.46.3", 12),
|
||||
SPOOFER_VERSION(@"v20.46.2", 13),
|
||||
SPOOFER_VERSION(@"v20.45.3", 14),
|
||||
SPOOFER_VERSION(@"v20.44.2", 15),
|
||||
SPOOFER_VERSION(@"v20.43.3", 16),
|
||||
SPOOFER_VERSION(@"v20.42.3", 17),
|
||||
SPOOFER_VERSION(@"v20.41.5", 18),
|
||||
SPOOFER_VERSION(@"v20.41.4", 19),
|
||||
SPOOFER_VERSION(@"v20.40.4", 20),
|
||||
SPOOFER_VERSION(@"v20.39.6", 21),
|
||||
SPOOFER_VERSION(@"v20.39.5", 22),
|
||||
SPOOFER_VERSION(@"v20.39.4", 23),
|
||||
SPOOFER_VERSION(@"v20.38.4", 24),
|
||||
SPOOFER_VERSION(@"v20.38.3", 25),
|
||||
SPOOFER_VERSION(@"v20.37.5", 26),
|
||||
SPOOFER_VERSION(@"v20.37.3", 27),
|
||||
SPOOFER_VERSION(@"v20.36.3", 28),
|
||||
SPOOFER_VERSION(@"v20.35.2", 29),
|
||||
SPOOFER_VERSION(@"v20.34.2", 30),
|
||||
SPOOFER_VERSION(@"v20.33.2", 31),
|
||||
SPOOFER_VERSION(@"v20.32.5", 32),
|
||||
SPOOFER_VERSION(@"v20.32.4", 33),
|
||||
SPOOFER_VERSION(@"v20.31.6", 34),
|
||||
SPOOFER_VERSION(@"v20.31.5", 35),
|
||||
SPOOFER_VERSION(@"v20.30.5", 36),
|
||||
SPOOFER_VERSION(@"v20.29.3", 37),
|
||||
SPOOFER_VERSION(@"v20.28.2", 38),
|
||||
SPOOFER_VERSION(@"v20.26.7", 39),
|
||||
SPOOFER_VERSION(@"v20.25.4", 40),
|
||||
SPOOFER_VERSION(@"v20.24.5", 41),
|
||||
SPOOFER_VERSION(@"v20.24.4", 42),
|
||||
SPOOFER_VERSION(@"v20.23.3", 43),
|
||||
SPOOFER_VERSION(@"v20.22.1", 44),
|
||||
SPOOFER_VERSION(@"v20.21.6", 45),
|
||||
SPOOFER_VERSION(@"v20.20.7", 46),
|
||||
SPOOFER_VERSION(@"v20.20.5", 47),
|
||||
SPOOFER_VERSION(@"v20.19.3", 48),
|
||||
SPOOFER_VERSION(@"v20.19.2", 49),
|
||||
SPOOFER_VERSION(@"v20.18.5", 50),
|
||||
SPOOFER_VERSION(@"v20.18.4", 51),
|
||||
SPOOFER_VERSION(@"v20.16.7", 52),
|
||||
SPOOFER_VERSION(@"v20.15.1", 53),
|
||||
SPOOFER_VERSION(@"v20.14.2", 54),
|
||||
SPOOFER_VERSION(@"v20.13.5", 55),
|
||||
SPOOFER_VERSION(@"v20.12.4", 56),
|
||||
SPOOFER_VERSION(@"v20.11.6", 57),
|
||||
SPOOFER_VERSION(@"v20.10.4", 58),
|
||||
SPOOFER_VERSION(@"v20.10.3", 59),
|
||||
SPOOFER_VERSION(@"v20.09.3", 60),
|
||||
SPOOFER_VERSION(@"v20.08.3", 61),
|
||||
SPOOFER_VERSION(@"v20.07.6", 62),
|
||||
SPOOFER_VERSION(@"v20.06.03", 63),
|
||||
SPOOFER_VERSION(@"v20.05.4", 64),
|
||||
SPOOFER_VERSION(@"v20.03.1", 65),
|
||||
SPOOFER_VERSION(@"v20.03.02", 66),
|
||||
SPOOFER_VERSION(@"v20.02.3", 67),
|
||||
SPOOFER_VERSION(@"v19.49.7", 68),
|
||||
SPOOFER_VERSION(@"v19.49.5", 69),
|
||||
SPOOFER_VERSION(@"v19.49.3", 70),
|
||||
SPOOFER_VERSION(@"v19.47.7", 71),
|
||||
SPOOFER_VERSION(@"v19.46.3", 72),
|
||||
SPOOFER_VERSION(@"v19.45.4", 73),
|
||||
SPOOFER_VERSION(@"v19.44.4", 74),
|
||||
SPOOFER_VERSION(@"v19.43.2", 75),
|
||||
SPOOFER_VERSION(@"v19.42.1", 76),
|
||||
SPOOFER_VERSION(@"v19.41.3", 77),
|
||||
SPOOFER_VERSION(@"v19.40.4", 78),
|
||||
SPOOFER_VERSION(@"v19.39.1", 79),
|
||||
SPOOFER_VERSION(@"v19.38.2", 80),
|
||||
SPOOFER_VERSION(@"v19.37.2", 81),
|
||||
SPOOFER_VERSION(@"v19.36.1", 82),
|
||||
SPOOFER_VERSION(@"v19.35.3", 83),
|
||||
SPOOFER_VERSION(@"v19.34.2", 84),
|
||||
SPOOFER_VERSION(@"v19.33.2", 85),
|
||||
SPOOFER_VERSION(@"v19.32.8", 86),
|
||||
SPOOFER_VERSION(@"v19.32.6", 87),
|
||||
SPOOFER_VERSION(@"v19.31.4", 88),
|
||||
SPOOFER_VERSION(@"v19.30.2", 89),
|
||||
SPOOFER_VERSION(@"v19.29.1", 90),
|
||||
SPOOFER_VERSION(@"v19.28.1", 91),
|
||||
SPOOFER_VERSION(@"v19.26.5", 92),
|
||||
SPOOFER_VERSION(@"v19.25.4", 93),
|
||||
SPOOFER_VERSION(@"v19.25.3", 94),
|
||||
SPOOFER_VERSION(@"v19.24.3", 95),
|
||||
SPOOFER_VERSION(@"v19.24.2", 96),
|
||||
SPOOFER_VERSION(@"v19.23.3", 97),
|
||||
SPOOFER_VERSION(@"v19.22.6", 98),
|
||||
SPOOFER_VERSION(@"v19.22.3", 99),
|
||||
SPOOFER_VERSION(@"v19.21.3", 100),
|
||||
SPOOFER_VERSION(@"v19.21.2", 101),
|
||||
SPOOFER_VERSION(@"v19.20.2 (Deprecated)", 102),
|
||||
SPOOFER_VERSION(@"v19.19.7 (Deprecated)", 103),
|
||||
SPOOFER_VERSION(@"v19.19.5 (Deprecated)", 104),
|
||||
SPOOFER_VERSION(@"v19.18.2 (Deprecated)", 105),
|
||||
SPOOFER_VERSION(@"v19.17.2 (Deprecated)", 106),
|
||||
SPOOFER_VERSION(@"v19.16.3 (Deprecated)", 107),
|
||||
SPOOFER_VERSION(@"v19.15.1 (Deprecated)", 108),
|
||||
SPOOFER_VERSION(@"v19.14.3 (Deprecated)", 109),
|
||||
SPOOFER_VERSION(@"v19.14.2 (Deprecated)", 110),
|
||||
SPOOFER_VERSION(@"v19.13.1 (Deprecated)", 111),
|
||||
SPOOFER_VERSION(@"v19.12.3 (Deprecated)", 112),
|
||||
SPOOFER_VERSION(@"v19.10.7 (Deprecated)", 113),
|
||||
SPOOFER_VERSION(@"v19.10.6 (Deprecated)", 114),
|
||||
SPOOFER_VERSION(@"v19.10.5 (Deprecated)", 115),
|
||||
SPOOFER_VERSION(@"v19.09.4 (Deprecated)", 116),
|
||||
SPOOFER_VERSION(@"v19.09.3 (Deprecated)", 117),
|
||||
SPOOFER_VERSION(@"v19.08.2 (Deprecated)", 118),
|
||||
SPOOFER_VERSION(@"v19.07.5 (Deprecated)", 119),
|
||||
SPOOFER_VERSION(@"v19.07.4 (Deprecated)", 120),
|
||||
SPOOFER_VERSION(@"v19.06.2 (Deprecated)", 121),
|
||||
SPOOFER_VERSION(@"v19.05.5 (Deprecated)", 122),
|
||||
SPOOFER_VERSION(@"v19.05.3 (Deprecated)", 123),
|
||||
SPOOFER_VERSION(@"v19.04.3 (Deprecated)", 124),
|
||||
SPOOFER_VERSION(@"v19.03.2 (Deprecated)", 125),
|
||||
SPOOFER_VERSION(@"v19.02.1 (Deprecated)", 126),
|
||||
SPOOFER_VERSION(@"v19.01.1 (Deprecated)", 127)
|
||||
];
|
||||
YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"VERSION_SPOOFER_SELECTOR") pickerSectionTitle:nil rows:rows selectedItemIndex:appVersionSpoofer() parentResponder:[self parentResponder]];
|
||||
[settingsViewController pushViewController:picker];
|
||||
|
|
@ -1029,37 +1004,44 @@ NSString *cacheDescription = [NSString stringWithFormat:@"%@", GetCacheSize()];
|
|||
detailTextBlock:^NSString *() {
|
||||
switch (getNotificationIconStyle()) {
|
||||
case 1:
|
||||
return @"Thin Outline (2020+)";
|
||||
return @"Bold Outline (2024+)";
|
||||
case 2:
|
||||
return @"Filled (2018+)";
|
||||
return @"Thin Outline (2020+)";
|
||||
case 3:
|
||||
return @"Filled (2018+)";
|
||||
case 4:
|
||||
return @"Classic/Inbox (2014+)";
|
||||
case 0:
|
||||
default:
|
||||
return @"Default";
|
||||
return @"Default (2025+)";
|
||||
}
|
||||
}
|
||||
selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
NSArray <YTSettingsSectionItem *> *rows = @[
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Default" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Default (2025+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"notificationIconStyle"];
|
||||
[settingsViewController reloadData];
|
||||
return YES;
|
||||
}],
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Thin Outline (2020+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Bold Outline (2024+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"notificationIconStyle"];
|
||||
[settingsViewController reloadData];
|
||||
return YES;
|
||||
}],
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Filled (2018+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Thin Outline (2020+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:2 forKey:@"notificationIconStyle"];
|
||||
[settingsViewController reloadData];
|
||||
return YES;
|
||||
}],
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Classic/Inbox (2014+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Filled (2018+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:3 forKey:@"notificationIconStyle"];
|
||||
[settingsViewController reloadData];
|
||||
return YES;
|
||||
}],
|
||||
[YTSettingsSectionItemClass checkmarkItemWithTitle:@"Classic/Inbox (2014+)" titleDescription:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
|
||||
[[NSUserDefaults standardUserDefaults] setInteger:4 forKey:@"notificationIconStyle"];
|
||||
[settingsViewController reloadData];
|
||||
return YES;
|
||||
}]
|
||||
];
|
||||
YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Notifications Tab nostalgic customization") pickerSectionTitle:nil rows:rows selectedItemIndex:getNotificationIconStyle() parentResponder:[self parentResponder]];
|
||||
|
|
|
|||
|
|
@ -6,103 +6,134 @@ typedef struct {
|
|||
} VersionMapping;
|
||||
|
||||
static VersionMapping versionMappings[] = {
|
||||
{0, @"20.33.2"},
|
||||
{1, @"20.32.5"},
|
||||
{2, @"20.32.4"},
|
||||
{3, @"20.31.6"},
|
||||
{4, @"20.31.5"},
|
||||
{5, @"20.30.5"},
|
||||
{6, @"20.29.3"},
|
||||
{7, @"20.28.2"},
|
||||
{8, @"20.26.7"},
|
||||
{9, @"20.25.4"},
|
||||
{10, @"20.24.5"},
|
||||
{11, @"20.24.4"},
|
||||
{12, @"20.23.3"},
|
||||
{13, @"20.22.1"},
|
||||
{14, @"20.21.6"},
|
||||
{15, @"20.20.7"},
|
||||
{16, @"20.20.5"},
|
||||
{17, @"20.19.3"},
|
||||
{18, @"20.19.2"},
|
||||
{19, @"20.18.5"},
|
||||
{20, @"20.18.4"},
|
||||
{21, @"20.16.7"},
|
||||
{22, @"20.15.1"},
|
||||
{23, @"20.14.2"},
|
||||
{24, @"20.13.5"},
|
||||
{25, @"20.12.4"},
|
||||
{26, @"20.11.6"},
|
||||
{27, @"20.10.4"},
|
||||
{28, @"20.10.3"},
|
||||
{29, @"20.09.3"},
|
||||
{30, @"20.08.3"},
|
||||
{31, @"20.07.6"},
|
||||
{32, @"20.06.03"},
|
||||
{33, @"20.05.4"},
|
||||
{34, @"20.03.1"},
|
||||
{35, @"20.03.02"},
|
||||
{36, @"20.02.3"},
|
||||
{37, @"19.49.7"},
|
||||
{38, @"19.49.5"},
|
||||
{39, @"19.49.3"},
|
||||
{40, @"19.47.7"},
|
||||
{41, @"19.46.3"},
|
||||
{42, @"19.45.4"},
|
||||
{43, @"19.44.4"},
|
||||
{44, @"19.43.2"},
|
||||
{45, @"19.42.1"},
|
||||
{46, @"19.41.3"},
|
||||
{47, @"19.40.4"},
|
||||
{48, @"19.39.1"},
|
||||
{49, @"19.38.2"},
|
||||
{50, @"19.37.2"},
|
||||
{51, @"19.36.1"},
|
||||
{52, @"19.35.3"},
|
||||
{53, @"19.34.2"},
|
||||
{54, @"19.33.2"},
|
||||
{55, @"19.32.8"},
|
||||
{56, @"19.32.6"},
|
||||
{57, @"19.31.4"},
|
||||
{58, @"19.30.2"},
|
||||
{59, @"19.29.1"},
|
||||
{60, @"19.28.1"},
|
||||
{61, @"19.26.5"},
|
||||
{62, @"19.25.4"},
|
||||
{63, @"19.25.3"},
|
||||
{64, @"19.24.3"},
|
||||
{65, @"19.24.2"},
|
||||
{66, @"19.23.3"},
|
||||
{67, @"19.22.6"},
|
||||
{68, @"19.22.3"},
|
||||
{69, @"19.21.3"},
|
||||
{70, @"19.21.2"},
|
||||
{71, @"19.20.2"},
|
||||
{72, @"19.19.7"},
|
||||
{73, @"19.19.5"},
|
||||
{74, @"19.18.2"},
|
||||
{75, @"19.17.2"},
|
||||
{76, @"19.16.3"},
|
||||
{77, @"19.15.1"},
|
||||
{78, @"19.14.3"},
|
||||
{79, @"19.14.2"},
|
||||
{80, @"19.13.1"},
|
||||
{81, @"19.12.3"},
|
||||
{82, @"19.10.7"},
|
||||
{83, @"19.10.6"},
|
||||
{84, @"19.10.5"},
|
||||
{85, @"19.09.4"},
|
||||
{86, @"19.09.3"},
|
||||
{87, @"19.08.2"},
|
||||
{88, @"19.07.5"},
|
||||
{89, @"19.07.4"},
|
||||
{90, @"19.06.2"},
|
||||
{91, @"19.05.5"},
|
||||
{92, @"19.05.3"},
|
||||
{93, @"19.04.3"},
|
||||
{94, @"19.03.2"},
|
||||
{95, @"19.02.1"},
|
||||
{96, @"19.01.1"}
|
||||
{0, @"21.08.3"},
|
||||
{1, @"21.07.4"},
|
||||
{2, @"21.06.2"},
|
||||
{3, @"21.05.3"},
|
||||
{4, @"21.04.2"},
|
||||
{5, @"21.03.2"},
|
||||
{6, @"21.02.3"},
|
||||
{7, @"20.50.10"},
|
||||
{8, @"20.50.9"},
|
||||
{9, @"20.50.6"},
|
||||
{10, @"20.49.5"},
|
||||
{11, @"20.47.3"},
|
||||
{12, @"20.46.3"},
|
||||
{13, @"20.46.2"},
|
||||
{14, @"20.45.3"},
|
||||
{15, @"20.44.2"},
|
||||
{16, @"20.43.3"},
|
||||
{17, @"20.42.3"},
|
||||
{18, @"20.41.5"},
|
||||
{19, @"20.41.4"},
|
||||
{20, @"20.40.4"},
|
||||
{21, @"20.39.6"},
|
||||
{22, @"20.39.5"},
|
||||
{23, @"20.39.4"},
|
||||
{24, @"20.38.4"},
|
||||
{25, @"20.38.3"},
|
||||
{26, @"20.37.5"},
|
||||
{27, @"20.37.3"},
|
||||
{28, @"20.36.3"},
|
||||
{29, @"20.35.2"},
|
||||
{30, @"20.34.2"},
|
||||
{31, @"20.33.2"},
|
||||
{32, @"20.32.5"},
|
||||
{33, @"20.32.4"},
|
||||
{34, @"20.31.6"},
|
||||
{35, @"20.31.5"},
|
||||
{36, @"20.30.5"},
|
||||
{37, @"20.29.3"},
|
||||
{38, @"20.28.2"},
|
||||
{39, @"20.26.7"},
|
||||
{40, @"20.25.4"},
|
||||
{41, @"20.24.5"},
|
||||
{42, @"20.24.4"},
|
||||
{43, @"20.23.3"},
|
||||
{44, @"20.22.1"},
|
||||
{45, @"20.21.6"},
|
||||
{46, @"20.20.7"},
|
||||
{47, @"20.20.5"},
|
||||
{48, @"20.19.3"},
|
||||
{49, @"20.19.2"},
|
||||
{50, @"20.18.5"},
|
||||
{51, @"20.18.4"},
|
||||
{52, @"20.16.7"},
|
||||
{53, @"20.15.1"},
|
||||
{54, @"20.14.2"},
|
||||
{55, @"20.13.5"},
|
||||
{56, @"20.12.4"},
|
||||
{57, @"20.11.6"},
|
||||
{58, @"20.10.4"},
|
||||
{59, @"20.10.3"},
|
||||
{60, @"20.09.3"},
|
||||
{61, @"20.08.3"},
|
||||
{62, @"20.07.6"},
|
||||
{63, @"20.06.03"},
|
||||
{64, @"20.05.4"},
|
||||
{65, @"20.03.1"},
|
||||
{66, @"20.03.02"},
|
||||
{67, @"20.02.3"},
|
||||
{68, @"19.49.7"},
|
||||
{69, @"19.49.5"},
|
||||
{70, @"19.49.3"},
|
||||
{71, @"19.47.7"},
|
||||
{72, @"19.46.3"},
|
||||
{73, @"19.45.4"},
|
||||
{74, @"19.44.4"},
|
||||
{75, @"19.43.2"},
|
||||
{76, @"19.42.1"},
|
||||
{77, @"19.41.3"},
|
||||
{78, @"19.40.4"},
|
||||
{79, @"19.39.1"},
|
||||
{80, @"19.38.2"},
|
||||
{81, @"19.37.2"},
|
||||
{82, @"19.36.1"},
|
||||
{83, @"19.35.3"},
|
||||
{84, @"19.34.2"},
|
||||
{85, @"19.33.2"},
|
||||
{86, @"19.32.8"},
|
||||
{87, @"19.32.6"},
|
||||
{88, @"19.31.4"},
|
||||
{89, @"19.30.2"},
|
||||
{90, @"19.29.1"},
|
||||
{91, @"19.28.1"},
|
||||
{92, @"19.26.5"},
|
||||
{93, @"19.25.4"},
|
||||
{94, @"19.25.3"},
|
||||
{95, @"19.24.3"},
|
||||
{96, @"19.24.2"},
|
||||
{97, @"19.23.3"},
|
||||
{98, @"19.22.6"},
|
||||
{99, @"19.22.3"},
|
||||
{100, @"19.21.3"},
|
||||
{101, @"19.21.2"},
|
||||
{102, @"19.20.2"},
|
||||
{103, @"19.19.7"},
|
||||
{104, @"19.19.5"},
|
||||
{105, @"19.18.2"},
|
||||
{106, @"19.17.2"},
|
||||
{107, @"19.16.3"},
|
||||
{108, @"19.15.1"},
|
||||
{109, @"19.14.3"},
|
||||
{110, @"19.14.2"},
|
||||
{111, @"19.13.1"},
|
||||
{112, @"19.12.3"},
|
||||
{113, @"19.10.7"},
|
||||
{114, @"19.10.6"},
|
||||
{115, @"19.10.5"},
|
||||
{116, @"19.09.4"},
|
||||
{117, @"19.09.3"},
|
||||
{118, @"19.08.2"},
|
||||
{119, @"19.07.5"},
|
||||
{120, @"19.07.4"},
|
||||
{121, @"19.06.2"},
|
||||
{122, @"19.05.5"},
|
||||
{123, @"19.05.3"},
|
||||
{124, @"19.04.3"},
|
||||
{125, @"19.03.2"},
|
||||
{126, @"19.02.1"},
|
||||
{127, @"19.01.1"}
|
||||
};
|
||||
|
||||
static int appVersionSpoofer() {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b9b0cd5784ef63922b9424c9c32b0e7f10898d49
|
||||
Subproject commit 63c099f62eb479883a4f3df212fb495af49fca05
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit f840113b3820fe5b90a8b614c1a0876c5c9cc5cb
|
||||
Subproject commit 842f93556427e208248c1f2bd94e432ce56405e5
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 634443f699950a1dbc2a4a4a1730a788c8683ae2
|
||||
Subproject commit 6cd5adc700cd79de80f7b02d0d14f1e5a7ea64aa
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0f59b38817d554ab692a0053456319847a6ab1a1
|
||||
Subproject commit f799b70cb40e32de6ba779529ad60ecd8f601cfd
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3060d66bfd86a85ab446ff9b04a1b6a2ddcb4d6f
|
||||
Subproject commit f428a716021fd3e389e0ada5f05b3f215e079e24
|
||||
1
Tweaks/YTweaks
Submodule
1
Tweaks/YTweaks
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 9a6b4df48981d69e36feb774852e46c49dd31b32
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 96c2a82845acc43f8473b6ef46c2385301fda04e
|
||||
Subproject commit 852a58dc2c53d1426557b25ac0ca53570338248b
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit eb33ec3b685a2e974272b971a559da795a1f6972
|
||||
Subproject commit 899a2fdd539ae308e5847bbb3d7212cfce30a3a6
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0548225b0abd354f55d6b2e7f436504e6ce7bca8
|
||||
Subproject commit 8d6726e569a194d3f1c1ae973b290c66301087f1
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 041f95f3bf795cbcf4c197a511821b2c574eb66c
|
||||
Subproject commit 49ece8b0fac8465ee4fd8bf0b54790106e50cb88
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 08e9ff49cfda6513d9f8823773692355902da944
|
||||
Subproject commit d56dccd4336f0902f05813f4af177360c69fe33f
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 20eab9638b4c19b6e9fa507ee3df5dbcec9303ee
|
||||
Subproject commit cbd7e9daf765ecf5d9ceb27afac15cc3eec3ecc0
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit d91d799245f503ef8816024b09234117af1a5b9a
|
||||
Subproject commit 79b9ed44958ad27fe75ee14ccc300aa99610c263
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit d7253fd7fe9bc2d5c900b156aa0d613de3b867e8
|
||||
Subproject commit 3be0cc98b300b7870abc99e1e01566e1c4ef6e07
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3e4157c2a84576d175fc73ae422927e3d2531055
|
||||
Subproject commit e0f97ef5fe47c5c3728ce2ff7a6fb02bc085e86b
|
||||
1
Tweaks/libundirect
Submodule
1
Tweaks/libundirect
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 35234fc8004e756772a12e22dee90b0b8a536143
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 8efdbbb991b27bbf49b425a98be9db45dd3c3b8c
|
||||
Subproject commit 57093a8bd5cb44211f323519a0045b883475666f
|
||||
Loading…
Reference in a new issue