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"));
+ }
+ }
+}
+