選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Reddit.xm 28KB

5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  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. }