Merge branch 'arichornlover:main' into main

This commit is contained in:
mattsblack 2024-07-13 14:33:51 -04:00 committed by GitHub
commit cc9e3300a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 180 additions and 160 deletions

View file

@ -1,3 +1,9 @@
# How to fix the "remote: Repository not found." Error (buildapp.yml) ⚠️
In order to simply fix this problem go to **Actions** and then go to **Update Submodules** and right as soon as you get there then trigger the **Run Workflow**
Also please know that I can't trigger actions when my account is flagged so I can't update them on uYouEnhanced myself.
# uYouEnhanced
<p align="center"> <p align="center">
<a href="https://user-images.githubusercontent.com/78001398/271790092-006e81cc-715a-4fbc-aff6-15832e2da8c4.png"> <a href="https://user-images.githubusercontent.com/78001398/271790092-006e81cc-715a-4fbc-aff6-15832e2da8c4.png">
<img src="https://user-images.githubusercontent.com/78001398/271790092-006e81cc-715a-4fbc-aff6-15832e2da8c4.png" alt="UYOUPLUS_LOGO" width="200" height="200"> <img src="https://user-images.githubusercontent.com/78001398/271790092-006e81cc-715a-4fbc-aff6-15832e2da8c4.png" alt="UYOUPLUS_LOGO" width="200" height="200">

View file

