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ů.

390 lines
13KB

  1. #import "Reddit.h"
  2. %group Redditv4
  3. %hook CommentTreeNode
  4. %property(assign,nonatomic)id commentTreeHeaderNode;
  5. %property(assign,nonatomic)id commentTreeCommandBarNode;
  6. %end
  7. %hook CommentTreeHeaderNode
  8. -(void) didLoad{
  9. %orig;
  10. [[self commentTreeNode] setCommentTreeHeaderNode:self];
  11. }
  12. %end
  13. %hook CommentTreeCommandBarNode
  14. %property(assign,nonatomic) id activityIndicator;
  15. %property(assign,nonatomic) id undeleteButton;
  16. -(void) didLoad{
  17. %orig;
  18. [[self commentTreeNode] setCommentTreeCommandBarNode:self];
  19. }
  20. %end
  21. %hook CommentActionSheetViewController
  22. -(void) setItems:(id) arg1{
  23. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  24. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  25. CGFloat scale = origImage.size.width / existingImageSize.width;
  26. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  27. id undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self comment]];
  28. %orig([arg1 arrayByAddingObject:undeleteItem]);
  29. [undeleteItem release];
  30. }
  31. -(void) handleDidSelectActionSheetItem:(id) arg1{
  32. %orig;
  33. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  34. [self dismissViewControllerAnimated:YES completion:nil];
  35. id commentTreeNode = [self commentTreeNode];
  36. id comment = [commentTreeNode comment];
  37. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  38. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  39. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment pk] componentsSeparatedByString:@"_"][1]]]];
  40. [request setHTTPMethod:@"GET"];
  41. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  42. NSString *author = @"[author]";
  43. NSString *body = @"[body]";
  44. if (data != nil && error == nil){
  45. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  46. if ([[jsonData objectForKey:@"data"] count] != 0){
  47. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  48. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  49. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  50. body = @"[pushshift was unable to archive this]";
  51. }
  52. } else {
  53. body = @"[pushshift has not archived this yet]";
  54. }
  55. } else if (error != nil || data == nil){
  56. body = @"[an error occured]";
  57. }
  58. NSArray* appVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] componentsSeparatedByString:@"."];
  59. id themeManager;
  60. id isNightMode;
  61. id textColor;
  62. if ([appVersion[1] integerValue] >= 45){
  63. themeManager = [[%c(ThemeManager) alloc] initWithAppSettings:[%c(AppSettings) sharedSettings]];
  64. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  65. if (isNightMode) {
  66. textColor = [[themeManager darkTheme] bodyTextColor];
  67. } else{
  68. textColor = [[themeManager lightTheme] bodyTextColor];
  69. }
  70. } else {
  71. themeManager = [[%c(ThemeManager) alloc] initWithTraitCollection:nil appSettings:[%c(AppSettings) sharedSettings]];
  72. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  73. if (isNightMode) {
  74. textColor = [[themeManager nightTheme] bodyTextColor];
  75. } else{
  76. textColor = [[themeManager dayTheme] bodyTextColor];
  77. }
  78. }
  79. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  80. [bodyMutableAttributedText beginEditing];
  81. [bodyMutableAttributedText enumerateAttribute:NSForegroundColorAttributeName inRange:NSMakeRange(0, bodyMutableAttributedText.length) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
  82. [bodyMutableAttributedText removeAttribute:NSForegroundColorAttributeName range:range];
  83. [bodyMutableAttributedText addAttribute:NSForegroundColorAttributeName value:textColor range:range];
  84. }];
  85. [bodyMutableAttributedText endEditing];
  86. [comment setValue:bodyMutableAttributedText forKey:@"bodyRichTextAttributed"];
  87. [comment setValue:author forKey:@"author"];
  88. [comment setValue:body forKey:@"bodyText"];
  89. [comment setValue:bodyMutableAttributedText forKey:@"bodyAttributedText"];
  90. [[commentTreeNode commentTreeHeaderNode] updateContentViewsForData:comment];
  91. [request release];
  92. [queue release];
  93. [bodyMutableAttributedText release];
  94. [themeManager release];
  95. }];
  96. }
  97. }
  98. %end
  99. %hook PostDetailViewController
  100. %property(assign,nonatomic) id feedPostTextWithThumbnailNode;
  101. %property(assign,nonatomic) id feedPostDetailCellNode;
  102. %end
  103. %hook FeedPostDetailCellNode
  104. -(void) didLoad{
  105. %orig;
  106. [[[self delegate] viewController] setFeedPostDetailCellNode:self];
  107. }
  108. %end
  109. %hook PostActionSheetViewController
  110. -(void) setItems:(id) arg1{
  111. id post = [self post];
  112. if ([post isSelfPost]){
  113. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  114. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  115. CGFloat scale = origImage.size.width / existingImageSize.width;
  116. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  117. id undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self post]];
  118. arg1 = [arg1 arrayByAddingObject:undeleteItem];
  119. [undeleteItem release];
  120. }
  121. %orig;
  122. }
  123. -(void) handleDidSelectActionSheetItem:(id) arg1{
  124. %orig;
  125. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  126. [self dismissViewControllerAnimated:YES completion:nil];
  127. id post = [self post];
  128. if ([post isSelfPost]){
  129. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  130. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  131. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post pk] componentsSeparatedByString:@"_"][1]]]];
  132. [request setHTTPMethod:@"GET"];
  133. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  134. NSString *author = @"[author]";
  135. NSString *body = @"[body]";
  136. if (data != nil && error == nil){
  137. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  138. if ([[jsonData objectForKey:@"data"] count] != 0){
  139. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  140. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  141. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  142. body = @"[pushshift was unable to archive this]";
  143. }
  144. } else {
  145. body = @"[pushshift has not archived this yet]";
  146. }
  147. } else if (error != nil || data == nil){
  148. body = @"[an error occured]";
  149. }
  150. NSArray* appVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] componentsSeparatedByString:@"."];
  151. id themeManager;
  152. id isNightMode;
  153. id textColor;
  154. if ([appVersion[1] integerValue] >= 45){
  155. themeManager = [[%c(ThemeManager) alloc] initWithAppSettings:[%c(AppSettings) sharedSettings]];
  156. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  157. if (isNightMode) {
  158. textColor = [[themeManager darkTheme] bodyTextColor];
  159. } else{
  160. textColor = [[themeManager lightTheme] bodyTextColor];
  161. }
  162. } else {
  163. themeManager = [[%c(ThemeManager) alloc] initWithTraitCollection:nil appSettings:[%c(AppSettings) sharedSettings]];
  164. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  165. if (isNightMode) {
  166. textColor = [[themeManager nightTheme] bodyTextColor];
  167. } else{
  168. textColor = [[themeManager dayTheme] bodyTextColor];
  169. }
  170. }
  171. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  172. [bodyMutableAttributedText beginEditing];
  173. [bodyMutableAttributedText enumerateAttribute:NSForegroundColorAttributeName inRange:NSMakeRange(0, bodyMutableAttributedText.length) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
  174. [bodyMutableAttributedText removeAttribute:NSForegroundColorAttributeName range:range];
  175. [bodyMutableAttributedText addAttribute:NSForegroundColorAttributeName value:textColor range:range];
  176. }];
  177. [bodyMutableAttributedText endEditing];
  178. [post setValue:bodyMutableAttributedText forKey:@"selfPostRichTextAttributed"];
  179. [post setValue:bodyMutableAttributedText forKey:@"previewFeedPostTextString"];
  180. [post setAuthor:author];
  181. [post setValue:body forKey:@"selfText"];
  182. if ([appVersion[1] integerValue] >= 44){
  183. [[[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] contentNode] configureSelfTextNode];
  184. } else {
  185. [[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] configureSelfTextNode];
  186. }
  187. [request release];
  188. [queue release];
  189. [bodyMutableAttributedText release];
  190. [themeManager release];
  191. }];
  192. }
  193. }
  194. }
  195. %end
  196. %end
  197. %group Redditv3
  198. %hook CommentView
  199. %new
  200. -(void) buttonAction {
  201. id commentsViewController = [self delegate];
  202. id comment = [self comment];
  203. NSError* error;
  204. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  205. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[comment pkWithoutPrefix]]]];
  206. [request setHTTPMethod:@"GET"];
  207. NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
  208. NSString *author = @"[author]";
  209. NSString *body = @"[body]";
  210. if (data != nil && error == nil){
  211. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  212. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  213. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  214. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  215. body = @"[comment was unable to be archived]";
  216. }
  217. } else if (error != nil || data == nil){
  218. body = @"[an error occured]";
  219. }
  220. [comment setValue:author forKey:@"author"];
  221. [comment setValue:[%c(MarkDownParser) attributedStringFromMarkdownString: body] forKey:@"bodyAttributedText"];
  222. [comment setValue:body forKey:@"bodyText"];
  223. [commentsViewController reloadCommentsWithNewCommentsHighlight:NO autoScroll:NO animated:NO];
  224. }
  225. -(id) initWithFrame:(id)arg1{
  226. id orig = %orig;
  227. id commandView = [self commandView];
  228. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  229. [undeleteButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
  230. UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  231. [undeleteButton setImage:undeleteImage forState:UIControlStateNormal];
  232. [commandView setUndeleteButton:undeleteButton];
  233. [commandView addSubview:undeleteButton];
  234. return orig;
  235. }
  236. %end
  237. %hook CommentCommandView
  238. %property (assign, nonatomic) id undeleteButton;
  239. -(void) layoutSubviews{
  240. %orig;
  241. UIButton *button = [self undeleteButton];
  242. button.frame = CGRectMake([[self overflowButton ] frame].origin.x - 32, 0, 32, 32);
  243. }
  244. %end
  245. %end
  246. %ctor{
  247. NSString* processName = [[NSProcessInfo processInfo] processName];
  248. NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  249. NSArray* versionArray = [version componentsSeparatedByString:@"."];
  250. if ([processName isEqualToString:@"Reddit"]){
  251. if ([versionArray[0] isEqualToString:@"4"]){
  252. %init(Redditv4);
  253. } else if ([versionArray[0] isEqualToString:@"3"]) {
  254. %init(Redditv3);
  255. }
  256. }
  257. }