Initial release

This commit is contained in:
dayanch96
2023-06-18 18:53:30 +03:00
parent 856886821d
commit e3c33adb01
11 changed files with 657 additions and 0 deletions
+18
View File
@@ -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
+226
View File
@@ -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 <YTSettingsSectionItem *> *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 <YTSettingsSectionItem *> *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 <YTSettingsSectionItem *> *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 <YTSettingsSectionItem *> *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
+41
View File
@@ -0,0 +1,41 @@
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <rootless.h>
#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
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Filter</key>
<dict>
<key>Bundles</key>
<array>
<string>com.google.ios.youtube</string>
</array>
</dict>
</dict>
</plist>
+266
View File
@@ -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 <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
// 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
// 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;
}
+9
View File
@@ -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
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleIdentifier</key>
<string>com.dvntm.ytlite</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>YTLite</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>YTLite</string>
</dict>
</plist>
@@ -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";
@@ -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" = "Разработчик твика";
Binary file not shown.
Binary file not shown.