浏览代码

Add Narwhal support, fix empty data crash

master
lint 5 年前
父节点
当前提交
c3dea79a28
共有 6 个文件被更改,包括 461 次插入38 次删除
  1. +4
    -2
      Makefile
  2. +2
    -1
      tfdidthatsay.plist
  3. +17
    -17
      tweak/Apollo.xm
  4. +131
    -0
      tweak/Narwhal.h
  5. +289
    -0
      tweak/Narwhal.xm
  6. +18
    -18
      tweak/Reddit.xm

+ 4
- 2
Makefile 查看文件

@@ -1,12 +1,14 @@
ARCHS = arm64
ARCHS = arm64 arm64e

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = tfdidthatsay
tfdidthatsay_FILES = $(wildcard tweak/*.xm)
#tfdidthatsay_CFLAGS = -fobjc-arc
tweak/Narwhal.xm_CFLAGS = -fobjc-arc

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::
install.exec "killall -9 Reddit"
install.exec "killall -9 Apollo"
install.exec "killall -9 narwhal"

+ 2
- 1
tfdidthatsay.plist 查看文件

@@ -2,7 +2,8 @@
Filter = {
Bundles = (
"com.reddit.Reddit",
"com.christianselig.Apollo"
"com.christianselig.Apollo",
"com.rickharrison.narwhal"
);
};
}

+ 17
- 17
tweak/Apollo.xm 查看文件

@@ -50,18 +50,18 @@ NSDictionary* apolloBodyAttributes = nil;
NSString *author = @"[author]";
NSString *body = @"[body]";
if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[comment was unable to be archived]";
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}
@@ -138,16 +138,16 @@ NSDictionary* apolloBodyAttributes = nil;
NSString *body = @"[body]";
if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[comment was unable to be archived]";
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}

+ 131
- 0
tweak/Narwhal.h 查看文件

@@ -0,0 +1,131 @@
/* -- Comment Interfaces -- */
@interface RKComment
@property(assign,nonatomic) NSString* author;
@property(assign,nonatomic) NSString* parentID;
@property(assign,nonatomic) NSString* body;
@property(assign,nonatomic) NSString* fullName;
-(BOOL) isSaved;
@end
@interface NRTCommentsManager
@property(assign,nonatomic) NSMutableArray* comments;
-(void) updateComment:(id) arg1 fromEdited:(id) arg2;
@end
/* -- Post Interfaces -- */
@interface RKLink
@property(assign,nonatomic) NSString* author;
@property(assign,nonatomic) NSString* selfText;
@property(assign,nonatomic) NSString* fullName;
@end
@interface NRTLinkTitleCell
-(void) configureCellForLink:(id) arg1;
@end
@interface NRTLinkTextCell
@property(assign,nonatomic) id bodyLabel;
-(void) configureCellForText:(id) arg1 links:(id) arg2;
@end
/* -- Other Interfaces -- */
@interface NRTAuthManager
@property(assign,nonatomic) NSString* currentUsername;
+(id) sharedManager;
@end
@interface NRTMarkdownManager
+(id) attributedStringFromMarkdown:(id) arg1 type:(id) arg2;
@end
@interface NRTAttributedLabel
@property(assign,nonatomic) id attributedText;
@end
@interface NRTMediaViewController : UIViewController
@end
@interface NRTLinkViewController : UIViewController
@property(assign,nonatomic) id comment;
@property(assign,nonatomic) id commentsManager;
@property(assign,nonatomic) id linkTextOffscreenCell;
@property(assign,nonatomic) id linkTitleOffscreenCell;
@property(assign,nonatomic) id link;
@property(assign,nonatomic) id linkText;
@property(assign,nonatomic) id tableView;
-(void) _handleActionSheetCopyCommentText:(id) arg1;
-(void) _handleActionSheetDeleteComment:(id) arg1;
-(void) _handleActionSheetDeletePost;
-(void) _handleActionSheetEditComment:(id) arg1;
-(void) _handleActionSheetEditPost;
-(void) _handleActionSheetOpenChrome;
-(void) _handleActionSheetOpenSafari;
-(void) _handleActionSheetPrivateMessage:(id) arg1;
-(void) _handleActionSheetRefreshComments;
-(void) _handleActionSheetRefreshPost;
-(void) _handleActionSheetReportComment:(id) arg1;
-(void) _handleActionSheetReportPost;
-(void) _handleActionSheetSaveComment:(id) arg1 index:(NSUInteger) arg2;
-(void) _handleActionSheetShareComment:(id) arg1;
-(void) _handleActionSheetShareLink;
-(void) _handleActionSheetSharePost;
-(void) _handleActionSheetSortComments;
-(void) _handleActionSheetUnsaveComment:(id) arg1 index:(NSUInteger) arg2;
-(void) _handleActionSheetViewParent:(id) arg1;
-(void) _handleActionSheetViewProfile:(id) arg1;
//custom elements
-(void) handleUndeleteAction:(id) arg1;
-(void) handleUndeletePostAction;
-(void) mainThreadTest:(id) arg1;
@end
@interface NRTMediaTableViewDataSource
@property(assign,nonatomic) id commentsManager;
@property(assign,nonatomic) id parentController;
-(void) _handleActionSheetCopyCommentText:(id) arg1;
-(void) _handleActionSheetDeleteComment:(id) arg1;
-(void) _handleActionSheetDeletePost;
-(void) _handleActionSheetEditComment:(id) arg1;
-(void) _handleActionSheetEditPost;
-(void) _handleActionSheetOpenChrome;
-(void) _handleActionSheetOpenSafari;
-(void) _handleActionSheetPrivateMessage:(id) arg1;
-(void) _handleActionSheetRefreshComments;
-(void) _handleActionSheetRefreshPost;
-(void) _handleActionSheetReportComment:(id) arg1;
-(void) _handleActionSheetReportPost;
-(void) _handleActionSheetSaveComment:(id) arg1 index:(NSUInteger) arg2;
-(void) _handleActionSheetShareComment:(id) arg1;
-(void) _handleActionSheetShareLink;
-(void) _handleActionSheetSharePost;
-(void) _handleActionSheetSortComments;
-(void) _handleActionSheetUnsaveComment:(id) arg1 index:(NSUInteger) arg2;
-(void) _handleActionSheetViewParent:(id) arg1;
-(void) _handleActionSheetViewProfile:(id) arg1;
//custom elements
-(void) handleUndeleteCommentAction:(id) comment;
@end

+ 289
- 0
tweak/Narwhal.xm 查看文件

@@ -0,0 +1,289 @@
#import "Narwhal.h"

%group Narwhal
UIAlertController* recreateActionSheet(id controller, id comment, NSInteger commentIndex){
UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:nil];
UIAlertAction* pmAction = [UIAlertAction actionWithTitle:[NSString stringWithFormat:@"private message %@", [comment author]] style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetPrivateMessage:comment];}];
UIAlertAction* viewProfileAction = [UIAlertAction actionWithTitle:@"view profile" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetViewProfile:comment];}];
UIAlertAction* shareAction = [UIAlertAction actionWithTitle:@"share comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetShareComment:comment];}];
UIAlertAction* copyAction = [UIAlertAction actionWithTitle:@"copy text" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetCopyCommentText:comment];}];
UIAlertAction* reportAction = [UIAlertAction actionWithTitle:@"report comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetReportComment:comment];}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:pmAction];
[alert addAction:viewProfileAction];
[alert addAction:shareAction];
[alert addAction:copyAction];
if ([comment isSaved]){
UIAlertAction* unsaveAction = [UIAlertAction actionWithTitle:@"unsave comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetUnsaveComment:comment index:commentIndex];}];
[alert addAction:unsaveAction];
} else {
UIAlertAction* saveAction = [UIAlertAction actionWithTitle:@"save comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetSaveComment:comment index:commentIndex];}];
[alert addAction:saveAction];
}
if ([[[comment parentID] componentsSeparatedByString:@"_"][0] isEqualToString:@"t1"]){
UIAlertAction* viewParentAction = [UIAlertAction actionWithTitle:@"view parent" style: nil handler:^(UIAlertAction* action){[controller _handleActionSheetViewParent:comment];}];
[alert addAction:viewParentAction];
}
if ([[comment author] isEqualToString:[[%c(NRTAuthManager) sharedManager] currentUsername]]) {
UIAlertAction* editAction = [UIAlertAction actionWithTitle:@"edit comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetEditComment:comment];}];
UIAlertAction* deleteAction = [UIAlertAction actionWithTitle:@"delete comment" style:nil handler:^(UIAlertAction* action){[controller _handleActionSheetDeleteComment:comment];}];
[alert addAction:editAction];
[alert addAction:deleteAction];
}
[alert addAction:reportAction];
[alert addAction:cancelAction];
UIAlertAction* undeleteAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){[controller handleUndeleteCommentAction:comment];}];
[alert addAction:undeleteAction];
return alert;
}
void getUndeleteCommentData(id controller, id comment){
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/comment/?ids=%@&fields=author,body",[[comment fullName] componentsSeparatedByString:@"_"][1]]]];
[request setHTTPMethod:@"GET"];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSString *author = @"[author]";
NSString *body = @"[body]";

if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
if (!body){
body = @"[wtf]";
}
if (!author){
author = @"[wtf]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}
[controller performSelectorOnMainThread:@selector(completeUndeleteComment:) withObject:@{@"body":body, @"author":author, @"comment":comment} waitUntilDone:NO];
}];
}
%hook NRTLinkViewController

