"]];
}
}
NSString *storyHeader = [NSString stringWithFormat:@
"",
[story_tags length] ?
[appDelegate.activeStory
objectForKey:@"long_parsed_date"] :
[appDelegate.activeStory
objectForKey:@"short_parsed_date"],
[appDelegate.activeStory objectForKey:@"story_title"],
story_author,
story_tags];
NSString *htmlString = [NSString stringWithFormat:@
""
"%@" // header string
""
" %@" // storyHeader
"
" // font-style
" %@" // share
" "
" %@"
""
"",
headerString,
contentWidthClass,
storyHeader,
fontStyleClass,
fontSizeClass,
[appDelegate.activeStory objectForKey:@"story_content"],
sharingHtmlString,
commentString,
footerString
];
// NSLog(@"\n\n\n\nhtmlString:\n\n\n%@\n\n\n", htmlString);
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString
//baseURL:[NSURL URLWithString:feed_link]];
baseURL:baseURL];
NSDictionary *feed;
NSString *feedIdStr = [NSString stringWithFormat:@"%@",
[appDelegate.activeStory
objectForKey:@"story_feed_id"]];
if (appDelegate.isSocialView) {
feed = [appDelegate.dictActiveFeeds objectForKey:feedIdStr];
// this is to catch when a user is already subscribed
if (!feed) {
feed = [appDelegate.dictFeeds objectForKey:feedIdStr];
}
} else {
feed = [appDelegate.dictFeeds objectForKey:feedIdStr];
}
self.feedTitleGradient = [appDelegate makeFeedTitleGradient:feed
withRect:CGRectMake(0, -1, 1024, 21)]; // 1024 hack for self.webView.frame.size.width
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];
}
}
for (NSObject *aSubView in [self.webView subviews]) {
if ([aSubView isKindOfClass:[UIScrollView class]]) {
UIScrollView * theScrollView = (UIScrollView *)aSubView;
if (appDelegate.isRiverView || appDelegate.isSocialView) {
theScrollView.contentInset = UIEdgeInsetsMake(19, 0, 0, 0);
theScrollView.scrollIndicatorInsets = UIEdgeInsetsMake(19, 0, 0, 0);
} else {
theScrollView.contentInset = UIEdgeInsetsMake(9, 0, 0, 0);
theScrollView.scrollIndicatorInsets = UIEdgeInsetsMake(9, 0, 0, 0);
}
[self.webView insertSubview:feedTitleGradient aboveSubview:theScrollView];
[theScrollView setContentOffset:CGPointMake(0, (appDelegate.isRiverView || appDelegate.isSocialView) ? -19 : -9) animated:NO];
break;
}
}
}
- (void)setActiveStory {
self.activeStoryId = [appDelegate.activeStory objectForKey:@"id"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [appDelegate.activeStory objectForKey:@"story_feed_id"]];
UIImage *titleImage = appDelegate.isRiverView ?
[UIImage imageNamed:@"folder.png"] :
[Utilities getImage:feedIdStr];
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:titleImage];
titleImageView.frame = CGRectMake(0.0, 2.0, 16.0, 16.0);
titleImageView.hidden = YES;
self.navigationItem.titleView = titleImageView;
titleImageView.hidden = NO;
}
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSArray *urlComponents = [url pathComponents];
NSString *action = @"";
if ([urlComponents count] > 1) {
action = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:1]];
}
// 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"]){
if ([action isEqualToString:@"reply"] ||
[action isEqualToString:@"edit-reply"] ||
[action isEqualToString:@"edit-share"] ||
[action isEqualToString:@"like-comment"] ||
[action isEqualToString:@"unlike-comment"]) {
appDelegate.activeComment = nil;
// search for the comment from friends comments
NSArray *friendComments = [appDelegate.activeStory objectForKey:@"friend_comments"];
for (int i = 0; i < friendComments.count; i++) {
NSString *userId = [NSString stringWithFormat:@"%@",
[[friendComments objectAtIndex:i] objectForKey:@"user_id"]];
if([userId isEqualToString:[NSString stringWithFormat:@"%@",
[urlComponents objectAtIndex:2]]]){
appDelegate.activeComment = [friendComments objectAtIndex:i];
}
}
if (appDelegate.activeComment == nil) {
NSArray *publicComments = [appDelegate.activeStory objectForKey:@"public_comments"];
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]]]){
appDelegate.activeComment = [publicComments objectAtIndex:i];
}
}
}
if ([action isEqualToString:@"reply"]) {
[appDelegate showShareView:@"reply"
setUserId:[NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]]
setUsername:[NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:3]]
setCommentIndex:nil];
} else if ([action isEqualToString:@"edit-reply"]) {
[appDelegate showShareView:@"edit-reply"
setUserId:[NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]]
setUsername:nil
setCommentIndex:[NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:4]]];
} else if ([action isEqualToString:@"edit-share"]) {
[appDelegate showShareView:@"edit-share"
setUserId:nil
setUsername:nil
setCommentIndex:nil];
} else if ([action isEqualToString:@"like-comment"]) {
[self toggleLikeComment:YES];
} else if ([action isEqualToString:@"unlike-comment"]) {
[self toggleLikeComment:NO];
}
return NO;
} else if ([action isEqualToString:@"share"]) {
// test to see if the user has commented
// search for the comment from friends comments
NSArray *friendComments = [appDelegate.activeStory objectForKey:@"friend_comments"];
NSString *currentUserId = [NSString stringWithFormat:@"%@", [appDelegate.dictUserProfile objectForKey:@"user_id"]];
for (int i = 0; i < friendComments.count; i++) {
NSString *userId = [NSString stringWithFormat:@"%@",
[[friendComments objectAtIndex:i] objectForKey:@"user_id"]];
if([userId isEqualToString:currentUserId]){
appDelegate.activeComment = [friendComments objectAtIndex:i];
}
}
if (appDelegate.activeComment == nil) {
[appDelegate showShareView:@"share"
setUserId:nil
setUsername:nil
setCommentIndex:nil];
} else {
[appDelegate showShareView:@"edit-share"
setUserId:nil
setUsername:nil
setCommentIndex:nil];
}
return NO;
} else if ([action isEqualToString:@"show-profile"]) {
appDelegate.activeUserProfileId = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[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]];
return NO;
}
}
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[appDelegate showOriginalStory:url];
return NO;
}
return YES;
}
- (void)showUserProfile:(NSString *)userId xCoordinate:(int)x yCoordinate:(int)y width:(int)width height:(int)height {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (popoverController == nil) {
popoverController = [[UIPopoverController alloc]
initWithContentViewController:appDelegate.userProfileViewController];
popoverController.delegate = self;
} else {
if (popoverController.isPopoverVisible) {
[popoverController dismissPopoverAnimated:YES];
return;
}
[popoverController setContentViewController:appDelegate.userProfileViewController];
}
[popoverController setPopoverContentSize:CGSizeMake(320, 416)];
// only adjust for the bar if user is scrolling
if (appDelegate.isRiverView || appDelegate.isSocialView) {
if (self.webView.scrollView.contentOffset.y == -19) {
y = y + 19;
}
} else {
if (self.webView.scrollView.contentOffset.y == -9) {
y = y + 9;
}
}
[popoverController presentPopoverFromRect:CGRectMake(x, y, width, height)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
} else {
[appDelegate showUserProfileModal];
}
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
if ([userPreferences integerForKey:@"fontSizing"]){
[self changeFontSize:[userPreferences stringForKey:@"fontSizing"]];
}
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
if ([userPreferences integerForKey:@"fontSizing"]){
[self changeFontSize:[userPreferences stringForKey:@"fontSizing"]];
}
}
#pragma mark -
#pragma mark Actions
- (IBAction)tapProgressBar:(id)sender {
[MBProgressHUD hideHUDForView:self.view animated:NO];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.mode = MBProgressHUDModeText;
hud.removeFromSuperViewOnHide = YES;
int unreadCount = appDelegate.unreadCount;
if (unreadCount == 0) {
hud.labelText = @"No unread stories";
} else if (unreadCount == 1) {
hud.labelText = @"1 unread story";
} else {
hud.labelText = [NSString stringWithFormat:@"%i unread stories", unreadCount];
}
[hud hide:YES afterDelay:0.8];
}
- (void)setNextPreviousButtons {
int nextIndex = [appDelegate indexOfNextUnreadStory];
int unreadCount = [appDelegate unreadCount];
if (nextIndex == -1 && unreadCount > 0) {
[buttonNext setStyle:UIBarButtonItemStyleBordered];
[buttonNext setTitle:@"Next Unread"];
} else if (nextIndex == -1) {
[buttonNext setStyle:UIBarButtonItemStyleDone];
[buttonNext setTitle:@"Done"];
} else {
[buttonNext setStyle:UIBarButtonItemStyleBordered];
[buttonNext setTitle:@"Next Unread"];
}
int readStoryCount = [appDelegate.readStories count];
if (readStoryCount == 0 ||
(readStoryCount == 1 &&
[appDelegate.readStories lastObject] == [appDelegate.activeStory objectForKey:@"id"])) {
[buttonPrevious setStyle:UIBarButtonItemStyleBordered];
[buttonPrevious setTitle:@"Previous"];
[buttonPrevious setEnabled:NO];
} else {
[buttonPrevious setStyle:UIBarButtonItemStyleBordered];
[buttonPrevious setTitle:@"Previous"];
[buttonPrevious setEnabled:YES];
}
float unreads = (float)[appDelegate unreadCount];
float total = [appDelegate originalStoryCount];
float progress = (total - unreads) / total;
[progressView setProgress:progress];
}
- (void)markStoryAsRead {
if ([[appDelegate.activeStory objectForKey:@"read_status"] intValue] != 1) {
[appDelegate markActiveStoryRead];
NSString *urlString;
if (appDelegate.isSocialView) {
urlString = [NSString stringWithFormat:@"http://%@/reader/mark_social_stories_as_read",
NEWSBLUR_URL];
} else {
urlString = [NSString stringWithFormat:@"http://%@/reader/mark_story_as_read",
NEWSBLUR_URL];
}
NSURL *url = [NSURL URLWithString:urlString];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
if (appDelegate.isSocialView) {
NSArray *storyId = [NSArray arrayWithObject:[appDelegate.activeStory objectForKey:@"id"]];
NSDictionary *feedStory = [NSDictionary dictionaryWithObject:storyId
forKey:[NSString stringWithFormat:@"%@",
[appDelegate.activeStory objectForKey:@"story_feed_id"]]];
NSDictionary *usersFeedsStories = [NSDictionary dictionaryWithObject:feedStory
forKey:[NSString stringWithFormat:@"%@",
[appDelegate.activeStory objectForKey:@"social_user_id"]]];
[request setPostValue:[usersFeedsStories JSONRepresentation] forKey:@"users_feeds_stories"];
} else {
[request setPostValue:[appDelegate.activeStory
objectForKey:@"id"]
forKey:@"story_id"];
[request setPostValue:[appDelegate.activeStory
objectForKey:@"story_feed_id"]
forKey:@"feed_id"];
}
[request setDidFinishSelector:@selector(finishMarkAsRead:)];
[request setDidFailSelector:@selector(finishedWithError:)];
[request setDelegate:self];
[request startAsynchronous];
}
}
- (void)toggleLikeComment:(BOOL)likeComment {
NSString *urlString;
if (likeComment) {
urlString = [NSString stringWithFormat:@"http://%@/social/like_comment",
NEWSBLUR_URL];
} else {
urlString = [NSString stringWithFormat:@"http://%@/social/remove_like_comment",
NEWSBLUR_URL];
}
NSURL *url = [NSURL URLWithString:urlString];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:[appDelegate.activeStory
objectForKey:@"id"]
forKey:@"story_id"];
[request setPostValue:[appDelegate.activeStory
objectForKey:@"story_feed_id"]
forKey:@"story_feed_id"];
[request setPostValue:[appDelegate.activeComment objectForKey:@"user_id"] forKey:@"comment_user_id"];
[request setDidFinishSelector:@selector(finishLikeComment:)];
[request setDidFailSelector:@selector(finishedWithError:)];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)finishLikeComment:(ASIHTTPRequest *)request {
NSString *responseString = [request responseString];
NSDictionary *results = [[NSDictionary alloc]
initWithDictionary:[responseString JSONValue]];
// add the comment into the activeStory dictionary
NSDictionary *newStory = [DataUtilities updateComment:results for:appDelegate];
// update the current story and the activeFeedStories
appDelegate.activeStory = newStory;
NSMutableArray *newActiveFeedStories = [[NSMutableArray alloc] init];
for (int i = 0; i < appDelegate.activeFeedStories.count; i++) {
NSDictionary *feedStory = [appDelegate.activeFeedStories objectAtIndex:i];
NSString *storyId = [NSString stringWithFormat:@"%@", [feedStory objectForKey:@"id"]];
NSString *currentStoryId = [NSString stringWithFormat:@"%@", [appDelegate.activeStory objectForKey:@"id"]];
if ([storyId isEqualToString: currentStoryId]){
[newActiveFeedStories addObject:newStory];
} else {
[newActiveFeedStories addObject:[appDelegate.activeFeedStories objectAtIndex:i]];
}
}
appDelegate.activeFeedStories = [NSArray arrayWithArray:newActiveFeedStories];
[appDelegate refreshComments];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSLog(@"Error in mark as read is %@", [request error]);
}
- (void)finishMarkAsRead:(ASIHTTPRequest *)request {
// NSString *responseString = [request responseString];
// NSDictionary *results = [[NSDictionary alloc]
// initWithDictionary:[responseString JSONValue]];
// NSLog(@"results in mark as read is %@", results);
}
- (void)refreshComments {
NSString *commentString = [self getComments:@"friends"];
NSString *jsString = [[NSString alloc] initWithFormat:@
"document.getElementById('NB-comments-wrapper').innerHTML = '%@';",
commentString];
NSLog(@"JSSTRING IS %@\n\n\n", jsString);
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
- (void)scrolltoBottom {
CGPoint bottomOffset = CGPointMake(0, self.webView.scrollView.contentSize.height - self.webView.bounds.size.height);
[self.webView.scrollView setContentOffset:bottomOffset animated:YES];
}
- (IBAction)doNextUnreadStory {
int nextIndex = [appDelegate indexOfNextUnreadStory];
int unreadCount = [appDelegate unreadCount];
[self.loadingIndicator stopAnimating];
if (self.appDelegate.feedDetailViewController.pageFetching) {
return;
}
if (nextIndex == -1 && unreadCount > 0 &&
self.appDelegate.feedDetailViewController.feedPage < 50 &&
!self.appDelegate.feedDetailViewController.pageFinished &&
!self.appDelegate.feedDetailViewController.pageFetching) {
// Fetch next page and see if it has the unreads.
[self.loadingIndicator startAnimating];
self.activity.customView = self.loadingIndicator;
[self.appDelegate.feedDetailViewController fetchNextPage:^() {
[self doNextUnreadStory];
}];
} else if (nextIndex == -1) {
[appDelegate.navigationController
popToViewController:[appDelegate.navigationController.viewControllers
objectAtIndex:0]
animated:YES];
[appDelegate hideStoryDetailView];
} else {
[appDelegate setActiveStory:[[appDelegate activeFeedStories]
objectAtIndex:nextIndex]];
[appDelegate pushReadStory:[appDelegate.activeStory objectForKey:@"id"]];
[self setActiveStory];
[self showStory];
[self markStoryAsRead];
[self setNextPreviousButtons];
[appDelegate changeActiveFeedDetailRow];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:self.view
cache:NO];
[UIView commitAnimations];
}
}
- (IBAction)doNextStory {
int nextIndex = [appDelegate indexOfNextStory];
if (nextIndex == -1) {
return;
}
[self.loadingIndicator stopAnimating];
if (self.appDelegate.feedDetailViewController.pageFetching) {
return;
}
[appDelegate setActiveStory:[[appDelegate activeFeedStories]
objectAtIndex:nextIndex]];
[appDelegate pushReadStory:[appDelegate.activeStory objectForKey:@"id"]];
[self setActiveStory];
[self showStory];
[self markStoryAsRead];
[self setNextPreviousButtons];
[appDelegate changeActiveFeedDetailRow];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
forView:self.view
cache:NO];
[UIView commitAnimations];
}
- (IBAction)doPreviousStory {
[self.loadingIndicator stopAnimating];
id previousStoryId = [appDelegate popReadStory];
if (!previousStoryId || previousStoryId == [appDelegate.activeStory objectForKey:@"id"]) {
[appDelegate.navigationController
popToViewController:[appDelegate.navigationController.viewControllers
objectAtIndex:0]
animated:YES];
[appDelegate hideStoryDetailView];
} else {
int previousIndex = [appDelegate locationOfStoryId:previousStoryId];
if (previousIndex == -1) {
return [self doPreviousStory];
}
[appDelegate setActiveStory:[[appDelegate activeFeedStories]
objectAtIndex:previousIndex]];
[appDelegate changeActiveFeedDetailRow];
[self setActiveStory];
[self showStory];
[self markStoryAsRead];
[self setNextPreviousButtons];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown
forView:self.view
cache:NO];
[UIView commitAnimations];
}
}
- (void)changeWebViewWidth:(int)width {
int contentWidth = self.view.frame.size.width;
NSString *contentWidthClass;
if (contentWidth > 740) {
contentWidthClass = @"NB-ipad-wide";
} else if (contentWidth > 420) {
contentWidthClass = @"NB-ipad-narrow";
} else {
contentWidthClass = @"NB-iphone";
}
NSString *jsString = [[NSString alloc] initWithFormat:
@"document.getElementsByTagName('body')[0].setAttribute('class', '%@');"
"document.getElementById(\"viewport\").setAttribute(\"content\", \"width=%i;initial-scale=1; maximum-scale=1.0; user-scalable=0;\");",
contentWidthClass,
contentWidth];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
- (IBAction)toggleFontSize:(id)sender {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (popoverController == nil) {
popoverController = [[UIPopoverController alloc]
initWithContentViewController:appDelegate.fontSettingsViewController];
popoverController.delegate = self;
} else {
if (popoverController.isPopoverVisible) {
[popoverController dismissPopoverAnimated:YES];
return;
}
[popoverController setContentViewController:appDelegate.fontSettingsViewController];
}
[popoverController setPopoverContentSize:CGSizeMake(274.0, 130.0)];
[popoverController presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
} else {
FontSettingsViewController *fontSettings = [[FontSettingsViewController alloc] init];
appDelegate.fontSettingsViewController = fontSettings;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:appDelegate.fontSettingsViewController];
// adding Done button
UIBarButtonItem *donebutton = [[UIBarButtonItem alloc]
initWithTitle:@"Done"
style:UIBarButtonItemStyleDone
target:self
action:@selector(hideToggleFontSize)];
appDelegate.fontSettingsViewController.navigationItem.rightBarButtonItem = donebutton;
appDelegate.fontSettingsViewController.navigationItem.title = @"Style";
navController.navigationBar.tintColor = [UIColor colorWithRed:0.16f green:0.36f blue:0.46 alpha:0.9];
[self presentModalViewController:navController animated:YES];
}
}
- (void)hideToggleFontSize {
[self dismissModalViewControllerAnimated:YES];
}
- (void)changeFontSize:(NSString *)fontSize {
NSString *jsString = [[NSString alloc] initWithFormat:@"document.getElementById('NB-font-size').setAttribute('class', '%@')",
fontSize];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
- (void)setFontStyle:(NSString *)fontStyle {
NSString *jsString;
NSString *fontStyleStr;
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
if ([fontStyle isEqualToString:@"Helvetica"]) {
[userPreferences setObject:@"NB-san-serif" forKey:@"fontStyle"];
fontStyleStr = @"NB-san-serif";
} else {
[userPreferences setObject:@"NB-serif" forKey:@"fontStyle"];
fontStyleStr = @"NB-serif";
}
[userPreferences synchronize];
jsString = [NSString stringWithFormat:@
"document.getElementById('NB-font-style').setAttribute('class', '%@')",
fontStyleStr];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
- (void)showOriginalSubview:(id)sender {
NSURL *url = [NSURL URLWithString:[appDelegate.activeStory
objectForKey:@"story_permalink"]];
[appDelegate showOriginalStory:url];
}
- (NSString *)textToHtml:(NSString*)htmlString {
htmlString = [htmlString stringByReplacingOccurrencesOfString:@"'" withString:@"'"];
return htmlString;
}
@end