You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

807 lines
28KB

  1. #import "Reddit.h"
  2. static BOOL isRedditEnabled;
  3. static BOOL isTFDeletedOnly;
  4. static CGFloat pushshiftRequestTimeoutValue;
  5. static NSArray *redditVersion;
  6. int getRedditVersionPart(int index){
  7. if (![redditVersion[index] isEqual:[NSNull null]]){
  8. return [redditVersion[index] intValue];
  9. } else {
  10. NSArray *newVersionArray = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] componentsSeparatedByString:@"."];
  11. if (![newVersionArray[index] isEqual:[NSNull null]]){
  12. return [newVersionArray[index] intValue];
  13. } else {
  14. return [@[@4, @48, @1][index] intValue];
  15. }
  16. }
  17. }
  18. %group Reddit_v4_current
  19. %hook CommentTreeNode
  20. %property(assign,nonatomic)id commentTreeHeaderNode;
  21. %property(assign,nonatomic)id commentTreeCommandBarNode;
  22. %end
  23. %hook CommentTreeHeaderView
  24. -(void) layoutSubviews{
  25. %orig;
  26. [[self commentTreeNode] setCommentTreeHeaderNode:self];
  27. }
  28. %end
  29. %hook CommentTreeHeaderNode
  30. -(void) didLoad{
  31. %orig;
  32. [[self commentTreeNode] setCommentTreeHeaderNode:self];
  33. }
  34. %end
  35. %hook CommentTreeCommandBarNode
  36. -(void) didLoad{
  37. %orig;
  38. [[self commentTreeNode] setCommentTreeCommandBarNode:self];
  39. }
  40. %end
  41. %hook CommentActionSheetViewController
  42. -(void) setItems:(id) arg1{
  43. NSString *commentBody = [[self comment] bodyText];
  44. if ((isTFDeletedOnly && ([commentBody isEqualToString:@"[deleted]"] || [commentBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){
  45. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  46. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  47. CGFloat scale = origImage.size.width / existingImageSize.width;
  48. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  49. id undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self comment]];
  50. arg1 = [arg1 arrayByAddingObject:undeleteItem];
  51. [undeleteItem release];
  52. }
  53. %orig;
  54. }
  55. -(void) handleDidSelectActionSheetItem:(id) arg1{
  56. %orig;
  57. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  58. [self dismissViewControllerAnimated:YES completion:nil];
  59. id commentTreeNode = [self commentTreeNode];
  60. Comment *comment = [commentTreeNode comment];
  61. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  62. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  63. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment pk] componentsSeparatedByString:@"_"][1]]]];
  64. [request setHTTPMethod:@"GET"];
  65. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  66. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  67. NSString *author = @"[author]";
  68. NSString *body = @"[body]";
  69. if (data != nil && error == nil){
  70. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  71. if ([[jsonData objectForKey:@"data"] count] != 0){
  72. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  73. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  74. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  75. body = @"[pushshift was unable to archive this]";
  76. }
  77. } else {
  78. body = @"[pushshift has not archived this yet]";
  79. }
  80. } else if (error != nil || data == nil){
  81. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  82. }
  83. NSMutableAttributedString *bodyMutableAttributedText;
  84. id themeManager;
  85. id isNightMode;
  86. id textColor;
  87. if (getRedditVersionPart(1) >= 45){
  88. themeManager = [[%c(ThemeManager) alloc] initWithAppSettings:[%c(AppSettings) sharedSettings]];
  89. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  90. if (isNightMode) {
  91. textColor = [[themeManager darkTheme] bodyTextColor];
  92. } else{
  93. textColor = [[themeManager lightTheme] bodyTextColor];
  94. }
  95. [themeManager release];
  96. } else if (getRedditVersionPart(1) >= 37){
  97. themeManager = [[%c(ThemeManager) alloc] initWithTraitCollection:nil appSettings:[%c(AppSettings) sharedSettings]];
  98. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  99. if (isNightMode) {
  100. textColor = [[themeManager nightTheme] bodyTextColor];
  101. } else{
  102. textColor = [[themeManager dayTheme] bodyTextColor];
  103. }
  104. [themeManager release];
  105. } else {
  106. themeManager = [%c(ThemeManager) sharedManager];
  107. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  108. if (isNightMode) {
  109. textColor = [[themeManager nightTheme] bodyTextColor];
  110. } else{
  111. textColor = [[themeManager dayTheme] bodyTextColor];
  112. }
  113. }
  114. bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  115. [bodyMutableAttributedText beginEditing];
  116. [bodyMutableAttributedText enumerateAttribute:NSForegroundColorAttributeName inRange:NSMakeRange(0, bodyMutableAttributedText.length) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
  117. [bodyMutableAttributedText removeAttribute:NSForegroundColorAttributeName range:range];
  118. [bodyMutableAttributedText addAttribute:NSForegroundColorAttributeName value:textColor range:range];
  119. }];
  120. [bodyMutableAttributedText endEditing];
  121. [comment setAuthor:author];
  122. [comment setBodyText:body];
  123. [comment setBodyRichTextAttributed:bodyMutableAttributedText];
  124. [comment setBodyAttributedText:bodyMutableAttributedText];
  125. [[commentTreeNode commentTreeHeaderNode] performSelectorOnMainThread:@selector(updateContentViewsForData:) withObject:comment waitUntilDone:NO];
  126. [request release];
  127. [queue release];
  128. [bodyMutableAttributedText release];
  129. }];
  130. }
  131. }
  132. %end
  133. %hook PostDetailViewController
  134. %property(strong,nonatomic) id feedPostTextWithThumbnailNode;
  135. %property(strong,nonatomic) id feedPostDetailCellNode;
  136. %end
  137. %hook FeedPostDetailCellNode
  138. -(void) didLoad{
  139. %orig;
  140. [[[self delegate] viewController] setFeedPostDetailCellNode:self];
  141. }
  142. %end
  143. %hook PostActionSheetViewController
  144. -(void) setItems:(id) arg1{
  145. Post *post = [self post];
  146. NSString *postBody = [post selfText];
  147. if ([post isSelfPost]){
  148. if ((isTFDeletedOnly && ([postBody isEqualToString:@"[deleted]"] || [postBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){
  149. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  150. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  151. CGFloat scale = origImage.size.width / existingImageSize.width;
  152. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  153. id undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self post]];
  154. arg1 = [arg1 arrayByAddingObject:undeleteItem];
  155. [undeleteItem release];
  156. }
  157. }
  158. %orig;
  159. }
  160. -(void) handleDidSelectActionSheetItem:(id) arg1{
  161. %orig;
  162. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  163. [self dismissViewControllerAnimated:YES completion:nil];
  164. Post *post = [self post];
  165. if ([post isSelfPost]){
  166. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  167. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  168. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post pk] componentsSeparatedByString:@"_"][1]]]];
  169. [request setHTTPMethod:@"GET"];
  170. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  171. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  172. NSString *author = @"[author]";
  173. NSString *body = @"[body]";
  174. if (data != nil && error == nil){
  175. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  176. if ([[jsonData objectForKey:@"data"] count] != 0){
  177. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  178. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  179. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  180. body = @"[pushshift was unable to archive this]";
  181. }
  182. } else {
  183. body = @"[pushshift has not archived this yet]";
  184. }
  185. } else if (error != nil || data == nil){
  186. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  187. }
  188. id themeManager;
  189. id isNightMode;
  190. id textColor;
  191. if (getRedditVersionPart(1) >= 45){
  192. themeManager = [[%c(ThemeManager) alloc] initWithAppSettings:[%c(AppSettings) sharedSettings]];
  193. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  194. if (isNightMode) {
  195. textColor = [[themeManager darkTheme] bodyTextColor];
  196. } else{
  197. textColor = [[themeManager lightTheme] bodyTextColor];
  198. }
  199. [themeManager release];
  200. } else if (getRedditVersionPart(1) >= 37){
  201. themeManager = [[%c(ThemeManager) alloc] initWithTraitCollection:nil appSettings:[%c(AppSettings) sharedSettings]];
  202. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  203. if (isNightMode) {
  204. textColor = [[themeManager nightTheme] bodyTextColor];
  205. } else{
  206. textColor = [[themeManager dayTheme] bodyTextColor];
  207. }
  208. [themeManager release];
  209. } else {
  210. themeManager = [%c(ThemeManager) sharedManager];
  211. isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];
  212. if (isNightMode) {
  213. textColor = [[themeManager nightTheme] bodyTextColor];
  214. } else{
  215. textColor = [[themeManager dayTheme] bodyTextColor];
  216. }
  217. }
  218. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  219. [bodyMutableAttributedText beginEditing];
  220. [bodyMutableAttributedText enumerateAttribute:NSForegroundColorAttributeName inRange:NSMakeRange(0, bodyMutableAttributedText.length) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
  221. [bodyMutableAttributedText removeAttribute:NSForegroundColorAttributeName range:range];
  222. [bodyMutableAttributedText addAttribute:NSForegroundColorAttributeName value:textColor range:range];
  223. }];
  224. [bodyMutableAttributedText endEditing];
  225. [post setSelfText:body];
  226. [post setAuthor:author];
  227. [post setSelfPostRichTextAttributed:bodyMutableAttributedText];
  228. [post setPreviewFeedPostTextString:bodyMutableAttributedText];
  229. if (getRedditVersionPart(1) >= 44){
  230. [[[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] contentNode] configureSelfTextNode];
  231. } else if (getRedditVersionPart(1) >= 38) {
  232. [[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] configureSelfTextNode];
  233. } else {
  234. [[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] configureSelfTextNode];
  235. [[[[[self postActionSheetDelegate] controller] feedPostDetailCellNode] titleNode] configureNodes];
  236. }
  237. [request release];
  238. [queue release];
  239. [bodyMutableAttributedText release];
  240. }];
  241. }
  242. }
  243. }
  244. %end
  245. %end
  246. %group Reddit_v4_ios10
  247. %hook CommentsViewController
  248. %new
  249. -(void) updateComments{
  250. [self reloadCommentsWithNewCommentsHighlight:NO autoScroll:NO animated:NO];
  251. }
  252. %new
  253. -(void) updatePostText{
  254. if (getRedditVersionPart(1) >= 2){
  255. [self reloadPostSection:YES];
  256. } else {
  257. [self feedPostViewDidUpdatePost:[self postData] shouldReloadFeed:NO];
  258. }
  259. }
  260. %end
  261. %hook CommentActionSheetViewController
  262. -(void) setItems:(id) arg1{
  263. NSString *commentBody = [[self comment] bodyText];
  264. if ((isTFDeletedOnly && ([commentBody isEqualToString:@"[deleted]"] || [commentBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){
  265. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  266. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  267. CGFloat scale = origImage.size.width / existingImageSize.width;
  268. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  269. id undeleteItem;
  270. if (getRedditVersionPart(1) >= 18) {
  271. undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self comment]];
  272. } else {
  273. undeleteItem = [[%c(ActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self comment]];
  274. }
  275. arg1 = [arg1 arrayByAddingObject:undeleteItem];
  276. [undeleteItem release];
  277. }
  278. %orig;
  279. }
  280. // >= 4.21
  281. -(void) handleDidSelectActionSheetItem:(id) arg1{
  282. %orig;
  283. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  284. [self dismissViewControllerAnimated:YES completion:nil];
  285. Comment *comment = [self comment];
  286. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  287. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  288. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment pk] componentsSeparatedByString:@"_"][1]]]];
  289. [request setHTTPMethod:@"GET"];
  290. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  291. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  292. NSString *author = @"[author]";
  293. NSString *body = @"[body]";
  294. if (data != nil && error == nil){
  295. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  296. if ([[jsonData objectForKey:@"data"] count] != 0){
  297. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  298. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  299. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  300. body = @"[pushshift was unable to archive this]";
  301. }
  302. } else {
  303. body = @"[pushshift has not archived this yet]";
  304. }
  305. } else if (error != nil || data == nil){
  306. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  307. }
  308. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  309. [comment setAuthor:author];
  310. [comment setBodyText:body];
  311. [comment setBodyRichTextAttributed:bodyMutableAttributedText];
  312. [comment setBodyAttributedText:bodyMutableAttributedText];
  313. [[self commentActionSheetDelegate] performSelectorOnMainThread:@selector(updateComments) withObject:nil waitUntilDone:NO];
  314. [request release];
  315. [queue release];
  316. [bodyMutableAttributedText release];
  317. }];
  318. }
  319. }
  320. // <= 4.20
  321. -(void) actionSheetViewController:(id) arg1 didSelectItem:(id) arg2{
  322. %orig;
  323. if ([[arg2 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  324. [self dismissViewControllerAnimated:YES completion:nil];
  325. Comment *comment = [self comment];
  326. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  327. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  328. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment pk] componentsSeparatedByString:@"_"][1]]]];
  329. [request setHTTPMethod:@"GET"];
  330. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  331. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  332. NSString *author = @"[author]";
  333. NSString *body = @"[body]";
  334. if (data != nil && error == nil){
  335. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  336. if ([[jsonData objectForKey:@"data"] count] != 0){
  337. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  338. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  339. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  340. body = @"[pushshift was unable to archive this]";
  341. }
  342. } else {
  343. body = @"[pushshift has not archived this yet]";
  344. }
  345. } else if (error != nil || data == nil){
  346. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  347. }
  348. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  349. [comment setAuthor:author];
  350. [comment setBodyText:body];
  351. [comment setBodyAttributedText:bodyMutableAttributedText];
  352. if (getRedditVersionPart(1) >= 12) {
  353. [comment setBodyRichTextAttributed:bodyMutableAttributedText];
  354. }
  355. [[self commentActionSheetDelegate] performSelectorOnMainThread:@selector(updateComments) withObject:nil waitUntilDone:NO];
  356. [request release];
  357. [queue release];
  358. [bodyMutableAttributedText release];
  359. }];
  360. }
  361. }
  362. %end
  363. %hook PostActionSheetViewController
  364. -(void) setItems:(id) arg1{
  365. Post *post = [self post];
  366. NSString *postBody = [post selfText];
  367. if ([post isSelfPost]){
  368. if ((isTFDeletedOnly && ([postBody isEqualToString:@"[deleted]"] || [postBody isEqualToString:@"[removed]"])) || !isTFDeletedOnly){
  369. UIImage* origImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  370. CGSize existingImageSize = [[arg1[0] leftIconImage] size];
  371. CGFloat scale = origImage.size.width / existingImageSize.width;
  372. UIImage *newImage = [UIImage imageWithCGImage:[origImage CGImage] scale:scale orientation:origImage.imageOrientation];
  373. id undeleteItem;
  374. if (getRedditVersionPart(1) >= 18) {
  375. undeleteItem = [[%c(RUIActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self post]];
  376. } else {
  377. undeleteItem = [[%c(ActionSheetItem) alloc] initWithLeftIconImage:newImage text:@"TF did that say?" identifier:@"undeleteItemIdentifier" context:[self post]];
  378. }
  379. arg1 = [arg1 arrayByAddingObject:undeleteItem];
  380. [undeleteItem release];
  381. }
  382. }
  383. %orig;
  384. }
  385. // >= 4.21
  386. -(void) handleDidSelectActionSheetItem:(id) arg1{
  387. %orig;
  388. if ([[arg1 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  389. [self dismissViewControllerAnimated:YES completion:nil];
  390. Post *post = [self post];
  391. if ([post isSelfPost]){
  392. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  393. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  394. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post pk] componentsSeparatedByString:@"_"][1]]]];
  395. [request setHTTPMethod:@"GET"];
  396. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  397. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  398. NSString *author = @"[author]";
  399. NSString *body = @"[body]";
  400. if (data != nil && error == nil){
  401. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  402. if ([[jsonData objectForKey:@"data"] count] != 0){
  403. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  404. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  405. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  406. body = @"[pushshift was unable to archive this]";
  407. }
  408. } else {
  409. body = @"[pushshift has not archived this yet]";
  410. }
  411. } else if (error != nil || data == nil){
  412. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  413. }
  414. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  415. [post setSelfText:body];
  416. [post setAuthor:author];
  417. [post setSelfPostRichTextAttributed:bodyMutableAttributedText];
  418. [post setPreviewFeedPostTextString:bodyMutableAttributedText];
  419. [[self postActionSheetDelegate] performSelectorOnMainThread:@selector(updatePostText) withObject:nil waitUntilDone:NO];
  420. [request release];
  421. [queue release];
  422. [bodyMutableAttributedText release];
  423. }];
  424. }
  425. }
  426. }
  427. // <= 4.20
  428. -(void) actionSheetViewController:(id) arg1 didSelectItem:(id) arg2{
  429. %orig;
  430. if ([[arg2 identifier] isEqualToString:@"undeleteItemIdentifier"]){
  431. [self dismissViewControllerAnimated:YES completion:nil];
  432. Post *post = [self post];
  433. if ([post isSelfPost]){
  434. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  435. NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  436. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post pk] componentsSeparatedByString:@"_"][1]]]];
  437. [request setHTTPMethod:@"GET"];
  438. [request setTimeoutInterval:pushshiftRequestTimeoutValue];
  439. [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  440. NSString *author = @"[author]";
  441. NSString *body = @"[body]";
  442. if (data != nil && error == nil){
  443. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  444. if ([[jsonData objectForKey:@"data"] count] != 0){
  445. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  446. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
  447. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  448. body = @"[pushshift was unable to archive this]";
  449. }
  450. } else {
  451. body = @"[pushshift has not archived this yet]";
  452. }
  453. } else if (error != nil || data == nil){
  454. body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
  455. }
  456. NSMutableAttributedString *bodyMutableAttributedText = [[NSMutableAttributedString alloc] initWithAttributedString:[%c(NSAttributedStringMarkdownParser) attributedStringUsingCurrentConfig:body]];
  457. [post setAuthor:author];
  458. [post setSelfText:body];
  459. [post setSelfTextAttributed:bodyMutableAttributedText];
  460. if (getRedditVersionPart(1) >= 8) {
  461. [post setSelfPostRichTextAttributed:bodyMutableAttributedText];
  462. }
  463. if (getRedditVersionPart(1) >= 15) {
  464. [post setPreviewFeedPostTextString:bodyMutableAttributedText];
  465. }
  466. [[self postActionSheetDelegate] performSelectorOnMainThread:@selector(updatePostText) withObject:nil waitUntilDone:NO];
  467. [request release];
  468. [queue release];
  469. [bodyMutableAttributedText release];
  470. }];
  471. }
  472. }
  473. }
  474. %end
  475. %end
  476. //outdated and unchanged from first version of this tweak...
  477. //TODO: move button to menu, add post support, make async requests once I feel like doing it
  478. %group Reddit_v3
  479. %hook CommentView
  480. %new
  481. -(void) buttonAction {
  482. id commentsViewController = [self delegate];
  483. id comment = [self comment];
  484. NSError* error;
  485. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  486. [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[comment pkWithoutPrefix]]]];
  487. [request setHTTPMethod:@"GET"];
  488. NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
  489. NSString *author = @"[author]";
  490. NSString *body = @"[body]";
  491. if (data != nil && error == nil){
  492. id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
  493. author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
  494. body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
  495. if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
  496. body = @"[comment was unable to be archived]";
  497. }
  498. } else if (error != nil || data == nil){
  499. body = @"[an error occured]";
  500. }
  501. [comment setValue:author forKey:@"author"];
  502. [comment setValue:[%c(MarkDownParser) attributedStringFromMarkdownString: body] forKey:@"bodyAttributedText"];
  503. [comment setValue:body forKey:@"bodyText"];
  504. [commentsViewController reloadCommentsWithNewCommentsHighlight:NO autoScroll:NO animated:NO];
  505. }
  506. -(id) initWithFrame:(id)arg1{
  507. id orig = %orig;
  508. id commandView = [self commandView];
  509. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  510. [undeleteButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
  511. UIImage* undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"];
  512. [undeleteButton setImage:undeleteImage forState:UIControlStateNormal];
  513. [commandView setUndeleteButton:undeleteButton];
  514. [commandView addSubview:undeleteButton];
  515. return orig;
  516. }
  517. %end
  518. %hook CommentCommandView
  519. %property (assign, nonatomic) id undeleteButton;
  520. -(void) layoutSubviews{
  521. %orig;
  522. UIButton *button = [self undeleteButton];
  523. button.frame = CGRectMake([[self overflowButton ] frame].origin.x - 32, 0, 32, 32);
  524. }
  525. %end
  526. %end
  527. static void loadPrefs(){
  528. NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"];
  529. if (prefs){
  530. if ([prefs objectForKey:@"isRedditEnabled"] != nil){
  531. isRedditEnabled = [[prefs objectForKey:@"isRedditEnabled"] boolValue];
  532. } else {
  533. isRedditEnabled = YES;
  534. }
  535. if ([prefs objectForKey:@"isTFDeletedOnly"] != nil) {
  536. isTFDeletedOnly = [[prefs objectForKey:@"isTFDeletedOnly"] boolValue];
  537. } else {
  538. isTFDeletedOnly = YES;
  539. }
  540. if ([prefs objectForKey:@"requestTimeoutValue"] != nil){
  541. pushshiftRequestTimeoutValue = [[prefs objectForKey:@"requestTimeoutValue"] doubleValue];
  542. } else {
  543. pushshiftRequestTimeoutValue = 10;
  544. }
  545. } else {
  546. isRedditEnabled = YES;
  547. isTFDeletedOnly = YES;
  548. pushshiftRequestTimeoutValue = 10;
  549. }
  550. }
  551. static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
  552. loadPrefs();
  553. }
  554. %ctor{
  555. loadPrefs();
  556. NSString* processName = [[NSProcessInfo processInfo] processName];
  557. redditVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] componentsSeparatedByString:@"."];
  558. if ([processName isEqualToString:@"Reddit"]){
  559. if (isRedditEnabled) {
  560. CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
  561. if (getRedditVersionPart(0) == 4){
  562. if (getRedditVersionPart(1) <= 32){
  563. %init(Reddit_v4_ios10);
  564. } else{
  565. %init(Reddit_v4_current);
  566. }
  567. } else if (getRedditVersionPart(0) == 3) {
  568. %init(Reddit_v3);
  569. }
  570. }
  571. }
  572. }