mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-08-05 16:58:59 +00:00
558 lines
22 KiB
Objective-C
558 lines
22 KiB
Objective-C
//
|
|
// FeedDetailViewController.m
|
|
// NewsBlur
|
|
//
|
|
// Created by Samuel Clay on 6/20/10.
|
|
// Copyright 2010 NewsBlur. All rights reserved.
|
|
//
|
|
|
|
#import "FeedDetailViewController.h"
|
|
#import "NewsBlurAppDelegate.h"
|
|
#import "FeedDetailTableCell.h"
|
|
#import "PullToRefreshView.h"
|
|
#import "ASIFormDataRequest.h"
|
|
#import "NSString+HTML.h"
|
|
#import "Base64.h"
|
|
#import "JSON.h"
|
|
|
|
#define kTableViewRowHeight 65;
|
|
|
|
#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]
|
|
|
|
@implementation FeedDetailViewController
|
|
|
|
@synthesize storyTitlesTable, feedViewToolbar, feedScoreSlider, feedMarkReadButton;
|
|
@synthesize stories;
|
|
@synthesize appDelegate;
|
|
@synthesize feedPage;
|
|
@synthesize pageFetching;
|
|
@synthesize pageRefreshing;
|
|
@synthesize pageFinished;
|
|
@synthesize intelligenceControl;
|
|
@synthesize pull;
|
|
|
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
|
|
|
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)viewDidLoad {
|
|
pull = [[PullToRefreshView alloc] initWithScrollView:self.storyTitlesTable];
|
|
[pull setDelegate:self];
|
|
[self.storyTitlesTable addSubview:pull];
|
|
|
|
[super viewDidLoad];
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
|
self.pageFinished = NO;
|
|
|
|
UIView *titleView = [[UIView alloc] init];
|
|
|
|
UILabel *titleLabel = [[[UILabel alloc] init] autorelease];
|
|
titleLabel.text = [NSString stringWithFormat:@" %@", [appDelegate.activeFeed objectForKey:@"feed_title"]];
|
|
titleLabel.backgroundColor = [UIColor clearColor];
|
|
titleLabel.textAlignment = UITextAlignmentLeft;
|
|
titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:15.0];
|
|
titleLabel.textColor = [UIColor whiteColor];
|
|
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
|
|
titleLabel.shadowColor = [UIColor blackColor];
|
|
titleLabel.shadowOffset = CGSizeMake(0, -1);
|
|
titleLabel.center = CGPointMake(28, -2);
|
|
[titleLabel sizeToFit];
|
|
|
|
|
|
UIImage *titleImage;
|
|
NSString *favicon = [appDelegate.activeFeed objectForKey:@"favicon"];
|
|
if ((NSNull *)favicon != [NSNull null] && [favicon length] > 0) {
|
|
NSData *imageData = [NSData dataWithBase64EncodedString:favicon];
|
|
titleImage = [UIImage imageWithData:imageData];
|
|
} else {
|
|
titleImage = [UIImage imageNamed:@"world.png"];
|
|
}
|
|
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:titleImage];
|
|
titleImageView.frame = CGRectMake(0.0, 2.0, 16.0, 16.0);
|
|
// self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:titleImageView] autorelease];
|
|
[titleLabel addSubview:titleImageView];
|
|
// [titleView addSubview:titleImageView];
|
|
[titleImageView release];
|
|
|
|
self.navigationItem.titleView = titleLabel;
|
|
// self.navigationItem.title = [appDelegate.activeFeed objectForKey:@"feed_title"];
|
|
|
|
[titleView release];
|
|
|
|
NSMutableArray *indexPaths = [NSMutableArray array];
|
|
for (id i in appDelegate.recentlyReadStories) {
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[i intValue]
|
|
inSection:0];
|
|
// NSLog(@"Read story: %d", [i intValue]);
|
|
[indexPaths addObject:indexPath];
|
|
}
|
|
if ([indexPaths count] > 0) {
|
|
[self.storyTitlesTable beginUpdates];
|
|
[self.storyTitlesTable reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
|
|
[self.storyTitlesTable endUpdates];
|
|
}
|
|
[appDelegate setRecentlyReadStories:[NSMutableArray array]];
|
|
[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];
|
|
[self.intelligenceControl setSelectedSegmentIndex:[appDelegate selectedIntelligence]+1];
|
|
[super viewWillAppear:animated];
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
|
// [[storyTitlesTable cellForRowAtIndexPath:[storyTitlesTable indexPathForSelectedRow]] setSelected:NO]; // TODO: DESELECT CELL --- done, see line below:
|
|
[self.storyTitlesTable deselectRowAtIndexPath:[storyTitlesTable indexPathForSelectedRow] animated:YES];
|
|
[super viewDidAppear:animated];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[storyTitlesTable release];
|
|
[feedViewToolbar release];
|
|
[feedScoreSlider release];
|
|
[feedMarkReadButton release];
|
|
[stories release];
|
|
[appDelegate release];
|
|
[intelligenceControl release];
|
|
[pull release];
|
|
[super dealloc];
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Initialization
|
|
|
|
- (void)resetFeedDetail {
|
|
self.pageFetching = NO;
|
|
self.pageFinished = NO;
|
|
self.pageRefreshing = NO;
|
|
self.feedPage = 1;
|
|
}
|
|
|
|
- (void)fetchNextPage:(void(^)())callback {
|
|
[self fetchFeedDetail:self.feedPage+1 withCallback:callback];
|
|
}
|
|
|
|
- (void)fetchFeedDetail:(int)page withCallback:(void(^)())callback {
|
|
if ([appDelegate.activeFeed objectForKey:@"id"] != nil && !self.pageFetching && !self.pageFinished) {
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
|
|
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];
|
|
}
|
|
|
|
NSString *theFeedDetailURL = [NSString stringWithFormat:@"http://%@/reader/feed/%@?page=%d",
|
|
NEWSBLUR_URL,
|
|
[appDelegate.activeFeed objectForKey:@"id"],
|
|
self.feedPage];
|
|
NSURL *urlFeedDetail = [NSURL URLWithString:theFeedDetailURL];
|
|
|
|
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:urlFeedDetail];
|
|
[request setDelegate:self];
|
|
[request setResponseEncoding:NSUTF8StringEncoding];
|
|
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
|
|
[request setFailedBlock:^(void) {
|
|
[self failLoadingFeed:request];
|
|
}];
|
|
[request setCompletionBlock:^(void) {
|
|
[self finishedLoadingFeed:request];
|
|
if (callback) {
|
|
callback();
|
|
}
|
|
}];
|
|
[request setTimeOutSeconds:30];
|
|
[request setTag:[[[appDelegate activeFeed] objectForKey:@"id"] intValue]];
|
|
[request startAsynchronous];
|
|
}
|
|
}
|
|
|
|
- (void)failLoadingFeed:(ASIHTTPRequest *)request {
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
|
|
if (self.feedPage <= 1) {
|
|
[appDelegate.navigationController
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
objectAtIndex:0]
|
|
animated:YES];
|
|
}
|
|
|
|
[NewsBlurAppDelegate informError:[request error]];
|
|
}
|
|
|
|
- (void)finishedLoadingFeed:(ASIHTTPRequest *)request {
|
|
NSString *responseString = [request responseString];
|
|
NSDictionary *results = [[NSDictionary alloc]
|
|
initWithDictionary:[responseString JSONValue]];
|
|
|
|
if (request.tag == [[results objectForKey:@"feed_id"] intValue]) {
|
|
[pull finishedLoading];
|
|
[self renderStories:[results objectForKey:@"stories"]];
|
|
}
|
|
|
|
[results release];
|
|
}
|
|
|
|
- (void)renderStories:(NSArray *)newStories {
|
|
NSInteger existingStoriesCount = [[appDelegate activeFeedStoryLocations] count];
|
|
NSInteger newStoriesCount = [newStories count];
|
|
|
|
if (self.feedPage == 1) {
|
|
[appDelegate setStories:newStories];
|
|
} else if (newStoriesCount > 0) {
|
|
[appDelegate addStories:newStories];
|
|
}
|
|
|
|
NSInteger newVisibleStoriesCount = [[appDelegate activeFeedStoryLocations] count] - existingStoriesCount;
|
|
|
|
// NSLog(@"Paging: %d/%d", existingStoriesCount, [appDelegate unreadCount]);
|
|
|
|
if (existingStoriesCount > 0 && newVisibleStoriesCount > 0) {
|
|
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
|
|
for (int i=0; i < newVisibleStoriesCount; i++) {
|
|
[indexPaths addObject:[NSIndexPath indexPathForRow:(existingStoriesCount+i)
|
|
inSection:0]];
|
|
}
|
|
[self.storyTitlesTable beginUpdates];
|
|
[self.storyTitlesTable insertRowsAtIndexPaths:indexPaths
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
[self.storyTitlesTable endUpdates];
|
|
[indexPaths release];
|
|
} else if (newVisibleStoriesCount > 0) {
|
|
[self.storyTitlesTable reloadData];
|
|
} else if (newStoriesCount == 0 ||
|
|
(self.feedPage > 15 &&
|
|
existingStoriesCount >= [appDelegate unreadCount])) {
|
|
self.pageFinished = YES;
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:existingStoriesCount
|
|
inSection:0];
|
|
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
|
|
[self.storyTitlesTable beginUpdates];
|
|
[self.storyTitlesTable reloadRowsAtIndexPaths:indexPaths
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
[self.storyTitlesTable endUpdates];
|
|
}
|
|
|
|
self.pageFetching = NO;
|
|
|
|
[self performSelector:@selector(checkScroll)
|
|
withObject:nil
|
|
afterDelay:0.2];
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
}
|
|
|
|
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
|
[connection release];
|
|
|
|
// inform the user
|
|
NSLog(@"Connection failed! Error - %@",
|
|
[error localizedDescription]);
|
|
|
|
self.pageFetching = NO;
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
|
|
// User clicking on another link before the page loads is OK.
|
|
if ([error code] != NSURLErrorCancelled) {
|
|
[NewsBlurAppDelegate informError:error];
|
|
}
|
|
}
|
|
|
|
- (UITableViewCell *)makeLoadingCell {
|
|
UITableViewCell *cell = [[[UITableViewCell alloc]
|
|
initWithStyle:UITableViewCellStyleSubtitle
|
|
reuseIdentifier:@"NoReuse"] autorelease];
|
|
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
|
|
if (self.pageFinished) {
|
|
UIView * blue = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 321, 17)];
|
|
[cell.contentView addSubview:blue];
|
|
blue.backgroundColor = [UIColor whiteColor];
|
|
[UIView beginAnimations:nil context:NULL];
|
|
[UIView setAnimationDuration:0.5f];
|
|
blue.backgroundColor = [UIColor colorWithRed:.7f green:0.7f blue:0.7f alpha:1.0f];
|
|
[UIView commitAnimations];
|
|
[blue release];
|
|
} else {
|
|
cell.textLabel.text = @"Loading...";
|
|
|
|
UIActivityIndicatorView *spinner = [[[UIActivityIndicatorView alloc]
|
|
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] autorelease];
|
|
UIImage *spacer = [UIImage imageNamed:@"spacer"];
|
|
UIGraphicsBeginImageContext(spinner.frame.size);
|
|
[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];
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Table View - Feed List
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
|
if (self.pageRefreshing) {
|
|
// Refreshing feed
|
|
return 1;
|
|
} else {
|
|
int storyCount = [[appDelegate activeFeedStoryLocations] count];
|
|
|
|
// The +1 is for the finished/loading bar.
|
|
return storyCount + 1;
|
|
}
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView
|
|
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
static NSString *FeedDetailCellIdentifier = @"FeedDetailCellIdentifier";
|
|
|
|
FeedDetailTableCell *cell = (FeedDetailTableCell *)[tableView dequeueReusableCellWithIdentifier:FeedDetailCellIdentifier];
|
|
if (cell == nil) {
|
|
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FeedDetailTableCell"
|
|
owner:self
|
|
options:nil];
|
|
for (id oneObject in nib) {
|
|
if ([oneObject isKindOfClass:[FeedDetailTableCell class]]) {
|
|
cell = (FeedDetailTableCell *)oneObject;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (indexPath.row >= [[appDelegate activeFeedStoryLocations] count]) {
|
|
return [self makeLoadingCell];
|
|
}
|
|
|
|
NSDictionary *story = [self getStoryAtRow:indexPath.row];
|
|
if ([[story objectForKey:@"story_authors"] class] != [NSNull class]) {
|
|
cell.storyAuthor.text = [[story objectForKey:@"story_authors"]
|
|
uppercaseString];
|
|
} else {
|
|
cell.storyAuthor.text = @"";
|
|
}
|
|
|
|
NSString *title = [story objectForKey:@"story_title"];
|
|
cell.storyTitle.text = [title stringByDecodingHTMLEntities];
|
|
cell.storyDate.text = [story objectForKey:@"short_parsed_date"];
|
|
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
|
|
if (score > 0) {
|
|
cell.storyUnreadIndicator.image = [UIImage imageNamed:@"bullet_green.png"];
|
|
} else if (score == 0) {
|
|
cell.storyUnreadIndicator.image = [UIImage imageNamed:@"bullet_yellow.png"];
|
|
} else if (score < 0) {
|
|
cell.storyUnreadIndicator.image = [UIImage imageNamed:@"bullet_red.png"];
|
|
}
|
|
|
|
if ([[story objectForKey:@"read_status"] intValue] != 1) {
|
|
// Unread story
|
|
cell.storyTitle.textColor = [UIColor colorWithRed:0.1f green:0.1f blue:0.1f alpha:1.0];
|
|
cell.storyTitle.font = [UIFont fontWithName:@"Helvetica-Bold" size:13];
|
|
cell.storyAuthor.textColor = [UIColor colorWithRed:0.58f green:0.58f blue:0.58f alpha:1.0];
|
|
cell.storyAuthor.font = [UIFont fontWithName:@"Helvetica-Bold" size:10];
|
|
cell.storyDate.textColor = [UIColor colorWithRed:0.14f green:0.18f blue:0.42f alpha:1.0];
|
|
cell.storyDate.font = [UIFont fontWithName:@"Helvetica-Bold" size:10];
|
|
cell.storyUnreadIndicator.alpha = 1;
|
|
|
|
} else {
|
|
// Read story
|
|
cell.storyTitle.textColor = [UIColor colorWithRed:0.15f green:0.25f blue:0.25f alpha:0.9];
|
|
cell.storyTitle.font = [UIFont fontWithName:@"Helvetica" size:12];
|
|
cell.storyAuthor.textColor = [UIColor colorWithRed:0.58f green:0.58f blue:0.58f alpha:0.5];
|
|
cell.storyAuthor.font = [UIFont fontWithName:@"Helvetica-Bold" size:10];
|
|
cell.storyDate.textColor = [UIColor colorWithRed:0.14f green:0.18f blue:0.42f alpha:0.5];
|
|
cell.storyDate.font = [UIFont fontWithName:@"Helvetica" size:10];
|
|
cell.storyUnreadIndicator.alpha = 0.15f;
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
if (indexPath.row < [appDelegate.activeFeedStoryLocations count]) {
|
|
int location = [[[appDelegate activeFeedStoryLocations] objectAtIndex:indexPath.row] intValue];
|
|
[appDelegate setActiveStory:[[appDelegate activeFeedStories] objectAtIndex:location]];
|
|
[appDelegate setOriginalStoryCount:[appDelegate unreadCount]];
|
|
[appDelegate loadStoryDetailView];
|
|
}
|
|
}
|
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
if (indexPath.row >= [[appDelegate activeFeedStoryLocations] count]) {
|
|
if (self.pageFinished) return 16;
|
|
else return kTableViewRowHeight;
|
|
} else {
|
|
return kTableViewRowHeight;
|
|
}
|
|
}
|
|
|
|
- (void)scrollViewDidScroll: (UIScrollView *)scroll {
|
|
[self checkScroll];
|
|
}
|
|
|
|
- (void)checkScroll {
|
|
NSInteger currentOffset = self.storyTitlesTable.contentOffset.y;
|
|
NSInteger maximumOffset = self.storyTitlesTable.contentSize.height - self.storyTitlesTable.frame.size.height;
|
|
|
|
if (maximumOffset - currentOffset <= 60.0) {
|
|
[self fetchFeedDetail:self.feedPage+1 withCallback:nil];
|
|
}
|
|
}
|
|
|
|
- (IBAction)markAllRead {
|
|
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];
|
|
[appDelegate markActiveFeedAllRead];
|
|
[appDelegate.navigationController
|
|
popToViewController:[appDelegate.navigationController.viewControllers
|
|
objectAtIndex:0]
|
|
animated:YES];
|
|
}
|
|
|
|
- (void)markedAsRead {
|
|
|
|
}
|
|
|
|
- (IBAction)selectIntelligence {
|
|
NSInteger newLevel = [self.intelligenceControl selectedSegmentIndex] - 1;
|
|
NSInteger previousLevel = [appDelegate selectedIntelligence];
|
|
NSMutableArray *insertIndexPaths = [NSMutableArray array];
|
|
NSMutableArray *deleteIndexPaths = [NSMutableArray array];
|
|
|
|
if (newLevel == previousLevel) return;
|
|
|
|
if (newLevel < previousLevel) {
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
|
[appDelegate calculateStoryLocations];
|
|
}
|
|
|
|
for (int i=0; i < [[appDelegate activeFeedStoryLocations] count]; i++) {
|
|
int location = [[[appDelegate activeFeedStoryLocations] objectAtIndex:i] intValue];
|
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
|
|
NSDictionary *story = [appDelegate.activeFeedStories objectAtIndex:location];
|
|
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];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (newLevel > previousLevel) {
|
|
[appDelegate setSelectedIntelligence:newLevel];
|
|
[appDelegate calculateStoryLocations];
|
|
}
|
|
|
|
[self.storyTitlesTable beginUpdates];
|
|
if ([deleteIndexPaths count] > 0) {
|
|
[self.storyTitlesTable deleteRowsAtIndexPaths:deleteIndexPaths
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
}
|
|
if ([insertIndexPaths count] > 0) {
|
|
[self.storyTitlesTable insertRowsAtIndexPaths:insertIndexPaths
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
}
|
|
[self.storyTitlesTable endUpdates];
|
|
|
|
[self performSelector:@selector(checkScroll)
|
|
withObject:nil
|
|
afterDelay:1.0];
|
|
}
|
|
|
|
- (NSDictionary *)getStoryAtRow:(NSInteger)indexPathRow {
|
|
int row = [[[appDelegate activeFeedStoryLocations] objectAtIndex:indexPathRow] intValue];
|
|
return [appDelegate.activeFeedStories objectAtIndex:row];
|
|
}
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark PullToRefresh
|
|
|
|
// called when the user pulls-to-refresh
|
|
- (void)pullToRefreshViewShouldRefresh:(PullToRefreshView *)view {
|
|
NSString *urlString = [NSString
|
|
stringWithFormat:@"http://%@/reader/refresh_feed/%@",
|
|
NEWSBLUR_URL,
|
|
[appDelegate.activeFeed objectForKey:@"id"]];
|
|
NSURL *url = [NSURL URLWithString:urlString];
|
|
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
|
|
[request setDelegate:self];
|
|
[request setResponseEncoding:NSUTF8StringEncoding];
|
|
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
|
|
[request setDidFinishSelector:@selector(finishedRefreshingFeed:)];
|
|
[request setDidFailSelector:@selector(failRefreshingFeed:)];
|
|
[request setTimeOutSeconds:60];
|
|
[request startAsynchronous];
|
|
|
|
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
|
|
[appDelegate setStories:nil];
|
|
self.feedPage = 1;
|
|
self.pageFetching = YES;
|
|
self.pageRefreshing = 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]];
|
|
[pull finishedLoading];
|
|
self.pageRefreshing = NO;
|
|
[self renderStories:[results objectForKey:@"stories"]];
|
|
|
|
[results release];
|
|
}
|
|
|
|
- (void)failRefreshingFeed:(ASIHTTPRequest *)request {
|
|
NSLog(@"Fail: %@", request);
|
|
self.pageRefreshing = NO;
|
|
[NewsBlurAppDelegate informError:[request error]];
|
|
[pull finishedLoading];
|
|
[self fetchFeedDetail:1 withCallback:nil];
|
|
}
|
|
|
|
// called when the date shown needs to be updated, optional
|
|
- (NSDate *)pullToRefreshViewLastUpdated:(PullToRefreshView *)view {
|
|
NSLog(@"Updated; %@", [appDelegate.activeFeed objectForKey:@"updated_seconds_ago"]);
|
|
int seconds = -1 * [[appDelegate.activeFeed objectForKey:@"updated_seconds_ago"] intValue];
|
|
return [[[NSDate alloc] initWithTimeIntervalSinceNow:seconds] autorelease];
|
|
}
|
|
|
|
|
|
@end
|