mirror of
https://github.com/SoPat712/YTLitePlus.git
synced 2025-08-22 02:58:45 -04:00
added files via upload
This commit is contained in:
666
Tweaks/YTLite/YTLite.x
Normal file
666
Tweaks/YTLite/YTLite.x
Normal file
@@ -0,0 +1,666 @@
|
||||
#import "YTLite.h"
|
||||
|
||||
// YouTube-X (https://github.com/PoomSmart/YouTube-X/)
|
||||
// Background Playback
|
||||
%hook YTIPlayabilityStatus
|
||||
- (BOOL)isPlayableInBackground { return kBackgroundPlayback ? YES : NO; }
|
||||
%end
|
||||
|
||||
%hook MLVideo
|
||||
- (BOOL)playableInBackground { return kBackgroundPlayback ? YES : NO; }
|
||||
%end
|
||||
|
||||
// Disable Ads
|
||||
%hook YTIPlayerResponse
|
||||
- (BOOL)isMonetized { return kNoAds ? NO : YES; }
|
||||
%end
|
||||
|
||||
%hook YTDataUtils
|
||||
+ (id)spamSignalsDictionary { return kNoAds ? nil : %orig; }
|
||||
+ (id)spamSignalsDictionaryWithoutIDFA { return kNoAds ? nil : %orig; }
|
||||
%end
|
||||
|
||||
%hook YTAdsInnerTubeContextDecorator
|
||||
- (void)decorateContext:(id)context { if (!kNoAds) %orig; }
|
||||
%end
|
||||
|
||||
%hook YTAccountScopedAdsInnerTubeContextDecorator
|
||||
- (void)decorateContext:(id)context { if (!kNoAds) %orig; }
|
||||
%end
|
||||
|
||||
BOOL isAd(YTIElementRenderer *self) {
|
||||
if (self == nil) return NO;
|
||||
if (self.hasCompatibilityOptions && self.compatibilityOptions.hasAdLoggingData) return YES;
|
||||
NSString *description = [self description];
|
||||
if (([description containsString:@"brand_promo"]
|
||||
|| [description containsString:@"product_carousel"]
|
||||
|| [description containsString:@"product_engagement_panel"]
|
||||
|| [description containsString:@"product_item"]) && kNoAds)
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
%hook YTSectionListViewController
|
||||
- (void)loadWithModel:(YTISectionListRenderer *)model {
|
||||
if (kNoAds) {
|
||||
NSMutableArray <YTISectionListSupportedRenderers *> *contentsArray = model.contentsArray;
|
||||
NSIndexSet *removeIndexes = [contentsArray indexesOfObjectsPassingTest:^BOOL(YTISectionListSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
|
||||
YTIItemSectionRenderer *sectionRenderer = renderers.itemSectionRenderer;
|
||||
YTIItemSectionSupportedRenderers *firstObject = [sectionRenderer.contentsArray firstObject];
|
||||
return firstObject.hasPromotedVideoRenderer || firstObject.hasCompactPromotedVideoRenderer || firstObject.hasPromotedVideoInlineMutedRenderer || isAd(firstObject.elementRenderer);
|
||||
}];
|
||||
[contentsArray removeObjectsAtIndexes:removeIndexes];
|
||||
} %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
// NOYTPremium (https://github.com/PoomSmart/NoYTPremium)
|
||||
// Alert
|
||||
%hook YTCommerceEventGroupHandler
|
||||
- (void)addEventHandlers {}
|
||||
%end
|
||||
|
||||
// Full-screen
|
||||
%hook YTInterstitialPromoEventGroupHandler
|
||||
- (void)addEventHandlers {}
|
||||
%end
|
||||
|
||||
%hook YTPromosheetEventGroupHandler
|
||||
- (void)addEventHandlers {}
|
||||
%end
|
||||
|
||||
%hook YTPromoThrottleController
|
||||
- (BOOL)canShowThrottledPromo { return NO; }
|
||||
- (BOOL)canShowThrottledPromoWithFrequencyCap:(id)arg1 { return NO; }
|
||||
- (BOOL)canShowThrottledPromoWithFrequencyCaps:(id)arg1 { return NO; }
|
||||
%end
|
||||
|
||||
%hook YTIShowFullscreenInterstitialCommand
|
||||
- (BOOL)shouldThrottleInterstitial { return YES; }
|
||||
%end
|
||||
|
||||
// "Try new features" in settings
|
||||
%hook YTSettingsSectionItemManager
|
||||
- (void)updatePremiumEarlyAccessSectionWithEntry:(id)arg1 {}
|
||||
%end
|
||||
|
||||
// Survey
|
||||
%hook YTSurveyController
|
||||
- (void)showSurveyWithRenderer:(id)arg1 surveyParentResponder:(id)arg2 {}
|
||||
%end
|
||||
|
||||
// Statement banner
|
||||
%hook YTPremiumSeasonCardCellController
|
||||
- (void)setCell:(id)arg1 { arg1 = NULL; %orig; }
|
||||
%end
|
||||
|
||||
%hook YTPremiumSeasonCardView
|
||||
- (long long)accessibilityElementCount { return 0; }
|
||||
%end
|
||||
|
||||
// Navbar Stuff
|
||||
// Disable Cast
|
||||
%hook MDXPlaybackRouteButtonController
|
||||
- (BOOL)isPersistentCastIconEnabled { return kNoCast ? NO : YES; }
|
||||
- (void)updateRouteButton:(id)arg1 { if (!kNoCast) %orig; }
|
||||
- (void)updateAllRouteButtons { if (!kNoCast) %orig; }
|
||||
%end
|
||||
|
||||
%hook YTSettings
|
||||
- (void)setDisableMDXDeviceDiscovery:(BOOL)arg1 { %orig(kNoCast); }
|
||||
%end
|
||||
|
||||
// Hide Cast, Notifications and Search Buttons
|
||||
%hook YTRightNavigationButtons
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
if (kNoCast && self.subviews.count > 1 && [self.subviews[1].accessibilityIdentifier isEqualToString:@"id.mdx.playbackroute.button"]) self.subviews[1].hidden = YES; // Hide icon immediately
|
||||
if (kNoNotifsButton) self.notificationButton.hidden = YES;
|
||||
if (kNoSearchButton) self.searchButton.hidden = YES;
|
||||
}
|
||||
%end
|
||||
|
||||
// Hide YouTube Logo
|
||||
%hook YTNavigationBarTitleView
|
||||
- (void)layoutSubviews { %orig; if (kNoYTLogo && self.subviews.count > 1 && [self.subviews[1].accessibilityIdentifier isEqualToString:@"id.yoodle.logo"]) self.subviews[1].hidden = YES; }
|
||||
%end
|
||||
|
||||
// Stick Navigation bar
|
||||
%hook YTHeaderView
|
||||
- (BOOL)stickyNavHeaderEnabled { return kStickyNavbar ? YES : NO; }
|
||||
%end
|
||||
|
||||
// Remove Subbar
|
||||
%hook YTMySubsFilterHeaderView
|
||||
- (void)setChipFilterView:(id)arg1 { if (!kNoSubbar) %orig; }
|
||||
%end
|
||||
|
||||
%hook YTHeaderContentComboView
|
||||
- (void)enableSubheaderBarWithView:(id)arg1 { if (!kNoSubbar) %orig; }
|
||||
%end
|
||||
|
||||
%hook YTHeaderContentComboView
|
||||
- (void)setFeedHeaderScrollMode:(int)arg1 { kNoSubbar ? %orig(0) : %orig; }
|
||||
%end
|
||||
|
||||
// Hide Autoplay Switch and Subs Button
|
||||
%hook YTMainAppControlsOverlayView
|
||||
- (void)setAutoplaySwitchButtonRenderer:(id)arg1 { if (!kHideAutoplay) %orig; }
|
||||
- (void)setClosedCaptionsOrSubtitlesButtonAvailable:(BOOL)arg1 { kHideSubs ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// Remove HUD Messages
|
||||
%hook YTHUDMessageView
|
||||
- (id)initWithMessage:(id)arg1 dismissHandler:(id)arg2 { return kNoHUDMsgs ? nil : %orig; }
|
||||
%end
|
||||
|
||||
|
||||
%hook YTColdConfig
|
||||
// Hide Next & Previous buttons
|
||||
- (BOOL)removeNextPaddleForSingletonVideos { return kHidePrevNext ? YES : NO; }
|
||||
- (BOOL)removePreviousPaddleForSingletonVideos { return kHidePrevNext ? YES : NO; }
|
||||
// Replace Next & Previous with Fast Forward & Rewind buttons
|
||||
- (BOOL)replaceNextPaddleWithFastForwardButtonForSingletonVods { return kReplacePrevNext ? YES : NO; }
|
||||
- (BOOL)replacePreviousPaddleWithRewindButtonForSingletonVods { return kReplacePrevNext ? YES : NO; }
|
||||
// Disable Free Zoom
|
||||
- (BOOL)videoZoomFreeZoomEnabledGlobalConfig { return kNoFreeZoom ? NO : YES; }
|
||||
// Use System Theme
|
||||
- (BOOL)shouldUseAppThemeSetting { return YES; }
|
||||
// Dismiss Panel By Swiping in Fullscreen Mode
|
||||
- (BOOL)isLandscapeEngagementPanelSwipeRightToDismissEnabled { return YES; }
|
||||
// Remove Video in Playlist By Swiping To The Right
|
||||
- (BOOL)enableSwipeToRemoveInPlaylistWatchEp { return YES; }
|
||||
%end
|
||||
|
||||
// Remove Dark Background in Overlay
|
||||
%hook YTMainAppVideoPlayerOverlayView
|
||||
- (void)setBackgroundVisible:(BOOL)arg1 { kNoDarkBg ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// No Endscreen Cards
|
||||
%hook YTCreatorEndscreenView
|
||||
- (void)setHidden:(BOOL)arg1 { kEndScreenCards ? %orig(YES) : %orig; }
|
||||
%end
|
||||
|
||||
// Disable Fullscreen Actions
|
||||
%hook YTFullscreenActionsView
|
||||
- (BOOL)enabled { return kNoFullscreenActions ? NO : YES; }
|
||||
- (void)setEnabled:(BOOL)arg1 { kNoFullscreenActions ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// Dont Show Related Videos on Finish
|
||||
%hook YTFullscreenEngagementOverlayController
|
||||
- (void)setRelatedVideosVisible:(BOOL)arg1 { kNoRelatedVids ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// Hide Paid Promotion Cards
|
||||
%hook YTMainAppVideoPlayerOverlayViewController
|
||||
- (void)setPaidContentWithPlayerData:(id)data { if (!kNoPromotionCards) %orig; }
|
||||
- (void)playerOverlayProvider:(YTPlayerOverlayProvider *)provider didInsertPlayerOverlay:(YTPlayerOverlay *)overlay {
|
||||
if ([[overlay overlayIdentifier] isEqualToString:@"player_overlay_paid_content"] && kNoPromotionCards) return;
|
||||
%orig;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook YTInlineMutedPlaybackPlayerOverlayViewController
|
||||
- (void)setPaidContentWithPlayerData:(id)data { if (!kNoPromotionCards) %orig; }
|
||||
%end
|
||||
|
||||
// Remove Watermarks
|
||||
%hook YTAnnotationsViewController
|
||||
- (void)loadFeaturedChannelWatermark { if (!kNoWatermarks) %orig; }
|
||||
%end
|
||||
|
||||
// Forcibly Enable Miniplayer
|
||||
%hook YTWatchMiniBarViewController
|
||||
- (void)updateMiniBarPlayerStateFromRenderer { if (!kMiniplayer) %orig; }
|
||||
%end
|
||||
|
||||
// Disable Autoplay
|
||||
%hook YTPlaybackConfig
|
||||
- (void)setStartPlayback:(BOOL)arg1 { kDisableAutoplay ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// Skip Content Warning (https://github.com/qnblackcat/uYouPlus/blob/main/uYouPlus.xm#L452-L454)
|
||||
%hook YTPlayabilityResolutionUserActionUIController
|
||||
- (void)showConfirmAlert { if (kNoContentWarning) [self confirmAlertDidPressConfirm]; }
|
||||
%end
|
||||
|
||||
// Classic Video Quality (https://github.com/PoomSmart/YTClassicVideoQuality)
|
||||
%hook YTVideoQualitySwitchControllerFactory
|
||||
- (id)videoQualitySwitchControllerWithParentResponder:(id)responder {
|
||||
Class originalClass = %c(YTVideoQualitySwitchOriginalController);
|
||||
if (kClassicQuality) {
|
||||
return originalClass ? [[originalClass alloc] initWithParentResponder:responder] : %orig;
|
||||
} return %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
// Disable Snap To Chapter (https://github.com/qnblackcat/uYouPlus/blob/main/uYouPlus.xm#L457-464)
|
||||
%hook YTSegmentableInlinePlayerBarView
|
||||
- (void)didMoveToWindow { %orig; if (kDontSnapToChapter) self.enableSnapToChapter = NO; }
|
||||
%end
|
||||
|
||||
// Red Progress Bar and Gray Buffer Progress
|
||||
%hook YTInlinePlayerBarContainerView
|
||||
- (id)quietProgressBarColor { return kRedProgressBar ? [UIColor redColor] : %orig; }
|
||||
%end
|
||||
|
||||
%hook YTSegmentableInlinePlayerBarView
|
||||
- (void)setBufferedProgressBarColor:(id)arg1 { if (kNoRelatedVids) %orig([UIColor colorWithRed:0.65 green:0.65 blue:0.65 alpha:0.60]); }
|
||||
%end
|
||||
|
||||
// Disable Hints
|
||||
%hook YTSettings
|
||||
- (BOOL)areHintsDisabled { return kNoHints ? YES : NO; }
|
||||
- (void)setHintsDisabled:(BOOL)arg1 { kNoHints ? %orig(YES) : %orig; }
|
||||
%end
|
||||
|
||||
%hook YTUserDefaults
|
||||
- (BOOL)areHintsDisabled { return kNoHints ? YES : NO; }
|
||||
- (void)setHintsDisabled:(BOOL)arg1 { kNoHints ? %orig(YES) : %orig; }
|
||||
%end
|
||||
|
||||
// Exit Fullscreen on Finish
|
||||
%hook YTWatchFlowController
|
||||
- (BOOL)shouldExitFullScreenOnFinish { return kExitFullscreen ? YES : NO; }
|
||||
%end
|
||||
|
||||
// Disable Double Tap To Seek
|
||||
%hook YTDoubleTapToSeekController
|
||||
- (void)enableDoubleTapToSeek:(BOOL)arg1 { kNoDoubleTapToSeek ? %orig(NO) : %orig; }
|
||||
%end
|
||||
|
||||
// Remove Shorts (https://github.com/MiRO92/YTNoShorts)
|
||||
%hook YTAsyncCollectionView
|
||||
- (id)cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (kHideShorts) {
|
||||
UICollectionViewCell *cell = %orig;
|
||||
if ([cell isKindOfClass:NSClassFromString(@"_ASCollectionViewCell")]) {
|
||||
_ASCollectionViewCell *cell = %orig;
|
||||
if ([cell respondsToSelector:@selector(node)]) {
|
||||
if ([[[cell node] accessibilityIdentifier] isEqualToString:@"eml.shorts-shelf"]) {
|
||||
[self removeShortsCellAtIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
} else if ([cell isKindOfClass:NSClassFromString(@"YTReelShelfCell")]) {
|
||||
[self removeShortsCellAtIndexPath:indexPath];
|
||||
} return %orig;
|
||||
} return %orig;
|
||||
}
|
||||
|
||||
%new
|
||||
- (void)removeShortsCellAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[self deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
|
||||
}
|
||||
%end
|
||||
|
||||
// Shorts Progress Bar (https://github.com/PoomSmart/YTShortsProgress)
|
||||
%hook YTReelPlayerViewController
|
||||
- (BOOL)shouldEnablePlayerBar { return kShortsProgress ? YES : NO; }
|
||||
- (BOOL)shouldAlwaysEnablePlayerBar { return kShortsProgress ? YES : NO; }
|
||||
- (BOOL)shouldEnablePlayerBarOnlyOnPause { return kShortsProgress ? NO : YES; }
|
||||
%end
|
||||
|
||||
%hook YTReelPlayerViewControllerSub
|
||||
- (BOOL)shouldEnablePlayerBar { return kShortsProgress ? YES : NO; }
|
||||
- (BOOL)shouldAlwaysEnablePlayerBar { return kShortsProgress ? YES : NO; }
|
||||
- (BOOL)shouldEnablePlayerBarOnlyOnPause { return kShortsProgress ? NO : YES; }
|
||||
%end
|
||||
|
||||
%hook YTColdConfig
|
||||
- (BOOL)iosEnableVideoPlayerScrubber { return kShortsProgress ? YES : NO; }
|
||||
- (BOOL)mobileShortsTabInlined { return kShortsProgress ? YES : NO; }
|
||||
%end
|
||||
|
||||
%hook YTHotConfig
|
||||
- (BOOL)enablePlayerBarForVerticalVideoWhenControlsHiddenInFullscreen { return kShortsProgress ? YES : NO; }
|
||||
%end
|
||||
|
||||
// Dont Startup Shorts
|
||||
%hook YTShortsStartupCoordinator
|
||||
- (id)evaluateResumeToShorts { return kResumeShorts ? nil : %orig; }
|
||||
%end
|
||||
|
||||
// Hide Shorts Elements
|
||||
%hook YTReelPausedStateCarouselView
|
||||
- (void)setPausedStateCarouselVisible:(BOOL)arg1 animated:(BOOL)arg2 { kHideShortsSubscriptions ? %orig(arg1 = NO, arg2) : %orig; }
|
||||
%end
|
||||
|
||||
%hook YTReelWatchPlaybackOverlayView
|
||||
- (void)setReelLikeButton:(id)arg1 { if (!kHideShortsLike) %orig; }
|
||||
- (void)setReelDislikeButton:(id)arg1 { if (!kHideShortsDislike) %orig; }
|
||||
- (void)setViewCommentButton:(id)arg1 { if (!kHideShortsComments) %orig; }
|
||||
- (void)setRemixButton:(id)arg1 { if (!kHideShortsRemix) %orig; }
|
||||
- (void)setShareButton:(id)arg1 { if (!kHideShortsShare) %orig; }
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
|
||||
for (UIView *subview in self.subviews) {
|
||||
if (kHideShortsAvatars && [NSStringFromClass([subview class]) isEqualToString:@"YTELMView"]) {
|
||||
subview.hidden = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
%hook YTReelHeaderView
|
||||
- (void)setTitleLabelVisible:(BOOL)arg1 animated:(BOOL)arg2 { kHideShortsLogo ? %orig(arg1 = NO, arg2) : %orig; }
|
||||
%end
|
||||
|
||||
%hook YTReelTransparentStackView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
if (kHideShortsSearch && self.subviews.count >= 3 && [self.subviews[0].accessibilityIdentifier isEqualToString:@"id.ui.generic.button"]) self.subviews[0].hidden = YES;
|
||||
if (kHideShortsCamera && self.subviews.count >= 3 && [self.subviews[1].accessibilityIdentifier isEqualToString:@"id.ui.generic.button"]) self.subviews[1].hidden = YES;
|
||||
if (kHideShortsMore && self.subviews.count >= 3 && [self.subviews[2].accessibilityIdentifier isEqualToString:@"id.ui.generic.button"]) self.subviews[2].hidden = YES;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook YTReelWatchHeaderView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
if (kHideShortsDescription && [self.subviews[2].accessibilityIdentifier isEqualToString:@"id.reels_smv_player_title_label"]) self.subviews[2].hidden = YES;
|
||||
if (kHideShortsThanks && [self.subviews[self.subviews.count - 3].accessibilityIdentifier isEqualToString:@"id.elements.components.suggested_action"]) self.subviews[self.subviews.count - 3].hidden = YES;
|
||||
if (kHideShortsChannelName) self.subviews[self.subviews.count - 2].hidden = YES;
|
||||
if (kHideShortsAudioTrack) self.subviews.lastObject.hidden = YES;
|
||||
}
|
||||
%end
|
||||
|
||||
// Remove Tabs
|
||||
%hook YTPivotBarView
|
||||
- (void)setRenderer:(YTIPivotBarRenderer *)renderer {
|
||||
NSMutableArray <YTIPivotBarSupportedRenderers *> *items = [renderer itemsArray];
|
||||
|
||||
NSDictionary *identifiersToRemove = @{
|
||||
@"FEshorts": @(kRemoveShorts),
|
||||
@"FEsubscriptions": @(kRemoveSubscriptions),
|
||||
@"FEuploads": @(kRemoveUploads),
|
||||
@"FElibrary": @(kRemoveLibrary)
|
||||
};
|
||||
|
||||
for (NSString *identifier in identifiersToRemove) {
|
||||
BOOL shouldRemoveItem = [identifiersToRemove[identifier] boolValue];
|
||||
NSUInteger index = [items indexOfObjectPassingTest:^BOOL(YTIPivotBarSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
|
||||
if ([identifier isEqualToString:@"FEuploads"]) {
|
||||
return shouldRemoveItem && [[[renderers pivotBarIconOnlyItemRenderer] pivotIdentifier] isEqualToString:identifier];
|
||||
} else {
|
||||
return shouldRemoveItem && [[[renderers pivotBarItemRenderer] pivotIdentifier] isEqualToString:identifier];
|
||||
}
|
||||
}];
|
||||
|
||||
if (index != NSNotFound) {
|
||||
[items removeObjectAtIndex:index];
|
||||
}
|
||||
} %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
// Replace Shorts with Explore tab (https://github.com/PoomSmart/YTReExplore)
|
||||
static void replaceTab(YTIGuideResponse *response) {
|
||||
NSMutableArray <YTIGuideResponseSupportedRenderers *> *renderers = [response itemsArray];
|
||||
for (YTIGuideResponseSupportedRenderers *guideRenderers in renderers) {
|
||||
YTIPivotBarRenderer *pivotBarRenderer = [guideRenderers pivotBarRenderer];
|
||||
NSMutableArray <YTIPivotBarSupportedRenderers *> *items = [pivotBarRenderer itemsArray];
|
||||
NSUInteger shortIndex = [items indexOfObjectPassingTest:^BOOL(YTIPivotBarSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
|
||||
return [[[renderers pivotBarItemRenderer] pivotIdentifier] isEqualToString:@"FEshorts"];
|
||||
}];
|
||||
if (shortIndex != NSNotFound) {
|
||||
[items removeObjectAtIndex:shortIndex];
|
||||
NSUInteger exploreIndex = [items indexOfObjectPassingTest:^BOOL(YTIPivotBarSupportedRenderers *renderers, NSUInteger idx, BOOL *stop) {
|
||||
return [[[renderers pivotBarItemRenderer] pivotIdentifier] isEqualToString:[%c(YTIBrowseRequest) browseIDForExploreTab]];
|
||||
}];
|
||||
if (exploreIndex == NSNotFound) {
|
||||
YTIPivotBarSupportedRenderers *exploreTab = [%c(YTIPivotBarRenderer) pivotSupportedRenderersWithBrowseId:[%c(YTIBrowseRequest) browseIDForExploreTab] title:LOC(@"Explore") iconType:292];
|
||||
[items insertObject:exploreTab atIndex:1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%hook YTGuideServiceCoordinator
|
||||
- (void)handleResponse:(YTIGuideResponse *)response withCompletion:(id)completion {
|
||||
if (kReExplore) replaceTab(response);
|
||||
%orig(response, completion);
|
||||
}
|
||||
- (void)handleResponse:(YTIGuideResponse *)response error:(id)error completion:(id)completion {
|
||||
if (kReExplore) replaceTab(response);
|
||||
%orig(response, error, completion);
|
||||
}
|
||||
%end
|
||||
|
||||
// Hide Tab Labels
|
||||
BOOL hasHomeBar = NO;
|
||||
CGFloat pivotBarViewHeight;
|
||||
|
||||
%hook YTPivotBarView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
pivotBarViewHeight = self.frame.size.height;
|
||||
}
|
||||
%end
|
||||
|
||||
%hook YTPivotBarItemView
|
||||
- (void)layoutSubviews {
|
||||
%orig;
|
||||
|
||||
CGFloat pivotBarAccessibilityControlWidth;
|
||||
|
||||
if (kRemoveLabels) {
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([subview isKindOfClass:objc_lookUpClass("YTPivotBarItemViewAccessibilityControl")]) {
|
||||
pivotBarAccessibilityControlWidth = CGRectGetWidth(subview.frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (UIView *subview in self.subviews) {
|
||||
if ([subview isKindOfClass:objc_lookUpClass("YTQTMButton")]) {
|
||||
for (UIView *buttonSubview in subview.subviews) {
|
||||
if ([buttonSubview isKindOfClass:[UILabel class]]) {
|
||||
[buttonSubview removeFromSuperview];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UIImageView *imageView = nil;
|
||||
for (UIView *buttonSubview in subview.subviews) {
|
||||
if ([buttonSubview isKindOfClass:[UIImageView class]]) {
|
||||
imageView = (UIImageView *)buttonSubview;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (imageView) {
|
||||
CGFloat imageViewHeight = imageView.image.size.height;
|
||||
CGFloat imageViewWidth = imageView.image.size.width;
|
||||
CGRect buttonFrame = subview.frame;
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
UIWindowScene *mainWindowScene = (UIWindowScene *)[[[UIApplication sharedApplication] connectedScenes] anyObject];
|
||||
if (mainWindowScene) {
|
||||
UIEdgeInsets safeAreaInsets = mainWindowScene.windows.firstObject.safeAreaInsets;
|
||||
if (safeAreaInsets.bottom > 0) {
|
||||
hasHomeBar = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CGFloat yOffset = hasHomeBar ? 15.0 : 0.0;
|
||||
CGFloat xOffset = (pivotBarAccessibilityControlWidth - imageViewWidth) / 2.0;
|
||||
|
||||
buttonFrame.origin.y = (pivotBarViewHeight - imageViewHeight - yOffset) / 2.0;
|
||||
buttonFrame.origin.x = xOffset;
|
||||
|
||||
buttonFrame.size.height = imageViewHeight;
|
||||
buttonFrame.size.width = imageViewWidth;
|
||||
|
||||
subview.frame = buttonFrame;
|
||||
subview.bounds = CGRectMake(0, 0, imageViewWidth, imageViewHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
// Startup Tab
|
||||
BOOL isTabSelected = NO;
|
||||
%hook YTPivotBarViewController
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
%orig();
|
||||
|
||||
if (!isTabSelected) {
|
||||
NSString *pivotIdentifier;
|
||||
switch (kPivotIndex) {
|
||||
case 0:
|
||||
pivotIdentifier = @"FEwhat_to_watch";
|
||||
break;
|
||||
case 1:
|
||||
pivotIdentifier = @"FEshorts";
|
||||
break;
|
||||
case 2:
|
||||
pivotIdentifier = @"FEsubscriptions";
|
||||
break;
|
||||
case 3:
|
||||
pivotIdentifier = @"FElibrary";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
[self selectItemWithPivotIdentifier:pivotIdentifier];
|
||||
isTabSelected = YES;
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
static void reloadPrefs() {
|
||||
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"YTLite.plist"];
|
||||
NSDictionary *prefs = [NSDictionary dictionaryWithContentsOfFile:path];
|
||||
|
||||
kNoAds = (prefs[@"noAds"] != nil) ? [prefs[@"noAds"] boolValue] : YES;
|
||||
kBackgroundPlayback = (prefs[@"backgroundPlayback"] != nil) ? [prefs[@"backgroundPlayback"] boolValue] : YES;
|
||||
kNoCast = [prefs[@"noCast"] boolValue] ?: NO;
|
||||
kNoNotifsButton = [prefs[@"removeNotifsButton"] boolValue] ?: NO;
|
||||
kNoSearchButton = [prefs[@"removeSearchButton"] boolValue] ?: NO;
|
||||
kStickyNavbar = [prefs[@"stickyNavbar"] boolValue] ?: NO;
|
||||
kNoSubbar = [prefs[@"noSubbar"] boolValue] ?: NO;
|
||||
kNoYTLogo = [prefs[@"noYTLogo"] boolValue] ?: NO;
|
||||
kHideAutoplay = [prefs[@"hideAutoplay"] boolValue] ?: NO;
|
||||
kHideSubs = [prefs[@"hideSubs"] boolValue] ?: NO;
|
||||
kNoHUDMsgs = [prefs[@"noHUDMsgs"] boolValue] ?: NO;
|
||||
kHidePrevNext = [prefs[@"hidePrevNext"] boolValue] ?: NO;
|
||||
kReplacePrevNext = [prefs[@"replacePrevNext"] boolValue] ?: NO;
|
||||
kNoDarkBg = [prefs[@"noDarkBg"] boolValue] ?: NO;
|
||||
kEndScreenCards = [prefs[@"endScreenCards"] boolValue] ?: NO;
|
||||
kNoFullscreenActions = [prefs[@"noFullscreenActions"] boolValue] ?: NO;
|
||||
kNoRelatedVids = [prefs[@"noRelatedVids"] boolValue] ?: NO;
|
||||
kNoPromotionCards = [prefs[@"noPromotionCards"] boolValue] ?: NO;
|
||||
kNoWatermarks = [prefs[@"noWatermarks"] boolValue] ?: NO;
|
||||
kMiniplayer = [prefs[@"miniplayer"] boolValue] ?: NO;
|
||||
kDisableAutoplay = [prefs[@"disableAutoplay"] boolValue] ?: NO;
|
||||
kNoContentWarning = [prefs[@"noContentWarning"] boolValue] ?: NO;
|
||||
kClassicQuality = [prefs[@"classicQuality"] boolValue] ?: NO;
|
||||
kDontSnapToChapter = [prefs[@"dontSnapToChapter"] boolValue] ?: NO;
|
||||
kRedProgressBar = [prefs[@"redProgressBar"] boolValue] ?: NO;
|
||||
kNoHints = [prefs[@"noHints"] boolValue] ?: NO;
|
||||
kNoFreeZoom = [prefs[@"noFreeZoom"] boolValue] ?: NO;
|
||||
kExitFullscreen = [prefs[@"exitFullscreen"] boolValue] ?: NO;
|
||||
kNoDoubleTapToSeek = [prefs[@"noDoubleTapToSeek"] boolValue] ?: NO;
|
||||
kHideShorts = [prefs[@"hideShorts"] boolValue] ?: NO;
|
||||
kShortsProgress = [prefs[@"shortsProgress"] boolValue] ?: NO;
|
||||
kResumeShorts = [prefs[@"resumeShorts"] boolValue] ?: NO;
|
||||
kHideShortsLogo = [prefs[@"hideShortsLogo"] boolValue] ?: NO;
|
||||
kHideShortsSearch = [prefs[@"hideShortsSearch"] boolValue] ?: NO;
|
||||
kHideShortsCamera = [prefs[@"hideShortsCamera"] boolValue] ?: NO;
|
||||
kHideShortsMore = [prefs[@"hideShortsMore"] boolValue] ?: NO;
|
||||
kHideShortsSubscriptions = [prefs[@"hideShortsSubscriptions"] boolValue] ?: NO;
|
||||
kHideShortsLike = [prefs[@"hideShortsLike"] boolValue] ?: NO;
|
||||
kHideShortsDislike = [prefs[@"hideShortsDislike"] boolValue] ?: NO;
|
||||
kHideShortsComments = [prefs[@"hideShortsComments"] boolValue] ?: NO;
|
||||
kHideShortsRemix = [prefs[@"hideShortsRemix"] boolValue] ?: NO;
|
||||
kHideShortsShare = [prefs[@"hideShortsShare"] boolValue] ?: NO;
|
||||
kHideShortsAvatars = [prefs[@"hideShortsAvatars"] boolValue] ?: NO;
|
||||
kHideShortsThanks = [prefs[@"hideShortsThanks"] boolValue] ?: NO;
|
||||
kHideShortsChannelName = [prefs[@"hideShortsChannelName"] boolValue] ?: NO;
|
||||
kHideShortsDescription = [prefs[@"hideShortsDescription"] boolValue] ?: NO;
|
||||
kHideShortsAudioTrack = [prefs[@"hideShortsAudioTrack"] boolValue] ?: NO;
|
||||
kRemoveLabels = [prefs[@"removeLabels"] boolValue] ?: NO;
|
||||
kReExplore = [prefs[@"reExplore"] boolValue] ?: NO;
|
||||
kRemoveShorts = [prefs[@"removeShorts"] boolValue] ?: NO;
|
||||
kRemoveSubscriptions = [prefs[@"removeSubscriptions"] boolValue] ?: NO;
|
||||
kRemoveUploads = (prefs[@"removeUploads"] != nil) ? [prefs[@"removeUploads"] boolValue] : YES;
|
||||
kRemoveLibrary = [prefs[@"removeLibrary"] boolValue] ?: NO;
|
||||
kPivotIndex = (prefs[@"pivotIndex"] != nil) ? [prefs[@"pivotIndex"] intValue] : 0;
|
||||
kAdvancedMode = [prefs[@"advancedMode"] boolValue] ?: NO;
|
||||
|
||||
NSDictionary *newSettings = @{
|
||||
@"noAds" : @(kNoAds),
|
||||
@"backgroundPlayback" : @(kBackgroundPlayback),
|
||||
@"noCast" : @(kNoCast),
|
||||
@"removeNotifsButton" : @(kNoNotifsButton),
|
||||
@"removeSearchButton" : @(kNoSearchButton),
|
||||
@"stickyNavbar" : @(kStickyNavbar),
|
||||
@"noSubbar" : @(kNoSubbar),
|
||||
@"noYTLogo" : @(kNoYTLogo),
|
||||
@"hideAutoplay" : @(kHideAutoplay),
|
||||
@"hideSubs" : @(kHideSubs),
|
||||
@"noHUDMsgs" : @(kNoHUDMsgs),
|
||||
@"hidePrevNext" : @(kHidePrevNext),
|
||||
@"replacePrevNext" : @(kReplacePrevNext),
|
||||
@"noDarkBg" : @(kNoDarkBg),
|
||||
@"endScreenCards" : @(kEndScreenCards),
|
||||
@"noFullscreenActions" : @(kNoFullscreenActions),
|
||||
@"noRelatedVids" : @(kNoRelatedVids),
|
||||
@"noPromotionCards" : @(kNoPromotionCards),
|
||||
@"noWatermarks" : @(kNoWatermarks),
|
||||
@"miniplayer" : @(kMiniplayer),
|
||||
@"disableAutoplay" : @(kDisableAutoplay),
|
||||
@"noContentWarning" : @(kNoContentWarning),
|
||||
@"classicQuality" : @(kClassicQuality),
|
||||
@"dontSnapToChapter" : @(kDontSnapToChapter),
|
||||
@"redProgressBar" : @(kRedProgressBar),
|
||||
@"noHints" : @(kNoHints),
|
||||
@"noFreeZoom" : @(kNoFreeZoom),
|
||||
@"exitFullscreen" : @(kExitFullscreen),
|
||||
@"noDoubleTapToSeek" : @(kNoDoubleTapToSeek),
|
||||
@"hideShorts" : @(kHideShorts),
|
||||
@"shortsProgress" : @(kShortsProgress),
|
||||
@"resumeShorts" : @(kResumeShorts),
|
||||
@"hideShortsLogo" : @(kHideShortsLogo),
|
||||
@"hideShortsSearch" : @(kHideShortsSearch),
|
||||
@"hideShortsCamera" : @(kHideShortsCamera),
|
||||
@"hideShortsMore" : @(kHideShortsMore),
|
||||
@"hideShortsSubscriptions" : @(kHideShortsSubscriptions),
|
||||
@"hideShortsLike" : @(kHideShortsLike),
|
||||
@"hideShortsDislike" : @(kHideShortsDislike),
|
||||
@"hideShortsComments" : @(kHideShortsComments),
|
||||
@"hideShortsRemix" : @(kHideShortsRemix),
|
||||
@"hideShortsShare" : @(kHideShortsShare),
|
||||
@"hideShortsAvatars" : @(kHideShortsAvatars),
|
||||
@"hideShortsThanks" : @(kHideShortsThanks),
|
||||
@"hideShortsChannelName" : @(kHideShortsChannelName),
|
||||
@"hideShortsDescription" : @(kHideShortsDescription),
|
||||
@"hideShortsAudioTrack" : @(kHideShortsAudioTrack),
|
||||
@"removeLabels" : @(kRemoveLabels),
|
||||
@"reExplore" : @(kReExplore),
|
||||
@"removeShorts" : @(kRemoveShorts),
|
||||
@"removeSubscriptions" : @(kRemoveSubscriptions),
|
||||
@"removeUploads" : @(kRemoveUploads),
|
||||
@"removeLibrary" : @(kRemoveLibrary),
|
||||
@"pivotIndex" : @(kPivotIndex),
|
||||
@"advancedMode" : @(kAdvancedMode)
|
||||
};
|
||||
|
||||
if (![newSettings isEqualToDictionary:prefs]) [newSettings writeToFile:path atomically:NO];
|
||||
}
|
||||
|
||||
static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
|
||||
reloadPrefs();
|
||||
}
|
||||
|
||||
%ctor {
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)prefsChanged, CFSTR("com.dvntm.ytlite.prefschanged"), NULL, CFNotificationSuspensionBehaviorCoalesce);
|
||||
reloadPrefs();
|
||||
}
|
Reference in New Issue
Block a user