New method using data manipulation

This commit is contained in:
Bryce Hackel 2024-04-05 03:38:35 -07:00
parent da933fd188
commit ae75588dcc
No known key found for this signature in database
GPG key ID: F031960F08455E88
3 changed files with 150 additions and 87 deletions

View file

@ -28,6 +28,9 @@
#import "Tweaks/YouTubeHeader/YTInnerTubeCollectionViewController.h" #import "Tweaks/YouTubeHeader/YTInnerTubeCollectionViewController.h"
#import "Tweaks/YouTubeHeader/YTPivotBarItemView.h" #import "Tweaks/YouTubeHeader/YTPivotBarItemView.h"
#import "Tweaks/YouTubeHeader/YTCollectionViewCell.h" #import "Tweaks/YouTubeHeader/YTCollectionViewCell.h"
#import "Tweaks/YouTubeHeader/YTIFormattedString.h"
#import "Tweaks/YouTubeHeader/GPBMessage.h"
#import "Tweaks/YouTubeHeader/YTIStringRun.h"
// Hide buttons under the video player by @PoomSmart // Hide buttons under the video player by @PoomSmart
#import "Tweaks/YouTubeHeader/ASCollectionElement.h" #import "Tweaks/YouTubeHeader/ASCollectionElement.h"
@ -66,12 +69,41 @@
@end @end
// Hide Premium Promo in You tab - @bhackel // Hide Premium Promo in You tab - @bhackel
@interface YTIconBadgeView : UIView @interface YTIIconThumbnailRenderer : GPBMessage
@property (nonatomic, strong) YTIIcon *icon;
- (bool)hasIcon;
@end @end
@interface YTLinkCell : YTCollectionViewCell @interface YTICompactListItemThumbnailSupportedRenderers : GPBMessage
@property(readonly, nonatomic) YTIconBadgeView *_iconBadgeView; @property (nonatomic, strong) YTIIconThumbnailRenderer *iconThumbnailRenderer;
- (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
@end
@interface YTInnerTubeCollectionViewController (uYouEnhanced)
@property(readonly, nonatomic) YTISectionListRenderer *model;
@end @end
// uYouPlus // uYouPlus
@interface YTHeaderLogoController : UIView @interface YTHeaderLogoController : UIView

View file

@ -214,6 +214,7 @@ BOOL isAd(YTIElementRenderer *self) {
// YTNoHoverCards: https://github.com/level3tjg/YTNoHoverCards // YTNoHoverCards: https://github.com/level3tjg/YTNoHoverCards
%hook YTCreatorEndscreenView %hook YTCreatorEndscreenView
- (void)setHidden:(BOOL)hidden { - (void)setHidden:(BOOL)hidden {
NSLog(@"bhackel debug: setHidden method called");
if (IS_ENABLED(@"hideHoverCards_enabled")) if (IS_ENABLED(@"hideHoverCards_enabled"))
hidden = YES; hidden = YES;
%orig; %orig;
@ -274,99 +275,125 @@ BOOL isAd(YTIElementRenderer *self) {
- (BOOL)savedSettingShouldExpire { return NO; } - (BOOL)savedSettingShouldExpire { return NO; }
%end %end
// Hide Premium promos in "You" and "Library" tab - @bhackel // Hide Premium promos in "You" tab - @bhackel
%group gHidePremiumPromos %group gHidePremiumPromos
// Hide "Get Youtube Premium" in the "You" tab // Hide "Get Youtube Premium" in the "You" tab
%hook YTAsyncCollectionView %hook YTAppCollectionViewController
// Property for tracking if the cell was hidden - (void)loadWithModel:(YTISectionListRenderer *)model {
- (void)layoutSubviews { NSLog(@"bhackel debug: loadWithModel method called");
%orig; NSMutableArray <YTISectionListSupportedRenderers *> *overallContentsArray = model.contentsArray;
// Check each subview for the "Get YouTube Premium" cell // Check each item in the overall array - this represents the whole You page
UIView *foundSubview = nil; YTISectionListSupportedRenderers *supportedRenderers;
for (UIView *subview in self.subviews) { for (supportedRenderers in overallContentsArray) {
// The cell is of type YTLinkCell NSLog(@"bhackel debug: in 1st loop");
if (![subview isKindOfClass:NSClassFromString(@"YTLinkCell")]) { YTIItemSectionRenderer *itemSectionRenderer = supportedRenderers.itemSectionRenderer;
continue; // Check each subobject - this would be visible as a cell in the You page
NSMutableArray <YTIItemSectionSupportedRenderers *> *subContentsArray = itemSectionRenderer.contentsArray;
bool found = NO;
YTIItemSectionSupportedRenderers *itemSectionSupportedRenderers;
for (itemSectionSupportedRenderers in subContentsArray) {
NSLog(@"bhackel debug: in 2nd loop");
// Check for a link cell
if ([itemSectionSupportedRenderers hasCompactLinkRenderer]) {
NSLog(@"bhackel debug: hasCompactLinkRenderer");
YTICompactLinkRenderer *compactLinkRenderer = [itemSectionSupportedRenderers compactLinkRenderer];
// Check for an icon in this cell
if ([compactLinkRenderer hasIcon]) {
NSLog(@"bhackel debug: hasIcon");
YTIIcon *icon = [compactLinkRenderer icon];
// Check if the icon is for the premium promo
if ([icon hasIconType] && icon.iconType == 117) {
NSLog(@"bhackel debug: iconType == 117, found... :D");
found = YES;
break;
}
}
}
} }
// Get the badge of this cell, as it is language-independent and unique // Remove object from array - perform outside of loop to avoid error
YTIconBadgeView *badgeView = [subview valueForKey:@"_iconBadgeView"]; if (found) {
if (!badgeView) { NSLog(@"bhackel debug: removing...");
continue; [subContentsArray removeObject:itemSectionSupportedRenderers];
}
// Walk down the subviews to get to a specific view
UIView *firstSubview = badgeView.subviews.firstObject;
if (!subview) {
continue;
}
UIImageView *secondSubview = firstSubview.subviews.firstObject;
if (!secondSubview || ![secondSubview respondsToSelector:@selector(description)]) {
continue;
}
// Check if "yt_outline_youtube_logo_icon" is in the description
NSString *description = secondSubview.description;
if ([description containsString:@"yt_outline_youtube_logo_icon"]) {
foundSubview = subview;
break; break;
} }
} }
if (self.hidden) { %orig;
return; }
} %end
%end
// Move all subviews that are below this cell upwards to remove blank space
CGFloat viewHeight = foundSubview.frame.size.height; // Fake premium in the You tab - @bhackel
bool foundThisSubview = false; %group gYouTabFakePremium
// Create a copy of foundSubview.superview.subviews %hook YTAppCollectionViewController
NSArray *subviewsCopy = [foundSubview.superview.subviews copy]; - (void)loadWithModel:(YTISectionListRenderer *)model {
for (UIView *subview in subviewsCopy) { NSLog(@"bhackel debug: loadWithModel method called");
if (foundThisSubview) { NSUInteger yourVideosIndex = -1;
dispatch_async(dispatch_get_main_queue(), ^{ NSMutableArray <YTISectionListSupportedRenderers *> *overallContentsArray = model.contentsArray;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Debug" // Check each item in the overall array - this represents the whole You page
message:@"moved a view up" YTISectionListSupportedRenderers *supportedRenderers;
preferredStyle:UIAlertControllerStyleAlert]; for (supportedRenderers in overallContentsArray) {
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" NSLog(@"bhackel debug: in 1st loop");
style:UIAlertActionStyleDefault YTIItemSectionRenderer *itemSectionRenderer = supportedRenderers.itemSectionRenderer;
handler:nil]; // Check each subobject - this would be visible as a cell in the You page
NSMutableArray <YTIItemSectionSupportedRenderers *> *subContentsArray = itemSectionRenderer.contentsArray;
[alert addAction:okAction]; YTIItemSectionSupportedRenderers *itemSectionSupportedRenderers;
// Find the appropriate view controller to present this alert for (itemSectionSupportedRenderers in subContentsArray) {
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; NSLog(@"bhackel debug: in 2nd loop");
while (rootViewController.presentedViewController) { // Check for a specific type of cell of type CompactLinkRenderer
rootViewController = rootViewController.presentedViewController; if ([itemSectionSupportedRenderers hasCompactLinkRenderer]) {
NSLog(@"bhackel debug: hasCompactLinkRenderer");
YTICompactLinkRenderer *compactLinkRenderer = [itemSectionSupportedRenderers compactLinkRenderer];
// Check for an icon in this cell
if ([compactLinkRenderer hasIcon]) {
NSLog(@"bhackel debug: hasIcon");
YTIIcon *icon = [compactLinkRenderer icon];
// Check if the icon is for the premium promo
if ([icon hasIconType] && icon.iconType == 117) {
NSLog(@"bhackel debug: iconType == 117, found... :D");
// Modify the icon type to be Premium
icon.iconType = 741;
// Modify the text
((YTIStringRun *)(compactLinkRenderer.title.runsArray.firstObject)).text = @"Your Premium benefits";
}
} }
[rootViewController presentViewController:alert animated:YES completion:nil]; }
}); // Check for a specific type of cell of type CompactListItemRenderer
CGFloat oldX = subview.frame.origin.x; if ([itemSectionSupportedRenderers hasCompactListItemRenderer]) {
CGFloat newY = subview.frame.origin.y - viewHeight; NSLog(@"bhackel debug: 2 hasCompactListItemRenderer");
CGFloat width = subview.frame.size.width; YTICompactListItemRenderer *compactListItemRenderer = itemSectionSupportedRenderers.compactListItemRenderer;
CGFloat height = subview.frame.size.height; if ([compactListItemRenderer hasThumbnail]) {
subview.frame = CGRectMake(oldX, newY, width, height); NSLog(@"bhackel debug: 2 hasThumbnail");
YTICompactListItemThumbnailSupportedRenderers *thumbnail = compactListItemRenderer.thumbnail;
if ([thumbnail hasIconThumbnailRenderer]) {
NSLog(@"bhackel debug: 2 hasIconThumbnailRenderer");
YTIIconThumbnailRenderer *iconThumbnailRenderer = thumbnail.iconThumbnailRenderer;
if ([iconThumbnailRenderer hasIcon]) {
NSLog(@"bhackel debug: 2 hasIcon");
YTIIcon *icon = iconThumbnailRenderer.icon;
if ([icon hasIconType] && icon.iconType == 658) {
NSLog(@"bhackel debug: 2 iconType == 658, found... :D");
// Note the index of this cell in the array
yourVideosIndex = [subContentsArray indexOfObject:itemSectionSupportedRenderers];
}
}
}
}
}
} }
// If we find this subview, we know that all subviews below it are to be moved if (yourVideosIndex != -1) {
if (subview == foundSubview) { NSLog(@"bhackel debug: yourVideosIndex != -1");
dispatch_async(dispatch_get_main_queue(), ^{ // Create a new cell with the same properties as the original cell
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Debug" YTIItemSectionSupportedRenderers *newItemSectionSupportedRenderers = [subContentsArray[yourVideosIndex] copy];
message:@"found this subview" // Modify the text
preferredStyle:UIAlertControllerStyleAlert]; ((YTIStringRun *)(newItemSectionSupportedRenderers.compactListItemRenderer.title.runsArray.firstObject)).text = @"Downloads";
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" // Modify the icon
style:UIAlertActionStyleDefault newItemSectionSupportedRenderers.compactListItemRenderer.thumbnail.iconThumbnailRenderer.icon.iconType = 147;
handler:nil]; // Insert the new cell at the index of the original cell
[subContentsArray insertObject:newItemSectionSupportedRenderers atIndex:yourVideosIndex + 1];
[alert addAction:okAction]; yourVideosIndex = -1;
// Find the appropriate view controller to present this alert
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (rootViewController.presentedViewController) {
rootViewController = rootViewController.presentedViewController;
}
[rootViewController presentViewController:alert animated:YES completion:nil];
});
foundThisSubview = true;
} }
} }
// Remove this cell from existence %orig;
foundSubview.hidden = YES;
foundSubview.frame = CGRectZero;
} }
%end %end
%end %end
@ -1423,6 +1450,9 @@ static BOOL findCell(ASNodeController *nodeController, NSArray <NSString *> *ide
if (IS_ENABLED(@"hidePremiumPromos_enabled")) { if (IS_ENABLED(@"hidePremiumPromos_enabled")) {
%init(gHidePremiumPromos); %init(gHidePremiumPromos);
} }
if (IS_ENABLED(@"youTabFakePremium_enabled")) {
%init(gYouTabFakePremium);
}
// YTNoModernUI - @arichorn // YTNoModernUI - @arichorn
BOOL ytNoModernUIEnabled = IS_ENABLED(@"ytNoModernUI_enabled"); BOOL ytNoModernUIEnabled = IS_ENABLED(@"ytNoModernUI_enabled");

View file

@ -276,6 +276,7 @@ extern NSBundle *uYouPlusBundle();
SWITCH_ITEM2(LOC(@"Hide `Privacy` Section"), LOC(@"App restart is required."), @"disablePrivacySection_enabled"); SWITCH_ITEM2(LOC(@"Hide `Privacy` Section"), LOC(@"App restart is required."), @"disablePrivacySection_enabled");
SWITCH_ITEM2(LOC(@"Hide `Live Chat` Section"), LOC(@"App restart is required."), @"disableLiveChatSection_enabled"); SWITCH_ITEM2(LOC(@"Hide `Live Chat` Section"), LOC(@"App restart is required."), @"disableLiveChatSection_enabled");
SWITCH_ITEM2(LOC(@"Hide `Get Youtube Premium` Section"), LOC(@"App restart is required."), @"hidePremiumPromos_enabled"); SWITCH_ITEM2(LOC(@"Hide `Get Youtube Premium` Section"), LOC(@"App restart is required."), @"hidePremiumPromos_enabled");
SWITCH_ITEM2(LOC(@"Fake Premium in You tab"), LOC(@"Makes it look like you have Premium. English only."), @"youTabFakePremium_enabled");
# pragma mark - UI interface options # pragma mark - UI interface options
SECTION_HEADER(LOC(@"UI Interface Options")); SECTION_HEADER(LOC(@"UI Interface Options"));