您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

280 行
9.2KB

  1. #import "Antenna.h"
  2. #import "assets/MMMarkdown.h"
  3. static BOOL isAntennaEnabled;
  4. static BOOL isTFDeletedOnly;
  5. static CGFloat pushshiftRequestTimeoutValue;
  6. %group Antenna
  7. BOOL shouldHaveAntennaUndeleteAction = NO;
  8. id tfAntennaController;
  9. id tfAntennaCommentCell;
  10. %hook RCPostSwift
  11. %end
  12. %hook RCCommentTextSwift
  13. %end
  14. %hook RCCommentSwift
  15. -(BOOL) isCommentDeleted{
  16. return NO;
  17. }
  18. %end
  19. %hook RCPostCommentsController
  20. -(void) didLongPressCell:(id) arg1 gesture:(id) arg2 {
  21. NSString *commentBody = [[[arg1 comment] commentText] body];
  22. if ((isTFDeletedOnly && ([commentBody isEqualToString:@"[deleted]"] || [commentBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){
  23. tfAntennaController = self;
  24. tfAntennaCommentCell = arg1;
  25. shouldHaveAntennaUndeleteAction = YES;
  26. }
  27. %orig;
  28. shouldHaveAntennaUndeleteAction = NO;
  29. }
  30. %new
  31. -(void) handleUndeleteCommentAction{
  32. id comment = [tfAntennaCommentCell comment];
  33. id commentText = [comment commentText];
  34. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  35. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  36. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[comment itemId]]]];
  37. [request setHTTPMethod:@"GET"];
  38. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  39. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  40. NSString *author = @"[author]";
  41. NSString *body = @"[body]";
  42. if (data != nil && error == nil){
  43. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  44. if ([[jsonData objectForKey:@"data"] count] != 0){
  45. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  46. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  47. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  48. body = @"[pushshift was unable to archive this]";
  49. }
  50. } else {
  51. body = @"[pushshift has not archived this yet]";
  52. }
  53. } else if (error != nil || data == nil){
  54. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  55. }
  56. [comment setAuthor:author];
  57. [commentText setBody:body];
  58. [commentText setBodyHTML:[%c(MMMarkdown) HTMLStringWithMarkdown:body extensions:MMMarkdownExtensionsGitHubFlavored error:nil]];
  59. [commentText setBodyAttributedString:nil];
  60. [commentText setBodyAttributedStringForPreview:nil];
  61. [commentText setTextHeightCache:nil];
  62. [self setCommentHeightCache:nil];
  63. [tfAntennaCommentCell performSelectorOnMainThread:@selector(updateWithModelObject:) withObject:comment waitUntilDone:YES];
  64. [[[self delegate] tableView] performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
  65. }];
  66. }
  67. %end
  68. %hook AHKActionSheet
  69. -(void)show{
  70. if (shouldHaveAntennaUndeleteAction){
  71. UIImage *undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  72. AHKActionSheetItem *actionItem = [self items][0];
  73. CGSize actionItemImageSize = [[actionItem image] size];
  74. CGSize newUndeleteImageSize = CGSizeMake(actionItemImageSize.width * 2, actionItemImageSize.height * 2);
  75. UIGraphicsBeginImageContext(newUndeleteImageSize);
  76. [undeleteImage drawInRect:CGRectMake(0, 0, newUndeleteImageSize.width, newUndeleteImageSize.height)];
  77. undeleteImage = UIGraphicsGetImageFromCurrentImageContext();
  78. UIGraphicsEndImageContext();
  79. undeleteImage = [[UIImage alloc] initWithCGImage:[undeleteImage CGImage] scale:2 orientation:UIImageOrientationUp];
  80. [self addButtonWithTitle:@"TF did that say?" image:undeleteImage type:0 handler:^{[tfAntennaController handleUndeleteCommentAction];}];
  81. }
  82. %orig;
  83. }
  84. %end
  85. %hook RCPostActionsSectionHeader
  86. %property(strong, nonatomic) UIButton *undeleteButton;
  87. -(void) layoutSubviews{
  88. BOOL isAbleToUndeletePost = NO;
  89. id post = [[self delegate] postInternal];
  90. NSString *postBody = [[post selfCommentText] body];
  91. if ([post isSelfPost]){
  92. if ((isTFDeletedOnly && ([postBody isEqualToString:@"[deleted]"] || [postBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly) {
  93. isAbleToUndeletePost = YES;
  94. NSMutableArray *barButtons = [self defaultHeaderButtons];
  95. if ([barButtons count] <= 5){
  96. UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
  97. [barButtons addObject:tempView];
  98. }
  99. %orig;
  100. if (![self undeleteButton]){
  101. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  102. [undeleteButton addTarget:[[self delegate] headerCellController] action:@selector(handleUndeletePostAction:) forControlEvents:UIControlEventTouchUpInside];
  103. [undeleteButton setImage:[[UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
  104. undeleteButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
  105. undeleteButton.tintColor = [barButtons[4] defaultColor];
  106. [self addSubview:undeleteButton];
  107. [self setUndeleteButton:undeleteButton];
  108. }
  109. [[self undeleteButton] setFrame:[barButtons[[barButtons count] - 1] frame]];
  110. }
  111. }
  112. if (!isAbleToUndeletePost){
  113. %orig;
  114. }
  115. }
  116. %end
  117. %hook RCPostHeaderCellController
  118. %new
  119. -(void) handleUndeletePostAction:(id) sender{
  120. [sender setEnabled:NO];
  121. id post = [self post];
  122. id postText = [post selfCommentText];
  123. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  124. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  125. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[post itemId]]]];
  126. [request setHTTPMethod:@"GET"];
  127. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  128. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  129. NSString *author = @"[author]";
  130. NSString *body = @"[body]";
  131. if (data != nil && error == nil){
  132. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  133. if ([[jsonData objectForKey:@"data"] count] != 0){
  134. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  135. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  136. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  137. body = @"[pushshift was unable to archive this]";
  138. }
  139. } else {
  140. body = @"[pushshift has not archived this yet]";
  141. }
  142. } else if (error != nil || data == nil){
  143. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  144. }
  145. [post setAuthor:author];
  146. [postText setBody:body];
  147. [postText setBodyHTML:[%c(MMMarkdown) HTMLStringWithMarkdown:body extensions:MMMarkdownExtensionsGitHubFlavored error:nil]];
  148. [postText setBodyAttributedString:nil];
  149. [postText setBodyAttributedStringForPreview:nil];
  150. [postText setTextHeightCache:nil];
  151. [self performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
  152. [[self tableView] performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
  153. [sender setEnabled:YES];
  154. }];
  155. }
  156. %end
  157. %end
  158. static void loadPrefs(){
  159. NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"];
  160. if (prefs){
  161. if ([prefs objectForKey:@"isAntennaEnabled"] != nil){
  162. isAntennaEnabled = [[prefs objectForKey:@"isAntennaEnabled"] boolValue];
  163. } else {
  164. isAntennaEnabled = YES;
  165. }
  166. if ([prefs objectForKey:@"isTFDeletedOnly"] != nil){
  167. isTFDeletedOnly = [[prefs objectForKey:@"isTFDeletedOnly"] boolValue];
  168. } else {
  169. isTFDeletedOnly = YES;
  170. }
  171. if ([prefs objectForKey:@"requestTimeoutValue"] != nil){
  172. pushshiftRequestTimeoutValue = [[prefs objectForKey:@"requestTimeoutValue"] doubleValue];
  173. } else {
  174. pushshiftRequestTimeoutValue = 10;
  175. }
  176. } else {
  177. isAntennaEnabled = YES;
  178. isTFDeletedOnly = YES;
  179. pushshiftRequestTimeoutValue = 10;
  180. }
  181. }
  182. static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
  183. loadPrefs();
  184. }
  185. %ctor{
  186. loadPrefs();
  187. NSString* processName = [[NSProcessInfo processInfo] processName];
  188. if ([processName isEqualToString:@"amrc"]){
  189. if (isAntennaEnabled){
  190. CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
  191. %init(Antenna, RCCommentSwift = objc_getClass("amrc.RCCommentSwift"), RCPostSwift = objc_getClass("amrc.RCPostSwift"), RCCommentTextSwift = objc_getClass("amrc.RCCommentTextSwift"));
  192. }
  193. }
  194. }