%new
-(void) completeUndeleteComment:(id) data{

id comment = data[@"comment"];

if (comment){

MSHookIvar<NSString*>(comment, "_author") = data[@"author"];
MSHookIvar<NSString*>(comment, "_body") = data[@"body"];
[[self commentsManager] updateComment:comment fromEdited:comment];
}
}

%new
-(void) completeUndeletePost:(id) data{

id post = data[@"post"];

MSHookIvar<NSString*>(post, "_author") = data[@"author"];
NSAttributedString* postBodyAttributedString = [%c(NRTMarkdownManager) attributedStringFromMarkdown:data[@"body"] type:0];
[self setLinkText:postBodyAttributedString];
[[self tableView] reloadData];
}
%new
-(void) handleUndeleteCommentAction:(id) comment{
getUndeleteCommentData(self, comment);
}
%new
-(void) handleUndeletePostAction{
id post = [self link];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.pushshift.io/reddit/search/submission/?ids=%@&fields=author,selftext",[[post fullName] componentsSeparatedByString:@"_"][1]]]];
[request setHTTPMethod:@"GET"];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSString *author = @"[author]";
NSString *body = @"[body]";
if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}
[self performSelectorOnMainThread:@selector(completeUndeletePost:) withObject:@{@"body":body, @"author":author, @"post":post} waitUntilDone:NO];
}];
}
-(void) swipeCell:(id) arg1 didEndDragWithState:(NSUInteger) arg2{
if (arg2 == 2){
if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) {
id comment = [arg1 comment];
NSInteger commentIndex = [[[self commentsManager] comments] indexOfObject:comment];
UIAlertController* alert = recreateActionSheet(self, comment, commentIndex);
[self presentViewController:alert animated:YES completion:nil];
} else {
%orig;
}
} else {
%orig;
}
}
-(void) _dotsButtonTouched:(id) arg1{
id post = [self link];
BOOL shouldHaveUndeleteAction = NO;
UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:nil];
UIAlertAction* undeletePostAction;
UIAlertAction* sharePostAction = [UIAlertAction actionWithTitle:@"share reddit post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetSharePost];}];
UIAlertAction* sortCommentsAction = [UIAlertAction actionWithTitle:@"sort comments" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetSortComments];}];
UIAlertAction* refreshCommentsAction = [UIAlertAction actionWithTitle:@"refresh comments" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetRefreshComments];}];
UIAlertAction* reportPostAction = [UIAlertAction actionWithTitle:@"report post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetReportPost];}];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:sharePostAction];
[alert addAction:sortCommentsAction];
[alert addAction:refreshCommentsAction];
if ([self linkTextOffscreenCell]){
UIAlertAction* refreshPostAction = [UIAlertAction actionWithTitle:@"refresh post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetRefreshPost];}];
[alert addAction:refreshPostAction];
undeletePostAction = [UIAlertAction actionWithTitle:@"tf did that say?" style:nil handler:^(UIAlertAction* action){[self handleUndeletePostAction];}];
shouldHaveUndeleteAction = YES;
}
if ([[post author] isEqualToString:[[%c(NRTAuthManager) sharedManager] currentUsername]]){
UIAlertAction* editPostAction = [UIAlertAction actionWithTitle:@"edit post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetEditPost];}];
UIAlertAction* deletePostAction = [UIAlertAction actionWithTitle:@"delete post" style:nil handler:^(UIAlertAction* action){[self _handleActionSheetDeletePost];}];
[alert addAction:editPostAction];
[alert addAction:deletePostAction];
}
[alert addAction:reportPostAction];
[alert addAction:cancelAction];
if (shouldHaveUndeleteAction){
[alert addAction:undeletePostAction];
}
[self presentViewController:alert animated:YES completion:nil];
}
%end
%hook NRTMediaTableViewDataSource

%new
-(void) completeUndeleteComment:(id) data{

id comment = data[@"comment"];

if (comment){

MSHookIvar<NSString*>(comment, "_author") = data[@"author"];
MSHookIvar<NSString*>(comment, "_body") = data[@"body"];
[[self commentsManager] updateComment:comment fromEdited:comment];
}
}
%new
-(void) handleUndeleteCommentAction:(id) comment{
getUndeleteCommentData(self, comment);
}
-(void) swipeCell:(id) arg1 didEndDragWithState:(NSUInteger) arg2{
if (arg2 == 2){
if ([arg1 isKindOfClass:[%c(NRTCommentTableViewCell) class]]) {
id comment = [arg1 comment];
NSInteger commentIndex = [[[self commentsManager] comments] indexOfObject:comment];
UIAlertController* alert = recreateActionSheet(self, comment, commentIndex);
[[self parentController] presentViewController:alert animated:YES completion:nil];
} else {
%orig;
}
} else {
%orig;
}
}
%end
%end
%ctor {
NSString* processName = [[NSProcessInfo processInfo] processName];

if ([processName isEqualToString:@"narwhal"]){
%init(Narwhal);
}
}

+ 18
- 18
tweak/Reddit.xm 查看文件

@@ -72,16 +72,16 @@
NSString *body = @"[body]";
if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[comment was unable to be archived]";
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"body"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}
@@ -188,21 +188,21 @@
NSString *author = @"[author]";
NSString *body = @"[body]";
if (data != nil && error == nil){
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[comment was unable to be archived]";
if ([[jsonData objectForKey:@"data"] count] != 0){
author = [[jsonData objectForKey:@"data"][0] objectForKey:@"author"];
body = [[jsonData objectForKey:@"data"][0] objectForKey:@"selftext"];
if ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"]){
body = @"[pushshift was unable to archive this]";
}
} else {
body = @"[pushshift has not archived this yet]";
}
} else if (error != nil || data == nil){
body = @"[an error occured]";
}
}
id themeManager = [[%c(ThemeManager) alloc] initWithTraitCollection:nil appSettings:[%c(AppSettings) sharedSettings]];
id isNightMode = [[[%c(AccountManager) sharedManager] defaults] objectForKey:@"kUseNightKey"];

正在加载...
取消
保存