Adding interactivity for tapping authors and tags and updating their classifier inline. Just need to hook them up to the server for persistence, update unread counts, and possibly update stories inline.

This commit is contained in:
Samuel Clay 2012-12-07 17:18:31 -08:00
parent 8af4e1b6e6
commit 51f396532e
7 changed files with 149 additions and 72 deletions

View file

@ -413,7 +413,7 @@
[self loadFaviconsFromActiveFeed];
}
appDelegate.activeClassifiers = [results objectForKey:@"classifiers"];
appDelegate.activeClassifiers = [[results objectForKey:@"classifiers"] mutableCopy];
NSArray *newStories = [results objectForKey:@"stories"];
NSMutableArray *confirmedNewStories = [[NSMutableArray alloc] init];

View file

@ -88,7 +88,7 @@
BOOL inFindingStoryMode;
NSString *tryFeedStoryId;
NSDictionary * activeFeed;
NSDictionary * activeClassifiers;
NSMutableDictionary * activeClassifiers;
NSString * activeFolder;
NSDictionary * activeComment;
NSString * activeShareType;
@ -171,7 +171,7 @@
@property (nonatomic, readwrite) BOOL inFeedDetail;
@property (nonatomic, readwrite) BOOL inStoryDetail;
@property (readwrite) NSDictionary * activeFeed;
@property (readwrite) NSDictionary * activeClassifiers;
@property (readwrite) NSMutableDictionary * activeClassifiers;
@property (readwrite) NSString * activeFolder;
@property (readwrite) NSDictionary * activeComment;
@property (readwrite) NSString * activeShareType;

View file

@ -57,6 +57,7 @@
- (void)finishSubscribeToBlurblog:(ASIHTTPRequest *)request;
- (void)requestFailed:(ASIHTTPRequest *)request;
- (void)setActiveStoryAtIndex:(NSInteger)activeStoryIndex;
- (NSString *)getHeader;
- (NSString *)getShareBar;
- (NSString *)getComments;
- (NSString *)getComment:(NSDictionary *)commentDict;
@ -64,6 +65,9 @@
- (NSString *)getAvatars:(NSString *)key;
- (NSDictionary *)getUser:(int)user_id;
- (void)toggleAuthorClassifier:(NSString *)author;
- (void)toggleTagClassifier:(NSString *)tag;
- (void)refreshHeader;
@end

View file