@ -1,53 +1,56 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <LocalAuthentication/LocalAuthentication.h>
#import <CaptainHook/CaptainHook.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <objc/runtime.h> #import <CaptainHook/CaptainHook.h>
#import <dlfcn.h> #import <dlfcn.h>
#import <sys/utsname.h> #import <LocalAuthentication/LocalAuthentication.h>
#import <substrate.h> #import <objc/runtime.h>
#import <rootless.h> #import <rootless.h>
#import <substrate.h>
#import "uYouPlusThemes.h" // Hide "Buy Super Thanks" banner (_ASDisplayView) #import <sys/utsname.h>
#import <YouTubeHeader/YTAppDelegate.h> // Activate FLEX
#import <YouTubeHeader/YTIMenuConditionalServiceItemRenderer.h>
#import <YouTubeHeader/YTIPlayerBarDecorationModel.h>
#import <YouTubeHeader/YTPlayerBarRectangleDecorationView.h>
#import <YouTubeHeader/YTVideoQualitySwitchOriginalController.h>
#import <YouTubeHeader/YTIGuideResponse.h>
#import <YouTubeHeader/YTIGuideResponseSupportedRenderers.h>
#import <YouTubeHeader/YTIPivotBarSupportedRenderers.h>
#import <YouTubeHeader/YTIPivotBarItemRenderer.h>
#import <YouTubeHeader/YTIBrowseRequest.h>
#import <YouTubeHeader/YTIButtonRenderer.h>
#import <YouTubeHeader/YTIElementRenderer.h>
#import <YouTubeHeader/YTISectionListRenderer.h>
#import <YouTubeHeader/YTWatchNextResultsViewController.h>
#import <YouTubeHeader/YTPlayerOverlay.h>
#import <YouTubeHeader/YTPlayerOverlayProvider.h>
#import <YouTubeHeader/YTMainAppVideoPlayerOverlayView.h>
#import <YouTubeHeader/YTMainAppVideoPlayerOverlayViewController.h>
#import <YouTubeHeader/YTReelWatchPlaybackOverlayView.h>
#import <YouTubeHeader/YTInlinePlayerBarContainerView.h>
#import <YouTubeHeader/YTInnerTubeCollectionViewController.h>
#import <YouTubeHeader/YTPivotBarItemView.h>
#import <YouTubeHeader/YTCollectionViewCell.h>
#import <YouTubeHeader/YTIFormattedString.h>
#import <YouTubeHeader/GPBMessage.h>
#import <YouTubeHeader/YTIStringRun.h>
#import <YouTubeHeader/YTWatchViewController.h>
#import <YouTubeHeader/YTIPivotBarRenderer.h>
#import <YouTubeHeader/YTPlayerOverlayManager.h> // Fixes uYou crash when trying to play video (#1422)
// Hide buttons under the video player by @PoomSmart
#import <YouTubeHeader/ASCollectionElement.h> #import <YouTubeHeader/ASCollectionElement.h>
#import <YouTubeHeader/ASCollectionView.h> #import <YouTubeHeader/ASCollectionView.h>
#import <YouTubeHeader/ELMNodeController.h>
// YouTube-X
#import <YouTubeHeader/YTReelModel.h>
#import <YouTubeHeader/YTVideoWithContextNode.h>
#import <YouTubeHeader/ELMCellNode.h> #import <YouTubeHeader/ELMCellNode.h>
#import <YouTubeHeader/ELMNodeController.h>
#import <YouTubeHeader/GPBMessage.h>
#import <YouTubeHeader/MLPlayerStickySettings.h>
#import <YouTubeHeader/YTAppDelegate.h>
#import <YouTubeHeader/YTCollectionViewCell.h>
#import <YouTubeHeader/YTIBrowseRequest.h>
#import <YouTubeHeader/YTIButtonRenderer.h>
#import <YouTubeHeader/YTICompactLinkRenderer.h>
#import <YouTubeHeader/YTICompactListItemRenderer.h>
#import <YouTubeHeader/YTICompactListItemThumbnailSupportedRenderers.h>
#import <YouTubeHeader/YTIIconThumbnailRenderer.h>
#import <YouTubeHeader/YTIElementRenderer.h>
#import <YouTubeHeader/YTIFormattedString.h>
#import <YouTubeHeader/YTIGuideResponse.h>
#import <YouTubeHeader/YTIGuideResponseSupportedRenderers.h>
#import <YouTubeHeader/YTIMenuConditionalServiceItemRenderer.h>
#import <YouTubeHeader/YTInnerTubeCollectionViewController.h>
#import <YouTubeHeader/YTInlinePlayerBarContainerView.h>
#import <YouTubeHeader/YTIPivotBarItemRenderer.h>
#import <YouTubeHeader/YTIPivotBarRenderer.h>
#import <YouTubeHeader/YTIPivotBarSupportedRenderers.h>
#import <YouTubeHeader/YTIPlayerBarDecorationModel.h>
#import <YouTubeHeader/YTISectionListRenderer.h>
#import <YouTubeHeader/YTIStringRun.h>
#import <YouTubeHeader/YTMainAppVideoPlayerOverlayViewController.h>
#import <YouTubeHeader/YTMainAppVideoPlayerOverlayView.h>
#import <YouTubeHeader/YTPlayerBarController.h>
#import <YouTubeHeader/YTPlayerBarRectangleDecorationView.h>
#import <YouTubeHeader/YTPlayerOverlay.h>
#import <YouTubeHeader/YTPlayerOverlayProvider.h>
#import <YouTubeHeader/YTPlayerOverlayManager.h>
#import <YouTubeHeader/YTReelModel.h>
#import <YouTubeHeader/YTReelWatchPlaybackOverlayView.h>
#import <YouTubeHeader/YTResponder.h>
#import <YouTubeHeader/YTVideoQualitySwitchOriginalController.h>
#import <YouTubeHeader/YTVideoWithContextNode.h>
#import <YouTubeHeader/YTWatchNextResultsViewController.h>
#import <YouTubeHeader/YTWatchPlayerViewLayoutSource.h>
#import <YouTubeHeader/YTWatchPullToFullController.h>
#import <YouTubeHeader/YTWatchViewController.h>
#import "uYouPlusThemes.h" // uYouPlus Themes
#define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil] #define LOC(x) [tweakBundle localizedStringForKey:x value:nil table:nil]
#define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k] #define IS_ENABLED(k) [[NSUserDefaults standardUserDefaults] boolForKey:k]
@ -58,12 +61,8 @@
#define LOWCONTRASTMODE_CUTOFF_VERSION @"17.38.10" // LowContrastMode (v17.33.2-17.38.10) #define LOWCONTRASTMODE_CUTOFF_VERSION @"17.38.10" // LowContrastMode (v17.33.2-17.38.10)
// Always show remaining time in video player - @bhackel // Always show remaining time in video player - @bhackel
@interface YTPlayerBarController : NSObject // Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTPlayerBarController.h
@property(nonatomic, strong) YTInlinePlayerBarContainerView *playerBar; // Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTInlinePlayerBarContainerView.h
@end
@interface YTInlinePlayerBarContainerView (uYouEnhanced)
@property(nonatomic, assign) BOOL shouldDisplayTimeRemaining;
@end
// IAmYouTube // IAmYouTube
@interface SSOConfiguration : NSObject @interface SSOConfiguration : NSObject
@ -85,12 +84,10 @@
// Hide Home Tab - @bhackel // Hide Home Tab - @bhackel
@interface YTPivotBarItemViewAccessibilityControl : UIControl @interface YTPivotBarItemViewAccessibilityControl : UIControl
@end @end
@interface YTPivotBarItemView (uYouEnhanced) // YTPivotBarItemView Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTPivotBarItemView.h
@property (nonatomic, strong) YTPivotBarItemViewAccessibilityControl *hitTarget;
@end
// YTTapToSeek - https://github.com/bhackel/YTTapToSeek // YTTapToSeek - https://github.com/bhackel/YTTapToSeek
// Header has been moved to https://github.com/arichornlover/YouTubeHeader/blob/main/YTMainAppVideoPlayerOverlayViewController.h // YTMainAppVideoPlayerOverlayViewController Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTMainAppVideoPlayerOverlayViewController.h
// Enable Premium logo - @bhackel // Enable Premium logo - @bhackel
@interface YTITopbarLogoRenderer : NSObject @interface YTITopbarLogoRenderer : NSObject
@ -98,36 +95,12 @@
@end @end
// Hide Premium Promo in You tab - @bhackel // Hide Premium Promo in You tab - @bhackel
@interface YTIIconThumbnailRenderer : GPBMessage // YTIIconThumbnailRenderer Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTIIconThumbnailRenderer.h
@property (nonatomic, strong) YTIIcon *icon; // YTICompactListItemThumbnailSupportedRenderers Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTICompactListItemThumbnailSupportedRenderers.h
- (BOOL)hasIcon; // YTICompactListItemRenderer Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTICompactListItemRenderer.h
@end // YTIIcon Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTIIcon.h
@interface YTICompactListItemThumbnailSupportedRenderers : GPBMessage // YTICompactLinkRenderer Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTICompactLinkRenderer.h
@property (nonatomic, strong) YTIIconThumbnailRenderer *iconThumbnailRenderer; // YTIItemSectionSupportedRenderers Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/YTIItemSectionSupportedRenderers.h
- (BOOL)hasIconThumbnailRenderer;
@end
@interface YTICompactListItemRenderer : GPBMessage
@property (nonatomic, strong) YTICompactListItemThumbnailSupportedRenderers *thumbnail;
@property (nonatomic, strong) YTIFormattedString *title;
- (BOOL)hasThumbnail;
- (BOOL)hasTitle;
@end
@interface YTIIcon (uYouEnhanced)
- (BOOL)hasIconType;
@end
@interface YTICompactLinkRenderer : GPBMessage
@property (nonatomic, strong) YTIIcon *icon;
@property (nonatomic, strong) YTIFormattedString *title;
@property (nonatomic, strong) YTICompactListItemThumbnailSupportedRenderers *thumbnail;
- (BOOL)hasIcon;
- (BOOL)hasThumbnail;
@end
@interface YTIItemSectionSupportedRenderers (uYouEnhanced)
@property(readonly, nonatomic) YTICompactLinkRenderer *compactLinkRenderer;
@property(readonly, nonatomic) YTICompactListItemRenderer *compactListItemRenderer;
- (BOOL)hasCompactLinkRenderer;
- (BOOL)hasCompactListItemRenderer;
@end
@interface YTAppCollectionViewController : YTInnerTubeCollectionViewController @interface YTAppCollectionViewController : YTInnerTubeCollectionViewController
- (void)uYouEnhancedFakePremiumModel:(YTISectionListRenderer *)model; - (void)uYouEnhancedFakePremiumModel:(YTISectionListRenderer *)model;
@end @end
@ -136,13 +109,10 @@
@end @end
// Disable Pull to Full for landscape videos - @bhackel // Disable Pull to Full for landscape videos - @bhackel
@interface YTWatchPullToFullController : NSObject // YTWatchPullToFullController Header has been moved to https://github.com/PoomSmart/YouTubeHeader/blob/main/YTWatchPullToFullController.h
@property(nonatomic, strong) YTWatchViewController *playerViewSource;
@end
@interface YTWatchViewController (uYouEnhanced)
@property(nonatomic, strong) YTWatchPullToFullController *pullToFullController;
- (NSUInteger) allowedFullScreenOrientations;
// Fullscreen to the Right (uYouEnhanced Version) - @arichornlover // Fullscreen to the Right (uYouEnhanced Version) - @arichornlover
@interface YTWatchViewController (uYouEnhanced)
- (UIInterfaceOrientationMask) supportedInterfaceOrientations; - (UIInterfaceOrientationMask) supportedInterfaceOrientations;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation; - (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;
- (void)forceRightFullscreenOrientation; - (void)forceRightFullscreenOrientation;
@ -195,17 +165,16 @@
// Buttons // Buttons
@interface YTRightNavigationButtons : UIView @interface YTRightNavigationButtons : UIView
- (id)_viewControllerForAncestor; - (id)_viewControllerForAncestor;
@property(readonly, nonatomic) YTQTMButton *searchButton; @property (readonly, nonatomic) NSArray *dynamicButtons;
@property(readonly, nonatomic) YTQTMButton *notificationButton; @property (readonly, nonatomic) NSArray *visibleButtons;
@property(strong, nonatomic) YTQTMButton *sponsorBlockButton; @property (readonly, nonatomic) NSArray *buttons;
@property(strong, nonatomic) YTQTMButton *uYouPlusButton; @property (readonly, nonatomic) YTQTMButton *searchButton;
@property (readonly, nonatomic) YTQTMButton *notificationButton;
@property (strong, nonatomic) YTQTMButton *sponsorBlockButton;
@property (strong, nonatomic) YTQTMButton *settingsButton;
- (void)setDynamicButtons:(NSArray *)buttons;
- (void)setLeadingPadding:(CGFloat)arg1; - (void)setLeadingPadding:(CGFloat)arg1;
- (void)uYouPlusRootOptionsAction; - (void)settingsAction;
@end
@interface YTISlimMetadataButtonSupportedRenderers : NSObject
- (id)slimButton_buttonRenderer;
- (id)slimMetadataButtonRenderer;
@end @end
// YTSpeed // YTSpeed
@ -220,9 +189,7 @@
- (void)internalSetRate; - (void)internalSetRate;
@end @end
@interface MLPlayerStickySettings (uYouPlus) // MLPlayerStickySettings Header has been moved to https://github.com/arichornloverALT/YouTubeHeader/blob/main/MLPlayerStickySettings.h
- (void)setRate:(float)rate;
@end
@interface MLPlayerEventCenter : NSObject @interface MLPlayerEventCenter : NSObject
- (void)broadcastRateChange:(float)rate; - (void)broadcastRateChange:(float)rate;

View file

@ -233,9 +233,10 @@ static __strong NSData *cellDividerData;
%end %end
%end %end
%group gCenterYouTubeLogo // Center YouTube Logo - @arichornlover
%group gCenterYouTubeLogo // BROKEN
%hook YTNavigationBarTitleView %hook YTNavigationBarTitleView
- (void)setShouldCenterNavBarTitleView:(BOOL)center { - (void)setShouldCenterNavBarTitleView:(BOOL)center { // Doesn't do anything?
%orig(YES); %orig(YES);
} }
- (BOOL)shouldCenterNavBarTitleView { - (BOOL)shouldCenterNavBarTitleView {
@ -301,7 +302,7 @@ static __strong NSData *cellDividerData;
- (BOOL)enableModularPlayerBarController { return NO; } // fixes some of the iSponorBlock problems - (BOOL)enableModularPlayerBarController { return NO; } // fixes some of the iSponorBlock problems
- (BOOL)mainAppCoreClientEnableCairoSettings { return IS_ENABLED(@"newSettingsUI_enabled"); } // New grouped settings UI - (BOOL)mainAppCoreClientEnableCairoSettings { return IS_ENABLED(@"newSettingsUI_enabled"); } // New grouped settings UI
- (BOOL)enableIosFloatingMiniplayer { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer - (BOOL)enableIosFloatingMiniplayer { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer
- (BOOL)enableIosFloatingMiniplayerSwipeUpToExpand { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer - Fix Swipe Up Animation - (BOOL)enableIosFloatingMiniplayerSwipeUpToExpand { return IS_ENABLED(@"floatingMiniplayer_enabled"); } // Floating Miniplayer
- (BOOL)enableIosFloatingMiniplayerRepositioning { return IS_ENABLED(@"floatingMiniplayer2_enabled"); } // Floating Miniplayer (Repositioning Support, Removes Swiping Up Gesture) - (BOOL)enableIosFloatingMiniplayerRepositioning { return IS_ENABLED(@"floatingMiniplayer2_enabled"); } // Floating Miniplayer (Repositioning Support, Removes Swiping Up Gesture)
%end %end
@ -578,7 +579,7 @@ static __strong NSData *cellDividerData;
} }
%end %end
// Classic Video Player - 17.33.2+ (Restores the functionality from the YT v16.xx.x Video Player) - @arichornlover // Classic Video Player (Restores the v16.xx.x Video Player Functionality) - @arichornlover
// To-do: disabling "Precise Video Scrubbing" https://9to5google.com/2022/06/29/youtube-precise-video-scrubbing/ // To-do: disabling "Precise Video Scrubbing" https://9to5google.com/2022/06/29/youtube-precise-video-scrubbing/
%group gClassicVideoPlayer %group gClassicVideoPlayer
%hook YTColdConfig %hook YTColdConfig
@ -766,7 +767,7 @@ static int contrastMode() {
%end %end
// YTTapToSeek - https://github.com/bhackel/YTTapToSeek // YTTapToSeek - https://github.com/bhackel/YTTapToSeek
%group YTTTS_Tweak %group gYTTapToSeek
%hook YTInlinePlayerBarContainerView %hook YTInlinePlayerBarContainerView
- (void)didPressScrubber:(id)arg1 { - (void)didPressScrubber:(id)arg1 {
%orig; %orig;
@ -851,6 +852,32 @@ static int contrastMode() {
%end %end
%end %end
// Fullscreen to the Right (iPhone-exclusive) - @arichornlover
// NOTE: Please turn off the “Portrait Fullscreen” Option while the code below is active
%group gFullscreenToTheRight
%hook YTWatchViewController
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
if ([self isFullscreen] && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationLandscapeRight;
}
return %orig;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
if ([self isFullscreen] && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskLandscape;
}
return %orig;
}
%new
- (void)forceRightFullscreenOrientation { // custom void
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
}
%end
%end
// Disable Double tap to skip chapter - @bhackel // Disable Double tap to skip chapter - @bhackel
%hook YTDoubleTapToSeekController %hook YTDoubleTapToSeekController
- (void)didTwoFingerDoubleTap:(id)arg1 { - (void)didTwoFingerDoubleTap:(id)arg1 {
@ -968,7 +995,7 @@ static int contrastMode() {
%hook YTWatchPullToFullController %hook YTWatchPullToFullController
- (BOOL)shouldRecognizeOverscrollEventsFromWatchOverscrollController:(id)arg1 { - (BOOL)shouldRecognizeOverscrollEventsFromWatchOverscrollController:(id)arg1 {
// Get the current player orientation // Get the current player orientation
YTWatchViewController *watchViewController = self.playerViewSource; YTWatchViewController *watchViewController = (YTWatchViewController *)self.playerViewSource;
NSUInteger allowedFullScreenOrientations = [watchViewController allowedFullScreenOrientations]; NSUInteger allowedFullScreenOrientations = [watchViewController allowedFullScreenOrientations];
// Check if the current player orientation is portrait // Check if the current player orientation is portrait
if (allowedFullScreenOrientations == UIInterfaceOrientationMaskAllButUpsideDown if (allowedFullScreenOrientations == UIInterfaceOrientationMaskAllButUpsideDown
@ -1334,7 +1361,7 @@ static int contrastMode() {
static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *identifiers) { static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *identifiers) {
for (id child in [nodeController children]) { for (id child in [nodeController children]) {
if ([child isKindOfClass:%c(ELMNodeController)]) { if ([child isKindOfClass:%c(ELMNodeController)]) {
NSArray <ELMComponent *> *elmChildren = [(ELMNodeController *)child children]; NSArray <ELMComponent *> *elmChildren = [(ELMNodeController * _Nullable)child children];
for (ELMComponent *elmChild in elmChildren) { for (ELMComponent *elmChild in elmChildren) {
for (NSString *identifier in identifiers) { for (NSString *identifier in identifiers) {
if ([[elmChild description] containsString:identifier]) if ([[elmChild description] containsString:identifier])
@ -1344,8 +1371,8 @@ static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *ide
} }
if ([child isKindOfClass:%c(ASNodeController)]) { if ([child isKindOfClass:%c(ASNodeController)]) {
ASDisplayNode *childNode = ((ASNodeController *)child).node; // ELMContainerNode ASDisplayNode *childNode = ((ASNodeController * _Nullable)child).node; // ELMContainerNode
NSArray *yogaChildren = childNode.yogaChildren; NSArray<id> *yogaChildren = childNode.yogaChildren;
for (ASDisplayNode *displayNode in yogaChildren) { for (ASDisplayNode *displayNode in yogaChildren) {
if ([identifiers containsObject:displayNode.accessibilityIdentifier]) if ([identifiers containsObject:displayNode.accessibilityIdentifier])
return YES; return YES;
@ -1361,7 +1388,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *ide
%hook ASCollectionView // This stopped working on May 14th 2024 due to a Server-Side Change from YouTube. %hook ASCollectionView // This stopped working on May 14th 2024 due to a Server-Side Change from YouTube.
- (CGSize)sizeForElement:(ASCollectionElement *)element { - (CGSize)sizeForElement:(ASCollectionElement * _Nullable)element {
if ([self.accessibilityIdentifier isEqualToString:@"id.video.scrollable_action_bar"]) { if ([self.accessibilityIdentifier isEqualToString:@"id.video.scrollable_action_bar"]) {
ASCellNode *node = [element node]; ASCellNode *node = [element node];
ASNodeController *nodeController = [node controller]; ASNodeController *nodeController = [node controller];
@ -1676,6 +1703,9 @@ static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *ide
if (IS_ENABLED(@"portraitFullscreen_enabled")) { if (IS_ENABLED(@"portraitFullscreen_enabled")) {
%init(gPortraitFullscreen); %init(gPortraitFullscreen);
} }
if (IS_ENABLED(@"fullscreenToTheRight_enabled")) {
%init(gFullscreenToTheRight);
}
if (IS_ENABLED(@"disableFullscreenButton_enabled")) { if (IS_ENABLED(@"disableFullscreenButton_enabled")) {
%init(gHideFullscreenButton); %init(gHideFullscreenButton);
} }
@ -1743,7 +1773,7 @@ static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *ide
%init(gDisableLiveChatSection); %init(gDisableLiveChatSection);
} }
if (IS_ENABLED(@"YTTapToSeek_enabled")) { if (IS_ENABLED(@"YTTapToSeek_enabled")) {
%init(YTTTS_Tweak); %init(gYTTapToSeek);
} }
if (IS_ENABLED(@"hidePremiumPromos_enabled")) { if (IS_ENABLED(@"hidePremiumPromos_enabled")) {
%init(gHidePremiumPromos); %init(gHidePremiumPromos);

View file

@ -85,6 +85,10 @@
+ (GPBExtensionDescriptor*)innertubeCommand; + (GPBExtensionDescriptor*)innertubeCommand;
@end @end
@interface YTAccountScopedCommandResponderEvent
@property (nonatomic, strong, readwrite) YTICommand *command;
@end
@interface YTIShareEntityEndpoint @interface YTIShareEntityEndpoint
@property (nonatomic, assign, readwrite) BOOL hasSerializedShareEntity; @property (nonatomic, assign, readwrite) BOOL hasSerializedShareEntity;
@property (nonatomic, copy, readwrite) NSString *serializedShareEntity; @property (nonatomic, copy, readwrite) NSString *serializedShareEntity;

View file

@ -2,6 +2,7 @@
# pragma mark - YouTube patches # pragma mark - YouTube patches
/*
// Fix Google Sign in by @PoomSmart and @level3tjg (qnblackcat/uYouPlus#684) // Fix Google Sign in by @PoomSmart and @level3tjg (qnblackcat/uYouPlus#684)
%hook NSBundle %hook NSBundle
- (NSDictionary *)infoDictionary { - (NSDictionary *)infoDictionary {
@ -11,6 +12,17 @@
return info; return info;
} }
%end %end
*/
// Workaround for MiRO92/uYou-for-YouTube#12, qnblackcat/uYouPlus#263
%hook YTDataUtils
+ (NSMutableDictionary *)spamSignalsDictionary {
return nil;
}
+ (NSMutableDictionary *)spamSignalsDictionaryWithoutIDFA {
return nil;
}
%end
%hook YTHotConfig %hook YTHotConfig
- (BOOL)disableAfmaIdfaCollection { return NO; } - (BOOL)disableAfmaIdfaCollection { return NO; }
@ -98,7 +110,6 @@ static inline NSString* extractIdWithFormat(GPBUnknownFieldSet *fields, NSIntege
NSString *id = [[NSString alloc] initWithData:[idField.lengthDelimitedList firstObject] encoding:NSUTF8StringEncoding]; NSString *id = [[NSString alloc] initWithData:[idField.lengthDelimitedList firstObject] encoding:NSUTF8StringEncoding];
return [NSString stringWithFormat:format, id]; return [NSString stringWithFormat:format, id];
} }
static BOOL showNativeShareSheet(NSString *serializedShareEntity) { static BOOL showNativeShareSheet(NSString *serializedShareEntity) {
GPBMessage *shareEntity = [%c(GPBMessage) deserializeFromString:serializedShareEntity]; GPBMessage *shareEntity = [%c(GPBMessage) deserializeFromString:serializedShareEntity];
GPBUnknownFieldSet *fields = shareEntity.unknownFields; GPBUnknownFieldSet *fields = shareEntity.unknownFields;
@ -107,7 +118,7 @@ static BOOL showNativeShareSheet(NSString *serializedShareEntity) {
if ([fields hasField:ShareEntityFieldClip]) { if ([fields hasField:ShareEntityFieldClip]) {
GPBUnknownField *shareEntityClip = [fields getField:ShareEntityFieldClip]; GPBUnknownField *shareEntityClip = [fields getField:ShareEntityFieldClip];
if ([shareEntityClip.lengthDelimitedList count] != 1) if ([shareEntityClip.lengthDelimitedList count] != 1)
return FALSE; return NO;
GPBMessage *clipMessage = [%c(GPBMessage) parseFromData:[shareEntityClip.lengthDelimitedList firstObject] error:nil]; GPBMessage *clipMessage = [%c(GPBMessage) parseFromData:[shareEntityClip.lengthDelimitedList firstObject] error:nil];
shareUrl = extractIdWithFormat(clipMessage.unknownFields, 1, @"https://youtube.com/clip/%@"); shareUrl = extractIdWithFormat(clipMessage.unknownFields, 1, @"https://youtube.com/clip/%@");
} }
@ -128,40 +139,38 @@ static BOOL showNativeShareSheet(NSString *serializedShareEntity) {
shareUrl = extractIdWithFormat(fields, ShareEntityFieldVideo, @"https://youtube.com/watch?v=%@"); shareUrl = extractIdWithFormat(fields, ShareEntityFieldVideo, @"https://youtube.com/watch?v=%@");
if (!shareUrl) if (!shareUrl)
return FALSE; return NO;
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]initWithActivityItems:@[shareUrl] applicationActivities:nil]; UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[shareUrl] applicationActivities:nil];
[[%c(YTUIUtils) topViewControllerForPresenting] presentViewController:activityViewController animated:YES completion:^{}]; activityViewController.excludedActivityTypes = @[UIActivityTypeAssignToContact, UIActivityTypePrint];
return TRUE;
UIViewController *topViewController = [%c(YTUIUtils) topViewControllerForPresenting];
if (activityViewController.popoverPresentationController) {
activityViewController.popoverPresentationController.sourceView = topViewController.view;
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
activityViewController.popoverPresentationController.sourceRect = CGRectMake(screenWidth / 2.0, screenHeight, 0, 0);
activityViewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[topViewController presentViewController:activityViewController animated:YES completion:nil];
return YES;
} }
/* -------------------- iPad Layout -------------------- */ /* -------------------- iPad Layout -------------------- */
/* %hook YTAccountScopedCommandResponderEvent
%hook YTShareRequestViewController - (void)send {
- (id)initWithService:(id)_service parentResponder:(id)_parentResponder {
id result = %orig;
// disable the default share sheet behavior and force the app to call [YTAccountScopedCommandRouter handleCommand] if available
if ([_parentResponder respondsToSelector:@selector(handleCommand:entry:fromView:sender:completionBlock:)]) {
[_parentResponder handleCommand:nil entry:nil fromView:nil sender:nil completionBlock:nil];
}
return result;
}
%end
*/
%hook YTAccountScopedCommandRouter
- (BOOL)handleCommand:(id)command entry:(id)_entry fromView:(id)_fromView sender:(id)_sender completionBlock:(id)_completionBlock {
GPBExtensionDescriptor *shareEntityEndpointDescriptor = [%c(YTIShareEntityEndpoint) shareEntityEndpoint]; GPBExtensionDescriptor *shareEntityEndpointDescriptor = [%c(YTIShareEntityEndpoint) shareEntityEndpoint];
if (![command hasExtension:shareEntityEndpointDescriptor]) if (![self.command hasExtension:shareEntityEndpointDescriptor])
return %orig; return %orig;
YTIShareEntityEndpoint *shareEntityEndpoint = [command getExtension:shareEntityEndpointDescriptor]; YTIShareEntityEndpoint *shareEntityEndpoint = [self.command getExtension:shareEntityEndpointDescriptor];
if(!shareEntityEndpoint.hasSerializedShareEntity) if (!shareEntityEndpoint.hasSerializedShareEntity)
return %orig; return %orig;
if (!showNativeShareSheet(shareEntityEndpoint.serializedShareEntity)) if (!showNativeShareSheet(shareEntityEndpoint.serializedShareEntity))
return %orig; return %orig;
return TRUE;
} }
%end %end
@ -186,6 +195,8 @@ static BOOL showNativeShareSheet(NSString *serializedShareEntity) {
} }
%end %end
//
// iOS 16 uYou crash fix - @level3tjg: https://github.com/qnblackcat/uYouPlus/pull/224 // iOS 16 uYou crash fix - @level3tjg: https://github.com/qnblackcat/uYouPlus/pull/224
// %group iOS16 // %group iOS16
// %hook OBPrivacyLinkButton // %hook OBPrivacyLinkButton
@ -340,7 +351,6 @@ static void refreshUYouAppearance() {
// Disable uYou's playback speed controls (prevent crash on video playback https://github.com/therealFoxster/uYouPlus/issues/2#issuecomment-1894912963) // Disable uYou's playback speed controls (prevent crash on video playback https://github.com/therealFoxster/uYouPlus/issues/2#issuecomment-1894912963)
// [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"showPlaybackRate"]; // [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"showPlaybackRate"];
// Disable uYou's adblock // Disable uYou's adblock
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"removeYouTubeAds"]; [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"removeYouTubeAds"];
} }

View file

@ -201,21 +201,19 @@ extern NSBundle *uYouPlusBundle();
selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
if (IS_ENABLED(@"replaceCopyandPasteButtons_enabled")) { if (IS_ENABLED(@"replaceCopyandPasteButtons_enabled")) {
// Export Settings functionality // Export Settings functionality
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSURL *tempFileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"exported_settings.txt"]];
NSMutableString *settingsString = [NSMutableString string]; NSMutableString *settingsString = [NSMutableString string];
for (NSString *key in copyKeys) { for (NSString *key in copyKeys) {
if ([userDefaults objectForKey:key]) { id value = [[NSUserDefaults standardUserDefaults] objectForKey:key];
NSString *value = [userDefaults objectForKey:key]; if (value) {
[settingsString appendFormat:@"%@: %@\n", key, value]; [settingsString appendFormat:@"%@: %@\n", key, value];
} }
} }
if (settingsString.length > 0) { [settingsString writeToURL:tempFileURL atomically:YES encoding:NSUTF8StringEncoding error:nil];
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.text"] inMode:UIDocumentPickerModeExportToService]; UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:tempFileURL inMode:UIDocumentPickerModeExportToService];
documentPicker.delegate = (id<UIDocumentPickerDelegate>)self; documentPicker.delegate = (id<UIDocumentPickerDelegate>)self;
documentPicker.allowsMultipleSelection = NO; documentPicker.allowsMultipleSelection = NO;
[UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPicker animated:YES completion:nil]; [settingsViewController presentViewController:documentPicker animated:YES completion:nil];
}
return YES;
} else { } else {
// Copy Settings functionality (default behavior) // Copy Settings functionality (default behavior)
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
@ -245,7 +243,7 @@ extern NSBundle *uYouPlusBundle();
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.text"] inMode:UIDocumentPickerModeImport]; UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.text"] inMode:UIDocumentPickerModeImport];
documentPicker.delegate = (id<UIDocumentPickerDelegate>)self; documentPicker.delegate = (id<UIDocumentPickerDelegate>)self;
documentPicker.allowsMultipleSelection = NO; documentPicker.allowsMultipleSelection = NO;
[UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:documentPicker animated:YES completion:nil]; [settingsViewController presentViewController:documentPicker animated:YES completion:nil];
return YES; return YES;
} else { } else {
// Paste Settings functionality (default behavior) // Paste Settings functionality (default behavior)
@ -262,7 +260,7 @@ extern NSBundle *uYouPlusBundle();
NSString *value = components[1]; NSString *value = components[1];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
} }
} }
[settingsViewController reloadData]; [settingsViewController reloadData];
SHOW_RELAUNCH_YT_SNACKBAR; SHOW_RELAUNCH_YT_SNACKBAR;
} }
@ -472,7 +470,7 @@ extern NSBundle *uYouPlusBundle();
LOC(@"HIDE_FULLSCREEN_ACTION_BUTTONS_DESC"), LOC(@"HIDE_FULLSCREEN_ACTION_BUTTONS_DESC"),
@"hideFullscreenActions_enabled", @"hideFullscreenActions_enabled",
({ ({
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
// Show alert if the option is not compatible with iPad // Show alert if the option is not compatible with iPad
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"iPad Compatibility Issue" message:@"This option is only compatible with iPhone devices." preferredStyle:UIAlertControllerStyleAlert]; UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"iPad Compatibility Issue" message:@"This option is only compatible with iPhone devices." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
@ -1395,18 +1393,23 @@ extern NSBundle *uYouPlusBundle();
[settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouEnhanced" titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES]; [settingsViewController setSectionItems:sectionItems forCategory:uYouPlusSection title:@"uYouEnhanced" titleDescription:LOC(@"TITLE DESCRIPTION") headerHidden:YES];
} }
// File Manager (Paste Settings) // File Manager (Import Settings .txt)
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls { - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
if (urls.count > 0) { if (urls.count > 0) {
NSString *fileContents = [NSString stringWithContentsOfURL:urls.firstObject encoding:NSUTF8StringEncoding error:nil]; NSURL *fileURL = urls.firstObject;
NSArray *lines = [fileContents componentsSeparatedByString:@"\n"]; NSString *fileContents = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:nil];
for (NSString *line in lines) { if (fileContents.length > 0) {
NSArray *components = [line componentsSeparatedByString:@": "]; NSArray *lines = [fileContents componentsSeparatedByString:@"\n"];
if (components.count == 2) { for (NSString *line in lines) {
NSString *key = components[0]; NSArray *components = [line componentsSeparatedByString:@": "];
NSString *value = components[1]; if (components.count == 2) {
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key]; NSString *key = components[0];
NSString *value = components[1];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
}
} }
YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"];
[settingsViewController reloadData];
} }
} }
} }