您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #import "Beam.h"
  2. #import "assets/TFHelper.h"
  3. static BOOL isBeamEnabled;
  4. static BOOL isTFDeletedOnly;
  5. static CGFloat pushshiftRequestTimeoutValue;
  6. %group Beam
  7. %hook CommentCell
  8. %property(strong, nonatomic) UIButton *undeleteButton;
  9. -(void) layoutSubviews{
  10. %orig;
  11. UIButton *undeleteButton = [self undeleteButton];
  12. if (undeleteButton){
  13. if ([self isCollapsed]){
  14. [undeleteButton setHidden:YES];
  15. } else {
  16. [undeleteButton setHidden:NO];
  17. }
  18. } else {
  19. NSString *commentBody = [[self comment] content];
  20. if ([%c(TFHelper) shouldShowUndeleteButtonWithInfo:commentBody isDeletedOnly:isTFDeletedOnly]){
  21. CGFloat authorTextHeight = [[self authorButton] frame].size.height;
  22. undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  23. [undeleteButton addTarget:self action:@selector(handleUndeleteCommentAction:) forControlEvents:UIControlEventTouchUpInside];
  24. [undeleteButton setImage:[UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"] forState:UIControlStateNormal];
  25. undeleteButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
  26. undeleteButton.imageEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
  27. undeleteButton.frame = CGRectMake([[UIScreen mainScreen] bounds].size.width - authorTextHeight - 5, 5, authorTextHeight, authorTextHeight);
  28. [[self commentContentView] addSubview:undeleteButton];
  29. [self setUndeleteButton:undeleteButton];
  30. }
  31. }
  32. }
  33. %new
  34. -(void) handleUndeleteCommentAction:(id) sender{
  35. [sender setEnabled:NO];
  36. [%c(TFHelper) getUndeleteDataWithID:[[self comment] identifier] isComment:YES timeout:pushshiftRequestTimeoutValue extraData:@{@"sender" : sender} completionTarget:self completionSelector:@selector(completeUndeleteCommentAction:)];
  37. }
  38. %new
  39. -(void) completeUndeleteCommentAction:(NSDictionary *) data{
  40. id comment = [self comment];
  41. [comment setAuthor:data[@"author"]];
  42. [comment setContent:data[@"body"]];
  43. [comment setMarkdownString:nil];
  44. [self setCommentDidChange:YES];
  45. [self reloadContents];
  46. [[MSHookIvar<id>(self, "delegate") tableView] reloadData];
  47. [data[@"sender"] setEnabled:YES];
  48. }
  49. %end
  50. %hook PostSelfTextPartCell
  51. -(void) setSelected:(BOOL) arg1 animated:(BOOL) arg2{
  52. %orig;
  53. id postViewController = [self _viewControllerForAncestor];
  54. if ([postViewController isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){
  55. [postViewController setSelfTextView:self];
  56. [postViewController setPost:[self post]];
  57. }
  58. }
  59. %end
  60. %hook PostMetadataView
  61. -(void) layoutSubviews{
  62. %orig;
  63. id postViewController = MSHookIvar<id>(self, "delegate");
  64. if ([postViewController isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){
  65. [postViewController setMetadataView:self];
  66. }
  67. }
  68. %end
  69. %hook PostToolbarView
  70. %property(strong, nonatomic) UIButton *undeleteButton;
  71. -(void) layoutSubviews{
  72. %orig;
  73. if (![self undeleteButton] && [[[self post] isSelfText] boolValue] && [MSHookIvar<id>(self, "delegate") isMemberOfClass:objc_getClass("beam.PostDetailEmbeddedViewController")]){
  74. NSString *postBody = [[self post] content];
  75. if ([%c(TFHelper) shouldShowUndeleteButtonWithInfo:postBody isDeletedOnly:isTFDeletedOnly]){
  76. id moreButton = MSHookIvar<id>(self, "moreButton");
  77. CGFloat buttonHeight = [moreButton frame].size.height;
  78. UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  79. [undeleteButton addTarget:MSHookIvar<id>(self, "delegate") action:@selector(handleUndeletePostAction:) forControlEvents:UIControlEventTouchUpInside];
  80. [undeleteButton setImage:[UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160dark.png"] forState:UIControlStateNormal];
  81. undeleteButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
  82. undeleteButton.imageEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
  83. undeleteButton.frame = CGRectMake([moreButton frame].origin.x - buttonHeight, 1, buttonHeight, buttonHeight);
  84. [self addSubview:undeleteButton];
  85. [self setUndeleteButton:undeleteButton];
  86. }
  87. }
  88. }
  89. %end
  90. %hook PostDetailEmbeddedViewController
  91. %property(strong, nonatomic) id selfTextView;
  92. %property(strong, nonatomic) id metadataView;
  93. %property(strong, nonatomic) id post;
  94. %new
  95. -(void) handleUndeletePostAction:(id) sender{
  96. [sender setEnabled:NO];
  97. id post = [self post];
  98. if (post){
  99. [%c(TFHelper) getUndeleteDataWithID:[post identifier] isComment:NO timeout:pushshiftRequestTimeoutValue extraData:@{@"sender" : sender} completionTarget:self completionSelector:@selector(completeUndeletePostAction:)];
  100. }
  101. }
  102. %new
  103. -(void) completeUndeletePostAction:(NSDictionary *) data{
  104. id post = [self post];
  105. [post setAuthor:data[@"author"]];
  106. [post setContent:data[@"body"]];
  107. [post setMarkdownString:nil];
  108. if ([self selfTextView]){
  109. [[self selfTextView] reloadContents];
  110. }
  111. if ([self metadataView]){
  112. [[self metadataView] setPost:post];
  113. }
  114. [[self tableView] reloadData];
  115. [data[@"sender"] setEnabled:YES];
  116. }
  117. %end
  118. %end
  119. static void loadPrefs(){
  120. NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"];
  121. if (prefs){
  122. if ([prefs objectForKey:@"isBeamEnabled"] != nil){
  123. isBeamEnabled = [[prefs objectForKey:@"isBeamEnabled"] boolValue];
  124. } else {
  125. isBeamEnabled = YES;
  126. }
  127. if ([prefs objectForKey:@"isTFDeletedOnly"] != nil) {
  128. isTFDeletedOnly = [[prefs objectForKey:@"isTFDeletedOnly"] boolValue];
  129. } else {
  130. isTFDeletedOnly = YES;
  131. }
  132. if ([prefs objectForKey:@"requestTimeoutValue"] != nil){
  133. pushshiftRequestTimeoutValue = [[prefs objectForKey:@"requestTimeoutValue"] doubleValue];
  134. } else {
  135. pushshiftRequestTimeoutValue = 10;
  136. }
  137. } else {
  138. isBeamEnabled = YES;
  139. isTFDeletedOnly = YES;
  140. pushshiftRequestTimeoutValue = 10;
  141. }
  142. }
  143. static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
  144. loadPrefs();
  145. }
  146. %ctor{
  147. loadPrefs();
  148. NSString* processName = [[NSProcessInfo processInfo] processName];
  149. if ([processName isEqualToString:@"beam"]){
  150. if (isBeamEnabled){
  151. CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
  152. %init(Beam, CommentCell = objc_getClass("beam.CommentCell"), PostDetailEmbeddedViewController = objc_getClass("beam.PostDetailEmbeddedViewController"), PostToolbarView = objc_getClass("beam.PostToolbarView"), PostSelfTextPartCell = objc_getClass("beam.PostSelfTextPartCell"), PostMetadataView = objc_getClass("beam.PostMetadataView"));
  153. }
  154. }
  155. }