forked from lint/TFDidThatSay
		
	Add Slide support (comments only)
This commit is contained in:
		
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							@ -18,3 +18,4 @@ after-install::
 | 
			
		||||
	install.exec "killall -9 Apollo"
 | 
			
		||||
	install.exec "killall -9 narwhal"
 | 
			
		||||
	install.exec "killall -9 AlienBlue"
 | 
			
		||||
	install.exec "killall -9 Slide\ for\ Reddit"
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.4 KiB  | 
@ -68,11 +68,25 @@
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>Enable Alien Blue</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>PostNotification</key>
 | 
			
		||||
			<string>com.lint.undelete.prefs.changed</string>
 | 
			
		||||
			<key>cell</key>
 | 
			
		||||
			<string>PSSwitchCell</string>
 | 
			
		||||
			<key>default</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
			<key>defaults</key>
 | 
			
		||||
			<string>com.lint.undelete.prefs</string>
 | 
			
		||||
			<key>key</key>
 | 
			
		||||
			<string>isSlideEnabled</string>
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>Enable Slide</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>cell</key>
 | 
			
		||||
			<string>PSGroupCell</string>
 | 
			
		||||
			<key>footerText</key>
 | 
			
		||||
			<string>On apps that have the eye button rather than in the menu, enable or disable that button from appearing on only deleted comments/posts.</string>
 | 
			
		||||
			<string>On apps that have an eye button rather than an option in the menu, enable or disable that button from appearing on only deleted comments/posts.</string>
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>visibility</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
@ -88,7 +102,7 @@
 | 
			
		||||
			<key>key</key>
 | 
			
		||||
			<string>isApolloDeletedCommentsOnly</string>
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>Apollo | Only on deleted comments</string>
 | 
			
		||||
			<string>Apollo | Deleted only</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>PostNotification</key>
 | 
			
		||||
@ -102,7 +116,21 @@
 | 
			
		||||
			<key>key</key>
 | 
			
		||||
			<string>isAlienBlueDeletedOnly</string>
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>Alien Blue | Only on deleted comments/posts</string>
 | 
			
		||||
			<string>Alien Blue | Deleted only</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>PostNotification</key>
 | 
			
		||||
			<string>com.lint.undelete.prefs.changed</string>
 | 
			
		||||
			<key>cell</key>
 | 
			
		||||
			<string>PSSwitchCell</string>
 | 
			
		||||
			<key>default</key>
 | 
			
		||||
			<true/>
 | 
			
		||||
			<key>defaults</key>
 | 
			
		||||
			<string>com.lint.undelete.prefs</string>
 | 
			
		||||
			<key>key</key>
 | 
			
		||||
			<string>isSlideDeletedOnly</string>
 | 
			
		||||
			<key>label</key>
 | 
			
		||||
			<string>Slide | Deleted only</string>
 | 
			
		||||
		</dict>
 | 
			
		||||
		<dict>
 | 
			
		||||
			<key>cell</key>
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										44
									
								
								tweak/Slide.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tweak/Slide.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
 | 
			
		||||
/* -- Comment Interfaces -- */
 | 
			
		||||
 | 
			
		||||
@interface RComment
 | 
			
		||||
@property(strong, nonatomic) NSString *subreddit;
 | 
			
		||||
@property(strong, nonatomic) NSString *author;
 | 
			
		||||
@property(strong, nonatomic) NSString *body;
 | 
			
		||||
@property(strong, nonatomic) NSString *id;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface CommentDepthCell
 | 
			
		||||
-(void) showMenu:(id) arg1;
 | 
			
		||||
 | 
			
		||||
//custom elements
 | 
			
		||||
-(void) addUndeleteButtonToMenu;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
/* -- Utility Interfaces -- */
 | 
			
		||||
 | 
			
		||||
@interface UIColor ()
 | 
			
		||||
+(UIColor *) colorWithHex:(NSString *) arg1;
 | 
			
		||||
-(NSString *) hexString;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface NSAttributedString ()
 | 
			
		||||
-(void) yy_setTextHighlightRange:(NSRange) range color:(UIColor *) color backgroundColor:(UIColor *) backgroundColor userInfo:(NSDictionary *) userInfo;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface ColorUtil : NSObject
 | 
			
		||||
+(UIColor *) accentColorForSub:(NSString *) arg1;
 | 
			
		||||
+(UIColor *) fontColorForTheme:(NSString *) arg1;
 | 
			
		||||
