From 7b8c0d957ec6b052464f34ed7a31251171a7fa16 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 3 Feb 2014 18:54:50 -0800 Subject: [PATCH] Handling gestures for entering original view. --- .../ios/Classes/FeedDetailViewController.m | 2 +- .../ios/Classes/NBContainerViewController.m | 8 ++-- clients/ios/Classes/NewsBlurAppDelegate.m | 6 +-- clients/ios/Classes/NewsBlurViewController.m | 5 +-- .../ios/Classes/OriginalStoryViewController.h | 3 +- .../ios/Classes/OriginalStoryViewController.m | 19 +++++++--- .../ios/Classes/StoryDetailViewController.h | 2 +- .../ios/Classes/StoryDetailViewController.m | 37 ++++++++++++++++++- clients/ios/Classes/Utilities.m | 2 +- .../ios/Classes/offline/OfflineFetchImages.m | 2 +- .../ios/Classes/offline/OfflineFetchStories.m | 2 +- 11 files changed, 65 insertions(+), 23 deletions(-) diff --git a/clients/ios/Classes/FeedDetailViewController.m b/clients/ios/Classes/FeedDetailViewController.m index 0519e0db6..7bfc3315d 100644 --- a/clients/ios/Classes/FeedDetailViewController.m +++ b/clients/ios/Classes/FeedDetailViewController.m @@ -1771,7 +1771,7 @@ heightForRowAtIndexPath:(NSIndexPath *)indexPath { options:kNilOptions error:&error]; - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0ul); dispatch_async(queue, ^{ for (id feed_id in results) { NSMutableDictionary *feed = [[appDelegate.dictActiveFeeds objectForKey:feed_id] mutableCopy]; diff --git a/clients/ios/Classes/NBContainerViewController.m b/clients/ios/Classes/NBContainerViewController.m index e574c73c2..ea243d0a5 100644 --- a/clients/ios/Classes/NBContainerViewController.m +++ b/clients/ios/Classes/NBContainerViewController.m @@ -744,11 +744,11 @@ // NSLog(@"Original frame: %@", NSStringFromCGRect(self.originalViewController.view.frame)); CGRect feedDetailFrame = self.feedDetailViewController.view.frame; - feedDetailFrame.origin.x = -1 * (1-percentage) * feedDetailFrame.size.width/6; + feedDetailFrame.origin.x = -1 * (1-percentage) * 100; self.feedDetailViewController.view.frame = feedDetailFrame; CGRect storyNavFrame = self.storyNavigationController.view.frame; - storyNavFrame.origin.x = -1 * (1-percentage) * feedDetailFrame.size.width/6; + storyNavFrame.origin.x = -1 * (1-percentage) * 100; self.storyNavigationController.view.frame = storyNavFrame; } else { CGRect originalNavFrame = self.originalNavigationController.view.frame; @@ -758,11 +758,11 @@ // NSLog(@"Original frame: %@", NSStringFromCGRect([[[[self.originalNavigationController viewControllers] objectAtIndex:0] view] frame])); CGRect feedDetailFrame = self.masterNavigationController.view.frame; - feedDetailFrame.origin.x = -1 * (1-percentage) * feedDetailFrame.size.width/6; + feedDetailFrame.origin.x = -1 * (1-percentage) * 100; self.masterNavigationController.view.frame = feedDetailFrame; CGRect storyNavFrame = self.storyNavigationController.view.frame; - storyNavFrame.origin.x = NB_DEFAULT_MASTER_WIDTH - 1 + -1 * (1-percentage) * feedDetailFrame.size.width/6; + storyNavFrame.origin.x = NB_DEFAULT_MASTER_WIDTH - 1 + -1 * (1-percentage) * 100; self.storyNavigationController.view.frame = storyNavFrame; } diff --git a/clients/ios/Classes/NewsBlurAppDelegate.m b/clients/ios/Classes/NewsBlurAppDelegate.m index e596b8ceb..81c75d55d 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.m +++ b/clients/ios/Classes/NewsBlurAppDelegate.m @@ -192,8 +192,8 @@ [window makeKeyAndVisible]; // [self performSelectorOnMainThread:@selector(showSplashView) withObject:nil waitUntilDone:NO]; - [[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0xE0E3DB)]; - [[UIToolbar appearance] setBarTintColor:UIColorFromRGB(0xE0E3DB)]; + [[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0xE3E6E0)]; + [[UIToolbar appearance] setBarTintColor: UIColorFromRGB(0xE3E6E0)]; [[UISegmentedControl appearance] setTintColor:UIColorFromRGB(0x8F918B)]; // [[UISegmentedControl appearance] setBackgroundColor:UIColorFromRGB(0x8F918B)]; @@ -2976,7 +2976,7 @@ - (void)flushQueuedReadStories:(BOOL)forceCheck withCallback:(void(^)())callback { if (self.hasQueuedReadStories || forceCheck) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, (unsigned long)NULL), ^(void) { [self.database inTransaction:^(FMDatabase *db, BOOL *rollback) { NSMutableDictionary *hashes = [NSMutableDictionary dictionary]; diff --git a/clients/ios/Classes/NewsBlurViewController.m b/clients/ios/Classes/NewsBlurViewController.m index a174313bf..7dab18777 100644 --- a/clients/ios/Classes/NewsBlurViewController.m +++ b/clients/ios/Classes/NewsBlurViewController.m @@ -522,7 +522,6 @@ static UIFont *userLabelFont; forKey:userKey]; } - NSLog(@"Setting dictSocialFeeds"); appDelegate.dictSocialFeeds = socialDict; [self loadAvatars]; @@ -1536,7 +1535,7 @@ heightForHeaderInSection:(NSInteger)section { } - (void)loadAvatars { - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0ul); dispatch_async(queue, ^{ for (NSString *feed_id in [appDelegate.dictSocialFeeds allKeys]) { NSDictionary *feed = [appDelegate.dictSocialFeeds objectForKey:feed_id]; @@ -1569,7 +1568,7 @@ heightForHeaderInSection:(NSInteger)section { options:kNilOptions error:&error]; - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0ul); dispatch_async(queue, ^{ for (id feed_id in results) { NSMutableDictionary *feed = [[appDelegate.dictFeeds objectForKey:feed_id] mutableCopy]; diff --git a/clients/ios/Classes/OriginalStoryViewController.h b/clients/ios/Classes/OriginalStoryViewController.h index 0d84ea583..2d529139a 100644 --- a/clients/ios/Classes/OriginalStoryViewController.h +++ b/clients/ios/Classes/OriginalStoryViewController.h @@ -12,7 +12,8 @@ @class NewsBlurAppDelegate; @interface OriginalStoryViewController : BaseViewController - { + { NewsBlurAppDelegate *appDelegate; NSString *activeUrl; diff --git a/clients/ios/Classes/OriginalStoryViewController.m b/clients/ios/Classes/OriginalStoryViewController.m index 0cf1e3dcc..df4ff5941 100644 --- a/clients/ios/Classes/OriginalStoryViewController.m +++ b/clients/ios/Classes/OriginalStoryViewController.m @@ -108,13 +108,12 @@ if ([recognizer state] == UIGestureRecognizerStateEnded || [recognizer state] == UIGestureRecognizerStateCancelled) { CGFloat velocity = [recognizer velocityInView:recognizer.view].x; - if (percentage > 0.25 && velocity > 0) { - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { - [appDelegate.masterContainerViewController transitionFromOriginalView]; - } else { - - } + if ((percentage > 0.25 && velocity > 0) || + (percentage > 0.05 && velocity > 1000)) { + NSLog(@"Original velocity ESCAPED: %f (at %.2f%%)", velocity, percentage*100); + [self transitionToFeedDetail:recognizer]; } else { + NSLog(@"Original velocity: %f (at %.2f%%)", velocity, percentage*100); if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { [appDelegate.masterContainerViewController transitionToOriginalView:NO]; } else { @@ -124,6 +123,14 @@ } } +- (void)transitionToFeedDetail:(UIGestureRecognizer *)recognizer { + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + [appDelegate.masterContainerViewController transitionFromOriginalView]; + } else { + + } +} + - (void)loadInitialStory { [self loadAddress:nil]; titleView.text = [[appDelegate activeStory] objectForKey:@"story_title"]; diff --git a/clients/ios/Classes/StoryDetailViewController.h b/clients/ios/Classes/StoryDetailViewController.h index 3f5a7f43b..aaf213650 100644 --- a/clients/ios/Classes/StoryDetailViewController.h +++ b/clients/ios/Classes/StoryDetailViewController.h @@ -14,7 +14,7 @@ @class ASIHTTPRequest; @interface StoryDetailViewController : BaseViewController - { + { NewsBlurAppDelegate *appDelegate; NSString *activeStoryId; diff --git a/clients/ios/Classes/StoryDetailViewController.m b/clients/ios/Classes/StoryDetailViewController.m index b35b1860a..f433d0d09 100644 --- a/clients/ios/Classes/StoryDetailViewController.m +++ b/clients/ios/Classes/StoryDetailViewController.m @@ -62,7 +62,7 @@ error:nil]; self.webView.scalesPageToFit = YES; - self.webView.multipleTouchEnabled = NO; +// self.webView.multipleTouchEnabled = NO; [self.webView.scrollView setDelaysContentTouches:NO]; [self.webView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal]; @@ -70,6 +70,10 @@ [self.webView.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + + UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] + initWithTarget:self action:@selector(showOriginalStory:)]; + [self.webView addGestureRecognizer:pinchGesture]; self.pageIndex = -2; self.inTextView = NO; @@ -1049,6 +1053,37 @@ shouldStartLoadWithRequest:(NSURLRequest *)request return YES; } +- (void)showOriginalStory:(UIGestureRecognizer *)gesture { + NSURL *url = [NSURL URLWithString:[appDelegate.activeStory + objectForKey:@"story_permalink"]]; + [appDelegate.masterContainerViewController hidePopover]; + + if (!gesture) { + [appDelegate showOriginalStory:url]; + return; + } + + if ([gesture isKindOfClass:[UIPinchGestureRecognizer class]] && + gesture.state == UIGestureRecognizerStateChanged && + [gesture numberOfTouches] >= 2) { + CGPoint touch1 = [gesture locationOfTouch:0 inView:self.view]; + CGPoint touch2 = [gesture locationOfTouch:1 inView:self.view]; + CGPoint slope = CGPointMake(touch2.x-touch1.x, touch2.y-touch1.y); + CGFloat distance = sqrtf(slope.x*slope.x + slope.y*slope.y); + CGFloat scale = [(UIPinchGestureRecognizer *)gesture scale]; + + NSLog(@"Gesture: %f - %f", [(UIPinchGestureRecognizer *)gesture scale], distance); + + if ((distance < 150 && scale <= 1.5) || + (distance < 500 && scale <= 1.2)) { + return; + } + [appDelegate showOriginalStory:url]; + gesture.enabled = NO; + gesture.enabled = YES; + } +} + - (void)showUserProfile:(NSString *)userId xCoordinate:(int)x yCoordinate:(int)y width:(int)width height:(int)height { CGRect frame = CGRectZero; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { diff --git a/clients/ios/Classes/Utilities.m b/clients/ios/Classes/Utilities.m index 874befda5..c26669d10 100644 --- a/clients/ios/Classes/Utilities.m +++ b/clients/ios/Classes/Utilities.m @@ -112,7 +112,7 @@ static NSMutableDictionary *imageCache; } + (void)saveimagesToDisk { - dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0); dispatch_async(queue, ^{ for (NSString *filename in [imageCache allKeys]) { diff --git a/clients/ios/Classes/offline/OfflineFetchImages.m b/clients/ios/Classes/offline/OfflineFetchImages.m index 1494c3d31..d289523aa 100644 --- a/clients/ios/Classes/offline/OfflineFetchImages.m +++ b/clients/ios/Classes/offline/OfflineFetchImages.m @@ -154,7 +154,7 @@ return; } - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, (unsigned long)NULL), ^{ NSString *storyHash = [[request userInfo] objectForKey:@"story_hash"]; diff --git a/clients/ios/Classes/offline/OfflineFetchStories.m b/clients/ios/Classes/offline/OfflineFetchStories.m index 6e08fde9a..b98a2a32e 100644 --- a/clients/ios/Classes/offline/OfflineFetchStories.m +++ b/clients/ios/Classes/offline/OfflineFetchStories.m @@ -78,7 +78,7 @@ NSLog(@"Failed fetch all unreads."); [lock signal]; }]; - request.successCallbackQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, + request.successCallbackQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, (unsigned long)NULL); [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; [request start];