@ -171,69 +171,13 @@
"</div></a>"
"</div>"
"</div></div>"];
NSString *story_author = @"";
if ([self.activeStory objectForKey:@"story_authors"]) {
NSString *author = [NSString stringWithFormat:@"%@",
[self.activeStory objectForKey:@"story_authors"]];
if (author && ![author isEqualToString:@"<null>"]) {
int author_score = [[[appDelegate.activeClassifiers objectForKey:@"authors"] objectForKey:author] intValue];
story_author = [NSString stringWithFormat:@"<div class=\"NB-story-author %@\">%@</div>", author_score > 0 ? @"NB-story-author-positive" : author_score < 0 ? @"NB-story-author-negative" : @"",
author];
}
}
NSString *story_tags = @"";
if ([self.activeStory objectForKey:@"story_tags"]) {
NSArray *tag_array = [self.activeStory objectForKey:@"story_tags"];
if ([tag_array count] > 0) {
NSMutableArray *tag_strings = [NSMutableArray array];
for (NSString *tag in tag_array) {
int tag_score = [[[appDelegate.activeClassifiers objectForKey:@"tags"] objectForKey:tag] intValue];
NSLog(@"Tag %@: %d", tag, tag_score);
NSString *tag_html = [NSString stringWithFormat:@"<div class=\"NB-story-tag %@\">%@</div>", tag_score > 0 ? @"NB-story-tag-positive" : tag_score < 0 ? @"NB-story-tag-negative" : @"",
tag];
[tag_strings addObject:tag_html];
}
story_tags = [NSString
stringWithFormat:@"<div class=\"NB-story-tags\">"
"%@"
"</div>",
[tag_strings componentsJoinedByString:@""]];
}
}
NSString *story_title = [self.activeStory objectForKey:@"story_title"];
for (NSString *title_classifier in [appDelegate.activeClassifiers objectForKey:@"titles"]) {
if ([story_title containsString:title_classifier]) {
int title_score = [[[appDelegate.activeClassifiers objectForKey:@"titles"]
objectForKey:title_classifier] intValue];
story_title = [story_title
stringByReplacingOccurrencesOfString:title_classifier
withString:[NSString stringWithFormat:@"<span class=\"NB-story-title-%@\">%@</span>",
title_score > 0 ? @"positive" : title_score < 0 ? @"negative" : @"",
title_classifier]];
}
}
NSString *storyHeader = [NSString stringWithFormat:@
"<div class=\"NB-header\"><div class=\"NB-header-inner\">"
"<div class=\"NB-story-date\">%@</div>"
"<div class=\"NB-story-title\">%@</div>"
"%@"
"%@"
"</div></div>",
[story_tags length] ?
[self.activeStory
objectForKey:@"long_parsed_date"] :
[self.activeStory
objectForKey:@"short_parsed_date"],
story_title,
story_author,
story_tags];
NSString *storyHeader = [self getHeader];
NSString *htmlString = [NSString stringWithFormat:@
"<html>"
"<head>%@</head>" // header string
"<body id=\"story_pane\" class=\"%@\">"
" %@" // storyHeader
" <div id=\"NB-header-container\">%@</div>" // storyHeader
" %@" // shareBar
" <div class=\"%@\" id=\"NB-font-style\">"
" <div class=\"%@\" id=\"NB-font-size\">"
@ -263,11 +207,8 @@
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString
//baseURL:[NSURL URLWithString:feed_link]];
baseURL:baseURL];
[webView loadHTMLString:htmlString baseURL:baseURL];
NSDictionary *feed;
NSString *feedIdStr = [NSString stringWithFormat:@"%@",
[self.activeStory
@ -283,8 +224,9 @@
feed = [appDelegate.dictFeeds objectForKey:feedIdStr];
}
self.feedTitleGradient = [appDelegate makeFeedTitleGradient:feed
withRect:CGRectMake(0, -1, self.view.frame.size.width, 21)]; // 1024 hack for self.webView.frame.size.width
self.feedTitleGradient = [appDelegate
makeFeedTitleGradient:feed
withRect:CGRectMake(0, -1, self.view.frame.size.width, 21)]; // 1024 hack for self.webView.frame.size.width
self.feedTitleGradient.tag = FEED_TITLE_GRADIENT_TAG; // Not attached yet. Remove old gradients, first.
[self.feedTitleGradient.layer setShadowColor:[[UIColor blackColor] CGColor]];
@ -335,6 +277,72 @@
#pragma mark -
#pragma mark Story layout
- (NSString *)getHeader {
NSString *story_author = @"";
if ([self.activeStory objectForKey:@"story_authors"]) {
NSString *author = [NSString stringWithFormat:@"%@",
[self.activeStory objectForKey:@"story_authors"]];
if (author && ![author isEqualToString:@"<null>"]) {
int author_score = [[[appDelegate.activeClassifiers objectForKey:@"authors"] objectForKey:author] intValue];
story_author = [NSString stringWithFormat:@"<a href=\"http://ios.newsblur.com/classify-author/%@\" "
"class=\"NB-story-author %@\">%@</a>",
author,
author_score > 0 ? @"NB-story-author-positive" : author_score < 0 ? @"NB-story-author-negative" : @"",
author];
}
}
NSString *story_tags = @"";
if ([self.activeStory objectForKey:@"story_tags"]) {
NSArray *tag_array = [self.activeStory objectForKey:@"story_tags"];
if ([tag_array count] > 0) {
NSMutableArray *tag_strings = [NSMutableArray array];
for (NSString *tag in tag_array) {
int tag_score = [[[appDelegate.activeClassifiers objectForKey:@"tags"] objectForKey:tag] intValue];
NSLog(@"Tag %@: %d", tag, tag_score);
NSString *tag_html = [NSString stringWithFormat:@"<a href=\"http://ios.newsblur.com/classify-tag/%@\" "
"class=\"NB-story-tag %@\">%@</a>",
tag,
tag_score > 0 ? @"NB-story-tag-positive" : tag_score < 0 ? @"NB-story-tag-negative" : @"",
tag];
[tag_strings addObject:tag_html];
}
story_tags = [NSString
stringWithFormat:@"<div class=\"NB-story-tags\">"
"%@"
"</div>",
[tag_strings componentsJoinedByString:@""]];
}
}
NSString *story_title = [self.activeStory objectForKey:@"story_title"];
for (NSString *title_classifier in [appDelegate.activeClassifiers objectForKey:@"titles"]) {
if ([story_title containsString:title_classifier]) {
int title_score = [[[appDelegate.activeClassifiers objectForKey:@"titles"]
objectForKey:title_classifier] intValue];
story_title = [story_title
stringByReplacingOccurrencesOfString:title_classifier
withString:[NSString stringWithFormat:@"<span class=\"NB-story-title-%@\">%@</span>",
title_score > 0 ? @"positive" : title_score < 0 ? @"negative" : @"",
title_classifier]];
}
}
NSString *storyHeader = [NSString stringWithFormat:@
"<div class=\"NB-header\"><div class=\"NB-header-inner\">"
"<div class=\"NB-story-date\">%@</div>"
"<div class=\"NB-story-title\">%@</div>"
"%@"
"%@"
"</div></div>",
[story_tags length] ?
[self.activeStory objectForKey:@"long_parsed_date"] :
[self.activeStory objectForKey:@"short_parsed_date"],
story_title,
story_author,
story_tags];
return storyHeader;
}
- (NSString *)getAvatars:(NSString *)key {
NSString *avatarString = @"";
NSArray *share_user_ids = [self.activeStory objectForKey:key];
@ -348,7 +356,8 @@
}
NSString *avatar = [NSString stringWithFormat:@
"<div class=\"NB-story-share-profile\"><div class=\"%@\">"
"<a id=\"NB-user-share-bar-%@\" class=\"NB-show-profile\" href=\"http://ios.newsblur.com/show-profile/%@\"><img src=\"%@\" /></a>"
"<a id=\"NB-user-share-bar-%@\" class=\"NB-show-profile\" "
" href=\"http://ios.newsblur.com/show-profile/%@\"><img src=\"%@\" /></a>"
"</div></div>",
avatarClass,
[user objectForKey:@"user_id"],
@ -856,7 +865,17 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
return NO;
} else if ([action isEqualToString:@"share"]) {
[self openShareDialog];
return NO;
return NO;
} else if ([action isEqualToString:@"classify-author"]) {
NSString *author = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
NSLog(@"Author: %@", author);
[self toggleAuthorClassifier:author];
return NO;
} else if ([action isEqualToString:@"classify-tag"]) {
NSString *tag = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
NSLog(@"Tag: %@", tag);
[self toggleTagClassifier:tag];
return NO;
} else if ([action isEqualToString:@"show-profile"]) {
appDelegate.activeUserProfileId = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
@ -1209,4 +1228,45 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
// self.webView.hidden = NO;
}
#pragma mark -
#pragma mark Classifiers
- (void)toggleAuthorClassifier:(NSString *)author {
int author_score = [[[appDelegate.activeClassifiers objectForKey:@"authors"] objectForKey:author] intValue];
if (author_score > 0) {
author_score = -1;
} else if (author_score < 0) {
author_score = 0;
} else {
author_score = 1;
}
NSMutableDictionary *authors = [[appDelegate.activeClassifiers objectForKey:@"authors"] mutableCopy];
[authors setObject:[NSNumber numberWithInt:author_score] forKey:author];
[appDelegate.activeClassifiers setObject:authors forKey:@"authors"];
[appDelegate.storyPageControl refreshHeaders];
}
- (void)toggleTagClassifier:(NSString *)tag {
int tag_score = [[[appDelegate.activeClassifiers objectForKey:@"tags"] objectForKey:tag] intValue];
if (tag_score > 0) {
tag_score = -1;
} else if (tag_score < 0) {
tag_score = 0;
} else {
tag_score = 1;
}
NSMutableDictionary *tags = [[appDelegate.activeClassifiers objectForKey:@"tags"] mutableCopy];
[tags setObject:[NSNumber numberWithInt:tag_score] forKey:tag];
[appDelegate.activeClassifiers setObject:tags forKey:@"tags"];
[appDelegate.storyPageControl refreshHeaders];
}
- (void)refreshHeader {
NSString *headerString = [[self getHeader] stringByReplacingOccurrencesOfString:@"\'" withString:@"\\'"];
NSString *jsString = [NSString stringWithFormat:@"document.getElementById('NB-header-container').innerHTML = '%@';",
headerString];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
@end

View file

@ -67,6 +67,7 @@
- (void)transitionFromFeedDetail;
- (void)resetPages;
- (void)refreshPages;
- (void)refreshHeaders;
- (void)setStoryFromScroll;
- (void)setStoryFromScroll:(BOOL)force;
- (void)updatePageWithActiveStory:(int)location;

View file

@ -237,6 +237,11 @@
// self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width * currentPage.pageIndex, 0);
}
- (void)refreshHeaders {
[currentPage refreshHeader];
[nextPage refreshHeader];
[previousPage refreshHeader];
}
- (void)resizeScrollView {
NSInteger widthCount = self.appDelegate.storyLocationsCount;
if (widthCount == 0) {

View file

@ -148,6 +148,7 @@ body.NB-iphone {
.NB-story-author {
color: #969696;
text-decoration: none;
text-transform: uppercase;
margin: 4px 8px 0px 0;
margin-bottom: 8px;
@ -171,6 +172,7 @@ body.NB-iphone {
.NB-story-tag {
float: left;
text-decoration: none;
font-weight: normal;
padding: 0px 4px 0px;
margin: 0px 4px 4px 0;
@ -418,7 +420,7 @@ a.NB-show-profile {
/* Disable certain interactions on touch devices */
.NB-button,
.NB-show-profile.a {
.NB-show-profile.a {
-webkit-text-size-adjust: none;
-webkit-user-select: none;
-webkit-highlight: none;
@ -426,6 +428,11 @@ a.NB-show-profile {
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
.NB-header {
-webkit-user-select: none;
-webkit-highlight: none;
}
.NB-share-button {
line-height: 20px;
font-family: Helvetica, sans-serif;