mirror of
https://github.com/SoPat712/YTLitePlus.git
synced 2025-08-21 18:28:47 -04:00
722 lines
24 KiB
Plaintext
722 lines
24 KiB
Plaintext
#import "YTLitePlus.h"
|
|
|
|
NSBundle *YTLitePlusBundle() {
|
|
static NSBundle *bundle = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
NSString *tweakBundlePath = [[NSBundle mainBundle] pathForResource:@"YTLitePlus" ofType:@"bundle"];
|
|
if (tweakBundlePath)
|
|
bundle = [NSBundle bundleWithPath:tweakBundlePath];
|
|
else
|
|
bundle = [NSBundle bundleWithPath:ROOT_PATH_NS(@"/Library/Application Support/YTLitePlus.bundle")];
|
|
});
|
|
return bundle;
|
|
}
|
|
NSBundle *tweakBundle = YTLitePlusBundle();
|
|
|
|
// Keychain fix
|
|
static NSString *accessGroupID() {
|
|
NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
(__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass,
|
|
@"bundleSeedID", kSecAttrAccount,
|
|
@"", kSecAttrService,
|
|
(id)kCFBooleanTrue, kSecReturnAttributes,
|
|
nil];
|
|
CFDictionaryRef result = nil;
|
|
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
|
|
if (status == errSecItemNotFound)
|
|
status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
|
|
if (status != errSecSuccess)
|
|
return nil;
|
|
NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup];
|
|
|
|
return accessGroup;
|
|
}
|
|
|
|
//
|
|
static BOOL IsEnabled(NSString *key) {
|
|
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
|
|
}
|
|
|
|
# pragma mark - Tweaks
|
|
|
|
// Activate FLEX
|
|
%hook YTAppDelegate
|
|
- (BOOL)application:(UIApplication *)application
|
|
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
|
BOOL didFinishLaunching = %orig;
|
|
|
|
if (IsEnabled(@"flex_enabled")) {
|
|
[[FLEXManager sharedManager] showExplorer];
|
|
}
|
|
|
|
return didFinishLaunching;
|
|
}
|
|
- (void)appWillResignActive:(id)arg1 {
|
|
%orig;
|
|
if (IsEnabled(@"flex_enabled")) {
|
|
[[FLEXManager sharedManager] showExplorer];
|
|
}
|
|
}
|
|
%end
|
|
|
|
// Enable Alternate Icons
|
|
%hook UIApplication
|
|
- (BOOL)supportsAlternateIcons {
|
|
return YES;
|
|
}
|
|
%end
|
|
|
|
// Fix Google Sign in by @PoomSmart and @level3tjg (qnblackcat/uYouPlus#684)
|
|
%hook NSBundle
|
|
- (NSDictionary *)infoDictionary {
|
|
NSMutableDictionary *info = %orig.mutableCopy;
|
|
if ([self isEqual:NSBundle.mainBundle])
|
|
info[@"CFBundleIdentifier"] = @"com.google.ios.youtube";
|
|
return info;
|
|
}
|
|
%end
|
|
|
|
// Skips content warning before playing *some videos - @PoomSmart
|
|
%hook YTPlayabilityResolutionUserActionUIController
|
|
- (void)showConfirmAlert { [self confirmAlertDidPressConfirm]; }
|
|
%end
|
|
|
|
// YTMiniPlayerEnabler: https://github.com/level3tjg/YTMiniplayerEnabler/
|
|
%hook YTWatchMiniBarViewController
|
|
- (void)updateMiniBarPlayerStateFromRenderer {
|
|
if (IsEnabled(@"ytMiniPlayer_enabled")) {}
|
|
else { return %orig; }
|
|
}
|
|
%end
|
|
|
|
# pragma mark - Hide SponsorBlock Button
|
|
%hook YTRightNavigationButtons
|
|
- (void)didMoveToWindow {
|
|
%orig;
|
|
}
|
|
|
|
- (void)layoutSubviews {
|
|
%orig;
|
|
if (IsEnabled(@"hideSponsorBlockButton_enabled")) {
|
|
self.sponsorBlockButton.hidden = YES;
|
|
}
|
|
}
|
|
%end
|
|
|
|
// Hide Video Player Cast Button
|
|
%group gHideCastButton
|
|
%hook MDXPlaybackRouteButtonController
|
|
- (BOOL)isPersistentCastIconEnabled { return NO; }
|
|
- (void)updateRouteButton:(id)arg1 {} // hide Cast button in video controls overlay
|
|
%end
|
|
|
|
%hook YTSettings
|
|
- (void)setDisableMDXDeviceDiscovery:(BOOL)arg1 { %orig(YES); }
|
|
%end
|
|
%end
|
|
|
|
// Enable Share Button / Enable Save to Playlist Button
|
|
%hook YTMainAppControlsOverlayView
|
|
- (void)setShareButtonAvailable:(BOOL)arg1 { // enable Share button
|
|
if (IsEnabled(@"enableShareButton_enabled")) {
|
|
%orig(YES);
|
|
} else {
|
|
%orig(NO);
|
|
}
|
|
}
|
|
- (void)setAddToButtonAvailable:(BOOL)arg1 { // enable Save To Playlist button
|
|
if (IsEnabled(@"enableSaveToButton_enabled")) {
|
|
%orig(YES);
|
|
} else {
|
|
%orig(NO);
|
|
}
|
|
}
|
|
%end
|
|
|
|
// Disable the right panel in fullscreen mode
|
|
%hook YTColdConfig
|
|
- (BOOL)isLandscapeEngagementPanelEnabled {
|
|
return IsEnabled(@"hideRightPanel_enabled") ? NO : %orig;
|
|
}
|
|
%end
|
|
|
|
%group gHideVideoPlayerShadowOverlayButtons
|
|
%hook YTMainAppControlsOverlayView
|
|
- (void)layoutSubviews {
|
|
%orig();
|
|
MSHookIvar<YTTransportControlsButtonView *>(self, "_previousButtonView").backgroundColor = nil;
|
|
MSHookIvar<YTTransportControlsButtonView *>(self, "_nextButtonView").backgroundColor = nil;
|
|
MSHookIvar<YTTransportControlsButtonView *>(self, "_seekBackwardAccessibilityButtonView").backgroundColor = nil;
|
|
MSHookIvar<YTTransportControlsButtonView *>(self, "_seekForwardAccessibilityButtonView").backgroundColor = nil;
|
|
MSHookIvar<YTPlaybackButton *>(self, "_playPauseButton").backgroundColor = nil;
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// A/B flags
|
|
%hook YTColdConfig
|
|
- (BOOL)respectDeviceCaptionSetting { return NO; } // YouRememberCaption: https://poomsmart.github.io/repo/depictions/youremembercaption.html
|
|
- (BOOL)isLandscapeEngagementPanelSwipeRightToDismissEnabled { return YES; } // Swipe right to dismiss the right panel in fullscreen mode
|
|
- (BOOL)commercePlatformClientEnablePopupWebviewInWebviewDialogController { return NO;}
|
|
%end
|
|
|
|
// Hide Upgrade Dialog - @arichorn
|
|
%hook YTGlobalConfig
|
|
- (BOOL)shouldBlockUpgradeDialog { return YES;}
|
|
- (BOOL)shouldForceUpgrade { return NO;}
|
|
- (BOOL)shouldShowUpgrade { return NO;}
|
|
- (BOOL)shouldShowUpgradeDialog { return NO;}
|
|
%end
|
|
|
|
// YTNoTracking - @arichorn - https://github.com/arichorn/YTNoTracking/
|
|
%hook UIApplication
|
|
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
|
NSString *originalURLString = [url absoluteString];
|
|
NSString *modifiedURLString = [originalURLString stringByReplacingOccurrencesOfString:@"&si=[a-zA-Z0-9_-]+" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, originalURLString.length)];
|
|
NSURL *modifiedURL = [NSURL URLWithString:modifiedURLString];
|
|
BOOL result = %orig(application, modifiedURL, options);
|
|
return result;
|
|
}
|
|
%end
|
|
|
|
// Hide Home Tab - @bhackel
|
|
%group gHideHomeTab
|
|
%hook YTPivotBarView
|
|
- (void)setRenderer:(YTIPivotBarRenderer *)renderer {
|
|
// Iterate over each renderer item
|
|
NSUInteger indexToRemove = -1;
|
|
NSMutableArray <YTIPivotBarSupportedRenderers *> *itemsArray = renderer.itemsArray;
|
|
for (NSUInteger i = 0; i < itemsArray.count; i++) {
|
|
YTIPivotBarSupportedRenderers *item = itemsArray[i];
|
|
// Check if this is the home tab button
|
|
YTIPivotBarItemRenderer *pivotBarItemRenderer = item.pivotBarItemRenderer;
|
|
NSString *pivotIdentifier = pivotBarItemRenderer.pivotIdentifier;
|
|
if ([pivotIdentifier isEqualToString:@"FEwhat_to_watch"]) {
|
|
// Remove the home tab button
|
|
indexToRemove = i;
|
|
break;
|
|
}
|
|
}
|
|
if (indexToRemove != -1) {
|
|
[itemsArray removeObjectAtIndex:indexToRemove];
|
|
}
|
|
%orig;
|
|
}
|
|
%end
|
|
// Fix bug where contents of leftmost tab is replaced by Home tab
|
|
BOOL isTabSelected = NO;
|
|
%hook YTPivotBarViewController
|
|
- (void)viewDidAppear:(BOOL)animated {
|
|
%orig;
|
|
if (!isTabSelected) {
|
|
// Get the identifier of the selected pivot
|
|
NSString *selectedPivotIdentifier = self.selectedPivotIdentifier;
|
|
// Find any different tab to switch from by looping through the renderer items
|
|
YTIPivotBarRenderer *renderer = self.renderer;
|
|
NSArray <YTIPivotBarSupportedRenderers *> *itemsArray = renderer.itemsArray;
|
|
for (YTIPivotBarSupportedRenderers *item in itemsArray) {
|
|
YTIPivotBarItemRenderer *pivotBarItemRenderer = item.pivotBarItemRenderer;
|
|
NSString *pivotIdentifier = pivotBarItemRenderer.pivotIdentifier;
|
|
if (![pivotIdentifier isEqualToString:selectedPivotIdentifier]) {
|
|
// Switch to this tab
|
|
[self selectItemWithPivotIdentifier:pivotIdentifier];
|
|
break;
|
|
}
|
|
}
|
|
// Clear any cached controllers to delete the broken home tab
|
|
[self resetViewControllersCache];
|
|
// Switch back to the original tab
|
|
[self selectItemWithPivotIdentifier:selectedPivotIdentifier];
|
|
// Update flag to not do it again
|
|
isTabSelected = YES;
|
|
}
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// YTNoModernUI - @arichorn
|
|
%group gYTNoModernUI
|
|
%hook YTVersionUtils // YTNoModernUI Original Version
|
|
+ (NSString *)appVersion { return @"17.38.10"; }
|
|
%end
|
|
|
|
%hook YTSettingsCell // Remove v17.38.10 Version Number - @Dayanch96
|
|
- (void)setDetailText:(id)arg1 {
|
|
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
|
NSString *appVersion = infoDictionary[@"CFBundleShortVersionString"];
|
|
|
|
if ([arg1 isEqualToString:@"17.38.10"]) {
|
|
arg1 = appVersion;
|
|
} %orig(arg1);
|
|
}
|
|
%end
|
|
|
|
%hook YTInlinePlayerBarContainerView // Red Progress Bar - YTNoModernUI
|
|
- (id)quietProgressBarColor {
|
|
return [UIColor redColor];
|
|
}
|
|
%end
|
|
|
|
%hook YTSegmentableInlinePlayerBarView // Gray Buffer Progress - YTNoModernUI
|
|
- (void)setBufferedProgressBarColor:(id)arg1 {
|
|
[UIColor colorWithRed:1.00 green:1.00 blue:1.00 alpha:0.90];
|
|
}
|
|
%end
|
|
|
|
%hook YTQTMButton // No Modern/Rounded Buttons - YTNoModernUI
|
|
+ (BOOL)buttonModernizationEnabled { return NO; }
|
|
%end
|
|
|
|
%hook YTBubbleHintView // No Modern/Rounded Hints - YTNoModernUI
|
|
+ (BOOL)modernRoundedCornersEnabled { return NO; }
|
|
%end
|
|
|
|
%hook YTColdConfig
|
|
// Disable Modern Content - YTNoModernUI
|
|
- (BOOL)creatorClientConfigEnableStudioModernizedMdeThumbnailPickerForClient { return NO; }
|
|
- (BOOL)cxClientEnableModernizedActionSheet { return NO; }
|
|
- (BOOL)enableClientShortsSheetsModernization { return NO; }
|
|
- (BOOL)enableTimestampModernizationForNative { return NO; }
|
|
- (BOOL)modernizeElementsTextColor { return NO; }
|
|
- (BOOL)modernizeElementsBgColor { return NO; }
|
|
- (BOOL)modernizeCollectionLockups { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigEnableModernButtonsForNative { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigIosEnableModernTabsForNative { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigIosEnableEpUxUpdates { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigIosEnableSheetsUxUpdates { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigIosEnableSnackbarModernization { return NO; }
|
|
// Disable Rounded Content - YTNoModernUI
|
|
- (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 Darker Dark Mode - YTNoModernUI
|
|
- (BOOL)enableDarkerDarkMode { return NO; }
|
|
- (BOOL)useDarkerPaletteBgColorForElements { return NO; }
|
|
- (BOOL)useDarkerPaletteTextColorForElements { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigUseDarkerPaletteTextColorForNative { return NO; }
|
|
- (BOOL)uiSystemsClientGlobalConfigUseDarkerPaletteBgColorForNative { return NO; }
|
|
// Disable Ambient Mode - YTNoModernUI
|
|
- (BOOL)disableCinematicForLowPowerMode { return NO; }
|
|
- (BOOL)enableCinematicContainer { return NO; }
|
|
- (BOOL)enableCinematicContainerOnClient { return NO; }
|
|
- (BOOL)enableCinematicContainerOnTablet { return NO; }
|
|
- (BOOL)enableTurnOffCinematicForFrameWithBlackBars { return YES; }
|
|
- (BOOL)enableTurnOffCinematicForVideoWithBlackBars { return YES; }
|
|
- (BOOL)iosCinematicContainerClientImprovement { return NO; }
|
|
- (BOOL)iosEnableGhostCardInlineTitleCinematicContainerFix { return NO; }
|
|
- (BOOL)iosUseFineScrubberMosaicStoreForCinematic { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicPlaylists { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicPlaylistsPostMvp { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicTablets { return NO; }
|
|
- (BOOL)iosEnableFullScreenAmbientMode { return NO; }
|
|
// 16.42.3 Styled YouTube Channel Page Interface - YTNoModernUI
|
|
- (BOOL)channelsClientConfigIosChannelNavRestructuring { return NO; }
|
|
- (BOOL)channelsClientConfigIosMultiPartChannelHeader { return NO; }
|
|
// Disable Optional Content - YTNoModernUI
|
|
- (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
|
|
|
|
%group gDisableAmbientMode
|
|
%hook YTColdConfig
|
|
- (BOOL)disableCinematicForLowPowerMode { return NO; }
|
|
- (BOOL)enableCinematicContainer { return NO; }
|
|
- (BOOL)enableCinematicContainerOnClient { return NO; }
|
|
- (BOOL)enableCinematicContainerOnTablet { return NO; }
|
|
- (BOOL)enableTurnOffCinematicForFrameWithBlackBars { return YES; }
|
|
- (BOOL)enableTurnOffCinematicForVideoWithBlackBars { return YES; }
|
|
- (BOOL)iosCinematicContainerClientImprovement { return NO; }
|
|
- (BOOL)iosEnableGhostCardInlineTitleCinematicContainerFix { return NO; }
|
|
- (BOOL)iosUseFineScrubberMosaicStoreForCinematic { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicPlaylists { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicPlaylistsPostMvp { return NO; }
|
|
- (BOOL)mainAppCoreClientEnableClientCinematicTablets { return NO; }
|
|
- (BOOL)iosEnableFullScreenAmbientMode { return NO; }
|
|
%end
|
|
%end
|
|
|
|
// Hide YouTube Heatwaves in Video Player (YouTube v17.19.2-present) - @level3tjg - https://www.reddit.com/r/jailbreak/comments/v29yvk/
|
|
%group gHideHeatwaves
|
|
%hook YTInlinePlayerBarContainerView
|
|
- (BOOL)canShowHeatwave { return NO; }
|
|
%end
|
|
%end
|
|
|
|
%hook YTYouThereController
|
|
- (BOOL)shouldShowYouTherePrompt { return NO; }
|
|
%end
|
|
// Fix login for YouTube 18.13.2 and higher
|
|
%hook SSOKeychainHelper
|
|
+ (NSString *)accessGroup {
|
|
return accessGroupID();
|
|
}
|
|
+ (NSString *)sharedAccessGroup {
|
|
return accessGroupID();
|
|
}
|
|
%end
|
|
|
|
// Fix login for YouTube 17.33.2 and higher - @BandarHL
|
|
// https://gist.github.com/BandarHL/492d50de46875f9ac7a056aad084ac10
|
|
%hook SSOKeychainCore
|
|
+ (NSString *)accessGroup {
|
|
return accessGroupID();
|
|
}
|
|
|
|
+ (NSString *)sharedAccessGroup {
|
|
return accessGroupID();
|
|
}
|
|
%end
|
|
|
|
// Fix App Group Directory by move it to document directory
|
|
%hook NSFileManager
|
|
- (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier {
|
|
if (groupIdentifier != nil) {
|
|
NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
|
|
NSURL *documentsURL = [paths lastObject];
|
|
return [documentsURL URLByAppendingPathComponent:@"AppGroup"];
|
|
}
|
|
return %orig(groupIdentifier);
|
|
}
|
|
%end
|
|
|
|
// YTUnShorts - https://github.com/PoomSmart/YTUnShorts
|
|
%hook YTIElementRenderer
|
|
|
|
static NSData *cellDividerData = nil;
|
|
|
|
- (NSData *)elementData {
|
|
NSString *description = [self description];
|
|
|
|
if (IsEnabled(@"UnShorts_enabled")) {
|
|
if ([description containsString:@"cell_divider"]) {
|
|
if (!cellDividerData) cellDividerData = %orig;
|
|
return cellDividerData;
|
|
}
|
|
|
|
BOOL hasShorts = ([description containsString:@"shorts_shelf.eml"] ||
|
|
[description containsString:@"shorts_video_cell.eml"] ||
|
|
[description containsString:@"6Shorts"]) &&
|
|
![description containsString:@"history*"];
|
|
BOOL hasShortsInHistory = [description containsString:@"compact_video.eml"] &&
|
|
[description containsString:@"youtube_shorts_"];
|
|
|
|
if (hasShorts || hasShortsInHistory) return cellDividerData;
|
|
}
|
|
|
|
// Hide Community Posts - @michael-winay & @arichorn
|
|
if (IsEnabled(@"hideCommunityPosts_enabled")) {
|
|
if ([description containsString:@"post_base_wrapper.eml"]) {
|
|
return nil;
|
|
}
|
|
}
|
|
return %orig;
|
|
}
|
|
%end
|
|
|
|
// YTNoSuggestedVideo - https://github.com/bhackel/YTNoSuggestedVideo
|
|
%hook YTMainAppVideoPlayerOverlayViewController
|
|
- (bool)shouldShowAutonavEndscreen {
|
|
if (IsEnabled(@"noSuggestedVideo_enabled")) {
|
|
return false;
|
|
}
|
|
return %orig;
|
|
}
|
|
%end
|
|
|
|
// Seek anywhere gesture - @bhackel
|
|
%hook YTColdConfig
|
|
- (BOOL)speedMasterArm2FastForwardWithoutSeekBySliding {
|
|
return IsEnabled(@"seekAnywhere_enabled") ? NO : %orig;
|
|
}
|
|
%end
|
|
|
|
// BigYTMiniPlayer: https://github.com/Galactic-Dev/BigYTMiniPlayer
|
|
%group Main
|
|
%hook YTWatchMiniBarView
|
|
- (void)setWatchMiniPlayerLayout:(int)arg1 {
|
|
%orig(1);
|
|
}
|
|
- (int)watchMiniPlayerLayout {
|
|
return 1;
|
|
}
|
|
- (void)layoutSubviews {
|
|
%orig;
|
|
self.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - self.frame.size.width), self.frame.origin.y, self.frame.size.width, self.frame.size.height);
|
|
}
|
|
%end
|
|
|
|
%hook YTMainAppVideoPlayerOverlayView
|
|
- (BOOL)isUserInteractionEnabled {
|
|
if([[self _viewControllerForAncestor].parentViewController.parentViewController isKindOfClass:%c(YTWatchMiniBarViewController)]) {
|
|
return NO;
|
|
}
|
|
return %orig;
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// YTSpeed - https://github.com/Lyvendia/YTSpeed
|
|
%group gYTSpeed
|
|
%hook YTVarispeedSwitchController
|
|
- (id)init {
|
|
id result = %orig;
|
|
|
|
const int size = 17;
|
|
float speeds[] = {0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 5.0};
|
|
id varispeedSwitchControllerOptions[size];
|
|
|
|
for (int i = 0; i < size; ++i) {
|
|
id title = [NSString stringWithFormat:@"%.2fx", speeds[i]];
|
|
varispeedSwitchControllerOptions[i] = [[%c(YTVarispeedSwitchControllerOption) alloc] initWithTitle:title rate:speeds[i]];
|
|
}
|
|
|
|
NSUInteger count = sizeof(varispeedSwitchControllerOptions) / sizeof(id);
|
|
NSArray *varispeedArray = [NSArray arrayWithObjects:varispeedSwitchControllerOptions count:count];
|
|
MSHookIvar<NSArray *>(self, "_options") = varispeedArray;
|
|
|
|
return result;
|
|
}
|
|
%end
|
|
|
|
%hook MLHAMQueuePlayer
|
|
- (void)setRate:(float)rate {
|
|
MSHookIvar<float>(self, "_rate") = rate;
|
|
MSHookIvar<float>(self, "_preferredRate") = rate;
|
|
|
|
id player = MSHookIvar<HAMPlayerInternal *>(self, "_player");
|
|
[player setRate: rate];
|
|
|
|
id stickySettings = MSHookIvar<MLPlayerStickySettings *>(self, "_stickySettings");
|
|
[stickySettings setRate: rate];
|
|
|
|
[self.playerEventCenter broadcastRateChange: rate];
|
|
|
|
YTSingleVideoController *singleVideoController = self.delegate;
|
|
[singleVideoController playerRateDidChange: rate];
|
|
}
|
|
%end
|
|
|
|
%hook YTPlayerViewController
|
|
%property (nonatomic, assign) float playbackRate;
|
|
- (void)singleVideo:(id)video playbackRateDidChange:(float)rate {
|
|
%orig;
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// YTStockVolumeHUD - https://github.com/lilacvibes/YTStockVolumeHUD
|
|
%group gStockVolumeHUD
|
|
%hook YTVolumeBarView
|
|
- (void)volumeChanged:(id)arg1 {
|
|
%orig(nil);
|
|
}
|
|
%end
|
|
|
|
%hook UIApplication
|
|
- (void)setSystemVolumeHUDEnabled:(BOOL)arg1 forAudioCategory:(id)arg2 {
|
|
%orig(true, arg2);
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// App Settings Overlay Options
|
|
%group gDisableAccountSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateAccountSwitcherSectionWithEntry:(id)arg1 {} // Account
|
|
%end
|
|
%end
|
|
|
|
%group gDisableAutoplaySection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateAutoplaySectionWithEntry:(id)arg1 {} // Autoplay
|
|
%end
|
|
%end
|
|
|
|
%group gDisableTryNewFeaturesSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updatePremiumEarlyAccessSectionWithEntry:(id)arg1 {} // Try new features
|
|
%end
|
|
%end
|
|
|
|
%group gDisableVideoQualityPreferencesSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateVideoQualitySectionWithEntry:(id)arg1 {} // Video quality preferences
|
|
%end
|
|
%end
|
|
|
|
%group gDisableNotificationsSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateNotificationSectionWithEntry:(id)arg1 {} // Notifications
|
|
%end
|
|
%end
|
|
|
|
%group gDisableManageAllHistorySection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateHistorySectionWithEntry:(id)arg1 {} // Manage all history
|
|
%end
|
|
%end
|
|
|
|
%group gDisableYourDataInYouTubeSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateYourDataSectionWithEntry:(id)arg1 {} // Your data in YouTube
|
|
%end
|
|
%end
|
|
|
|
%group gDisablePrivacySection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updatePrivacySectionWithEntry:(id)arg1 {} // Privacy
|
|
%end
|
|
%end
|
|
|
|
%group gDisableLiveChatSection
|
|
%hook YTSettingsSectionItemManager
|
|
- (void)updateLiveChatSectionWithEntry:(id)arg1 {} // Live chat
|
|
%end
|
|
%end
|
|
|
|
// Miscellaneous
|
|
%group giPadLayout // https://github.com/LillieH001/YouTube-Reborn
|
|
%hook UIDevice
|
|
- (long long)userInterfaceIdiom {
|
|
return YES;
|
|
}
|
|
%end
|
|
%hook UIStatusBarStyleAttributes
|
|
- (long long)idiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%hook UIKBTree
|
|
- (long long)nativeIdiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%hook UIKBRenderer
|
|
- (long long)assetIdiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%end
|
|
|
|
%group giPhoneLayout // https://github.com/LillieH001/YouTube-Reborn
|
|
%hook UIDevice
|
|
- (long long)userInterfaceIdiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%hook UIStatusBarStyleAttributes
|
|
- (long long)idiom {
|
|
return YES;
|
|
}
|
|
%end
|
|
%hook UIKBTree
|
|
- (long long)nativeIdiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%hook UIKBRenderer
|
|
- (long long)assetIdiom {
|
|
return NO;
|
|
}
|
|
%end
|
|
%end
|
|
|
|
// YT startup animation
|
|
%hook YTColdConfig
|
|
- (BOOL)mainAppCoreClientIosEnableStartupAnimation {
|
|
return IsEnabled(@"ytStartupAnimation_enabled") ? YES : NO;
|
|
}
|
|
%end
|
|
|
|
# pragma mark - ctor
|
|
%ctor {
|
|
%init;
|
|
if (IsEnabled(@"hideCastButton_enabled")) {
|
|
%init(gHideCastButton);
|
|
}
|
|
if (IsEnabled(@"iPadLayout_enabled")) {
|
|
%init(giPadLayout);
|
|
}
|
|
if (IsEnabled(@"iPhoneLayout_enabled")) {
|
|
%init(giPhoneLayout);
|
|
}
|
|
if (IsEnabled(@"bigYTMiniPlayer_enabled") && (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad)) {
|
|
%init(Main);
|
|
}
|
|
if (IsEnabled(@"hideVideoPlayerShadowOverlayButtons_enabled")) {
|
|
%init(gHideVideoPlayerShadowOverlayButtons);
|
|
}
|
|
if (IsEnabled(@"hideHeatwaves_enabled")) {
|
|
%init(gHideHeatwaves);
|
|
}
|
|
if (IsEnabled(@"ytNoModernUI_enabled")) {
|
|
%init(gYTNoModernUI);
|
|
}
|
|
if (IsEnabled(@"disableAmbientMode_enabled")) {
|
|
%init(gDisableAmbientMode);
|
|
}
|
|
if (IsEnabled(@"ytSpeed_enabled")) {
|
|
%init(gYTSpeed);
|
|
}
|
|
if (IsEnabled(@"stockVolumeHUD_enabled")) {
|
|
%init(gStockVolumeHUD);
|
|
}
|
|
if (IsEnabled(@"disableAccountSection_enabled")) {
|
|
%init(gDisableAccountSection);
|
|
}
|
|
if (IsEnabled(@"disableAutoplaySection_enabled")) {
|
|
%init(gDisableAutoplaySection);
|
|
}
|
|
if (IsEnabled(@"disableTryNewFeaturesSection_enabled")) {
|
|
%init(gDisableTryNewFeaturesSection);
|
|
}
|
|
if (IsEnabled(@"disableVideoQualityPreferencesSection_enabled")) {
|
|
%init(gDisableVideoQualityPreferencesSection);
|
|
}
|
|
if (IsEnabled(@"disableNotificationsSection_enabled")) {
|
|
%init(gDisableNotificationsSection);
|
|
}
|
|
if (IsEnabled(@"disableManageAllHistorySection_enabled")) {
|
|
%init(gDisableManageAllHistorySection);
|
|
}
|
|
if (IsEnabled(@"disableYourDataInYouTubeSection_enabled")) {
|
|
%init(gDisableYourDataInYouTubeSection);
|
|
}
|
|
if (IsEnabled(@"disablePrivacySection_enabled")) {
|
|
%init(gDisablePrivacySection);
|
|
}
|
|
if (IsEnabled(@"disableLiveChatSection_enabled")) {
|
|
%init(gDisableLiveChatSection);
|
|
}
|
|
if (IsEnabled(@"hideHomeTab_enabled")) {
|
|
%init(gHideHomeTab);
|
|
}
|
|
|
|
|
|
// Change the default value of some options
|
|
NSArray *allKeys = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys];
|
|
if (![allKeys containsObject:@"RYD-ENABLED"]) {
|
|
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"RYD-ENABLED"];
|
|
}
|
|
if (![allKeys containsObject:@"YouPiPEnabled"]) {
|
|
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"YouPiPEnabled"];
|
|
}
|
|
}
|