From dc2ac10eb4e0ab8adc5b4f892e3d869e443877a2 Mon Sep 17 00:00:00 2001 From: lint <47455468+lint@users.noreply.github.com> Date: Fri, 27 Dec 2019 18:44:29 -0500 Subject: [PATCH] Add Beam support --- prefs/Resources/Root.plist | 14 ++ tfdidthatsay.plist | Bin 250 -> 275 bytes tweak/Beam.h | 56 ++++++++ tweak/Beam.xm | 277 +++++++++++++++++++++++++++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 tweak/Beam.h create mode 100644 tweak/Beam.xm diff --git a/prefs/Resources/Root.plist b/prefs/Resources/Root.plist index 1e6f384..45ab025 100644 --- a/prefs/Resources/Root.plist +++ b/prefs/Resources/Root.plist @@ -110,6 +110,20 @@ label Enable Antenna + + PostNotification + com.lint.undelete.prefs.changed + cell + PSSwitchCell + default + + defaults + com.lint.undelete.prefs + key + isBeamEnabled + label + Enable Beam + cell PSGroupCell diff --git a/tfdidthatsay.plist b/tfdidthatsay.plist index 712ff8192b244f8c89cc801b75a1ea21fd81b999..70df4c60678562d77f2818d4040cefbe0db7e673 100644 GIT binary patch delta 88 zcmeyxIGJgJEawVVHg*n9E^eNQsw-XM1w@kbbMFiHvj+t delta 63 zcmbQt^owzVEXQ(IHg*n9F7AnHD|I-yg+yglEkg_1=kI0!14c#&&A(self, "delegate") tableView] performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; + + [sender setEnabled:YES]; + }]; +} + +%end + + +%hook PostSelfTextPartCell + +-(void) setSelected:(BOOL) arg1 animated:(BOOL) arg2{ + %orig; + + id postViewController = [self _viewControllerForAncestor]; + + if ([postViewController isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){ + + [postViewController setSelfTextView:self]; + [postViewController setPost:[self post]]; + } +} + +%end + + +%hook PostMetadataView + +-(void) layoutSubviews{ + %orig; + + id postViewController = MSHookIvar(self, "delegate"); + + if ([postViewController isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){ + [postViewController setMetadataView:self]; + } +} + +%end + + +%hook PostToolbarView +%property(strong, nonatomic) UIButton *undeleteButton; + +-(void) layoutSubviews{ + %orig; + + if (![self undeleteButton] && [[[self post] isSelfText] boolValue] && [MSHookIvar(self, "delegate") isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){ + + NSString *postBody = [[self post] content]; + + if ((isTFDeletedOnly && ([postBody isEqualToString:@"[deleted]"] || [postBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){ + + id moreButton = MSHookIvar(self, "moreButton"); + + CGFloat buttonHeight = [moreButton frame].size.height; + + UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [undeleteButton addTarget:MSHookIvar(self, "delegate") action:@selector(handleUndeletePostAction:) forControlEvents:UIControlEventTouchUpInside]; + + [undeleteButton setImage:[UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"] forState:UIControlStateNormal]; + undeleteButton.imageView.contentMode = UIViewContentModeScaleAspectFit; + undeleteButton.imageEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5); + + undeleteButton.frame = CGRectMake([moreButton frame].origin.x - buttonHeight, 1, buttonHeight, buttonHeight); + + [self addSubview:undeleteButton]; + [self setUndeleteButton:undeleteButton]; + } + } +} + +%end + +%hook PostDetailEmbeddedViewController +%property(strong, nonatomic) id selfTextView; +%property(strong, nonatomic) id metadataView; +%property(strong, nonatomic) id post; + +%new +-(void) handleUndeletePostAction:(id) sender{ + + [sender setEnabled:NO]; + + id post = [self post]; + + if (post){ + + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + + [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext", [post identifier]]]]; + [request setHTTPMethod:@"GET"]; + [request setTimeoutInterval:pushshiftRequestTimeoutValue]; + + [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { + + NSString *author = @"[author]"; + NSString *body = @"[body]"; + + if (data != nil && error == nil){ + id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + if ([[jsonData objectForKey:@"data"] count] != 0){ + author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"]; + body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"]; + if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){ + body = @"[pushshift was unable to archive this]"; + } + } else { + body = @"[pushshift has not archived this yet]"; + } + } else if (error != nil || data == nil){ + body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]]; + } + + [post setAuthor:author]; + [post setContent:body]; + [post setMarkdownString:nil]; + + if ([self selfTextView]){ + [[self selfTextView] performSelectorOnMainThread:@selector(reloadContents) withObject:nil waitUntilDone:YES]; + } + + if ([self metadataView]){ + [[self metadataView] performSelectorOnMainThread:@selector(setPost:) withObject:post waitUntilDone:YES]; + } + + [[self tableView] performSelectorOnMainThread:@selector(reloadData) withObject:post waitUntilDone:NO]; + + [sender setEnabled:YES]; + }]; + } +} + +%end + +%end + + +static void loadPrefs(){ + NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"]; + + if (prefs){ + + if ([prefs objectForKey:@"isBeamEnabled"] != nil){ + isBeamEnabled = [[prefs objectForKey:@"isBeamEnabled"] boolValue]; + } else { + isBeamEnabled = YES; + } + + if ([prefs objectForKey:@"isTFDeletedOnly"] != nil) { + isTFDeletedOnly = [[prefs objectForKey:@"isTFDeletedOnly"] boolValue]; + } else { + isTFDeletedOnly = YES; + } + + if ([prefs objectForKey:@"requestTimeoutValue"] != nil){ + pushshiftRequestTimeoutValue = [[prefs objectForKey:@"requestTimeoutValue"] doubleValue]; + } else { + pushshiftRequestTimeoutValue = 10; + } + + } else { + isBeamEnabled = YES; + isTFDeletedOnly = YES; + pushshiftRequestTimeoutValue = 10; + } +} + +static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { + loadPrefs(); +} + + +%ctor{ + loadPrefs(); + + NSString* processName = [[NSProcessInfo processInfo] processName]; + + if ([processName isEqualToString:@"beam"]){ + if (isBeamEnabled){ + + CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); + + %init(Beam, CommentCell = objc_getClass("beam.CommentCell"), PostDetailEmbeddedViewController = objc_getClass("beam.PostDetailEmbeddedViewController"), PostToolbarView = objc_getClass("beam.PostToolbarView"), PostSelfTextPartCell = objc_getClass("beam.PostSelfTextPartCell"), PostMetadataView = objc_getClass("beam.PostMetadataView")); + } + } +} +