Permalink
Browse files

Ading pull to refresh on feed detail in iphone app. Not done, but als…

…o added extra parameter in feed canonical model that gives seconds since last update.
  • Loading branch information...
samuelclay committed Aug 18, 2011
1 parent bffb8a6 commit 442012fdeb58f9c2d1183c707a73a93dfae568ed
View
@@ -26,6 +26,7 @@
from utils.feed_functions import levenshtein_distance
from utils.feed_functions import timelimit, TimeoutError
from utils.feed_functions import relative_timesince
+from utils.feed_functions import seconds_timesince
from utils.story_functions import pre_process_story
from utils.diff import HTMLDiff
@@ -71,6 +72,7 @@ def canonical(self, full=False, include_favicon=True):
'feed_link': self.feed_link,
'num_subscribers': self.num_subscribers,
'updated': relative_timesince(self.last_update),
+ 'updated_seconds_ago': seconds_timesince(self.last_update),
'subs': self.num_subscribers,
'favicon_color': self.favicon_color,
'favicon_fetching': bool(not (self.favicon_not_found or self.favicon_color))
View
@@ -5,3 +5,5 @@ ServerAliveCountMax=6
StrictHostKeyChecking=no
Compression=yes
ForwardAgent=yes
+ControlMaster auto
+ControlPath /tmp/ssh_mux_%h_%p_%r
View
@@ -1,4 +1,5 @@
# Path to your oh-my-zsh configuration.
+plugins=(git osx ruby gem github pip rails)
export ZSH=$HOME/.oh-my-zsh
# Set to the name theme to load.
@@ -10,7 +11,8 @@ export CASE_SENSITIVE="true"
export LC_COLLATE='C'
source $ZSH/oh-my-zsh.sh
-export PROMPT='%{$fg_bold[green]%}%n@%M:%{$fg_bold[blue]%}%~ $(git_prompt_info)%{$reset_color%}%(!.#.$) '
+
+export DISABLE_AUTO_UPDATE="true"
export PYTHONSTARTUP=$HOME/.pystartup
export LSCOLORS='gxgxcxdxBxegedabagacad'
@@ -32,7 +34,7 @@ zle -N expand-or-complete-with-dots
bindkey "^I" expand-or-complete-with-dots
unsetopt LIST_BEEP
-PROMPT='%{$fg_bold[green]%}%n%{$reset_color%}%{$fg[yellow]%}@%M:%{$fg_bold[blue]%}%~%b $(git_prompt_info)%{$reset_color%}%(!.#.$) '
+PROMPT='%{$fg_bold[green]%}%n%{$reset_color%}%{$fg_bold[yellow]%}@%M:%{$fg_bold[blue]%}%~%b $(git_prompt_info)%{$reset_color%}%(!.#.$) '
ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg[red]%}‹%B"
ZSH_THEME_GIT_PROMPT_SUFFIX="%b%{$fg[red]%}›%{$reset_color%}"
View
@@ -13,6 +13,7 @@ body {
height: 100%;
overflow: hidden;
text-rendering: optimizeLegibility;
+ background-color: white;
}
a, a:active, a:hover, a:visited, button {
@@ -7,6 +7,7 @@
//
#import <UIKit/UIKit.h>
+#import "PullToRefreshView.h"
@class NewsBlurAppDelegate;
@@ -25,6 +26,7 @@
UISlider * feedScoreSlider;
UIBarButtonItem * feedMarkReadButton;
UISegmentedControl * intelligenceControl;
+ PullToRefreshView *pull;
}
- (void)fetchFeedDetail:(int)page;
@@ -34,13 +36,16 @@
- (NSDictionary *)getStoryAtRow:(NSInteger)indexPathRow;
- (void)checkScroll;
- (void)markedAsRead;
+- (void)pullToRefreshViewShouldRefresh:(PullToRefreshView *)view;
+- (NSDate *)pullToRefreshViewLastUpdated:(PullToRefreshView *)view;
@property (nonatomic, retain) IBOutlet NewsBlurAppDelegate *appDelegate;
@property (nonatomic, retain) IBOutlet UITableView *storyTitlesTable;
@property (nonatomic, retain) IBOutlet UIToolbar *feedViewToolbar;
@property (nonatomic, retain) IBOutlet UISlider * feedScoreSlider;
@property (nonatomic, retain) IBOutlet UIBarButtonItem * feedMarkReadButton;
@property (nonatomic, retain) IBOutlet UISegmentedControl * intelligenceControl;
+@property (nonatomic, retain) PullToRefreshView *pull;
@property (nonatomic, retain) NSArray * stories;
@property (nonatomic, retain) NSMutableData * jsonString;
@@ -9,6 +9,7 @@
#import "FeedDetailViewController.h"
#import "NewsBlurAppDelegate.h"
#import "FeedDetailTableCell.h"
+#import "PullToRefreshView.h"
#import "ASIFormDataRequest.h"
#import "NSString+HTML.h"
#import "JSON.h"
@@ -25,6 +26,7 @@ @implementation FeedDetailViewController
@synthesize pageFetching;
@synthesize pageFinished;
@synthesize intelligenceControl;
+@synthesize pull;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
@@ -33,6 +35,13 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)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;
self.title = [appDelegate.activeFeed objectForKey:@"feed_title"];
@@ -82,6 +91,7 @@ - (void)dealloc {
[appDelegate release];
[jsonString release];
[intelligenceControl release];
+ [pull release];
[super dealloc];
}
@@ -188,6 +198,13 @@ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)err
[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 {
@@ -415,4 +432,19 @@ - (NSDictionary *)getStoryAtRow:(NSInteger)indexPathRow {
return [appDelegate.activeFeedStories objectAtIndex:row];
}
+
+#pragma mark -
+#pragma mark PullToRefresh
+
+// called when the user pulls-to-refresh
+- (void)pullToRefreshViewShouldRefresh:(PullToRefreshView *)view {
+// [self fetchFeedList:NO];
+}
+
+// called when the date shown needs to be updated, optional
+- (NSDate *)pullToRefreshViewLastUpdated:(PullToRefreshView *)view {
+// return self.lastUpdate;
+}
+
+
@end
@@ -83,6 +83,7 @@
- (void)markActiveFeedAllRead;
- (void)calculateStoryLocations;
+ (int)computeStoryScore:(NSDictionary *)intelligence;
++ (void)informError:(NSError *)error;
@end
@@ -283,4 +283,15 @@ + (int)computeStoryScore:(NSDictionary *)intelligence {
return score;
}
++ (void)informError:(NSError *)error {
+ NSString* localizedDescription = [error localizedDescription];
+ UIAlertView* alertView = [[UIAlertView alloc]
+ initWithTitle:@"Error"
+ message:localizedDescription delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil];
+ [alertView show];
+ [alertView release];
+}
+
@end
@@ -178,6 +178,16 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"%@", [NSString stringWithFormat:@"Connection failed: %@", [error description]]);
+
+ [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];
+ }
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
@@ -329,6 +339,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView
FeedTableCell *cell = (FeedTableCell *)[tableView dequeueReusableCellWithIdentifier:FeedCellIdentifier];
if (cell == nil) {
cell = [[[FeedTableCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"FeedCellIdentifier"] autorelease];
+ cell.appDelegate = (NewsBlurAppDelegate *)[[UIApplication sharedApplication] delegate];
+
}
NSString *folderName = [self.dictFoldersArray objectAtIndex:indexPath.section];
@@ -438,7 +450,10 @@ - (IBAction)selectIntelligence {
// NSLog(@"Select Intelligence from %d to %d.", previousLevel, newLevel);
[self updateFeedsWithIntelligence:previousLevel newLevel:newLevel];
}
- // TODO: Refresh cells on screen to show correct unread pills.
+
+ for (UITableViewCell *cell in self.feedTitlesTable.visibleCells) {
+ [cell setNeedsDisplay];
+ }
}
- (void)updateFeedsWithIntelligence:(int)previousLevel newLevel:(int)newLevel {
@@ -493,23 +508,26 @@ - (void)updateFeedsWithIntelligence:(int)previousLevel newLevel:(int)newLevel {
}
}
+ BOOL isVisible = !![self.stillVisibleFeeds objectForKey:feedIdStr];
BOOL notDeletedYetVisible = !deleted &&
previousLevel != newLevel &&
(maxScore < newLevel) &&
- [self.stillVisibleFeeds objectForKey:feedIdStr];
+ isVisible;
if (notDeletedYetVisible) {
// NSLog(@"DELETING: %@ - %d - %d - %d - %d", [feed objectForKey:@"feed_title"], maxScore, newLevel, previousLevel, !deleted);
[deleteIndexPaths addObject:indexPath];
[self.stillVisibleFeeds removeObjectForKey:feedIdStr];
+ } else if (deleted && isVisible) {
+ [self.stillVisibleFeeds removeObjectForKey:feedIdStr];
}
}
}
for (id feedIdStr in [self.stillVisibleFeeds allKeys]) {
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
int maxScore = [NewsBlurViewController computeMaxScoreForFeed:feed];
-// NSLog(@"Still visible: %@ - %d - %d - %d", [feed objectForKey:@"feed_title"], maxScore, newLevel, previousLevel);
if (previousLevel != newLevel && maxScore < newLevel) {
+ NSLog(@"Still visible: %@ - %d - %d - %d", [feed objectForKey:@"feed_title"], maxScore, newLevel, previousLevel);
[deleteIndexPaths addObject:[self.stillVisibleFeeds objectForKey:feedIdStr]];
[self.stillVisibleFeeds removeObjectForKey:feedIdStr];
}
@@ -634,4 +652,15 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[appDelegate reloadFeedsView];
}
+- (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];
+ }
+}
+
@end
@@ -52,6 +52,5 @@ static const CGFloat kButtonWidth = 48.0f;
- (void)updateTitle:(UIWebView*)aWebView;
- (void)updateAddress:(NSURLRequest*)request;
- (void)updateButtons;
-- (void)informError:(NSError*)error;
@end
@@ -180,7 +180,7 @@ - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
// User clicking on another link before the page loads is OK.
if ([error code] != NSURLErrorCancelled) {
- [self informError:error];
+ [NewsBlurAppDelegate informError:error];
}
}
- (void)updateTitle:(UIWebView*)aWebView
@@ -200,17 +200,6 @@ - (void)updateButtons
self.back.enabled = self.webView.canGoBack;
// self.stop.enabled = self.webView.loading;
}
-- (void)informError:(NSError *)error
-{
- NSString* localizedDescription = [error localizedDescription];
- UIAlertView* alertView = [[UIAlertView alloc]
- initWithTitle:@"Error"
- message:localizedDescription delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil];
- [alertView show];
- [alertView release];
-}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
@@ -248,9 +237,9 @@ - (IBAction)doOpenActionSheet {
NSArray *buttonTitles;
if ([[appDelegate.activeOriginalStoryURL absoluteString] isEqualToString:self.pageUrl.text]) {
- buttonTitles = [NSArray arrayWithObjects:@"Open story in Safari", nil];
+ buttonTitles = [NSArray arrayWithObjects:@"Open Story in Safari", nil];
} else {
- buttonTitles = [NSArray arrayWithObjects:@"Open this page in Safari", @"Open original in Safari", nil];
+ buttonTitles = [NSArray arrayWithObjects:@"Open this Page in Safari", @"Open Original in Safari", nil];
}
for (id title in buttonTitles) {
[options addButtonWithTitle:title];
@@ -308,7 +308,7 @@ - (void)setActiveStory {
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
-
+ self.activeStoryId = nil;
// Release any cached data, images, etc that aren't in use.
}
@@ -6,6 +6,8 @@
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
+ <key>CFBundleDocumentTypes</key>
+ <array/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@@ -24,20 +26,26 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>1</string>
+ <string></string>
<key>CFBundleSignature</key>
<string>????</string>
+ <key>CFBundleURLTypes</key>
+ <array/>
<key>CFBundleVersion</key>
- <string>1.0</string>
+ <string>1.0b3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
+ <key>UIPrerenderedIcon</key>
+ <true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
- <key>UIPrerenderedIcon</key>
- <true/>
+ <key>UTExportedTypeDeclarations</key>
+ <array/>
+ <key>UTImportedTypeDeclarations</key>
+ <array/>
</dict>
</plist>
@@ -7,10 +7,14 @@
//
#import <UIKit/UIKit.h>
+#import "NewsBlurAppDelegate.h"
#import "ABTableViewCell.h"
+@class NewsBlurAppDelegate;
@interface FeedTableCell : ABTableViewCell {
+ NewsBlurAppDelegate *appDelegate;
+
NSString *feedTitle;
UIImage *feedFavicon;
int _positiveCount;
@@ -21,6 +25,7 @@
NSString *_negativeCountStr;
}
+@property (nonatomic, retain) NewsBlurAppDelegate *appDelegate;
@property (nonatomic, retain) NSString *feedTitle;
@property (nonatomic, retain) UIImage *feedFavicon;
@property (assign, nonatomic) int positiveCount;
Oops, something went wrong.

0 comments on commit 442012f

Please sign in to comment.