Skip to content

Commit dff35cb

Browse files
committed
Timestamped Links, Tabbar Indicators, More ads
1 parent 245baff commit dff35cb

13 files changed

Lines changed: 76 additions & 17 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ endif
55
DEBUG=0
66
FINALPACKAGE=1
77
ARCHS = arm64
8-
PACKAGE_VERSION = 2.3.1
8+
PACKAGE_VERSION = 2.4
99
TARGET := iphone:clang:latest:11.0
1010

1111
include $(THEOS)/makefiles/common.mk

Settings.x

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@
66

77
static const NSInteger YTLiteSection = 789;
88

9-
static void resetYTLiteSettings() {
10-
NSString *prefsPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"YTLite.plist"];
11-
[[NSFileManager defaultManager] removeItemAtPath:prefsPath error:nil];
12-
13-
[[UIApplication sharedApplication] performSelector:@selector(suspend)];
14-
[NSThread sleepForTimeInterval:1.0];
15-
exit(0);
16-
}
17-
189
NSBundle *YTLiteBundle() {
1910
static NSBundle *bundle = nil;
2011
static dispatch_once_t onceToken;
@@ -179,6 +170,7 @@ static YTSettingsSectionItem *createSwitchItem(NSString *title, NSString *titleD
179170
NSArray <YTSettingsSectionItem *> *rows = @[
180171
createSwitchItem(LOC(@"Miniplayer"), LOC(@"MiniplayerDesc"), @"miniplayer", &kMiniplayer, selfObject),
181172
createSwitchItem(LOC(@"PortraitFullscreen"), LOC(@"PortraitFullscreenDesc"), @"portraitFullscreen", &kPortraitFullscreen, selfObject),
173+
createSwitchItem(LOC(@"CopyWithTimestamp"), LOC(@"CopyWithTimestampDesc"), @"copyWithTimestamp", &kCopyWithTimestamp, selfObject),
182174
createSwitchItem(LOC(@"DisableAutoplay"), LOC(@"DisableAutoplayDesc"), @"disableAutoplay", &kDisableAutoplay, selfObject),
183175
createSwitchItem(LOC(@"NoContentWarning"), LOC(@"NoContentWarningDesc"), @"noContentWarning", &kNoContentWarning, selfObject),
184176
createSwitchItem(LOC(@"ClassicQuality"), LOC(@"ClassicQualityDesc"), @"classicQuality", &kClassicQuality, selfObject),
@@ -240,6 +232,7 @@ static YTSettingsSectionItem *createSwitchItem(NSString *title, NSString *titleD
240232
selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
241233
NSArray <YTSettingsSectionItem *> *rows = @[
242234
createSwitchItem(LOC(@"RemoveLabels"), LOC(@"RemoveLabelsDesc"), @"removeLabels", &kRemoveLabels, selfObject),
235+
createSwitchItem(LOC(@"RemoveIndicators"), LOC(@"RemoveIndicatorsDesc"), @"removeIndicators", &kRemoveIndicators, selfObject),
243236
createSwitchItem(LOC(@"ReExplore"), LOC(@"ReExploreDesc"), @"reExplore", &kReExplore, selfObject),
244237
createSwitchItem(LOC(@"HideShortsTab"), LOC(@"HideShortsTabDesc"), @"removeShorts", &kRemoveShorts, selfObject),
245238
createSwitchItem(LOC(@"HideSubscriptionsTab"), LOC(@"HideSubscriptionsTabDesc"), @"removeSubscriptions", &kRemoveSubscriptions, selfObject),
@@ -392,7 +385,12 @@ static YTSettingsSectionItem *createSwitchItem(NSString *title, NSString *titleD
392385

393386
YTSettingsSectionItem *reset = [%c(YTSettingsSectionItem) itemWithTitle:LOC(@"ResetSettings") titleDescription:nil accessibilityIdentifier:nil detailTextBlock:nil selectBlock:^BOOL (YTSettingsCell *cell, NSUInteger arg1) {
394387
YTAlertView *alertView = [%c(YTAlertView) confirmationDialogWithAction:^{
395-
resetYTLiteSettings();
388+
NSString *prefsPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"YTLite.plist"];
389+
[[NSFileManager defaultManager] removeItemAtPath:prefsPath error:nil];
390+
391+
[[UIApplication sharedApplication] performSelector:@selector(suspend)];
392+
[NSThread sleepForTimeInterval:1.0];
393+
exit(0);
396394
}
397395
actionTitle:LOC(@"Yes")
398396
cancelTitle:LOC(@"No")];

YTLite.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ BOOL kNoPromotionCards;
4949
BOOL kNoWatermarks;
5050
BOOL kMiniplayer;
5151
BOOL kPortraitFullscreen;
52+
BOOL kCopyWithTimestamp;
5253
BOOL kDisableAutoplay;
5354
BOOL kNoContentWarning;
5455
BOOL kClassicQuality;
@@ -80,6 +81,7 @@ BOOL kHideShortsDescription;
8081
BOOL kHideShortsAudioTrack;
8182
BOOL kHideShortsPromoCards;
8283
BOOL kRemoveLabels;
84+
BOOL kRemoveIndicators;
8385
BOOL kReExplore;
8486
BOOL kRemoveShorts;
8587
BOOL kRemoveSubscriptions;
@@ -169,6 +171,9 @@ int kPivotIndex;
169171
@interface YTELMView : UIView
170172
@end
171173

174+
@interface _ASDisplayView : UIView
175+
@end
176+
172177
@interface MLHAMQueuePlayer : NSObject
173178
@property id playerEventCenter;
174179
-(void)setRate:(float)rate;
@@ -192,4 +197,9 @@ int kPivotIndex;
192197
+ (instancetype)infoDialog;
193198
+ (instancetype)confirmationDialogWithAction:(void (^)(void))action actionTitle:(NSString *)actionTitle cancelTitle:(NSString *)cancelTitle;
194199
- (void)show;
200+
@end
201+
202+
@interface YTMainAppVideoPlayerOverlayViewController : UIViewController
203+
@property (readonly, nonatomic) CGFloat mediaTime;
204+
@property (readonly, nonatomic) NSString *videoID;
195205
@end

YTLite.x

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
- (NSData *)elementData {
3333
if (self.hasCompatibilityOptions && self.compatibilityOptions.hasAdLoggingData && kNoAds) return nil;
3434

35-
NSArray *adDescriptions = @[@"brand_promo", @"product_carousel", @"product_engagement_panel", @"product_item", @"text_search_ad", @"text_image_button_layout", @"carousel_headered_layout", @"square_image_layout", @"feed_ad_metadata"];
35+
NSArray *adDescriptions = @[@"brand_promo", @"product_carousel", @"product_engagement_panel", @"product_item", @"text_search_ad", @"text_image_button_layout", @"carousel_headered_layout", @"carousel_footered_layout", @"square_image_layout", @"landscape_image_wide_button_layout", @"feed_ad_metadata"];
3636
NSString *description = [self description];
3737
if (([adDescriptions containsObject:description] && kNoAds) || ([description containsString:@"inline_shorts"] && kHideShorts)) {
3838
return [NSData data];
@@ -389,9 +389,22 @@
389389
- (BOOL)shouldExitFullScreenOnFinish { return kExitFullscreen ? YES : NO; }
390390
%end
391391

392-
// Disable Double Tap To Seek
393392
%hook YTMainAppVideoPlayerOverlayViewController
393+
// Disable Double Tap To Seek
394394
- (BOOL)allowDoubleTapToSeekGestureRecognizer { return kNoDoubleTapToSeek ? NO : %orig; }
395+
396+
// Copy Timestamped Link by Pressing On Pause
397+
- (void)didPressPause:(id)arg1 {
398+
%orig;
399+
400+
if (kCopyWithTimestamp) {
401+
NSInteger mediaTimeInteger = (NSInteger)self.mediaTime;
402+
NSString *currentTimeLink = [NSString stringWithFormat:@"https://www.youtube.com/watch?v=%@&t=%lds", self.videoID, mediaTimeInteger];
403+
404+
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
405+
pasteboard.string = currentTimeLink;
406+
}
407+
}
395408
%end
396409

397410
// Fit 'Play All' Buttons Text For Localizations
@@ -528,7 +541,6 @@
528541
- (void)layoutSubviews {
529542
%orig;
530543
if (kHideShortsDescription && [self.subviews[2].accessibilityIdentifier isEqualToString:@"id.reels_smv_player_title_label"]) self.subviews[2].hidden = YES;
531-
if (kHideShortsThanks && [self.subviews[self.subviews.count - 3].accessibilityIdentifier isEqualToString:@"id.elements.components.suggested_action"]) self.subviews[self.subviews.count - 3].hidden = YES; // Might be useful for older versions
532544
if (kHideShortsChannelName) self.subviews[self.subviews.count - 2].hidden = YES;
533545
if (kHideShortsAudioTrack) self.subviews.lastObject.hidden = YES;
534546
for (UIView *subview in self.subviews) {
@@ -539,10 +551,11 @@
539551
}
540552
%end
541553

542-
%hook YTELMView
554+
555+
%hook _ASDisplayView
543556
- (void)layoutSubviews {
544557
%orig;
545-
if (kHideShortsThanks && [self.subviews.firstObject.accessibilityIdentifier isEqualToString:@"id.elements.components.suggested_action"]) self.subviews.firstObject.hidden = YES;
558+
if (kHideShortsThanks && [self.accessibilityIdentifier isEqualToString:@"id.elements.components.suggested_action"]) self.hidden = YES;
546559
}
547560
%end
548561

@@ -608,6 +621,12 @@ static void replaceTab(YTIGuideResponse *response) {
608621
}
609622
%end
610623

624+
// Hide Tab Bar Indicators
625+
%hook YTPivotBarIndicatorView
626+
- (void)setFillColor:(id)arg1 { %orig(kRemoveIndicators ? [UIColor clearColor] : arg1); }
627+
- (void)setBorderColor:(id)arg1 { %orig(kRemoveIndicators ? [UIColor clearColor] : arg1); }
628+
%end
629+
611630
// Hide Tab Labels
612631
BOOL hasHomeBar = NO;
613632
CGFloat pivotBarViewHeight;
@@ -745,6 +764,7 @@ static void reloadPrefs() {
745764
kNoWatermarks = [prefs[@"noWatermarks"] boolValue] ?: NO;
746765
kMiniplayer = [prefs[@"miniplayer"] boolValue] ?: NO;
747766
kPortraitFullscreen = [prefs[@"portraitFullscreen"] boolValue] ?: NO;
767+
kCopyWithTimestamp = [prefs[@"copyWithTimestamp"] boolValue] ?: NO;
748768
kDisableAutoplay = [prefs[@"disableAutoplay"] boolValue] ?: NO;
749769
kNoContentWarning = [prefs[@"noContentWarning"] boolValue] ?: NO;
750770
kClassicQuality = [prefs[@"classicQuality"] boolValue] ?: NO;
@@ -776,6 +796,7 @@ static void reloadPrefs() {
776796
kHideShortsAudioTrack = [prefs[@"hideShortsAudioTrack"] boolValue] ?: NO;
777797
kHideShortsPromoCards = [prefs[@"hideShortsPromoCards"] boolValue] ?: NO;
778798
kRemoveLabels = [prefs[@"removeLabels"] boolValue] ?: NO;
799+
kRemoveIndicators = [prefs[@"removeIndicators"] boolValue] ?: NO;
779800
kReExplore = [prefs[@"reExplore"] boolValue] ?: NO;
780801
kRemoveShorts = [prefs[@"removeShorts"] boolValue] ?: NO;
781802
kRemoveSubscriptions = [prefs[@"removeSubscriptions"] boolValue] ?: NO;
@@ -816,6 +837,7 @@ static void reloadPrefs() {
816837
@"noWatermarks" : @(kNoWatermarks),
817838
@"miniplayer" : @(kMiniplayer),
818839
@"portraitFullscreen" : @(kPortraitFullscreen),
840+
@"copyWithTimestamp" : @(kCopyWithTimestamp),
819841
@"disableAutoplay" : @(kDisableAutoplay),
820842
@"noContentWarning" : @(kNoContentWarning),
821843
@"classicQuality" : @(kClassicQuality),
@@ -847,6 +869,7 @@ static void reloadPrefs() {
847869
@"hideShortsAudioTrack" : @(kHideShortsAudioTrack),
848870
@"hideShortsPromoCards" : @(kHideShortsPromoCards),
849871
@"removeLabels" : @(kRemoveLabels),
872+
@"removeIndicators" : @(kRemoveIndicators),
850873
@"reExplore" : @(kReExplore),
851874
@"removeShorts" : @(kRemoveShorts),
852875
@"removeSubscriptions" : @(kRemoveSubscriptions),

layout/Library/Application Support/YTLite.bundle/en.lproj/Localizable.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "Enables the mini player for videos that were not originally designed for it, such as videos targeted for children.";
5050
"PortraitFullscreen" = "Portrait fullscreen mode";
5151
"PortraitFullscreenDesc" = "Enables portrait fullscreen mode support.";
52+
"CopyWithTimestamp" = "Copy timestamped links";
53+
"CopyWithTimestampDesc" = "Allows to copy timestamped link to the clipboard by pressing pause button.";
5254
"DisableAutoplay" = "Disable Autoplay videos";
5355
"DisableAutoplayDesc" = "Prevents video playback after opening.";
5456
"NoContentWarning" = "Skip content warning";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "Tab bar";
7678
"RemoveLabels" = "Remove labels";
7779
"RemoveLabelsDesc" = "Removes tab labels.";
80+
"RemoveIndicators" = "Remove indicators";
81+
"RemoveIndicatorsDesc" = "Removes tab indicators.";
7882
"ReExplore" = "Replace Shorts tab with Explore tab";
7983
"ReExploreDesc" = "Shows Explore tab instead of Shorts tab as on old YouTube versions.";
8084
"HideShortsTab" = "Hide Shorts tab";

layout/Library/Application Support/YTLite.bundle/es.lproj/Localizable.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "Activa el mini reproductor para vídeos que no fueron diseñados originalmente para ello, como los vídeos dirigidos a niños.";
5050
"PortraitFullscreen" = "Modo de pantalla completa vertical";
5151
"PortraitFullscreenDesc" = "Activa el modo de pantalla completa vertical.";
52+
"CopyWithTimestamp" = "Copy timestamped links";
53+
"CopyWithTimestampDesc" = "Allows to copy timestamped link to the clipboard by pressing pause button.";
5254
"DisableAutoplay" = "Desactivar reproducción automática";
5355
"DisableAutoplayDesc" = "Evita la reproducción automática de vídeos después de abrirlos.";
5456
"NoContentWarning" = "Omitir advertencia de contenido";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "Barra de pestañas";
7678
"RemoveLabels" = "Eliminar etiquetas";
7779
"RemoveLabelsDesc" = "Elimina las etiquetas de las pestañas.";
80+
"RemoveIndicators" = "Remove indicators";
81+
"RemoveIndicatorsDesc" = "Removes tab indicators.";
7882
"ReExplore" = "Reemplazar pestaña Shorts con pestaña Explorar";
7983
"ReExploreDesc" = "Muestra la pestaña Explorar en lugar de la pestaña Shorts como en versiones antiguas de YouTube.";
8084
"HideShortsTab" = "Ocultar pestaña Shorts";

layout/Library/Application Support/YTLite.bundle/fr.lproj/Localizable.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "Active le mini-lecteur pour les vidéos qui n'étaient pas initialement conçues pour cela, comme les vidéos destinées aux enfants.";
5050
"PortraitFullscreen" = "Mode plein écran en portrait";
5151
"PortraitFullscreenDesc" = "Active la prise en charge du mode plein écran en portrait.";
52+
"CopyWithTimestamp" = "Copy timestamped links";
53+
"CopyWithTimestampDesc" = "Allows to copy timestamped link to the clipboard by pressing pause button.";
5254
"DisableAutoplay" = "Désactiver la lecture automatique des vidéos";
5355
"DisableAutoplayDesc" = "Empêche la lecture des vidéos après ouverture.";
5456
"NoContentWarning" = "Passer l'avertissement de contenu";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "Barre d'onglets";
7678
"RemoveLabels" = "Supprimer les sous-titres";
7779
"RemoveLabelsDesc" = "Supprime les sous-titres des onglets.";
80+
"RemoveIndicators" = "Remove indicators";
81+
"RemoveIndicatorsDesc" = "Removes tab indicators.";
7882
"ReExplore" = "Remplacer l'onglet Shorts par l'onglet Explorer";
7983
"ReExploreDesc" = "Affiche l'onglet Explorer à la place de l'onglet Shorts comme dans les anciennes versions de YouTube.";
8084
"HideShortsTab" = "Masquer l'onglet Shorts";

layout/Library/Application Support/YTLite.bundle/ja.lproj/Localizable.strings

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "ミニプレイヤーに対応していない動画(子供向けの動画など)でもミニプレイヤーを有効にします";
5050
"PortraitFullscreen" = "縦画面フルスクリーンモード";
5151
"PortraitFullscreenDesc" = "縦画面フルスクリーンモードをサポートします";
52+
"CopyWithTimestamp" = "Copy timestamped links";
53+
"CopyWithTimestampDesc" = "Allows to copy timestamped link to the clipboard by pressing pause button.";
5254
"DisableAutoplay" = "自動再生を無効化";
5355
"DisableAutoplayDesc" = "アプリを開いた後に動画の自動再生を防止します";
5456
"NoContentWarning" = "コンテンツ警告をスキップ";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "タブバー";
7678
"RemoveLabels" = "ラベルを削除";
7779
"RemoveLabelsDesc" = "タブラベルを削除します";
80+
"RemoveIndicators" = "Remove indicators";
81+
"RemoveIndicatorsDesc" = "Removes tab indicators.";
7882
"ReExplore" = "ショートタブを探索タブに置き換え";
7983
"ReExploreDesc" = "古いYouTubeバージョンのように、ショートタブの代わりに探索タブを表示します";
8084
"HideShortsTab" = "ショートタブを非表示";
@@ -165,4 +169,4 @@
165169
"ResetSettings" = "YTLiteの設定をリセット";
166170
"ResetMessage" = "このオプションを選択するとYTLiteの設定がデフォルトにリセットされ、YouTubeが終了します。\n\n続行してもよろしいですか?";
167171
"Yes" = "はい";
168-
"No" = "いいえ";
172+
"No" = "いいえ";

layout/Library/Application Support/YTLite.bundle/ru.lproj/Localizable.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "Принудительно активирует миниплеер для видео, в которых изначально не был предназначен (например, видеоролики для детей).";
5050
"PortraitFullscreen" = "Портретный полноэкранный режим";
5151
"PortraitFullscreenDesc" = "Активирует поддержку портретного полноэкранного режима.";
52+
"CopyWithTimestamp" = "Ссылки с временной отметкой";
53+
"CopyWithTimestampDesc" = "Позволяет скопировать ссылку на видео с временной отметкой в буфер обмена нажатием на кнопку паузы.";
5254
"DisableAutoplay" = "Запретить автовоспроизведение";
5355
"DisableAutoplayDesc" = "Принудительно запрещает автовоспроизведение видео при его открытии.";
5456
"NoContentWarning" = "Пропускать предупреждения";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "Панель вкладок";
7678
"RemoveLabels" = "Скрыть названия";
7779
"RemoveLabelsDesc" = "Скрывает названия вкладок.";
80+
"RemoveIndicators" = "Скрыть индикаторы";
81+
"RemoveIndicatorsDesc" = "Скрывает индикаторы вкладок.";
7882
"ReExplore" = "Вкладка «Навигация» вместо «Shorts»";
7983
"ReExploreDesc" = "Заменяет вкладку «Shorts» на привычную нам «Навигацию».";
8084
"HideShortsTab" = "Скрыть «Shorts»";

layout/Library/Application Support/YTLite.bundle/zh-Hans.lproj/Localizable.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
"MiniplayerDesc" = "启用迷你播放器来播放最初不是为其设计的视频,例如针对儿童的视频。";
5050
"PortraitFullscreen" = "竖屏全屏模式";
5151
"PortraitFullscreenDesc" = "启用竖屏全屏模式支持。";
52+
"CopyWithTimestamp" = "Copy timestamped links";
53+
"CopyWithTimestampDesc" = "Allows to copy timestamped link to the clipboard by pressing pause button.";
5254
"DisableAutoplay" = "禁用自动播放视频";
5355
"DisableAutoplayDesc" = "打开后防止视频自动播放。";
5456
"NoContentWarning" = "跳过内容警告";
@@ -75,6 +77,8 @@
7577
"Tabbar" = "选项卡栏";
7678
"RemoveLabels" = "移除标签";
7779
"RemoveLabelsDesc" = "删除选项卡标签。";
80+
"RemoveIndicators" = "Remove indicators";
81+
"RemoveIndicatorsDesc" = "Removes tab indicators.";
7882
"ReExplore" = "“短视频”替换为“探索”";
7983
"ReExploreDesc" = "在旧版本 YouTube 中将“短视频”选项卡替换为“探索”。";
8084
"HideShortsTab" = "隐藏短视频";

0 commit comments

Comments
 (0)