+(UIColor *) backgroundColorForTheme:(NSString *) arg1;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface DTHTMLAttributedStringBuilder
 | 
			
		||||
-(id) initWithHTML:(NSData *)data options:(NSDictionary *)options documentAttributes:(NSDictionary * __autoreleasing*)docAttributes;
 | 
			
		||||
-(NSAttributedString *) generatedAttributedString;
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
@interface FontGenerator : NSObject
 | 
			
		||||
+(UIFont *) fontOfSize:(CGFloat) arg1 submission:(BOOL) arg2 willOffset:(BOOL) arg3;
 | 
			
		||||
+(UIFont *) boldFontOfSize:(CGFloat) arg1 submission:(BOOL) arg2 willOffset:(BOOL) arg3;
 | 
			
		||||
+(UIFont *) italicFontOfSize:(CGFloat) arg1 submission:(BOOL) arg2 willOffset:(BOOL) arg3;
 | 
			
		||||
@end
 | 
			
		||||
							
								
								
									
										469
									
								
								tweak/Slide.xm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								tweak/Slide.xm
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,469 @@
 | 
			
		||||
 | 
			
		||||
#import "Slide.h"
 | 
			
		||||
#import "assets/MMMarkdown.h"
 | 
			
		||||
 | 
			
		||||
static BOOL isSlideEnabled;
 | 
			
		||||
static BOOL isSlideDeletedOnly;
 | 
			
		||||
static CGFloat pushshiftRequestTimeoutValue;
 | 
			
		||||
 | 
			
		||||
%group Slide
 | 
			
		||||
 | 
			
		||||
@implementation FontGenerator
 | 
			
		||||
 | 
			
		||||
