2010-06-20 11:04:23 -04:00
|
|
|
//
|
|
|
|
// NewsBlurViewController.m
|
|
|
|
// NewsBlur
|
|
|
|
//
|
|
|
|
// Created by Samuel Clay on 6/16/10.
|
|
|
|
// Copyright NewsBlur 2010. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "NewsBlurViewController.h"
|
2010-06-21 17:17:26 -04:00
|
|
|
#import "NewsBlurAppDelegate.h"
|
2011-07-18 09:56:48 -07:00
|
|
|
#import "FeedTableCell.h"
|
2011-08-04 17:58:28 -07:00
|
|
|
#import "ASIHTTPRequest.h"
|
|
|
|
#import "PullToRefreshView.h"
|
2011-08-13 23:00:51 -07:00
|
|
|
#import "MBProgressHUD.h"
|
2011-08-03 10:00:41 -07:00
|
|
|
#import "Base64.h"
|
2010-06-20 11:04:23 -04:00
|
|
|
#import "JSON.h"
|
|
|
|
|
2011-07-19 09:38:49 -07:00
|
|
|
#define kTableViewRowHeight 40;
|
|
|
|
|
2011-08-12 10:12:30 -07:00
|
|
|
#define UIColorFromRGB(rgbValue) [UIColor \
|
|
|
|
colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
|
|
|
|
green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
|
|
|
|
blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
|
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
@implementation NewsBlurViewController
|
2010-06-21 17:17:26 -04:00
|
|
|
|
|
|
|
@synthesize appDelegate;
|
|
|
|
|
2010-11-15 19:40:17 -05:00
|
|
|
@synthesize responseData;
|
2011-08-02 09:16:54 -07:00
|
|
|
@synthesize feedTitlesTable;
|
2010-06-20 11:04:23 -04:00
|
|
|
@synthesize feedViewToolbar;
|
2010-06-21 17:17:26 -04:00
|
|
|
@synthesize feedScoreSlider;
|
2010-11-11 23:48:27 -05:00
|
|
|
@synthesize logoutButton;
|
2011-08-02 09:16:54 -07:00
|
|
|
@synthesize intelligenceControl;
|
2011-08-02 10:13:06 -07:00
|
|
|
@synthesize activeFeedLocations;
|
2011-08-15 17:57:37 -07:00
|
|
|
@synthesize stillVisibleFeeds;
|
2011-08-03 10:00:41 -07:00
|
|
|
@synthesize sitesButton;
|
2011-08-04 17:27:31 -07:00
|
|
|
@synthesize viewShowingAllFeeds;
|
2011-08-04 17:58:28 -07:00
|
|
|
@synthesize pull;
|
|
|
|
@synthesize lastUpdate;
|
2010-06-20 11:04:23 -04:00
|
|
|
|
|
|
|
@synthesize dictFolders;
|
2011-06-10 10:40:44 -04:00
|
|
|
@synthesize dictFeeds;
|
2010-06-20 11:04:23 -04:00
|
|
|
@synthesize dictFoldersArray;
|
|
|
|
|
2010-06-21 17:17:26 -04:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Globals
|
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
2010-06-21 17:17:26 -04:00
|
|
|
|
|
|
|
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
|
|
|
|
[appDelegate hideNavigationBar:NO];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)viewDidLoad {
|
2011-07-24 20:34:54 -07:00
|
|
|
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Logout" style:UIBarButtonItemStylePlain target:self action:@selector(doLogoutButton)] autorelease];
|
2010-11-13 18:32:43 -05:00
|
|
|
[appDelegate showNavigationBar:NO];
|
2011-08-04 17:27:31 -07:00
|
|
|
self.viewShowingAllFeeds = NO;
|
2011-08-04 17:58:28 -07:00
|
|
|
pull = [[PullToRefreshView alloc] initWithScrollView:self.feedTitlesTable];
|
|
|
|
[pull setDelegate:self];
|
|
|
|
[self.feedTitlesTable addSubview:pull];
|
2010-06-20 11:04:23 -04:00
|
|
|
[super viewDidLoad];
|
|
|
|
}
|
|
|
|
|
2010-06-25 18:36:01 -04:00
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
2011-08-02 09:16:54 -07:00
|
|
|
[self.feedTitlesTable deselectRowAtIndexPath:[feedTitlesTable indexPathForSelectedRow] animated:animated];
|
2011-07-24 22:14:50 -07:00
|
|
|
if (appDelegate.activeFeedIndexPath) {
|
|
|
|
// NSLog(@"Refreshing feed at %d / %d: %@", appDelegate.activeFeedIndexPath.section, appDelegate.activeFeedIndexPath.row, [appDelegate activeFeed]);
|
2011-08-02 09:16:54 -07:00
|
|
|
[self.feedTitlesTable beginUpdates];
|
|
|
|
[self.feedTitlesTable
|
|
|
|
reloadRowsAtIndexPaths:[NSArray
|
|
|
|
arrayWithObject:appDelegate.activeFeedIndexPath]
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
[self.feedTitlesTable endUpdates];
|
2011-08-02 18:19:46 -07:00
|
|
|
|
|
|
|
NSInteger previousLevel = [self.intelligenceControl selectedSegmentIndex] - 1;
|
|
|
|
NSInteger newLevel = [appDelegate selectedIntelligence];
|
|
|
|
[self updateFeedsWithIntelligence:previousLevel newLevel:newLevel];
|
2011-07-24 22:14:50 -07:00
|
|
|
}
|
2011-08-02 09:16:54 -07:00
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullet_red.png"] forSegmentAtIndex:0];
|
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullet_yellow.png"] forSegmentAtIndex:1];
|
|
|
|
[self.intelligenceControl setImage:[UIImage imageNamed:@"bullet_green.png"] forSegmentAtIndex:2];
|
|
|
|
[self.intelligenceControl addTarget:self
|
|
|
|
action:@selector(selectIntelligence)
|
|
|
|
forControlEvents:UIControlEventValueChanged];
|
2011-08-13 17:08:26 -07:00
|
|
|
[self.intelligenceControl
|
|
|
|
setSelectedSegmentIndex:[appDelegate selectedIntelligence]+1];
|
2010-11-13 18:32:43 -05:00
|
|
|
[appDelegate showNavigationBar:animated];
|
2010-06-25 18:36:01 -04:00
|
|
|
}
|
|
|
|
|
2010-06-21 17:17:26 -04:00
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
2010-06-25 18:36:01 -04:00
|
|
|
appDelegate.activeFeed = nil;
|
2010-06-21 17:17:26 -04:00
|
|
|
[super viewDidAppear:animated];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)viewWillDisappear:(BOOL)animated {
|
2010-11-12 10:55:44 -05:00
|
|
|
//[appDelegate showNavigationBar:YES];
|
2010-06-21 17:17:26 -04:00
|
|
|
[super viewWillDisappear:animated];
|
|
|
|
}
|
2010-06-20 11:04:23 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
// Override to allow orientations other than the default portrait orientation.
|
|
|
|
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
|
|
|
// Return YES for supported orientations
|
|
|
|
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
|
|
// Releases the view if it doesn't have a superview.
|
|
|
|
[super didReceiveMemoryWarning];
|
|
|
|
|
|
|
|
// Release any cached data, images, etc that aren't in use.
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)viewDidUnload {
|
|
|
|
// Release any retained subviews of the main view.
|
|
|
|
// e.g. self.myOutlet = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-08-01 09:43:13 -07:00
|
|
|
- (void)dealloc {
|
|
|
|
[appDelegate release];
|
|
|
|
|
2011-08-02 09:16:54 -07:00
|
|
|
[feedTitlesTable release];
|
2011-08-01 09:43:13 -07:00
|
|
|
[feedViewToolbar release];
|
|
|
|
[feedScoreSlider release];
|
|
|
|
[logoutButton release];
|
2011-08-02 09:16:54 -07:00
|
|
|
[intelligenceControl release];
|
2011-08-02 10:13:06 -07:00
|
|
|
[activeFeedLocations release];
|
2011-08-15 17:57:37 -07:00
|
|
|
[stillVisibleFeeds release];
|
2011-08-03 10:00:41 -07:00
|
|
|
[sitesButton release];
|
2011-08-04 17:58:28 -07:00
|
|
|
[pull release];
|
|
|
|
[lastUpdate release];
|
2011-08-01 09:43:13 -07:00
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
[dictFolders release];
|
2011-06-10 10:40:44 -04:00
|
|
|
[dictFeeds release];
|
2010-06-20 11:04:23 -04:00
|
|
|
[dictFoldersArray release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Initialization
|
|
|
|
|
2011-08-13 23:00:51 -07:00
|
|
|
- (void)fetchFeedList:(BOOL)showLoader {
|
|
|
|
if (showLoader) {
|
|
|
|
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
|
|
|
|
HUD.labelText = @"On its way...";
|
|
|
|
}
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
|
2011-08-13 17:08:26 -07:00
|
|
|
NSURL *urlFeedList = [NSURL URLWithString:
|
|
|
|
[NSString stringWithFormat:@"http://www.newsblur.com/reader/feeds?flat=true"]];
|
2010-11-13 13:42:20 -05:00
|
|
|
responseData = [[NSMutableData data] retain];
|
2010-06-20 11:04:23 -04:00
|
|
|
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: urlFeedList];
|
2011-08-13 17:08:26 -07:00
|
|
|
NSURLConnection *connection = [[NSURLConnection alloc]
|
|
|
|
initWithRequest:request delegate:self];
|
2010-06-20 11:04:23 -04:00
|
|
|
[connection release];
|
|
|
|
[request release];
|
2011-08-04 17:58:28 -07:00
|
|
|
|
|
|
|
self.lastUpdate = [NSDate date];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
|
2010-11-11 23:48:27 -05:00
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
2010-11-13 13:42:20 -05:00
|
|
|
[responseData setLength:0];
|
2010-11-11 23:48:27 -05:00
|
|
|
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
|
|
|
|
int responseStatusCode = [httpResponse statusCode];
|
|
|
|
if (responseStatusCode == 403) {
|
|
|
|
[appDelegate showLogin];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-13 13:42:20 -05:00
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
2010-11-13 18:32:43 -05:00
|
|
|
//NSLog(@"didReceiveData: %@", data);
|
2010-11-13 13:42:20 -05:00
|
|
|
[responseData appendData:data];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
|
|
|
NSLog(@"%@", [NSString stringWithFormat:@"Connection failed: %@", [error description]]);
|
2011-08-18 09:56:52 -07:00
|
|
|
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
|
|
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
|
|
|
[pull finishedLoading];
|
|
|
|
|
|
|
|
// User clicking on another link before the page loads is OK.
|
|
|
|
if ([error code] != NSURLErrorCancelled) {
|
|
|
|
[NewsBlurAppDelegate informError:error];
|
|
|
|
}
|
2010-11-13 13:42:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
|
|
|
//[connection release];
|
2011-08-13 23:00:51 -07:00
|
|
|
|
|
|
|
[MBProgressHUD hideHUDForView:self.view animated:YES];
|
2011-08-15 17:57:37 -07:00
|
|
|
self.stillVisibleFeeds = [NSMutableDictionary dictionary];
|
2011-08-04 17:58:28 -07:00
|
|
|
[pull finishedLoading];
|
2011-08-04 18:25:38 -07:00
|
|
|
[self loadFavicons];
|
2011-08-13 23:00:51 -07:00
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
2010-11-13 13:42:20 -05:00
|
|
|
NSString *jsonString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
|
|
|
|
[responseData release];
|
2011-08-15 17:57:37 -07:00
|
|
|
|
2010-11-13 13:42:20 -05:00
|
|
|
if ([jsonString length] > 0) {
|
2011-08-13 17:08:26 -07:00
|
|
|
NSDictionary *results = [[NSDictionary alloc]
|
|
|
|
initWithDictionary:[jsonString JSONValue]];
|
2010-11-13 18:32:43 -05:00
|
|
|
appDelegate.activeUsername = [results objectForKey:@"user"];
|
|
|
|
[appDelegate setTitle:[results objectForKey:@"user"]];
|
2010-11-13 13:42:20 -05:00
|
|
|
self.dictFolders = [results objectForKey:@"flat_folders"];
|
2011-06-10 10:40:44 -04:00
|
|
|
self.dictFeeds = [results objectForKey:@"feeds"];
|
2011-08-01 09:43:13 -07:00
|
|
|
// NSLog(@"Received Feeds: %@", dictFolders);
|
2011-07-29 21:27:37 -07:00
|
|
|
// NSSortDescriptor *sortDescriptor;
|
|
|
|
// sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"feed_title"
|
|
|
|
// ascending:YES] autorelease];
|
|
|
|
// NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
|
2010-11-13 13:42:20 -05:00
|
|
|
NSMutableDictionary *sortedFolders = [[NSMutableDictionary alloc] init];
|
2011-07-29 21:27:37 -07:00
|
|
|
// NSArray *sortedArray;
|
2010-11-13 13:42:20 -05:00
|
|
|
|
2011-08-01 09:43:13 -07:00
|
|
|
self.dictFoldersArray = [NSMutableArray array];
|
2010-11-13 13:42:20 -05:00
|
|
|
for (id f in self.dictFolders) {
|
2011-08-15 17:57:37 -07:00
|
|
|
// NSString *folderTitle = [f
|
|
|
|
// stringByTrimmingCharactersInSet:
|
|
|
|
// [NSCharacterSet whitespaceCharacterSet]];
|
2010-11-13 13:42:20 -05:00
|
|
|
[self.dictFoldersArray addObject:f];
|
2011-06-10 10:40:44 -04:00
|
|
|
// NSArray *folder = [self.dictFolders objectForKey:f];
|
|
|
|
// NSLog(@"F: %@", f);
|
|
|
|
// NSLog(@"F: %@", folder);
|
|
|
|
// NSLog(@"F: %@", sortDescriptors);
|
|
|
|
// sortedArray = [folder sortedArrayUsingDescriptors:sortDescriptors];
|
|
|
|
// [sortedFolders setValue:sortedArray forKey:f];
|
2010-11-13 13:42:20 -05:00
|
|
|
}
|
|
|
|
|
2011-06-10 10:40:44 -04:00
|
|
|
// self.dictFolders = sortedFolders;
|
2010-11-13 13:42:20 -05:00
|
|
|
[self.dictFoldersArray sortUsingSelector:@selector(caseInsensitiveCompare:)];
|
2011-08-02 10:13:06 -07:00
|
|
|
|
|
|
|
[self calculateFeedLocations];
|
2011-08-02 09:16:54 -07:00
|
|
|
[self.feedTitlesTable reloadData];
|
2010-11-13 13:42:20 -05:00
|
|
|
|
|
|
|
[sortedFolders release];
|
|
|
|
[results release];
|
|
|
|
}
|
2011-08-15 17:57:37 -07:00
|
|
|
|
2011-03-09 18:23:55 -05:00
|
|
|
[jsonString release];
|
2010-11-11 23:48:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (IBAction)doLogoutButton {
|
2010-11-15 19:40:17 -05:00
|
|
|
NSLog(@"Logging out...");
|
2011-08-01 09:43:13 -07:00
|
|
|
NSString *urlS = @"http://www.newsblur.com/reader/logout?api=1";
|
2010-11-13 13:42:20 -05:00
|
|
|
NSURL *url = [NSURL URLWithString:urlS];
|
|
|
|
NSURLRequest *urlR=[[[NSURLRequest alloc] initWithURL:url] autorelease];
|
2010-11-11 23:48:27 -05:00
|
|
|
[[NSHTTPCookieStorage sharedHTTPCookieStorage]
|
|
|
|
setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
|
2010-11-13 13:42:20 -05:00
|
|
|
LogoutDelegate *ld = [LogoutDelegate alloc];
|
2011-08-02 10:13:06 -07:00
|
|
|
NSURLConnection *urlConnection = [[NSURLConnection alloc]
|
|
|
|
initWithRequest:urlR
|
|
|
|
delegate:ld];
|
2010-11-13 13:42:20 -05:00
|
|
|
[urlConnection release];
|
2011-03-09 18:23:55 -05:00
|
|
|
[ld release];
|
2010-11-13 13:42:20 -05:00
|
|
|
}
|
2010-11-11 23:48:27 -05:00
|
|
|
|
2011-08-16 19:55:44 -07:00
|
|
|
- (IBAction)doSwitchSitesUnread {
|
2011-08-04 17:27:31 -07:00
|
|
|
self.viewShowingAllFeeds = !self.viewShowingAllFeeds;
|
2011-08-03 10:00:41 -07:00
|
|
|
|
2011-08-04 17:27:31 -07:00
|
|
|
if (self.viewShowingAllFeeds) {
|
|
|
|
[self.sitesButton setTitle:@"Unreads"];
|
|
|
|
} else {
|
|
|
|
[self.sitesButton setTitle:@"All Sites"];
|
|
|
|
}
|
|
|
|
|
|
|
|
NSInteger intelligenceLevel = [appDelegate selectedIntelligence];
|
|
|
|
NSMutableArray *indexPaths = [NSMutableArray array];
|
|
|
|
|
|
|
|
if (self.viewShowingAllFeeds) {
|
|
|
|
[self calculateFeedLocations];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int s=0; s < [self.dictFoldersArray count]; s++) {
|
|
|
|
NSString *folderName = [self.dictFoldersArray objectAtIndex:s];
|
|
|
|
NSArray *activeFolderFeeds = [self.activeFeedLocations objectForKey:folderName];
|
|
|
|
NSArray *originalFolder = [self.dictFolders objectForKey:folderName];
|
|
|
|
for (int f=0; f < [activeFolderFeeds count]; f++) {
|
|
|
|
int location = [[activeFolderFeeds objectAtIndex:f] intValue];
|
|
|
|
id feedId = [originalFolder objectAtIndex:location];
|
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:f inSection:s];
|
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
|
|
|
int maxScore = [NewsBlurViewController computeMaxScoreForFeed:feed];
|
|
|
|
|
2011-08-16 19:55:44 -07:00
|
|
|
if (maxScore < intelligenceLevel &&
|
|
|
|
![self.stillVisibleFeeds objectForKey:feedIdStr]) {
|
2011-08-04 17:27:31 -07:00
|
|
|
[indexPaths addObject:indexPath];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!self.viewShowingAllFeeds) {
|
|
|
|
[self calculateFeedLocations];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self.feedTitlesTable beginUpdates];
|
|
|
|
if ([indexPaths count] > 0) {
|
|
|
|
if (self.viewShowingAllFeeds) {
|
|
|
|
[self.feedTitlesTable insertRowsAtIndexPaths:indexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
} else {
|
|
|
|
[self.feedTitlesTable deleteRowsAtIndexPaths:indexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[self.feedTitlesTable endUpdates];
|
2011-08-16 19:55:44 -07:00
|
|
|
|
|
|
|
// Forget still visible feeds, since they won't be populated when
|
|
|
|
// all feeds are showing, and shouldn't be populated after this
|
|
|
|
// hide/show runs.
|
|
|
|
self.stillVisibleFeeds = [NSMutableDictionary dictionary];
|
2011-08-03 10:00:41 -07:00
|
|
|
}
|
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Table View - Feed List
|
|
|
|
|
|
|
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
|
|
|
return [self.dictFoldersArray count];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
2011-08-02 18:03:11 -07:00
|
|
|
return [self.dictFoldersArray objectAtIndex:section];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
2011-08-02 18:03:11 -07:00
|
|
|
NSString *folderName = [self.dictFoldersArray objectAtIndex:section];
|
|
|
|
return [[self.activeFeedLocations objectForKey:folderName] count];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
|
2011-08-02 18:03:11 -07:00
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView
|
|
|
|
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
2011-07-18 09:56:48 -07:00
|
|
|
static NSString *FeedCellIdentifier = @"FeedCellIdentifier";
|
2010-06-20 11:04:23 -04:00
|
|
|
|
2011-07-19 09:38:49 -07:00
|
|
|
FeedTableCell *cell = (FeedTableCell *)[tableView dequeueReusableCellWithIdentifier:FeedCellIdentifier];
|
2010-06-20 11:04:23 -04:00
|
|
|
if (cell == nil) {
|
2011-08-11 10:06:10 -07:00
|
|
|
cell = [[[FeedTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"FeedCellIdentifier"] autorelease];
|
2011-08-18 09:56:52 -07:00
|
|
|
cell.appDelegate = (NewsBlurAppDelegate *)[[UIApplication sharedApplication] delegate];
|
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
|
2011-08-02 18:03:11 -07:00
|
|
|
NSString *folderName = [self.dictFoldersArray objectAtIndex:indexPath.section];
|
|
|
|
NSArray *feeds = [self.dictFolders objectForKey:folderName];
|
|
|
|
NSArray *activeFolderFeeds = [self.activeFeedLocations objectForKey:folderName];
|
|
|
|
int location = [[activeFolderFeeds objectAtIndex:indexPath.row] intValue];
|
|
|
|
id feedId = [feeds objectAtIndex:location];
|
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
2011-08-12 10:12:30 -07:00
|
|
|
cell.feedTitle = [feed objectForKey:@"feed_title"];
|
2011-08-03 10:00:41 -07:00
|
|
|
|
|
|
|
NSString *favicon = [feed objectForKey:@"favicon"];
|
2011-08-04 17:27:31 -07:00
|
|
|
if ((NSNull *)favicon != [NSNull null] && [favicon length] > 0) {
|
2011-08-03 10:00:41 -07:00
|
|
|
NSData *imageData = [NSData dataWithBase64EncodedString:favicon];
|
2011-08-12 10:12:30 -07:00
|
|
|
cell.feedFavicon = [UIImage imageWithData:imageData];
|
2011-08-03 10:00:41 -07:00
|
|
|
} else {
|
2011-08-12 10:12:30 -07:00
|
|
|
cell.feedFavicon = [UIImage imageNamed:@"world.png"];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
2011-08-11 10:06:10 -07:00
|
|
|
|
|
|
|
cell.positiveCount = [[feed objectForKey:@"ps"] intValue];
|
2011-08-13 17:08:26 -07:00
|
|
|
cell.neutralCount = [[feed objectForKey:@"nt"] intValue];
|
2011-08-11 10:06:10 -07:00
|
|
|
cell.negativeCount = [[feed objectForKey:@"ng"] intValue];
|
2010-06-20 11:04:23 -04:00
|
|
|
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
2011-08-12 10:12:30 -07:00
|
|
|
- (void)tableView:(UITableView *)tableView
|
|
|
|
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
2011-08-02 18:19:46 -07:00
|
|
|
NSString *folderName = [self.dictFoldersArray objectAtIndex:indexPath.section];
|
|
|
|
NSArray *feeds = [self.dictFolders objectForKey:folderName];
|
|
|
|
NSArray *activeFolderFeeds = [self.activeFeedLocations objectForKey:folderName];
|
|
|
|
int location = [[activeFolderFeeds objectAtIndex:indexPath.row] intValue];
|
|
|
|
id feedId = [feeds objectAtIndex:location];
|
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
2011-08-15 17:57:37 -07:00
|
|
|
|
2011-08-16 19:55:44 -07:00
|
|
|
// If all feeds are already showing, no need to remember this one.
|
|
|
|
if (!self.viewShowingAllFeeds) {
|
|
|
|
[self.stillVisibleFeeds setObject:indexPath forKey:feedIdStr];
|
|
|
|
}
|
2011-08-15 17:57:37 -07:00
|
|
|
|
2011-08-02 18:19:46 -07:00
|
|
|
[appDelegate setActiveFeed:feed];
|
|
|
|
[appDelegate setActiveFeedIndexPath:indexPath];
|
2010-06-27 19:35:17 -04:00
|
|
|
|
2010-06-25 18:36:01 -04:00
|
|
|
[appDelegate loadFeedDetailView];
|
2010-06-20 11:04:23 -04:00
|
|
|
}
|
|
|
|
|
2011-08-12 10:12:30 -07:00
|
|
|
- (CGFloat)tableView:(UITableView *)tableView
|
|
|
|
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
2011-07-19 09:38:49 -07:00
|
|
|
return kTableViewRowHeight;
|
|
|
|
}
|
|
|
|
|
2011-08-12 10:12:30 -07:00
|
|
|
- (UIView *)tableView:(UITableView *)tableView
|
|
|
|
viewForHeaderInSection:(NSInteger)section {
|
|
|
|
// create the parent view that will hold header Label
|
|
|
|
UIView* customView = [[[UIView alloc]
|
|
|
|
initWithFrame:CGRectMake(0.0, 0.0,
|
|
|
|
tableView.bounds.size.width, 21.0)]
|
|
|
|
autorelease];
|
|
|
|
|
|
|
|
|
|
|
|
UIView *borderBottom = [[[UIView alloc]
|
|
|
|
initWithFrame:CGRectMake(0.0, 20.0,
|
|
|
|
tableView.bounds.size.width, 1.0)]
|
|
|
|
autorelease];
|
|
|
|
borderBottom.backgroundColor = [UIColorFromRGB(0xB7BDC6) colorWithAlphaComponent:0.5];
|
|
|
|
borderBottom.opaque = NO;
|
|
|
|
[customView addSubview:borderBottom];
|
|
|
|
|
|
|
|
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
|
|
|
customView.backgroundColor = [UIColorFromRGB(0xD7DDE6)
|
|
|
|
colorWithAlphaComponent:0.8];
|
|
|
|
customView.opaque = NO;
|
|
|
|
headerLabel.backgroundColor = [UIColor clearColor];
|
|
|
|
headerLabel.opaque = NO;
|
|
|
|
headerLabel.textColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1.0];
|
|
|
|
headerLabel.highlightedTextColor = [UIColor whiteColor];
|
|
|
|
headerLabel.font = [UIFont boldSystemFontOfSize:11];
|
2011-08-13 17:08:26 -07:00
|
|
|
headerLabel.frame = CGRectMake(36.0, 1.0, 286.0, 20.0);
|
2011-08-12 10:12:30 -07:00
|
|
|
headerLabel.text = [[self.dictFoldersArray objectAtIndex:section] uppercaseString];
|
|
|
|
headerLabel.shadowColor = [UIColor colorWithRed:.94 green:0.94 blue:0.97 alpha:1.0];
|
|
|
|
headerLabel.shadowOffset = CGSizeMake(1.0, 1.0);
|
|
|
|
[customView addSubview:headerLabel];
|
|
|
|
[headerLabel release];
|
|
|
|
|
|
|
|
UIImage *folderImage = [UIImage imageNamed:@"folder.png"];
|
|
|
|
UIImageView *folderImageView = [[UIImageView alloc] initWithImage:folderImage];
|
2011-08-13 17:08:26 -07:00
|
|
|
folderImageView.frame = CGRectMake(14.0, 2.0, 16.0, 16.0);
|
2011-08-12 10:12:30 -07:00
|
|
|
[customView addSubview:folderImageView];
|
|
|
|
[folderImageView release];
|
|
|
|
|
|
|
|
return customView;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
|
2011-08-13 17:08:26 -07:00
|
|
|
NSString *folder = [self.dictFoldersArray objectAtIndex:section];
|
|
|
|
if ([[folder stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
2011-08-12 10:12:30 -07:00
|
|
|
return 21;
|
|
|
|
}
|
|
|
|
|
2011-08-02 09:16:54 -07:00
|
|
|
- (IBAction)selectIntelligence {
|
2011-08-04 17:27:31 -07:00
|
|
|
if (!self.viewShowingAllFeeds) {
|
|
|
|
NSInteger newLevel = [self.intelligenceControl selectedSegmentIndex] - 1;
|
|
|
|
NSInteger previousLevel = [appDelegate selectedIntelligence];
|
2011-08-16 10:11:08 -07:00
|
|
|
// NSLog(@"Select Intelligence from %d to %d.", previousLevel, newLevel);
|
2011-08-04 17:27:31 -07:00
|
|
|
[self updateFeedsWithIntelligence:previousLevel newLevel:newLevel];
|
|
|
|
}
|
2011-08-18 09:56:52 -07:00
|
|
|
|
|
|
|
for (UITableViewCell *cell in self.feedTitlesTable.visibleCells) {
|
|
|
|
[cell setNeedsDisplay];
|
|
|
|
}
|
2011-08-02 18:19:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)updateFeedsWithIntelligence:(int)previousLevel newLevel:(int)newLevel {
|
2011-08-02 09:16:54 -07:00
|
|
|
NSMutableArray *insertIndexPaths = [NSMutableArray array];
|
|
|
|
NSMutableArray *deleteIndexPaths = [NSMutableArray array];
|
2011-08-04 17:27:31 -07:00
|
|
|
|
2011-08-02 09:16:54 -07:00
|
|
|
if (newLevel < previousLevel) {
|
|
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
2011-08-02 10:13:06 -07:00
|
|
|
[self calculateFeedLocations];
|
2011-08-02 09:16:54 -07:00
|
|
|
}
|
|
|
|
|
2011-08-15 17:57:37 -07:00
|
|
|
BOOL deleted = NO;
|
|
|
|
// BOOL inserted = NO;
|
|
|
|
|
2011-08-02 10:13:06 -07:00
|
|
|
for (int s=0; s < [self.dictFoldersArray count]; s++) {
|
2011-08-02 18:03:11 -07:00
|
|
|
NSString *folderName = [self.dictFoldersArray objectAtIndex:s];
|
|
|
|
NSArray *activeFolderFeeds = [self.activeFeedLocations objectForKey:folderName];
|
|
|
|
NSArray *originalFolder = [self.dictFolders objectForKey:folderName];
|
|
|
|
for (int f=0; f < [activeFolderFeeds count]; f++) {
|
|
|
|
int location = [[activeFolderFeeds objectAtIndex:f] intValue];
|
|
|
|
id feedId = [originalFolder objectAtIndex:location];
|
2011-08-02 10:13:06 -07:00
|
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:f inSection:s];
|
2011-08-02 18:03:11 -07:00
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
|
|
|
int maxScore = [NewsBlurViewController computeMaxScoreForFeed:feed];
|
2011-08-15 17:57:37 -07:00
|
|
|
deleted = NO;
|
|
|
|
// inserted = NO;
|
2011-08-02 10:13:06 -07:00
|
|
|
|
2011-08-02 18:03:11 -07:00
|
|
|
if (previousLevel == -1) {
|
|
|
|
if (newLevel == 0 && maxScore == -1) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
deleted = YES;
|
2011-08-02 18:03:11 -07:00
|
|
|
} else if (newLevel == 1 && maxScore < 1) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
deleted = YES;
|
2011-08-02 18:03:11 -07:00
|
|
|
}
|
|
|
|
} else if (previousLevel == 0) {
|
|
|
|
if (newLevel == -1 && maxScore == -1) {
|
|
|
|
[insertIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
// inserted = YES;
|
2011-08-02 18:03:11 -07:00
|
|
|
} else if (newLevel == 1 && maxScore == 0) {
|
|
|
|
[deleteIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
deleted = YES;
|
2011-08-02 18:03:11 -07:00
|
|
|
}
|
|
|
|
} else if (previousLevel == 1) {
|
|
|
|
if (newLevel == 0 && maxScore == 0) {
|
|
|
|
[insertIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
// inserted = YES;
|
2011-08-03 10:00:41 -07:00
|
|
|
} else if (newLevel == -1 && (maxScore == -1 || maxScore == 0)) {
|
2011-08-02 18:03:11 -07:00
|
|
|
[insertIndexPaths addObject:indexPath];
|
2011-08-15 17:57:37 -07:00
|
|
|
// inserted = YES;
|
2011-08-02 18:03:11 -07:00
|
|
|
}
|
|
|
|
}
|
2011-08-15 17:57:37 -07:00
|
|
|
|
2011-08-18 09:56:52 -07:00
|
|
|
BOOL isVisible = !![self.stillVisibleFeeds objectForKey:feedIdStr];
|
2011-08-16 10:11:08 -07:00
|
|
|
BOOL notDeletedYetVisible = !deleted &&
|
|
|
|
previousLevel != newLevel &&
|
2011-08-15 17:57:37 -07:00
|
|
|
(maxScore < newLevel) &&
|
2011-08-18 09:56:52 -07:00
|
|
|
isVisible;
|
2011-08-15 17:57:37 -07:00
|
|
|
if (notDeletedYetVisible) {
|
2011-08-16 10:11:08 -07:00
|
|
|
// NSLog(@"DELETING: %@ - %d - %d - %d - %d", [feed objectForKey:@"feed_title"], maxScore, newLevel, previousLevel, !deleted);
|
2011-08-15 17:57:37 -07:00
|
|
|
[deleteIndexPaths addObject:indexPath];
|
|
|
|
[self.stillVisibleFeeds removeObjectForKey:feedIdStr];
|
2011-08-18 09:56:52 -07:00
|
|
|
} else if (deleted && isVisible) {
|
|
|
|
[self.stillVisibleFeeds removeObjectForKey:feedIdStr];
|
2011-08-15 17:57:37 -07:00
|
|
|
}
|
2011-08-02 18:03:11 -07:00
|
|
|
}
|
|
|
|
}
|
2011-08-16 10:11:08 -07:00
|
|
|
|
|
|
|
for (id feedIdStr in [self.stillVisibleFeeds allKeys]) {
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
|
|
|
int maxScore = [NewsBlurViewController computeMaxScoreForFeed:feed];
|
|
|
|
if (previousLevel != newLevel && maxScore < newLevel) {
|
2011-08-18 09:56:52 -07:00
|
|
|
NSLog(@"Still visible: %@ - %d - %d - %d", [feed objectForKey:@"feed_title"], maxScore, newLevel, previousLevel);
|
2011-08-16 10:11:08 -07:00
|
|
|
[deleteIndexPaths addObject:[self.stillVisibleFeeds objectForKey:feedIdStr]];
|
|
|
|
[self.stillVisibleFeeds removeObjectForKey:feedIdStr];
|
|
|
|
}
|
|
|
|
}
|
2011-08-02 09:16:54 -07:00
|
|
|
|
|
|
|
if (newLevel > previousLevel) {
|
|
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
2011-08-02 10:13:06 -07:00
|
|
|
[self calculateFeedLocations];
|
2011-08-02 09:16:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
[self.feedTitlesTable beginUpdates];
|
|
|
|
if ([deleteIndexPaths count] > 0) {
|
|
|
|
[self.feedTitlesTable deleteRowsAtIndexPaths:deleteIndexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
}
|
|
|
|
if ([insertIndexPaths count] > 0) {
|
|
|
|
[self.feedTitlesTable insertRowsAtIndexPaths:insertIndexPaths
|
|
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
|
|
}
|
|
|
|
[self.feedTitlesTable endUpdates];
|
2011-08-02 10:13:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)calculateFeedLocations {
|
|
|
|
self.activeFeedLocations = [NSMutableDictionary dictionary];
|
2011-08-02 18:03:11 -07:00
|
|
|
for (NSString *folderName in self.dictFoldersArray) {
|
|
|
|
NSArray *folder = [self.dictFolders objectForKey:folderName];
|
2011-08-02 10:13:06 -07:00
|
|
|
NSMutableArray *feedLocations = [NSMutableArray array];
|
|
|
|
for (int f=0; f < [folder count]; f++) {
|
2011-08-02 18:03:11 -07:00
|
|
|
id feedId = [folder objectAtIndex:f];
|
|
|
|
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
|
2011-08-04 17:27:31 -07:00
|
|
|
|
|
|
|
if (self.viewShowingAllFeeds) {
|
2011-08-02 10:13:06 -07:00
|
|
|
NSNumber *location = [NSNumber numberWithInt:f];
|
|
|
|
[feedLocations addObject:location];
|
2011-08-04 17:27:31 -07:00
|
|
|
} else {
|
|
|
|
int maxScore = [NewsBlurViewController computeMaxScoreForFeed:feed];
|
|
|
|
if (maxScore >= appDelegate.selectedIntelligence) {
|
|
|
|
NSNumber *location = [NSNumber numberWithInt:f];
|
|
|
|
[feedLocations addObject:location];
|
|
|
|
}
|
2011-08-02 10:13:06 -07:00
|
|
|
}
|
|
|
|
}
|
2011-08-02 18:03:11 -07:00
|
|
|
[self.activeFeedLocations setObject:feedLocations forKey:folderName];
|
2011-08-02 10:13:06 -07:00
|
|
|
}
|
2011-08-02 09:16:54 -07:00
|
|
|
}
|
|
|
|
|
2011-08-02 18:03:11 -07:00
|
|
|
+ (int)computeMaxScoreForFeed:(NSDictionary *)feed {
|
|
|
|
int maxScore = -2;
|
|
|
|
if ([[feed objectForKey:@"ng"] intValue] > 0) maxScore = -1;
|
|
|
|
if ([[feed objectForKey:@"nt"] intValue] > 0) maxScore = 0;
|
|
|
|
if ([[feed objectForKey:@"ps"] intValue] > 0) maxScore = 1;
|
|
|
|
return maxScore;
|
|
|
|
}
|
|
|
|
|
2011-08-04 17:58:28 -07:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Favicons
|
|
|
|
|
|
|
|
|
|
|
|
- (void)loadFavicons {
|
2011-08-12 10:12:30 -07:00
|
|
|
NSString *urlString = @"http://www.newsblur.com/reader/favicons";
|
2011-08-04 17:58:28 -07:00
|
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
|
|
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
|
2011-08-04 18:25:38 -07:00
|
|
|
|
|
|
|
[request setDidFinishSelector:@selector(saveAndDrawFavicons:)];
|
|
|
|
[request setDidFailSelector:@selector(requestFailed:)];
|
2011-08-04 17:58:28 -07:00
|
|
|
[request setDelegate:self];
|
|
|
|
[request startAsynchronous];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)saveAndDrawFavicons:(ASIHTTPRequest *)request {
|
|
|
|
NSString *responseString = [request responseString];
|
|
|
|
NSDictionary *results = [[NSDictionary alloc]
|
|
|
|
initWithDictionary:[responseString JSONValue]];
|
2011-08-04 18:25:38 -07:00
|
|
|
|
|
|
|
for (id feed_id in results) {
|
|
|
|
NSDictionary *feed = [self.dictFeeds objectForKey:feed_id];
|
|
|
|
[feed setValue:[results objectForKey:feed_id] forKey:@"favicon"];
|
|
|
|
[self.dictFeeds setValue:feed forKey:feed_id];
|
|
|
|
}
|
|
|
|
|
2011-08-12 10:12:30 -07:00
|
|
|
[results release];
|
2011-08-04 18:25:38 -07:00
|
|
|
[self.feedTitlesTable reloadData];
|
2011-08-04 17:58:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)requestFailed:(ASIHTTPRequest *)request {
|
|
|
|
NSError *error = [request error];
|
|
|
|
NSLog(@"Error: %@", error);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark PullToRefresh
|
|
|
|
|
|
|
|
// called when the user pulls-to-refresh
|
|
|
|
- (void)pullToRefreshViewShouldRefresh:(PullToRefreshView *)view {
|
2011-08-13 23:00:51 -07:00
|
|
|
[self fetchFeedList:NO];
|
2011-08-04 17:58:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// called when the date shown needs to be updated, optional
|
|
|
|
- (NSDate *)pullToRefreshViewLastUpdated:(PullToRefreshView *)view {
|
|
|
|
return self.lastUpdate;
|
|
|
|
}
|
|
|
|
|
2010-06-20 11:04:23 -04:00
|
|
|
@end
|
2010-11-13 13:42:20 -05:00
|
|
|
|
|
|
|
|
|
|
|
@implementation LogoutDelegate
|
|
|
|
|
|
|
|
@synthesize appDelegate;
|
|
|
|
|
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
|
|
|
|
|
|
|
}
|
|
|
|
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
2010-11-15 19:40:17 -05:00
|
|
|
appDelegate = [[UIApplication sharedApplication] delegate];
|
2010-11-13 13:42:20 -05:00
|
|
|
NSLog(@"Logout: %@", appDelegate);
|
|
|
|
[appDelegate reloadFeedsView];
|
|
|
|
}
|
|
|
|
|
2011-08-18 09:56:52 -07:00
|
|
|
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
|
|
|
NSLog(@"%@", [NSString stringWithFormat:@"Connection failed: %@", [error description]]);
|
|
|
|
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
|
|
|
|
|
|
// User clicking on another link before the page loads is OK.
|
|
|
|
if ([error code] != NSURLErrorCancelled) {
|
|
|
|
[NewsBlurAppDelegate informError:error];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-13 13:42:20 -05:00
|
|
|
@end
|