Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

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