+(UIFont *) fontOfSize:(CGFloat) size submission:(BOOL) isSubmission willOffset:(BOOL) willOffset{
 | 
			
		||||
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
	
 | 
			
		||||
	NSString *fontName;
 | 
			
		||||
	CGFloat fontSize = size;
 | 
			
		||||
	
 | 
			
		||||
	if (willOffset){
 | 
			
		||||
		if (isSubmission){
 | 
			
		||||
			fontSize += ([userDefaults objectForKey:@"POST_FONT_SIZE"] == nil) ? 0 : [userDefaults integerForKey:@"POST_FONT_SIZE"];
 | 
			
		||||
		} else {
 | 
			
		||||
			fontSize += ([userDefaults objectForKey:@"COMMENT_FONT_SIZE"] == nil) ? -2 : [userDefaults integerForKey:@"COMMENT_FONT_SIZE"];
 | 
			
		||||
		}	
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if ([userDefaults stringForKey:(isSubmission ? @"postfont" : @"commentfont")] == nil){
 | 
			
		||||
		fontName =  isSubmission ? @"AvenirNext-DemiBold" : @"AvenirNext-Medium";
 | 
			
		||||
	} else {
 | 
			
		||||
		fontName = [userDefaults stringForKey:(isSubmission ? @"postfont" : @"commentfont")];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	UIFont *font = [UIFont fontWithName:fontName size:fontSize]; 
 | 
			
		||||
	
 | 
			
		||||
	if (!font){
 | 
			
		||||
		font = [UIFont systemFontOfSize:fontSize];
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return font;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
+(UIFont *) boldFontOfSize:(CGFloat) size submission:(BOOL) isSubmission willOffset:(BOOL) willOffset {
 | 
			
		||||
	UIFont *font = [self fontOfSize:size submission:isSubmission willOffset:willOffset];
 | 
			
		||||
	
 | 
			
		||||
	if ([font.fontName isEqualToString:[UIFont systemFontOfSize:10].fontName]){
 | 
			
		||||
		return [UIFont boldSystemFontOfSize:font.pointSize];
 | 
			
		||||
	} else {
 | 
			
		||||
		UIFontDescriptor *desc = [font.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
 | 
			
		||||
		
 | 
			
		||||
		if (desc == nil){
 | 
			
		||||
			return font;
 | 
			
		||||
		} else {
 | 
			
		||||
			return [UIFont fontWithDescriptor:desc size: 0];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+(UIFont *) italicFontOfSize:(CGFloat) size submission:(BOOL) isSubmission willOffset:(BOOL) willOffset {
 | 
			
		||||
	UIFont *font = [self fontOfSize:size submission:isSubmission willOffset:willOffset];
 | 
			
		||||
	
 | 
			
		||||
	if ([font.fontName isEqualToString:[UIFont systemFontOfSize:10].fontName]){
 | 
			
		||||
		return [UIFont italicSystemFontOfSize:font.pointSize];
 | 
			
		||||
	} else {
 | 
			
		||||
		UIFontDescriptor *desc = [font.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic];
 | 
			
		||||
		
 | 
			
		||||
		if (desc == nil){
 | 
			
		||||
			return font;
 | 
			
		||||
		} else {
 | 
			
		||||
			return [UIFont fontWithDescriptor:desc size: 0];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@implementation ColorUtil 
 | 
			
		||||
 | 
			
		||||
+(UIColor *) accentColorForSub:(NSString *) subreddit{
 | 
			
		||||
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
	NSData *colorData = [userDefaults dataForKey:[NSString stringWithFormat:@"accent+%@", subreddit]];
 | 
			
		||||
	UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
 | 
			
		||||
	if (color) {
 | 
			
		||||
		return color;
 | 
			
		||||
	} else {
 | 
			
		||||
		UIColor *baseAccentColor = [NSKeyedUnarchiver unarchiveObjectWithData:[userDefaults dataForKey:@"accentcolor"]];
 | 
			
		||||
		
 | 
			
		||||
		if (baseAccentColor){
 | 
			
		||||
			return baseAccentColor;
 | 
			
		||||
		} else {
 | 
			
		||||
			return [UIColor colorWithRed:0.161 green:0.475 blue:1.0 alpha:1.0];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+(UIColor *) fontColorForTheme:(NSString *)theme{
 | 
			
		||||
	UIColor *fontColor;
 | 
			
		||||
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
	
 | 
			
		||||
	//if only switch blocks worked with strings...
 | 
			
		||||
	if ([theme isEqualToString:@"light"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"dark"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"black"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"blue"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"sepia"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0.243 green:.239 blue:.212 alpha:0.87]; 
 | 
			
		||||
	} else if ([theme isEqualToString:@"red"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:0.969 blue:0.929 alpha:0.87]; 
 | 
			
		||||
	} else if ([theme isEqualToString:@"deep"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"mint"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0.035 green:0.212 blue:0.059 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"cream"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0.267 green:0.255 blue:0.224 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"acontrast"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"pink"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0.149 green:0.157 blue:0.267 alpha:0.87];
 | 
			
		||||
	} else if ([theme isEqualToString:@"solarize"]) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0.514 green:0.580 blue:0.588 alpha:0.87];
 | 
			
		||||
	} else if (!theme) {
 | 
			
		||||
		fontColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.87];
 | 
			
		||||
	} else {
 | 
			
		||||
		NSString *customThemeString = [[userDefaults stringForKey:[NSString stringWithFormat:@"Theme+%@", theme]] stringByRemovingPercentEncoding];
 | 
			
		||||
		if (customThemeString) {
 | 
			
		||||
			NSString *customFontColorHex = [customThemeString componentsSeparatedByString:@"#"][4];
 | 
			
		||||
			fontColor =  [UIColor colorWithHex:customFontColorHex]; 
 | 
			
		||||
		} else {
 | 
			
		||||
			fontColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.87];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return fontColor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
+(UIColor *) backgroundColorForTheme:(NSString *) theme{
 | 
			
		||||
	UIColor *backgroundColor;
 | 
			
		||||
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
 | 
			
		||||
	if ([theme isEqualToString:@"light"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.352 green:0.352 blue:0.352 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"dark"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.051 green:0.051 blue:0.051 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"black"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"blue"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.071 green:0.094 blue:0.106 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"sepia"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.310 green:0.302 blue:0.267 alpha:1.0]; 
 | 
			
		||||
	} else if ([theme isEqualToString:@"red"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.075 green:0.055 blue:0.051 alpha:1.0]; 
 | 
			
		||||
	} else if ([theme isEqualToString:@"deep"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.035 green:0.035 blue:0.043 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"mint"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.364 green:0.376 blue:0.357 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"cream"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.322 green:0.314 blue:0.286 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"acontrast"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.027 green:0.027 blue:0.24 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"pink"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:1.0 green:0.376 blue:0.357 alpha:1.0];
 | 
			
		||||
	} else if ([theme isEqualToString:@"solarize"]) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.040 green:0.067 blue:0.082 alpha:1.0];
 | 
			
		||||
	} else if (!theme) {
 | 
			
		||||
		backgroundColor = [UIColor colorWithRed:0.352 green:0.352 blue:0.352 alpha:1.0];
 | 
			
		||||
	} else {
 | 
			
		||||
		NSString *customThemeString = [[userDefaults stringForKey:[NSString stringWithFormat:@"Theme+%@", theme]] stringByRemovingPercentEncoding];
 | 
			
		||||
		if (customThemeString) {
 | 
			
		||||
			NSString *customFontColorHex = [customThemeString componentsSeparatedByString:@"#"][3];
 | 
			
		||||
			backgroundColor =  [UIColor colorWithHex:customFontColorHex]; 
 | 
			
		||||
		} else {
 | 
			
		||||
			backgroundColor = [UIColor colorWithRed:0.352 green:0.352 blue:0.352 alpha:1.0];
 | 
			
		||||
		}
 | 
			
		||||
	} 
 | 
			
		||||
	
 | 
			
		||||
	return backgroundColor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static UIButton * createUndeleteButton(){
 | 
			
		||||
	
 | 
			
		||||
	UIButton *undeleteButton = [UIButton buttonWithType:UIButtonTypeCustom];		
 | 
			
		||||
	UIImage *undeleteImage = [UIImage imageWithContentsOfFile:@"/var/mobile/Library/Application Support/TFDidThatSay/eye160white.png"];
 | 
			
		||||
	
 | 
			
		||||
	UIGraphicsBeginImageContextWithOptions(CGSizeMake(20, 20), NO, 0);
 | 
			
		||||
	[undeleteImage drawInRect:CGRectMake(0, 0, 20, 20)];
 | 
			
		||||
	undeleteImage = UIGraphicsGetImageFromCurrentImageContext();
 | 
			
		||||
	UIGraphicsEndImageContext();
 | 
			
		||||
	
 | 
			
		||||
	UIGraphicsBeginImageContextWithOptions(CGSizeMake(35, 35), NO, 0);
 | 
			
		||||
	CGContextRef context = UIGraphicsGetCurrentContext();
 | 
			
		||||
	UIGraphicsPushContext(context);
 | 
			
		||||
	[undeleteImage drawAtPoint:CGPointMake(7.5, 7.5)];
 | 
			
		||||
	UIGraphicsPopContext();
 | 
			
		||||
	undeleteImage = UIGraphicsGetImageFromCurrentImageContext();
 | 
			
		||||
	UIGraphicsEndImageContext();
 | 
			
		||||
 | 
			
		||||
	[undeleteButton setImage:undeleteImage forState:UIControlStateNormal];
 | 
			
		||||
	undeleteButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
 | 
			
		||||
	
 | 
			
		||||
	return undeleteButton;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//because it wont compile without this
 | 
			
		||||
%hook RComment
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%hook UIColor
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
+(UIColor *) colorWithHex:(NSString *) arg1 {
 | 
			
		||||
	if (!arg1){
 | 
			
		||||
		NSString *firstChar = [arg1 substringToIndex:1];
 | 
			
		||||
		if ([firstChar isEqualToString:@"#"]){
 | 
			
		||||
			arg1 = [arg1 substringWithRange:NSMakeRange(1, [arg1 length]-1)];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		unsigned rgbValue = 0;
 | 
			
		||||
		NSScanner *scanner = [NSScanner scannerWithString:arg1];
 | 
			
		||||
		[scanner scanHexInt:&rgbValue];
 | 
			
		||||
			
 | 
			
		||||
		return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:0.87];
 | 
			
		||||
	} else {
 | 
			
		||||
		return nil;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%new 
 | 
			
		||||
-(NSString *) hexString {
 | 
			
		||||
	const CGFloat *components = CGColorGetComponents(self.CGColor);
 | 
			
		||||
 | 
			
		||||
    CGFloat r = components[0];
 | 
			
		||||
    CGFloat g = components[1];
 | 
			
		||||
    CGFloat b = components[2];
 | 
			
		||||
 | 
			
		||||
    return [NSString stringWithFormat:@"#%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%hook CommentDepthCell
 | 
			
		||||
 | 
			
		||||
-(void) doShortClick{
 | 
			
		||||
	%orig;
 | 
			
		||||
	
 | 
			
		||||
	[self addUndeleteButtonToMenu];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-(void) doLongClick	{
 | 
			
		||||
	%orig;
 | 
			
		||||
	
 | 
			
		||||
	[self addUndeleteButtonToMenu];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%new 
 | 
			
		||||
-(void) addUndeleteButtonToMenu{
 | 
			
		||||
	
 | 
			
		||||
	NSString *body = [MSHookIvar<id>(self, "comment") body];
 | 
			
		||||
	
 | 
			
		||||
	if ((isSlideDeletedOnly && ([body isEqualToString:@"[deleted]"] || [body isEqualToString:@"[removed]"])) || !isSlideDeletedOnly){
 | 
			
		||||
	
 | 
			
		||||
		id controller = MSHookIvar<id>(self, "parent");
 | 
			
		||||
		
 | 
			
		||||
		if (MSHookIvar<id>(controller, "menuCell")){
 | 
			
		||||
			
 | 
			
		||||
			UIStackView *menu = MSHookIvar<UIStackView *>(self, "menu");
 | 
			
		||||
			
 | 
			
		||||
			if (![[[[menu arrangedSubviews] lastObject] actionsForTarget:self forControlEvent:UIControlEventTouchUpInside] containsObject:@"handleUndeleteComment:"]){
 | 
			
		||||
				UIButton *undeleteButton = createUndeleteButton();
 | 
			
		||||
				[undeleteButton addTarget:self action:@selector(handleUndeleteComment:) forControlEvents:UIControlEventTouchUpInside];
 | 
			
		||||
			
 | 
			
		||||
				[menu addArrangedSubview:undeleteButton];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%new
 | 
			
		||||
-(void) handleUndeleteComment:(id) sender{
 | 
			
		||||
	
 | 
			
		||||
	[sender setEnabled:NO];
 | 
			
		||||
	
 | 
			
		||||
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
 | 
			
		||||
	id textStackDisplayView = MSHookIvar<id>(self, "commentBody");
 | 
			
		||||
	id comment = MSHookIvar<id>(self, "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 id] componentsSeparatedByString:@"_"][1]]]];
 | 
			
		||||
	[request setHTTPMethod:@"GET"];
 | 
			
		||||
	[request setTimeoutInterval:pushshiftRequestTimeoutValue];
 | 
			
		||||
 | 
			
		||||
	[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]";
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				body = @"[pushshift has not archived this yet]";
 | 
			
		||||
			}
 | 
			
		||||
		} else if (error != nil || data == nil){
 | 
			
		||||
			body = [NSString stringWithFormat:@"[an error occured while attempting to contact pushshift api (%@)]", [error localizedDescription]];
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		//Attributed string generation rewrote from Slide_for_Reddit.TextDisplayStackView.createAttributedChunk(...) 
 | 
			
		||||
		
 | 
			
		||||
		UIFont *font = [%c(FontGenerator) fontOfSize:MSHookIvar<CGFloat>(textStackDisplayView, "fontSize") submission:NO willOffset:YES];
 | 
			
		||||
			
 | 
			
		||||
		NSString *themeName = [userDefaults stringForKey:@"theme"];
 | 
			
		||||
		UIColor *fontColor = [%c(ColorUtil) fontColorForTheme:themeName];
 | 
			
		||||
		UIColor *accentColor = [%c(ColorUtil) accentColorForSub:[comment subreddit]];
 | 
			
		||||
		
 | 
			
		||||
		NSString *html = [%c(MMMarkdown) HTMLStringWithMarkdown:body extensions:MMMarkdownExtensionsGitHubFlavored error:nil];
 | 
			
		||||
		html = [[html stringByReplacingOccurrencesOfString:@"<sup>" withString:@"<font size=\"1\">"] stringByReplacingOccurrencesOfString:@"</sup>" withString:@"</font>"];
 | 
			
		||||
		html = [[html stringByReplacingOccurrencesOfString:@"<del>" withString:@"<font color=\"green\">"] stringByReplacingOccurrencesOfString:@"</del>" withString:@"</font>"];
 | 
			
		||||
		html = [[html stringByReplacingOccurrencesOfString:@"<code>" withString:@"<font color=\"blue\">"] stringByReplacingOccurrencesOfString:@"</code>" withString:@"</font>"];
 | 
			
		||||
		html = [html stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
 | 
			
		||||
		
 | 
			
		||||
		DTHTMLAttributedStringBuilder *dthtmlBuilder = [[%c(DTHTMLAttributedStringBuilder) alloc] initWithHTML:[html dataUsingEncoding:NSUTF8StringEncoding] options:@{@"DTUseiOS6Attributes": @YES, @"DTDefaultTextColor": fontColor, @"DTDefaultFontSize": @([font pointSize])} documentAttributes:nil];
 | 
			
		||||
		
 | 
			
		||||
		NSMutableAttributedString *htmlAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:[dthtmlBuilder generatedAttributedString]];
 | 
			
		||||
		NSRange htmlStringRange = NSMakeRange(0, [htmlAttributedString length]);
 | 
			
		||||
		
 | 
			
		||||
		[[htmlAttributedString mutableString] replaceOccurrencesOfString:@"\t•\t" withString:@" • " options:nil range: htmlStringRange];
 | 
			
		||||
		[[htmlAttributedString mutableString] replaceOccurrencesOfString:@"\t◦\t" withString:@"  ◦ " options:nil range: htmlStringRange];
 | 
			
		||||
		[[htmlAttributedString mutableString] replaceOccurrencesOfString:@"\t▪\t" withString:@"   ▪ " options:nil range: htmlStringRange];
 | 
			
		||||
		
 | 
			
		||||
		[htmlAttributedString removeAttribute:@"CTForegroundColorFromContext" range:htmlStringRange];
 | 
			
		||||
		
 | 
			
		||||
		[htmlAttributedString enumerateAttributesInRange:htmlStringRange options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary *attributes, NSRange range, BOOL *stop) {
 | 
			
		||||
			for (NSString *key in attributes){
 | 
			
		||||
				
 | 
			
		||||
				if ([(UIColor *) attributes[key] isKindOfClass:[UIColor class]]){
 | 
			
		||||
					UIColor *attrColor = (UIColor *) attributes[key];
 | 
			
		||||
					if ([[attrColor hexString] isEqualToString:@"#0000FF"]){
 | 
			
		||||
						UIFont *tempFont = [UIFont fontWithName:@"Courier" size:font.pointSize];
 | 
			
		||||
						
 | 
			
		||||
						[htmlAttributedString setAttributes:@{NSForegroundColorAttributeName: accentColor, NSBackgroundColorAttributeName: [%c(ColorUtil) backgroundColorForTheme:themeName], NSFontAttributeName: (tempFont ? tempFont : font)} range:range];
 | 
			
		||||
					} else if ([[attrColor hexString] isEqualToString:@"#008000"]) {
 | 
			
		||||
						[htmlAttributedString setAttributes:@{NSForegroundColorAttributeName: fontColor, NSFontAttributeName:font} range:range];
 | 
			
		||||
					}
 | 
			
		||||
				} else if ([(NSURL *) attributes[key] isKindOfClass:[NSURL class]]){
 | 
			
		||||
					NSURL *attrUrl = (NSURL *)attributes[key];
 | 
			
		||||
 | 
			
		||||
					if (([userDefaults objectForKey:@"ENLARGE_LINKS"] == nil) ? YES : [userDefaults boolForKey:@"ENLARGE_LINKS"]){
 | 
			
		||||
						[htmlAttributedString addAttribute:NSFontAttributeName value:[%c(FontGenerator) boldFontOfSize:18 submission:NO willOffset:YES] range:range];
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					[htmlAttributedString addAttribute:NSForegroundColorAttributeName value:accentColor range:range]; 
 | 
			
		||||
					[htmlAttributedString addAttribute:NSUnderlineColorAttributeName value:[UIColor clearColor] range:range];
 | 
			
		||||
		
 | 
			
		||||
					//skipping showLinkContentType b/c not necessary and spoilers b/c MMMarkdown doesn't support them
 | 
			
		||||
 | 
			
		||||
					[htmlAttributedString yy_setTextHighlightRange:range color: accentColor backgroundColor:nil userInfo:@{@"url": attrUrl}];
 | 
			
		||||
					break; 
 | 
			
		||||
				} 
 | 
			
		||||
			}
 | 
			
		||||
		}];
 | 
			
		||||
		
 | 
			
		||||
		[htmlAttributedString beginEditing];
 | 
			
		||||
		[htmlAttributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, [htmlAttributedString length]) options:nil usingBlock:^(id value, NSRange range, BOOL *stop){
 | 
			
		||||
			
 | 
			
		||||
			UIFont *attrFont = (UIFont *)value;
 | 
			
		||||
			
 | 
			
		||||
			BOOL isBold = (attrFont.fontDescriptor.symbolicTraits & UIFontDescriptorTraitBold) != 0;
 | 
			
		||||
			BOOL isItalic = (attrFont.fontDescriptor.symbolicTraits & UIFontDescriptorTraitItalic) != 0;
 | 
			
		||||
			
 | 
			
		||||
			UIFont *newFont = font;
 | 
			
		||||
			
 | 
			
		||||
			if (isBold){
 | 
			
		||||
				newFont = [%c(FontGenerator) boldFontOfSize:attrFont.pointSize submission:NO willOffset:NO];
 | 
			
		||||
			} else if (isItalic){
 | 
			
		||||
				newFont = [%c(FontGenerator) italicFontOfSize:attrFont.pointSize submission:NO willOffset:NO];
 | 
			
		||||
			}
 | 
			
		||||
		
 | 
			
		||||
			[htmlAttributedString removeAttribute:NSFontAttributeName range:range];
 | 
			
		||||
			[htmlAttributedString addAttribute:NSFontAttributeName value:newFont range:range];	
 | 
			
		||||
		
 | 
			
		||||
		}];
 | 
			
		||||
		[htmlAttributedString endEditing];
 | 
			
		||||
		
 | 
			
		||||
		NSMutableAttributedString *newCommentText = [MSHookIvar<NSMutableAttributedString *>(self, "cellContent") initWithAttributedString:htmlAttributedString];
 | 
			
		||||
		NSAttributedString *tempAttributedString = [[NSAttributedString alloc] initWithString:@""];
 | 
			
		||||
		[newCommentText appendAttributedString:tempAttributedString]; //to keep the compiler happy
 | 
			
		||||
		
 | 
			
		||||
		[comment setAuthor:author];
 | 
			
		||||
		[comment setBody:body];	
 | 
			
		||||
		
 | 
			
		||||
		id controller = MSHookIvar<id>(self, "parent");
 | 
			
		||||
		
 | 
			
		||||
		[self performSelectorOnMainThread:@selector(showMenu:) withObject:nil waitUntilDone:YES];
 | 
			
		||||
		[MSHookIvar<id>(controller, "tableView") performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
 | 
			
		||||
		
 | 
			
		||||
		[sender setEnabled:YES];
 | 
			
		||||
	}];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
%end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void loadPrefs(){
 | 
			
		||||
	NSMutableDictionary *prefs = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"];
 | 
			
		||||
	
 | 
			
		||||
	if (prefs){
 | 
			
		||||
		
 | 
			
		||||
		if ([prefs objectForKey:@"isSlideEnabled"] != nil){
 | 
			
		||||
			isSlideEnabled = [[prefs objectForKey:@"isSlideEnabled"] boolValue];
 | 
			
		||||
		} else {
 | 
			
		||||
			isSlideEnabled = YES;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ([prefs objectForKey:@"isSlideDeletedOnly"] != nil){
 | 
			
		||||
			isSlideDeletedOnly = [[prefs objectForKey:@"isSlideDeletedOnly"] boolValue];
 | 
			
		||||
		} else {
 | 
			
		||||
			isSlideDeletedOnly = YES;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ([prefs objectForKey:@"requestTimeoutValue"] != nil){
 | 
			
		||||
			pushshiftRequestTimeoutValue = [[prefs objectForKey:@"requestTimeoutValue"] doubleValue];
 | 
			
		||||
		} else {
 | 
			
		||||
			pushshiftRequestTimeoutValue = 10;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	} else {
 | 
			
		||||
		isSlideEnabled = YES;
 | 
			
		||||
		isSlideDeletedOnly = YES;
 | 
			
		||||
		pushshiftRequestTimeoutValue = 10;
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prefsChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
 | 
			
		||||
  loadPrefs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%ctor {
 | 
			
		||||
	loadPrefs();
 | 
			
		||||
	
 | 
			
		||||
	NSString* processName = [[NSProcessInfo processInfo] processName];
 | 
			
		||||
 | 
			
		||||
	if ([processName isEqualToString:@"Slide for Reddit"]){
 | 
			
		||||
		if (isSlideEnabled){
 | 
			
		||||
			
 | 
			
		||||
			CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, prefsChanged, CFSTR("com.lint.undelete.prefs.changed"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
 | 
			
		||||
			
 | 
			
		||||
			%init(Slide, CommentDepthCell = objc_getClass("Slide_for_Reddit.CommentDepthCell"), RComment = objc_getClass("Slide_for_Reddit.RSubmission"));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user