2010-06-25 18:36:01 -04:00
//
// StoryDetailViewController . m
// NewsBlur
//
// Created by Samuel Clay on 6 / 24 / 10.
// Copyright 2010 __MyCompanyName __ . All rights reserved .
//
2013-10-02 19:01:15 -07:00
# import < AVFoundation / AVFoundation . h >
2010-06-25 18:36:01 -04:00
# import "StoryDetailViewController.h"
# import "NewsBlurAppDelegate.h"
2012-07-15 15:06:06 -07:00
# import "NewsBlurViewController.h"
2011-09-05 22:06:31 -07:00
# import "FeedDetailViewController.h"
2012-06-18 14:31:42 -07:00
# import "FontSettingsViewController.h"
2012-07-03 17:54:36 -07:00
# import "UserProfileViewController.h"
2012-07-12 13:34:41 -07:00
# import "ShareViewController.h"
2012-11-07 17:54:16 -08:00
# import "StoryPageControl.h"
2015-09-18 15:02:15 -07:00
# import "AFHTTPRequestOperation.h"
2011-09-05 22:06:31 -07:00
# import "Base64.h"
2011-10-17 09:37:16 -07:00
# import "Utilities.h"
2012-07-20 19:55:38 -07:00
# import "NSString+HTML.h"
2012-07-24 15:29:01 -07:00
# import "NBContainerViewController.h"
2012-07-26 13:54:45 -07:00
# import "DataUtilities.h"
2015-09-16 21:34:41 -07:00
# import "FMDatabase.h"
2015-09-16 16:53:07 -07:00
# import "SBJson4.h"
2012-12-07 16:17:48 -08:00
# import "StringHelper.h"
2014-02-12 20:09:37 -08:00
# import "StoriesCollection.h"
2014-09-17 19:02:12 -07:00
# import "UIWebView+Offsets.h"
# import "UIView+ViewController.h"
2015-09-16 21:34:41 -07:00
# import "JNWThrottledBlock.h"
2010-06-25 18:36:01 -04:00
2016-04-06 18:14:06 -07:00
# define iPadPro ( [ [ UIDevice currentDevice ] userInterfaceIdiom ] = = UIUserInterfaceIdiomPad && ( [ UIScreen mainScreen ] . bounds . size . height = = 1366 || [ UIScreen mainScreen ] . bounds . size . width = = 1366 ) )
2016-02-05 12:19:48 -08:00
@ interface StoryDetailViewController ( )
2016-08-23 20:52:34 -04:00
@ property ( nonatomic , strong ) NSString * fullStoryHTML ;
2016-02-05 12:19:48 -08:00
@ end
2016-02-01 10:44:59 -08:00
@ implementation StoryDetailViewController
2010-06-25 18:36:01 -04:00
2016-02-01 10:44:59 -08:00
@ synthesize appDelegate ;
@ synthesize activeStoryId ;
@ synthesize activeStory ;
@ synthesize innerView ;
@ synthesize webView ;
@ synthesize feedTitleGradient ;
@ synthesize noStoryMessage ;
@ synthesize pullingScrollview ;
@ synthesize pageIndex ;
@ synthesize storyHUD ;
@ synthesize inTextView ;
@ synthesize isRecentlyUnread ;
2012-07-26 18:07:29 -07:00
2011-12-01 09:01:18 -08:00
# pragma mark -
# pragma mark View boilerplate
2010-06-25 18:36:01 -04:00
- ( id ) initWithNibName : ( NSString * ) nibNameOrNil bundle : ( NSBundle * ) nibBundleOrNil {
2011-03-09 18:23:55 -05:00
if ( ( self = [ super initWithNibName : nibNameOrNil bundle : nibBundleOrNil ] ) ) {
2010-06-25 18:36:01 -04:00
}
return self ;
}
2011-08-14 00:16:25 -07:00
2015-04-26 21:22:25 -07:00
- ( NSString * ) description {
2016-02-01 10:44:59 -08:00
NSString * page = appDelegate . storyPageControl . currentPage = = self ? @ "currentPage" : appDelegate . storyPageControl . previousPage = = self ? @ "previousPage" : appDelegate . storyPageControl . nextPage = = self ? @ "nextPage" : @ "unattached page" ;
2015-04-26 21:22:25 -07:00
return [ NSString stringWithFormat : @ "%@" , page ] ;
}
2011-08-24 10:24:02 -07:00
- ( void ) viewDidLoad {
2012-07-16 10:10:52 -07:00
[ super viewDidLoad ] ;
2012-07-23 15:27:20 -07:00
self . view . autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight ;
2013-10-02 19:01:15 -07:00
AVAudioSession * audioSession = [ AVAudioSession sharedInstance ] ;
[ audioSession setCategory : AVAudioSessionCategoryPlayback
error : nil ] ;
2016-02-01 10:44:59 -08:00
self . webView . scalesPageToFit = YES ;
2014-02-03 18:54:50 -08:00
// self . webView . multipleTouchEnabled = NO ;
2012-12-27 18:37:05 -08:00
[ self . webView . scrollView setDelaysContentTouches : NO ] ;
[ self . webView . scrollView setDecelerationRate : UIScrollViewDecelerationRateNormal ] ;
2015-09-23 11:34:03 -07:00
[ self . webView . scrollView setAutoresizesSubviews : ( UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight ) ] ;
2013-03-22 19:25:41 -07:00
[ self . webView . scrollView addObserver : self forKeyPath : @ "contentOffset"
options : NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context : nil ] ;
2015-12-10 15:07:23 -08:00
[ self clearWebView ] ;
2014-02-03 18:54:50 -08:00
2014-02-04 12:40:46 -08:00
// UIPinchGestureRecognizer * pinchGesture = [ [ UIPinchGestureRecognizer alloc ]
// initWithTarget : self action : @ selector ( showOriginalStory : ) ] ;
// [ self . webView addGestureRecognizer : pinchGesture ] ;
2013-10-11 17:46:09 -07:00
2014-02-03 19:20:26 -08:00
UITapGestureRecognizer * doubleTapGesture = [ [ UITapGestureRecognizer alloc ]
2014-09-18 18:25:38 -07:00
initWithTarget : self action : @ selector ( doubleTap : ) ] ;
2014-02-03 19:20:26 -08:00
doubleTapGesture . numberOfTapsRequired = 2 ;
doubleTapGesture . delegate = self ;
2014-09-18 18:25:38 -07:00
[ self . webView addGestureRecognizer : doubleTapGesture ] ;
2014-09-19 14:48:54 -07:00
// UITapGestureRecognizer * tapGesture = [ [ UITapGestureRecognizer alloc ]
// initWithTarget : self action : @ selector ( tap : ) ] ;
// tapGesture . numberOfTapsRequired = 1 ;
// tapGesture . delegate = self ;
// [ tapGesture requireGestureRecognizerToFail : doubleTapGesture ] ;
// [ self . webView addGestureRecognizer : tapGesture ] ;
2014-02-03 19:20:26 -08:00
2014-02-05 17:14:23 -08:00
UITapGestureRecognizer * doubleDoubleTapGesture = [ [ UITapGestureRecognizer alloc ]
initWithTarget : self
2014-09-18 18:25:38 -07:00
action : @ selector ( doubleTap : ) ] ;
2014-02-05 17:14:23 -08:00
doubleDoubleTapGesture . numberOfTouchesRequired = 2 ;
doubleDoubleTapGesture . numberOfTapsRequired = 2 ;
doubleDoubleTapGesture . delegate = self ;
2014-09-18 18:25:38 -07:00
[ self . webView addGestureRecognizer : doubleDoubleTapGesture ] ;
2015-12-07 16:09:49 -08:00
[ [ ThemeManager themeManager ] addThemeGestureRecognizerToView : self . webView ] ;
2015-12-20 22:04:55 -08:00
// This makes the theme gesture work reliably , but makes scrolling more "sticky" , so isn ' t acceptable :
// UIGestureRecognizer * themeGesture = [ [ ThemeManager themeManager ] addThemeGestureRecognizerToView : self . webView ] ;
// [ self . webView . scrollView . panGestureRecognizer requireGestureRecognizerToFail : themeGesture ] ;
2012-11-14 17:31:52 -08:00
self . pageIndex = -2 ;
2013-05-29 13:36:39 -07:00
self . inTextView = NO ;
2014-09-17 19:02:12 -07:00
[ [ NSNotificationCenter defaultCenter ] addObserver : self
selector : @ selector ( tapAndHold : )
name : @ "TapAndHoldNotification"
object : nil ] ;
2016-02-01 10:44:59 -08:00
_orientation = [ UIApplication sharedApplication ] . statusBarOrientation ;
2011-08-24 10:24:02 -07:00
}
2014-02-03 19:20:26 -08:00
- ( BOOL ) gestureRecognizer : ( UIGestureRecognizer * ) gestureRecognizer shouldReceiveTouch : ( UITouch * ) touch {
2016-02-01 10:44:59 -08:00
// NSLog ( @ "Gesture: %d - %d" , ( unsigned long ) touch . tapCount , gestureRecognizer . state ) ;
inDoubleTap = ( touch . tapCount = = 2 ) ;
CGPoint pt = [ self pointForGesture : gestureRecognizer ] ;
if ( pt . x = = CGPointZero . x && pt . y = = CGPointZero . y ) return YES ;
// NSLog ( @ "Tapped point: %@" , NSStringFromCGPoint ( pt ) ) ;
NSString * tagName = [ webView stringByEvaluatingJavaScriptFromString :
[ NSString stringWithFormat : @ "linkAt(%li, %li, 'tagName');" ,
( long ) pt . x , ( long ) pt . y ] ] ;
if ( [ tagName isEqualToString : @ "IMG" ] && ! inDoubleTap ) {
return NO ;
}
if ( inDoubleTap ) {
self . webView . scrollView . scrollEnabled = NO ;
[ self performSelector : @ selector ( deferredEnableScrolling ) withObject : nil afterDelay : 0.0 ] ;
}
2014-02-03 19:20:26 -08:00
return YES ;
}
2014-02-05 17:14:23 -08:00
2014-02-03 19:20:26 -08:00
- ( BOOL ) gestureRecognizer : ( UIGestureRecognizer * ) gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer : ( UIGestureRecognizer * ) otherGestureRecognizer {
2014-09-19 16:58:56 -07:00
// NSLog ( @ "Should conflict? \n\tgesture:%@ \n\t other:%@" ,
// gestureRecognizer , otherGestureRecognizer ) ;
2014-09-18 18:25:38 -07:00
return YES ;
}
- ( void ) tap : ( UITapGestureRecognizer * ) gestureRecognizer {
2016-02-01 10:44:59 -08:00
// NSLog ( @ "Gesture tap: %d (%d) - %d" , gestureRecognizer . state , UIGestureRecognizerStateEnded , inDoubleTap ) ;
2014-09-18 18:25:38 -07:00
if ( gestureRecognizer . state = = UIGestureRecognizerStateEnded && gestureRecognizer . numberOfTouches = = 1 ) {
[ self tapImage : gestureRecognizer ] ;
}
}
- ( void ) doubleTap : ( UITapGestureRecognizer * ) gestureRecognizer {
2016-02-01 10:44:59 -08:00
// NSLog ( @ "Gesture double tap: %d (%d) - %d" , gestureRecognizer . state , UIGestureRecognizerStateEnded , inDoubleTap ) ;
if ( gestureRecognizer . state = = UIGestureRecognizerStateEnded && inDoubleTap ) {
2014-03-03 15:47:24 -08:00
NSUserDefaults * preferences = [ NSUserDefaults standardUserDefaults ] ;
BOOL openOriginal = NO ;
BOOL showText = NO ;
2014-03-03 16:21:26 -08:00
BOOL markUnread = NO ;
BOOL saveStory = NO ;
2014-02-05 17:14:23 -08:00
if ( gestureRecognizer . numberOfTouches = = 2 ) {
2014-03-03 15:47:24 -08:00
NSString * twoFingerTap = [ preferences stringForKey : @ "two_finger_double_tap" ] ;
if ( [ twoFingerTap isEqualToString : @ "open_original_story" ] ) {
openOriginal = YES ;
} else if ( [ twoFingerTap isEqualToString : @ "show_original_text" ] ) {
showText = YES ;
2014-03-03 16:21:26 -08:00
} else if ( [ twoFingerTap isEqualToString : @ "mark_unread" ] ) {
markUnread = YES ;
} else if ( [ twoFingerTap isEqualToString : @ "save_story" ] ) {
saveStory = YES ;
2014-03-03 15:47:24 -08:00
}
2014-02-05 17:14:23 -08:00
} else {
2014-03-03 15:47:24 -08:00
NSString * doubleTap = [ preferences stringForKey : @ "double_tap_story" ] ;
if ( [ doubleTap isEqualToString : @ "open_original_story" ] ) {
openOriginal = YES ;
} else if ( [ doubleTap isEqualToString : @ "show_original_text" ] ) {
showText = YES ;
2014-03-03 16:21:26 -08:00
} else if ( [ doubleTap isEqualToString : @ "mark_unread" ] ) {
markUnread = YES ;
} else if ( [ doubleTap isEqualToString : @ "save_story" ] ) {
saveStory = YES ;
2014-03-03 15:47:24 -08:00
}
}
if ( openOriginal ) {
2014-02-05 17:14:23 -08:00
[ self showOriginalStory : gestureRecognizer ] ;
2014-03-03 15:47:24 -08:00
} else if ( showText ) {
[ self fetchTextView ] ;
2014-03-03 16:21:26 -08:00
} else if ( markUnread ) {
2016-02-01 10:44:59 -08:00
[ appDelegate . storiesCollection toggleStoryUnread ] ;
[ appDelegate . feedDetailViewController reloadData ] ;
2014-03-03 16:21:26 -08:00
} else if ( saveStory ) {
2016-02-01 10:44:59 -08:00
[ appDelegate . storiesCollection toggleStorySaved ] ;
[ appDelegate . feedDetailViewController reloadData ] ;
2014-02-05 17:14:23 -08:00
}
2016-02-01 10:44:59 -08:00
inDoubleTap = NO ;
2015-11-12 15:30:40 -08:00
[ self performSelector : @ selector ( deferredEnableScrolling ) withObject : nil afterDelay : 0.0 ] ;
2014-02-04 12:40:46 -08:00
}
2014-02-03 19:20:26 -08:00
}
2015-11-12 15:30:40 -08:00
- ( void ) deferredEnableScrolling {
self . webView . scrollView . scrollEnabled = YES ;
}
2012-07-20 19:55:38 -07:00
- ( void ) viewDidUnload {
[ self setInnerView : nil ] ;
2013-09-12 21:26:38 -07:00
2012-07-20 19:55:38 -07:00
[ super viewDidUnload ] ;
}
2011-08-14 10:22:26 -07:00
- ( void ) viewDidDisappear : ( BOOL ) animated {
2014-09-18 11:25:51 -07:00
[ super viewDidDisappear : animated ] ;
2015-11-05 14:16:11 -08:00
2016-02-01 10:44:59 -08:00
if ( ! appDelegate . showingSafariViewController &&
appDelegate . navigationController . visibleViewController ! = ( UIViewController * ) appDelegate . originalStoryViewController ) {
2015-11-05 14:16:11 -08:00
[ self clearStory ] ;
}
2011-08-14 10:22:26 -07:00
}
2014-12-02 18:36:38 -08:00
- ( void ) viewWillDisappear : ( BOOL ) animated {
[ super viewWillDisappear : animated ] ;
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2016-02-01 10:44:59 -08:00
[ appDelegate . feedDetailViewController . view endEditing : YES ] ;
2014-12-02 18:36:38 -08:00
}
2015-09-17 13:15:10 -07:00
[ self storeScrollPosition : NO ] ;
2014-12-02 18:36:38 -08:00
}
- ( void ) viewWillAppear : ( BOOL ) animated {
[ super viewWillAppear : animated ] ;
2016-10-05 21:03:32 -07:00
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2016-02-01 10:44:59 -08:00
[ appDelegate . feedDetailViewController . view endEditing : YES ] ;
2014-12-02 18:36:38 -08:00
}
2016-02-01 10:44:59 -08:00
if ( _orientation ! = [ UIApplication sharedApplication ] . statusBarOrientation ) {
_orientation = [ UIApplication sharedApplication ] . statusBarOrientation ;
2015-09-23 14:37:54 -07:00
NSLog ( @ "Found stale orientation in story detail: %@" , NSStringFromCGSize ( self . view . bounds . size ) ) ;
}
2015-10-27 21:52:11 -07:00
2015-12-12 15:42:39 -08:00
if ( ! self . hasStory ) {
2015-10-27 21:52:11 -07:00
[ self drawStory ] ;
}
2015-09-23 14:37:54 -07:00
}
2015-09-28 20:01:17 -07:00
- ( void ) viewDidAppear : ( BOOL ) animated {
[ super viewDidAppear : animated ] ;
2015-10-24 20:58:00 -07:00
// Fix the position and size ; can probably remove this once all views use auto layout
CGRect viewFrame = self . view . frame ;
CGSize superSize = self . view . superview . bounds . size ;
if ( viewFrame . size . height > superSize . height ) {
self . view . frame = CGRectMake ( viewFrame . origin . x , viewFrame . origin . y , viewFrame . size . width , superSize . height ) ;
}
2015-09-28 20:01:17 -07:00
}
2015-09-22 13:10:35 -07:00
- ( void ) viewWillTransitionToSize : ( CGSize ) size withTransitionCoordinator : ( id < UIViewControllerTransitionCoordinator > ) coordinator {
2015-09-23 14:37:54 -07:00
[ super viewWillTransitionToSize : size withTransitionCoordinator : coordinator ] ;
2016-02-01 10:44:59 -08:00
scrollPct = self . webView . scrollView . contentOffset . y / self . webView . scrollView . contentSize . height ;
// NSLog ( @ "Current scroll is %2.2f%% (offset %.0f - height %.0f)" , scrollPct * 100 , self . webView . scrollView . contentOffset . y ,
2015-11-30 18:12:10 -08:00
// self . webView . scrollView . contentSize . height ) ;
2015-09-28 20:01:17 -07:00
2015-09-22 13:10:35 -07:00
[ coordinator animateAlongsideTransition : ^ ( id < UIViewControllerTransitionCoordinatorContext > _Nonnull context ) {
2016-02-01 10:44:59 -08:00
_orientation = [ UIApplication sharedApplication ] . statusBarOrientation ;
2015-09-22 13:10:35 -07:00
[ self changeWebViewWidth ] ;
[ self drawFeedGradient ] ;
2015-09-28 20:01:17 -07:00
[ self scrollToLastPosition : NO ] ;
2015-09-22 13:10:35 -07:00
} completion : ^ ( id < UIViewControllerTransitionCoordinatorContext > _Nonnull context ) {
} ] ;
}
2015-09-28 20:01:17 -07:00
- ( void ) viewWillLayoutSubviews {
2015-11-30 18:12:10 -08:00
UIInterfaceOrientation orientation = [ UIApplication sharedApplication ] . statusBarOrientation ;
2015-09-28 20:01:17 -07:00
[ super viewWillLayoutSubviews ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl layoutForInterfaceOrientation : orientation ] ;
2015-09-28 20:01:17 -07:00
[ self changeWebViewWidth ] ;
[ self drawFeedGradient ] ;
2015-11-30 18:12:10 -08:00
2015-12-01 16:51:18 -08:00
// NSLog ( @ "viewWillLayoutSubviews: %.2f" , self . webView . scrollView . bounds . size . width ) ;
2015-09-28 20:01:17 -07:00
}
2015-11-30 18:12:10 -08:00
- ( void ) layoutForInterfaceOrientation : ( UIInterfaceOrientation ) interfaceOrientation {
2016-02-01 10:44:59 -08:00
if ( interfaceOrientation ! = _orientation ) {
_orientation = interfaceOrientation ;
2015-11-30 18:12:10 -08:00
[ self changeWebViewWidth ] ;
[ self drawFeedGradient ] ;
[ self drawStory ] ;
}
2015-09-28 20:01:17 -07:00
}
2015-11-28 22:07:38 -08:00
- ( BOOL ) isPhoneOrCompact {
return UI_USER _INTERFACE _IDIOM ( ) = = UIUserInterfaceIdiomPhone || self . appDelegate . isCompactWidth ;
}
2015-11-21 23:23:37 -05:00
// allow keyboard comands
- ( BOOL ) canBecomeFirstResponder {
return YES ;
}
2011-12-01 09:01:18 -08:00
# pragma mark -
2012-11-08 17:39:32 -08:00
# pragma mark Story setup
2012-11-06 12:45:19 -08:00
- ( void ) initStory {
2016-02-01 10:44:59 -08:00
appDelegate . inStoryDetail = YES ;
2013-09-26 19:26:10 -07:00
self . noStoryMessage . hidden = YES ;
2015-10-05 11:45:33 -07:00
self . inTextView = NO ;
2012-11-08 17:39:32 -08:00
2016-02-01 10:44:59 -08:00
[ appDelegate hideShareView : NO ] ;
2012-11-08 17:39:32 -08:00
}
2016-08-23 20:52:34 -04:00
- ( void ) loadHTMLString : ( NSString * ) html {
static NSURL * baseURL ;
static dispatch_once _t onceToken ;
dispatch_once ( & onceToken , ^ {
baseURL = [ NSBundle mainBundle ] . bundleURL ;
} ) ;
[ self . webView loadHTMLString : html baseURL : baseURL ] ;
}
2013-09-12 21:26:38 -07:00
- ( void ) hideNoStoryMessage {
2013-09-26 19:26:10 -07:00
self . noStoryMessage . hidden = YES ;
2013-09-12 21:26:38 -07:00
}
2012-11-08 17:39:32 -08:00
- ( void ) drawStory {
2013-03-04 17:15:50 -08:00
UIInterfaceOrientation orientation = [ UIApplication sharedApplication ] . statusBarOrientation ;
[ self drawStory : NO withOrientation : orientation ] ;
}
- ( void ) drawStory : ( BOOL ) force withOrientation : ( UIInterfaceOrientation ) orientation {
2015-10-06 18:52:58 -07:00
if ( ! force && [ self . activeStoryId isEqualToString : [ self . activeStory objectForKey : @ "story_hash" ] ] ) {
2015-12-01 16:51:18 -08:00
// NSLog ( @ "Already drawn story, drawing anyway: %@" , [ self . activeStory objectForKey : @ "story_title" ] ) ;
2012-11-14 17:31:52 -08:00
// return ;
}
2015-03-10 18:58:23 -07:00
2016-02-01 10:44:59 -08:00
scrollPct = 0 ;
hasScrolled = NO ;
2014-12-01 17:22:40 -08:00
2012-11-06 12:45:19 -08:00
NSString * shareBarString = [ self getShareBar ] ;
NSString * commentString = [ self getComments ] ;
NSString * headerString ;
NSString * sharingHtmlString ;
NSString * footerString ;
NSString * fontStyleClass = @ "" ;
2015-11-03 12:10:28 -08:00
NSString * customStyle = @ "" ;
2013-11-23 13:03:14 -08:00
NSString * fontSizeClass = @ "NB-" ;
2014-05-15 18:06:56 -07:00
NSString * lineSpacingClass = @ "NB-line-spacing-" ;
2013-06-23 22:19:08 -07:00
NSString * storyContent = [ self . activeStory objectForKey : @ "story_content" ] ;
2015-03-10 18:58:23 -07:00
if ( self . inTextView && [ self . activeStory objectForKey : @ "original_text" ] ) {
storyContent = [ self . activeStory objectForKey : @ "original_text" ] ;
}
2012-11-06 12:45:19 -08:00
NSUserDefaults * userPreferences = [ NSUserDefaults standardUserDefaults ] ;
2015-11-02 22:17:06 -08:00
2015-11-03 12:10:28 -08:00
fontStyleClass = [ userPreferences stringForKey : @ "fontStyle" ] ;
if ( ! fontStyleClass ) {
fontStyleClass = @ "NB-helvetica" ;
2012-11-06 12:45:19 -08:00
}
2015-11-03 12:10:28 -08:00
2013-11-23 13:03:14 -08:00
fontSizeClass = [ fontSizeClass stringByAppendingString : [ userPreferences stringForKey : @ "story_font_size" ] ] ;
2012-11-06 12:45:19 -08:00
2015-11-03 12:10:28 -08:00
if ( ! [ fontStyleClass hasPrefix : @ "NB-" ] ) {
customStyle = [ NSString stringWithFormat : @ " style='font-family: %@;'" , fontStyleClass ] ;
2015-11-02 22:17:06 -08:00
}
2014-05-15 18:06:56 -07:00
if ( [ userPreferences stringForKey : @ "story_line_spacing" ] ) {
lineSpacingClass = [ lineSpacingClass stringByAppendingString : [ userPreferences stringForKey : @ "story_line_spacing" ] ] ;
} else {
lineSpacingClass = [ lineSpacingClass stringByAppendingString : @ "medium" ] ;
}
2015-09-28 20:01:17 -07:00
int contentWidth = CGRectGetWidth ( self . webView . scrollView . bounds ) ;
2012-11-06 12:45:19 -08:00
NSString * contentWidthClass ;
2015-12-01 16:51:18 -08:00
// NSLog ( @ "Drawing story: %@ / %d" , [ self . activeStory objectForKey : @ "story_title" ] , contentWidth ) ;
2012-11-06 12:45:19 -08:00
2015-11-28 22:07:38 -08:00
if ( UIInterfaceOrientationIsLandscape ( orientation ) && ! self . isPhoneOrCompact ) {
2016-04-06 18:14:06 -07:00
if ( iPadPro ) {
contentWidthClass = @ "NB-ipad-wide NB-ipad-pro-wide" ;
} else {
contentWidthClass = @ "NB-ipad-wide" ;
}
2015-11-28 22:07:38 -08:00
} else if ( ! UIInterfaceOrientationIsLandscape ( orientation ) && ! self . isPhoneOrCompact ) {
2016-04-06 18:14:06 -07:00
if ( iPadPro ) {
contentWidthClass = @ "NB-ipad-narrow NB-ipad-pro-narrow" ;
} else {
contentWidthClass = @ "NB-ipad-narrow" ;
}
2015-11-28 22:07:38 -08:00
} else if ( UIInterfaceOrientationIsLandscape ( orientation ) && self . isPhoneOrCompact ) {
2014-09-19 17:25:57 -07:00
contentWidthClass = @ "NB-iphone-wide" ;
2012-11-06 12:45:19 -08:00
} else {
contentWidthClass = @ "NB-iphone" ;
}
2014-09-24 12:00:47 -07:00
contentWidthClass = [ NSString stringWithFormat : @ "%@ NB-width-%d" ,
contentWidthClass , ( int ) floorf ( CGRectGetWidth ( self . view . frame ) ) ] ;
2013-06-26 16:22:44 -07:00
// Replace image urls that are locally cached , even when online
2014-09-26 17:38:35 -07:00
// NSString * storyHash = [ self . activeStory objectForKey : @ "story_hash" ] ;
2016-02-01 10:44:59 -08:00
// NSArray * imageUrls = [ appDelegate . activeCachedImages objectForKey : storyHash ] ;
2014-09-26 17:38:35 -07:00
// if ( imageUrls ) {
// NSArray * paths = NSSearchPathForDirectoriesInDomains ( NSCachesDirectory , NSUserDomainMask , YES ) ;
// NSString * storyImagesDirectory = [ [ paths objectAtIndex : 0 ]
// stringByAppendingPathComponent : @ "story_images" ] ;
// for ( NSString * imageUrl in imageUrls ) {
// NSString * cachedImage = [ storyImagesDirectory
// stringByAppendingPathComponent : [ Utilities md5 : imageUrl ] ] ;
// storyContent = [ storyContent
// stringByReplacingOccurrencesOfString : imageUrl
// withString : cachedImage ] ;
// }
// }
2013-06-23 22:19:08 -07:00
2016-02-01 10:44:59 -08:00
NSString * riverClass = ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) ?
2013-03-06 14:29:40 -08:00
@ "NB-river" : @ "NB-non-river" ;
2015-12-07 16:09:49 -08:00
NSString * themeStyle = [ ThemeManager themeManager ] . themeCSSSuffix ;
if ( themeStyle . length ) {
themeStyle = [ NSString stringWithFormat : @ "<link rel=\" stylesheet \ " type=\" text / css \ " href=\" storyDetailView % @ . css \ ">" , themeStyle ] ;
}
2012-11-06 12:45:19 -08:00
// set up layout values based on iPad / iPhone
headerString = [ NSString stringWithFormat : @
2015-12-07 16:09:49 -08:00
"<link rel=\" stylesheet \ " type=\" text / css \ " href=\" storyDetailView . css \ ">%@"
2015-09-22 13:10:35 -07:00
"<meta name=\" viewport \ " id=\" viewport \ " content=\" width = % d , initial - scale = 1.0 , minimum - scale = 1.0 , maximum - scale = 1.0 , user - scalable = no \ "/>" ,
2015-12-07 16:09:49 -08:00
themeStyle , contentWidth ] ;
2012-11-06 12:45:19 -08:00
footerString = [ NSString stringWithFormat : @
"<script src=\" zepto . js \ "></script>"
2014-01-06 15:02:12 -08:00
"<script src=\" fitvid . js \ "></script>"
2012-12-25 19:03:50 -08:00
"<script src=\" storyDetailView . js \ "></script>"
"<script src=\" fastTouch . js \ "></script>" ] ;
2012-11-06 12:45:19 -08:00
2014-05-21 12:24:22 -07:00
sharingHtmlString = [ self getSideoptions ] ;
2012-12-07 17:18:31 -08:00
NSString * storyHeader = [ self getHeader ] ;
2016-02-05 12:19:48 -08:00
NSString * htmlTop = [ NSString stringWithFormat : @
2016-01-21 14:01:25 -08:00
"<!DOCTYPE html>\n"
2012-11-06 12:45:19 -08:00
"<html>"
"<head>%@</head>" // header string
2013-03-06 14:29:40 -08:00
"<body id=\" story_pane \ " class=\" % @ % @ \ ">"
2015-11-02 22:17:06 -08:00
" <div class=\" % @ \ " id=\" NB - font - style \ "%@>"
2014-05-15 18:06:56 -07:00
" <div class=\" % @ \ " id=\" NB - font - size \ ">"
" <div class=\" % @ \ " id=\" NB - line - spacing \ ">"
" <div id=\" NB - header - container \ ">%@</div>" // storyHeader
2016-02-05 12:19:48 -08:00
" %@" , // shareBar
2012-11-06 12:45:19 -08:00
headerString ,
contentWidthClass ,
2013-03-06 14:29:40 -08:00
riverClass ,
2012-11-06 12:45:19 -08:00
fontStyleClass ,
2015-11-02 22:17:06 -08:00
customStyle ,
2012-11-06 12:45:19 -08:00
fontSizeClass ,
2014-05-15 18:06:56 -07:00
lineSpacingClass ,
2012-12-11 17:53:17 -08:00
storyHeader ,
2016-02-05 12:19:48 -08:00
shareBarString
] ;
NSString * htmlBottom = [ NSString stringWithFormat : @
" </div>" // line - spacing
" </div>" // font - size
" </div>" // font - style
"</body>"
"</html>"
2012-11-06 12:45:19 -08:00
] ;
2016-02-05 12:19:48 -08:00
NSString * htmlContent = [ NSString stringWithFormat : @
"%@" // header
" <div id=\" NB - story \ " class=\" NB - story \ ">%@</div>"
" <div id=\" NB - sideoptions - container \ ">%@</div>"
" <div id=\" NB - comments - wrapper \ ">"
" %@" // friends comments
" </div>"
" %@"
"%@" , // footer
htmlTop ,
storyContent ,
sharingHtmlString ,
commentString ,
footerString ,
htmlBottom
] ;
2016-08-23 20:52:34 -04:00
NSString * htmlTopAndBottom = [ htmlTop stringByAppendingString : htmlBottom ] ;
2016-02-05 12:19:48 -08:00
2016-02-27 13:20:32 -08:00
// NSLog ( @ "\n\n\n\nStory html (%@):\n\n\n%@\n\n\n" , self . activeStory [ @ "story_title" ] , htmlContent ) ;
2016-08-23 20:52:34 -04:00
self . hasStory = NO ;
self . fullStoryHTML = htmlContent ;
2016-02-05 12:19:48 -08:00
2015-10-02 16:04:49 -07:00
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
2015-12-01 16:51:18 -08:00
// NSLog ( @ "Drawing Story: %@" , [ self . activeStory objectForKey : @ "story_title" ] ) ;
2016-02-01 10:44:59 -08:00
[ self . webView setMediaPlaybackRequiresUserAction : NO ] ;
2016-08-23 20:52:34 -04:00
[ self loadHTMLString : htmlTopAndBottom ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl setTextButton : self ] ;
2015-10-02 16:04:49 -07:00
} ) ;
2015-03-10 18:58:23 -07:00
2014-12-01 17:22:40 -08:00
self . activeStoryId = [ self . activeStory objectForKey : @ "story_hash" ] ;
2015-09-16 21:34:41 -07:00
}
2014-12-01 17:22:40 -08:00
- ( void ) drawFeedGradient {
2012-11-06 12:45:19 -08:00
NSString * feedIdStr = [ NSString stringWithFormat : @ "%@" ,
[ self . activeStory
objectForKey : @ "story_feed_id" ] ] ;
2016-02-01 10:44:59 -08:00
NSDictionary * feed = [ appDelegate getFeed : feedIdStr ] ;
2012-11-06 12:45:19 -08:00
2015-09-28 20:01:17 -07:00
if ( self . feedTitleGradient ) {
[ self . feedTitleGradient removeFromSuperview ] ;
self . feedTitleGradient = nil ;
}
2016-02-01 10:44:59 -08:00
self . feedTitleGradient = [ appDelegate
2012-12-07 17:18:31 -08:00
makeFeedTitleGradient : feed
2015-09-22 18:20:48 -07:00
withRect : CGRectMake ( 0 , -1 , CGRectGetWidth ( self . view . bounds ) , 21 ) ] ; // 1024 hack for self . webView . frame . size . width
self . feedTitleGradient . autoresizingMask = UIViewAutoresizingFlexibleWidth ;
2012-11-06 12:45:19 -08:00
self . feedTitleGradient . tag = FEED_TITLE _GRADIENT _TAG ; // Not attached yet . Remove old gradients , first .
for ( UIView * subview in self . webView . subviews ) {
if ( subview . tag = = FEED_TITLE _GRADIENT _TAG ) {
[ subview removeFromSuperview ] ;
}
}
2016-02-01 10:44:59 -08:00
if ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) {
2012-11-06 12:45:19 -08:00
self . webView . scrollView . scrollIndicatorInsets = UIEdgeInsetsMake ( 20 , 0 , 0 , 0 ) ;
} else {
self . webView . scrollView . scrollIndicatorInsets = UIEdgeInsetsMake ( 9 , 0 , 0 , 0 ) ;
}
2016-02-01 10:44:59 -08:00
[ self . webView insertSubview : feedTitleGradient aboveSubview : self . webView . scrollView ] ;
2012-11-06 12:45:19 -08:00
}
2012-11-08 17:39:32 -08:00
- ( void ) showStory {
2014-02-12 20:41:29 -08:00
id storyId = [ self . activeStory objectForKey : @ "story_hash" ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storiesCollection pushReadStory : storyId ] ;
[ appDelegate resetShareComments ] ;
2012-11-08 17:39:32 -08:00
}
- ( void ) clearStory {
2012-11-14 17:31:52 -08:00
self . activeStoryId = nil ;
2015-10-06 18:52:58 -07:00
if ( self . activeStory ) self . activeStoryId = [ self . activeStory objectForKey : @ "story_hash" ] ;
2015-12-10 15:07:23 -08:00
[ self clearWebView ] ;
2013-10-17 11:21:37 -07:00
[ MBProgressHUD hideHUDForView : self . webView animated : NO ] ;
2012-11-08 17:39:32 -08:00
}
- ( void ) hideStory {
2012-11-14 17:31:52 -08:00
self . activeStoryId = nil ;
2012-11-08 17:39:32 -08:00
self . webView . hidden = YES ;
2013-09-26 19:26:10 -07:00
self . noStoryMessage . hidden = NO ;
2012-11-08 17:39:32 -08:00
}
# pragma mark -
# pragma mark Story layout
2015-12-10 15:07:23 -08:00
- ( void ) clearWebView {
2015-12-12 15:42:39 -08:00
self . hasStory = NO ;
2016-01-07 21:12:58 -08:00
self . view . backgroundColor = UIColorFromRGB ( NEWSBLUR_WHITE _COLOR ) ;
self . webView . hidden = YES ;
self . activityIndicator . color = UIColorFromRGB ( NEWSBLUR_BLACK _COLOR ) ;
[ self . activityIndicator startAnimating ] ;
2015-12-10 15:07:23 -08:00
NSString * themeStyle = [ ThemeManager themeManager ] . themeCSSSuffix ;
if ( themeStyle . length ) {
themeStyle = [ NSString stringWithFormat : @ "<link rel=\" stylesheet \ " type=\" text / css \ " href=\" storyDetailView % @ . css \ ">" , themeStyle ] ;
}
NSString * html = [ NSString stringWithFormat : @ "<html>"
"<head><link rel=\" stylesheet \ " type=\" text / css \ " href=\" storyDetailView . css \ ">%@</head>" // header string
"<body></body>"
"</html>" , themeStyle ] ;
2016-08-23 20:52:34 -04:00
[ self loadHTMLString : html ] ;
2015-12-10 15:07:23 -08:00
}
2012-12-07 17:18:31 -08:00
- ( NSString * ) getHeader {
2012-12-19 15:37:36 -08:00
NSString * feedId = [ NSString stringWithFormat : @ "%@" , [ self . activeStory
2012-12-11 11:50:06 -08:00
objectForKey : @ "story_feed_id" ] ] ;
NSString * storyAuthor = @ "" ;
if ( [ [ self . activeStory objectForKey : @ "story_authors" ] class ] ! = [ NSNull class ] &&
[ [ self . activeStory objectForKey : @ "story_authors" ] length ] ) {
2012-12-07 17:18:31 -08:00
NSString * author = [ NSString stringWithFormat : @ "%@" ,
2016-03-07 22:46:34 -08:00
[ [ [ [ self . activeStory objectForKey : @ "story_authors" ] stringByReplacingOccurrencesOfString : @ "\" " withString:@" " ]
stringByReplacingOccurrencesOfString : @ "<" withString : @ "<" ]
stringByReplacingOccurrencesOfString : @ ">" withString : @ ">" ] ] ;
if ( author && author . length ) {
2016-02-01 10:44:59 -08:00
int authorScore = [ [ [ [ appDelegate . storiesCollection . activeClassifiers objectForKey : feedId ]
2012-12-11 11:50:06 -08:00
objectForKey : @ "authors" ]
objectForKey : author ] intValue ] ;
2013-03-05 10:39:15 -08:00
storyAuthor = [ NSString stringWithFormat : @ "<span class=\" NB - middot \ ">·</span><a href=\" http : // ios . newsblur . com / classify - author / % @ \ " "
2012-12-11 11:50:06 -08:00
"class=\" NB - story - author % @ \ " id=\" NB - story - author \ "><div class=\" NB - highlight \ "></div>%@</a>" ,
author ,
authorScore > 0 ? @ "NB-story-author-positive" : authorScore < 0 ? @ "NB-story-author-negative" : @ "" ,
author ] ;
2012-12-07 17:18:31 -08:00
}
}
2012-12-11 11:50:06 -08:00
NSString * storyTags = @ "" ;
2012-12-07 17:18:31 -08:00
if ( [ self . activeStory objectForKey : @ "story_tags" ] ) {
2012-12-11 11:50:06 -08:00
NSArray * tagArray = [ self . activeStory objectForKey : @ "story_tags" ] ;
if ( [ tagArray count ] > 0 ) {
NSMutableArray * tagStrings = [ NSMutableArray array ] ;
for ( NSString * tag in tagArray ) {
2016-02-01 10:44:59 -08:00
int tagScore = [ [ [ [ appDelegate . storiesCollection . activeClassifiers objectForKey : feedId ]
2012-12-11 11:50:06 -08:00
objectForKey : @ "tags" ]
objectForKey : tag ] intValue ] ;
NSString * tagHtml = [ NSString stringWithFormat : @ "<a href=\" http : // ios . newsblur . com / classify - tag / % @ \ " "
2013-08-05 17:29:42 -07:00
"class=\" NB - story - tag % @ \ "><div class=\" NB - highlight \ "></div>%@</a>" ,
tag ,
tagScore > 0 ? @ "NB-story-tag-positive" : tagScore < 0 ? @ "NB-story-tag-negative" : @ "" ,
tag ] ;
2012-12-11 11:50:06 -08:00
[ tagStrings addObject : tagHtml ] ;
2012-12-07 17:18:31 -08:00
}
2012-12-11 11:50:06 -08:00
storyTags = [ NSString
stringWithFormat : @ "<div id=\" NB - story - tags \ " class=\" NB - story - tags \ ">"
"%@"
"</div>" ,
[ tagStrings componentsJoinedByString : @ "" ] ] ;
2012-12-07 17:18:31 -08:00
}
}
2013-08-05 17:29:42 -07:00
NSString * storyStarred = @ "" ;
2014-11-04 17:13:53 -08:00
NSString * storyUserTags = @ "" ;
2014-11-10 18:25:31 -08:00
NSMutableArray * tagStrings = [ NSMutableArray array ] ;
2013-08-05 17:29:42 -07:00
if ( [ self . activeStory objectForKey : @ "starred" ] && [ self . activeStory objectForKey : @ "starred_date" ] ) {
2014-11-04 17:13:53 -08:00
storyStarred = [ NSString stringWithFormat : @ "<div class=\" NB - story - starred - date \ ">Saved on %@</div>" ,
2013-08-05 17:29:42 -07:00
[ self . activeStory objectForKey : @ "starred_date" ] ] ;
2014-11-04 17:13:53 -08:00
if ( [ self . activeStory objectForKey : @ "user_tags" ] ) {
NSArray * tagArray = [ self . activeStory objectForKey : @ "user_tags" ] ;
if ( [ tagArray count ] > 0 ) {
for ( NSString * tag in tagArray ) {
NSString * tagHtml = [ NSString stringWithFormat : @ "<a href=\" http : // ios . newsblur . com / remove - user - tag / % @ \ " "
"class=\" NB - user - tag \ "><div class=\" NB - highlight \ "></div>%@</a>" ,
tag ,
tag ] ;
[ tagStrings addObject : tagHtml ] ;
}
}
}
2014-11-10 18:25:31 -08:00
storyUserTags = [ NSString
stringWithFormat : @ "<div id=\" NB - user - tags \ " class=\" NB - user - tags \ ">"
"%@"
"<a class=\" NB - user - tag NB - add - user - tag \ " href=\" http : // ios . newsblur . com / add - user - tag / add - user - tag / \ "><div class=\" NB - highlight \ "></div>Add Tag</a>"
"</div>" ,
[ tagStrings componentsJoinedByString : @ "" ] ] ;
2013-08-05 17:29:42 -07:00
}
2012-12-07 17:18:31 -08:00
2013-10-04 12:37:51 -07:00
NSString * storyUnread = @ "" ;
2016-02-01 10:44:59 -08:00
if ( self . isRecentlyUnread && [ appDelegate . storiesCollection isStoryUnread : self . activeStory ] ) {
2013-10-04 12:37:51 -07:00
NSInteger score = [ NewsBlurAppDelegate computeStoryScore : [ self . activeStory objectForKey : @ "intelligence" ] ] ;
storyUnread = [ NSString stringWithFormat : @ "<div class=\" NB - story - unread NB - % @ \ "></div>" ,
score > 0 ? @ "positive" : score < 0 ? @ "negative" : @ "neutral" ] ;
}
2012-12-11 11:50:06 -08:00
NSString * storyTitle = [ self . activeStory objectForKey : @ "story_title" ] ;
2013-11-23 13:25:26 -08:00
NSString * storyPermalink = [ self . activeStory objectForKey : @ "story_permalink" ] ;
2016-02-01 10:44:59 -08:00
NSMutableDictionary * titleClassifiers = [ [ appDelegate . storiesCollection . activeClassifiers
2014-02-12 20:09:37 -08:00
objectForKey : feedId ]
objectForKey : @ "titles" ] ;
2012-12-11 11:50:06 -08:00
for ( NSString * titleClassifier in titleClassifiers ) {
if ( [ storyTitle containsString : titleClassifier ] ) {
int titleScore = [ [ titleClassifiers objectForKey : titleClassifier ] intValue ] ;
storyTitle = [ storyTitle
stringByReplacingOccurrencesOfString : titleClassifier
withString : [ NSString stringWithFormat : @ "<span class=\" NB - story - title - % @ \ ">%@</span>" ,
titleScore > 0 ? @ "positive" : titleScore < 0 ? @ "negative" : @ "" ,
titleClassifier ] ] ;
2012-12-07 17:18:31 -08:00
}
}
2013-10-10 12:58:40 -07:00
NSString * storyDate = [ Utilities formatLongDateFromTimestamp : [ [ self . activeStory
objectForKey : @ "story_timestamp" ]
integerValue ] ] ;
2012-12-07 17:18:31 -08:00
NSString * storyHeader = [ NSString stringWithFormat : @
"<div class=\" NB - header \ "><div class=\" NB - header - inner \ ">"
2013-10-04 12:37:51 -07:00
"<div class=\" NB - story - title \ ">"
" %@"
2013-11-23 13:25:26 -08:00
" <a href=\" % @ \ " class=\" NB - story - permalink \ ">%@</a>"
2013-10-04 12:37:51 -07:00
"</div>"
2013-03-05 10:39:15 -08:00
"<div class=\" NB - story - date \ ">%@</div>"
2012-12-07 17:18:31 -08:00
"%@"
"%@"
2013-08-05 17:29:42 -07:00
"%@"
2014-11-04 17:13:53 -08:00
"%@"
2012-12-07 17:18:31 -08:00
"</div></div>" ,
2013-10-04 12:37:51 -07:00
storyUnread ,
2013-11-23 13:25:26 -08:00
storyPermalink ,
2012-12-11 11:50:06 -08:00
storyTitle ,
2013-10-10 12:58:40 -07:00
storyDate ,
2012-12-11 11:50:06 -08:00
storyAuthor ,
2013-08-05 17:29:42 -07:00
storyTags ,
2014-11-04 17:13:53 -08:00
storyStarred ,
storyUserTags ] ;
2012-12-07 17:18:31 -08:00
return storyHeader ;
}
2014-05-21 12:24:22 -07:00
- ( NSString * ) getSideoptions {
BOOL isSaved = [ [ self . activeStory objectForKey : @ "starred" ] boolValue ] ;
BOOL isShared = [ [ self . activeStory objectForKey : @ "shared" ] boolValue ] ;
NSString * sideoptions = [ NSString stringWithFormat : @
"<div class='NB-sideoptions'>"
"<div class='NB-share-header'></div>"
"<div class='NB-share-wrapper'><div class='NB-share-inner-wrapper'>"
" <div id=\" NB - share - button - id \ " class='NB-share-button NB-train-button NB-button'>"
" <a href=\" http : // ios . newsblur . com / train \ "><div>"
" <span class=\" NB - icon \ "></span> Train"
" </div></a>"
" </div>"
" <div id=\" NB - share - button - id \ " class='NB-share-button NB-button %@'>"
" <a href=\" http : // ios . newsblur . com / share \ "><div>"
" <span class=\" NB - icon \ "></span> %@"
" </div></a>"
" </div>"
" <div id=\" NB - share - button - id \ " class='NB-share-button NB-save-button NB-button %@'>"
2014-12-16 15:36:58 -08:00
" <a href=\" http : // ios . newsblur . com / save / save / \ "><div>"
2014-05-21 12:24:22 -07:00
" <span class=\" NB - icon \ "></span> %@"
" </div></a>"
" </div>"
"</div></div></div>" ,
isShared ? @ "NB-button-active" : @ "" ,
isShared ? @ "Shared" : @ "Share" ,
isSaved ? @ "NB-button-active" : @ "" ,
isSaved ? @ "Saved" : @ "Save"
] ;
return sideoptions ;
}
2012-08-10 09:45:44 -07:00
- ( NSString * ) getAvatars : ( NSString * ) key {
2012-06-24 18:17:22 -07:00
NSString * avatarString = @ "" ;
2012-12-11 11:50:06 -08:00
NSArray * shareUserIds = [ self . activeStory objectForKey : key ] ;
2012-06-24 18:17:22 -07:00
2012-12-11 11:50:06 -08:00
for ( int i = 0 ; i < shareUserIds . count ; i + + ) {
2016-02-01 10:44:59 -08:00
NSDictionary * user = [ appDelegate getUser : [ [ shareUserIds objectAtIndex : i ] intValue ] ] ;
2012-08-13 15:34:53 -07:00
NSString * avatarClass = @ "NB-user-avatar" ;
if ( [ key isEqualToString : @ "commented_by_public" ] ||
[ key isEqualToString : @ "shared_by_public" ] ) {
avatarClass = @ "NB-public-user NB-user-avatar" ;
}
2012-06-24 18:17:22 -07:00
NSString * avatar = [ NSString stringWithFormat : @
2012-08-13 15:34:53 -07:00
"<div class=\" NB - story - share - profile \ "><div class=\" % @ \ ">"
2012-12-07 17:18:31 -08:00
"<a id=\" NB - user - share - bar - % @ \ " class=\" NB - show - profile \ " "
2012-12-11 11:50:06 -08:00
" href=\" http : // ios . newsblur . com / show - profile / % @ \ ">"
"<div class=\" NB - highlight \ "></div>"
"<img src=\" % @ \ " />"
"</a>"
2012-06-24 18:17:22 -07:00
"</div></div>" ,
2012-08-13 15:34:53 -07:00
avatarClass ,
2012-07-01 21:58:55 -07:00
[ user objectForKey : @ "user_id" ] ,
2012-08-01 12:41:02 -07:00
[ user objectForKey : @ "user_id" ] ,
2012-07-11 10:33:39 -07:00
[ user objectForKey : @ "photo_url" ] ] ;
2012-06-24 18:17:22 -07:00
avatarString = [ avatarString stringByAppendingString : avatar ] ;
}
2012-08-10 09:45:44 -07:00
2012-06-24 18:17:22 -07:00
return avatarString ;
}
2012-08-07 11:27:00 -07:00
- ( NSString * ) getComments {
2015-09-16 20:24:11 -07:00
NSString * comments = @ "" ;
2012-07-27 12:27:13 -07:00
2015-09-16 20:24:11 -07:00
if ( [ self . activeStory objectForKey : @ "share_count" ] ! = [ NSNull null ] &&
[ [ self . activeStory objectForKey : @ "share_count" ] intValue ] > 0 ) {
2012-11-05 17:16:10 -08:00
NSDictionary * story = self . activeStory ;
2012-07-20 00:21:24 -07:00
NSArray * friendsCommentsArray = [ story objectForKey : @ "friend_comments" ] ;
2015-09-07 21:39:51 -07:00
NSArray * friendsShareArray = [ story objectForKey : @ "friend_shares" ] ;
NSArray * publicCommentsArray = [ story objectForKey : @ "public_comments" ] ;
2013-03-05 12:26:37 -08:00
2013-03-05 17:00:03 -08:00
if ( [ [ story objectForKey : @ "comment_count_friends" ] intValue ] > 0 ) {
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingString : @ "<div class=\" NB - story - comments - group NB - story - comment - friend - comments \ ">" ] ;
2013-03-05 17:00:03 -08:00
NSString * commentHeader = [ NSString stringWithFormat : @
"<div class=\" NB - story - comments - friends - header - wrapper \ ">"
" <div class=\" NB - story - comments - friends - header \ ">%i comment%@</div>"
"</div>" ,
[ [ story objectForKey : @ "comment_count_friends" ] intValue ] ,
[ [ story objectForKey : @ "comment_count_friends" ] intValue ] = = 1 ? @ "" : @ "s" ] ;
comments = [ comments stringByAppendingString : commentHeader ] ;
// add friends comments
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingFormat : @ "<div class=\" NB - feed - story - comments \ ">" ] ;
2013-03-05 17:00:03 -08:00
for ( int i = 0 ; i < friendsCommentsArray . count ; i + + ) {
NSString * comment = [ self getComment : [ friendsCommentsArray objectAtIndex : i ] ] ;
comments = [ comments stringByAppendingString : comment ] ;
}
2015-09-08 14:17:01 -07:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2015-09-07 19:56:44 -07:00
}
2015-09-07 21:39:51 -07:00
NSInteger sharedByFriendsCount = [ [ story objectForKey : @ "shared_by_friends" ] count ] ;
if ( sharedByFriendsCount > 0 ) {
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingString : @ "<div class=\" NB - story - comments - group NB - story - comment - friend - shares \ ">" ] ;
2015-09-07 19:56:44 -07:00
NSString * commentHeader = [ NSString stringWithFormat : @
2015-09-07 21:39:51 -07:00
"<div class=\" NB - story - comments - friend - shares - header - wrapper \ ">"
" <div class=\" NB - story - comments - friends - header \ ">%ld share%@</div>"
2015-09-07 19:56:44 -07:00
"</div>" ,
2015-09-07 21:39:51 -07:00
( long ) sharedByFriendsCount ,
sharedByFriendsCount = = 1 ? @ "" : @ "s" ] ;
2015-09-07 19:56:44 -07:00
comments = [ comments stringByAppendingString : commentHeader ] ;
2015-09-16 20:24:11 -07:00
// add friend shares
comments = [ comments stringByAppendingFormat : @ "<div class=\" NB - feed - story - comments \ ">" ] ;
2015-09-07 21:39:51 -07:00
for ( int i = 0 ; i < friendsShareArray . count ; i + + ) {
NSString * comment = [ self getComment : [ friendsShareArray objectAtIndex : i ] ] ;
2015-09-07 19:56:44 -07:00
comments = [ comments stringByAppendingString : comment ] ;
}
2015-09-08 14:17:01 -07:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2015-09-07 19:56:44 -07:00
}
2012-08-07 11:27:00 -07:00
2013-07-19 17:53:52 -07:00
if ( [ [ [ NSUserDefaults standardUserDefaults ] objectForKey : @ "show_public_comments" ] boolValue ] &&
[ [ story objectForKey : @ "comment_count_public" ] intValue ] > 0 ) {
2015-09-16 20:24:11 -07:00
comments = [ comments stringByAppendingString : @ "<div class=\" NB - story - comments - group NB - story - comment - public - comments \ ">" ] ;
2012-08-07 11:27:00 -07:00
NSString * publicCommentHeader = [ NSString stringWithFormat : @
"<div class=\" NB - story - comments - public - header - wrapper \ ">"
2013-03-05 12:26:37 -08:00
" <div class=\" NB - story - comments - public - header \ ">%i public comment%@</div>"
2012-08-07 11:27:00 -07:00
"</div>" ,
[ [ story objectForKey : @ "comment_count_public" ] intValue ] ,
[ [ story objectForKey : @ "comment_count_public" ] intValue ] = = 1 ? @ "" : @ "s" ] ;
comments = [ comments stringByAppendingString : publicCommentHeader ] ;
2013-03-05 12:26:37 -08:00
comments = [ comments stringByAppendingFormat : @ "<div class=\" NB - feed - story - comments \ ">" ] ;
2013-03-05 17:00:03 -08:00
2013-03-05 12:26:37 -08:00
// add public comments
2012-08-07 11:27:00 -07:00
for ( int i = 0 ; i < publicCommentsArray . count ; i + + ) {
NSString * comment = [ self getComment : [ publicCommentsArray objectAtIndex : i ] ] ;
comments = [ comments stringByAppendingString : comment ] ;
}
2015-09-08 14:17:01 -07:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2016-02-06 14:40:07 -08:00
comments = [ comments stringByAppendingString : @ "</div>" ] ;
2012-08-07 11:27:00 -07:00
}
}
return comments ;
}
- ( NSString * ) getShareBar {
2012-08-13 15:34:53 -07:00
NSString * comments = @ "<div id=\" NB - share - bar - wrapper \ ">" ;
2012-08-10 09:45:44 -07:00
NSString * commentLabel = @ "" ;
NSString * shareLabel = @ "" ;
2012-08-13 15:34:53 -07:00
// NSString * replyStr = @ "" ;
2012-08-10 09:45:44 -07:00
2012-11-05 17:16:10 -08:00
// if ( [ [ self . activeStory objectForKey : @ "reply_count" ] intValue ] = = 1 ) {
2012-08-13 15:34:53 -07:00
// replyStr = [ NSString stringWithFormat : @ " and <b>1 reply</b>" ] ;
2012-11-05 17:16:10 -08:00
// } else if ( [ [ self . activeStory objectForKey : @ "reply_count" ] intValue ] = = 1 ) {
// replyStr = [ NSString stringWithFormat : @ " and <b>%@ replies</b>" , [ self . activeStory objectForKey : @ "reply_count" ] ] ;
2012-08-13 15:34:53 -07:00
// }
2012-11-05 17:16:10 -08:00
if ( ! [ [ self . activeStory objectForKey : @ "comment_count" ] isKindOfClass : [ NSNull class ] ] &&
[ [ self . activeStory objectForKey : @ "comment_count" ] intValue ] ) {
2012-08-10 09:45:44 -07:00
commentLabel = [ commentLabel stringByAppendingString : [ NSString stringWithFormat : @
"<div class=\" NB - story - comments - label \ ">"
2012-12-11 17:53:17 -08:00
"%@" // comment count
// "%@" // reply count
2012-08-10 09:45:44 -07:00
"</div>"
"<div class=\" NB - story - share - profiles NB - story - share - profiles - comments \ ">"
2012-12-11 17:53:17 -08:00
"%@" // friend avatars
"%@" // public avatars
2012-08-10 09:45:44 -07:00
"</div>" ,
2012-11-05 17:16:10 -08:00
[ [ self . activeStory objectForKey : @ "comment_count" ] intValue ] = = 1
2014-09-17 16:41:48 -07:00
? [ NSString stringWithFormat : @ "<b>1 comment</b>" ] :
2012-11-05 17:16:10 -08:00
[ NSString stringWithFormat : @ "<b>%@ comments</b>" , [ self . activeStory objectForKey : @ "comment_count" ] ] ,
2012-08-10 09:45:44 -07:00
2012-08-13 15:34:53 -07:00
// replyStr ,
2012-08-10 09:45:44 -07:00
[ self getAvatars : @ "commented_by_friends" ] ,
[ self getAvatars : @ "commented_by_public" ] ] ] ;
}
2012-11-05 17:16:10 -08:00
if ( ! [ [ self . activeStory objectForKey : @ "share_count" ] isKindOfClass : [ NSNull class ] ] &&
[ [ self . activeStory objectForKey : @ "share_count" ] intValue ] ) {
2012-08-10 09:45:44 -07:00
shareLabel = [ shareLabel stringByAppendingString : [ NSString stringWithFormat : @
2012-08-13 15:34:53 -07:00
"<div class=\" NB - right \ ">"
"<div class=\" NB - story - share - profiles NB - story - share - profiles - shares \ ">"
2012-08-10 09:45:44 -07:00
"%@" // friend avatars
"%@" // public avatars
2012-08-13 15:34:53 -07:00
"</div>"
2012-12-11 17:53:17 -08:00
"<div class=\" NB - story - share - label \ ">"
"%@" // comment count
"</div>"
2012-08-13 15:34:53 -07:00
"</div>" ,
[ self getAvatars : @ "shared_by_public" ] ,
[ self getAvatars : @ "shared_by_friends" ] ,
2012-11-05 17:16:10 -08:00
[ [ self . activeStory objectForKey : @ "share_count" ] intValue ] = = 1
2012-08-10 09:45:44 -07:00
? [ NSString stringWithFormat : @ "<b>1 share</b>" ] :
2012-11-05 17:16:10 -08:00
[ NSString stringWithFormat : @ "<b>%@ shares</b>" , [ self . activeStory objectForKey : @ "share_count" ] ] ] ] ;
2012-08-10 09:45:44 -07:00
}
2012-08-07 11:27:00 -07:00
2012-11-05 17:16:10 -08:00
if ( [ self . activeStory objectForKey : @ "share_count" ] ! = [ NSNull null ] &&
[ [ self . activeStory objectForKey : @ "share_count" ] intValue ] > 0 ) {
2012-08-02 18:33:55 -07:00
2012-08-09 17:01:37 -07:00
comments = [ comments stringByAppendingString : [ NSString stringWithFormat : @
"<div class=\" NB - story - shares \ ">"
2012-12-11 17:53:17 -08:00
"<div class=\" NB - story - comments - shares - teaser - wrapper \ ">"
"<div class=\" NB - story - comments - shares - teaser \ ">"
"%@"
"%@"
"</div>"
"</div>"
"</div>" ,
2012-08-10 09:45:44 -07:00
commentLabel ,
shareLabel
2012-08-09 17:01:37 -07:00
] ] ;
2012-06-22 15:53:51 -07:00
}
2012-08-13 15:34:53 -07:00
comments = [ comments stringByAppendingString : [ NSString stringWithFormat : @ "</div>" ] ] ;
2012-06-22 15:53:51 -07:00
return comments ;
}
2012-06-22 18:01:08 -07:00
2012-06-25 20:28:07 -07:00
- ( NSString * ) getComment : ( NSDictionary * ) commentDict {
2016-02-01 10:44:59 -08:00
NSDictionary * user = [ appDelegate getUser : [ [ commentDict objectForKey : @ "user_id" ] intValue ] ] ;
2012-07-03 17:54:36 -07:00
NSString * userAvatarClass = @ "NB-user-avatar" ;
NSString * userReshareString = @ "" ;
2012-07-20 00:21:24 -07:00
NSString * userEditButton = @ "" ;
2012-07-23 10:57:11 -07:00
NSString * userLikeButton = @ "" ;
2012-07-20 00:21:24 -07:00
NSString * commentUserId = [ NSString stringWithFormat : @ "%@" , [ commentDict objectForKey : @ "user_id" ] ] ;
2016-02-01 10:44:59 -08:00
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" , [ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
2012-12-13 14:24:47 -08:00
NSArray * likingUsersArray = [ commentDict objectForKey : @ "liking_users" ] ;
NSString * likingUsers = @ "" ;
2012-07-26 13:54:45 -07:00
2012-12-13 14:24:47 -08:00
if ( [ likingUsersArray count ] ) {
likingUsers = @ "<div class=\" NB - story - comment - likes - icon \ "></div>" ;
for ( NSNumber * likingUser in likingUsersArray ) {
2016-02-01 10:44:59 -08:00
NSDictionary * sourceUser = [ appDelegate getUser : [ likingUser intValue ] ] ;
2012-12-13 14:24:47 -08:00
NSString * likingUserString = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment - likes - user \ ">"
" <div class=\" NB - user - avatar \ "><img src=\" % @ \ "></div>"
"</div>" ,
[ sourceUser objectForKey : @ "photo_url" ] ] ;
likingUsers = [ likingUsers stringByAppendingString : likingUserString ] ;
}
}
2012-07-20 00:21:24 -07:00
if ( [ commentUserId isEqualToString : currentUserId ] ) {
userEditButton = [ NSString stringWithFormat : @
2012-07-23 10:57:11 -07:00
"<div class=\" NB - story - comment - edit - button NB - story - comment - share - edit - button NB - button \ ">"
2012-08-08 12:02:54 -07:00
"<a href=\" http : // ios . newsblur . com / edit - share / % @ \ "><div class=\" NB - story - comment - edit - button - wrapper \ ">"
"Edit"
"</div></a>"
2012-07-20 18:04:54 -07:00
"</div>" ,
commentUserId ] ;
2012-07-23 10:57:11 -07:00
} else {
2012-07-26 13:54:45 -07:00
BOOL isInLikingUsers = NO ;
2012-12-13 14:24:47 -08:00
for ( int i = 0 ; i < likingUsersArray . count ; i + + ) {
if ( [ [ [ likingUsersArray objectAtIndex : i ] stringValue ] isEqualToString : currentUserId ] ) {
2012-07-26 13:54:45 -07:00
isInLikingUsers = YES ;
break ;
}
}
if ( isInLikingUsers ) {
userLikeButton = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment - like - button NB - button selected \ ">"
2012-08-08 12:02:54 -07:00
"<a href=\" http : // ios . newsblur . com / unlike - comment / % @ \ "><div class=\" NB - story - comment - like - button - wrapper \ ">"
2012-12-11 17:53:17 -08:00
"<span class=\" NB - favorite - icon \ "></span>"
2012-08-08 12:02:54 -07:00
"</div></a>"
2012-07-26 13:54:45 -07:00
"</div>" ,
commentUserId ] ;
} else {
userLikeButton = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment - like - button NB - button \ ">"
2012-08-08 12:02:54 -07:00
"<a href=\" http : // ios . newsblur . com / like - comment / % @ \ "><div class=\" NB - story - comment - like - button - wrapper \ ">"
2012-12-11 17:53:17 -08:00
"<span class=\" NB - favorite - icon \ "></span>"
2012-08-08 12:02:54 -07:00
"</div></a>"
2012-07-26 13:54:45 -07:00
"</div>" ,
commentUserId ] ;
}
2012-07-20 00:21:24 -07:00
}
2012-07-03 17:54:36 -07:00
if ( [ commentDict objectForKey : @ "source_user_id" ] ! = [ NSNull null ] ) {
userAvatarClass = @ "NB-user-avatar NB-story-comment-reshare" ;
2016-02-01 10:44:59 -08:00
NSDictionary * sourceUser = [ appDelegate getUser : [ [ commentDict objectForKey : @ "source_user_id" ] intValue ] ] ;
2012-07-03 17:54:36 -07:00
userReshareString = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment - reshares \ ">"
" <div class=\" NB - story - share - profile \ ">"
" <div class=\" NB - user - avatar \ "><img src=\" % @ \ "></div>"
" </div>"
"</div>" ,
2012-07-11 10:33:39 -07:00
[ sourceUser objectForKey : @ "photo_url" ] ] ;
2012-07-03 17:54:36 -07:00
}
2012-07-23 16:17:49 -07:00
NSString * commentContent = [ self textToHtml : [ commentDict objectForKey : @ "comments" ] ] ;
2012-07-29 13:24:03 -07:00
NSString * comment ;
2012-08-09 16:34:59 -07:00
NSString * locationHtml = @ "" ;
NSString * location = [ NSString stringWithFormat : @ "%@" , [ user objectForKey : @ "location" ] ] ;
2013-09-05 16:34:39 -07:00
if ( location . length && ! [ [ user objectForKey : @ "location" ] isKindOfClass : [ NSNull class ] ] ) {
2012-08-09 16:34:59 -07:00
locationHtml = [ NSString stringWithFormat : @ "<div class=\" NB - story - comment - location \ ">%@</div>" , location ] ;
}
2012-07-29 13:24:03 -07:00
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2012-07-29 13:24:03 -07:00
comment = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment \ " id=\" NB - user - comment - % @ \ ">"
2012-12-11 11:50:06 -08:00
"<div class=\" % @ \ ">"
"<a class=\" NB - show - profile \ " href=\" http : // ios . newsblur . com / show - profile / % @ \ ">"
"<div class=\" NB - highlight \ "></div>"
"<img src=\" % @ \ " />"
"</a>"
"</div>"
2012-07-29 13:24:03 -07:00
"<div class=\" NB - story - comment - author - container \ ">"
" %@"
" <div class=\" NB - story - comment - username \ ">%@</div>"
" <div class=\" NB - story - comment - date \ ">%@ ago</div>"
2012-12-13 14:24:47 -08:00
" <div class=\" NB - story - comment - likes \ ">%@</div>"
2012-12-11 17:53:17 -08:00
"</div>"
"<div class=\" NB - story - comment - content \ ">%@</div>"
"%@" // location
"<div class=\" NB - button - wrapper \ ">"
2012-07-29 13:24:03 -07:00
" <div class=\" NB - story - comment - reply - button NB - button \ ">"
2012-08-08 12:02:54 -07:00
" <a href=\" http : // ios . newsblur . com / reply / % @ / % @ \ "><div class=\" NB - story - comment - reply - button - wrapper \ ">"
" Reply"
" </div></a>"
2012-07-29 13:24:03 -07:00
" </div>"
2012-12-11 17:53:17 -08:00
" %@" // User Like Button
" %@" // User Edit Button
2012-07-29 13:24:03 -07:00
"</div>"
"%@"
"</div>" ,
[ commentDict objectForKey : @ "user_id" ] ,
userAvatarClass ,
[ commentDict objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "photo_url" ] ,
userReshareString ,
[ user objectForKey : @ "username" ] ,
[ commentDict objectForKey : @ "shared_date" ] ,
2012-12-13 14:24:47 -08:00
likingUsers ,
2012-12-11 17:53:17 -08:00
commentContent ,
locationHtml ,
2012-08-13 15:34:53 -07:00
[ commentDict objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "username" ] ,
2012-12-11 17:53:17 -08:00
userEditButton ,
userLikeButton ,
[ self getReplies : [ commentDict objectForKey : @ "replies" ] forUserId : [ commentDict objectForKey : @ "user_id" ] ] ] ;
2012-07-29 13:24:03 -07:00
} else {
comment = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment \ " id=\" NB - user - comment - % @ \ ">"
2012-12-11 11:50:06 -08:00
"<div class=\" % @ \ ">"
"<a class=\" NB - show - profile \ " href=\" http : // ios . newsblur . com / show - profile / % @ \ ">"
"<div class=\" NB - highlight \ "></div>"
"<img src=\" % @ \ " />"
"</a>"
"</div>"
2012-07-29 13:24:03 -07:00
"<div class=\" NB - story - comment - author - container \ ">"
2012-12-11 17:53:17 -08:00
" %@"
2012-07-29 13:24:03 -07:00
" <div class=\" NB - story - comment - username \ ">%@</div>"
" <div class=\" NB - story - comment - date \ ">%@ ago</div>"
2012-12-13 16:41:52 -08:00
" <div class=\" NB - story - comment - likes \ ">%@</div>"
2012-07-29 13:24:03 -07:00
"</div>"
2012-08-13 16:20:23 -07:00
"<div class=\" NB - story - comment - content \ ">%@</div>"
2012-12-11 17:53:17 -08:00
"%@" // location
"<div class=\" NB - button - wrapper \ ">"
2012-07-29 13:24:03 -07:00
" <div class=\" NB - story - comment - reply - button NB - button \ ">"
2012-08-08 12:02:54 -07:00
" <a href=\" http : // ios . newsblur . com / reply / % @ / % @ \ "><div class=\" NB - story - comment - reply - button - wrapper \ ">"
" Reply"
" </div></a>"
2012-07-29 13:24:03 -07:00
" </div>"
2012-12-11 17:53:17 -08:00
" %@" // User Like Button
" %@" // User Edit Button
2012-07-29 13:24:03 -07:00
"</div>"
"%@"
"</div>" ,
[ commentDict objectForKey : @ "user_id" ] ,
userAvatarClass ,
[ commentDict objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "photo_url" ] ,
userReshareString ,
[ user objectForKey : @ "username" ] ,
[ commentDict objectForKey : @ "shared_date" ] ,
2012-12-13 16:41:52 -08:00
likingUsers ,
2012-08-02 00:57:01 -07:00
commentContent ,
2012-12-11 17:53:17 -08:00
locationHtml ,
2012-08-13 16:20:23 -07:00
[ commentDict objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "username" ] ,
2012-12-11 17:53:17 -08:00
userEditButton ,
userLikeButton ,
2012-07-29 13:24:03 -07:00
[ self getReplies : [ commentDict objectForKey : @ "replies" ] forUserId : [ commentDict objectForKey : @ "user_id" ] ] ] ;
2012-07-03 17:54:36 -07:00
2012-07-29 13:24:03 -07:00
}
2012-06-25 20:28:07 -07:00
return comment ;
}
2012-07-20 15:54:10 -07:00
- ( NSString * ) getReplies : ( NSArray * ) replies forUserId : ( NSString * ) commentUserId {
2012-06-22 18:01:08 -07:00
NSString * repliesString = @ "" ;
if ( replies . count > 0 ) {
repliesString = [ repliesString stringByAppendingString : @ "<div class=\" NB - story - comment - replies \ ">" ] ;
for ( int i = 0 ; i < replies . count ; i + + ) {
2012-07-20 15:54:10 -07:00
NSDictionary * replyDict = [ replies objectAtIndex : i ] ;
2016-02-01 10:44:59 -08:00
NSDictionary * user = [ appDelegate getUser : [ [ replyDict objectForKey : @ "user_id" ] intValue ] ] ;
2012-07-20 15:54:10 -07:00
NSString * userEditButton = @ "" ;
NSString * replyUserId = [ NSString stringWithFormat : @ "%@" , [ replyDict objectForKey : @ "user_id" ] ] ;
2012-07-30 14:58:57 -07:00
NSString * replyId = [ replyDict objectForKey : @ "reply_id" ] ;
2016-02-01 10:44:59 -08:00
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" , [ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
2012-07-20 15:54:10 -07:00
if ( [ replyUserId isEqualToString : currentUserId ] ) {
userEditButton = [ NSString stringWithFormat : @
2012-07-23 10:57:11 -07:00
"<div class=\" NB - story - comment - edit - button NB - story - comment - share - edit - button NB - button \ ">"
2012-08-08 12:02:54 -07:00
"<a href=\" http : // ios . newsblur . com / edit - reply / % @ / % @ / % @ \ ">"
2012-07-20 15:54:10 -07:00
"<div class=\" NB - story - comment - edit - button - wrapper \ ">"
2012-08-13 16:20:23 -07:00
"Edit"
2012-07-20 15:54:10 -07:00
"</div>"
2012-08-08 12:02:54 -07:00
"</a>"
2012-07-20 15:54:10 -07:00
"</div>" ,
commentUserId ,
replyUserId ,
2012-07-30 14:58:57 -07:00
replyId
2012-07-20 15:54:10 -07:00
] ;
}
2012-07-23 16:17:49 -07:00
NSString * replyContent = [ self textToHtml : [ replyDict objectForKey : @ "comments" ] ] ;
2012-08-09 16:45:52 -07:00
NSString * locationHtml = @ "" ;
NSString * location = [ NSString stringWithFormat : @ "%@" , [ user objectForKey : @ "location" ] ] ;
if ( location . length ) {
locationHtml = [ NSString stringWithFormat : @ "<div class=\" NB - story - comment - location \ ">%@</div>" , location ] ;
}
2012-07-21 18:25:56 -07:00
2012-08-13 15:34:53 -07:00
NSString * reply ;
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2012-08-13 15:34:53 -07:00
reply = [ NSString stringWithFormat : @
2012-12-11 17:53:17 -08:00
"<div class=\" NB - story - comment - reply \ " id=\" NB - user - comment - % @ \ ">"
" <a class=\" NB - show - profile \ " href=\" http : // ios . newsblur . com / show - profile / % @ \ ">"
" <div class=\" NB - highlight \ "></div>"
" <img class=\" NB - story - comment - reply - photo \ " src=\" % @ \ " />"
" </a>"
" <div class=\" NB - story - comment - username NB - story - comment - reply - username \ ">%@</div>"
" <div class=\" NB - story - comment - date NB - story - comment - reply - date \ ">%@ ago</div>"
" <div class=\" NB - story - comment - reply - content \ ">%@</div>"
" %@" // location
" <div class=\" NB - button - wrapper \ ">"
" %@" // edit
" </div>"
"</div>" ,
[ replyDict objectForKey : @ "reply_id" ] ,
[ user objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "photo_url" ] ,
[ user objectForKey : @ "username" ] ,
[ replyDict objectForKey : @ "publish_date" ] ,
replyContent ,
locationHtml ,
userEditButton ] ;
2012-08-13 15:34:53 -07:00
} else {
2012-08-13 16:20:23 -07:00
reply = [ NSString stringWithFormat : @
"<div class=\" NB - story - comment - reply \ " id=\" NB - user - comment - % @ \ ">"
" <a class=\" NB - show - profile \ " href=\" http : // ios . newsblur . com / show - profile / % @ \ ">"
2012-12-11 11:50:06 -08:00
" <div class=\" NB - highlight \ "></div>"
2012-08-13 16:20:23 -07:00
" <img class=\" NB - story - comment - reply - photo \ " src=\" % @ \ " />"
" </a>"
" <div class=\" NB - story - comment - username NB - story - comment - reply - username \ ">%@</div>"
" <div class=\" NB - story - comment - date NB - story - comment - reply - date \ ">%@ ago</div>"
" <div class=\" NB - story - comment - reply - content \ ">%@</div>"
2012-12-11 17:53:17 -08:00
" %@"
" <div class=\" NB - button - wrapper \ ">"
" %@" // edit
" </div>"
2012-08-13 16:20:23 -07:00
"</div>" ,
[ replyDict objectForKey : @ "reply_id" ] ,
[ user objectForKey : @ "user_id" ] ,
[ user objectForKey : @ "photo_url" ] ,
[ user objectForKey : @ "username" ] ,
[ replyDict objectForKey : @ "publish_date" ] ,
replyContent ,
2012-12-11 17:53:17 -08:00
locationHtml ,
2012-08-13 16:20:23 -07:00
userEditButton ] ;
2012-08-13 15:34:53 -07:00
}
2012-06-22 18:01:08 -07:00
repliesString = [ repliesString stringByAppendingString : reply ] ;
}
repliesString = [ repliesString stringByAppendingString : @ "</div>" ] ;
}
return repliesString ;
}
2016-08-10 13:26:52 -07:00
# pragma mark - Scrolling
2012-10-04 10:59:44 -07:00
- ( void ) observeValueForKeyPath : ( NSString * ) keyPath ofObject : ( id ) object change : ( NSDictionary * ) change context : ( void * ) context {
2016-02-01 10:44:59 -08:00
if ( [ keyPath isEqual : @ "contentOffset" ] ) {
2013-03-06 14:29:40 -08:00
if ( self . webView . scrollView . contentOffset . y < ( -1 * self . feedTitleGradient . frame . size . height + 1 + self . webView . scrollView . scrollIndicatorInsets . top ) ) {
2012-10-04 10:59:44 -07:00
// Pulling
2016-02-01 10:44:59 -08:00
if ( ! pullingScrollview ) {
pullingScrollview = YES ;
2012-10-04 10:59:44 -07:00
for ( id subview in self . webView . scrollView . subviews ) {
UIImageView * imgView = [ subview isKindOfClass : [ UIImageView class ] ] ?
( UIImageView * ) subview : nil ;
// image views whose image is 1 px wide are shadow images , hide them
2013-03-06 14:29:40 -08:00
if ( imgView && imgView . image . size . width > 1 ) {
[ self . webView . scrollView insertSubview : self . feedTitleGradient
belowSubview : subview ] ;
[ self . webView . scrollView bringSubviewToFront : subview ] ;
2012-10-04 10:59:44 -07:00
}
}
}
} else {
// Normal reading
2016-02-01 10:44:59 -08:00
if ( pullingScrollview ) {
pullingScrollview = NO ;
2012-10-04 10:59:44 -07:00
[ self . feedTitleGradient . layer setShadowOpacity : 0 ] ;
[ self . webView insertSubview : self . feedTitleGradient aboveSubview : self . webView . scrollView ] ;
self . feedTitleGradient . frame = CGRectMake ( 0 , -1 ,
self . feedTitleGradient . frame . size . width ,
self . feedTitleGradient . frame . size . height ) ;
for ( id subview in self . webView . scrollView . subviews ) {
UIImageView * imgView = [ subview isKindOfClass : [ UIImageView class ] ] ?
( UIImageView * ) subview : nil ;
// image views whose image is 1 px wide are shadow images , hide them
if ( imgView && imgView . image . size . width = = 1 ) {
imgView . hidden = NO ;
}
}
2011-10-28 10:51:03 -07:00
}
2011-10-27 19:05:38 -07:00
}
2013-03-06 14:29:40 -08:00
2016-02-01 10:44:59 -08:00
if ( appDelegate . storyPageControl . currentPage ! = self ) return ;
if ( ! hasScrolled ) hasScrolled = YES ;
2015-10-06 18:52:58 -07:00
2013-03-07 10:55:23 -05:00
int webpageHeight = self . webView . scrollView . contentSize . height ;
int viewportHeight = self . webView . scrollView . frame . size . height ;
int topPosition = self . webView . scrollView . contentOffset . y ;
int bottomPosition = webpageHeight - topPosition - viewportHeight ;
2014-05-21 13:21:40 -07:00
BOOL singlePage = webpageHeight - 200 <= viewportHeight ;
BOOL atBottom = bottomPosition < 150 ;
2013-03-07 10:55:23 -05:00
BOOL atTop = topPosition < 10 ;
2014-05-21 13:21:40 -07:00
if ( ! atTop && ! atBottom && ! singlePage ) {
2013-03-06 14:29:40 -08:00
// Hide
[ UIView animateWithDuration : .3 delay : 0
options : UIViewAnimationOptionCurveEaseInOut
animations : ^ {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . alpha = 0 ;
2013-03-06 14:29:40 -08:00
} completion : ^ ( BOOL finished ) {
} ] ;
2013-03-13 14:05:58 -07:00
} else if ( singlePage ) {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . alpha = 1 ;
CGRect tvf = appDelegate . storyPageControl . traverseView . frame ;
2013-03-13 14:05:58 -07:00
if ( bottomPosition > 0 ) {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . frame = CGRectMake ( tvf . origin . x ,
2013-03-13 14:05:58 -07:00
self . webView . scrollView . frame . size . height - tvf . size . height ,
tvf . size . width , tvf . size . height ) ;
} else {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . frame = CGRectMake ( tvf . origin . x ,
2013-03-13 14:05:58 -07:00
( self . webView . scrollView . contentSize . height - self . webView . scrollView . contentOffset . y ) - tvf . size . height ,
tvf . size . width , tvf . size . height ) ;
}
2013-03-07 10:55:23 -05:00
} else if ( ! singlePage && ( atTop && ! atBottom ) ) {
2013-03-13 14:05:58 -07:00
// Pin to bottom of viewport , regardless of scrollview
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traversePinned = YES ;
appDelegate . storyPageControl . traverseFloating = NO ;
CGRect tvf = appDelegate . storyPageControl . traverseView . frame ;
appDelegate . storyPageControl . traverseView . frame = CGRectMake ( tvf . origin . x ,
2013-03-06 14:29:40 -08:00
self . webView . scrollView . frame . size . height - tvf . size . height ,
tvf . size . width , tvf . size . height ) ;
[ UIView animateWithDuration : .3 delay : 0
options : UIViewAnimationOptionCurveEaseInOut
animations : ^ {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . alpha = 1 ;
2013-07-17 18:14:04 -07:00
} completion : nil ] ;
2016-02-01 10:44:59 -08:00
} else if ( appDelegate . storyPageControl . traverseView . alpha = = 1 &&
appDelegate . storyPageControl . traversePinned ) {
2013-03-07 10:55:23 -05:00
// Scroll with bottom of scrollview , but smoothly
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseFloating = YES ;
CGRect tvf = appDelegate . storyPageControl . traverseView . frame ;
2013-03-07 10:55:23 -05:00
[ UIView animateWithDuration : .3 delay : 0
options : UIViewAnimationOptionCurveEaseInOut
animations : ^ {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traverseView . frame = CGRectMake ( tvf . origin . x ,
2013-03-07 10:55:23 -05:00
( self . webView . scrollView . contentSize . height - self . webView . scrollView . contentOffset . y ) - tvf . size . height ,
tvf . size . width , tvf . size . height ) ;
} completion : ^ ( BOOL finished ) {
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traversePinned = NO ;
2013-03-07 10:55:23 -05:00
} ] ;
2013-03-06 14:29:40 -08:00
} else {
// Scroll with bottom of scrollview
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . traversePinned = NO ;
appDelegate . storyPageControl . traverseFloating = YES ;
appDelegate . storyPageControl . traverseView . alpha = 1 ;
CGRect tvf = appDelegate . storyPageControl . traverseView . frame ;
appDelegate . storyPageControl . traverseView . frame = CGRectMake ( tvf . origin . x ,
2013-03-06 14:29:40 -08:00
( self . webView . scrollView . contentSize . height - self . webView . scrollView . contentOffset . y ) - tvf . size . height ,
tvf . size . width , tvf . size . height ) ;
}
2015-09-16 21:34:41 -07:00
2015-09-17 13:15:10 -07:00
[ self storeScrollPosition : YES ] ;
}
}
2015-09-22 16:34:24 -07:00
- ( NSInteger ) scrollPosition {
NSInteger updatedPos = floor ( self . webView . scrollView . contentOffset . y / self . webView . scrollView . contentSize . height
* 1000 ) ;
return updatedPos ;
}
2015-09-17 13:15:10 -07:00
- ( void ) storeScrollPosition : ( BOOL ) queue {
2015-09-22 16:34:24 -07:00
__block NSInteger position = [ self scrollPosition ] ;
2015-09-22 13:10:35 -07:00
__block NSDictionary * story = self . activeStory ;
__weak __typeof ( & * self ) weakSelf = self ;
if ( position < 0 ) return ;
NSString * storyIdentifier = [ NSString stringWithFormat : @ "markScrollPosition:%@" , [ story objectForKey : @ "story_hash" ] ] ;
if ( queue ) {
NSTimeInterval interval = 2 ;
[ JNWThrottledBlock runBlock : ^ {
__strong __typeof ( & * weakSelf ) strongSelf = weakSelf ;
if ( ! strongSelf ) return ;
2015-09-22 16:34:24 -07:00
NSInteger updatedPos = [ strongSelf scrollPosition ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate markScrollPosition : updatedPos inStory : story ] ;
2015-09-22 13:10:35 -07:00
} withIdentifier : storyIdentifier throttle : interval ] ;
} else {
2015-10-02 16:04:49 -07:00
dispatch_async ( dispatch_get _global _queue ( DISPATCH_QUEUE _PRIORITY _LOW ,
2015-09-22 13:10:35 -07:00
( unsigned long ) NULL ) , ^ ( void ) {
2016-02-01 10:44:59 -08:00
[ appDelegate markScrollPosition : position inStory : story ] ;
2015-09-22 13:10:35 -07:00
} ) ;
2011-10-27 19:05:38 -07:00
}
2011-10-30 22:17:35 -07:00
}
2015-09-28 20:01:17 -07:00
- ( void ) scrollToLastPosition : ( BOOL ) animated {
2016-02-01 10:44:59 -08:00
if ( hasScrolled ) return ;
hasScrolled = YES ;
2015-10-06 18:52:58 -07:00
2015-09-22 16:34:24 -07:00
__block NSString * storyHash = [ self . activeStory objectForKey : @ "story_hash" ] ;
__weak __typeof ( & * self ) weakSelf = self ;
2015-10-02 16:04:49 -07:00
dispatch_async ( dispatch_get _global _queue ( DISPATCH_QUEUE _PRIORITY _LOW ,
2015-09-22 16:34:24 -07:00
( unsigned long ) NULL ) , ^ ( void ) {
2016-02-01 10:44:59 -08:00
[ appDelegate . database inDatabase : ^ ( FMDatabase * db ) {
2015-09-22 16:34:24 -07:00
__strong __typeof ( & * weakSelf ) strongSelf = weakSelf ;
if ( ! strongSelf ) {
NSLog ( @ " !!! Lost strong reference to story detail vc" ) ;
return ;
}
FMResultSet * cursor = [ db executeQuery : @ "SELECT scroll, story_hash FROM story_scrolls s WHERE s.story_hash = ? LIMIT 1" , storyHash ] ;
while ( [ cursor next ] ) {
NSDictionary * story = [ cursor resultDictionary ] ;
id scroll = [ story objectForKey : @ "scroll" ] ;
2016-02-01 10:44:59 -08:00
if ( [ scroll isKindOfClass : [ NSNull class ] ] && ! scrollPct ) {
2015-09-22 16:34:24 -07:00
NSLog ( @ "No scroll found for story: %@" , [ strongSelf . activeStory objectForKey : @ "story_title" ] ) ;
// No scroll found
continue ;
}
2016-02-01 10:44:59 -08:00
if ( ! scrollPct ) scrollPct = [ scroll floatValue ] / 1000. f ;
NSInteger position = floor ( scrollPct * strongSelf . webView . scrollView . contentSize . height ) ;
2015-09-22 16:34:24 -07:00
NSInteger maxPosition = ( NSInteger ) ( floor ( strongSelf . webView . scrollView . contentSize . height - strongSelf . webView . frame . size . height ) ) ;
if ( position > maxPosition ) {
2015-10-02 16:04:49 -07:00
NSLog ( @ "Position too far, scaling back to max position: %ld > %ld" , ( long ) position , ( long ) maxPosition ) ;
2015-09-22 16:34:24 -07:00
position = maxPosition ;
}
2015-10-02 16:04:49 -07:00
if ( position > 0 ) {
2016-02-01 10:44:59 -08:00
NSLog ( @ "Scrolling to %ld / %.1f%% (%.f+%.f) on %@-%@" , ( long ) position , scrollPct * 100 , strongSelf . webView . scrollView . contentSize . height , strongSelf . webView . frame . size . height , [ story objectForKey : @ "story_hash" ] , [ strongSelf . activeStory objectForKey : @ "story_title" ] ) ;
2015-10-02 16:04:49 -07:00
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
[ strongSelf . webView . scrollView setContentOffset : CGPointMake ( 0 , position ) animated : animated ] ;
} ) ;
}
2015-09-22 16:34:24 -07:00
}
[ cursor close ] ;
} ] ;
} ) ;
}
2012-11-05 17:16:10 -08:00
- ( void ) setActiveStoryAtIndex : ( NSInteger ) activeStoryIndex {
if ( activeStoryIndex >= 0 ) {
2016-02-01 10:44:59 -08:00
self . activeStory = [ [ appDelegate . storiesCollection . activeFeedStories
2014-02-12 20:09:37 -08:00
objectAtIndex : activeStoryIndex ] mutableCopy ] ;
2012-11-05 17:16:10 -08:00
} else {
2016-02-01 10:44:59 -08:00
self . activeStory = [ appDelegate . activeStory mutableCopy ] ;
2012-11-05 17:16:10 -08:00
}
2011-12-01 09:01:18 -08:00
}
2016-02-01 10:44:59 -08:00
- ( BOOL ) webView : ( UIWebView * ) webView
shouldStartLoadWithRequest : ( NSURLRequest * ) request
navigationType : ( UIWebViewNavigationType ) navigationType {
NSURL * url = [ request URL ] ;
2012-06-25 23:06:16 -07:00
NSArray * urlComponents = [ url pathComponents ] ;
2012-07-23 16:17:49 -07:00
NSString * action = @ "" ;
2012-12-27 18:37:05 -08:00
NSString * feedId = [ NSString stringWithFormat : @ "%@" , [ self . activeStory
objectForKey : @ "story_feed_id" ] ] ;
2012-07-23 16:17:49 -07:00
if ( [ urlComponents count ] > 1 ) {
action = [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 1 ] ] ;
}
2012-12-13 12:40:05 -08:00
2013-03-04 17:15:50 -08:00
// NSLog ( @ "Tapped url: %@" , url ) ;
2012-06-25 23:06:16 -07:00
// HACK : Using ios . newsblur . com to intercept the javascript share , reply , and edit events .
// the pathComponents do not work correctly unless it is a correctly formed url
// Is there a better way ? Someone show me the light
if ( [ [ url host ] isEqualToString : @ "ios.newsblur.com" ] ) {
2012-07-27 12:27:13 -07:00
// reset the active comment
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = nil ;
appDelegate . activeShareType = action ;
2012-07-27 12:27:13 -07:00
2012-07-20 15:54:10 -07:00
if ( [ action isEqualToString : @ "reply" ] ||
[ action isEqualToString : @ "edit-reply" ] ||
2012-07-26 13:54:45 -07:00
[ action isEqualToString : @ "edit-share" ] ||
[ action isEqualToString : @ "like-comment" ] ||
[ action isEqualToString : @ "unlike-comment" ] ) {
2012-07-27 12:27:13 -07:00
2015-09-16 18:16:23 -07:00
// search for the comment from friends comments and shares
2012-11-05 17:16:10 -08:00
NSArray * friendComments = [ self . activeStory objectForKey : @ "friend_comments" ] ;
2012-07-20 00:21:24 -07:00
for ( int i = 0 ; i < friendComments . count ; i + + ) {
2012-06-25 23:06:16 -07:00
NSString * userId = [ NSString stringWithFormat : @ "%@" ,
2012-07-20 00:21:24 -07:00
[ [ friendComments objectAtIndex : i ] objectForKey : @ "user_id" ] ] ;
2012-06-25 23:06:16 -07:00
if ( [ userId isEqualToString : [ NSString stringWithFormat : @ "%@" ,
[ urlComponents objectAtIndex : 2 ] ] ] ) {
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = [ friendComments objectAtIndex : i ] ;
2012-07-20 00:21:24 -07:00
}
}
2015-09-16 18:16:23 -07:00
NSArray * friendShares = [ self . activeStory objectForKey : @ "friend_shares" ] ;
for ( int i = 0 ; i < friendShares . count ; i + + ) {
NSString * userId = [ NSString stringWithFormat : @ "%@" ,
[ [ friendShares objectAtIndex : i ] objectForKey : @ "user_id" ] ] ;
if ( [ userId isEqualToString : [ NSString stringWithFormat : @ "%@" ,
[ urlComponents objectAtIndex : 2 ] ] ] ) {
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = [ friendShares objectAtIndex : i ] ;
2015-09-16 18:16:23 -07:00
}
}
2016-02-01 10:44:59 -08:00
if ( appDelegate . activeComment = = nil ) {
2012-11-05 17:16:10 -08:00
NSArray * publicComments = [ self . activeStory objectForKey : @ "public_comments" ] ;
2012-07-20 00:21:24 -07:00
for ( int i = 0 ; i < publicComments . count ; i + + ) {
NSString * userId = [ NSString stringWithFormat : @ "%@" ,
[ [ publicComments objectAtIndex : i ] objectForKey : @ "user_id" ] ] ;
if ( [ userId isEqualToString : [ NSString stringWithFormat : @ "%@" ,
[ urlComponents objectAtIndex : 2 ] ] ] ) {
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = [ publicComments objectAtIndex : i ] ;
2012-07-20 00:21:24 -07:00
}
2012-06-25 18:05:25 -07:00
}
}
2012-07-20 15:54:10 -07:00
2016-02-01 10:44:59 -08:00
if ( appDelegate . activeComment = = nil ) {
2012-07-27 12:27:13 -07:00
NSLog ( @ "PROBLEM! the active comment was not found in friend or public comments" ) ;
2016-02-01 10:44:59 -08:00
return NO ;
2012-07-27 12:27:13 -07:00
}
2012-07-20 15:54:10 -07:00
if ( [ action isEqualToString : @ "reply" ] ) {
2016-02-01 10:44:59 -08:00
[ appDelegate showShareView : @ "reply"
2012-07-20 15:54:10 -07:00
setUserId : [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 2 ] ]
setUsername : [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 3 ] ]
2012-07-30 14:58:57 -07:00
setReplyId : nil ] ;
2012-07-20 15:54:10 -07:00
} else if ( [ action isEqualToString : @ "edit-reply" ] ) {
2016-02-01 10:44:59 -08:00
[ appDelegate showShareView : @ "edit-reply"
2012-07-20 15:54:10 -07:00
setUserId : [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 2 ] ]
setUsername : nil
2012-07-30 14:58:57 -07:00
setReplyId : [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 4 ] ] ] ;
2012-07-20 15:54:10 -07:00
} else if ( [ action isEqualToString : @ "edit-share" ] ) {
2016-02-01 10:44:59 -08:00
[ appDelegate showShareView : @ "edit-share"
2012-07-20 15:54:10 -07:00
setUserId : nil
setUsername : nil
2012-07-30 14:58:57 -07:00
setReplyId : nil ] ;
2012-07-26 13:54:45 -07:00
} else if ( [ action isEqualToString : @ "like-comment" ] ) {
[ self toggleLikeComment : YES ] ;
} else if ( [ action isEqualToString : @ "unlike-comment" ] ) {
[ self toggleLikeComment : NO ] ;
2012-07-20 15:54:10 -07:00
}
2016-02-01 10:44:59 -08:00
return NO ;
2012-06-25 23:06:16 -07:00
} else if ( [ action isEqualToString : @ "share" ] ) {
2012-10-15 09:16:01 -07:00
[ self openShareDialog ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2013-09-26 19:26:10 -07:00
} else if ( [ action isEqualToString : @ "train" ] && [ urlComponents count ] > 5 ) {
2012-12-27 23:04:25 -08:00
[ self openTrainingDialog : [ [ urlComponents objectAtIndex : 2 ] intValue ]
yCoordinate : [ [ urlComponents objectAtIndex : 3 ] intValue ]
width : [ [ urlComponents objectAtIndex : 4 ] intValue ]
height : [ [ urlComponents objectAtIndex : 5 ] intValue ] ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2014-05-21 12:24:22 -07:00
} else if ( [ action isEqualToString : @ "save" ] ) {
2016-02-01 10:44:59 -08:00
BOOL isSaved = [ appDelegate . storiesCollection toggleStorySaved : self . activeStory ] ;
2014-12-16 15:36:58 -08:00
if ( isSaved ) {
[ self openUserTagsDialog : [ [ urlComponents objectAtIndex : 3 ] intValue ]
yCoordinate : [ [ urlComponents objectAtIndex : 4 ] intValue ]
width : [ [ urlComponents objectAtIndex : 5 ] intValue ]
height : [ [ urlComponents objectAtIndex : 6 ] intValue ] ] ;
}
2016-02-01 10:44:59 -08:00
return NO ;
2014-11-10 16:00:59 -08:00
} else if ( [ action isEqualToString : @ "remove-user-tag" ] || [ action isEqualToString : @ "add-user-tag" ] ) {
[ self openUserTagsDialog : [ [ urlComponents objectAtIndex : 3 ] intValue ]
yCoordinate : [ [ urlComponents objectAtIndex : 4 ] intValue ]
width : [ [ urlComponents objectAtIndex : 5 ] intValue ]
height : [ [ urlComponents objectAtIndex : 6 ] intValue ] ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2012-12-07 17:18:31 -08:00
} else if ( [ action isEqualToString : @ "classify-author" ] ) {
NSString * author = [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 2 ] ] ;
2012-12-27 18:37:05 -08:00
[ self . appDelegate toggleAuthorClassifier : author feedId : feedId ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2012-12-07 17:18:31 -08:00
} else if ( [ action isEqualToString : @ "classify-tag" ] ) {
NSString * tag = [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 2 ] ] ;
2012-12-27 18:37:05 -08:00
[ self . appDelegate toggleTagClassifier : tag feedId : feedId ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2013-09-26 19:26:10 -07:00
} else if ( [ action isEqualToString : @ "show-profile" ] && [ urlComponents count ] > 6 ) {
2016-02-01 10:44:59 -08:00
appDelegate . activeUserProfileId = [ NSString stringWithFormat : @ "%@" , [ urlComponents objectAtIndex : 2 ] ] ;
2012-07-28 14:15:20 -07:00
2016-02-01 10:44:59 -08:00
for ( int i = 0 ; i < appDelegate . storiesCollection . activeFeedUserProfiles . count ; i + + ) {
NSString * userId = [ NSString stringWithFormat : @ "%@" , [ [ appDelegate . storiesCollection . activeFeedUserProfiles objectAtIndex : i ] objectForKey : @ "user_id" ] ] ;
if ( [ userId isEqualToString : appDelegate . activeUserProfileId ] ) {
appDelegate . activeUserProfileName = [ NSString stringWithFormat : @ "%@" , [ [ appDelegate . storiesCollection . activeFeedUserProfiles objectAtIndex : i ] objectForKey : @ "username" ] ] ;
2012-07-28 14:15:20 -07:00
break ;
}
}
2016-02-01 10:44:59 -08:00
2012-07-03 17:54:36 -07:00
[ self showUserProfile : [ urlComponents objectAtIndex : 2 ]
xCoordinate : [ [ urlComponents objectAtIndex : 3 ] intValue ]
yCoordinate : [ [ urlComponents objectAtIndex : 4 ] intValue ]
width : [ [ urlComponents objectAtIndex : 5 ] intValue ]
height : [ [ urlComponents objectAtIndex : 6 ] intValue ] ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2012-06-22 13:15:31 -07:00
}
2012-12-13 16:41:52 -08:00
} else if ( [ url . host hasSuffix : @ "itunes.apple.com" ] ) {
2017-01-05 11:44:18 -08:00
[ [ UIApplication sharedApplication ] openURL : url options : @ { } completionHandler : nil ] ;
2016-02-01 10:44:59 -08:00
return NO ;
2011-12-01 09:01:18 -08:00
}
2012-12-13 16:41:52 -08:00
2016-02-01 10:44:59 -08:00
if ( navigationType = = UIWebViewNavigationTypeLinkClicked ) {
// NSLog ( @ "Link clicked, views: %@ = %@" , appDelegate . navigationController . topViewController , appDelegate . masterContainerViewController . childViewControllers ) ;
if ( appDelegate . isPresentingActivities ) return NO ;
[ appDelegate showOriginalStory : url ] ;
return NO ;
2012-06-25 23:06:16 -07:00
}
2014-09-17 19:02:12 -07:00
2016-02-01 10:44:59 -08:00
return YES ;
2011-12-01 09:01:18 -08:00
}
2014-02-03 18:54:50 -08:00
- ( void ) showOriginalStory : ( UIGestureRecognizer * ) gesture {
2016-02-01 10:44:59 -08:00
NSURL * url = [ NSURL URLWithString : [ appDelegate . activeStory
2014-02-03 18:54:50 -08:00
objectForKey : @ "story_permalink" ] ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate hidePopover ] ;
2014-02-03 18:54:50 -08:00
2014-02-04 12:40:46 -08:00
if ( ! gesture || [ gesture isKindOfClass : [ UITapGestureRecognizer class ] ] ) {
2016-02-01 10:44:59 -08:00
[ appDelegate showOriginalStory : url ] ;
2014-02-03 18:54:50 -08:00
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 ] ;
2014-02-04 12:40:46 -08:00
// NSLog ( @ "Gesture: %f - %f" , [ ( UIPinchGestureRecognizer * ) gesture scale ] , distance ) ;
2014-02-03 18:54:50 -08:00
if ( ( distance < 150 && scale <= 1.5 ) ||
( distance < 500 && scale <= 1.2 ) ) {
return ;
}
2016-02-01 10:44:59 -08:00
[ appDelegate showOriginalStory : url ] ;
2014-02-03 18:54:50 -08:00
gesture . enabled = NO ;
gesture . enabled = YES ;
}
}
2012-07-03 17:54:36 -07:00
- ( void ) showUserProfile : ( NSString * ) userId xCoordinate : ( int ) x yCoordinate : ( int ) y width : ( int ) width height : ( int ) height {
2012-07-28 14:15:20 -07:00
CGRect frame = CGRectZero ;
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2012-07-25 17:34:45 -07:00
// only adjust for the bar if user is scrolling
2016-02-01 10:44:59 -08:00
if ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) {
2012-10-04 10:59:44 -07:00
if ( self . webView . scrollView . contentOffset . y = = -20 ) {
y = y + 20 ;
2012-07-25 17:34:45 -07:00
}
} else {
if ( self . webView . scrollView . contentOffset . y = = -9 ) {
y = y + 9 ;
}
}
2012-07-28 12:56:51 -07:00
frame = CGRectMake ( x , y , width , height ) ;
}
2016-02-01 10:44:59 -08:00
[ appDelegate showUserProfileModal : [ NSValue valueWithCGRect : frame ] ] ;
2012-07-03 17:54:36 -07:00
}
2016-02-01 10:44:59 -08:00
- ( void ) webViewDidStartLoad : ( UIWebView * ) webView {
2016-08-23 20:52:34 -04:00
if ( ! self . hasStory ) // other Web page loads aren ' t visible
return ;
// DOM should already be set up here
2014-05-15 18:06:56 -07:00
NSUserDefaults * userPreferences = [ NSUserDefaults standardUserDefaults ] ;
2013-11-23 13:03:14 -08:00
[ self changeFontSize : [ userPreferences stringForKey : @ "story_font_size" ] ] ;
2014-05-15 18:06:56 -07:00
[ self changeLineSpacing : [ userPreferences stringForKey : @ "story_line_spacing" ] ] ;
2016-08-23 20:52:34 -04:00
[ self . webView stringByEvaluatingJavaScriptFromString : @ "document.body.style.webkitTouchCallout='none';" ] ;
2011-12-01 09:01:18 -08:00
}
2016-02-01 10:44:59 -08:00
- ( void ) webViewDidFinishLoad : ( UIWebView * ) webView {
2016-01-07 21:12:58 -08:00
[ self . activityIndicator stopAnimating ] ;
2016-08-23 20:52:34 -04:00
if ( ! self . fullStoryHTML )
return ; // if we ' re loading anything other than a full story , the view will be hidden
2016-02-05 12:19:48 -08:00
2016-08-23 20:52:34 -04:00
[ self loadHTMLString : self . fullStoryHTML ] ;
self . fullStoryHTML = nil ;
self . hasStory = YES ;
2016-02-05 12:19:48 -08:00
2012-07-31 23:49:51 -07:00
[ MBProgressHUD hideHUDForView : self . view animated : YES ] ;
2016-02-01 10:44:59 -08:00
if ( [ appDelegate . storiesCollection . activeFeedStories count ] &&
2016-08-23 20:52:34 -04:00
self . activeStoryId ) {
2016-02-01 10:44:59 -08:00
dispatch_after ( dispatch_time ( DISPATCH_TIME _NOW , .15 * NSEC_PER _SEC ) ,
dispatch_get _main _queue ( ) , ^ {
[ self checkTryFeedStory ] ;
} ) ;
}
2016-08-23 20:52:34 -04:00
[ self scrollToLastPosition : YES ] ;
self . webView . hidden = NO ;
[ self . webView setNeedsDisplay ] ;
2012-11-13 12:28:16 -08:00
}
- ( void ) checkTryFeedStory {
2012-07-31 23:49:51 -07:00
// see if it ' s a tryfeed for animation
2012-11-09 14:13:44 -08:00
if ( ! self . webView . hidden &&
2016-02-01 10:44:59 -08:00
appDelegate . tryFeedCategory &&
( [ [ self . activeStory objectForKey : @ "id" ] isEqualToString : appDelegate . tryFeedStoryId ] ||
[ [ self . activeStory objectForKey : @ "story_hash" ] isEqualToString : appDelegate . tryFeedStoryId ] ) ) {
[ MBProgressHUD hideHUDForView : appDelegate . storyPageControl . view animated : YES ] ;
2012-11-13 12:28:16 -08:00
2016-02-01 10:44:59 -08:00
if ( [ appDelegate . tryFeedCategory isEqualToString : @ "comment_like" ] ||
[ appDelegate . tryFeedCategory isEqualToString : @ "comment_reply" ] ) {
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" , [ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
2012-08-01 12:41:02 -07:00
NSString * jsFlashString = [ [ NSString alloc ] initWithFormat : @ "slideToComment('%@', true, true);" , currentUserId ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsFlashString ] ;
} else if ( [ appDelegate . tryFeedCategory isEqualToString : @ "story_reshare" ] ||
[ appDelegate . tryFeedCategory isEqualToString : @ "reply_reply" ] ) {
2012-11-05 17:16:10 -08:00
NSString * blurblogUserId = [ NSString stringWithFormat : @ "%@" , [ self . activeStory objectForKey : @ "social_user_id" ] ] ;
2012-11-28 16:24:15 -08:00
NSString * jsFlashString = [ [ NSString alloc ] initWithFormat : @ "slideToComment('%@', true, true);" , blurblogUserId ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsFlashString ] ;
2012-07-31 23:49:51 -07:00
}
2016-02-01 10:44:59 -08:00
appDelegate . tryFeedCategory = nil ;
2012-07-31 23:49:51 -07:00
}
2011-12-01 09:01:18 -08:00
}
2012-11-05 17:16:10 -08:00
- ( void ) setFontStyle : ( NSString * ) fontStyle {
2016-02-01 10:44:59 -08:00
NSString * jsString ;
2012-11-05 17:16:10 -08:00
NSUserDefaults * userPreferences = [ NSUserDefaults standardUserDefaults ] ;
2015-11-03 12:10:28 -08:00
[ userPreferences setObject : fontStyle forKey : @ "fontStyle" ] ;
2012-11-05 17:16:10 -08:00
[ userPreferences synchronize ] ;
jsString = [ NSString stringWithFormat : @
"document.getElementById('NB-font-style').setAttribute('class', '%@')" ,
2015-11-03 12:10:28 -08:00
fontStyle ] ;
2012-11-05 17:16:10 -08:00
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
if ( ! [ fontStyle hasPrefix : @ "NB-" ] ) {
jsString = [ NSString stringWithFormat : @
"document.getElementById('NB-font-style').setAttribute('style', 'font-family: %@;')" ,
fontStyle ] ;
} else {
jsString = @ "document.getElementById('NB-font-style').setAttribute('style', '')" ;
}
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
2012-07-25 10:50:52 -07:00
}
2012-11-05 17:16:10 -08:00
- ( void ) changeFontSize : ( NSString * ) fontSize {
2013-11-23 13:03:14 -08:00
NSString * jsString = [ [ NSString alloc ] initWithFormat : @ "document.getElementById('NB-font-size').setAttribute('class', 'NB-%@')" ,
2012-11-05 17:16:10 -08:00
fontSize ] ;
2012-07-28 11:49:31 -07:00
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
2011-12-01 09:01:18 -08:00
}
2014-05-15 18:06:56 -07:00
- ( void ) changeLineSpacing : ( NSString * ) lineSpacing {
NSString * jsString = [ [ NSString alloc ] initWithFormat : @ "document.getElementById('NB-line-spacing').setAttribute('class', 'NB-line-spacing-%@')" ,
lineSpacing ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
2014-05-15 18:06:56 -07:00
}
2012-11-05 17:16:10 -08:00
# pragma mark -
# pragma mark Actions
2011-12-01 09:01:18 -08:00
2012-07-26 13:54:45 -07:00
- ( void ) toggleLikeComment : ( BOOL ) likeComment {
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl showShareHUD : @ "Favoriting" ] ;
2012-07-26 13:54:45 -07:00
NSString * urlString ;
if ( likeComment ) {
2013-06-18 21:23:20 -04:00
urlString = [ NSString stringWithFormat : @ "%@/social/like_comment" ,
2016-01-21 22:11:37 -08:00
self . appDelegate . url ] ;
2012-07-26 13:54:45 -07:00
} else {
2013-06-18 21:23:20 -04:00
urlString = [ NSString stringWithFormat : @ "%@/social/remove_like_comment" ,
2016-01-21 22:11:37 -08:00
self . appDelegate . url ] ;
2012-07-26 13:54:45 -07:00
}
NSURL * url = [ NSURL URLWithString : urlString ] ;
ASIFormDataRequest * request = [ ASIFormDataRequest requestWithURL : url ] ;
2012-11-05 17:16:10 -08:00
[ request setPostValue : [ self . activeStory
2012-07-26 13:54:45 -07:00
objectForKey : @ "id" ]
forKey : @ "story_id" ] ;
2012-11-05 17:16:10 -08:00
[ request setPostValue : [ self . activeStory
2012-07-26 13:54:45 -07:00
objectForKey : @ "story_feed_id" ]
forKey : @ "story_feed_id" ] ;
2016-02-01 10:44:59 -08:00
[ request setPostValue : [ appDelegate . activeComment objectForKey : @ "user_id" ] forKey : @ "comment_user_id" ] ;
2012-07-26 13:54:45 -07:00
[ request setDidFinishSelector : @ selector ( finishLikeComment : ) ] ;
2012-10-17 15:07:53 -07:00
[ request setDidFailSelector : @ selector ( requestFailed : ) ] ;
2012-07-26 13:54:45 -07:00
[ request setDelegate : self ] ;
[ request startAsynchronous ] ;
}
- ( void ) finishLikeComment : ( ASIHTTPRequest * ) request {
NSString * responseString = [ request responseString ] ;
2012-07-27 16:21:44 -07:00
NSData * responseData = [ responseString dataUsingEncoding : NSUTF8StringEncoding ] ;
NSError * error ;
NSDictionary * results = [ NSJSONSerialization
JSONObjectWithData : responseData
options : kNilOptions
error : & error ] ;
2013-09-05 16:34:39 -07:00
if ( request . responseStatusCode ! = 200 ) {
return [ self requestFailed : request ] ;
}
2012-07-26 13:54:45 -07:00
// add the comment into the activeStory dictionary
2016-02-01 10:44:59 -08:00
NSDictionary * newStory = [ DataUtilities updateComment : results for : appDelegate ] ;
2012-07-26 13:54:45 -07:00
// update the current story and the activeFeedStories
2016-02-01 10:44:59 -08:00
appDelegate . activeStory = newStory ;
2012-11-05 17:16:10 -08:00
[ self setActiveStoryAtIndex : -1 ] ;
2012-07-26 13:54:45 -07:00
NSMutableArray * newActiveFeedStories = [ [ NSMutableArray alloc ] init ] ;
2016-02-01 10:44:59 -08:00
for ( int i = 0 ; i < appDelegate . storiesCollection . activeFeedStories . count ; i + + ) {
NSDictionary * feedStory = [ appDelegate . storiesCollection . activeFeedStories objectAtIndex : i ] ;
2014-02-12 20:41:29 -08:00
NSString * storyId = [ NSString stringWithFormat : @ "%@" , [ feedStory objectForKey : @ "story_hash" ] ] ;
NSString * currentStoryId = [ NSString stringWithFormat : @ "%@" , [ self . activeStory objectForKey : @ "story_hash" ] ] ;
2012-07-26 13:54:45 -07:00
if ( [ storyId isEqualToString : currentStoryId ] ) {
[ newActiveFeedStories addObject : newStory ] ;
} else {
2016-02-01 10:44:59 -08:00
[ newActiveFeedStories addObject : [ appDelegate . storiesCollection . activeFeedStories objectAtIndex : i ] ] ;
2012-07-26 13:54:45 -07:00
}
}
2016-02-01 10:44:59 -08:00
appDelegate . storiesCollection . activeFeedStories = [ NSArray arrayWithArray : newActiveFeedStories ] ;
2012-07-26 13:54:45 -07:00
2016-02-01 10:44:59 -08:00
[ MBProgressHUD hideHUDForView : appDelegate . storyPageControl . view animated : NO ] ;
2012-07-30 14:58:57 -07:00
[ self refreshComments : @ "like" ] ;
2012-07-26 13:54:45 -07:00
}
2012-06-29 12:54:52 -07:00
- ( void ) requestFailed : ( ASIHTTPRequest * ) request {
2012-10-17 15:07:53 -07:00
NSLog ( @ "Error in story detail: %@" , [ request error ] ) ;
NSString * error ;
2013-09-05 16:34:39 -07:00
2016-02-01 10:44:59 -08:00
[ MBProgressHUD hideHUDForView : appDelegate . storyPageControl . view animated : NO ] ;
2013-09-05 16:34:39 -07:00
2012-10-17 15:07:53 -07:00
if ( [ request error ] ) {
error = [ NSString stringWithFormat : @ "%@" , [ request error ] ] ;
} else {
error = @ "The server barfed!" ;
}
[ self informError : error ] ;
2012-06-29 12:54:52 -07:00
}
2012-10-15 09:16:01 -07:00
- ( void ) openShareDialog {
// test to see if the user has commented
// search for the comment from friends comments
2012-11-05 17:16:10 -08:00
NSArray * friendComments = [ self . activeStory objectForKey : @ "friend_comments" ] ;
2015-09-16 18:16:23 -07:00
2016-02-01 10:44:59 -08:00
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" , [ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
2012-10-15 09:16:01 -07:00
for ( int i = 0 ; i < friendComments . count ; i + + ) {
NSString * userId = [ NSString stringWithFormat : @ "%@" ,
[ [ friendComments objectAtIndex : i ] objectForKey : @ "user_id" ] ] ;
if ( [ userId isEqualToString : currentUserId ] ) {
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = [ friendComments objectAtIndex : i ] ;
2013-09-23 15:07:25 -07:00
break ;
} else {
2016-02-01 10:44:59 -08:00
appDelegate . activeComment = nil ;
2012-10-15 09:16:01 -07:00
}
}
2016-02-01 10:44:59 -08:00
if ( appDelegate . activeComment = = nil ) {
[ appDelegate showShareView : @ "share"
2012-10-15 09:16:01 -07:00
setUserId : nil
setUsername : nil
setReplyId : nil ] ;
} else {
2016-02-01 10:44:59 -08:00
[ appDelegate showShareView : @ "edit-share"
2012-10-15 09:16:01 -07:00
setUserId : nil
setUsername : nil
setReplyId : nil ] ;
}
}
2012-12-27 23:04:25 -08:00
- ( void ) openTrainingDialog : ( int ) x yCoordinate : ( int ) y width : ( int ) width height : ( int ) height {
CGRect frame = CGRectZero ;
2015-11-28 22:07:38 -08:00
if ( ! self . isPhoneOrCompact ) {
2012-12-27 23:04:25 -08:00
// only adjust for the bar if user is scrolling
2016-02-01 10:44:59 -08:00
if ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) {
2012-12-27 23:04:25 -08:00
if ( self . webView . scrollView . contentOffset . y = = -20 ) {
y = y + 20 ;
}
} else {
if ( self . webView . scrollView . contentOffset . y = = -9 ) {
y = y + 9 ;
}
}
frame = CGRectMake ( x , y , width , height ) ;
}
2014-11-10 16:00:59 -08:00
// NSLog ( @ "Open trainer: %@ (%d/%d/%d/%d)" , NSStringFromCGRect ( frame ) , x , y , width , height ) ;
2016-02-01 10:44:59 -08:00
[ appDelegate openTrainStory : [ NSValue valueWithCGRect : frame ] ] ;
2012-12-27 23:04:25 -08:00
}
2014-11-10 16:00:59 -08:00
- ( void ) openUserTagsDialog : ( int ) x yCoordinate : ( int ) y width : ( int ) width height : ( int ) height {
CGRect frame = CGRectZero ;
// only adjust for the bar if user is scrolling
2016-02-01 10:44:59 -08:00
if ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) {
2014-11-10 16:00:59 -08:00
if ( self . webView . scrollView . contentOffset . y = = -20 ) {
y = y + 20 ;
}
} else {
if ( self . webView . scrollView . contentOffset . y = = -9 ) {
y = y + 9 ;
}
}
frame = CGRectMake ( x , y , width , height ) ;
2016-02-01 10:44:59 -08:00
[ appDelegate openUserTagsStory : [ NSValue valueWithCGRect : frame ] ] ;
2014-11-10 16:00:59 -08:00
}
2014-09-18 18:25:38 -07:00
- ( void ) tapImage : ( UIGestureRecognizer * ) gestureRecognizer {
2016-02-01 10:44:59 -08:00
CGPoint pt = [ self pointForGesture : gestureRecognizer ] ;
if ( pt . x = = CGPointZero . x && pt . y = = CGPointZero . y ) return ;
// NSLog ( @ "Tapped point: %@" , NSStringFromCGPoint ( pt ) ) ;
NSString * tagName = [ webView stringByEvaluatingJavaScriptFromString :
[ NSString stringWithFormat : @ "linkAt(%li, %li, 'tagName');" ,
( long ) pt . x , ( long ) pt . y ] ] ;
if ( [ tagName isEqualToString : @ "IMG" ] ) {
[ self showImageMenu : pt ] ;
[ gestureRecognizer setEnabled : NO ] ;
[ gestureRecognizer setEnabled : YES ] ;
}
2014-09-18 16:55:37 -07:00
}
2014-09-17 19:02:12 -07:00
- ( void ) tapAndHold : ( NSNotification * ) notification {
2016-02-01 10:44:59 -08:00
CGPoint pt = [ self pointForEvent : notification ] ;
if ( pt . x = = CGPointZero . x && pt . y = = CGPointZero . y ) return ;
NSString * tagName = [ webView stringByEvaluatingJavaScriptFromString :
[ NSString stringWithFormat : @ "linkAt(%li, %li, 'tagName');" ,
( long ) pt . x , ( long ) pt . y ] ] ;
if ( [ tagName isEqualToString : @ "IMG" ] ) {
[ self showImageMenu : pt ] ;
}
if ( [ tagName isEqualToString : @ "A" ] ) {
[ self showLinkContextMenu : pt ] ;
}
2014-09-18 16:55:37 -07:00
}
- ( void ) showImageMenu : ( CGPoint ) pt {
2016-02-01 10:44:59 -08:00
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 showFromRect : CGRectMake ( pt . x , pt . y , 1 , 1 )
inView : appDelegate . storyPageControl . view animated : YES ] ;
// [ actions showInView : appDelegate . storyPageControl . view ] ;
2014-09-18 16:55:37 -07:00
}
- ( void ) showLinkContextMenu : ( CGPoint ) pt {
2016-02-01 10:44:59 -08:00
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 ;
NSValue * ptValue = [ NSValue valueWithCGPoint : pt ] ;
[ appDelegate showSendTo : appDelegate . storyPageControl
sender : ptValue
withUrl : url
authorName : nil
text : nil
title : title
feedTitle : nil
images : nil ] ;
}
- ( CGPoint ) pointForEvent : ( NSNotification * ) notification {
if ( self ! = appDelegate . storyPageControl . currentPage ) return CGPointZero ;
if ( ! self . view . window ) return CGPointZero ;
2014-09-17 19:02:12 -07:00
CGPoint pt ;
NSDictionary * coord = [ notification object ] ;
pt . x = [ [ coord objectForKey : @ "x" ] floatValue ] ;
pt . y = [ [ coord objectForKey : @ "y" ] floatValue ] ;
// convert point from window to view coordinate system
2016-02-01 10:44:59 -08:00
pt = [ webView convertPoint : pt fromView : nil ] ;
2014-09-17 19:02:12 -07:00
2014-09-18 18:25:38 -07:00
// convert point from view to HTML coordinate system
2016-02-01 10:44:59 -08:00
// CGPoint offset = [ self . webView scrollOffset ] ;
2014-09-18 18:25:38 -07:00
CGSize viewSize = [ self . webView frame ] . size ;
2016-02-01 10:44:59 -08:00
CGSize windowSize = [ self . webView windowSize ] ;
2014-09-18 18:25:38 -07:00
2016-02-01 10:44:59 -08:00
CGFloat f = windowSize . width / viewSize . width ;
pt . x = pt . x * f ; // + offset . x ;
pt . y = pt . y * f ; // + offset . y ;
return pt ;
2014-09-18 18:25:38 -07:00
}
2016-02-01 10:44:59 -08:00
- ( CGPoint ) pointForGesture : ( UIGestureRecognizer * ) gestureRecognizer {
if ( self ! = appDelegate . storyPageControl . currentPage ) return CGPointZero ;
if ( ! self . view . window ) return CGPointZero ;
2014-09-18 18:25:38 -07:00
2016-02-01 10:44:59 -08:00
CGPoint pt = [ gestureRecognizer locationInView : appDelegate . storyPageControl . currentPage . webView ] ;
2014-09-18 18:25:38 -07:00
2014-09-17 19:02:12 -07:00
// convert point from view to HTML coordinate system
2016-02-01 10:44:59 -08:00
// CGPoint offset = [ self . webView scrollOffset ] ;
2014-09-17 19:02:12 -07:00
CGSize viewSize = [ self . webView frame ] . size ;
2016-02-01 10:44:59 -08:00
CGSize windowSize = [ self . webView windowSize ] ;
2014-09-17 19:02:12 -07:00
2016-02-01 10:44:59 -08:00
CGFloat f = windowSize . width / viewSize . width ;
pt . x = pt . x * f ; // + offset . x ;
pt . y = pt . y * f ; // + offset . y ;
return pt ;
2014-09-17 19:02:12 -07:00
}
2014-09-18 15:15:41 -07:00
- ( void ) actionSheet : ( UIActionSheet * ) actionSheet clickedButtonAtIndex : ( NSInteger ) buttonIndex {
2016-02-01 10:44:59 -08:00
if ( buttonIndex = = actionSheetViewImageIndex ) {
[ appDelegate showOriginalStory : activeLongPressUrl ] ;
} else if ( buttonIndex = = actionSheetCopyImageIndex ||
buttonIndex = = actionSheetSaveImageIndex ) {
[ self fetchImage : activeLongPressUrl buttonIndex : buttonIndex ] ;
2014-09-18 15:15:41 -07:00
}
}
- ( void ) fetchImage : ( NSURL * ) url buttonIndex : ( NSInteger ) buttonIndex {
[ MBProgressHUD hideHUDForView : self . webView animated : YES ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl showShareHUD : buttonIndex = = actionSheetCopyImageIndex ?
2014-09-18 15:15:41 -07:00
@ "Copying..." : @ "Saving..." ] ;
NSURLRequest * urlRequest = [ NSURLRequest requestWithURL : url ] ;
2015-09-18 15:02:15 -07:00
AFHTTPRequestOperation * requestOperation = [ [ AFHTTPRequestOperation alloc ]
initWithRequest : urlRequest ] ;
[ requestOperation setResponseSerializer : [ AFImageResponseSerializer serializer ] ] ;
2014-09-18 15:15:41 -07:00
[ requestOperation setCompletionBlockWithSuccess : ^ ( AFHTTPRequestOperation * operation , id responseObject ) {
UIImage * image = responseObject ;
2016-02-01 10:44:59 -08:00
if ( buttonIndex = = actionSheetCopyImageIndex ) {
2014-09-18 15:15:41 -07:00
[ UIPasteboard generalPasteboard ] . image = image ;
[ self flashCheckmarkHud : @ "copied" ] ;
2016-02-01 10:44:59 -08:00
} else if ( buttonIndex = = actionSheetSaveImageIndex ) {
2014-09-18 15:15:41 -07:00
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 ] ;
}
2015-11-24 13:52:16 -05:00
- ( BOOL ) canPerformAction : ( SEL ) action withSender : ( id ) sender {
if ( [ self respondsToSelector : action ] )
return self . noStoryMessage . hidden ;
return [ super canPerformAction : action withSender : sender ] ;
}
2012-08-06 19:21:39 -07:00
# pragma mark
# pragma mark Subscribing to blurblog
- ( void ) subscribeToBlurblog {
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl showShareHUD : @ "Following" ] ;
2013-06-18 21:23:20 -04:00
NSString * urlString = [ NSString stringWithFormat : @ "%@/social/follow" ,
2016-01-21 22:11:37 -08:00
self . appDelegate . url ] ;
2012-08-06 19:21:39 -07:00
NSURL * url = [ NSURL URLWithString : urlString ] ;
ASIFormDataRequest * request = [ ASIFormDataRequest requestWithURL : url ] ;
2016-02-01 10:44:59 -08:00
[ request setPostValue : [ appDelegate . storiesCollection . activeFeed
2012-08-06 19:21:39 -07:00
objectForKey : @ "user_id" ]
forKey : @ "user_id" ] ;
[ request setDidFinishSelector : @ selector ( finishSubscribeToBlurblog : ) ] ;
[ request setDidFailSelector : @ selector ( requestFailed : ) ] ;
[ request setDelegate : self ] ;
[ request startAsynchronous ] ;
}
- ( void ) finishSubscribeToBlurblog : ( ASIHTTPRequest * ) request {
2016-02-01 10:44:59 -08:00
[ MBProgressHUD hideHUDForView : appDelegate . storyPageControl . view animated : NO ] ;
2014-09-18 15:15:41 -07:00
self . storyHUD = [ MBProgressHUD showHUDAddedTo : self . webView animated : YES ] ;
2012-08-06 19:21:39 -07:00
self . storyHUD . customView = [ [ UIImageView alloc ] initWithImage : [ UIImage imageNamed : @ "37x-Checkmark.png" ] ] ;
self . storyHUD . mode = MBProgressHUDModeCustomView ;
self . storyHUD . removeFromSuperViewOnHide = YES ;
self . storyHUD . labelText = @ "Followed" ;
[ self . storyHUD hide : YES afterDelay : 1 ] ;
2016-02-01 10:44:59 -08:00
appDelegate . storyPageControl . navigationItem . leftBarButtonItem = nil ;
[ appDelegate reloadFeedsView : NO ] ;
2012-08-07 09:57:21 -07:00
}
2012-08-06 19:21:39 -07:00
2012-07-30 14:58:57 -07:00
- ( void ) refreshComments : ( NSString * ) replyId {
2012-08-13 15:34:53 -07:00
NSString * shareBarString = [ self getShareBar ] ;
2012-08-07 11:27:00 -07:00
NSString * commentString = [ self getComments ] ;
2012-06-25 20:28:07 -07:00
NSString * jsString = [ [ NSString alloc ] initWithFormat : @
2012-08-13 15:34:53 -07:00
"document.getElementById('NB-comments-wrapper').innerHTML = '%@';"
2012-11-28 16:33:21 -08:00
"document.getElementById('NB-share-bar-wrapper').innerHTML = '%@';" ,
2012-08-13 15:34:53 -07:00
commentString ,
shareBarString ] ;
2016-02-01 10:44:59 -08:00
NSString * shareType = appDelegate . activeShareType ;
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
[ self . webView stringByEvaluatingJavaScriptFromString : @ "attachFastClick();" ] ;
// HACK to make the scroll event happen after the replace innerHTML event above happens .
dispatch_after ( dispatch_time ( DISPATCH_TIME _NOW , .15 * NSEC_PER _SEC ) ,
dispatch_get _main _queue ( ) , ^ {
if ( ! replyId ) {
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" ,
[ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
NSString * jsFlashString = [ [ NSString alloc ]
initWithFormat : @ "slideToComment('%@', true);" , currentUserId ] ;
[ self . webView stringByEvaluatingJavaScriptFromString : jsFlashString ] ;
} else if ( [ replyId isEqualToString : @ "like" ] ) {
2016-01-30 20:54:50 -08:00
2016-02-01 10:44:59 -08:00
} else {
NSString * jsFlashString = [ [ NSString alloc ]
initWithFormat : @ "slideToComment('%@', true);" , replyId ] ;
[ self . webView stringByEvaluatingJavaScriptFromString : jsFlashString ] ;
}
} ) ;
// // adding in a simulated delay
// sleep ( 1 ) ;
[ self flashCheckmarkHud : shareType ] ;
[ self refreshSideoptions ] ;
2012-12-18 17:29:23 -08:00
}
- ( void ) flashCheckmarkHud : ( NSString * ) messageType {
2014-09-18 15:15:41 -07:00
[ MBProgressHUD hideHUDForView : self . webView animated : NO ] ;
self . storyHUD = [ MBProgressHUD showHUDAddedTo : self . webView animated : YES ] ;
2012-07-27 12:27:13 -07:00
self . storyHUD . customView = [ [ UIImageView alloc ] initWithImage : [ UIImage imageNamed : @ "37x-Checkmark.png" ] ] ;
self . storyHUD . mode = MBProgressHUDModeCustomView ;
2012-12-18 17:29:23 -08:00
self . storyHUD . removeFromSuperViewOnHide = YES ;
if ( [ messageType isEqualToString : @ "reply" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Replied" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "edit-reply" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Edited Reply" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "edit-share" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Edited Comment" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "share" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Shared" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "like-comment" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Favorited" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "unlike-comment" ] ) {
2012-07-27 12:27:13 -07:00
self . storyHUD . labelText = @ "Unfavorited" ;
2012-12-18 17:29:23 -08:00
} else if ( [ messageType isEqualToString : @ "saved" ] ) {
self . storyHUD . labelText = @ "Saved" ;
} else if ( [ messageType isEqualToString : @ "unsaved" ] ) {
self . storyHUD . labelText = @ "No longer saved" ;
2012-12-19 15:37:36 -08:00
} else if ( [ messageType isEqualToString : @ "unread" ] ) {
self . storyHUD . labelText = @ "Unread" ;
2013-07-13 16:56:33 +02:00
} else if ( [ messageType isEqualToString : @ "added" ] ) {
self . storyHUD . labelText = @ "Added" ;
2014-09-18 15:15:41 -07:00
} else if ( [ messageType isEqualToString : @ "copied" ] ) {
self . storyHUD . labelText = @ "Copied" ;
} else if ( [ messageType isEqualToString : @ "saved" ] ) {
self . storyHUD . labelText = @ "Saved" ;
2012-07-27 12:27:13 -07:00
}
[ self . storyHUD hide : YES afterDelay : 1 ] ;
2012-07-12 13:34:41 -07:00
}
2015-11-21 23:23:37 -05:00
# pragma mark -
# pragma mark Scrolling
2012-07-30 14:58:57 -07:00
- ( void ) scrolltoComment {
2016-02-01 10:44:59 -08:00
NSString * currentUserId = [ NSString stringWithFormat : @ "%@" , [ appDelegate . dictSocialProfile objectForKey : @ "user_id" ] ] ;
2012-07-30 15:50:52 -07:00
NSString * jsFlashString = [ [ NSString alloc ] initWithFormat : @ "slideToComment('%@', true);" , currentUserId ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsFlashString ] ;
2012-06-25 20:28:07 -07:00
}
2015-11-21 23:23:37 -05:00
- ( void ) tryScrollingDown : ( BOOL ) down {
2016-02-01 10:44:59 -08:00
UIScrollView * scrollView = webView . scrollView ;
2015-11-21 23:23:37 -05:00
CGPoint contentOffset = scrollView . contentOffset ;
CGFloat frameHeight = scrollView . frame . size . height ;
CGFloat scrollHeight = frameHeight - 45 ; // ~ height of source bar and buttons
if ( down ) {
CGSize contentSize = scrollView . contentSize ;
if ( contentOffset . y + frameHeight = = contentSize . height )
return ;
contentOffset . y = MIN ( contentOffset . y + scrollHeight , contentSize . height - frameHeight ) ;
} else {
if ( contentOffset . y <= 0 )
return ;
contentOffset . y = MAX ( contentOffset . y - scrollHeight , 0 ) ;
}
[ scrollView setContentOffset : contentOffset animated : YES ] ;
}
- ( void ) scrollPageDown : ( id ) sender {
[ self tryScrollingDown : YES ] ;
}
- ( void ) scrollPageUp : ( id ) sender {
[ self tryScrollingDown : NO ] ;
}
2012-11-05 17:16:10 -08:00
- ( NSString * ) textToHtml : ( NSString * ) htmlString {
htmlString = [ htmlString stringByReplacingOccurrencesOfString : @ "'" withString : @ "'" ] ;
htmlString = [ htmlString stringByReplacingOccurrencesOfString : @ "\n" withString : @ "<br/>" ] ;
return htmlString ;
2011-06-14 10:35:33 -04:00
}
2012-11-07 17:54:16 -08:00
- ( void ) changeWebViewWidth {
2016-11-01 15:10:56 -07:00
// Don ' t do this in the background , to avoid scrolling to the top unnecessarily
if ( [ UIApplication sharedApplication ] . applicationState = = UIApplicationStateBackground ) {
return ;
}
2015-10-05 11:45:33 -07:00
// [ webView setNeedsLayout ] ;
// [ webView layoutIfNeeded ] ;
2015-09-28 20:01:17 -07:00
2016-02-01 10:44:59 -08:00
// NSLog ( @ "changeWebViewWidth: %@ / %@ / %@" , NSStringFromCGSize ( self . view . bounds . size ) , NSStringFromCGSize ( webView . scrollView . bounds . size ) , NSStringFromCGSize ( webView . scrollView . contentSize ) ) ;
2015-09-23 11:34:03 -07:00
2016-02-01 10:44:59 -08:00
NSInteger contentWidth = CGRectGetWidth ( webView . scrollView . bounds ) ;
2015-09-22 13:10:35 -07:00
UIInterfaceOrientation orientation = [ [ UIApplication sharedApplication ] statusBarOrientation ] ;
2012-06-28 11:12:38 -07:00
NSString * contentWidthClass ;
2014-09-19 17:25:57 -07:00
2015-11-28 22:07:38 -08:00
if ( UIInterfaceOrientationIsLandscape ( orientation ) && ! self . isPhoneOrCompact ) {
2016-04-06 18:14:06 -07:00
if ( iPadPro ) {
contentWidthClass = @ "NB-ipad-wide NB-ipad-pro-wide" ;
} else {
contentWidthClass = @ "NB-ipad-wide" ;
}
2015-11-28 22:07:38 -08:00
} else if ( ! UIInterfaceOrientationIsLandscape ( orientation ) && ! self . isPhoneOrCompact ) {
2016-04-06 18:14:06 -07:00
if ( iPadPro ) {
contentWidthClass = @ "NB-ipad-narrow NB-ipad-pro-narrow" ;
} else {
contentWidthClass = @ "NB-ipad-narrow" ;
}
2015-11-28 22:07:38 -08:00
} else if ( UIInterfaceOrientationIsLandscape ( orientation ) && self . isPhoneOrCompact ) {
2014-09-19 17:25:57 -07:00
contentWidthClass = @ "NB-iphone-wide" ;
2012-06-28 11:12:38 -07:00
} else {
contentWidthClass = @ "NB-iphone" ;
}
2014-09-19 17:25:57 -07:00
2014-09-24 12:00:47 -07:00
contentWidthClass = [ NSString stringWithFormat : @ "%@ NB-width-%d" ,
2016-02-01 10:44:59 -08:00
contentWidthClass , ( int ) floorf ( CGRectGetWidth ( webView . scrollView . bounds ) ) ] ;
2014-09-24 12:00:47 -07:00
2016-02-01 10:44:59 -08:00
NSString * riverClass = ( appDelegate . storiesCollection . isRiverView ||
appDelegate . storiesCollection . isSocialView ||
appDelegate . storiesCollection . isSavedView ||
appDelegate . storiesCollection . isReadView ) ?
2013-03-13 14:05:58 -07:00
@ "NB-river" : @ "NB-non-river" ;
2012-06-28 11:12:38 -07:00
2012-07-12 13:34:41 -07:00
NSString * jsString = [ [ NSString alloc ] initWithFormat :
2013-03-13 14:05:58 -07:00
@ "$('body').attr('class', '%@ %@');"
2015-09-23 11:34:03 -07:00
"document.getElementById(\" viewport \ ").setAttribute(\" content \ ", \" width = % li ; initial - scale = 1 ; minimum - scale = 1.0 ; maximum - scale = 1.0 ; user - scalable = 0 ; \ ");" ,
2012-07-16 10:10:52 -07:00
contentWidthClass ,
2013-03-13 14:05:58 -07:00
riverClass ,
2015-09-22 13:10:35 -07:00
( long ) contentWidth ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
2012-11-08 17:39:32 -08:00
2012-11-09 14:57:33 -08:00
// self . webView . hidden = NO ;
2012-06-27 21:28:04 -07:00
}
2012-12-07 17:18:31 -08:00
- ( void ) refreshHeader {
2012-12-13 12:40:05 -08:00
NSString * headerString = [ [ [ self getHeader ] stringByReplacingOccurrencesOfString : @ "\'" withString : @ "\\'" ]
2014-05-21 12:24:22 -07:00
stringByReplacingOccurrencesOfString : @ "\n" withString : @ " " ] ;
2012-12-07 17:18:31 -08:00
NSString * jsString = [ NSString stringWithFormat : @ "document.getElementById('NB-header-container').innerHTML = '%@';" ,
headerString ] ;
2014-05-21 12:24:22 -07:00
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
[ self . webView stringByEvaluatingJavaScriptFromString : @ "attachFastClick();" ] ;
2014-05-21 12:24:22 -07:00
}
2012-12-13 12:40:05 -08:00
2014-05-21 12:24:22 -07:00
- ( void ) refreshSideoptions {
NSString * sideoptionsString = [ [ [ self getSideoptions ] stringByReplacingOccurrencesOfString : @ "\'" withString : @ "\\'" ]
stringByReplacingOccurrencesOfString : @ "\n" withString : @ " " ] ;
NSString * jsString = [ NSString stringWithFormat : @ "document.getElementById('NB-sideoptions-container').innerHTML = '%@';" ,
sideoptionsString ] ;
2016-02-01 10:44:59 -08:00
[ self . webView stringByEvaluatingJavaScriptFromString : jsString ] ;
[ self . webView stringByEvaluatingJavaScriptFromString : @ "attachFastClick();" ] ;
2012-12-07 17:18:31 -08:00
}
2013-05-28 18:07:19 -07:00
# pragma mark -
# pragma mark Text view
2015-10-05 11:45:33 -07:00
- ( void ) showTextOrStoryView {
NSString * feedIdStr = [ NSString stringWithFormat : @ "%@" ,
[ self . activeStory objectForKey : @ "story_feed_id" ] ] ;
2016-02-01 10:44:59 -08:00
if ( [ appDelegate isFeedInTextView : feedIdStr ] ) {
2015-10-05 11:45:33 -07:00
if ( ! self . inTextView ) {
[ self fetchTextView ] ;
}
} else {
if ( self . inTextView ) {
[ self showStoryView ] ;
}
}
}
2015-11-21 23:23:37 -05:00
- ( void ) toggleTextView : ( id ) sender {
if ( self . inTextView )
[ self showStoryView ] ;
else
[ self fetchTextView ] ;
}
2015-03-10 18:58:23 -07:00
- ( void ) showStoryView {
self . inTextView = NO ;
[ MBProgressHUD hideHUDForView : self . webView animated : YES ] ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl setTextButton : self ] ;
2015-03-10 18:58:23 -07:00
[ self drawStory ] ;
}
2013-05-28 18:07:19 -07:00
- ( void ) fetchTextView {
2015-03-09 14:20:45 -07:00
if ( ! self . activeStoryId || ! self . activeStory ) return ;
2015-03-10 18:58:23 -07:00
self . inTextView = YES ;
2015-03-12 19:43:39 -07:00
// NSLog ( @ "Fetching Text: %@" , [ self . activeStory objectForKey : @ "story_title" ] ) ;
2016-02-01 10:44:59 -08:00
if ( self . activeStory = = appDelegate . storyPageControl . currentPage . activeStory ) {
2015-11-30 18:12:10 -08:00
dispatch_async ( dispatch_get _main _queue ( ) , ^ {
[ self . appDelegate . storyPageControl showFetchingTextNotifier ] ;
} ) ;
}
2013-05-28 18:07:19 -07:00
2013-06-18 21:23:20 -04:00
NSString * urlString = [ NSString stringWithFormat : @ "%@/rss_feeds/original_text" ,
2016-01-21 22:11:37 -08:00
self . appDelegate . url ] ;
2013-05-28 18:07:19 -07:00
ASIFormDataRequest * request = [ self formRequestWithURL : urlString ] ;
2015-03-09 14:20:45 -07:00
[ request addPostValue : [ self . activeStory objectForKey : @ "id" ] forKey : @ "story_id" ] ;
[ request addPostValue : [ self . activeStory objectForKey : @ "story_feed_id" ] forKey : @ "feed_id" ] ;
[ request setUserInfo : @ { @ "storyId" : [ self . activeStory objectForKey : @ "id" ] } ] ;
2013-05-28 18:07:19 -07:00
[ request setDidFinishSelector : @ selector ( finishFetchTextView : ) ] ;
2016-10-05 21:03:32 -07:00
[ request setDidFailSelector : @ selector ( failedFetchText : ) ] ;
2013-05-28 18:07:19 -07:00
[ request setDelegate : self ] ;
[ request startAsynchronous ] ;
}
2015-03-10 18:58:23 -07:00
- ( void ) failedFetchText : ( ASIHTTPRequest * ) request {
2015-10-28 21:50:23 -07:00
[ self . appDelegate . storyPageControl hideNotifier ] ;
2015-03-10 18:58:23 -07:00
[ MBProgressHUD hideHUDForView : self . webView animated : YES ] ;
2016-02-01 10:44:59 -08:00
if ( self . activeStory = = appDelegate . storyPageControl . currentPage . activeStory ) {
2015-11-30 18:12:10 -08:00
[ self informError : @ "Could not fetch text" ] ;
}
2015-03-10 18:58:23 -07:00
self . inTextView = NO ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl setTextButton : self ] ;
2015-03-10 18:58:23 -07:00
}
2013-05-28 18:07:19 -07:00
- ( void ) finishFetchTextView : ( ASIHTTPRequest * ) request {
NSString * responseString = [ request responseString ] ;
NSData * responseData = [ responseString dataUsingEncoding : NSUTF8StringEncoding ] ;
NSError * error ;
NSDictionary * results = [ NSJSONSerialization
JSONObjectWithData : responseData
options : kNilOptions
error : & error ] ;
if ( [ [ results objectForKey : @ "failed" ] boolValue ] ) {
2015-03-10 18:58:23 -07:00
[ self failedFetchText : request ] ;
2013-05-28 18:07:19 -07:00
return ;
}
2013-10-17 11:21:37 -07:00
if ( ! [ [ request . userInfo objectForKey : @ "storyId" ]
2015-03-09 14:20:45 -07:00
isEqualToString : [ self . activeStory objectForKey : @ "id" ] ] ) {
2015-10-28 21:50:23 -07:00
[ self . appDelegate . storyPageControl hideNotifier ] ;
2013-10-17 11:21:37 -07:00
[ MBProgressHUD hideHUDForView : self . webView animated : YES ] ;
self . inTextView = NO ;
2016-02-01 10:44:59 -08:00
[ appDelegate . storyPageControl setTextButton : self ] ;
2013-10-17 11:21:37 -07:00
return ;
}
2015-03-10 18:58:23 -07:00
NSMutableDictionary * newActiveStory = [ self . activeStory mutableCopy ] ;
2014-05-29 12:48:25 -07:00
[ newActiveStory setObject : [ results objectForKey : @ "original_text" ] forKey : @ "original_text" ] ;
2016-02-01 10:44:59 -08:00
if ( [ [ self . activeStory objectForKey : @ "story_hash" ] isEqualToString : [ appDelegate . activeStory objectForKey : @ "story_hash" ] ] ) {
appDelegate . activeStory = newActiveStory ;
2015-09-22 17:15:50 -07:00
}
2015-03-10 18:58:23 -07:00
self . activeStory = newActiveStory ;
2013-05-28 18:07:19 -07:00
2015-10-28 21:50:23 -07:00
[ self . appDelegate . storyPageControl hideNotifier ] ;
2013-05-28 18:07:19 -07:00
[ MBProgressHUD hideHUDForView : self . webView animated : YES ] ;
2013-05-29 13:36:39 -07:00
self . inTextView = YES ;
2015-03-10 18:58:23 -07:00
[ self drawStory ] ;
2015-03-12 19:43:39 -07:00
// NSLog ( @ "Fetched Text: %@" , [ self . activeStory objectForKey : @ "story_title" ] ) ;
2013-05-28 18:07:19 -07:00
}
2010-06-25 18:36:01 -04:00
@ end