diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..03cdcce --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +ifeq ($(ROOTLESS),1) +THEOS_PACKAGE_SCHEME=rootless +endif + +DEBUG=0 +FINALPACKAGE=1 +ARCHS = arm64 +PACKAGE_VERSION = 1.0 +TARGET := iphone:clang:latest:11.0 + +include $(THEOS)/makefiles/common.mk + +TWEAK_NAME = YTLite +$(TWEAK_NAME)_FRAMEWORKS = UIKit Foundation +$(TWEAK_NAME)_CFLAGS = -fobjc-arc -DTWEAK_VERSION=$(PACKAGE_VERSION) +$(TWEAK_NAME)_FILES = YTLite.x Settings.x + +include $(THEOS_MAKE_PATH)/tweak.mk diff --git a/Settings.x b/Settings.x new file mode 100644 index 0000000..bcdc53a --- /dev/null +++ b/Settings.x @@ -0,0 +1,226 @@ +#import "YTLite.h" + +@interface YTSettingsSectionItemManager (YTLite) +- (void)updateYTLiteSectionWithEntry:(id)entry; +@end + +static const NSInteger YTLiteSection = 789; + +NSBundle *YTLiteBundle() { + static NSBundle *bundle = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *tweakBundlePath = [[NSBundle mainBundle] pathForResource:@"YTLite" ofType:@"bundle"]; + if (tweakBundlePath) + bundle = [NSBundle bundleWithPath:tweakBundlePath]; + else + bundle = [NSBundle bundleWithPath:ROOT_PATH_NS("/Library/Application Support/YTLite.bundle")]; + }); + return bundle; +} + +// Settings +%hook YTAppSettingsPresentationData ++ (NSArray *)settingsCategoryOrder { + NSArray *order = %orig; + NSMutableArray *mutableOrder = [order mutableCopy]; + NSUInteger insertIndex = [order indexOfObject:@(1)]; + if (insertIndex != NSNotFound) + [mutableOrder insertObject:@(YTLiteSection) atIndex:insertIndex + 1]; + return mutableOrder; +} +%end + +%hook YTSettingsSectionController +- (void)setSelectedItem:(NSUInteger)selectedItem { + if (selectedItem != NSNotFound) %orig; +} +%end + +%hook YTSettingsSectionItemManager +%new +- (void)updatePrefsForKey:(NSString *)key enabled:(BOOL)enabled { + NSString *prefsPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"YTLite.plist"]; + NSMutableDictionary *prefs = [NSMutableDictionary dictionaryWithContentsOfFile:prefsPath]; + + if (!prefs) prefs = [NSMutableDictionary dictionary]; + + [prefs setObject:@(enabled) forKey:key]; + [prefs writeToFile:prefsPath atomically:NO]; + + CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFSTR("com.dvntm.ytlite.prefschanged"), NULL, NULL, YES); +} + +%new(v@:@) +- (void)updateYTLiteSectionWithEntry:(id)entry { + NSMutableArray *sectionItems = [NSMutableArray array]; + Class YTSettingsSectionItemClass = %c(YTSettingsSectionItem); + YTSettingsViewController *settingsViewController = [self valueForKey:@"_settingsViewControllerDelegate"]; + + YTSettingsSectionItem *general = [YTSettingsSectionItemClass itemWithTitle:LOC(@"General") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return @"‣"; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"RemoveAds") + titleDescription:LOC(@"RemoveAdsDesc") + accessibilityIdentifier:nil + switchOn:kNoAds + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"noAds" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"BackgroundPlayback") + titleDescription:LOC(@"BackgroundPlaybackDesc") + accessibilityIdentifier:nil + switchOn:kBackgroundPlayback + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"backgroundPlayback" enabled:enabled]; + return YES; + } + settingItemId:0] + ]; + + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"General") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + }]; + [sectionItems addObject:general]; + + YTSettingsSectionItem *navbar = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Navbar") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return @"‣"; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"RemoveCast") + titleDescription:LOC(@"RemoveCastDesc") + accessibilityIdentifier:nil + switchOn:kNoCast + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"noCast" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"RemoveNotifications") + titleDescription:LOC(@"RemoveNotificationsDesc") + accessibilityIdentifier:nil + switchOn:kNoNotifsButton + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeNotifsButton" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"RemoveSearch") + titleDescription:LOC(@"RemoveSearchDesc") + accessibilityIdentifier:nil + switchOn:kNoSearchButton + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeSearchButton" enabled:enabled]; + return YES; + } + settingItemId:0] + ]; + + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Navbar") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + }]; + [sectionItems addObject:navbar]; + + YTSettingsSectionItem *tabbar = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Tabbar") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return @"‣"; + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"RemoveLabels") + titleDescription:LOC(@"RemoveLabelsDesc") + accessibilityIdentifier:nil + switchOn:kRemoveLabels + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeLabels" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"HideShortsTab") + titleDescription:LOC(@"HideShortsTabDesc") + accessibilityIdentifier:nil + switchOn:kRemoveShorts + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeShorts" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"HideSubscriptionsTab") + titleDescription:LOC(@"HideSubscriptionsTabDesc") + accessibilityIdentifier:nil + switchOn:kRemoveSubscriptions + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeSubscriptions" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"HideUploadButton") + titleDescription:LOC(@"HideUploadButtonDesc") + accessibilityIdentifier:nil + switchOn:kRemoveUploads + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeUploads" enabled:enabled]; + return YES; + } + settingItemId:0], + [YTSettingsSectionItemClass switchItemWithTitle:LOC(@"HideLibraryTab") + titleDescription:LOC(@"HideLibraryTabDesc") + accessibilityIdentifier:nil + switchOn:kRemoveLibrary + switchBlock:^BOOL (YTSettingsCell *cell, BOOL enabled) { + [self updatePrefsForKey:@"removeLibrary" enabled:enabled]; + return YES; + } + settingItemId:0] + ]; + + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"Tabbar") pickerSectionTitle:nil rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + }]; + [sectionItems addObject:tabbar]; + + YTSettingsSectionItem *ps = [%c(YTSettingsSectionItem) itemWithTitle:@"PoomSmart" titleDescription:@"YouTube-X, YTNoPremium, YouTubeHeaders" accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/PoomSmart/"]]; + }]; + + YTSettingsSectionItem *dayanch96 = [%c(YTSettingsSectionItem) itemWithTitle:@"Dayanch96" titleDescription:LOC(@"Developer") accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + return [%c(YTUIUtils) openURL:[NSURL URLWithString:@"https://github.com/Dayanch96/"]]; + }]; + + YTSettingsSectionItem *version = [YTSettingsSectionItemClass itemWithTitle:LOC(@"Version") + accessibilityIdentifier:nil + detailTextBlock:^NSString *() { + return @(OS_STRINGIFY(TWEAK_VERSION)); + } + selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) { + NSArray *rows = @[ps, dayanch96]; + + YTSettingsPickerViewController *picker = [[%c(YTSettingsPickerViewController) alloc] initWithNavTitle:LOC(@"About") pickerSectionTitle:LOC(@"Credits") rows:rows selectedItemIndex:NSNotFound parentResponder:[self parentResponder]]; + [settingsViewController pushViewController:picker]; + return YES; + }]; + [sectionItems addObject:version]; + + [settingsViewController setSectionItems:sectionItems forCategory:YTLiteSection title:@"YTLite" titleDescription:nil headerHidden:NO]; +} + +- (void)updateSectionForCategory:(NSUInteger)category withEntry:(id)entry { + if (category == YTLiteSection) { + [self updateYTLiteSectionWithEntry:entry]; + return; + } %orig; +} +%end \ No newline at end of file diff --git a/YTLite.h b/YTLite.h new file mode 100644 index 0000000..4824381 --- /dev/null +++ b/YTLite.h @@ -0,0 +1,41 @@ +#import +#import +#import +#import "../YouTubeHeader/YTIPivotBarSupportedRenderers.h" +#import "../YouTubeHeader/YTIPivotBarRenderer.h" +#import "../YouTubeHeader/YTISectionListRenderer.h" +#import "../YouTubeHeader/YTQTMButton.h" +#import "../YouTubeHeader/YTSettingsViewController.h" +#import "../YouTubeHeader/YTSettingsSectionItem.h" +#import "../YouTubeHeader/YTSettingsSectionItemManager.h" +#import "../YouTubeHeader/YTSettingsPickerViewController.h" +#import "../YouTubeHeader/YTUIUtils.h" + +extern NSBundle *YTLiteBundle(); + +static inline NSString *LOC(NSString *key) { + NSBundle *tweakBundle = YTLiteBundle(); + return [tweakBundle localizedStringForKey:key value:nil table:nil]; +} + +BOOL kNoAds; +BOOL kBackgroundPlayback; +BOOL kNoCast; +BOOL kNoNotifsButton; +BOOL kNoSearchButton; +BOOL kRemoveLabels; +BOOL kRemoveShorts; +BOOL kRemoveSubscriptions; +BOOL kRemoveUploads; +BOOL kRemoveLibrary; + +@interface YTPivotBarView : UIView +@end + +@interface YTPivotBarItemView : UIView +@end + +@interface YTRightNavigationButtons : UIView +@property (nonatomic, strong) YTQTMButton *notificationButton; +@property (nonatomic, strong) YTQTMButton *searchButton; +@end diff --git a/YTLite.plist b/YTLite.plist new file mode 100644 index 0000000..d036024 --- /dev/null +++ b/YTLite.plist @@ -0,0 +1,13 @@ + + + + + Filter + + Bundles + + com.google.ios.youtube + + + + diff --git a/YTLite.x b/YTLite.x new file mode 100644 index 0000000..a4bb1b2 --- /dev/null +++ b/YTLite.x @@ -0,0 +1,266 @@ +#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 *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 + +// Remove Tabs +%hook YTPivotBarView +- (void)setRenderer:(YTIPivotBarRenderer *)renderer { + NSMutableArray *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 + +// 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:NSClassFromString(@"YTPivotBarItemViewAccessibilityControl")]) { + pivotBarAccessibilityControlWidth = CGRectGetWidth(subview.frame); + break; + } + } + + for (UIView *subview in self.subviews) { + if ([subview isKindOfClass:NSClassFromString(@"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 + +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; + kRemoveLabels = [prefs[@"removeLabels"] 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; + + NSDictionary *newSettings = @{ + @"noAds" : @(kNoAds), + @"backgroundPlayback" : @(kBackgroundPlayback), + @"noCast" : @(kNoCast), + @"removeNotifsButton" : @(kNoNotifsButton), + @"removeSearchButton" : @(kNoSearchButton), + @"removeLabels" : @(kRemoveLabels), + @"removeShorts" : @(kRemoveShorts), + @"removeSubscriptions" : @(kRemoveSubscriptions), + @"removeUploads" : @(kRemoveUploads), + @"removeLibrary" : @(kRemoveLibrary) + }; + + 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(); + %init; +} diff --git a/control b/control new file mode 100644 index 0000000..bcca9d9 --- /dev/null +++ b/control @@ -0,0 +1,9 @@ +Package: com.dvntm.ytlite +Name: YTLite +Depends: mobilesubstrate +Version: 0.0.1 +Architecture: iphoneos-arm +Description: Lightweight YouTube Enhancer +Maintainer: dvntm +Author: dvntm +Section: Tweaks diff --git a/layout/Library/Application Support/YTLite.bundle/Info.plist b/layout/Library/Application Support/YTLite.bundle/Info.plist new file mode 100644 index 0000000..fa80b7d --- /dev/null +++ b/layout/Library/Application Support/YTLite.bundle/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleShortVersionString + 1.0.0 + CFBundleIdentifier + com.dvntm.ytlite + CFBundleSignature + ???? + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + English + CFBundleExecutable + YTLite + CFBundlePackageType + BNDL + CFBundleVersion + 1.0 + NSPrincipalClass + YTLite + + diff --git a/layout/Library/Application Support/YTLite.bundle/en.lproj/Localizable.strings b/layout/Library/Application Support/YTLite.bundle/en.lproj/Localizable.strings new file mode 100644 index 0000000..56893ac --- /dev/null +++ b/layout/Library/Application Support/YTLite.bundle/en.lproj/Localizable.strings @@ -0,0 +1,30 @@ +"General" = "General"; +"RemoveAds" = "Remove ads"; +"RemoveAdsDesc" = "Removes in-app ads."; +"BackgroundPlayback" = "Background playback"; +"BackgroundPlaybackDesc" = "Enables background playback."; + +"Navbar" = "Navigation bar"; +"RemoveCast" = "Hide Cast button"; +"RemoveCastDesc" = "Hides Cast button from the Navigation bar."; +"RemoveNotifications" = "Hide Notifications button"; +"RemoveNotificationsDesc" = "Hides Notifications button from the Navigation bar."; +"RemoveSearch" = "Hide Search button"; +"RemoveSearchDesc" = "Hides Search button from the Navigation bar."; + +"Tabbar" = "Tab bar"; +"RemoveLabels" = "Remove labels"; +"RemoveLabelsDesc" = "Removes tab labels."; +"HideShortsTab" = "Hide Shorts tab"; +"HideShortsTabDesc" = "Hides Shorts tab from the Tab bar"; +"HideSubscriptionsTab" = "Hide Subscriptions tab"; +"HideSubscriptionsTabDesc" = "Hides Subscriptions tab from the Tab bar"; +"HideUploadButton" = "Hide Upload button"; +"HideUploadButtonDesc" = "Hides Upload button from the Tab bar"; +"HideLibraryTab" = "Hide Library tab"; +"HideLibraryTabDesc" = "Hides Library tab from the Tab bar"; + +"Version" = "Version"; +"About" = "About"; +"Credits" = "Credits"; +"Developer" = "YTLite developer"; \ No newline at end of file diff --git a/layout/Library/Application Support/YTLite.bundle/ru.lproj/Localizable.strings b/layout/Library/Application Support/YTLite.bundle/ru.lproj/Localizable.strings new file mode 100644 index 0000000..c05defb --- /dev/null +++ b/layout/Library/Application Support/YTLite.bundle/ru.lproj/Localizable.strings @@ -0,0 +1,30 @@ +"General" = "Основные"; +"RemoveAds" = "Убрать рекламу"; +"RemoveAdsDesc" = "Убирает рекламу в приложении."; +"BackgroundPlayback" = "Фоновое воспроизведение"; +"BackgroundPlaybackDesc" = "Активирует фоновое воспроизведение."; + +"Navbar" = "Панель навигации"; +"RemoveCast" = "Скрыть «Трансляция»"; +"RemoveCastDesc" = "Скрывает кнопку трансляции с панели навигации."; +"RemoveNotifications" = "Скрыть «Уведомления»"; +"RemoveNotificationsDesc" = "Скрывает кнопку уведомлений с панели навигации."; +"RemoveSearch" = "Скрыть «Поиск»"; +"RemoveSearchDesc" = "Скрвыает кнопку поиска с панели навигации."; + +"Tabbar" = "Панель вкладок"; +"RemoveLabels" = "Скрыть названия"; +"RemoveLabelsDesc" = "Скрывает названия вкладок."; +"HideShortsTab" = "Скрыть «Shorts»"; +"HideShortsTabDesc" = "Скрывает вкладку «Shorts» с панели вкладок."; +"HideSubscriptionsTab" = "Скрыть «Подписки»"; +"HideSubscriptionsTabDesc" = "Скрывает вкладку «Подписки» с панели вкладок."; +"HideUploadButton" = "Скрыть «Создать» (+)"; +"HideUploadButtonDesc" = "Скрывает кнопку «Создать» с панели вкладок."; +"HideLibraryTab" = "Скрыть «Библиотеку»"; +"HideLibraryTabDesc" = "Скрывает вкладку «Библиотека» с панели вкладок."; + +"Version" = "Версия"; +"About" = "О твике"; +"Credits" = "Авторы"; +"Developer" = "Разработчик твика"; diff --git a/packages/com.dvntm.ytlite_1.0_iphoneos-arm.deb b/packages/com.dvntm.ytlite_1.0_iphoneos-arm.deb new file mode 100644 index 0000000..1ae1080 Binary files /dev/null and b/packages/com.dvntm.ytlite_1.0_iphoneos-arm.deb differ diff --git a/packages/com.dvntm.ytlite_1.0_iphoneos-arm64.deb b/packages/com.dvntm.ytlite_1.0_iphoneos-arm64.deb new file mode 100644 index 0000000..408d8a0 Binary files /dev/null and b/packages/com.dvntm.ytlite_1.0_iphoneos-arm64.deb differ