Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

244 lines
8.5KB

  1. #import "Apollo.h"
  2. %group Apollo
  3. const NSDictionary* settings = [[NSDictionary alloc] initWithContentsOfFile:@"/var/mobile/Library/Preferences/com.lint.undelete.prefs.plist"];
  4. NSDictionary* apolloBodyAttributes = nil;
  5. %hook ApolloApolloButtonNode
  6. %end
  7. %hook RKComment
  8. -(BOOL) isDeleted{
  9. return NO;
  10. }
  11. -(BOOL) isModeratorRemoved{
  12. return NO;
  13. }
  14. %end
  15. %hook MarkdownRenderer
  16. +(id) attributedStringFromHTML:(id)arg1 attributes:(id) arg2 compact:(BOOL) arg3{
  17. apolloBodyAttributes = [arg2 copy];
  18. return %orig;
  19. }
  20. %end
  21. %hook ApolloCommentCellNode
  22. %property(strong,nonatomic) id undeleteButton;
  23. %new
  24. -(void) didTapUndeleteButton:(id) sender{
  25. [sender setEnabled:NO];
  26. id bodyNode = MSHookIvar<id>(self, "bodyNode");
  27. id authorNode = MSHookIvar<id>(self, "authorNode");
  28. id authorTextNode = [authorNode subnodes][0];
  29. id comment = MSHookIvar<id>(self, "comment");
  30. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  31. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  32. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment fullName] componentsSeparatedByString:@"_"][1]]]];
  33. [request setHTTPMethod:@"GET"];
  34. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  35. NSString *author = @"[author]";
  36. NSString *body = @"[body]";
  37. if (data != nil && error == nil){
  38. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  39. if ([[jsonData objectForKey:@"data"] count] != 0){
  40. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  41. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  42. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  43. body = @"[pushshift was unable to archive this]";
  44. }
  45. } else {
  46. body = @"[pushshift has not archived this yet]";
  47. }
  48. } else if (error != nil || data == nil){
  49. body = @"[an error occured]";
  50. }
  51. id prevAuthorAttributedString = [authorTextNode attributedString];
  52. NSDictionary *authorStringAttributes = [prevAuthorAttributedString attributesAtIndex:0 longestEffectiveRange:nil inRange:NSMakeRange(0, [prevAuthorAttributedString length])];
  53. NSAttributedString* newAuthorAttributedString = [[NSAttributedString alloc] initWithString:author attributes:authorStringAttributes];
  54. [authorTextNode setAttributedText:newAuthorAttributedString];
  55. [authorTextNode setAttributedString:newAuthorAttributedString];
  56. [comment setAuthor:author];
  57. [bodyNode setAttributedString:[%c(MarkdownRenderer) attributedStringFromMarkdown:body withAttributes:apolloBodyAttributes]];
  58. [sender setEnabled:YES];
  59. }];
  60. }
  61. -(void) didLoad {
  62. %orig;
  63. id commentBody = [MSHookIvar<id>(self, "comment") body];
  64. id isDeletedOnly = [settings valueForKey:@"isApolloDeletedCommentsOnly"];
  65. if (([isDeletedOnly isEqual:@1] && ([commentBody isEqualToString:@"[deleted]"] || [commentBody isEqualToString:@"[removed]"])) || [isDeletedOnly isEqual:@0] ) {
  66. CGFloat imageSize = 20.0f;
  67. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  68. [undeleteButton addTarget:self action:@selector(didTapUndeleteButton:) forControlEvents:UIControlEventTouchUpInside];
  69. undeleteButton.frame = CGRectMake(0, 0, imageSize, imageSize);
  70. UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  71. [undeleteButton setImage:undeleteImage forState:UIControlStateNormal];
  72. [[self view] addSubview:undeleteButton];
  73. [self setUndeleteButton:undeleteButton];
  74. }
  75. }
  76. -(void) _layoutSublayouts{
  77. %orig;
  78. if ([self undeleteButton]){
  79. CGFloat imageSize = 20.0f;
  80. id moreNode = MSHookIvar<id>(self, "moreOptionsNode");
  81. id ageNode = MSHookIvar<id>(self, "ageNode");
  82. CGRect nodeFrame = [moreNode frame];
  83. CGFloat centerHeight = (nodeFrame.size.height + nodeFrame.origin.y * 2) / 2.0f;
  84. CGFloat nodeSpacing =[ageNode frame].origin.x - nodeFrame.origin.x - nodeFrame.size.width;
  85. [[self undeleteButton] setFrame:CGRectMake(nodeFrame.origin.x - imageSize - nodeSpacing, centerHeight - (imageSize / 2), imageSize, imageSize)];
  86. }
  87. }
  88. %end
  89. %hook ApolloCommentsHeaderCellNode
  90. %property(strong, nonatomic) id undeleteButton;
  91. %new
  92. -(void) didTapUndeleteButton:(id) sender{
  93. [sender setEnabled:NO];
  94. id bodyNode = MSHookIvar<id>(self, "bodyNode");
  95. id postInfoNode = MSHookIvar<id>(self, "postInfoNode");
  96. id authorNode = MSHookIvar<id>(postInfoNode, "authorButtonNode");
  97. id authorTextNode = [authorNode subnodes][0];
  98. id post = MSHookIvar<id>(self, "link");
  99. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  100. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  101. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post fullName] componentsSeparatedByString:@"_"][1]]]];
  102. [request setHTTPMethod:@"GET"];
  103. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  104. NSString *author = @"[author]";
  105. NSString *body = @"[body]";
  106. if (data != nil && error == nil){
  107. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  108. if ([[jsonData objectForKey:@"data"] count] != 0){
  109. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  110. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  111. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  112. body = @"[pushshift was unable to archive this]";
  113. }
  114. } else {
  115. body = @"[pushshift has not archived this yet]";
  116. }
  117. } else if (error != nil || data == nil){
  118. body = @"[an error occured]";
  119. }
  120. //MSHookIvar<NSString*>(post, "_author") = author; //Crashes when clicking on author name. You will have to search the author name to go find the profile.
  121. author = [NSString stringWithFormat:@"by %@", author];
  122. id prevAuthorAttributedString = [authorTextNode attributedString];
  123. NSDictionary *authorStringAttributes = [prevAuthorAttributedString attributesAtIndex:0 longestEffectiveRange:nil inRange:NSMakeRange(0, [prevAuthorAttributedString length])];
  124. NSAttributedString* newAuthorAttributedString = [[NSAttributedString alloc] initWithString:author attributes:authorStringAttributes];
  125. [authorTextNode setAttributedText:newAuthorAttributedString];
  126. [authorTextNode setAttributedString:newAuthorAttributedString];
  127. [bodyNode setAttributedString:[%c(MarkdownRenderer) attributedStringFromMarkdown:body withAttributes:apolloBodyAttributes]];
  128. [sender setEnabled:YES];
  129. }];
  130. }
  131. -(void) didLoad{
  132. %orig;
  133. if ([MSHookIvar<id>(self, "link") isSelfPost]){
  134. CGFloat imageSize = 20.0f;
  135. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  136. [undeleteButton addTarget:self action:@selector(didTapUndeleteButton:) forControlEvents:UIControlEventTouchUpInside];
  137. UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  138. [undeleteButton setImage:undeleteImage forState:UIControlStateNormal];
  139. undeleteButton.frame = CGRectMake(0, 0, imageSize, imageSize);
  140. [[self view] addSubview:undeleteButton];
  141. [self setUndeleteButton:undeleteButton];
  142. }
  143. }
  144. -(void) _layoutSublayouts{
  145. %orig;
  146. if ([self undeleteButton]){
  147. CGFloat imageSize = 20.0f;
  148. id postInfoNode = MSHookIvar<id>(self, "postInfoNode");
  149. id ageNode = MSHookIvar<id>(postInfoNode, "ageButtonNode");
  150. CGFloat centerHeight = [postInfoNode frame].origin.y + ([ageNode frame].size.height + [ageNode frame].origin.y * 2) / 2.0f;
  151. CGFloat buttonXPos = [postInfoNode frame].origin.x + [postInfoNode frame].size.width - imageSize;
  152. [[self undeleteButton] setFrame:CGRectMake(buttonXPos, centerHeight - (imageSize / 2), imageSize, imageSize)];
  153. }
  154. }
  155. %end
  156. %end
  157. %ctor {
  158. NSString* processName = [[NSProcessInfo processInfo] processName];
  159. if ([processName isEqualToString:@"Apollo"]){
  160. %init(Apollo, ApolloCommentsHeaderCellNode = objc_getClass("Apollo.CommentsHeaderCellNode"), ApolloCommentCellNode = objc_getClass("Apollo.CommentCellNode"), ApolloApolloButtonNode = objc_getClass("Apollo.ApolloButtonNode"));
  161. }
  162. }