2010-06-21 17:17:26 -04:00
|
|
|
//
|
|
|
|
// FeedDetailViewController.m
|
|
|
|
// NewsBlur
|
|
|
|
//
|
|
|
|
// Created by Samuel Clay on 6/20/10.
|
|
|
|
// Copyright 2010 NewsBlur. All rights reserved.
|
|
|
|
//
|
|
|
|
|
2011-10-26 08:40:31 -07:00
|
|
|
#import <QuartzCore/QuartzCore.h>
|
2010-06-21 17:17:26 -04:00
|
|
|
#import "FeedDetailViewController.h"
|
|
|
|
#import "NewsBlurAppDelegate.h"
|
2012-07-25 17:29:29 -07:00
|
|
|
#import "NBContainerViewController.h"
|
2010-07-15 00:44:38 -04:00
|
|
|
#import "FeedDetailTableCell.h"
|
2011-07-24 22:23:38 -07:00
|
|
|
#import "ASIFormDataRequest.h"
|
2012-07-12 22:05:23 -07:00
|
|
|
#import "UserProfileViewController.h"
|
2011-08-08 09:58:15 -07:00
|
|
|
#import "NSString+HTML.h"
|
2011-10-17 09:28:15 -07:00
|
|
|
#import "MBProgressHUD.h"
|
2011-09-05 22:06:31 -07:00
|
|
|
#import "Base64.h"
|
2010-06-24 00:22:26 -04:00
|
|
|
#import "JSON.h"
|
2011-10-26 08:40:31 -07:00
|
|
|
#import "StringHelper.h"
|
2011-10-17 09:37:16 -07:00
|
|
|
#import "Utilities.h"
|
2010-06-21 17:17:26 -04:00
|
|
|
|
2012-07-25 17:29:29 -07:00
|
|
|
|
2011-08-03 10:00:41 -07:00
|
|
|
#define kTableViewRowHeight 65;
|
2011-10-26 09:40:04 -07:00
|
|
|
#define kTableViewRiverRowHeight 81;
|
2011-11-05 16:25:04 -07:00
|
|
|
#define kMarkReadActionSheet 1;
|
|
|
|
#define kSettingsActionSheet 2;
|
2010-06-21 17:17:26 -04:00
|
|
|
|
|
|
|
@implementation FeedDetailViewController
|
|
|
|
|
2012-07-12 22:05:23 -07:00
|
|
|
@synthesize popoverController;
|
2010-11-22 10:44:52 -05:00
|
|
|
@synthesize storyTitlesTable, feedViewToolbar, feedScoreSlider, feedMarkReadButton;
|
2011-12-05 10:42:25 -08:00
|
|
|
@synthesize settingsButton;
|
2010-06-24 00:22:26 -04:00
|
|
|
@synthesize stories;
|
2010-06-21 17:17:26 -04:00
|
|
|
@synthesize appDelegate;
|
2011-07-20 22:21:11 -07:00
|
|
|
@synthesize feedPage;
|
|
|
|
@synthesize pageFetching;
|
2011-07-24 16:52:24 -07:00
|
|
|
@synthesize pageFinished;
|
2011-07-29 09:06:17 -07:00
|
|
|
@synthesize intelligenceControl;
|
2010-06-21 17:17:26 -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-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
2012-07-18 17:23:57 -07:00
|
|
|
|
2011-10-05 10:07:26 -07:00
|
|
|
- (void)viewDidLoad {
|
2011-08-18 09:56:52 -07:00
|
|
|
[super viewDidLoad];
|
|
|
|
}
|
|
|
|
|
2012-06-08 10:37:51 -07:00
|
|
|
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
2012-06-08 19:21:10 -07:00
|
|
|
return YES;
|
2012-06-08 10:37:51 -07:00
|
|
|
}
|
|
|
|
|
2012-06-29 23:25:56 -07:00
|
|
|
|
2012-07-09 21:26:53 -07:00
|
|
|
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
|
|
|
|
duration:(NSTimeInterval)duration {
|
|
|
|
/* When MGSplitViewController rotates, it causes a
|
|
|
|
resize of our view; we need to resize our UIBarButtonControls or they will be 0-width */
|
2012-06-29 23:25:56 -07:00
|
|
|
[self.navigationItem.titleView sizeToFit];
|
|
|
|
}
|
|
|
|
|
2012-07-18 17:23:57 -07:00
|
|
|
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
|
|
|
|
[self checkScroll];
|
|
|
|
}
|
|
|
|
|
2012-07-15 18:23:08 -07:00
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
2011-07-24 16:52:24 -07:00
|
|
|
self.pageFinished = NO;
|
2011-10-17 09:28:15 -07:00
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
2011-08-24 10:24:02 -07:00
|
|
|
|
2012-07-23 10:57:11 -07:00
|
|
|
// if (appDelegate.isRiverView || appDelegate.isSocialView) {
|
|
|
|
// self.storyTitlesTable.separatorStyle = UITableViewCellSeparatorStyleNone;
|
|
|
|
// //self.storyTitlesTable.separatorColor = [UIColor clearColor];
|
|
|
|
// } else {
|
|
|
|
// self.storyTitlesTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
|
|
|
|
// self.storyTitlesTable.separatorColor = [UIColor colorWithRed:.9 green:.9 blue:.9 alpha:1.0];
|
|
|
|
// }
|
|
|
|
|
|
|
|
self.storyTitlesTable.separatorStyle = UITableViewCellSeparatorStyleNone;
|
|
|
|
|
2011-08-24 10:24:02 -07:00
|
|
|
|
2012-07-12 22:05:23 -07:00
|
|
|
// set center title
|
|
|
|
UIView *titleLabel = [appDelegate makeFeedTitle:appDelegate.activeFeed];
|
2012-06-27 14:37:37 -07:00
|
|
|
self.navigationItem.titleView = titleLabel;
|
2012-07-12 22:05:23 -07:00
|
|
|
|
|
|
|
// set right avatar title image
|
|
|
|
if (appDelegate.isSocialView) {
|
|
|
|
UIButton *titleImageButton = [appDelegate makeRightFeedTitle:appDelegate.activeFeed];
|
2012-07-25 17:29:29 -07:00
|
|
|
[titleImageButton addTarget:self action:@selector(showUserProfile) forControlEvents:UIControlEventTouchUpInside];
|
2012-07-15 15:06:06 -07:00
|
|
|
UIBarButtonItem *titleImageBarButton = [[UIBarButtonItem alloc]
|
|
|
|
initWithCustomView:titleImageButton];
|
2012-07-12 22:05:23 -07:00
|
|
|
self.navigationItem.rightBarButtonItem = titleImageBarButton;
|
|
|
|
} else {
|
|
|
|
self.navigationItem.rightBarButtonItem = nil;
|
|
|
|
}
|
2011-10-15 18:43:03 -07:00
|
|
|
|
2012-07-12 22:05:23 -07:00
|
|
|
|
2011-10-15 18:43:03 -07:00
|
|
|
// Commenting out until training is ready...
|
|
|
|
// UIBarButtonItem *trainBarButton = [UIBarButtonItem alloc];
|
|
|
|
// [trainBarButton setImage:[UIImage imageNamed:@"train.png"]];
|
|
|
|
// [trainBarButton setEnabled:YES];
|
|
|
|
// [self.navigationItem setRightBarButtonItem:trainBarButton animated:YES];
|
|
|
|
// [trainBarButton release];
|
2011-07-24 21:47:58 -07:00
|
|
|
|
|
|
|
NSMutableArray *indexPaths = [NSMutableArray array];
|
|
|
|
for (id i in appDelegate.recentlyReadStories) {
|
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[i intValue]
|
|
|
|
inSection:0];
|
2011-08-16 19:55:44 -07:00
|
|
|
// NSLog(@"Read story: %d", [i intValue]);
|
2011-07-24 21:47:58 -07:00
|
|
|
[indexPaths addObject:indexPath];
|
|
|
|
}
|
|
|
|
if ([indexPaths count] > 0) {
|
|
|
|
[self.storyTitlesTable beginUpdates];
|
|
|
|
[self.storyTitlesTable reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
[self.storyTitlesTable endUpdates];
|
2012-06-29 10:20:06 -07:00
|
|
|
//[self.storyTitlesTable reloadData];
|
2011-07-24 21:47:58 -07:00
|
|
|
}
|
2011-08-08 09:58:15 -07:00
|
|
|
[appDelegate setRecentlyReadStories:[NSMutableArray array]];
|
2012-06-21 11:53:48 -07:00
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullets_all.png"] forSegmentAtIndex:0];
|
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullets_yellow_green.png"] forSegmentAtIndex:1];
|
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullet_green.png"] forSegmentAtIndex:2];
|
2011-07-29 09:06:17 -07:00
|
|
|
[self.intelligenceControl addTarget:self
|
|
|
|
action:@selector(selectIntelligence)
|
|
|
|
forControlEvents:UIControlEventValueChanged];
|
2012-07-13 21:31:48 -07:00
|
|
|
[self.intelligenceControl setSelectedSegmentIndex:[appDelegate selectedIntelligence] + 1];
|
2011-10-30 18:53:10 -07:00
|
|
|
|
2010-06-24 12:53:50 -04:00
|
|
|
[super viewWillAppear:animated];
|
2012-06-15 19:12:48 -07:00
|
|
|
|
2012-07-09 21:26:53 -07:00
|
|
|
if ((appDelegate.isRiverView || appDelegate.isSocialView) ||
|
|
|
|
[appDelegate.activeFolder isEqualToString:@"Everything"]) {
|
2011-12-05 10:42:25 -08:00
|
|
|
settingsButton.enabled = NO;
|
|
|
|
} else {
|
|
|
|
settingsButton.enabled = YES;
|
2012-07-16 19:45:14 -07:00
|
|
|
}
|
2010-06-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
|
2012-07-12 22:05:23 -07:00
|
|
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
|
|
[super viewWillDisappear:animated];
|
|
|
|
[self.popoverController dismissPopoverAnimated:YES];
|
|
|
|
}
|
|
|
|
|
2012-06-29 10:20:06 -07:00
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
2010-06-21 17:17:26 -04:00
|
|
|
[super viewDidAppear:animated];
|
2012-07-15 16:46:46 -07:00
|
|
|
|
|
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
|
|
|
|
// have the selected cell deselect
|
|
|
|
[self.storyTitlesTable deselectRowAtIndexPath:[self.storyTitlesTable indexPathForSelectedRow]
|
|
|
|
animated:YES];
|
|
|
|
}
|
2010-06-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
2010-06-24 00:22:26 -04:00
|
|
|
#pragma mark Initialization
|
|
|
|
|
2011-09-06 17:51:02 -07:00
|
|
|
- (void)resetFeedDetail {
|
|
|
|
self.pageFetching = NO;
|
|
|
|
self.pageFinished = NO;
|
|
|
|
self.feedPage = 1;
|
|
|
|
}
|
|
|
|
|
2012-06-29 10:20:06 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Regular and Social Feeds
|
|
|
|
|
2011-09-05 22:06:31 -07:00
|
|
|
- (void)fetchNextPage:(void(^)())callback {
|
|
|
|
[self fetchFeedDetail:self.feedPage+1 withCallback:callback];
|
|
|
|
}
|
|
|
|
|
2012-07-16 10:10:52 -07:00
|
|
|
- (void)fetchFeedDetail:(int)page withCallback:(void(^)())callback {
|
2012-06-25 15:02:20 -07:00
|
|
|
NSString *theFeedDetailURL;
|
|
|
|
|
2012-07-16 19:45:14 -07:00
|
|
|
if (!self.pageFetching && !self.pageFinished) {
|
|
|
|
|
2011-07-20 22:21:11 -07:00
|
|
|
self.feedPage = page;
|
|
|
|
self.pageFetching = YES;
|
2011-07-24 16:52:24 -07:00
|
|
|
int storyCount = appDelegate.storyCount;
|
|
|
|
if (storyCount == 0) {
|
|
|
|
[self.storyTitlesTable reloadData];
|
2011-07-22 09:10:13 -07:00
|
|
|
[storyTitlesTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
|
|
|
|
}
|
2012-06-26 16:24:19 -07:00
|
|
|
if (appDelegate.isSocialView) {
|
2012-07-15 21:52:25 -07:00
|
|
|
theFeedDetailURL = [NSString stringWithFormat:@"http://%@/social/stories/%@/?page=%d",
|
2012-06-25 15:02:20 -07:00
|
|
|
NEWSBLUR_URL,
|
|
|
|
[appDelegate.activeFeed objectForKey:@"user_id"],
|
|
|
|
self.feedPage];
|
|
|
|
} else {
|
2012-07-15 21:52:25 -07:00
|
|
|
theFeedDetailURL = [NSString stringWithFormat:@"http://%@/reader/feed/%@/?page=%d",
|
2012-06-25 15:02:20 -07:00
|
|
|
NEWSBLUR_URL,
|
|
|
|
[appDelegate.activeFeed objectForKey:@"id"],
|
|
|
|
self.feedPage];
|
|
|
|
}
|
2011-11-30 09:38:31 -08:00
|
|
|
[self cancelRequests];
|
2012-07-15 15:06:06 -07:00
|
|
|
__weak ASIHTTPRequest *request = [self requestWithURL:theFeedDetailURL];
|
2011-09-05 22:06:31 -07:00
|
|
|
[request setDelegate:self];
|
|
|
|
[request setResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setFailedBlock:^(void) {
|
2012-07-12 00:10:42 -07:00
|
|
|
NSLog(@"in failed block %@", request);
|
2011-11-30 09:38:31 -08:00
|
|
|
[self informError:[request error]];
|
2011-09-05 22:06:31 -07:00
|
|
|
}];
|
|
|
|
[request setCompletionBlock:^(void) {
|
|
|
|
[self finishedLoadingFeed:request];
|
|
|
|
if (callback) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}];
|
2012-07-12 00:10:42 -07:00
|
|
|
[request setTimeOutSeconds:10];
|
2011-09-05 22:06:31 -07:00
|
|
|
[request setTag:[[[appDelegate activeFeed] objectForKey:@"id"] intValue]];
|
|
|
|
[request startAsynchronous];
|
|
|
|
}
|
2010-07-15 23:32:37 -04:00
|
|
|
}
|
|
|
|
|
2012-06-29 10:20:06 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark River of News
|
|
|
|
|
2012-07-16 10:10:52 -07:00
|
|
|
- (void)fetchRiverPage:(int)page withCallback:(void(^)())callback {
|
2012-06-29 10:20:06 -07:00
|
|
|
if (!self.pageFetching && !self.pageFinished) {
|
|
|
|
self.feedPage = page;
|
|
|
|
self.pageFetching = YES;
|
|
|
|
int storyCount = appDelegate.storyCount;
|
|
|
|
if (storyCount == 0) {
|
|
|
|
[self.storyTitlesTable reloadData];
|
|
|
|
[storyTitlesTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
|
|
|
|
}
|
|
|
|
int readStoriesCount = 0;
|
|
|
|
if (self.feedPage > 1) {
|
|
|
|
for (id story in appDelegate.activeFeedStories) {
|
|
|
|
if ([[story objectForKey:@"read_status"] intValue] == 1) {
|
|
|
|
readStoriesCount += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-09 21:26:53 -07:00
|
|
|
NSString *theFeedDetailURL = [NSString stringWithFormat:
|
|
|
|
@"http://%@/reader/river_stories/?feeds=%@&page=%d&read_stories_count=%d",
|
2012-06-29 10:20:06 -07:00
|
|
|
NEWSBLUR_URL,
|
|
|
|
[appDelegate.activeFolderFeeds componentsJoinedByString:@"&feeds="],
|
|
|
|
self.feedPage,
|
|
|
|
readStoriesCount];
|
|
|
|
|
|
|
|
[self cancelRequests];
|
2012-07-15 15:06:06 -07:00
|
|
|
__weak ASIHTTPRequest *request = [self requestWithURL:theFeedDetailURL];
|
2012-07-16 22:35:28 -07:00
|
|
|
NSLog(@"theFeedDetailURL is %@", theFeedDetailURL);
|
2012-06-29 10:20:06 -07:00
|
|
|
[request setDelegate:self];
|
|
|
|
[request setResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setFailedBlock:^(void) {
|
|
|
|
[self informError:[request error]];
|
|
|
|
}];
|
|
|
|
[request setCompletionBlock:^(void) {
|
|
|
|
[self finishedLoadingFeed:request];
|
|
|
|
if (callback) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
[request setTimeOutSeconds:30];
|
|
|
|
[request startAsynchronous];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Processing Stories
|
|
|
|
|
2011-09-05 22:06:31 -07:00
|
|
|
- (void)finishedLoadingFeed:(ASIHTTPRequest *)request {
|
2011-11-30 09:38:31 -08:00
|
|
|
if ([request responseStatusCode] >= 500) {
|
|
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.15 * NSEC_PER_SEC),
|
|
|
|
dispatch_get_current_queue(), ^{
|
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
|
|
|
});
|
|
|
|
[self informError:@"The server barfed!"];
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2012-06-19 15:47:51 -07:00
|
|
|
|
2011-09-05 22:06:31 -07:00
|
|
|
NSString *responseString = [request responseString];
|
2010-06-24 12:53:50 -04:00
|
|
|
NSDictionary *results = [[NSDictionary alloc]
|
2012-06-26 16:24:19 -07:00
|
|
|
initWithDictionary:[responseString JSONValue]];
|
2012-07-16 19:45:14 -07:00
|
|
|
|
2012-06-26 16:24:19 -07:00
|
|
|
if (!(appDelegate.isRiverView || appDelegate.isSocialView) && request.tag != [[results objectForKey:@"feed_id"] intValue]) {
|
2011-10-26 20:09:28 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-26 16:24:19 -07:00
|
|
|
if ([appDelegate isSocialView]) {
|
|
|
|
NSArray *newFeeds = [results objectForKey:@"feeds"];
|
|
|
|
for (int i = 0; i < newFeeds.count; i++){
|
|
|
|
NSString *feedKey = [NSString stringWithFormat:@"%@", [[newFeeds objectAtIndex:i] objectForKey:@"id"]];
|
|
|
|
[appDelegate.dictActiveFeeds setObject:[newFeeds objectAtIndex:i]
|
|
|
|
forKey:feedKey];
|
|
|
|
}
|
2012-06-29 10:20:06 -07:00
|
|
|
[self loadFaviconsFromActiveFeed];
|
2012-06-26 16:24:19 -07:00
|
|
|
}
|
2012-07-16 19:45:14 -07:00
|
|
|
|
2011-10-26 20:09:28 -07:00
|
|
|
NSArray *newStories = [results objectForKey:@"stories"];
|
|
|
|
NSMutableArray *confirmedNewStories = [NSMutableArray array];
|
|
|
|
if ([appDelegate.activeFeedStories count]) {
|
|
|
|
NSMutableSet *storyIds = [NSMutableSet set];
|
|
|
|
for (id story in appDelegate.activeFeedStories) {
|
|
|
|
[storyIds addObject:[story objectForKey:@"id"]];
|
|
|
|
}
|
|
|
|
for (id story in newStories) {
|
|
|
|
if (![storyIds containsObject:[story objectForKey:@"id"]]) {
|
|
|
|
[confirmedNewStories addObject:story];
|
2011-10-26 09:05:59 -07:00
|
|
|
}
|
|
|
|
}
|
2011-10-26 20:09:28 -07:00
|
|
|
} else {
|
2012-07-15 15:06:06 -07:00
|
|
|
confirmedNewStories = [newStories copy];
|
2011-09-06 17:51:02 -07:00
|
|
|
}
|
2012-06-22 18:01:08 -07:00
|
|
|
|
|
|
|
// Adding new user profiles to appDelegate.activeFeedUserProfiles
|
|
|
|
NSArray *newUserProfiles = [results objectForKey:@"user_profiles"];
|
2012-07-20 00:21:24 -07:00
|
|
|
|
|
|
|
// add self to user profiles
|
|
|
|
if (self.feedPage == 1) {
|
|
|
|
newUserProfiles = [newUserProfiles arrayByAddingObject:appDelegate.dictUserProfile];
|
|
|
|
}
|
|
|
|
|
2012-06-22 18:01:08 -07:00
|
|
|
if ([newUserProfiles count]){
|
|
|
|
NSMutableArray *confirmedNewUserProfiles = [NSMutableArray array];
|
|
|
|
if ([appDelegate.activeFeedUserProfiles count]) {
|
|
|
|
NSMutableSet *userProfileIds = [NSMutableSet set];
|
|
|
|
for (id userProfile in appDelegate.activeFeedUserProfiles) {
|
|
|
|
[userProfileIds addObject:[userProfile objectForKey:@"id"]];
|
|
|
|
}
|
|
|
|
for (id userProfile in newUserProfiles) {
|
|
|
|
if (![userProfileIds containsObject:[userProfile objectForKey:@"id"]]) {
|
|
|
|
[confirmedNewUserProfiles addObject:userProfile];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2012-07-15 15:06:06 -07:00
|
|
|
confirmedNewUserProfiles = [newUserProfiles copy];
|
2012-06-22 18:01:08 -07:00
|
|
|
}
|
|
|
|
|
2012-07-16 10:10:52 -07:00
|
|
|
|
|
|
|
if (self.feedPage == 1) {
|
|
|
|
[appDelegate setFeedUserProfiles:confirmedNewUserProfiles];
|
|
|
|
} else if (newUserProfiles.count > 0) {
|
|
|
|
[appDelegate addFeedUserProfiles:confirmedNewUserProfiles];
|
|
|
|
}
|
|
|
|
|
2012-07-15 18:23:08 -07:00
|
|
|
// NSLog(@"activeFeedUserProfiles is %@", appDelegate.activeFeedUserProfiles);
|
2012-07-01 21:58:55 -07:00
|
|
|
// NSLog(@"# of user profiles added: %i", appDelegate.activeFeedUserProfiles.count);
|
|
|
|
// NSLog(@"user profiles added: %@", appDelegate.activeFeedUserProfiles);
|
2012-06-22 18:01:08 -07:00
|
|
|
}
|
|
|
|
|
2011-10-26 20:09:28 -07:00
|
|
|
[self renderStories:confirmedNewStories];
|
2011-08-21 13:46:43 -07:00
|
|
|
}
|
|
|
|
|
2011-10-25 09:47:55 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Stories
|
|
|
|
|
2011-08-21 13:46:43 -07:00
|
|
|
- (void)renderStories:(NSArray *)newStories {
|
2011-07-29 21:27:37 -07:00
|
|
|
NSInteger existingStoriesCount = [[appDelegate activeFeedStoryLocations] count];
|
2011-08-09 17:58:43 -07:00
|
|
|
NSInteger newStoriesCount = [newStories count];
|
2011-07-22 09:10:13 -07:00
|
|
|
|
2011-07-20 22:21:11 -07:00
|
|
|
if (self.feedPage == 1) {
|
2011-07-24 16:52:24 -07:00
|
|
|
[appDelegate setStories:newStories];
|
2011-08-09 17:58:43 -07:00
|
|
|
} else if (newStoriesCount > 0) {
|
2011-07-24 16:52:24 -07:00
|
|
|
[appDelegate addStories:newStories];
|
2011-07-22 09:10:13 -07:00
|
|
|
}
|
2011-07-24 16:52:24 -07:00
|
|
|
|
2011-08-09 17:58:43 -07:00
|
|
|
NSInteger newVisibleStoriesCount = [[appDelegate activeFeedStoryLocations] count] - existingStoriesCount;
|
2011-07-29 21:27:37 -07:00
|
|
|
|
2011-08-09 17:58:43 -07:00
|
|
|
if (existingStoriesCount > 0 && newVisibleStoriesCount > 0) {
|
2011-07-24 16:52:24 -07:00
|
|
|
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
|
2011-08-09 17:58:43 -07:00
|
|
|
for (int i=0; i < newVisibleStoriesCount; i++) {
|
2011-07-29 21:56:54 -07:00
|
|
|
[indexPaths addObject:[NSIndexPath indexPathForRow:(existingStoriesCount+i)
|
|
|
|
inSection:0]];
|
2011-07-22 09:10:13 -07:00
|
|
|
}
|
2012-06-30 12:05:49 -07:00
|
|
|
|
2012-07-15 19:51:05 -07:00
|
|
|
[self.storyTitlesTable reloadData];
|
2012-06-30 12:05:49 -07:00
|
|
|
|
2011-08-09 17:58:43 -07:00
|
|
|
} else if (newVisibleStoriesCount > 0) {
|
2011-07-22 09:10:13 -07:00
|
|
|
[self.storyTitlesTable reloadData];
|
2012-07-01 23:40:11 -07:00
|
|
|
|
2011-08-09 17:58:43 -07:00
|
|
|
} else if (newStoriesCount == 0 ||
|
|
|
|
(self.feedPage > 15 &&
|
|
|
|
existingStoriesCount >= [appDelegate unreadCount])) {
|
2011-07-24 16:52:24 -07:00
|
|
|
self.pageFinished = YES;
|
2012-07-15 19:51:05 -07:00
|
|
|
[self.storyTitlesTable reloadData];
|
2011-07-20 22:21:11 -07:00
|
|
|
}
|
2012-07-01 23:40:11 -07:00
|
|
|
|
2011-07-20 22:21:11 -07:00
|
|
|
self.pageFetching = NO;
|
2011-07-24 16:52:24 -07:00
|
|
|
|
2012-07-16 19:45:14 -07:00
|
|
|
// test for tryfeed
|
2012-07-16 22:35:28 -07:00
|
|
|
if (appDelegate.inFindingStoryMode && appDelegate.tryFeedStoryId) {
|
2012-07-16 19:45:14 -07:00
|
|
|
for (int i = 0; i < appDelegate.activeFeedStories.count; i++) {
|
|
|
|
NSString *storyIdStr = [[appDelegate.activeFeedStories objectAtIndex:i] objectForKey:@"id"];
|
|
|
|
if ([storyIdStr isEqualToString:appDelegate.tryFeedStoryId]) {
|
|
|
|
NSDictionary *feed = [appDelegate.activeFeedStories objectAtIndex:i];
|
|
|
|
|
|
|
|
int score = [NewsBlurAppDelegate computeStoryScore:[feed objectForKey:@"intelligence"]];
|
|
|
|
|
|
|
|
if (score < appDelegate.selectedIntelligence) {
|
|
|
|
[self changeIntelligence:score];
|
|
|
|
}
|
|
|
|
int locationOfStoryId = [appDelegate locationOfStoryId:storyIdStr];
|
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:locationOfStoryId inSection:0];
|
|
|
|
|
|
|
|
[self.storyTitlesTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionBottom];
|
|
|
|
|
2012-07-23 10:57:11 -07:00
|
|
|
FeedDetailTableCell *cell = (FeedDetailTableCell *)[self.storyTitlesTable cellForRowAtIndexPath:indexPath];
|
2012-07-16 19:45:14 -07:00
|
|
|
[self loadStory:cell atRow:indexPath.row];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-29 21:56:54 -07:00
|
|
|
[self performSelector:@selector(checkScroll)
|
|
|
|
withObject:nil
|
2011-08-13 23:00:51 -07:00
|
|
|
afterDelay:0.2];
|
2010-06-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
|
2011-07-24 20:34:54 -07:00
|
|
|
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
2010-07-15 23:32:37 -04:00
|
|
|
|
|
|
|
// inform the user
|
2010-11-15 19:40:17 -05:00
|
|
|
NSLog(@"Connection failed! Error - %@",
|
|
|
|
[error localizedDescription]);
|
2011-07-20 22:21:11 -07:00
|
|
|
|
|
|
|
self.pageFetching = NO;
|
2011-08-18 09:56:52 -07:00
|
|
|
|
|
|
|
// User clicking on another link before the page loads is OK.
|
|
|
|
if ([error code] != NSURLErrorCancelled) {
|
2011-10-27 09:44:58 -07:00
|
|
|
[self informError:error];
|
2011-08-18 09:56:52 -07:00
|
|
|
}
|
2010-07-15 23:32:37 -04:00
|
|
|
}
|
|
|
|
|
2011-07-24 16:52:24 -07:00
|
|
|
- (UITableViewCell *)makeLoadingCell {
|
2012-07-15 15:06:06 -07:00
|
|
|
UITableViewCell *cell = [[UITableViewCell alloc]
|
2011-07-24 20:34:54 -07:00
|
|
|
initWithStyle:UITableViewCellStyleSubtitle
|
2012-07-15 15:06:06 -07:00
|
|
|
reuseIdentifier:@"NoReuse"];
|
2011-07-24 16:52:24 -07:00
|
|
|
|
2011-07-24 17:18:05 -07:00
|
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
|
|
|
2011-07-24 16:52:24 -07:00
|
|
|
if (self.pageFinished) {
|
2012-07-09 18:17:01 -07:00
|
|
|
UIImage *img = [UIImage imageNamed:@"fleuron.png"];
|
|
|
|
UIImageView *fleuron = [[UIImageView alloc] initWithImage:img];
|
|
|
|
int height = 0;
|
|
|
|
|
|
|
|
if (appDelegate.isRiverView || appDelegate.isSocialView) {
|
|
|
|
height = kTableViewRiverRowHeight;
|
|
|
|
} else {
|
|
|
|
height = kTableViewRowHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
fleuron.frame = CGRectMake(0, 0, self.view.frame.size.width, height);
|
|
|
|
fleuron.contentMode = UIViewContentModeCenter;
|
|
|
|
[cell.contentView addSubview:fleuron];
|
|
|
|
fleuron.backgroundColor = [UIColor whiteColor];
|
2011-07-24 16:52:24 -07:00
|
|
|
} else {
|
|
|
|
cell.textLabel.text = @"Loading...";
|
|
|
|
|
2012-07-15 15:06:06 -07:00
|
|
|
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
|
|
|
|
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
2011-07-24 16:52:24 -07:00
|
|
|
UIImage *spacer = [UIImage imageNamed:@"spacer"];
|
2011-07-29 21:56:54 -07:00
|
|
|
UIGraphicsBeginImageContext(spinner.frame.size);
|
2011-07-24 16:52:24 -07:00
|
|
|
[spacer drawInRect:CGRectMake(0,0,spinner.frame.size.width,spinner.frame.size.height)];
|
|
|
|
UIImage* resizedSpacer = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
|
UIGraphicsEndImageContext();
|
|
|
|
cell.imageView.image = resizedSpacer;
|
|
|
|
[cell.imageView addSubview:spinner];
|
|
|
|
[spinner startAnimating];
|
|
|
|
}
|
|
|
|
|
2012-07-23 16:17:49 -07:00
|
|
|
UIView *topBorder = [[UIView alloc] init];
|
|
|
|
topBorder.frame = CGRectMake(0, 0, self.view.frame.size.width, 1);
|
|
|
|
topBorder.backgroundColor = [UIColor colorWithRed:.9 green:.9 blue:.9 alpha:1.0];
|
|
|
|
[cell addSubview:topBorder];
|
|
|
|
|
2011-07-24 16:52:24 -07:00
|
|
|
return cell;
|
|
|
|
}
|
2010-06-21 17:17:26 -04:00
|
|
|
|
2010-06-24 00:22:26 -04:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Table View - Feed List
|
2010-06-21 17:17:26 -04:00
|
|
|
|
2012-06-15 19:12:48 -07:00
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
|
|
|
int storyCount = [[appDelegate activeFeedStoryLocations] count];
|
2011-08-21 13:46:43 -07:00
|
|
|
|
2012-06-15 19:12:48 -07:00
|
|
|
// The +1 is for the finished/loading bar.
|
|
|
|
return storyCount + 1;
|
2010-06-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
|
2011-08-13 17:08:26 -07:00
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView
|
|
|
|
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
2012-06-29 10:20:06 -07:00
|
|
|
|
2012-07-22 17:21:32 -07:00
|
|
|
NSString *cellIdentifier;
|
2012-06-26 16:24:19 -07:00
|
|
|
NSDictionary *feed ;
|
|
|
|
|
|
|
|
if (appDelegate.isRiverView || appDelegate.isSocialView) {
|
2011-10-26 20:09:28 -07:00
|
|
|
cellIdentifier = @"FeedRiverDetailCellIdentifier";
|
2011-10-25 09:28:05 -07:00
|
|
|
} else {
|
|
|
|
cellIdentifier = @"FeedDetailCellIdentifier";
|
|
|
|
}
|
|
|
|
|
2012-07-22 17:08:29 -07:00
|
|
|
// FeedDetailTableCell *cell = (FeedDetailTableCell *)[tableView
|
|
|
|
// dequeueReusableCellWithIdentifier:cellIdentifier];
|
|
|
|
// if (cell == nil) {
|
|
|
|
// NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FeedDetailTableCell"
|
|
|
|
// owner:self
|
|
|
|
// options:nil];
|
|
|
|
// for (id oneObject in nib) {
|
|
|
|
// if ([oneObject isKindOfClass:[FeedDetailTableCell class]]) {
|
|
|
|
// if (([(FeedDetailTableCell *)oneObject tag] == 0 && !(appDelegate.isRiverView || appDelegate.isSocialView)) ||
|
|
|
|
// ([(FeedDetailTableCell *)oneObject tag] == 1 && (appDelegate.isRiverView || appDelegate.isSocialView))) {
|
|
|
|
// cell = (FeedDetailTableCell *)oneObject;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
2011-10-25 09:28:05 -07:00
|
|
|
FeedDetailTableCell *cell = (FeedDetailTableCell *)[tableView
|
2012-07-22 17:08:29 -07:00
|
|
|
dequeueReusableCellWithIdentifier:cellIdentifier];
|
|
|
|
if (cell == nil) {
|
|
|
|
cell = [[FeedDetailTableCell alloc] initWithStyle:UITableViewCellStyleDefault
|
2012-07-22 17:21:32 -07:00
|
|
|
reuseIdentifier:nil];
|
2012-07-22 17:08:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-29 21:27:37 -07:00
|
|
|
if (indexPath.row >= [[appDelegate activeFeedStoryLocations] count]) {
|
2011-07-24 16:52:24 -07:00
|
|
|
return [self makeLoadingCell];
|
|
|
|
}
|
2012-07-01 23:40:11 -07:00
|
|
|
|
2011-07-29 09:06:17 -07:00
|
|
|
NSDictionary *story = [self getStoryAtRow:indexPath.row];
|
2012-06-26 16:24:19 -07:00
|
|
|
|
2011-10-26 20:09:28 -07:00
|
|
|
id feedId = [story objectForKey:@"story_feed_id"];
|
2012-06-26 16:24:19 -07:00
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@", feedId];
|
|
|
|
|
|
|
|
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];
|
|
|
|
}
|
2012-07-22 17:08:29 -07:00
|
|
|
|
|
|
|
NSString *siteTitle = [feed objectForKey:@"feed_title"];
|
|
|
|
cell.siteTitle = siteTitle;
|
|
|
|
|
|
|
|
NSString *title = [story objectForKey:@"story_title"];
|
|
|
|
cell.storyTitle = [title stringByDecodingHTMLEntities];
|
|
|
|
|
|
|
|
cell.storyDate = [story objectForKey:@"short_parsed_date"];
|
2011-10-26 20:09:28 -07:00
|
|
|
|
2010-07-15 00:44:38 -04:00
|
|
|
if ([[story objectForKey:@"story_authors"] class] != [NSNull class]) {
|
2012-07-22 17:08:29 -07:00
|
|
|
cell.storyAuthor = [[story objectForKey:@"story_authors"] uppercaseString];
|
2010-07-15 00:44:38 -04:00
|
|
|
} else {
|
2012-07-22 17:08:29 -07:00
|
|
|
cell.storyAuthor = @"";
|
2011-10-27 19:05:38 -07:00
|
|
|
}
|
2012-06-26 16:24:19 -07:00
|
|
|
|
2012-07-22 17:08:29 -07:00
|
|
|
// feed color bar border
|
|
|
|
unsigned int colorBorder = 0;
|
|
|
|
NSString *faviconColor = [feed valueForKey:@"favicon_color"];
|
2010-07-15 00:44:38 -04:00
|
|
|
|
2012-07-22 17:08:29 -07:00
|
|
|
if ([faviconColor class] == [NSNull class]) {
|
|
|
|
faviconColor = @"505050";
|
|
|
|
}
|
|
|
|
NSScanner *scannerBorder = [NSScanner scannerWithString:faviconColor];
|
|
|
|
[scannerBorder scanHexInt:&colorBorder];
|
2010-06-21 17:17:26 -04:00
|
|
|
|
2012-07-22 17:08:29 -07:00
|
|
|
cell.feedColorBar = UIColorFromRGB(colorBorder);
|
2012-07-22 14:23:50 -07:00
|
|
|
|
2012-07-22 17:08:29 -07:00
|
|
|
// feed color bar border
|
2012-07-22 14:23:50 -07:00
|
|
|
NSString *faviconFade = [feed valueForKey:@"favicon_fade"];
|
|
|
|
if ([faviconFade class] == [NSNull class]) {
|
|
|
|
faviconFade = @"505050";
|
|
|
|
}
|
2012-07-22 17:08:29 -07:00
|
|
|
scannerBorder = [NSScanner scannerWithString:faviconFade];
|
2012-07-22 14:23:50 -07:00
|
|
|
[scannerBorder scanHexInt:&colorBorder];
|
2012-07-22 17:08:29 -07:00
|
|
|
cell.feedColorBarTopBorder = UIColorFromRGB(colorBorder);
|
|
|
|
|
|
|
|
// favicon
|
|
|
|
cell.siteFavicon = [Utilities getImage:feedIdStr];
|
|
|
|
|
|
|
|
// undread indicator
|
|
|
|
|
|
|
|
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
|
|
|
|
if (score > 0) {
|
|
|
|
cell.storyUnreadIndicator = [UIImage imageNamed:@"bullet_green.png"];
|
|
|
|
} else if (score == 0) {
|
|
|
|
cell.storyUnreadIndicator = [UIImage imageNamed:@"bullet_yellow.png"];
|
|
|
|
} else if (score < 0) {
|
|
|
|
cell.storyUnreadIndicator = [UIImage imageNamed:@"bullet_red.png"];
|
2012-07-22 14:23:50 -07:00
|
|
|
}
|
2012-07-22 17:08:29 -07:00
|
|
|
|
|
|
|
cell.isRead = [[story objectForKey:@"read_status"] intValue] == 1;
|
2012-07-22 14:23:50 -07:00
|
|
|
|
2012-07-23 10:57:11 -07:00
|
|
|
if (appDelegate.isRiverView || appDelegate.isSocialView) {
|
|
|
|
cell.isRiverOrSocial = YES;
|
|
|
|
}
|
2012-07-22 14:23:50 -07:00
|
|
|
|
2012-07-23 10:57:11 -07:00
|
|
|
int rowIndex = [appDelegate locationOfActiveStory];
|
|
|
|
if (rowIndex == indexPath.row) {
|
|
|
|
[self.storyTitlesTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
|
|
|
|
}
|
2012-07-22 17:08:29 -07:00
|
|
|
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
2012-07-23 10:57:11 -07:00
|
|
|
- (void)loadStory:(FeedDetailTableCell *)cell atRow:(int)row {
|
|
|
|
cell.isRead = YES;
|
|
|
|
[cell setNeedsLayout];
|
2012-07-16 19:45:14 -07:00
|
|
|
[appDelegate setActiveStory:[[appDelegate activeFeedStories] objectAtIndex:row]];
|
|
|
|
[appDelegate setOriginalStoryCount:[appDelegate unreadCount]];
|
|
|
|
[appDelegate loadStoryDetailView];
|
|
|
|
}
|
|
|
|
|
2010-06-21 17:17:26 -04:00
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
2011-08-14 10:22:26 -07:00
|
|
|
if (indexPath.row < [appDelegate.activeFeedStoryLocations count]) {
|
2012-07-23 10:57:11 -07:00
|
|
|
FeedDetailTableCell *cell = (FeedDetailTableCell*) [tableView cellForRowAtIndexPath:indexPath];
|
2011-07-29 21:56:54 -07:00
|
|
|
int location = [[[appDelegate activeFeedStoryLocations] objectAtIndex:indexPath.row] intValue];
|
2012-07-16 19:45:14 -07:00
|
|
|
[self loadStory:cell atRow:location];
|
2011-07-24 16:52:24 -07:00
|
|
|
}
|
2010-06-21 17:17:26 -04:00
|
|
|
}
|
|
|
|
|
2010-07-15 00:44:38 -04:00
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
2012-07-01 23:40:11 -07:00
|
|
|
if (appDelegate.isRiverView || appDelegate.isSocialView) {
|
|
|
|
return kTableViewRiverRowHeight;
|
2011-07-24 16:52:24 -07:00
|
|
|
} else {
|
2012-07-01 23:40:11 -07:00
|
|
|
return kTableViewRowHeight;
|
2011-07-24 16:52:24 -07:00
|
|
|
}
|
2010-07-15 00:44:38 -04:00
|
|
|
}
|
|
|
|
|
2011-07-20 22:21:11 -07:00
|
|
|
- (void)scrollViewDidScroll: (UIScrollView *)scroll {
|
2011-07-29 21:56:54 -07:00
|
|
|
[self checkScroll];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)checkScroll {
|
|
|
|
NSInteger currentOffset = self.storyTitlesTable.contentOffset.y;
|
|
|
|
NSInteger maximumOffset = self.storyTitlesTable.contentSize.height - self.storyTitlesTable.frame.size.height;
|
2011-07-20 22:21:11 -07:00
|
|
|
|
2012-07-16 19:45:14 -07:00
|
|
|
if (maximumOffset - currentOffset <= 60.0 ||
|
2012-07-16 22:35:28 -07:00
|
|
|
(appDelegate.inFindingStoryMode)) {
|
2011-10-26 08:40:31 -07:00
|
|
|
if (appDelegate.isRiverView) {
|
|
|
|
[self fetchRiverPage:self.feedPage+1 withCallback:nil];
|
|
|
|
} else {
|
|
|
|
[self fetchFeedDetail:self.feedPage+1 withCallback:nil];
|
|
|
|
}
|
2011-07-20 22:21:11 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-29 09:06:17 -07:00
|
|
|
- (IBAction)selectIntelligence {
|
|
|
|
NSInteger newLevel = [self.intelligenceControl selectedSegmentIndex] - 1;
|
2012-07-16 19:45:14 -07:00
|
|
|
[self changeIntelligence:newLevel];
|
|
|
|
|
|
|
|
[self performSelector:@selector(checkScroll)
|
|
|
|
withObject:nil
|
|
|
|
afterDelay:1.0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)changeIntelligence:(NSInteger)newLevel {
|
2011-07-29 09:06:17 -07:00
|
|
|
NSInteger previousLevel = [appDelegate selectedIntelligence];
|
|
|
|
NSMutableArray *insertIndexPaths = [NSMutableArray array];
|
|
|
|
NSMutableArray *deleteIndexPaths = [NSMutableArray array];
|
|
|
|
|
2011-08-02 09:16:54 -07:00
|
|
|
if (newLevel == previousLevel) return;
|
|
|
|
|
2011-07-29 21:27:37 -07:00
|
|
|
if (newLevel < previousLevel) {
|
|
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
2012-07-16 19:45:14 -07:00
|
|
|
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
|
|
|
|
[userPreferences setInteger:(newLevel + 1) forKey:@"selectedIntelligence"];
|
|
|
|
[userPreferences synchronize];
|
|
|
|
|
2011-07-29 21:27:37 -07:00
|
|
|
[appDelegate calculateStoryLocations];
|
|
|
|
}
|
2012-07-16 19:45:14 -07:00
|
|
|
|
2011-07-29 21:27:37 -07:00
|
|
|
for (int i=0; i < [[appDelegate activeFeedStoryLocations] count]; i++) {
|
|
|
|
int location = [[[appDelegate activeFeedStoryLocations] objectAtIndex:i] intValue];
|
2011-07-29 09:06:17 -07:00
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
|
2011-07-29 21:27:37 -07:00
|
|
|
NSDictionary *story = [appDelegate.activeFeedStories objectAtIndex:location];
|
2011-07-29 09:06:17 -07:00
|
|
|
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
|
|
|
|
|
|
|
|
if (previousLevel == -1) {
|
|
|
|
if (newLevel == 0 && score == -1) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
|
|
|
} else if (newLevel == 1 && score < 1) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
|
|
|
}
|
|
|
|
} else if (previousLevel == 0) {
|
|
|
|
if (newLevel == -1 && score == -1) {
|
|
|
|
[insertIndexPaths addObject:indexPath];
|
|
|
|
} else if (newLevel == 1 && score == 0) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
|
|
|
}
|
|
|
|
} else if (previousLevel == 1) {
|
|
|
|
if (newLevel == 0 && score == 0) {
|
|
|
|
[insertIndexPaths addObject:indexPath];
|
|
|
|
} else if (newLevel == -1 && score < 1) {
|
|
|
|
[insertIndexPaths addObject:indexPath];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-07-29 21:27:37 -07:00
|
|
|
|
|
|
|
if (newLevel > previousLevel) {
|
|
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
|
|
|
[appDelegate calculateStoryLocations];
|
|
|
|
}
|
|
|
|
|
2011-07-29 09:06:17 -07:00
|
|
|
[self.storyTitlesTable beginUpdates];
|
2011-07-29 21:27:37 -07:00
|
|
|
if ([deleteIndexPaths count] > 0) {
|
|
|
|
[self.storyTitlesTable deleteRowsAtIndexPaths:deleteIndexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
}
|
|
|
|
if ([insertIndexPaths count] > 0) {
|
|
|
|
[self.storyTitlesTable insertRowsAtIndexPaths:insertIndexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
}
|
2011-07-29 09:06:17 -07:00
|
|
|
[self.storyTitlesTable endUpdates];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *)getStoryAtRow:(NSInteger)indexPathRow {
|
2011-07-29 21:27:37 -07:00
|
|
|
int row = [[[appDelegate activeFeedStoryLocations] objectAtIndex:indexPathRow] intValue];
|
2011-07-29 09:06:17 -07:00
|
|
|
return [appDelegate.activeFeedStories objectAtIndex:row];
|
2011-07-24 22:23:38 -07:00
|
|
|
}
|
|
|
|
|
2011-10-17 09:28:15 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Feed Actions
|
|
|
|
|
2011-11-04 08:46:24 -07:00
|
|
|
|
2011-11-09 09:51:42 -08:00
|
|
|
- (void)markFeedsReadWithAllStories:(BOOL)includeHidden {
|
2011-11-29 17:57:20 -08:00
|
|
|
NSLog(@"mark feeds read: %d %d", appDelegate.isRiverView, includeHidden);
|
2011-11-09 09:51:42 -08:00
|
|
|
if (appDelegate.isRiverView && includeHidden) {
|
|
|
|
// Mark folder as read
|
2011-11-29 17:57:20 -08:00
|
|
|
NSString *urlString = [NSString stringWithFormat:@"http://%@/reader/mark_feed_as_read",
|
2011-11-09 09:51:42 -08:00
|
|
|
NEWSBLUR_URL];
|
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
|
2011-11-29 17:57:20 -08:00
|
|
|
for (id feed_id in [appDelegate.dictFolders objectForKey:appDelegate.activeFolder]) {
|
|
|
|
[request addPostValue:feed_id forKey:@"feed_id"];
|
|
|
|
}
|
2011-11-09 09:51:42 -08:00
|
|
|
[request setDelegate:nil];
|
|
|
|
[request startAsynchronous];
|
2011-11-10 18:28:22 -08:00
|
|
|
|
|
|
|
[appDelegate markActiveFolderAllRead];
|
2011-11-09 09:51:42 -08:00
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
|
|
|
} else if (!appDelegate.isRiverView && includeHidden) {
|
|
|
|
// Mark feed as read
|
2011-11-04 08:46:24 -07:00
|
|
|
NSString *urlString = [NSString stringWithFormat:@"http://%@/reader/mark_feed_as_read",
|
|
|
|
NEWSBLUR_URL];
|
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
|
|
|
|
[request setPostValue:[appDelegate.activeFeed objectForKey:@"id"] forKey:@"feed_id"];
|
|
|
|
[request setDelegate:nil];
|
|
|
|
[request startAsynchronous];
|
2011-11-10 18:28:22 -08:00
|
|
|
|
2011-11-04 08:46:24 -07:00
|
|
|
[appDelegate markActiveFeedAllRead];
|
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
2011-11-09 09:51:42 -08:00
|
|
|
} else {
|
|
|
|
// Mark visible stories as read
|
2011-11-10 18:28:22 -08:00
|
|
|
NSDictionary *feedsStories = [appDelegate markVisibleStoriesRead];
|
|
|
|
NSString *urlString = [NSString stringWithFormat:@"http://%@/reader/mark_feed_stories_as_read",
|
2011-11-09 09:51:42 -08:00
|
|
|
NEWSBLUR_URL];
|
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
|
2011-11-10 18:28:22 -08:00
|
|
|
[request setPostValue:[feedsStories JSONRepresentation] forKey:@"feeds_stories"];
|
2011-11-09 09:51:42 -08:00
|
|
|
[request setDelegate:nil];
|
|
|
|
[request startAsynchronous];
|
2011-11-10 18:28:22 -08:00
|
|
|
|
2011-11-09 09:51:42 -08:00
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
2011-11-04 08:46:24 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (IBAction)doOpenMarkReadActionSheet:(id)sender {
|
2011-11-29 17:57:20 -08:00
|
|
|
// Individual sites just get marked as read, no action sheet needed.
|
|
|
|
if (!appDelegate.isRiverView) {
|
|
|
|
[self markFeedsReadWithAllStories:YES];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-11-09 09:51:42 -08:00
|
|
|
NSString *title = appDelegate.isRiverView ?
|
|
|
|
appDelegate.activeFolder :
|
|
|
|
[appDelegate.activeFeed objectForKey:@"feed_title"];
|
2011-11-04 08:46:24 -07:00
|
|
|
UIActionSheet *options = [[UIActionSheet alloc]
|
2011-11-09 09:51:42 -08:00
|
|
|
initWithTitle:title
|
2011-11-04 08:46:24 -07:00
|
|
|
delegate:self
|
|
|
|
cancelButtonTitle:nil
|
|
|
|
destructiveButtonTitle:nil
|
|
|
|
otherButtonTitles:nil];
|
|
|
|
|
2011-11-09 09:51:42 -08:00
|
|
|
int visibleUnreadCount = appDelegate.visibleUnreadCount;
|
|
|
|
int totalUnreadCount = [appDelegate unreadCount];
|
|
|
|
NSArray *buttonTitles = nil;
|
2011-12-05 18:10:40 -08:00
|
|
|
BOOL showVisible = YES;
|
|
|
|
BOOL showEntire = YES;
|
|
|
|
if ([appDelegate.activeFolder isEqualToString:@"Everything"]) showEntire = NO;
|
|
|
|
if (visibleUnreadCount >= totalUnreadCount || visibleUnreadCount <= 0) showVisible = NO;
|
|
|
|
NSString *entireText = [NSString stringWithFormat:@"Mark %@ read",
|
|
|
|
appDelegate.isRiverView ?
|
|
|
|
@"entire folder" :
|
|
|
|
@"this site"];
|
|
|
|
NSString *visibleText = [NSString stringWithFormat:@"Mark %@ read",
|
|
|
|
visibleUnreadCount == 1 ? @"this story as" :
|
|
|
|
[NSString stringWithFormat:@"these %d stories",
|
|
|
|
visibleUnreadCount]];
|
|
|
|
if (showVisible && showEntire) {
|
2011-11-09 09:51:42 -08:00
|
|
|
buttonTitles = [NSArray arrayWithObjects:visibleText, entireText, nil];
|
|
|
|
options.destructiveButtonIndex = 1;
|
2011-12-05 18:10:40 -08:00
|
|
|
} else if (showVisible && !showEntire) {
|
|
|
|
buttonTitles = [NSArray arrayWithObjects:visibleText, nil];
|
|
|
|
options.destructiveButtonIndex = -1;
|
|
|
|
} else if (!showVisible && showEntire) {
|
|
|
|
buttonTitles = [NSArray arrayWithObjects:entireText, nil];
|
|
|
|
options.destructiveButtonIndex = 0;
|
2011-11-09 09:51:42 -08:00
|
|
|
}
|
|
|
|
|
2011-11-04 08:46:24 -07:00
|
|
|
for (id title in buttonTitles) {
|
|
|
|
[options addButtonWithTitle:title];
|
|
|
|
}
|
|
|
|
options.cancelButtonIndex = [options addButtonWithTitle:@"Cancel"];
|
|
|
|
|
2011-11-05 16:25:04 -07:00
|
|
|
options.tag = kMarkReadActionSheet;
|
2011-11-04 08:46:24 -07:00
|
|
|
[options showInView:self.view];
|
|
|
|
}
|
|
|
|
|
2011-10-17 09:28:15 -07:00
|
|
|
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
|
2011-12-03 18:22:14 -08:00
|
|
|
// NSLog(@"Action option #%d on %d", buttonIndex, actionSheet.tag);
|
2011-11-05 16:25:04 -07:00
|
|
|
if (actionSheet.tag == 1) {
|
2011-11-09 09:51:42 -08:00
|
|
|
int visibleUnreadCount = appDelegate.visibleUnreadCount;
|
|
|
|
int totalUnreadCount = [appDelegate unreadCount];
|
2011-12-05 18:10:40 -08:00
|
|
|
BOOL showVisible = YES;
|
|
|
|
BOOL showEntire = YES;
|
|
|
|
if ([appDelegate.activeFolder isEqualToString:@"Everything"]) showEntire = NO;
|
|
|
|
if (visibleUnreadCount >= totalUnreadCount || visibleUnreadCount <= 0) showVisible = NO;
|
2011-12-03 18:22:14 -08:00
|
|
|
// NSLog(@"Counts: %d %d = %d", visibleUnreadCount, totalUnreadCount, visibleUnreadCount >= totalUnreadCount || visibleUnreadCount <= 0);
|
2011-12-05 18:10:40 -08:00
|
|
|
|
|
|
|
if (showVisible && showEntire) {
|
2011-11-09 09:51:42 -08:00
|
|
|
if (buttonIndex == 0) {
|
2011-12-20 08:56:55 -08:00
|
|
|
[self markFeedsReadWithAllStories:NO];
|
|
|
|
} else if (buttonIndex == 1) {
|
|
|
|
[self markFeedsReadWithAllStories:YES];
|
|
|
|
}
|
2011-12-05 18:10:40 -08:00
|
|
|
} else if (showVisible && !showEntire) {
|
2011-11-09 09:51:42 -08:00
|
|
|
if (buttonIndex == 0) {
|
|
|
|
[self markFeedsReadWithAllStories:NO];
|
2011-12-05 18:10:40 -08:00
|
|
|
}
|
|
|
|
} else if (!showVisible && showEntire) {
|
|
|
|
if (buttonIndex == 0) {
|
2011-11-09 09:51:42 -08:00
|
|
|
[self markFeedsReadWithAllStories:YES];
|
2011-12-05 18:10:40 -08:00
|
|
|
}
|
2011-11-09 09:51:42 -08:00
|
|
|
}
|
2011-11-05 16:25:04 -07:00
|
|
|
} else if (actionSheet.tag == 2) {
|
|
|
|
if (buttonIndex == 0) {
|
|
|
|
[self confirmDeleteSite];
|
2011-12-03 18:22:14 -08:00
|
|
|
} else if (buttonIndex == 1) {
|
|
|
|
[self openMoveView];
|
2012-06-27 15:38:51 -07:00
|
|
|
} else if (buttonIndex == 2) {
|
|
|
|
[self instafetchFeed];
|
2011-11-05 16:25:04 -07:00
|
|
|
}
|
2012-06-27 15:38:51 -07:00
|
|
|
}
|
2011-10-17 09:28:15 -07:00
|
|
|
}
|
|
|
|
|
2011-12-20 08:56:55 -08:00
|
|
|
- (IBAction)doOpenSettingsActionSheet {
|
|
|
|
NSString *title = appDelegate.isRiverView ?
|
|
|
|
appDelegate.activeFolder :
|
|
|
|
[appDelegate.activeFeed objectForKey:@"feed_title"];
|
|
|
|
UIActionSheet *options = [[UIActionSheet alloc]
|
|
|
|
initWithTitle:title
|
|
|
|
delegate:self
|
|
|
|
cancelButtonTitle:nil
|
|
|
|
destructiveButtonTitle:nil
|
|
|
|
otherButtonTitles:nil];
|
|
|
|
|
|
|
|
if (![title isEqualToString:@"Everything"]) {
|
|
|
|
NSString *deleteText = [NSString stringWithFormat:@"Delete %@",
|
|
|
|
appDelegate.isRiverView ?
|
|
|
|
@"this entire folder" :
|
|
|
|
@"this site"];
|
|
|
|
[options addButtonWithTitle:deleteText];
|
|
|
|
options.destructiveButtonIndex = 0;
|
|
|
|
|
|
|
|
NSString *moveText = @"Move to another folder";
|
|
|
|
[options addButtonWithTitle:moveText];
|
2012-06-27 15:38:51 -07:00
|
|
|
|
2012-07-01 12:08:30 -07:00
|
|
|
NSString *fetchText = @"Insta-fetch stories";
|
2012-06-27 15:38:51 -07:00
|
|
|
[options addButtonWithTitle:fetchText];
|
|
|
|
|
2011-12-20 08:56:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
options.cancelButtonIndex = [options addButtonWithTitle:@"Cancel"];
|
|
|
|
options.tag = kSettingsActionSheet;
|
|
|
|
[options showInView:self.view];
|
|
|
|
}
|
|
|
|
|
2011-10-17 09:28:15 -07:00
|
|
|
- (void)confirmDeleteSite {
|
2012-07-09 21:26:53 -07:00
|
|
|
UIAlertView *deleteConfirm = [[UIAlertView alloc]
|
|
|
|
initWithTitle:@"Positive?"
|
|
|
|
message:nil
|
|
|
|
delegate:self
|
|
|
|
cancelButtonTitle:@"Cancel"
|
|
|
|
otherButtonTitles:@"Delete",
|
|
|
|
nil];
|
2011-10-17 09:28:15 -07:00
|
|
|
[deleteConfirm show];
|
|
|
|
[deleteConfirm setTag:0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
|
|
|
|
if (alertView.tag == 0) {
|
|
|
|
if (buttonIndex == 0) {
|
|
|
|
return;
|
|
|
|
} else {
|
2011-12-05 09:26:02 -08:00
|
|
|
if (appDelegate.isRiverView) {
|
|
|
|
[self deleteFolder];
|
|
|
|
} else {
|
|
|
|
[self deleteSite];
|
|
|
|
}
|
2011-10-17 09:28:15 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)deleteSite {
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
|
|
|
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
|
|
|
|
HUD.labelText = @"Deleting...";
|
2011-10-20 09:32:39 -07:00
|
|
|
|
|
|
|
NSString *theFeedDetailURL = [NSString stringWithFormat:@"http://%@/reader/delete_feed",
|
|
|
|
NEWSBLUR_URL];
|
|
|
|
NSURL *urlFeedDetail = [NSURL URLWithString:theFeedDetailURL];
|
|
|
|
|
2012-07-15 15:06:06 -07:00
|
|
|
__weak ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:urlFeedDetail];
|
2011-10-20 09:32:39 -07:00
|
|
|
[request setDelegate:self];
|
|
|
|
[request addPostValue:[[appDelegate activeFeed] objectForKey:@"id"] forKey:@"feed_id"];
|
2011-12-04 21:09:16 -08:00
|
|
|
[request addPostValue:[appDelegate extractFolderName:appDelegate.activeFolder] forKey:@"in_folder"];
|
2011-10-20 09:32:39 -07:00
|
|
|
[request setFailedBlock:^(void) {
|
2011-11-30 09:38:31 -08:00
|
|
|
[self informError:[request error]];
|
2011-10-20 09:32:39 -07:00
|
|
|
}];
|
|
|
|
[request setCompletionBlock:^(void) {
|
2011-12-03 18:22:14 -08:00
|
|
|
[appDelegate reloadFeedsView:YES];
|
2011-10-20 09:32:39 -07:00
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
|
|
|
}];
|
|
|
|
[request setTimeOutSeconds:30];
|
|
|
|
[request setTag:[[[appDelegate activeFeed] objectForKey:@"id"] intValue]];
|
|
|
|
[request startAsynchronous];
|
2011-10-17 09:28:15 -07:00
|
|
|
}
|
2011-08-18 09:56:52 -07:00
|
|
|
|
2011-12-05 09:26:02 -08:00
|
|
|
- (void)deleteFolder {
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
|
|
|
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
|
|
|
|
HUD.labelText = @"Deleting...";
|
|
|
|
|
|
|
|
NSString *theFeedDetailURL = [NSString stringWithFormat:@"http://%@/reader/delete_folder",
|
|
|
|
NEWSBLUR_URL];
|
|
|
|
NSURL *urlFeedDetail = [NSURL URLWithString:theFeedDetailURL];
|
|
|
|
|
2012-07-15 15:06:06 -07:00
|
|
|
__weak ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:urlFeedDetail];
|
2011-12-05 09:26:02 -08:00
|
|
|
[request setDelegate:self];
|
|
|
|
[request addPostValue:[appDelegate extractFolderName:appDelegate.activeFolder]
|
|
|
|
forKey:@"folder_to_delete"];
|
|
|
|
[request addPostValue:[appDelegate extractFolderName:[appDelegate extractParentFolderName:appDelegate.activeFolder]]
|
|
|
|
forKey:@"in_folder"];
|
|
|
|
[request setFailedBlock:^(void) {
|
|
|
|
[self informError:[request error]];
|
|
|
|
}];
|
|
|
|
[request setCompletionBlock:^(void) {
|
|
|
|
[appDelegate reloadFeedsView:YES];
|
|
|
|
[appDelegate.navigationController
|
|
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
|
|
objectAtIndex:0]
|
|
|
|
animated:YES];
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
|
|
|
}];
|
|
|
|
[request setTimeOutSeconds:30];
|
|
|
|
[request startAsynchronous];
|
|
|
|
}
|
|
|
|
|
2011-12-03 18:22:14 -08:00
|
|
|
- (void)openMoveView {
|
|
|
|
[appDelegate showMoveSite];
|
|
|
|
}
|
|
|
|
|
2012-07-25 17:29:29 -07:00
|
|
|
- (void)showUserProfile {
|
2012-07-12 22:05:23 -07:00
|
|
|
appDelegate.activeUserProfileId = [NSString stringWithFormat:@"%@", [appDelegate.activeFeed objectForKey:@"user_id"]];
|
2012-07-25 17:29:29 -07:00
|
|
|
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
|
|
|
[appDelegate.masterContainerViewController showUserProfilePopover:self.navigationItem.rightBarButtonItem];
|
2012-07-12 22:05:23 -07:00
|
|
|
} else {
|
|
|
|
[appDelegate showUserProfileModal];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-20 19:18:29 -07:00
|
|
|
- (void)changeActiveFeedDetailRow {
|
2012-06-21 11:53:48 -07:00
|
|
|
int rowIndex = [appDelegate locationOfActiveStory];
|
|
|
|
|
2012-06-18 16:45:36 -07:00
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
|
|
|
|
NSIndexPath *offsetIndexPath = [NSIndexPath indexPathForRow:rowIndex - 1 inSection:0];
|
|
|
|
|
2012-06-18 17:20:34 -07:00
|
|
|
[storyTitlesTable selectRowAtIndexPath:indexPath
|
|
|
|
animated:YES
|
|
|
|
scrollPosition:UITableViewScrollPositionNone];
|
2012-06-18 16:45:36 -07:00
|
|
|
|
|
|
|
// check to see if the cell is completely visible
|
|
|
|
CGRect cellRect = [storyTitlesTable rectForRowAtIndexPath:indexPath];
|
|
|
|
|
|
|
|
cellRect = [storyTitlesTable convertRect:cellRect toView:storyTitlesTable.superview];
|
|
|
|
|
|
|
|
BOOL completelyVisible = CGRectContainsRect(storyTitlesTable.frame, cellRect);
|
|
|
|
|
|
|
|
if (!completelyVisible) {
|
2012-06-18 17:20:34 -07:00
|
|
|
[storyTitlesTable scrollToRowAtIndexPath:offsetIndexPath
|
|
|
|
atScrollPosition:UITableViewScrollPositionTop
|
|
|
|
animated:YES];
|
2012-06-18 16:45:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-18 09:56:52 -07:00
|
|
|
|
2012-06-22 18:33:44 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark instafetchFeed
|
|
|
|
|
|
|
|
// called when the user taps refresh button
|
|
|
|
|
2012-06-27 15:38:51 -07:00
|
|
|
- (void)instafetchFeed {
|
2012-06-22 18:33:44 -07:00
|
|
|
NSLog(@"Instafetch");
|
|
|
|
|
|
|
|
NSString *urlString = [NSString
|
|
|
|
stringWithFormat:@"http://%@/reader/refresh_feed/%@",
|
|
|
|
NEWSBLUR_URL,
|
|
|
|
[appDelegate.activeFeed objectForKey:@"id"]];
|
|
|
|
[self cancelRequests];
|
|
|
|
__block ASIHTTPRequest *request = [self requestWithURL:urlString];
|
|
|
|
[request setDelegate:self];
|
|
|
|
[request setResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
|
|
|
|
[request setDidFinishSelector:@selector(finishedRefreshingFeed:)];
|
|
|
|
[request setDidFailSelector:@selector(failRefreshingFeed:)];
|
|
|
|
[request setTimeOutSeconds:60];
|
|
|
|
[request startAsynchronous];
|
|
|
|
|
|
|
|
[appDelegate setStories:nil];
|
|
|
|
self.feedPage = 1;
|
|
|
|
self.pageFetching = YES;
|
|
|
|
[self.storyTitlesTable reloadData];
|
|
|
|
[storyTitlesTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)finishedRefreshingFeed:(ASIHTTPRequest *)request {
|
|
|
|
NSString *responseString = [request responseString];
|
|
|
|
NSDictionary *results = [[NSDictionary alloc]
|
|
|
|
initWithDictionary:[responseString JSONValue]];
|
2012-07-16 19:45:14 -07:00
|
|
|
|
2012-06-22 18:33:44 -07:00
|
|
|
[self renderStories:[results objectForKey:@"stories"]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)failRefreshingFeed:(ASIHTTPRequest *)request {
|
|
|
|
NSLog(@"Fail: %@", request);
|
|
|
|
[self informError:[request error]];
|
|
|
|
[self fetchFeedDetail:1 withCallback:nil];
|
|
|
|
}
|
|
|
|
|
2012-06-29 10:20:06 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark loadSocial Feeds
|
|
|
|
|
|
|
|
- (void)loadFaviconsFromActiveFeed {
|
|
|
|
NSArray * keys = [appDelegate.dictActiveFeeds allKeys];
|
2012-07-20 15:54:10 -07:00
|
|
|
|
|
|
|
if (![keys count]) {
|
|
|
|
// if no new favicons, return
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-29 10:20:06 -07:00
|
|
|
NSString *feedIdsQuery = [NSString stringWithFormat:@"?feed_ids=%@",
|
|
|
|
[[keys valueForKey:@"description"] componentsJoinedByString:@"&feed_ids="]];
|
|
|
|
NSString *urlString = [NSString stringWithFormat:@"http://%@/reader/favicons%@",
|
|
|
|
NEWSBLUR_URL,
|
|
|
|
feedIdsQuery];
|
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
|
|
|
|
|
|
|
|
[request setDidFinishSelector:@selector(saveAndDrawFavicons:)];
|
|
|
|
[request setDidFailSelector:@selector(requestFailed:)];
|
|
|
|
[request setDelegate:self];
|
|
|
|
[request startAsynchronous];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)saveAndDrawFavicons:(ASIHTTPRequest *)request {
|
|
|
|
|
|
|
|
NSString *responseString = [request responseString];
|
|
|
|
NSDictionary *results = [[NSDictionary alloc]
|
|
|
|
initWithDictionary:[responseString JSONValue]];
|
|
|
|
|
|
|
|
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
|
|
|
|
dispatch_async(queue, ^{
|
|
|
|
for (id feed_id in results) {
|
|
|
|
NSDictionary *feed = [appDelegate.dictActiveFeeds objectForKey:feed_id];
|
|
|
|
[feed setValue:[results objectForKey:feed_id] forKey:@"favicon"];
|
|
|
|
[appDelegate.dictActiveFeeds setValue:feed forKey:feed_id];
|
|
|
|
|
|
|
|
NSString *favicon = [feed objectForKey:@"favicon"];
|
|
|
|
if ((NSNull *)favicon != [NSNull null] && [favicon length] > 0) {
|
|
|
|
NSData *imageData = [NSData dataWithBase64EncodedString:favicon];
|
|
|
|
UIImage *faviconImage = [UIImage imageWithData:imageData];
|
|
|
|
[Utilities saveImage:faviconImage feedId:feed_id];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[Utilities saveimagesToDisk];
|
|
|
|
|
|
|
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
|
|
[self.storyTitlesTable reloadData];
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)requestFailed:(ASIHTTPRequest *)request {
|
|
|
|
NSError *error = [request error];
|
|
|
|
NSLog(@"Error: %@", error);
|
|
|
|
}
|
|
|
|
|
2010-06-21 17:17:26 -04:00
|
|
|
@end
|