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.

768 lines
24KB

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