From 2ef7f4f7248ae6651e8d5f5d9405eeb00e187ae8 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Thu, 18 Sep 2014 15:15:41 -0700 Subject: [PATCH] Adding long press menu to images. See the alt text (perfect for reading xkcd), copy image, save image to camera roll, or zoom image. --- .../ios/Classes/StoryDetailViewController.h | 7 +- .../ios/Classes/StoryDetailViewController.m | 81 ++++++++++++++++--- clients/ios/Classes/StoryPageControl.m | 6 +- clients/ios/NewsBlur_Prefix.pch | 2 +- clients/ios/static/storyDetailView.css | 2 + 5 files changed, 82 insertions(+), 16 deletions(-) diff --git a/clients/ios/Classes/StoryDetailViewController.h b/clients/ios/Classes/StoryDetailViewController.h index fe4df4dd7..54c0ed447 100644 --- a/clients/ios/Classes/StoryDetailViewController.h +++ b/clients/ios/Classes/StoryDetailViewController.h @@ -14,7 +14,8 @@ @class ASIHTTPRequest; @interface StoryDetailViewController : BaseViewController - { + { NewsBlurAppDelegate *appDelegate; NSString *activeStoryId; @@ -25,6 +26,10 @@ BOOL pullingScrollview; BOOL inTextView; BOOL inDoubleTap; + NSURL *activeLongPressUrl; + NSInteger actionSheetViewImageIndex; + NSInteger actionSheetCopyImageIndex; + NSInteger actionSheetSaveImageIndex; } @property (nonatomic) IBOutlet NewsBlurAppDelegate *appDelegate; diff --git a/clients/ios/Classes/StoryDetailViewController.m b/clients/ios/Classes/StoryDetailViewController.m index c5f69c040..a4fdde931 100644 --- a/clients/ios/Classes/StoryDetailViewController.m +++ b/clients/ios/Classes/StoryDetailViewController.m @@ -17,6 +17,7 @@ #import "StoryPageControl.h" #import "ASIHTTPRequest.h" #import "ASIFormDataRequest.h" +#import "AFImageRequestOperation.h" #import "Base64.h" #import "Utilities.h" #import "NSString+HTML.h" @@ -1471,18 +1472,40 @@ shouldStartLoadWithRequest:(NSURLRequest *)request NSString *tagName = [webView stringByEvaluatingJavaScriptFromString: [NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');", (long)pt.x,(long)pt.y]]; - NSString *href = [webView stringByEvaluatingJavaScriptFromString: - [NSString stringWithFormat:@"linkAt(%li, %li, 'href');", - (long)pt.x,(long)pt.y]]; - NSString *title = [webView stringByEvaluatingJavaScriptFromString: - [NSString stringWithFormat:@"linkAt(%li, %li, 'innerText');", - (long)pt.x,(long)pt.y]]; - NSURL *url = [NSURL URLWithString:href]; if ([tagName isEqualToString:@"IMG"]) { - return; + NSString *title = [webView stringByEvaluatingJavaScriptFromString: + [NSString stringWithFormat:@"linkAt(%li, %li, 'title');", + (long)pt.x,(long)pt.y]]; + NSString *alt = [webView stringByEvaluatingJavaScriptFromString: + [NSString stringWithFormat:@"linkAt(%li, %li, 'alt');", + (long)pt.x,(long)pt.y]]; + NSString *src = [webView stringByEvaluatingJavaScriptFromString: + [NSString stringWithFormat:@"linkAt(%li, %li, 'src');", + (long)pt.x,(long)pt.y]]; + title = title.length ? title : alt; + activeLongPressUrl = [NSURL URLWithString:src]; + + UIActionSheet *actions = [[UIActionSheet alloc] initWithTitle:title.length ? title : nil + delegate:self + cancelButtonTitle:@"Done" + destructiveButtonTitle:nil + otherButtonTitles:nil]; + actionSheetViewImageIndex = [actions addButtonWithTitle:@"View and zoom"]; + actionSheetCopyImageIndex = [actions addButtonWithTitle:@"Copy image"]; + actionSheetSaveImageIndex = [actions addButtonWithTitle:@"Save to camera roll"]; + [actions showInView:appDelegate.storyPageControl.view]; } + if ([tagName isEqualToString:@"A"]) { + NSString *href = [webView stringByEvaluatingJavaScriptFromString: + [NSString stringWithFormat:@"linkAt(%li, %li, 'href');", + (long)pt.x,(long)pt.y]]; + NSString *title = [webView stringByEvaluatingJavaScriptFromString: + [NSString stringWithFormat:@"linkAt(%li, %li, 'innerText');", + (long)pt.x,(long)pt.y]]; + NSURL *url = [NSURL URLWithString:href]; + if (!href || ![href length]) return; [appDelegate showSendTo:appDelegate.storyPageControl @@ -1496,6 +1519,38 @@ shouldStartLoadWithRequest:(NSURLRequest *)request } } +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { + if (buttonIndex == actionSheetViewImageIndex) { + [appDelegate showOriginalStory:activeLongPressUrl]; + } else if (buttonIndex == actionSheetCopyImageIndex || + buttonIndex == actionSheetSaveImageIndex) { + [self fetchImage:activeLongPressUrl buttonIndex:buttonIndex]; + } +} + +- (void)fetchImage:(NSURL *)url buttonIndex:(NSInteger)buttonIndex { + [MBProgressHUD hideHUDForView:self.webView animated:YES]; + [appDelegate.storyPageControl showShareHUD:buttonIndex == actionSheetCopyImageIndex ? + @"Copying..." : @"Saving..."]; + + NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; + AFImageRequestOperation *requestOperation = [[AFImageRequestOperation alloc] initWithRequest:urlRequest]; + [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + UIImage *image = responseObject; + if (buttonIndex == actionSheetCopyImageIndex) { + [UIPasteboard generalPasteboard].image = image; + [self flashCheckmarkHud:@"copied"]; + } else if (buttonIndex == actionSheetSaveImageIndex) { + UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); + [self flashCheckmarkHud:@"saved"]; + } + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + [MBProgressHUD hideHUDForView:self.webView animated:YES]; + [self informError:@"Could not fetch image"]; + }]; + [requestOperation start]; +} + # pragma mark # pragma mark Subscribing to blurblog @@ -1519,7 +1574,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request - (void)finishSubscribeToBlurblog:(ASIHTTPRequest *)request { [MBProgressHUD hideHUDForView:appDelegate.storyPageControl.view animated:NO]; - self.storyHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + self.storyHUD = [MBProgressHUD showHUDAddedTo:self.webView animated:YES]; self.storyHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; self.storyHUD.mode = MBProgressHUDModeCustomView; self.storyHUD.removeFromSuperViewOnHide = YES; @@ -1570,8 +1625,8 @@ shouldStartLoadWithRequest:(NSURLRequest *)request } - (void)flashCheckmarkHud:(NSString *)messageType { - [MBProgressHUD hideHUDForView:appDelegate.storyPageControl.view animated:NO]; - self.storyHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + [MBProgressHUD hideHUDForView:self.webView animated:NO]; + self.storyHUD = [MBProgressHUD showHUDAddedTo:self.webView animated:YES]; self.storyHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; self.storyHUD.mode = MBProgressHUDModeCustomView; self.storyHUD.removeFromSuperViewOnHide = YES; @@ -1596,6 +1651,10 @@ shouldStartLoadWithRequest:(NSURLRequest *)request self.storyHUD.labelText = @"Unread"; } else if ([messageType isEqualToString:@"added"]) { self.storyHUD.labelText = @"Added"; + } else if ([messageType isEqualToString:@"copied"]) { + self.storyHUD.labelText = @"Copied"; + } else if ([messageType isEqualToString:@"saved"]) { + self.storyHUD.labelText = @"Saved"; } [self.storyHUD hide:YES afterDelay:1]; } diff --git a/clients/ios/Classes/StoryPageControl.m b/clients/ios/Classes/StoryPageControl.m index 8c4e749b5..5c26d1bac 100644 --- a/clients/ios/Classes/StoryPageControl.m +++ b/clients/ios/Classes/StoryPageControl.m @@ -916,8 +916,8 @@ } - (IBAction)tapProgressBar:(id)sender { - [MBProgressHUD hideHUDForView:self.view animated:NO]; - MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + [MBProgressHUD hideHUDForView:currentPage.webView animated:NO]; + MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:currentPage.webView animated:YES]; hud.mode = MBProgressHUDModeText; hud.removeFromSuperViewOnHide = YES; NSInteger unreadCount = appDelegate.unreadCount; @@ -992,7 +992,7 @@ - (void)showShareHUD:(NSString *)msg { // [MBProgressHUD hideHUDForView:self.view animated:NO]; - self.storyHUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + self.storyHUD = [MBProgressHUD showHUDAddedTo:currentPage.webView animated:YES]; self.storyHUD.labelText = msg; self.storyHUD.margin = 20.0f; self.currentPage.noStoryMessage.hidden = YES; diff --git a/clients/ios/NewsBlur_Prefix.pch b/clients/ios/NewsBlur_Prefix.pch index 743695d63..252e01e0e 100644 --- a/clients/ios/NewsBlur_Prefix.pch +++ b/clients/ios/NewsBlur_Prefix.pch @@ -5,7 +5,7 @@ #import #import -//#define DEBUG 1 +#define DEBUG 1 //#define PROD_DEBUG 1 #ifdef DEBUG diff --git a/clients/ios/static/storyDetailView.css b/clients/ios/static/storyDetailView.css index cd1c324f6..fb8581734 100644 --- a/clients/ios/static/storyDetailView.css +++ b/clients/ios/static/storyDetailView.css @@ -453,6 +453,8 @@ div + p { width: auto; max-width: 100% !important; display: none; + -webkit-touch-callout: none; + -webkit-user-select: none; /* Disable selection/copy in UIWebView */ } .NB-story img.NB-large-image,