diff --git a/Makefile b/Makefile index df0db51..19b277b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,11 @@ tweak/Narwhal.xm_CFLAGS = -fobjc-arc include $(THEOS_MAKE_PATH)/tweak.mk +SUBPROJECTS += prefs +include $(THEOS_MAKE_PATH)/aggregate.mk + + after-install:: install.exec "killall -9 Reddit" install.exec "killall -9 Apollo" - install.exec "killall -9 narwhal" \ No newline at end of file + install.exec "killall -9 narwhal" diff --git a/control b/control index ec98a2c..0d89210 100644 --- a/control +++ b/control @@ -1,7 +1,7 @@ Package: com.lint.undelete Name: TFDidThatSay? Depends: mobilesubstrate -Version: 1.2.2 +Version: 1.2.3 Architecture: iphoneos-arm Description: See "[deleted]" comments and posts without leaving Reddit! Maintainer: lint diff --git a/prefs/Makefile b/prefs/Makefile new file mode 100644 index 0000000..a94143a --- /dev/null +++ b/prefs/Makefile @@ -0,0 +1,17 @@ +include $(THEOS)/makefiles/common.mk + +ARCHS = arm64 arm64e + +BUNDLE_NAME = TFDidThatSayPrefs + +TFDidThatSayPrefs_FILES = TFDTSRootListController.m +TFDidThatSayPrefs_INSTALL_PATH = /Library/PreferenceBundles +TFDidThatSayPrefs_FRAMEWORKS = UIKit +TFDidThatSayPrefs_PRIVATE_FRAMEWORKS = Preferences +TFDidThatSayPrefs_CFLAGS = -fobjc-arc + +include $(THEOS_MAKE_PATH)/bundle.mk + +internal-stage:: + $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) + $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/TFDidThatSayPrefs.plist$(ECHO_END) diff --git a/prefs/Resources/Info.plist b/prefs/Resources/Info.plist new file mode 100644 index 0000000..3553794 --- /dev/null +++ b/prefs/Resources/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + TFDidThatSayPrefs + CFBundleIdentifier + com.lint.undelete.prefs + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + TFDTSRootListController + + diff --git a/prefs/Resources/Root.plist b/prefs/Resources/Root.plist new file mode 100644 index 0000000..c39d9d3 --- /dev/null +++ b/prefs/Resources/Root.plist @@ -0,0 +1,29 @@ + + + + + items + + + cell + PSGroupCell + label + Apollo + + + cell + PSSwitchCell + default + + defaults + com.lint.undelete.prefs + key + isApolloDeletedCommentsOnly + label + Only display eye on deleted comments + + + title + TFDidThatSay? + + diff --git a/prefs/Resources/icon.png b/prefs/Resources/icon.png new file mode 100644 index 0000000..3bc919e Binary files /dev/null and b/prefs/Resources/icon.png differ diff --git a/prefs/Resources/icon@2x.png b/prefs/Resources/icon@2x.png new file mode 100644 index 0000000..f44fc17 Binary files /dev/null and b/prefs/Resources/icon@2x.png differ diff --git a/prefs/Resources/icon@3x.png b/prefs/Resources/icon@3x.png new file mode 100644 index 0000000..95dd6ea Binary files /dev/null and b/prefs/Resources/icon@3x.png differ diff --git a/prefs/TFDTSRootListController.h b/prefs/TFDTSRootListController.h new file mode 100644 index 0000000..e96e2b1 --- /dev/null +++ b/prefs/TFDTSRootListController.h @@ -0,0 +1,5 @@ +#import + +@interface TFDTSRootListController : PSListController + +@end diff --git a/prefs/TFDTSRootListController.m b/prefs/TFDTSRootListController.m new file mode 100644 index 0000000..bf34ad2 --- /dev/null +++ b/prefs/TFDTSRootListController.m @@ -0,0 +1,13 @@ +#include "TFDTSRootListController.h" + +@implementation TFDTSRootListController + +- (NSArray *)specifiers { + if (!_specifiers) { + _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; + } + + return _specifiers; +} + +@end diff --git a/prefs/entry.plist b/prefs/entry.plist new file mode 100644 index 0000000..374fa63 --- /dev/null +++ b/prefs/entry.plist @@ -0,0 +1,21 @@ + + + + + entry + + bundle + TFDidThatSayPrefs + cell + PSLinkCell + detail + TFDTSRootListController + icon + icon.png + isController + + label + TFDidThatSay? + + + diff --git a/tfdidthatsay.plist b/tfdidthatsay.plist index 344fea0..99887e3 100644 Binary files a/tfdidthatsay.plist and b/tfdidthatsay.plist differ diff --git a/tweak/Apollo.h b/tweak/Apollo.h index 301d6cf..b541b06 100644 --- a/tweak/Apollo.h +++ b/tweak/Apollo.h @@ -16,8 +16,7 @@ -(void) calculatedLayoutDidChange; //custom element -@property(assign,nonatomic) id undeleteButton; - +@property(strong,nonatomic) id undeleteButton; @end /* -- Post Interfaces -- */ @@ -31,7 +30,7 @@ @end @interface ApolloCommentsHeaderCellNode -@property(assign, nonatomic) id undeleteButton; +@property(strong, nonatomic) id undeleteButton; @end /* -- Other Interfaces -- */ diff --git a/tweak/Apollo.xm b/tweak/Apollo.xm index 726c4bd..b953be2 100644 --- a/tweak/Apollo.xm +++ b/tweak/Apollo.xm @@ -3,18 +3,22 @@ %group Apollo -%hook ApolloApolloButtonNode -%end - +const NSDictionary* settings = [[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.lint.undelete.prefs.plist"]; NSDictionary* apolloBodyAttributes = nil; +%hook ApolloApolloButtonNode +%end %hook RKComment -(BOOL) isDeleted{ return NO; } + +-(BOOL) isModeratorRemoved{ + return NO; +} %end @@ -30,10 +34,12 @@ NSDictionary* apolloBodyAttributes = nil; %hook ApolloCommentCellNode -%property(assign,nonatomic) id undeleteButton; +%property(strong,nonatomic) id undeleteButton; %new --(void) didTapUndeleteButton{ +-(void) didTapUndeleteButton:(id) sender{ + + [sender setEnabled:NO]; id bodyNode = MSHookIvar(self, "bodyNode"); id authorNode = MSHookIvar(self, "authorNode"); @@ -77,48 +83,64 @@ NSDictionary* apolloBodyAttributes = nil; [bodyNode setAttributedString:[%c(MarkdownRenderer) attributedStringFromMarkdown:body withAttributes:apolloBodyAttributes]]; + [sender setEnabled:YES]; + }]; } -(void) didLoad { %orig; - CGFloat imageSize = 20.0f; - - UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [undeleteButton addTarget:self action:@selector(didTapUndeleteButton) forControlEvents:UIControlEventTouchUpInside]; - undeleteButton.frame = CGRectMake(0, 0, imageSize, imageSize); + id commentBody = [MSHookIvar(self, "comment") body]; - UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"]; - [undeleteButton setImage:undeleteImage forState:UIControlStateNormal]; + id isDeletedOnly = [settings valueForKey:@"isApolloDeletedCommentsOnly"]; + + if (([isDeletedOnly isEqual:@1] && ([commentBody isEqualToString:@"[deleted]"] || [commentBody isEqualToString:@"[removed]"])) || [isDeletedOnly isEqual:@0] ) { + + CGFloat imageSize = 20.0f; - [[self view] addSubview:undeleteButton]; - [self setUndeleteButton:undeleteButton]; + UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; + [undeleteButton addTarget:self action:@selector(didTapUndeleteButton:) forControlEvents:UIControlEventTouchUpInside]; + undeleteButton.frame = CGRectMake(0, 0, imageSize, imageSize); + + UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"]; + [undeleteButton setImage:undeleteImage forState:UIControlStateNormal]; + + [[self view] addSubview:undeleteButton]; + [self setUndeleteButton:undeleteButton]; + + } } -(void) _layoutSublayouts{ %orig; - CGFloat imageSize = 20.0f; + if ([self undeleteButton]){ + + CGFloat imageSize = 20.0f; - id moreNode = MSHookIvar(self, "moreOptionsNode"); - id ageNode = MSHookIvar(self, "ageNode"); + id moreNode = MSHookIvar(self, "moreOptionsNode"); + id ageNode = MSHookIvar(self, "ageNode"); - CGRect nodeFrame = [moreNode frame]; - CGFloat centerHeight = (nodeFrame.size.height + nodeFrame.origin.y * 2) / 2.0f; - CGFloat nodeSpacing =[ageNode frame].origin.x - nodeFrame.origin.x - nodeFrame.size.width; + CGRect nodeFrame = [moreNode frame]; + CGFloat centerHeight = (nodeFrame.size.height + nodeFrame.origin.y * 2) / 2.0f; + CGFloat nodeSpacing =[ageNode frame].origin.x - nodeFrame.origin.x - nodeFrame.size.width; - [[self undeleteButton] setFrame:CGRectMake(nodeFrame.origin.x - imageSize - nodeSpacing, centerHeight - (imageSize / 2), imageSize, imageSize)]; + [[self undeleteButton] setFrame:CGRectMake(nodeFrame.origin.x - imageSize - nodeSpacing, centerHeight - (imageSize / 2), imageSize, imageSize)]; + + } } %end %hook ApolloCommentsHeaderCellNode -%property(assign, nonatomic) id undeleteButton; +%property(strong, nonatomic) id undeleteButton; %new --(void) didTapUndeleteButton{ +-(void) didTapUndeleteButton:(id) sender{ + + [sender setEnabled:NO]; id bodyNode = MSHookIvar(self, "bodyNode"); id postInfoNode = MSHookIvar(self, "postInfoNode"); @@ -165,6 +187,8 @@ NSDictionary* apolloBodyAttributes = nil; [bodyNode setAttributedString:[%c(MarkdownRenderer) attributedStringFromMarkdown:body withAttributes:apolloBodyAttributes]]; + [sender setEnabled:YES]; + }]; } @@ -177,7 +201,7 @@ NSDictionary* apolloBodyAttributes = nil; CGFloat imageSize = 20.0f; UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [undeleteButton addTarget:self action:@selector(didTapUndeleteButton) forControlEvents:UIControlEventTouchUpInside]; + [undeleteButton addTarget:self action:@selector(didTapUndeleteButton:) forControlEvents:UIControlEventTouchUpInside]; UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"]; [undeleteButton setImage:undeleteImage forState:UIControlStateNormal]; @@ -201,7 +225,6 @@ NSDictionary* apolloBodyAttributes = nil; CGFloat centerHeight = [postInfoNode frame].origin.y + ([ageNode frame].size.height + [ageNode frame].origin.y * 2) / 2.0f; CGFloat buttonXPos = [postInfoNode frame].origin.x + [postInfoNode frame].size.width - imageSize; - //Compiling with DEBUG=0 causes this to break the app, I have no idea why. [[self undeleteButton] setFrame:CGRectMake(buttonXPos, centerHeight - (imageSize / 2), imageSize, imageSize)]; } } @@ -211,10 +234,10 @@ NSDictionary* apolloBodyAttributes = nil; %ctor { + NSString* processName = [[NSProcessInfo processInfo] processName]; if ([processName isEqualToString:@"Apollo"]){ %init(Apollo, ApolloCommentsHeaderCellNode = objc_getClass("Apollo.CommentsHeaderCellNode"), ApolloCommentCellNode = objc_getClass("Apollo.CommentCellNode"), ApolloApolloButtonNode = objc_getClass("Apollo.ApolloButtonNode")); } } - diff --git a/tweak/Narwhal.xm b/tweak/Narwhal.xm index dea2c66..6a3657a 100644 --- a/tweak/Narwhal.xm +++ b/tweak/Narwhal.xm @@ -3,52 +3,9 @@ %group Narwhal -UIAlertController* recreateActionSheet(id controller, id comment, NSInteger commentIndex){ - - UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:nil]; - - UIAlertAction* pmAction = [UIAlertAction actionWithTitle:[NSString stringWithFormat:@"private message %@", [comment author]] style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetPrivateMessage:comment];}]; - UIAlertAction* viewProfileAction = [UIAlertAction actionWithTitle:@"view profile" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetViewProfile:comment];}]; - UIAlertAction* shareAction = [UIAlertAction actionWithTitle:@"share comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetShareComment:comment];}]; - UIAlertAction* copyAction = [UIAlertAction actionWithTitle:@"copy text" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetCopyCommentText:comment];}]; - UIAlertAction* reportAction = [UIAlertAction actionWithTitle:@"report comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetReportComment:comment];}]; - UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:nil]; - - [alert addAction:pmAction]; - [alert addAction:viewProfileAction]; - [alert addAction:shareAction]; - [alert addAction:copyAction]; - - if ([comment isSaved]){ - UIAlertAction* unsaveAction = [UIAlertAction actionWithTitle:@"unsave comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetUnsaveComment:comment index:commentIndex];}]; - [alert addAction:unsaveAction]; - - } else { - UIAlertAction* saveAction = [UIAlertAction actionWithTitle:@"save comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetSaveComment:comment index:commentIndex];}]; - [alert addAction:saveAction]; - } - - if ([[[comment parentID] componentsSeparatedByString:@"_"][0] isEqualToString:@"t1"]){ - UIAlertAction* viewParentAction = [UIAlertAction actionWithTitle:@"view parent" style: nil handler:^(UIAlertAction* action){[controller _handleActionSheetViewParent:comment];}]; - [alert addAction:viewParentAction]; - } - - if ([[comment author] isEqualToString:[[%c(NRTAuthManager) sharedManager] currentUsername]]) { - UIAlertAction* editAction = [UIAlertAction actionWithTitle:@"edit comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetEditComment:comment];}]; - UIAlertAction* deleteAction = [UIAlertAction actionWithTitle:@"delete comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetDeleteComment:comment];}]; - - [alert addAction:editAction]; - [alert addAction:deleteAction]; - } - - [alert addAction:reportAction]; - [alert addAction:cancelAction]; - - UIAlertAction* undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){[controller handleUndeleteCommentAction:comment];}]; - [alert addAction:undeleteAction]; - - return alert; -} +BOOL shouldHaveUndeleteAction = NO; +id tfComment; +id tfController; void getUndeleteCommentData(id controller, id comment){ @@ -71,12 +28,6 @@ void getUndeleteCommentData(id controller, id comment){ if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){ body = @"[pushshift was unable to archive this]"; } - if (!body){ - body = @"[wtf]"; - } - if (!author){ - author = @"[wtf]"; - } } else { body = @"[pushshift has not archived this yet]"; } @@ -87,7 +38,34 @@ void getUndeleteCommentData(id controller, id comment){ [controller performSelectorOnMainThread:@selector(completeUndeleteComment:) withObject:@{@"body":body, @"author":author, @"comment":comment} waitUntilDone:NO]; }]; -} +} + + + +%hook UIViewController + +-(void) presentViewController:(id) arg1 animated:(BOOL) arg2 completion:(id) arg3{ + + if ([arg1 isKindOfClass:[UIAlertController class]] && shouldHaveUndeleteAction){ + + UIAlertAction* undeleteAction; + + if (tfComment){ + undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){getUndeleteCommentData(tfController, tfComment);}]; + } else { + undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){[tfController handleUndeletePostAction];}]; + } + + [arg1 addAction:undeleteAction]; + + } + + %orig; +} + +%end + + %hook NRTLinkViewController @@ -119,11 +97,6 @@ void getUndeleteCommentData(id controller, id comment){ [[self tableView] reloadData]; } -%new --(void) handleUndeleteCommentAction:(id) comment{ - getUndeleteCommentData(self, comment); -} - %new -(void) handleUndeletePostAction{ @@ -158,8 +131,6 @@ void getUndeleteCommentData(id controller, id comment){ [self performSelectorOnMainThread:@selector(completeUndeletePost:) withObject:@{@"body":body, @"author":author, @"post":post} waitUntilDone:NO]; }]; - - } -(void) swipeCell:(id) arg1 didEndDragWithState:(NSUInteger) arg2{ @@ -168,66 +139,32 @@ void getUndeleteCommentData(id controller, id comment){ if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) { - id comment = [arg1 comment]; - NSInteger commentIndex = [[[self commentsManager] comments] indexOfObject:comment]; + tfComment = [arg1 comment]; + tfController = self; + shouldHaveUndeleteAction = YES; - UIAlertController* alert = recreateActionSheet(self, comment, commentIndex); - - [self presentViewController:alert animated:YES completion:nil]; - - } else { - %orig; - } - } else { - %orig; - } + } + } + + %orig; + + shouldHaveUndeleteAction = NO; } -(void) _dotsButtonTouched:(id) arg1{ - id post = [self link]; - BOOL shouldHaveUndeleteAction = NO; - - UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:nil]; - - UIAlertAction* undeletePostAction; - - UIAlertAction* sharePostAction = [UIAlertAction actionWithTitle:@"share reddit post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetSharePost];}]; - UIAlertAction* sortCommentsAction = [UIAlertAction actionWithTitle:@"sort comments" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetSortComments];}]; - UIAlertAction* refreshCommentsAction = [UIAlertAction actionWithTitle:@"refresh comments" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetRefreshComments];}]; - UIAlertAction* reportPostAction = [UIAlertAction actionWithTitle:@"report post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetReportPost];}]; - UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:nil]; - - [alert addAction:sharePostAction]; - [alert addAction:sortCommentsAction]; - [alert addAction:refreshCommentsAction]; - if ([self linkTextOffscreenCell]){ - UIAlertAction* refreshPostAction = [UIAlertAction actionWithTitle:@"refresh post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetRefreshPost];}]; - [alert addAction:refreshPostAction]; - undeletePostAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){[self handleUndeletePostAction];}]; + tfController = self; + tfComment = nil; shouldHaveUndeleteAction = YES; - } - - if ([[post author] isEqualToString:[[%c(NRTAuthManager) sharedManager] currentUsername]]){ - UIAlertAction* editPostAction = [UIAlertAction actionWithTitle:@"edit post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetEditPost];}]; - UIAlertAction* deletePostAction = [UIAlertAction actionWithTitle:@"delete post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetDeletePost];}]; - [alert addAction:editPostAction]; - [alert addAction:deletePostAction]; } - [alert addAction:reportPostAction]; - [alert addAction:cancelAction]; - - if (shouldHaveUndeleteAction){ - [alert addAction:undeletePostAction]; - } - - [self presentViewController:alert animated:YES completion:nil]; + %orig; + shouldHaveUndeleteAction = NO; } %end @@ -249,30 +186,22 @@ void getUndeleteCommentData(id controller, id comment){ } } -%new --(void) handleUndeleteCommentAction:(id) comment{ - getUndeleteCommentData(self, comment); -} - -(void) swipeCell:(id) arg1 didEndDragWithState:(NSUInteger) arg2{ if (arg2 == 2){ if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) { - - id comment = [arg1 comment]; - NSInteger commentIndex = [[[self commentsManager] comments] indexOfObject:comment]; - UIAlertController* alert = recreateActionSheet(self, comment, commentIndex); - - [[self parentController] presentViewController:alert animated:YES completion:nil]; + tfComment = [arg1 comment]; + tfController = self; + shouldHaveUndeleteAction = YES; - } else { - %orig; - } - } else { - %orig; - } + } + } + + %orig; + + shouldHaveUndeleteAction = NO; } %end