diff --git a/BHTwitter.xcodeproj/project.pbxproj b/BHTwitter.xcodeproj/project.pbxproj index cd58a9c6..67245947 100644 --- a/BHTwitter.xcodeproj/project.pbxproj +++ b/BHTwitter.xcodeproj/project.pbxproj @@ -504,6 +504,7 @@ 50D73502252CBFC6007838C7 /* SceneKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50D73501252CBFC6007838C7 /* SceneKit.framework */; }; 50D73504252CBFD0007838C7 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 50D73503252CBFCB007838C7 /* libsqlite3.tbd */; }; 50E7ABEF24F5A8F700A8619D /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50E7ABEE24F5A8F600A8619D /* WebKit.framework */; }; + 50EE4D4B286F7F70007DE117 /* BHColorThemeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50EE4D4A286F7F70007DE117 /* BHColorThemeViewController.swift */; }; 50FCAB7E27268E1600265B5D /* HBlinkCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FCAB7C27268E1600265B5D /* HBlinkCell.h */; }; 50FCAB7F27268E1600265B5D /* HBlinkCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 50FCAB7D27268E1600265B5D /* HBlinkCell.m */; }; /* End PBXBuildFile section */ @@ -1019,6 +1020,7 @@ 50D73501252CBFC6007838C7 /* SceneKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SceneKit.framework; path = System/Library/Frameworks/SceneKit.framework; sourceTree = SDKROOT; }; 50D73503252CBFCB007838C7 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; 50E7ABEE24F5A8F600A8619D /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 50EE4D4A286F7F70007DE117 /* BHColorThemeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BHColorThemeViewController.swift; sourceTree = ""; }; 50FCAB7C27268E1600265B5D /* HBlinkCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HBlinkCell.h; sourceTree = ""; }; 50FCAB7D27268E1600265B5D /* HBlinkCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HBlinkCell.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1123,6 +1125,7 @@ 505C0EBD2801ED020028D1C9 /* BHDownloadInlineButton.m */, 50C15C9B271400DA00E8B5E8 /* BHTwitter+UIImage.h */, 50C15C9C271401CB00E8B5E8 /* BHTwitter+NSURL.h */, + 50EE4D49286F7F56007DE117 /* ThemeColor */, 5061F3BE2806132400F3D5D3 /* CustomTabBar */, 503FA66D2753F04A00BBB92A /* Classes */, 50C15CA827178C0D00E8B5E8 /* HBPreferences */, @@ -2009,6 +2012,14 @@ path = HBPreferences; sourceTree = ""; }; + 50EE4D49286F7F56007DE117 /* ThemeColor */ = { + isa = PBXGroup; + children = ( + 50EE4D4A286F7F70007DE117 /* BHColorThemeViewController.swift */, + ); + path = ThemeColor; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -2578,6 +2589,7 @@ 503FA9252753F04C00BBB92A /* FLEXKeychain.m in Sources */, 503FA96C2753F04D00BBB92A /* FHSView.m in Sources */, 503FA9392753F04C00BBB92A /* FLEXAddressExplorerCoordinator.m in Sources */, + 50EE4D4B286F7F70007DE117 /* BHColorThemeViewController.swift in Sources */, 503FA8412753F04B00BBB92A /* FLEXKeyValueTableViewCell.m in Sources */, 503FA97C2753F04D00BBB92A /* FLEXUtility.m in Sources */, 503FA8722753F04B00BBB92A /* FLEXShortcut.m in Sources */, diff --git a/BHTwitter/BHDownloadInlineButton.m b/BHTwitter/BHDownloadInlineButton.m index a87f500a..0ef1e851 100644 --- a/BHTwitter/BHDownloadInlineButton.m +++ b/BHTwitter/BHDownloadInlineButton.m @@ -44,14 +44,12 @@ - (id)_t1_imageNamed:(id)arg1 fitSize:(struct CGSize)arg2 fillColor:(id)arg3 { } - (void)DownloadHandler:(UIButton *)sender { NSAttributedString *AttString = [[NSAttributedString alloc] initWithString:@"\nSelect video quality you want to download" attributes:@{ - NSFontAttributeName: [[objc_getClass("TAEStandardFontGroup") sharedFontGroup] fixedLargeBoldFont], + NSFontAttributeName: [[objc_getClass("TAEStandardFontGroup") sharedFontGroup] headline2BoldFont], NSForegroundColorAttributeName: UIColor.labelColor }]; TFNActiveTextItem *title = [[objc_getClass("TFNActiveTextItem") alloc] initWithTextModel:[[objc_getClass("TFNAttributedTextModel") alloc] initWithAttributedString:AttString] activeRanges:nil]; - TFNMenuSheetCenteredIconItem *icon = [[objc_getClass("TFNMenuSheetCenteredIconItem") alloc] initWithIconImageName:@"2728" height:55 fillColor:UIColor.clearColor]; NSMutableArray *actions = [[NSMutableArray alloc] init]; - [actions addObject:icon]; [actions addObject:title]; for (TFSTwitterEntityMedia *i in self.delegate.viewModel.entities.media) { diff --git a/BHTwitter/BHTManager.h b/BHTwitter/BHTManager.h index 550bb97d..8d27fdb5 100644 --- a/BHTwitter/BHTManager.h +++ b/BHTwitter/BHTManager.h @@ -15,7 +15,7 @@ + (BOOL)isVideoCell:(id )model; + (bool)isDMVideoCell:(T1InlineMediaView *)view; + (BOOL)doesContainDigitsOnly:(NSString *)string; -+ (UIViewController *)BHTSettings; ++ (UIViewController *)BHTSettingsWithAccount:(TFNTwitterAccount *)twAccount; + (void)showSaveVC:(NSURL *)url; + (void)save:(NSURL *)url; + (float)TwitterVersion; @@ -47,5 +47,7 @@ + (BOOL)TwitterCircle; + (BOOL)CopyProfileInfo; + (BOOL)tweetToImage; ++ (BOOL)hideSpacesBar; ++ (BOOL)disableRTL; @end diff --git a/BHTwitter/BHTManager.m b/BHTwitter/BHTManager.m index 22a66eb3..3f810fd1 100644 --- a/BHTwitter/BHTManager.m +++ b/BHTwitter/BHTManager.m @@ -6,6 +6,8 @@ // #import "BHTManager.h" +#import "BHTwitter-Swift.h" +#import "BHTwitter+NSURL.h" @implementation BHTManager + (float)TwitterVersion { @@ -188,13 +190,22 @@ + (BOOL)CopyProfileInfo { + (BOOL)tweetToImage { return [[NSUserDefaults standardUserDefaults] boolForKey:@"TweetToImage"]; } -+ (UIViewController *)BHTSettings { ++ (BOOL)hideSpacesBar { + return [[NSUserDefaults standardUserDefaults] boolForKey:@"hide_spaces"]; +} ++ (BOOL)disableRTL { + return [[NSUserDefaults standardUserDefaults] boolForKey:@"dis_rtl"]; +} ++ (UIViewController *)BHTSettingsWithAccount:(TFNTwitterAccount *)twAccount { HBPreferences *pref = [[HBPreferences alloc] initTableWithTableStyle:UITableViewStyleInsetGrouped title:@"BHTwitter" SeparatorStyle:UITableViewCellSeparatorStyleSingleLine]; + [pref.navigationItem setTitleView:[objc_getClass("TFNTitleView") titleViewWithTitle:@"BHTwitter" subtitle:twAccount.displayUsername]]; + HBSection *mainSection = [HBSection sectionWithTitle:@"BHTwitter Preferences" footer:nil]; + HBSection *twitterBlueSection = [HBSection sectionWithTitle:@"Twitter blue features" footer:@"You may need to restart Twitter app to apply changes"]; HBSection *layoutSection = [HBSection sectionWithTitle:@"Layout customization" footer:@"Restart Twitter app to apply changes"]; - HBSection *tabBarLayoutSection = [HBSection sectionWithTitle:@"Tab bar customization" footer:@"Restart Twitter app to apply changes"]; HBSection *debug = [HBSection sectionWithTitle:@"Debugging" footer:nil]; - HBSection *developer = [HBSection sectionWithTitle:@"Developer" footer:nil]; + HBSection *legalSection = [HBSection sectionWithTitle:@"Legal notices" footer:nil]; + HBSection *developer = [HBSection sectionWithTitle:@"Developer" footer:@"BHTwitter v2.9.7"]; HBSwitchCell *download = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Downloading videos" DetailTitle:@"Downloading videos. By adding button in tweet and inside video tab bar." switchKey:@"dw_v" withBlock:^(UISwitch *weakSender) { if (weakSender.isOn) { @@ -381,7 +392,7 @@ + (UIViewController *)BHTSettings { } }]; - HBSwitchCell *tweetToImage = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Save tweet as image" DetailTitle:@"You can export tweets as image, by long pressing on the Tweet Share button" switchKey:@"TweetToImage" withBlock:^(UISwitch *weakSender) { + HBSwitchCell *tweetToImage = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Save tweet as an image" DetailTitle:@"You can export tweets as image, by long pressing on the Tweet Share button" switchKey:@"TweetToImage" withBlock:^(UISwitch *weakSender) { if (weakSender.isOn) { [[NSUserDefaults standardUserDefaults] setBool:true forKey:@"TweetToImage"]; } else { @@ -389,6 +400,22 @@ + (UIViewController *)BHTSettings { } }]; + HBSwitchCell *hideSpace = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Hide spaces bar" DetailTitle:nil switchKey:@"hide_spaces" withBlock:^(UISwitch *weakSender) { + if (weakSender.isOn) { + [[NSUserDefaults standardUserDefaults] setBool:true forKey:@"hide_spaces"]; + } else { + [[NSUserDefaults standardUserDefaults] setBool:false forKey:@"hide_spaces"]; + } + }]; + + HBSwitchCell *disableRTL = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Disable RTL" DetailTitle:@"Force Twitter use LTL with RTL language.\nRestart Twitter app to apply changes" switchKey:@"dis_rtl" withBlock:^(UISwitch *weakSender) { + if (weakSender.isOn) { + [[NSUserDefaults standardUserDefaults] setBool:true forKey:@"dis_rtl"]; + } else { + [[NSUserDefaults standardUserDefaults] setBool:false forKey:@"dis_rtl"]; + } + }]; + HBViewControllerCell *fontsPicker = [[HBViewControllerCell alloc] initCellWithTitle:@"Font" detail:[[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"] action:^UIViewController *{ UIFontPickerViewControllerConfiguration *configuration = [[UIFontPickerViewControllerConfiguration alloc] init]; [configuration setFilteredTraits:UIFontDescriptorClassMask]; @@ -410,20 +437,31 @@ + (UIViewController *)BHTSettings { }]; HBViewControllerCell *CustomTabBarVC = [[HBViewControllerCell alloc] initCellWithTitle:@"Custom Tab Bar" detail:nil action:^UIViewController *{ - return [[CustomTabBarViewController alloc] init]; + CustomTabBarViewController *customTabBArVC = [[CustomTabBarViewController alloc] init]; + [customTabBArVC.navigationItem setTitleView:[objc_getClass("TFNTitleView") titleViewWithTitle:@"Custom Tab Bar" subtitle:twAccount.displayUsername]]; + return customTabBArVC; + }]; + + HBViewControllerCell *appTheme = [[HBViewControllerCell alloc] initCellWithTitle:@"Theme" detail:@"Choose a theme color for you Twitter experience that can only be seen by you." action:^UIViewController *{ +// I create my own Color Theme ViewController for two main reasons: +// 1- Twitter use swift to build their view controller, so I can't hook anything on it. +// 2- Twitter knows you do not actually subscribe with Twitter Blue, so it keeps resting the changes and resting 'T1ColorSettingsPrimaryColorOptionKey' key, so I had to create another key to track the original one and keep sure no changes, but it still not enough to keep the new theme after relaunching app, so i had to force the changes again with new lunch. + BHColorThemeViewController *themeVC = [[BHColorThemeViewController alloc] init]; + [themeVC.navigationItem setTitleView:[objc_getClass("TFNTitleView") titleViewWithTitle:@"Theme" subtitle:twAccount.displayUsername]]; + return themeVC; }]; HBSwitchCell *font = [[HBSwitchCell alloc] initSwitchCellWithImage:nil Title:@"Enable changing font" DetailTitle:@"Option to allow changing Twitter font and show font picker." switchKey:@"en_font" withBlock:^(UISwitch *weakSender) { if (weakSender.isOn) { [[NSUserDefaults standardUserDefaults] setBool:true forKey:@"en_font"]; [layoutSection addCells:@[fontsPicker, BoldfontsPicker]]; - [pref.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:1], [NSIndexPath indexPathForRow:4 inSection:1]] withRowAnimation:UITableViewRowAnimationAutomatic]; + [pref.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:2], [NSIndexPath indexPathForRow:4 inSection:2]] withRowAnimation:UITableViewRowAnimationAutomatic]; } else { [[NSUserDefaults standardUserDefaults] setBool:false forKey:@"en_font"]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"bhtwitter_font_1"]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"bhtwitter_font_2"]; [layoutSection removeCells:@[fontsPicker, BoldfontsPicker]]; - [pref.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:1], [NSIndexPath indexPathForRow:4 inSection:1]] withRowAnimation:UITableViewRowAnimationAutomatic]; + [pref.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:3 inSection:2], [NSIndexPath indexPathForRow:4 inSection:2]] withRowAnimation:UITableViewRowAnimationAutomatic]; } }]; @@ -445,22 +483,30 @@ + (UIViewController *)BHTSettings { } }]; + HBViewControllerCell *acknowledgements = [[HBViewControllerCell alloc] initCellWithTitle:@"Acknowledgements" detail:nil action:^UIViewController *{ + T1RichTextFormatViewController *acknowledgementsVC = [[objc_getClass("T1RichTextFormatViewController") alloc] initWithRichTextFormatDocumentPath:[NSURL bhtwitter_fileURLWithPath:@"Acknowledgements.rtf"].path]; + [acknowledgementsVC.navigationItem setTitleView:[objc_getClass("TFNTitleView") titleViewWithTitle:@"Acknowledgements" subtitle:twAccount.displayUsername]]; + return acknowledgementsVC; + }]; + HBTwitterCell *bandarhl = [[HBTwitterCell alloc] initTwitterCellWithTitle:@"BandarHelal" detail:@"@BandarHL" AccountLink:@"https://twitter.com/BandarHL"]; HBlinkCell *tipJar = [[HBlinkCell alloc] initLinkCellWithTitle:@"Tip Jar" detailTitle:@"Donate" link:@"https://www.paypal.me/BandarHL"]; HBGithubCell *sourceCode = [[HBGithubCell alloc] initGithubCellWithTitle:@"BHTwitter" detailTitle:@"Code source of BHTwitter" GithubURL:@"https://github.com/BandarHL/BHTwitter/"]; - [mainSection addCells:@[download, hide_ads, hide_topics, disable_VODCaptions, direct_save, voice, voice_in_replay, UndoTweet, ReaderMode, ReplyLater, VideoZoom, NoHistory, BioTranslate, like_confirm, tweet_confirm, follow_confirm, padlock, DmModularSearch, autoHighestLoad, disableSensitiveTweetWarnings, copyProfileInfo, trustedFriends, tweetToImage]]; + [mainSection addCells:@[download, hide_ads, hide_topics, disable_VODCaptions, direct_save, voice, voice_in_replay, ReplyLater, VideoZoom, NoHistory, BioTranslate, like_confirm, tweet_confirm, follow_confirm, padlock, DmModularSearch, autoHighestLoad, disableSensitiveTweetWarnings, copyProfileInfo, tweetToImage, hideSpace, disableRTL]]; + [twitterBlueSection addCells:@[UndoTweet, ReaderMode, trustedFriends, appTheme, CustomTabBarVC]]; [layoutSection addCells:@[oldTweetStyle, dwbLayout, font]]; if ([BHTManager changeFont]) { [layoutSection addCells:@[fontsPicker, BoldfontsPicker]]; } - [tabBarLayoutSection addCell:CustomTabBarVC]; + [debug addCell:flex]; + [legalSection addCell:acknowledgements]; [developer addCells:@[bandarhl, sourceCode, tipJar]]; - [pref addSections:@[mainSection, layoutSection, tabBarLayoutSection, debug, developer]]; + [pref addSections:@[mainSection, twitterBlueSection, layoutSection, debug, legalSection, developer]]; return pref; } diff --git a/BHTwitter/BHTwitter+NSURL.h b/BHTwitter/BHTwitter+NSURL.h index 8576bc7e..b515b8b7 100644 --- a/BHTwitter/BHTwitter+NSURL.h +++ b/BHTwitter/BHTwitter+NSURL.h @@ -17,7 +17,9 @@ if ([fileManager fileExistsAtPath:@"/Library/Application Support/BHT/Ressources.bundle"]) { return [NSURL fileURLWithPath:[NSString stringWithFormat:@"/Library/Application Support/BHT/Ressources.bundle/%@", path]]; } else { - return [NSURL fileURLWithPath:[NSString stringWithFormat:@"Ressources.bundle/%@", path]]; + NSURL *ressourcesBundle = [[NSBundle mainBundle] URLForResource:@"Ressources" withExtension:@"bundle"]; +// return [NSURL fileURLWithPath:[NSString stringWithFormat:@"Ressources.bundle/%@", path]]; + return [ressourcesBundle URLByAppendingPathComponent:path]; } } @end diff --git a/BHTwitter/BHTwitter-Bridging-Header.h b/BHTwitter/BHTwitter-Bridging-Header.h index 1b2cb5d6..abd5c6a7 100644 --- a/BHTwitter/BHTwitter-Bridging-Header.h +++ b/BHTwitter/BHTwitter-Bridging-Header.h @@ -2,3 +2,5 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // +#import "BHTwitter+UIImage.h" +#import "TWHeaders.h" diff --git a/BHTwitter/BHTwitter.xm b/BHTwitter/BHTwitter.xm index a1c7afcf..79e18292 100644 --- a/BHTwitter/BHTwitter.xm +++ b/BHTwitter/BHTwitter.xm @@ -2,6 +2,7 @@ #import "SAMKeychain/AuthViewController.h" #import "Colours.h" #import "BHTManager.h" +#import "BHTwitter-Swift.h" %config(generator=internal) @@ -269,14 +270,12 @@ } %new - (void)DownloadHandler { NSAttributedString *AttString = [[NSAttributedString alloc] initWithString:@"\nSelect video quality you want to download" attributes:@{ - NSFontAttributeName: [[%c(TAEStandardFontGroup) sharedFontGroup] fixedLargeBoldFont], + NSFontAttributeName: [[%c(TAEStandardFontGroup) sharedFontGroup] headline2BoldFont], NSForegroundColorAttributeName: UIColor.labelColor }]; TFNActiveTextItem *title = [[%c(TFNActiveTextItem) alloc] initWithTextModel:[[%c(TFNAttributedTextModel) alloc] initWithAttributedString:AttString] activeRanges:nil]; - TFNMenuSheetCenteredIconItem *icon = [[%c(TFNMenuSheetCenteredIconItem) alloc] initWithIconImageName:@"2728" height:55 fillColor:UIColor.clearColor]; NSMutableArray *actions = [[NSMutableArray alloc] init]; - [actions addObject:icon]; [actions addObject:title]; T1PlayerMediaEntitySessionProducible *session = self.inlineMediaView.viewModel.playerSessionProducer.sessionProducible; @@ -316,24 +315,68 @@ } %end -// MARK: Save tweet as image +// MARK: Color theme +%hook TFNPagingViewController +- (void)viewDidAppear:(_Bool)animated { + %orig(animated); + + static dispatch_once_t once; + dispatch_once(&once, ^ { + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bh_color_theme_selectedColor"]) { + BH_changeTwitterColor([[NSUserDefaults standardUserDefaults] integerForKey:@"bh_color_theme_selectedColor"]); + } + }); +} +%end + +%hook T1AppSplitViewController +- (void)viewDidAppear:(_Bool)animated { + %orig(animated); + + static dispatch_once_t once; + dispatch_once(&once, ^ { + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bh_color_theme_selectedColor"]) { + BH_changeTwitterColor([[NSUserDefaults standardUserDefaults] integerForKey:@"bh_color_theme_selectedColor"]); + } + }); +} +%end + +%hook NSUserDefaults +- (void)setObject:(id)value forKey:(NSString *)defaultName { + if ([defaultName isEqualToString:@"T1ColorSettingsPrimaryColorOptionKey"]) { + id selectedColor = [[NSUserDefaults standardUserDefaults] objectForKey:@"bh_color_theme_selectedColor"]; + if (selectedColor != nil) { + if ([value isEqual:selectedColor]) { + return %orig; + } else { + return; + } + } + return %orig; + } + return %orig; +} +%end + +// MARK: Save tweet as an image %hook T1StatusInlineShareButton - (void)didLongPressActionButton:(UILongPressGestureRecognizer *)gestureRecognizer { if ([BHTManager tweetToImage]) { if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { T1StatusInlineActionsView *actionsView = self.delegate; - UIView *tweetView; + T1StatusCell *tweetView; // it supposed the T1StatusInlineShareButton class only exist in Tweet view, but just to make sure we are working in tweet. :) if ([actionsView.superview isKindOfClass:%c(T1StandardStatusView)]) { // normal tweet in the time line - tweetView = actionsView.superview; + tweetView = [(T1StandardStatusView *)actionsView.superview eventHandler]; } else if ([actionsView.superview isKindOfClass:%c(T1TweetDetailsFocalStatusView)]) { // Focus tweet - tweetView = actionsView.superview; + tweetView = [(T1TweetDetailsFocalStatusView *)actionsView.superview eventHandler]; } else { - return; + return %orig; } - UIImage *tweetImage = imageFromView(tweetView); + UIImage *tweetImage = BH_imageFromView(tweetView); UIActivityViewController *acVC = [[UIActivityViewController alloc] initWithActivityItems:@[tweetImage] applicationActivities:nil]; if (is_iPad()) { acVC.popoverPresentationController.sourceView = self; @@ -370,6 +413,22 @@ } %end +// MARK: Disable RTL +%hook NSParagraphStyle ++ (NSWritingDirection)defaultWritingDirectionForLanguage:(id)lang { + if ([BHTManager disableRTL]) { + return NSWritingDirectionLeftToRight; + } + return %orig; +} ++ (NSWritingDirection)_defaultWritingDirection { + if ([BHTManager disableRTL]) { + return NSWritingDirectionLeftToRight; + } + return %orig; +} +%end + // MARK: Bio Translate %hook TFNTwitterCanonicalUser - (_Bool)isProfileBioTranslatable { @@ -403,6 +462,27 @@ } %end +// MARK: Voice, TwitterCircle, SensitiveTweetWarnings, autoHighestLoad, VideoZoom, ReplyLater, VODCaptions, disableSpacesBar feature +%hook TPSTwitterFeatureSwitches +// Twitter save all the features and keys in side JSON file in bundle of application fs_embedded_defaults_production.json, and use it in TFNTwitterAccount class but with DM voice maybe developers forget to add boolean variable in the class, so i had to change it from the file. +// also, you can find every key for every feature i used in this tweak, i can remove all the codes below and find every key for it but I'm lazy to do that, :) +- (BOOL)boolForKey:(NSString *)key { + if ([BHTManager VoiceFeature] && [key isEqualToString:@"dm_voice_creation_enabled"]) { + return true; + } + return %orig; +} +%end + +%hook T1HomeTimelineItemsViewController +- (void)_t1_initializeFleets { + if ([BHTManager hideSpacesBar]) { + return; + } + return %orig; +} +%end + %hook TFNTwitterMediaUploadConfiguration - (_Bool)photoUploadHighQualityImagesSettingIsVisible { if ([BHTManager autoHighestLoad]) { @@ -423,7 +503,7 @@ if ([BHTManager autoHighestLoad]) { arg3 = true; } - return %orig; + return %orig(arg1, arg2, arg3); } %end @@ -451,7 +531,6 @@ } %end -// MARK: Voice feature %hook TFSTwitterAPICommandAccountStateProvider - (_Bool)allowPromotedContent { if ([BHTManager HidePromoted]) { @@ -538,15 +617,6 @@ } return %orig; } -- (bool)isVODInlineAudioToggleEnabled { - return true; -} -- (_Bool)isConversationThreadingVoiceOverSupportEnabled { - if ([BHTManager VoiceFeature]) { - return true; - } - return %orig; -} - (_Bool)isDMVoiceRenderingEnabled { if ([BHTManager VoiceFeature]) { return true; @@ -569,21 +639,6 @@ } %end -%hook T1MediaAutoplaySettings -- (_Bool)voiceOverEnabled { - if ([BHTManager VoiceFeature]) { - return true; - } - return %orig; -} -- (void)setVoiceOverEnabled:(_Bool)arg1 { - if ([BHTManager VoiceFeature]) { - arg1 = true; - } - return %orig(arg1); -} -%end - %hook T1PhotoMediaRailViewController - (void)setVoiceButtonHidden:(BOOL)arg1 { if ([BHTManager VoiceFeature]) { @@ -745,7 +800,7 @@ if ([self.sections count] == 1) { TFNItemsDataViewControllerBackingStore *DataViewControllerBackingStore = self.backingStore; TFNSettingsNavigationItem *bhtwitter = [[%c(TFNSettingsNavigationItem) alloc] initWithTitle:@"Settings" detail:@"BHTwitter preferences" systemIconName:@"gear" controllerFactory:^UIViewController *{ - return [BHTManager BHTSettings]; + return [BHTManager BHTSettingsWithAccount:self.account]; }]; [DataViewControllerBackingStore insertSection:0 atIndex:0]; [DataViewControllerBackingStore insertItem:bhtwitter atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; @@ -786,7 +841,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([indexPath section]== 0 && [indexPath row]== 1) { - [self.navigationController pushViewController:[BHTManager BHTSettings] animated:true]; + [self.navigationController pushViewController:[BHTManager BHTSettingsWithAccount:self.account] animated:true]; } else { return %orig; } @@ -800,916 +855,388 @@ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Custom fonts" style:UIBarButtonItemStylePlain target:self action:@selector(customFontsHandler)]; } %new - (void)customFontsHandler { - NSAttributedString *AttString = [[NSAttributedString alloc] initWithString:@"\nSelect your custom font" attributes:@{ - NSFontAttributeName: [[%c(TAEStandardFontGroup) sharedFontGroup] fixedLargeBoldFont], - NSForegroundColorAttributeName: UIColor.labelColor - }]; - TFNActiveTextItem *title = [[%c(TFNActiveTextItem) alloc] initWithTextModel:[[%c(TFNAttributedTextModel) alloc] initWithAttributedString:AttString] activeRanges:nil]; - TFNMenuSheetCenteredIconItem *icon = [[%c(TFNMenuSheetCenteredIconItem) alloc] initWithIconImageName:@"2728" height:55 fillColor:UIColor.clearColor]; - - NSMutableArray *actions = [[NSMutableArray alloc] init]; - [actions addObject:icon]; - [actions addObject:title]; - - NSPropertyListFormat plistFormat; - NSMutableDictionary *plistDictionary = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:@"/var/mobile/Library/Fonts/AddedFontCache.plist"]] options:NSPropertyListImmutable format:&plistFormat error:nil]; - [plistDictionary enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - @try { - NSString *fontName = ((NSMutableArray *)[[plistDictionary valueForKey:key] valueForKey:@"psNames"]).firstObject; - TFNActionItem *fontAction = [%c(TFNActionItem) actionItemWithTitle:fontName action:^{ - if (self.configuration.includeFaces) { - [self setSelectedFontDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{ - UIFontDescriptorNameAttribute: fontName - }]]; - } else { - [self setSelectedFontDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{ - UIFontDescriptorFamilyAttribute: fontName - }]]; - } - [self.delegate fontPickerViewControllerDidPickFont:self]; - }]; - [actions addObject:fontAction]; - } @catch (NSException *exception) { - NSLog(@"Unable to find installed fonts /n reason: %@", exception.reason); - } - }]; - - TFNMenuSheetViewController *alert = [[%c(TFNMenuSheetViewController) alloc] initWithActionItems:[NSArray arrayWithArray:actions]]; - [alert tfnPresentedCustomPresentFromViewController:self animated:YES completion:nil]; + if ([[NSFileManager defaultManager] fileExistsAtPath:@"/var/mobile/Library/Fonts/AddedFontCache.plist"]) { + NSAttributedString *AttString = [[NSAttributedString alloc] initWithString:@"\nSelect your custom font" attributes:@{ + NSFontAttributeName: [[%c(TAEStandardFontGroup) sharedFontGroup] headline2BoldFont], + NSForegroundColorAttributeName: UIColor.labelColor + }]; + TFNActiveTextItem *title = [[%c(TFNActiveTextItem) alloc] initWithTextModel:[[%c(TFNAttributedTextModel) alloc] initWithAttributedString:AttString] activeRanges:nil]; + + NSMutableArray *actions = [[NSMutableArray alloc] init]; + [actions addObject:title]; + + NSPropertyListFormat plistFormat; + NSMutableDictionary *plistDictionary = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:@"/var/mobile/Library/Fonts/AddedFontCache.plist"]] options:NSPropertyListImmutable format:&plistFormat error:nil]; + [plistDictionary enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + @try { + NSString *fontName = ((NSMutableArray *)[[plistDictionary valueForKey:key] valueForKey:@"psNames"]).firstObject; + TFNActionItem *fontAction = [%c(TFNActionItem) actionItemWithTitle:fontName action:^{ + if (self.configuration.includeFaces) { + [self setSelectedFontDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{ + UIFontDescriptorNameAttribute: fontName + }]]; + } else { + [self setSelectedFontDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{ + UIFontDescriptorFamilyAttribute: fontName + }]]; + } + [self.delegate fontPickerViewControllerDidPickFont:self]; + }]; + [actions addObject:fontAction]; + } @catch (NSException *exception) { + NSLog(@"Unable to find installed fonts /n reason: %@", exception.reason); + } + }]; + + TFNMenuSheetViewController *alert = [[%c(TFNMenuSheetViewController) alloc] initWithActionItems:[NSArray arrayWithArray:actions]]; + [alert tfnPresentedCustomPresentFromViewController:self animated:YES completion:nil]; + } else { + UIAlertController *errAlert = [UIAlertController alertControllerWithTitle:@"BHTwitter" message:@"Cannot find any custom/installed font on this device. \nHow can I install custom fonts? \nGo to the AppStore and install the iFont application, from iFont you can search or import fonts to install, after that you should find your custom font here." preferredStyle:UIAlertControllerStyleAlert]; + + [errAlert addAction:[UIAlertAction actionWithTitle:@"iFont application" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://apps.apple.com/sa/app/ifont-find-install-any-font/id1173222289"] options:@{} completionHandler:nil]; + }]]; + [errAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController:errAlert animated:true completion:nil]; + } } %end %hook TAEStandardFontGroup - (UIFont *)profilesFollowingCountFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)profilesFollowingFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)userCellFollowsYouFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)dashFollowingCountFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)dashFollowingFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)carouselUsernameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)carouselDisplayNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)profilesFullNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)profilesUsernameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeSmallFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeSmallBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeMediumFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeMediumBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)readerModeLargeBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)treeTopicsDescriptionFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)treeTopicsCategoryNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)treeTopicsNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)treeTopicsCategoryNameLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)topicsPillNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)topicsDescriptionFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)topicsNameFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)composerTextEditorFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)statusCellEdgeToEdgeBodyBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)statusCellEdgeToEdgeBodyFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)statusCellBodyFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)statusCellBodyBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)cardAttributionFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)cardTitleBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)cardTitleFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)tweetDetailBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)tweetDetailFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)directMessageBubbleBodyFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)directMessageComposePersistentBarFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedJumboBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedXLargeBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedLargeBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedNormalBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedSmallBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedJumboFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedXLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedNormalFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)fixedSmallFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)jumboBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)xLargeBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)largeBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)normalBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)smallBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)xSmallBoldFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_2"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(true, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)jumboFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)xLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)largeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)normalFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)smallFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)xSmallFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonXLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonLargeFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonMediumFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonMedium_CondensedFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonMedium_CondensedLighterFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonSmallFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonSmallLighterFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonSmall_CondensedFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonSmall_CondensedLighterFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonNavigationBarFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } - (UIFont *)buttonHeavyNavigationBarFont { - if ([BHTManager changeFont]) { - if ([[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]) { - NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:@"bhtwitter_font_1"]; - UIFont *ffont = %orig; - return [UIFont fontWithName:fontName size:ffont.pointSize]; - } else { - return %orig; - } - } else { - return %orig; - } + UIFont *origFont = %orig; + UIFont *newFont = BH_getDefaultFont(false, origFont.pointSize); + return newFont != nil ? newFont : origFont; } %end diff --git a/BHTwitter/CustomTabBar/CustomTabBarViewController.swift b/BHTwitter/CustomTabBar/CustomTabBarViewController.swift index 24d4a297..a297bf22 100644 --- a/BHTwitter/CustomTabBar/CustomTabBarViewController.swift +++ b/BHTwitter/CustomTabBar/CustomTabBarViewController.swift @@ -80,7 +80,6 @@ class CustomTabBarViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - title = "Custom Tab Bar" view.addSubview(tableView) NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.topAnchor), diff --git a/BHTwitter/HBPreferences/HBPreferences.m b/BHTwitter/HBPreferences/HBPreferences.m index ee2ad833..e7e8d99a 100755 --- a/BHTwitter/HBPreferences/HBPreferences.m +++ b/BHTwitter/HBPreferences/HBPreferences.m @@ -109,13 +109,13 @@ - (void)fontPickerViewControllerDidPickFont:(UIFontPickerViewController *)viewCo if (viewController.configuration.includeFaces) { [[NSUserDefaults standardUserDefaults] setObject:fontName forKey:@"bhtwitter_font_2"]; [viewController dismissViewControllerAnimated:true completion:^{ - HBCell *cell = [self.sections[1] cells][4]; + HBCell *cell = [self.sections[2] cells][4]; [cell.detailTextLabel setText:fontName]; }]; } else { [[NSUserDefaults standardUserDefaults] setObject:fontFamily forKey:@"bhtwitter_font_1"]; [viewController dismissViewControllerAnimated:true completion:^{ - HBCell *cell = [self.sections[1] cells][3]; + HBCell *cell = [self.sections[2] cells][3]; [cell.detailTextLabel setText:fontFamily]; }]; } diff --git a/BHTwitter/Package/DEBIAN/control b/BHTwitter/Package/DEBIAN/control index 670f6125..8eb74634 100644 --- a/BHTwitter/Package/DEBIAN/control +++ b/BHTwitter/Package/DEBIAN/control @@ -1,6 +1,6 @@ Package: com.bandarhl.BHTwitter Name: BHTwitter -Version: 2.9.6 +Version: 2.9.7 Description: Awesome tweak for Twitter Section: Tweaks Depends: firmware (>= 13.0), mobilesubstrate diff --git a/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/Acknowledgements.rtf b/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/Acknowledgements.rtf new file mode 100644 index 00000000..33003bcf --- /dev/null +++ b/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/Acknowledgements.rtf @@ -0,0 +1,155 @@ +{\rtf1\ansi\ansicpg1252\cocoartf2638 +\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} +{\*\expandedcolortbl;;\cssrgb\c0\c0\c0;} +\paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 +\deftab720 +\pard\pardeftab720\partightenfactor0 + +\f0\b\fs24 \cf0 \expnd0\expndtw0\kerning0 +Colours +\f1\b0 \ +\ +Copyright (C) 2013 by Benjamin Gordon\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy\ +of this software and associated documentation files (the "Software"), to deal\ +in the Software without restriction, including without limitation the rights\ +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ +copies of the Software, and to permit persons to whom the Software is\ +furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in\ +all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\ +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\ +THE SOFTWARE.\ +\ + +\f0\b FLEX +\f1\b0 \ +\ +Copyright (c) 2014-2016, Flipboard\ +All rights reserved.\ +\ +Redistribution and use in source and binary forms, with or without modification,\ +are permitted provided that the following conditions are met:\ +\ +* Redistributions of source code must retain the above copyright notice, this\ + list of conditions and the following disclaimer.\ +\ +* Redistributions in binary form must reproduce the above copyright notice, this\ + list of conditions and the following disclaimer in the documentation and/or\ + other materials provided with the distribution.\ +\ +* Neither the name of Flipboard nor the names of its\ + contributors may be used to endorse or promote products derived from\ + this software without specific prior written permission.\ +\ +* You must NOT include this project in an application to be submitted\ + to the App Store\'99, as this project uses too many private APIs.\ +\ +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\ +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\ +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\ +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\ +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\ +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\ +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\ +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\ +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\ +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\ +\ + +\f0\b SAMKeychain +\f1\b0 \ +\ +Copyright (c) 2010-2016 Sam Soffes, http://soff.es\ +\ +Permission is hereby granted, free of charge, to any person obtaining\ +a copy of this software and associated documentation files (the\ +"Software"), to deal in the Software without restriction, including\ +without limitation the rights to use, copy, modify, merge, publish,\ +distribute, sublicense, and/or sell copies of the Software, and to\ +permit persons to whom the Software is furnished to do so, subject to\ +the following conditions:\ +\ +The above copyright notice and this permission notice shall be\ +included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\ +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\ +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\ +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\ +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\ +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ + +\f0\b JGProgressHUD +\f1\b0 \ +\ +The MIT License (MIT)\ +\ +Copyright (c) 2014-2018 Jonas Gessner\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of\ +this software and associated documentation files (the "Software"), to deal in\ +the Software without restriction, including without limitation the rights to\ +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\ +the Software, and to permit persons to whom the Software is furnished to do so,\ +subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all\ +copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\ +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\ +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\ +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\ +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ + +\f0\b ALActionBlocks +\f1\b0 \ +\ +Copyright (c) 2014 Andy LaVoy\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\ +\ + +\f0\b SwifterSwift +\f1\b0 \ +\ +MIT License\ +\ +Copyright (c) 2015-2018 SwifterSwift (https://github.com/swifterswift)\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy\ +of this software and associated documentation files (the "Software"), to deal\ +in the Software without restriction, including without limitation the rights\ +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ +copies of the Software, and to permit persons to whom the Software is\ +furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in\ +all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\ +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\ +THE SOFTWARE.\ +} \ No newline at end of file diff --git a/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/BandarHL.jpg b/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/BandarHL.jpg index f44a59af..8873946c 100644 Binary files a/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/BandarHL.jpg and b/BHTwitter/Package/Library/Application Support/BHT/Ressources.bundle/BandarHL.jpg differ diff --git a/BHTwitter/TWHeaders.h b/BHTwitter/TWHeaders.h index 308bab20..2e0acc58 100644 --- a/BHTwitter/TWHeaders.h +++ b/BHTwitter/TWHeaders.h @@ -9,7 +9,6 @@ #import #import #import -#import "BHTwitter-Swift.h" #import "./Classes/Utility/FLEXAlert.h" #import "./Classes/FLEX.h" #import "BHDownload.h" @@ -27,6 +26,18 @@ @property(retain, nonatomic) UIWindow *window; @end +@interface NSParagraphStyle () ++ (NSWritingDirection)_defaultWritingDirection; +@end + +@interface TFNTwitterAccount : NSObject +@property (nonatomic, strong) NSString *displayFullName; +@property (nonatomic, strong) NSString *username; +@property (nonatomic, strong) NSString *displayUsername; +@property (nonatomic, strong) NSString *fullName; +@property (nonatomic, strong) id scribe; +@end + @interface TFNTableView: UITableView @end @@ -57,6 +68,7 @@ @interface T1GenericSettingsViewController: UIViewController @property (nonatomic, strong) TFNItemsDataViewControllerBackingStore *backingStore; @property (nonatomic, strong) NSArray *sections; +@property (nonatomic, strong) TFNTwitterAccount *account; @end @interface TTSSearchTypeaheadViewController : TFNItemsDataViewController @@ -66,9 +78,14 @@ - (void)clearActionControlWantsClear:(id)arg1; @end +@interface T1ColorThemeSettingsViewController : TFNItemsDataViewController +- (instancetype)initWithAccount:(TFNTwitterAccount *)acoount scribeContext:(id)context; +@end + @interface TAEStandardFontGroup : NSObject + (instancetype)sharedFontGroup; - (UIFont *)fixedLargeBoldFont; +- (UIFont *)headline2BoldFont; @end @interface TFNActionItem : NSObject @@ -105,6 +122,7 @@ @interface T1SettingsViewController : UIViewController @property (nonatomic, strong) TFNItemsDataViewControllerBackingStore *backingStore; @property (nonatomic, strong) NSArray *sections; +@property (nonatomic, strong) TFNTwitterAccount *account; @end @interface TFNSettingsNavigationItem : NSObject @@ -153,6 +171,15 @@ @property(nonatomic) __weak id delegate; @end +@protocol TTACoreStatusViewEventHandler +@end + +@interface T1StatusCell : UITableViewCell +@end + +@interface T1TweetDetailsFocalStatusViewTableViewCell : T1StatusCell +@end + @interface TFSTwitterEntityMediaVideoVariant : NSObject @property(readonly, copy, nonatomic) NSString *contentType; @property(readonly, copy, nonatomic) NSString *url; @@ -181,10 +208,12 @@ @end @interface T1StandardStatusView : UIView +@property(nonatomic) __weak id eventHandler; @property(readonly, nonatomic) UIView *visibleInlineActionsView; @end @interface T1TweetDetailsFocalStatusView : UIView +@property(nonatomic) __weak id eventHandler; @end @interface TFNButtonBarView : UIView @@ -279,26 +308,54 @@ @property(readonly, nonatomic) id viewModel; // @synthesize viewModel=_viewModel; @end +@interface T1RichTextFormatViewController : UIViewController +- (instancetype)initWithRichTextFormatDocumentPath:(NSString *)documentPath; +@end + +@interface TFNTitleView: UIView ++ (instancetype)titleViewWithTitle:(NSString *)title subtitle:(NSString *)subTitle; +@end + @interface TAETwitterColorPaletteSettingInfo : NSObject @property(readonly, nonatomic) _Bool isDark; @end @interface TAEColorSettings : NSObject @property(retain, nonatomic) TAETwitterColorPaletteSettingInfo *currentColorPalette; +- (void)setPrimaryColorOption:(NSInteger)colorOption; + (instancetype)sharedSettings; @end -static UIImage *imageFromView(UIView *view) { +static void BH_changeTwitterColor(NSInteger colorID) { + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + TAEColorSettings *colorSettings = [objc_getClass("TAEColorSettings") sharedSettings]; + + [defaults setObject:@(colorID) forKey:@"T1ColorSettingsPrimaryColorOptionKey"]; + [colorSettings setPrimaryColorOption:colorID]; +} +static UIImage *BH_imageFromView(UIView *view) { TAEColorSettings *colorSettings = [objc_getClass("TAEColorSettings") sharedSettings]; bool opaque = [colorSettings.currentColorPalette isDark] ? true : false; - UIGraphicsBeginImageContextWithOptions(view.layer.frame.size, opaque, 0.0); - [view.layer renderInContext:UIGraphicsGetCurrentContext()]; + UIGraphicsBeginImageContextWithOptions(view.frame.size, opaque, 0.0); +// [view.layer renderInContext:UIGraphicsGetCurrentContext()]; + [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:false]; UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } +static UIFont * _Nullable BH_getDefaultFont(bool isBold, CGFloat pointSize) { + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"en_font"]) { + if ([[NSUserDefaults standardUserDefaults] objectForKey:isBold ? @"bhtwitter_font_2" : @"bhtwitter_font_1"]) { + NSString *fontName = [[NSUserDefaults standardUserDefaults] objectForKey:isBold ? @"bhtwitter_font_2" : @"bhtwitter_font_1"]; + return [UIFont fontWithName:fontName size:pointSize]; + } + return nil; + } + return nil; +} + static BOOL isDeviceLanguageRTL() { return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft); } diff --git a/BHTwitter/ThemeColor/BHColorThemeViewController.swift b/BHTwitter/ThemeColor/BHColorThemeViewController.swift new file mode 100644 index 00000000..0e292e25 --- /dev/null +++ b/BHTwitter/ThemeColor/BHColorThemeViewController.swift @@ -0,0 +1,272 @@ +// +// BHColorThemeViewController.swift +// BHTwitter +// +// Created by BandarHelal on 27/06/2022. +// + +import UIKit + +class ColorThemeCell: UICollectionViewCell { + + var colorLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.textColor = .label + label.textAlignment = .center + label.layer.masksToBounds = true + label.layer.cornerRadius = 18 + label.font = .systemFont(ofSize: 15, weight: .bold) + return label + }() + let checkIMG: UIImageView = { + let imageView = UIImageView() + imageView.image = .init(systemName: "circle") + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.addSubview(colorLabel) + self.addSubview(checkIMG) + + NSLayoutConstraint.activate([ + colorLabel.topAnchor.constraint(equalTo: self.topAnchor), + colorLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor), + colorLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor), + colorLabel.heightAnchor.constraint(equalToConstant: 36), + + checkIMG.topAnchor.constraint(equalTo: colorLabel.bottomAnchor, constant: 12), + checkIMG.centerXAnchor.constraint(equalTo: self.centerXAnchor), + checkIMG.widthAnchor.constraint(equalToConstant: 24), + checkIMG.heightAnchor.constraint(equalToConstant: 24), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} +struct ColorThemeItem { + let colorID: Int + let name: String + var color: UIColor + + init(colorID: Int, name: String, color: UIColor = .label) { + self.colorID = colorID + self.name = name + self.color = color + } +} + +class BHColorThemeViewController: UIViewController { + + var colors = [ + ColorThemeItem(colorID: 1, name: "Blue", color: UIColor(argbHexString: "#1D9BF0")!), + ColorThemeItem(colorID: 2, name: "Yellow", color: UIColor(argbHexString: "#FFD400")!), + ColorThemeItem(colorID: 3, name: "Red", color: UIColor(argbHexString: "#F91880")!), + ColorThemeItem(colorID: 4, name: "Purple", color: UIColor(argbHexString: "#7856FF")!), + ColorThemeItem(colorID: 5, name: "Orange", color: UIColor(argbHexString: "#FF7A00")!), + ColorThemeItem(colorID: 6, name: "Green", color: UIColor(argbHexString: "#00BA7C")!), + ] { + didSet { + colorCollectionView.reloadData() + } + } + lazy var colorCollectionView: UICollectionView = { + let collection = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + collection.contentInsetAdjustmentBehavior = .always + collection.register(ColorThemeCell.self, forCellWithReuseIdentifier: "colorItem") + collection.delegate = self + collection.dataSource = self + collection.translatesAutoresizingMaskIntoConstraints = false + return collection + }() + + var headerLabel: UILabel = { + let label = UILabel() + label.text = "Choose a theme color for your Twitter experience that can be seen by you." + label.textColor = .secondaryLabel + label.numberOfLines = 0 + label.font = .systemFont(ofSize: 15) + label.textAlignment = .justified + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = .systemBackground + self.view.addSubview(headerLabel) + self.view.addSubview(colorCollectionView) + + NSLayoutConstraint.activate([ + headerLabel.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), + headerLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), + headerLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16), + + colorCollectionView.topAnchor.constraint(equalTo: self.headerLabel.bottomAnchor), + colorCollectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), + colorCollectionView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), + colorCollectionView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), + ]) + + } + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + colorCollectionView.collectionViewLayout.invalidateLayout() + super.viewWillTransition(to: size, with: coordinator) + } +} + +extension BHColorThemeViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.colors.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colorItem", for: indexPath) as! ColorThemeCell + let currCell = self.colors[indexPath.row] + + cell.colorLabel.text = currCell.name + cell.colorLabel.backgroundColor = currCell.color + + if (UserDefaults.standard.object(forKey: "bh_color_theme_selectedColor") != nil) { + let selectedColor = UserDefaults.standard.integer(forKey: "bh_color_theme_selectedColor") + switch selectedColor { + case 1: + if (currCell.colorID == 1) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + case 2: + if (currCell.colorID == 2) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + case 3: + if (currCell.colorID == 3) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + case 4: + if (currCell.colorID == 4) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + case 5: + if (currCell.colorID == 5) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + case 6: + if (currCell.colorID == 6) { + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + default: + break + } + } else { + if (currCell.colorID == 0) { + cell.checkIMG.image = .init(systemName: "checkmark.circle") + } + } + + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let colorItem = self.colors[indexPath.row] + collectionView.visibleCells.forEach { cell in + guard let colorCell = cell as? ColorThemeCell else {return} + colorCell.checkIMG.image = .init(systemName: "circle") + } + guard let currCell = collectionView.cellForItem(at: indexPath) as? ColorThemeCell else {return} + currCell.checkIMG.image = .init(systemName: "checkmark.circle") + UserDefaults.standard.set(colorItem.colorID, forKey: "bh_color_theme_selectedColor") + BH_changeTwitterColor(colorItem.colorID) + } + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { + return UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { + return 10 + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { + return 10 + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: 98, height: 74) + } +} + +// https://github.com/SwifterSwift/SwifterSwift/ +public extension UIColor { + /// SwifterSwift: Create Color from RGB values with optional transparency. + /// + /// - Parameters: + /// - red: red component. + /// - green: green component. + /// - blue: blue component. + /// - transparency: optional transparency value (default is 1). + convenience init?(red: Int, green: Int, blue: Int, transparency: CGFloat = 1) { + guard red >= 0, red <= 255 else { return nil } + guard green >= 0, green <= 255 else { return nil } + guard blue >= 0, blue <= 255 else { return nil } + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) + } + + /// SwifterSwift: Create Color from hexadecimal string in the format ARGB (alpha-red-green-blue). + /// + /// - Parameters: + /// - argbHexString: hexadecimal string (examples: 7FEDE7F6, 0x7FEDE7F6, #7FEDE7F6, #f0ff, 0xFF0F, ..). + convenience init?(argbHexString: String) { + var string = argbHexString.replacingOccurrences(of: "0x", with: "").replacingOccurrences(of: "#", with: "") + + if string.count <= 4 { // convert hex to long format if in short format + var str = "" + for character in string { + str.append(String(repeating: String(character), count: 2)) + } + string = str + } + + guard let hexValue = Int(string, radix: 16) else { return nil } + + let hasAlpha = string.count == 8 + + let alpha = hasAlpha ? (hexValue >> 24) & 0xFF : 0xFF + let red = (hexValue >> 16) & 0xFF + let green = (hexValue >> 8) & 0xFF + let blue = hexValue & 0xFF + + self.init(red: red, green: green, blue: blue, transparency: CGFloat(alpha) / 255) + } +}