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

Narwhal.xm 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #import "Narwhal.h"
  2. #import "assets/TFHelper.h"
  3. static BOOL isEnabled;
  4. static BOOL isNarwhalEnabled;
  5. static BOOL isTFDeletedOnly;
  6. static CGFloat pushshiftRequestTimeoutValue;
  7. %group Narwhal
  8. BOOL shouldHaveUndeleteAction = NO;
  9. id tfComment;
  10. id tfController;
  11. void getUndeleteCommentData(id controller, id comment){
  12. [%c(TFHelper) getUndeleteDataWithID:[[comment fullName] componentsSeparatedByString:@"_"][1] isComment:YES timeout:pushshiftRequestTimeoutValue extraData:@{@"comment" : comment} completionTarget:controller completionSelector:@selector(completeUndeleteCommentAction:)];
  13. }
  14. %hook UIViewController
  15. - (void)presentViewController:(id)arg1 animated:(BOOL)arg2 completion:(id)arg3 {
  16. if ([arg1 isKindOfClass:[UIAlertController class]] && shouldHaveUndeleteAction) {
  17. UIAlertAction* undeleteAction;
  18. if (tfComment) {
  19. undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){getUndeleteCommentData(tfController, tfComment);}];
  20. } else {
  21. undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){[tfController handleUndeletePostAction];}];
  22. }
  23. [arg1 addAction:undeleteAction];
  24. }
  25. %orig;
  26. }
  27. %end
  28. %hook NRTLinkViewController
  29. - (void)swipeCell:(id)arg1 didEndDragWithState:(NSUInteger)arg2 {
  30. if (arg2 == 2) {
  31. if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) {
  32. NSString *commentBody = MSHookIvar<NSString*>([arg1 comment], "_body");
  33. if ([%c(TFHelper) shouldShowUndeleteButtonWithInfo:commentBody isDeletedOnly:isTFDeletedOnly]){
  34. tfComment = [arg1 comment];
  35. tfController = self;
  36. shouldHaveUndeleteAction = YES;
  37. }
  38. }
  39. }
  40. %orig;
  41. shouldHaveUndeleteAction = NO;
  42. }
  43. - (void)_dotsButtonTouched:(id)arg1 {
  44. if ([self linkTextOffscreenCell]) {
  45. NSString *postBody = [[self link] selfText];
  46. if ([%c(TFHelper) shouldShowUndeleteButtonWithInfo:postBody isDeletedOnly:isTFDeletedOnly]) {
  47. tfController = self;
  48. tfComment = nil;
  49. shouldHaveUndeleteAction = YES;
  50. }
  51. }
  52. %orig;
  53. shouldHaveUndeleteAction = NO;
  54. }
  55. %new
  56. - (void)handleUndeletePostAction {
  57. id post = [self link];
  58. [%c(TFHelper) getUndeleteDataWithID:[[post fullName] componentsSeparatedByString:@"_"][1] isComment:NO timeout:pushshiftRequestTimeoutValue extraData:@{@"post" : post} completionTarget:self completionSelector:@selector(completeUndeletePostAction:)];
  59. }
  60. %new
  61. - (void)completeUndeletePostAction:(NSDictionary *)data {
  62. id post = data[@"post"];
  63. MSHookIvar<NSString*>(post, "_author") = data[@"author"];
  64. NSAttributedString* postBodyAttributedString = [%c(NRTMarkdownManager) attributedStringFromMarkdown:data[@"body"] type:0];
  65. [self setLinkText:postBodyAttributedString];
  66. [[self tableView] reloadData];
  67. }
  68. %new
  69. - (void)completeUndeleteCommentAction:(NSDictionary *)data {
  70. id comment = data[@"comment"];
  71. if (comment) {
  72. MSHookIvar<NSString*>(comment, "_author") = data[@"author"];
  73. MSHookIvar<NSString*>(comment, "_body") = data[@"body"];
  74. [[self commentsManager] updateComment:comment fromEdited:comment];
  75. }
  76. }
  77. %end
  78. %hook NRTMediaTableViewDataSource
  79. - (void)swipeCell:(id)arg1 didEndDragWithState:(NSUInteger)arg2 {
  80. if (arg2 == 2) {
  81. if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) {
  82. NSString *commentBody = MSHookIvar<NSString*>([arg1 comment], "_body");
  83. if ([%c(TFHelper) shouldShowUndeleteButtonWithInfo:commentBody isDeletedOnly:isTFDeletedOnly]) {
  84. tfComment = [arg1 comment];
  85. tfController = self;
  86. shouldHaveUndeleteAction = YES;
  87. }
  88. }
  89. }
  90. %orig;
  91. shouldHaveUndeleteAction = NO;
  92. }
  93. %new
  94. - (void)completeUndeleteCommentAction:(NSDictionary *)data {
  95. id comment = data[@"comment"];
  96. if (comment) {
  97. MSHookIvar<NSString*>(comment, "_author") = data[@"author"];
  98. MSHookIvar<NSString*>(comment, "_body") = data[@"body"];
  99. [[self commentsManager] updateComment:comment fromEdited:comment];
  100. }
  101. }
  102. %end
  103. %end
  104. static void loadPrefs(){
  105. NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"];
  106. if (prefs){
  107. isEnabled = [prefs objectForKey:@"isEnabled"] ? [[prefs objectForKey:@"isEnabled"] boolValue] : YES;
  108. isNarwhalEnabled = [prefs objectForKey:@"isNarwhalEnabled"] ? [[prefs objectForKey:@"isNarwhalEnabled"] boolValue] : YES;
  109. isTFDeletedOnly = [prefs objectForKey:@"isTFDeletedOnly"] ? [[prefs objectForKey:@"isTFDeletedOnly"] boolValue] : YES;
  110. pushshiftRequestTimeoutValue = [prefs objectForKey:@"requestTimeoutValue"] ? [[prefs objectForKey:@"requestTimeoutValue"] doubleValue] : 10;
  111. } else {
  112. isEnabled = YES;
  113. isNarwhalEnabled = YES;
  114. isTFDeletedOnly = YES;
  115. pushshiftRequestTimeoutValue = 10;
  116. }
  117. }
  118. static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
  119. loadPrefs();
  120. }
  121. %ctor {
  122. loadPrefs();
  123. NSString* processName = [[NSProcessInfo processInfo] processName];
  124. if ([processName isEqualToString:@"narwhal"]){
  125. if (isNarwhalEnabled && isEnabled){
  126. CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorCoalesce);
  127. %init(Narwhal);
  128. }
  129. }
  130. }