NewsBlur/media/ios/Classes/NewsBlurAppDelegate.m

1987 lines
79 KiB
Mathematica
Raw Normal View History

//
// NewsBlurAppDelegate.m
// NewsBlur
//
// Created by Samuel Clay on 6/16/10.
// Copyright NewsBlur 2010. All rights reserved.
//
#import "NewsBlurAppDelegate.h"
#import "NewsBlurViewController.h"
#import "NBContainerViewController.h"
#import "FeedDetailViewController.h"
2012-07-15 15:06:06 -07:00
#import "DashboardViewController.h"
2012-06-19 10:55:46 -07:00
#import "FeedsMenuViewController.h"
#import "FeedDetailMenuViewController.h"
#import "StoryDetailViewController.h"
#import "StoryPageControl.h"
#import "FirstTimeUserViewController.h"
#import "FriendsListViewController.h"
#import "LoginViewController.h"
#import "AddSiteViewController.h"
#import "MoveSiteViewController.h"
2012-12-24 23:01:25 -08:00
#import "TrainerViewController.h"
#import "OriginalStoryViewController.h"
2012-06-21 11:53:48 -07:00
#import "ShareViewController.h"
2012-07-01 18:26:39 -07:00
#import "UserProfileViewController.h"
2012-07-24 16:03:16 -07:00
#import "NBContainerViewController.h"
#import "AFJSONRequestOperation.h"
#import "InteractionsModule.h"
#import "ActivityModule.h"
2012-08-15 13:04:05 -07:00
#import "FirstTimeUserViewController.h"
#import "FirstTimeUserAddSitesViewController.h"
#import "FirstTimeUserAddFriendsViewController.h"
#import "FirstTimeUserAddNewsBlurViewController.h"
#import "MBProgressHUD.h"
#import "Utilities.h"
#import "StringHelper.h"
#import "AuthorizeServicesViewController.h"
2013-03-06 16:23:17 -08:00
#import "ShareThis.h"
@implementation NewsBlurAppDelegate
2012-11-01 15:26:50 -07:00
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
@synthesize window;
2012-07-22 14:23:50 -07:00
@synthesize ftuxNavigationController;
@synthesize navigationController;
2012-07-31 17:17:02 -07:00
@synthesize modalNavigationController;
2012-08-13 18:45:06 -07:00
@synthesize shareNavigationController;
@synthesize trainNavigationController;
@synthesize userProfileNavigationController;
@synthesize masterContainerViewController;
@synthesize dashboardViewController;
@synthesize feedsViewController;
2012-06-19 10:55:46 -07:00
@synthesize feedsMenuViewController;
@synthesize feedDetailViewController;
@synthesize feedDetailMenuViewController;
2012-06-20 09:32:55 -07:00
@synthesize feedDashboardViewController;
2012-07-01 18:26:39 -07:00
@synthesize friendsListViewController;
@synthesize fontSettingsViewController;
@synthesize storyDetailViewController;
@synthesize storyPageControl;
@synthesize shareViewController;
@synthesize loginViewController;
@synthesize addSiteViewController;
@synthesize moveSiteViewController;
2012-12-24 23:01:25 -08:00
@synthesize trainerViewController;
@synthesize originalStoryViewController;
2012-07-01 18:26:39 -07:00
@synthesize userProfileViewController;
2012-07-22 14:23:50 -07:00
@synthesize firstTimeUserViewController;
@synthesize firstTimeUserAddSitesViewController;
@synthesize firstTimeUserAddFriendsViewController;
@synthesize firstTimeUserAddNewsBlurViewController;
2012-06-20 08:33:16 -07:00
@synthesize feedDetailPortraitYCoordinate;
@synthesize activeUsername;
@synthesize activeUserProfileId;
@synthesize activeUserProfileName;
@synthesize hasNoSites;
@synthesize isRiverView;
2012-06-26 11:45:42 -07:00
@synthesize isSocialView;
2012-08-08 10:57:38 -07:00
@synthesize isSocialRiverView;
@synthesize isTryFeedView;
2012-08-02 18:00:48 -07:00
@synthesize inFindingStoryMode;
2012-07-16 19:45:14 -07:00
@synthesize tryFeedStoryId;
@synthesize tryFeedCategory;
@synthesize popoverHasFeedView;
2012-06-29 23:25:56 -07:00
@synthesize inFeedDetail;
2012-08-02 18:00:48 -07:00
@synthesize inStoryDetail;
2012-06-25 18:05:25 -07:00
@synthesize activeComment;
@synthesize activeShareType;
@synthesize activeFeed;
@synthesize activeClassifiers;
@synthesize activePopularTags;
@synthesize activePopularAuthors;
@synthesize activeFolder;
@synthesize activeFolderFeeds;
@synthesize activeFeedStories;
@synthesize activeFeedStoryLocations;
@synthesize activeFeedStoryLocationIds;
@synthesize activeFeedUserProfiles;
@synthesize activeStory;
@synthesize storyCount;
2012-11-26 09:54:20 -08:00
@synthesize storyLocationsCount;
@synthesize visibleUnreadCount;
@synthesize savedStoriesCount;
@synthesize originalStoryCount;
@synthesize selectedIntelligence;
@synthesize activeOriginalStoryURL;
@synthesize recentlyReadStories;
@synthesize recentlyReadFeeds;
@synthesize readStories;
@synthesize folderCountCache;
@synthesize dictFolders;
@synthesize dictFeeds;
2012-06-26 16:24:19 -07:00
@synthesize dictActiveFeeds;
2012-06-25 15:02:20 -07:00
@synthesize dictSocialFeeds;
@synthesize dictSocialProfile;
2012-07-01 18:26:39 -07:00
@synthesize dictUserProfile;
@synthesize dictSocialServices;
2012-07-26 23:07:47 -07:00
@synthesize userInteractionsArray;
@synthesize userActivitiesArray;
@synthesize dictFoldersArray;
@synthesize categories;
@synthesize categoryFeeds;
+ (NewsBlurAppDelegate*) sharedAppDelegate {
return (NewsBlurAppDelegate*) [UIApplication sharedApplication].delegate;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
2012-06-30 00:02:08 -07:00
NSString *currentiPhoneVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
self.navigationController.delegate = self;
2012-07-24 16:03:16 -07:00
self.navigationController.viewControllers = [NSArray arrayWithObject:self.feedsViewController];
2012-06-30 00:02:08 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[ASIHTTPRequest setDefaultUserAgentString:[NSString stringWithFormat:@"NewsBlur iPad App v%@",
currentiPhoneVersion]];
[window addSubview:self.masterContainerViewController.view];
self.window.rootViewController = self.masterContainerViewController;
} else {
2012-07-24 16:03:16 -07:00
[ASIHTTPRequest setDefaultUserAgentString:[NSString stringWithFormat:@"NewsBlur iPhone App v%@",
currentiPhoneVersion]];
[window addSubview:self.navigationController.view];
2012-07-24 16:03:16 -07:00
self.window.rootViewController = self.navigationController;
}
2012-07-24 16:03:16 -07:00
[window makeKeyAndVisible];
2012-08-09 10:18:15 -07:00
[self.feedsViewController fetchFeedList:YES];
2012-11-01 15:26:50 -07:00
2012-11-08 17:39:32 -08:00
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
2012-11-01 15:26:50 -07:00
splashView = [[UIImageView alloc] init];
2012-11-08 17:39:32 -08:00
int rotate = 0;
if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(@"UPSIDE DOWN");
rotate = -2;
} else if (orientation == UIInterfaceOrientationLandscapeLeft) {
rotate = -1;
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
rotate = 1;
}
splashView.transform = CGAffineTransformMakeRotation(M_PI * rotate * 90.0 / 180);
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad &&
UIInterfaceOrientationIsLandscape(orientation)) {
splashView.frame = self.view.frame;
splashView.image = [UIImage imageNamed:@"Default-Landscape.png"];
} else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-11-01 15:26:50 -07:00
splashView.frame = self.view.frame;
splashView.image = [UIImage imageNamed:@"Default-Portrait.png"];
} else if (IS_IPHONE_5) {
splashView.frame = self.window.frame;
splashView.image = [UIImage imageNamed:@"Default-568h.png"];
} else {
splashView.frame = self.window.frame;
splashView.image = [UIImage imageNamed:@"Default.png"];
}
2012-11-08 17:39:32 -08:00
[splashView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
splashView.alpha = 1.0;
2012-11-01 15:26:50 -07:00
[window addSubview:splashView];
[window bringSubviewToFront:splashView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.6];
2012-11-01 15:26:50 -07:00
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:window cache:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(startupAnimationDone:finished:context:)];
splashView.alpha = 0.0;
// splashView.frame = CGRectMake(-60, -80, 440, 728);
[UIView commitAnimations];
2013-03-06 16:23:17 -08:00
[ShareThis startSessionWithFacebookURLSchemeSuffix:@"newsblur" pocketAPI:@"c23d9HbTT2a8fma098AfIr9zQTgcF0l9" readabilityKey:@"samuelclay" readabilitySecret:@"ktLQc88S9WCE8PfvZ4u4q995Q3HMzg6Q"];
[[UINavigationBar appearance]
setBackgroundImage:[UIImage imageNamed:@"navbar_background.png"]
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance]
setBackgroundImage:[UIImage imageNamed:@"navbar_landscape_background.png"]
forBarMetrics:UIBarMetricsLandscapePhone];
[[UIToolbar appearance]
setBackgroundImage:[UIImage imageNamed:@"toolbar_background.png"]
forToolbarPosition:UIToolbarPositionBottom barMetrics:UIBarMetricsDefault];
[[UIToolbar appearance]
setBackgroundImage:[UIImage imageNamed:@"navbar_background.png"]
forToolbarPosition:UIToolbarPositionTop barMetrics:UIBarMetricsDefault];
[[UIToolbar appearance]
setBackgroundImage:[UIImage imageNamed:@"navbar_landscape_background.png"]
forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsLandscapePhone];
2013-02-28 17:07:51 -08:00
[[UINavigationBar appearance]
setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
UIColorFromRGB(0x404040), UITextAttributeTextColor,
UIColorFromRGB(0xFAFAFA), UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
UITextAttributeTextShadowOffset,
2013-02-28 17:07:51 -08:00
nil]];
2012-08-11 16:58:03 -07:00
// [self showFirstTimeUser];
return YES;
}
- (void)viewDidLoad {
self.visibleUnreadCount = 0;
self.savedStoriesCount = 0;
[self setRecentlyReadStories:[NSMutableArray array]];
}
2012-11-01 15:26:50 -07:00
- (void)startupAnimationDone:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[splashView removeFromSuperview];
}
2013-03-06 16:23:17 -08:00
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:AppDidBecomeActiveNotificationName object:nil];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:AppWillTerminateNotificationName object:nil];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [ShareThis handleFacebookOpenUrl:url];
}
2012-06-29 23:48:47 -07:00
#pragma mark -
#pragma mark Social Views
- (void)showUserProfileModal:(id)sender {
2012-08-02 18:00:48 -07:00
UserProfileViewController *newUserProfile = [[UserProfileViewController alloc] init];
self.userProfileViewController = newUserProfile;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.userProfileViewController];
self.userProfileNavigationController = navController;
// adding Done button
UIBarButtonItem *donebutton = [[UIBarButtonItem alloc]
2012-07-28 14:56:40 -07:00
initWithTitle:@"Close"
style:UIBarButtonItemStyleDone
target:self
action:@selector(hideUserProfileModal)];
2012-08-02 18:00:48 -07:00
newUserProfile.navigationItem.rightBarButtonItem = donebutton;
newUserProfile.navigationItem.title = self.activeUserProfileName;
newUserProfile.navigationItem.backBarButtonItem.title = self.activeUserProfileName;
[newUserProfile getUserProfile];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self.masterContainerViewController showUserProfilePopover:sender];
} else {
[self.navigationController presentModalViewController:navController animated:YES];
}
}
- (void)pushUserProfile {
UserProfileViewController *userProfileView = [[UserProfileViewController alloc] init];
// adding Done button
UIBarButtonItem *donebutton = [[UIBarButtonItem alloc]
2012-07-28 14:56:40 -07:00
initWithTitle:@"Close"
style:UIBarButtonItemStyleDone
target:self
action:@selector(hideUserProfileModal)];
userProfileView.navigationItem.rightBarButtonItem = donebutton;
userProfileView.navigationItem.title = self.activeUserProfileName;
userProfileView.navigationItem.backBarButtonItem.title = self.activeUserProfileName;
2012-07-31 10:24:38 -07:00
[userProfileView getUserProfile];
2012-08-13 23:35:11 -07:00
if (self.modalNavigationController.view.window == nil) {
[self.userProfileNavigationController pushViewController:userProfileView animated:YES];
} else {
[self.modalNavigationController pushViewController:userProfileView animated:YES];
};
}
- (void)hideUserProfileModal {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self.masterContainerViewController hidePopover];
} else {
[self.navigationController dismissModalViewControllerAnimated:YES];
}
}
- (void)showFindFriends {
2012-07-31 15:17:51 -07:00
FriendsListViewController *friendsBVC = [[FriendsListViewController alloc] init];
UINavigationController *friendsNav = [[UINavigationController alloc] initWithRootViewController:friendsListViewController];
2012-07-31 15:17:51 -07:00
self.friendsListViewController = friendsBVC;
2012-07-31 17:17:02 -07:00
self.modalNavigationController = friendsNav;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-31 17:17:02 -07:00
self.modalNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[masterContainerViewController presentModalViewController:modalNavigationController animated:YES];
} else {
2012-07-31 17:17:02 -07:00
[navigationController presentModalViewController:modalNavigationController animated:YES];
}
[self.friendsListViewController loadSuggestedFriendsList];
}
2012-06-29 23:48:47 -07:00
2012-07-20 15:54:10 -07:00
- (void)showShareView:(NSString *)type
setUserId:(NSString *)userId
setUsername:(NSString *)username
setReplyId:(NSString *)replyId {
[self.shareViewController setCommentType:type];
2012-07-12 23:44:14 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-25 20:38:44 -07:00
[self.masterContainerViewController transitionToShareView];
2012-07-12 23:44:14 -07:00
} else {
2012-08-13 18:45:06 -07:00
if (self.shareNavigationController == nil) {
UINavigationController *shareNav = [[UINavigationController alloc]
initWithRootViewController:self.shareViewController];
2012-08-13 18:45:06 -07:00
self.shareNavigationController = shareNav;
}
[self.shareViewController setSiteInfo:type setUserId:userId setUsername:username setReplyId:replyId];
2012-08-13 18:45:06 -07:00
[self.navigationController presentModalViewController:self.shareNavigationController animated:YES];
2012-07-12 23:44:14 -07:00
}
[self.shareViewController setSiteInfo:type setUserId:userId setUsername:username setReplyId:replyId];
}
- (void)hideShareView:(BOOL)resetComment {
if (resetComment) {
self.shareViewController.commentField.text = @"";
2012-08-13 23:54:10 -07:00
self.shareViewController.currentType = nil;
}
2012-07-26 11:11:43 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-25 20:38:44 -07:00
[self.masterContainerViewController transitionFromShareView];
2012-07-12 23:44:14 -07:00
} else {
[self.navigationController dismissModalViewControllerAnimated:YES];
2012-07-26 11:11:43 -07:00
[self.shareViewController.commentField resignFirstResponder];
2012-07-12 23:44:14 -07:00
}
2012-06-29 23:48:47 -07:00
}
- (void)resetShareComments {
[shareViewController clearComments];
}
#pragma mark -
#pragma mark Views
- (void)showLogin {
self.dictFeeds = nil;
self.dictSocialFeeds = nil;
self.dictFolders = nil;
self.dictFoldersArray = nil;
self.userActivitiesArray = nil;
self.userInteractionsArray = nil;
[self.feedsViewController.feedTitlesTable reloadData];
[self.feedsViewController resetToolbar];
[self.dashboardViewController.interactionsModule.interactionsTable reloadData];
[self.dashboardViewController.activitiesModule.activitiesTable reloadData];
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
[userPreferences setInteger:-1 forKey:@"selectedIntelligence"];
[userPreferences synchronize];
2012-06-13 12:19:35 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self.masterContainerViewController presentModalViewController:loginViewController animated:NO];
2012-06-13 12:19:35 -07:00
} else {
2012-06-19 10:55:46 -07:00
[feedsMenuViewController dismissModalViewControllerAnimated:NO];
2012-07-22 14:23:50 -07:00
[self.navigationController presentModalViewController:loginViewController animated:NO];
2012-06-13 12:19:35 -07:00
}
}
- (void)showFirstTimeUser {
2012-08-15 13:04:05 -07:00
// [self.feedsViewController changeToAllMode];
2012-07-22 14:23:50 -07:00
UINavigationController *ftux = [[UINavigationController alloc] initWithRootViewController:self.firstTimeUserViewController];
self.ftuxNavigationController = ftux;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-22 14:23:50 -07:00
self.ftuxNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;
2012-07-24 16:03:16 -07:00
[self.masterContainerViewController presentModalViewController:self.ftuxNavigationController animated:YES];
self.ftuxNavigationController.view.superview.frame = CGRectMake(0, 0, 540, 540);//it's important to do this after
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsPortrait(orientation)) {
self.ftuxNavigationController.view.superview.center = self.view.center;
} else {
self.ftuxNavigationController.view.superview.center = CGPointMake(self.view.center.y, self.view.center.x);
}
} else {
2012-07-22 14:23:50 -07:00
[self.navigationController presentModalViewController:self.ftuxNavigationController animated:YES];
}
}
- (void)showMoveSite {
UINavigationController *navController = self.navigationController;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
moveSiteViewController.modalPresentationStyle=UIModalPresentationFormSheet;
[navController presentModalViewController:moveSiteViewController animated:YES];
} else {
[navController presentModalViewController:moveSiteViewController animated:YES];
}
}
2012-12-24 23:01:25 -08:00
- (void)openTrainSite {
UINavigationController *navController = self.navigationController;
trainerViewController.feedTrainer = YES;
trainerViewController.storyTrainer = NO;
2012-12-24 23:01:25 -08:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// trainerViewController.modalPresentationStyle=UIModalPresentationFormSheet;
// [navController presentModalViewController:trainerViewController animated:YES];
[self.masterContainerViewController showTrainingPopover:self.feedDetailViewController.settingsBarButton];
} else {
if (self.trainNavigationController == nil) {
self.trainNavigationController = [[UINavigationController alloc]
initWithRootViewController:self.trainerViewController];
}
[navController presentModalViewController:self.trainNavigationController animated:YES];
}
}
- (void)openTrainStory:(id)sender {
UINavigationController *navController = self.navigationController;
trainerViewController.feedTrainer = NO;
trainerViewController.storyTrainer = YES;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self.masterContainerViewController showTrainingPopover:sender];
2012-12-24 23:01:25 -08:00
} else {
if (self.trainNavigationController == nil) {
self.trainNavigationController = [[UINavigationController alloc]
initWithRootViewController:self.trainerViewController];
}
[navController presentModalViewController:self.trainNavigationController animated:YES];
2012-12-24 23:01:25 -08:00
}
}
- (void)reloadFeedsView:(BOOL)showLoader {
2012-08-09 10:18:15 -07:00
[feedsViewController fetchFeedList:showLoader];
2012-08-12 16:50:34 -07:00
[loginViewController dismissModalViewControllerAnimated:NO];
}
- (void)loadFeedDetailView {
2012-06-20 07:39:49 -07:00
[self setStories:nil];
[self setFeedUserProfiles:nil];
self.inFeedDetail = YES;
popoverHasFeedView = YES;
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc]
initWithTitle: @"All"
style: UIBarButtonItemStyleBordered
target: nil
action: nil];
[feedsViewController.navigationItem setBackBarButtonItem:newBackButton];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[self.masterContainerViewController transitionToFeedDetail];
} else {
[navigationController pushViewController:feedDetailViewController
animated:YES];
2012-07-20 22:00:30 -07:00
}
[feedDetailViewController resetFeedDetail];
[feedDetailViewController fetchFeedDetail:1 withCallback:nil];
}
2012-11-09 14:13:44 -08:00
- (void)loadTryFeedDetailView:(NSString *)feedId
withStory:(NSString *)contentId
isSocial:(BOOL)social
withUser:(NSDictionary *)user
showFindingStory:(BOOL)showHUD {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[self.navigationController popToRootViewControllerAnimated:NO];
[self.navigationController dismissModalViewControllerAnimated:YES];
if (self.feedsViewController.popoverController) {
[self.feedsViewController.popoverController dismissPopoverAnimated:NO];
}
}
NSDictionary *feed = nil;
if (social) {
feed = [self.dictSocialFeeds objectForKey:feedId];
self.isSocialView = YES;
2012-08-01 12:41:02 -07:00
self.inFindingStoryMode = YES;
if (feed == nil) {
feed = user;
self.isTryFeedView = YES;
}
} else {
feed = [self.dictFeeds objectForKey:feedId];
if (feed == nil) {
feed = user;
self.isTryFeedView = YES;
}
[self setIsSocialView:NO];
[self setInFindingStoryMode:NO];
}
self.tryFeedStoryId = contentId;
self.activeFeed = feed;
self.activeFolder = nil;
2012-07-16 19:45:14 -07:00
[self loadFeedDetailView];
2012-11-09 14:13:44 -08:00
if (showHUD) {
[self.storyPageControl showShareHUD:@"Finding story..."];
2012-11-09 14:13:44 -08:00
}
2012-07-16 19:45:14 -07:00
}
- (BOOL)isSocialFeed:(NSString *)feedIdStr {
if ([feedIdStr length] > 6) {
NSString *feedIdSubStr = [feedIdStr substringToIndex:6];
if ([feedIdSubStr isEqualToString:@"social"]) {
return YES;
}
}
return NO;
}
2012-06-26 12:29:37 -07:00
2012-07-02 13:10:00 -07:00
- (BOOL)isPortrait {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
return YES;
} else {
return NO;
}
}
- (NSString *)orderKey {
if (self.isRiverView) {
return [NSString stringWithFormat:@"folder:%@:order", self.activeFolder];
} else {
return [NSString stringWithFormat:@"%@:order", [self.activeFeed objectForKey:@"id"]];
}
}
- (NSString *)readFilterKey {
if (self.isRiverView) {
return [NSString stringWithFormat:@"folder:%@:read_filter", self.activeFolder];
} else {
return [NSString stringWithFormat:@"%@:read_filter", [self.activeFeed objectForKey:@"id"]];
}
}
- (void)confirmLogout {
UIAlertView *logoutConfirm = [[UIAlertView alloc] initWithTitle:@"Positive?"
message:nil
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Logout", nil];
[logoutConfirm show];
[logoutConfirm setTag:1];
}
- (void)showConnectToService:(NSString *)serviceName {
2013-03-05 08:49:37 -08:00
AuthorizeServicesViewController *serviceVC = [[AuthorizeServicesViewController alloc] init];
serviceVC.url = [NSString stringWithFormat:@"/oauth/%@_connect", serviceName];
serviceVC.type = serviceName;
serviceVC.fromStory = YES;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2013-03-05 08:49:37 -08:00
UINavigationController *connectNav = [[UINavigationController alloc]
initWithRootViewController:serviceVC];
self.modalNavigationController = connectNav;
self.modalNavigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self.masterContainerViewController presentModalViewController:modalNavigationController
animated:YES];
} else {
2013-03-05 08:49:37 -08:00
[self.shareNavigationController pushViewController:serviceVC animated:YES];
}
}
- (void)refreshUserProfile:(void(^)())callback {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/social/load_user_profile",
NEWSBLUR_URL]];
ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:url];
__weak ASIHTTPRequest *request = _request;
[request setResponseEncoding:NSUTF8StringEncoding];
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
[request setFailedBlock:^(void) {
NSLog(@"Failed user profile");
callback();
}];
[request setCompletionBlock:^(void) {
NSString *responseString = [request responseString];
NSData *responseData=[responseString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *results = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
self.dictUserProfile = [results objectForKey:@"user_profile"];
self.dictSocialServices = [results objectForKey:@"services"];
callback();
}];
[request setTimeOutSeconds:30];
[request startAsynchronous];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == 1) { // this is logout
if (buttonIndex == 0) {
return;
} else {
NSLog(@"Logging out...");
NSString *urlS = [NSString stringWithFormat:@"http://%@/reader/logout?api=1",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlS];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setResponseEncoding:NSUTF8StringEncoding];
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
[request setFailedBlock:^(void) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
}];
[request setCompletionBlock:^(void) {
NSLog(@"Logout successful");
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self showLogin];
}];
[request setTimeOutSeconds:30];
[request startAsynchronous];
[ASIHTTPRequest setSessionCookies:nil];
[MBProgressHUD hideHUDForView:self.view animated:YES];
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = @"Logging out...";
}
}
}
2012-06-20 07:39:49 -07:00
- (void)loadRiverFeedDetailView {
[self setStories:nil];
[self setFeedUserProfiles:nil];
2012-06-29 23:25:56 -07:00
self.inFeedDetail = YES;
2012-06-27 14:37:37 -07:00
2012-06-20 07:39:49 -07:00
[feedDetailViewController resetFeedDetail];
[feedDetailViewController fetchRiverPage:1 withCallback:nil];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-24 16:03:16 -07:00
[self.masterContainerViewController transitionToFeedDetail];
} else {
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: @"All"
style: UIBarButtonItemStyleBordered
target: nil
action: nil];
[feedsViewController.navigationItem setBackBarButtonItem: newBackButton];
UINavigationController *navController = self.navigationController;
[navController pushViewController:feedDetailViewController animated:YES];
}
2012-06-20 07:39:49 -07:00
}
- (void)adjustStoryDetailWebView {
// change UIWebView
2012-11-07 17:54:16 -08:00
[storyPageControl.currentPage changeWebViewWidth];
[storyPageControl.nextPage changeWebViewWidth];
[storyPageControl.previousPage changeWebViewWidth];
2012-07-23 15:27:20 -07:00
}
- (void)calibrateStoryTitles {
[self.feedDetailViewController checkScroll];
[self.feedDetailViewController changeActiveFeedDetailRow];
}
- (void)recalculateIntelligenceScores:(id)feedId {
NSString *feedIdStr = [NSString stringWithFormat:@"%@", feedId];
NSMutableArray *newFeedStories = [NSMutableArray array];
for (NSDictionary *story in self.activeFeedStories) {
NSString *storyFeedId = [NSString stringWithFormat:@"%@",
[story objectForKey:@"story_feed_id"]];
if (![storyFeedId isEqualToString:feedIdStr]) {
[newFeedStories addObject:story];
continue;
}
NSMutableDictionary *newStory = [story mutableCopy];
// If the story is visible, mark it as sticky so it doesn;t go away on page loads.
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
if (score >= self.selectedIntelligence) {
[newStory setObject:[NSNumber numberWithBool:YES] forKey:@"sticky"];
}
NSNumber *zero = [NSNumber numberWithInt:0];
NSMutableDictionary *intelligence = [NSMutableDictionary
dictionaryWithObjects:[NSArray arrayWithObjects:
[zero copy], [zero copy],
[zero copy], [zero copy], nil]
forKeys:[NSArray arrayWithObjects:
@"author", @"feed", @"tags", @"title", nil]];
NSDictionary *classifiers = [self.activeClassifiers objectForKey:feedIdStr];
for (NSString *title in [classifiers objectForKey:@"titles"]) {
if ([[intelligence objectForKey:@"title"] intValue] <= 0 &&
[[story objectForKey:@"story_title"] containsString:title]) {
int score = [[[classifiers objectForKey:@"titles"] objectForKey:title] intValue];
[intelligence setObject:[NSNumber numberWithInt:score] forKey:@"title"];
}
}
for (NSString *author in [classifiers objectForKey:@"authors"]) {
if ([[intelligence objectForKey:@"author"] intValue] <= 0 &&
[[story objectForKey:@"story_authors"] class] != [NSNull class] &&
[[story objectForKey:@"story_authors"] containsString:author]) {
int score = [[[classifiers objectForKey:@"authors"] objectForKey:author] intValue];
[intelligence setObject:[NSNumber numberWithInt:score] forKey:@"author"];
}
}
for (NSString *tag in [classifiers objectForKey:@"tags"]) {
if ([[intelligence objectForKey:@"tags"] intValue] <= 0 &&
[[story objectForKey:@"story_tags"] class] != [NSNull class] &&
[[story objectForKey:@"story_tags"] containsObject:tag]) {
int score = [[[classifiers objectForKey:@"tags"] objectForKey:tag] intValue];
[intelligence setObject:[NSNumber numberWithInt:score] forKey:@"tags"];
}
}
for (NSString *feed in [classifiers objectForKey:@"feeds"]) {
if ([[intelligence objectForKey:@"feed"] intValue] <= 0 &&
[storyFeedId isEqualToString:feed]) {
int score = [[[classifiers objectForKey:@"feeds"] objectForKey:feed] intValue];
[intelligence setObject:[NSNumber numberWithInt:score] forKey:@"feed"];
}
}
[newStory setObject:intelligence forKey:@"intelligence"];
[newFeedStories addObject:newStory];
}
self.activeFeedStories = newFeedStories;
}
2012-06-20 08:33:16 -07:00
- (void)dragFeedDetailView:(float)y {
2012-06-24 20:08:39 -07:00
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
if (UIInterfaceOrientationIsPortrait(storyDetailViewController.interfaceOrientation)) {
2012-06-22 19:15:48 -07:00
y = y + 20;
if(y > 955) {
self.feedDetailPortraitYCoordinate = 960;
} else if(y < 950 && y > 200) {
2012-06-20 08:33:16 -07:00
self.feedDetailPortraitYCoordinate = y;
2012-06-22 19:15:48 -07:00
}
2012-06-24 20:08:39 -07:00
[userPreferences setInteger:self.feedDetailPortraitYCoordinate forKey:@"feedDetailPortraitYCoordinate"];
[userPreferences synchronize];
[self adjustStoryDetailWebView];
2012-06-20 08:33:16 -07:00
}
}
- (void)changeActiveFeedDetailRow {
[feedDetailViewController changeActiveFeedDetailRow];
}
- (void)loadStoryDetailView {
NSString *feedTitle;
if (self.isRiverView) {
if ([self.activeFolder isEqualToString:@"river_blurblogs"]) {
feedTitle = @"All Shared Stories";
} else if ([self.activeFolder isEqualToString:@"river_global"]) {
feedTitle = @"Global Shared Stories";
} else if ([self.activeFolder isEqualToString:@"everything"]) {
feedTitle = @"All Stories";
} else if ([self.activeFolder isEqualToString:@"saved_stories"]) {
feedTitle = @"Saved Stories";
} else {
feedTitle = self.activeFolder;
}
} else {
feedTitle = [activeFeed objectForKey:@"feed_title"];
}
int activeStoryLocation = [self locationOfActiveStory];
if (activeStoryLocation >= 0) {
BOOL animated = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad &&
!self.tryFeedCategory);
[self.storyPageControl changePage:activeStoryLocation animated:animated];
// [self.storyPageControl updatePageWithActiveStory:activeStoryLocation];
}
2012-07-24 16:03:16 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:feedTitle style: UIBarButtonItemStyleBordered target: nil action: nil];
[feedDetailViewController.navigationItem setBackBarButtonItem: newBackButton];
UINavigationController *navController = self.navigationController;
[navController pushViewController:storyPageControl animated:YES];
2012-07-15 15:06:06 -07:00
[navController.navigationItem setLeftBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:feedTitle style:UIBarButtonItemStyleBordered target:nil action:nil]];
navController.navigationItem.hidesBackButton = YES;
}
2012-11-07 17:54:16 -08:00
}
- (void)navigationController:(UINavigationController *)navController
willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[viewController viewWillAppear:animated];
}
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[viewController viewDidAppear:animated];
}
}
- (void)setTitle:(NSString *)title {
UILabel *label = [[UILabel alloc] init];
[label setFont:[UIFont boldSystemFontOfSize:16.0]];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:UIColorFromRGB(0x404040)];
[label setText:title];
[label setShadowOffset:CGSizeMake(0, -1)];
[label setShadowColor:UIColorFromRGB(0xFAFAFA)];
[label sizeToFit];
[navigationController.navigationBar.topItem setTitleView:label];
}
- (void)showOriginalStory:(NSURL *)url {
self.activeOriginalStoryURL = url;
2012-06-29 10:46:26 -07:00
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-24 16:03:16 -07:00
[self.masterContainerViewController presentModalViewController:originalStoryViewController animated:YES];
2012-06-29 10:46:26 -07:00
} else {
2012-07-24 16:03:16 -07:00
[self.navigationController presentModalViewController:originalStoryViewController animated:YES];
2012-06-29 10:46:26 -07:00
}
}
- (void)closeOriginalStory {
2013-03-04 17:15:50 -08:00
if (![[self modalViewController] isBeingDismissed]) {
[originalStoryViewController dismissModalViewControllerAnimated:YES];
}
}
- (void)hideStoryDetailView {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
2012-07-24 16:03:16 -07:00
[self.masterContainerViewController transitionFromFeedDetail];
2012-07-11 18:08:07 -07:00
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
2012-06-28 15:03:28 -07:00
- (int)indexOfNextUnreadStory {
int location = [self locationOfNextUnreadStory];
return [self indexFromLocation:location];
}
- (int)locationOfNextUnreadStory {
int activeLocation = [self locationOfActiveStory];
int readStatus = -1;
for (int i=activeLocation+1; i < [self.activeFeedStoryLocations count]; i++) {
int storyIndex = [[self.activeFeedStoryLocations objectAtIndex:i] intValue];
NSDictionary *story = [activeFeedStories objectAtIndex:storyIndex];
readStatus = [[story objectForKey:@"read_status"] intValue];
if (readStatus == 0) {
return i;
}
}
if (activeLocation > 0) {
for (int i=activeLocation-1; i >= 0; i--) {
int storyIndex = [[self.activeFeedStoryLocations objectAtIndex:i] intValue];
NSDictionary *story = [activeFeedStories objectAtIndex:storyIndex];
readStatus = [[story objectForKey:@"read_status"] intValue];
if (readStatus == 0) {
return i;
}
2011-06-15 11:21:55 -04:00
}
}
return -1;
}
2012-06-28 15:03:28 -07:00
- (int)indexOfNextStory {
int location = [self locationOfNextStory];
return [self indexFromLocation:location];
}
- (int)locationOfNextStory {
2012-06-28 15:03:28 -07:00
int activeLocation = [self locationOfActiveStory];
int nextStoryLocation = activeLocation + 1;
if (nextStoryLocation < [self.activeFeedStoryLocations count]) {
return nextStoryLocation;
2012-06-28 15:03:28 -07:00
}
return -1;
}
2011-06-15 11:21:55 -04:00
- (int)indexOfActiveStory {
for (int i=0; i < self.storyCount; i++) {
2011-06-15 11:21:55 -04:00
NSDictionary *story = [activeFeedStories objectAtIndex:i];
if ([activeStory objectForKey:@"id"] == [story objectForKey:@"id"]) {
return i;
}
}
2011-06-15 11:21:55 -04:00
return -1;
}
- (int)indexOfStoryId:(id)storyId {
for (int i=0; i < self.storyCount; i++) {
NSDictionary *story = [activeFeedStories objectAtIndex:i];
if ([story objectForKey:@"id"] == storyId) {
return i;
}
}
return -1;
}
- (int)locationOfStoryId:(id)storyId {
for (int i=0; i < [activeFeedStoryLocations count]; i++) {
if ([activeFeedStoryLocationIds objectAtIndex:i] == storyId) {
return i;
}
}
return -1;
}
- (int)locationOfActiveStory {
for (int i=0; i < [activeFeedStoryLocations count]; i++) {
if ([[activeFeedStoryLocationIds objectAtIndex:i]
isEqualToString:[self.activeStory objectForKey:@"id"]]) {
return i;
}
}
return -1;
}
- (int)indexFromLocation:(int)location {
if (location == -1) return -1;
return [[activeFeedStoryLocations objectAtIndex:location] intValue];
}
- (void)pushReadStory:(id)storyId {
if ([self.readStories lastObject] != storyId) {
[self.readStories addObject:storyId];
}
}
- (id)popReadStory {
if (storyCount == 0) {
return nil;
} else {
[self.readStories removeLastObject];
id lastStory = [self.readStories lastObject];
return lastStory;
}
}
- (int)unreadCount {
2012-08-13 17:07:26 -07:00
if (self.isRiverView || self.isSocialRiverView) {
return [self unreadCountForFolder:nil];
} else {
return [self unreadCountForFeed:nil];
}
}
- (int)allUnreadCount {
int total = 0;
for (id key in self.dictSocialFeeds) {
NSDictionary *feed = [self.dictSocialFeeds objectForKey:key];
total += [[feed objectForKey:@"ps"] intValue];
total += [[feed objectForKey:@"nt"] intValue];
NSLog(@"feed title and number is %@ %i", [feed objectForKey:@"feed_title"], ([[feed objectForKey:@"ps"] intValue] + [[feed objectForKey:@"nt"] intValue]));
NSLog(@"total is %i", total);
}
for (id key in self.dictFeeds) {
NSDictionary *feed = [self.dictFeeds objectForKey:key];
total += [[feed objectForKey:@"ps"] intValue];
total += [[feed objectForKey:@"nt"] intValue];
NSLog(@"feed title and number is %@ %i", [feed objectForKey:@"feed_title"], ([[feed objectForKey:@"ps"] intValue] + [[feed objectForKey:@"nt"] intValue]));
NSLog(@"total is %i", total);
}
return total;
}
- (int)unreadCountForFeed:(NSString *)feedId {
int total = 0;
NSDictionary *feed;
if (feedId) {
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
if ([feedIdStr containsString:@"social:"]) {
2012-08-01 12:41:02 -07:00
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
} else {
feed = [self.dictFeeds objectForKey:feedIdStr];
}
} else {
feed = self.activeFeed;
}
total += [[feed objectForKey:@"ps"] intValue];
if ([self selectedIntelligence] <= 0) {
total += [[feed objectForKey:@"nt"] intValue];
}
if ([self selectedIntelligence] <= -1) {
total += [[feed objectForKey:@"ng"] intValue];
}
return total;
}
- (int)unreadCountForFolder:(NSString *)folderName {
int total = 0;
NSArray *folder;
if ([folderName isEqual:@"river_blurblogs"] ||
(!folderName && [self.activeFolder isEqual:@"river_blurblogs"])) {
2012-08-13 17:07:26 -07:00
for (id feedId in self.dictSocialFeeds) {
total += [self unreadCountForFeed:feedId];
}
} else if ([folderName isEqual:@"river_global"] ||
(!folderName && [self.activeFolder isEqual:@"river_global"])) {
total = 0;
} else if ([folderName isEqual:@"everything"] ||
(!folderName && [self.activeFolder isEqual:@"everything"])) {
for (id feedId in self.dictFeeds) {
total += [self unreadCountForFeed:feedId];
}
} else {
if (!folderName) {
folder = [self.dictFolders objectForKey:self.activeFolder];
} else {
folder = [self.dictFolders objectForKey:folderName];
}
for (id feedId in folder) {
total += [self unreadCountForFeed:feedId];
}
}
return total;
}
- (UnreadCounts *)splitUnreadCountForFeed:(NSString *)feedId {
UnreadCounts *counts = [UnreadCounts alloc];
NSDictionary *feed;
if (feedId) {
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
if ([feedIdStr containsString:@"social:"]) {
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
} else {
feed = [self.dictFeeds objectForKey:feedIdStr];
}
} else {
feed = self.activeFeed;
}
counts.ps += [[feed objectForKey:@"ps"] intValue];
2013-02-15 16:41:20 -08:00
counts.nt += [[feed objectForKey:@"nt"] intValue];
counts.ng += [[feed objectForKey:@"ng"] intValue];
return counts;
}
- (UnreadCounts *)splitUnreadCountForFolder:(NSString *)folderName {
UnreadCounts *counts = [UnreadCounts alloc];
NSArray *folder;
if ([[self.folderCountCache objectForKey:folderName] boolValue]) {
counts.ps = [[self.folderCountCache objectForKey:[NSString stringWithFormat:@"%@-ps", folderName]] intValue];
counts.nt = [[self.folderCountCache objectForKey:[NSString stringWithFormat:@"%@-nt", folderName]] intValue];
counts.ng = [[self.folderCountCache objectForKey:[NSString stringWithFormat:@"%@-ng", folderName]] intValue];
return counts;
}
if ([folderName isEqual:@"river_blurblogs"] ||
(!folderName && [self.activeFolder isEqual:@"river_blurblogs"])) {
for (id feedId in self.dictSocialFeeds) {
[counts addCounts:[self splitUnreadCountForFeed:feedId]];
}
} else if ([folderName isEqual:@"river_global"] ||
(!folderName && [self.activeFolder isEqual:@"river_global"])) {
// Nothing for global
} else if ([folderName isEqual:@"everything"] ||
(!folderName && [self.activeFolder isEqual:@"everything"])) {
for (NSArray *folder in [self.dictFolders allValues]) {
for (id feedId in folder) {
[counts addCounts:[self splitUnreadCountForFeed:feedId]];
}
}
} else {
if (!folderName) {
folder = [self.dictFolders objectForKey:self.activeFolder];
} else {
folder = [self.dictFolders objectForKey:folderName];
}
for (id feedId in folder) {
[counts addCounts:[self splitUnreadCountForFeed:feedId]];
}
}
if (!self.folderCountCache) {
self.folderCountCache = [[NSMutableDictionary alloc] init];
}
[self.folderCountCache setObject:[NSNumber numberWithBool:YES] forKey:folderName];
[self.folderCountCache setObject:[NSNumber numberWithInt:counts.ps] forKey:[NSString stringWithFormat:@"%@-ps", folderName]];
[self.folderCountCache setObject:[NSNumber numberWithInt:counts.nt] forKey:[NSString stringWithFormat:@"%@-nt", folderName]];
[self.folderCountCache setObject:[NSNumber numberWithInt:counts.ng] forKey:[NSString stringWithFormat:@"%@-ng", folderName]];
return counts;
}
- (void)addStories:(NSArray *)stories {
self.activeFeedStories = [self.activeFeedStories arrayByAddingObjectsFromArray:stories];
self.storyCount = [self.activeFeedStories count];
[self calculateStoryLocations];
2012-11-26 09:54:20 -08:00
self.storyLocationsCount = [self.activeFeedStoryLocations count];
}
- (void)setStories:(NSArray *)activeFeedStoriesValue {
self.activeFeedStories = activeFeedStoriesValue;
self.storyCount = [self.activeFeedStories count];
self.recentlyReadStories = [NSMutableArray array];
self.recentlyReadFeeds = [NSMutableSet set];
[self calculateStoryLocations];
2012-11-26 09:54:20 -08:00
self.storyLocationsCount = [self.activeFeedStoryLocations count];
}
- (void)setFeedUserProfiles:(NSArray *)activeFeedUserProfilesValue{
self.activeFeedUserProfiles = activeFeedUserProfilesValue;
}
- (void)addFeedUserProfiles:(NSArray *)activeFeedUserProfilesValue {
self.activeFeedUserProfiles = [self.activeFeedUserProfiles arrayByAddingObjectsFromArray:activeFeedUserProfilesValue];
}
- (void)markActiveStoryRead {
int activeLocation = [self locationOfActiveStory];
if (activeLocation == -1) {
return;
}
// changes the story layout in story feed detail
[self.feedDetailViewController changeActiveStoryTitleCellLayout];
2012-08-07 11:27:00 -07:00
int activeIndex = [[activeFeedStoryLocations objectAtIndex:activeLocation] intValue];
2012-06-29 12:54:52 -07:00
NSDictionary *feed;
2012-08-07 11:27:00 -07:00
NSDictionary *friendFeed;
2012-07-29 13:24:03 -07:00
id feedId;
NSString *feedIdStr;
NSDictionary *story = [activeFeedStories objectAtIndex:activeIndex];
2012-08-10 18:10:07 -07:00
NSMutableArray *otherFriendShares = [[self.activeStory objectForKey:@"shared_by_friends"] mutableCopy];
NSMutableArray *otherFriendComments = [[self.activeStory objectForKey:@"commented_by_friends"] mutableCopy];
2012-06-29 12:54:52 -07:00
2012-08-10 18:10:07 -07:00
if (self.isSocialView) {
feedId = [self.activeStory objectForKey:@"social_user_id"];
feedIdStr = [NSString stringWithFormat:@"social:%@",feedId];
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
2012-08-10 18:10:07 -07:00
[otherFriendShares removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendShares);
[otherFriendComments removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendComments);
// make sure we set the active feed
self.activeFeed = feed;
} else if (self.isSocialRiverView) {
if ([[self.activeStory objectForKey:@"friend_user_ids"] count]) {
feedId = [[self.activeStory objectForKey:@"friend_user_ids"] objectAtIndex:0];
feedIdStr = [NSString stringWithFormat:@"social:%@",feedId];
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
2012-08-10 18:10:07 -07:00
[otherFriendShares removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendShares);
[otherFriendComments removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendComments);
// make sure we set the active feed
self.activeFeed = feed;
}
2012-06-29 12:54:52 -07:00
} else {
feedId = [self.activeStory objectForKey:@"story_feed_id"];
feedIdStr = [NSString stringWithFormat:@"%@",feedId];
2012-06-29 12:54:52 -07:00
feed = [self.dictFeeds objectForKey:feedIdStr];
// make sure we set the active feed
self.activeFeed = feed;
}
2012-08-07 11:27:00 -07:00
// decrement all other friend feeds if they have the same story
if (self.isSocialView || self.isSocialRiverView) {
2012-08-10 18:10:07 -07:00
for (int i = 0; i < otherFriendShares.count; i++) {
feedIdStr = [NSString stringWithFormat:@"social:%@",
[otherFriendShares objectAtIndex:i]];
friendFeed = [self.dictSocialFeeds objectForKey:feedIdStr];
[self markStoryRead:story feed:friendFeed];
}
for (int i = 0; i < otherFriendComments.count; i++) {
feedIdStr = [NSString stringWithFormat:@"social:%@",
2012-08-10 18:10:07 -07:00
[otherFriendComments objectAtIndex:i]];
2012-08-07 11:27:00 -07:00
friendFeed = [self.dictSocialFeeds objectForKey:feedIdStr];
[self markStoryRead:story feed:friendFeed];
}
}
2012-08-07 11:27:00 -07:00
[self.recentlyReadStories addObject:[NSNumber numberWithInt:activeLocation]];
[self markStoryRead:story feed:feed];
2012-10-16 17:24:01 -07:00
self.activeStory = [self.activeFeedStories objectAtIndex:activeIndex];
}
- (void)markActiveStoryUnread {
int activeLocation = [self locationOfActiveStory];
if (activeLocation == -1) {
return;
}
// changes the story layout in story feed detail
[self.feedDetailViewController changeActiveStoryTitleCellLayout];
int activeIndex = [[activeFeedStoryLocations objectAtIndex:activeLocation] intValue];
NSDictionary *feed;
NSDictionary *friendFeed;
id feedId;
NSString *feedIdStr;
NSDictionary *story = [activeFeedStories objectAtIndex:activeIndex];
NSMutableArray *otherFriendShares = [[self.activeStory objectForKey:@"shared_by_friends"] mutableCopy];
NSMutableArray *otherFriendComments = [[self.activeStory objectForKey:@"commented_by_friends"] mutableCopy];
if (self.isSocialView) {
feedId = [self.activeStory objectForKey:@"social_user_id"];
feedIdStr = [NSString stringWithFormat:@"social:%@",feedId];
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
[otherFriendShares removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendShares);
[otherFriendComments removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendComments);
// make sure we set the active feed
self.activeFeed = feed;
} else if (self.isSocialRiverView) {
feedId = [[self.activeStory objectForKey:@"friend_user_ids"] objectAtIndex:0];
feedIdStr = [NSString stringWithFormat:@"social:%@",feedId];
feed = [self.dictSocialFeeds objectForKey:feedIdStr];
[otherFriendShares removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendShares);
[otherFriendComments removeObject:feedId];
NSLog(@"otherFriendFeeds is %@", otherFriendComments);
// make sure we set the active feed
self.activeFeed = feed;
} else {
feedId = [self.activeStory objectForKey:@"story_feed_id"];
feedIdStr = [NSString stringWithFormat:@"%@",feedId];
feed = [self.dictFeeds objectForKey:feedIdStr];
// make sure we set the active feed
self.activeFeed = feed;
}
// decrement all other friend feeds if they have the same story
if (self.isSocialView || self.isSocialRiverView) {
for (int i = 0; i < otherFriendShares.count; i++) {
feedIdStr = [NSString stringWithFormat:@"social:%@",
[otherFriendShares objectAtIndex:i]];
friendFeed = [self.dictSocialFeeds objectForKey:feedIdStr];
[self markStoryUnread:story feed:friendFeed];
}
for (int i = 0; i < otherFriendComments.count; i++) {
feedIdStr = [NSString stringWithFormat:@"social:%@",
[otherFriendComments objectAtIndex:i]];
friendFeed = [self.dictSocialFeeds objectForKey:feedIdStr];
[self markStoryUnread:story feed:friendFeed];
}
}
[self.recentlyReadStories removeObject:[NSNumber numberWithInt:activeLocation]];
[self markStoryUnread:story feed:feed];
self.activeStory = [self.activeFeedStories objectAtIndex:activeIndex];
}
- (NSDictionary *)markVisibleStoriesRead {
NSMutableDictionary *feedsStories = [NSMutableDictionary dictionary];
for (NSDictionary *story in self.activeFeedStories) {
if ([[story objectForKey:@"read_status"] intValue] != 0) {
continue;
}
NSString *feedIdStr = [NSString stringWithFormat:@"%@",[story objectForKey:@"story_feed_id"]];
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
if (![feedsStories objectForKey:feedIdStr]) {
[feedsStories setObject:[NSMutableArray array] forKey:feedIdStr];
}
NSMutableArray *stories = [feedsStories objectForKey:feedIdStr];
[stories addObject:[story objectForKey:@"id"]];
[self markStoryRead:story feed:feed];
}
return feedsStories;
}
- (void)markStoryRead:(NSString *)storyId feedId:(id)feedId {
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
NSDictionary *story = nil;
for (NSDictionary *s in self.activeFeedStories) {
if ([[s objectForKey:@"story_guid"] isEqualToString:storyId]) {
story = s;
break;
}
}
[self markStoryRead:story feed:feed];
}
- (void)markStoryRead:(NSDictionary *)story feed:(NSDictionary *)feed {
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [feed objectForKey:@"id"]];
2012-07-27 16:48:30 -07:00
NSMutableDictionary *newStory = [story mutableCopy];
[newStory setValue:[NSNumber numberWithInt:1] forKey:@"read_status"];
2012-08-06 15:46:05 -07:00
// make the story as read in self.activeFeedStories
NSString *newStoryIdStr = [NSString stringWithFormat:@"%@", [newStory valueForKey:@"id"]];
NSMutableArray *newActiveFeedStories = [self.activeFeedStories mutableCopy];
for (int i = 0; i < [newActiveFeedStories count]; i++) {
NSMutableArray *thisStory = [[newActiveFeedStories objectAtIndex:i] mutableCopy];
NSString *thisStoryIdStr = [NSString stringWithFormat:@"%@", [thisStory valueForKey:@"id"]];
if ([newStoryIdStr isEqualToString:thisStoryIdStr]) {
[newActiveFeedStories replaceObjectAtIndex:i withObject:newStory];
break;
}
}
self.activeFeedStories = newActiveFeedStories;
2012-10-16 17:24:01 -07:00
self.visibleUnreadCount -= 1;
2012-07-27 16:48:30 -07:00
if (![self.recentlyReadFeeds containsObject:[newStory objectForKey:@"story_feed_id"]]) {
[self.recentlyReadFeeds addObject:[newStory objectForKey:@"story_feed_id"]];
}
2012-07-27 18:42:42 -07:00
NSMutableDictionary *newFeed = [feed mutableCopy];
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
if (score > 0) {
2012-08-01 12:41:02 -07:00
int unreads = MAX(0, [[newFeed objectForKey:@"ps"] intValue] - 1);
2012-07-27 18:42:42 -07:00
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"ps"];
} else if (score == 0) {
2012-08-01 12:41:02 -07:00
int unreads = MAX(0, [[newFeed objectForKey:@"nt"] intValue] - 1);
2012-07-27 18:42:42 -07:00
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"nt"];
} else if (score < 0) {
2012-08-01 12:41:02 -07:00
int unreads = MAX(0, [[newFeed objectForKey:@"ng"] intValue] - 1);
2012-07-27 18:42:42 -07:00
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"ng"];
}
2012-07-27 18:42:42 -07:00
2012-08-10 18:10:07 -07:00
if (self.isSocialView || self.isSocialRiverView) {
2012-08-01 12:41:02 -07:00
[self.dictSocialFeeds setValue:newFeed forKey:feedIdStr];
} else {
[self.dictFeeds setValue:newFeed forKey:feedIdStr];
}
self.activeFeed = newFeed;
}
2012-10-16 17:24:01 -07:00
- (void)markStoryUnread:(NSString *)storyId feedId:(id)feedId {
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
NSDictionary *feed = [self.dictFeeds objectForKey:feedIdStr];
NSDictionary *story = nil;
for (NSDictionary *s in self.activeFeedStories) {
if ([[s objectForKey:@"story_guid"] isEqualToString:storyId]) {
story = s;
break;
}
}
[self markStoryUnread:story feed:feed];
}
- (void)markStoryUnread:(NSDictionary *)story feed:(NSDictionary *)feed {
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [feed objectForKey:@"id"]];
NSMutableDictionary *newStory = [story mutableCopy];
[newStory setValue:[NSNumber numberWithInt:0] forKey:@"read_status"];
// make the story as read in self.activeFeedStories
NSString *newStoryIdStr = [NSString stringWithFormat:@"%@", [newStory valueForKey:@"id"]];
NSMutableArray *newActiveFeedStories = [self.activeFeedStories mutableCopy];
for (int i = 0; i < [newActiveFeedStories count]; i++) {
NSMutableArray *thisStory = [[newActiveFeedStories objectAtIndex:i] mutableCopy];
NSString *thisStoryIdStr = [NSString stringWithFormat:@"%@", [thisStory valueForKey:@"id"]];
if ([newStoryIdStr isEqualToString:thisStoryIdStr]) {
[newActiveFeedStories replaceObjectAtIndex:i withObject:newStory];
break;
}
}
self.activeFeedStories = newActiveFeedStories;
self.visibleUnreadCount += 1;
// if ([self.recentlyReadFeeds containsObject:[newStory objectForKey:@"story_feed_id"]]) {
[self.recentlyReadFeeds removeObject:[newStory objectForKey:@"story_feed_id"]];
// }
NSMutableDictionary *newFeed = [feed mutableCopy];
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
if (score > 0) {
int unreads = MAX(1, [[newFeed objectForKey:@"ps"] intValue] + 1);
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"ps"];
} else if (score == 0) {
int unreads = MAX(1, [[newFeed objectForKey:@"nt"] intValue] + 1);
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"nt"];
} else if (score < 0) {
int unreads = MAX(1, [[newFeed objectForKey:@"ng"] intValue] + 1);
[newFeed setValue:[NSNumber numberWithInt:unreads] forKey:@"ng"];
}
if (self.isSocialView || self.isSocialRiverView) {
[self.dictSocialFeeds setValue:newFeed forKey:feedIdStr];
} else {
[self.dictFeeds setValue:newFeed forKey:feedIdStr];
}
self.activeFeed = newFeed;
}
- (void)markActiveStorySaved:(BOOL)saved {
NSMutableDictionary *newStory = [self.activeStory mutableCopy];
[newStory setValue:[NSNumber numberWithBool:saved] forKey:@"starred"];
self.activeStory = newStory;
// make the story as read in self.activeFeedStories
NSString *newStoryIdStr = [NSString stringWithFormat:@"%@", [newStory valueForKey:@"id"]];
NSMutableArray *newActiveFeedStories = [self.activeFeedStories mutableCopy];
for (int i = 0; i < [newActiveFeedStories count]; i++) {
NSMutableArray *thisStory = [[newActiveFeedStories objectAtIndex:i] mutableCopy];
NSString *thisStoryIdStr = [NSString stringWithFormat:@"%@", [thisStory valueForKey:@"id"]];
if ([newStoryIdStr isEqualToString:thisStoryIdStr]) {
[newActiveFeedStories replaceObjectAtIndex:i withObject:newStory];
break;
}
}
self.activeFeedStories = newActiveFeedStories;
if (saved) {
self.savedStoriesCount += 1;
} else {
self.savedStoriesCount -= 1;
}
}
2012-10-16 17:24:01 -07:00
- (void)markActiveFeedAllRead {
id feedId = [self.activeFeed objectForKey:@"id"];
[self markFeedAllRead:feedId];
}
- (void)markActiveFolderAllRead {
if ([self.activeFolder isEqual:@"everything"]) {
for (NSString *folderName in self.dictFoldersArray) {
for (id feedId in [self.dictFolders objectForKey:folderName]) {
[self markFeedAllRead:feedId];
}
}
} else {
for (id feedId in [self.dictFolders objectForKey:self.activeFolder]) {
[self markFeedAllRead:feedId];
}
}
}
- (void)markFeedAllRead:(id)feedId {
NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId];
NSMutableDictionary *feed = self.isSocialView ? [[self.dictSocialFeeds objectForKey:feedIdStr] mutableCopy] : [[self.dictFeeds objectForKey:feedIdStr] mutableCopy];
[feed setValue:[NSNumber numberWithInt:0] forKey:@"ps"];
[feed setValue:[NSNumber numberWithInt:0] forKey:@"nt"];
[feed setValue:[NSNumber numberWithInt:0] forKey:@"ng"];
if (self.isSocialView) {
[self.dictSocialFeeds setValue:feed forKey:feedIdStr];
} else {
[self.dictFeeds setValue:feed forKey:feedIdStr];
}
}
- (void)calculateStoryLocations {
self.visibleUnreadCount = 0;
self.activeFeedStoryLocations = [NSMutableArray array];
self.activeFeedStoryLocationIds = [NSMutableArray array];
for (int i=0; i < self.storyCount; i++) {
NSDictionary *story = [self.activeFeedStories objectAtIndex:i];
int score = [NewsBlurAppDelegate computeStoryScore:[story objectForKey:@"intelligence"]];
if (score >= self.selectedIntelligence || [[story objectForKey:@"sticky"] boolValue]) {
NSNumber *location = [NSNumber numberWithInt:i];
[self.activeFeedStoryLocations addObject:location];
[self.activeFeedStoryLocationIds addObject:[story objectForKey:@"id"]];
if ([[story objectForKey:@"read_status"] intValue] == 0) {
self.visibleUnreadCount += 1;
}
}
}
}
+ (int)computeStoryScore:(NSDictionary *)intelligence {
int score = 0;
int title = [[intelligence objectForKey:@"title"] intValue];
int author = [[intelligence objectForKey:@"author"] intValue];
int tags = [[intelligence objectForKey:@"tags"] intValue];
int score_max = MAX(title, MAX(author, tags));
int score_min = MIN(title, MIN(author, tags));
if (score_max > 0) score = score_max;
else if (score_min < 0) score = score_min;
if (score == 0) score = [[intelligence objectForKey:@"feed"] integerValue];
// NSLog(@"%d/%d -- %d: %@", score_max, score_min, score, intelligence);
return score;
}
- (NSString *)extractParentFolderName:(NSString *)folderName {
if ([folderName containsString:@"Top Level"] ||
[folderName isEqual:@"everything"]) {
folderName = @"";
}
if ([folderName containsString:@" - "]) {
int lastFolderLoc = [folderName rangeOfString:@" - " options:NSBackwardsSearch].location;
folderName = [folderName substringToIndex:lastFolderLoc];
} else {
folderName = @"— Top Level —";
}
return folderName;
}
- (NSString *)extractFolderName:(NSString *)folderName {
if ([folderName containsString:@"Top Level"] ||
[folderName isEqual:@"everything"]) {
folderName = @"";
}
if ([folderName containsString:@" - "]) {
int folder_loc = [folderName rangeOfString:@" - " options:NSBackwardsSearch].location;
folderName = [folderName substringFromIndex:(folder_loc + 3)];
}
return folderName;
}
- (NSDictionary *)getFeed:(NSString *)feedId {
NSDictionary *feed;
if (self.isSocialView || self.isSocialRiverView) {
feed = [self.dictActiveFeeds objectForKey:feedId];
// this is to catch when a user is already subscribed
if (!feed) {
feed = [self.dictFeeds objectForKey:feedId];
}
} else {
feed = [self.dictFeeds objectForKey:feedId];
}
return feed;
}
#pragma mark -
#pragma mark Feed Templates
+ (void)fillGradient:(CGRect)r startColor:(UIColor *)startColor endColor:(UIColor *)endColor {
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
CGGradientRef gradient;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[2] = {0.0f, 1.0f};
CGFloat startRed, startGreen, startBlue, startAlpha;
CGFloat endRed, endGreen, endBlue, endAlpha;
[startColor getRed:&startRed green:&startGreen blue:&startBlue alpha:&startAlpha];
[endColor getRed:&endRed green:&endGreen blue:&endBlue alpha:&endAlpha];
CGFloat components[8] = {
startRed, startGreen, startBlue, startAlpha,
endRed, endGreen, endBlue, endAlpha
};
gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
CGColorSpaceRelease(colorSpace);
2013-02-15 16:41:20 -08:00
CGPoint startPoint = CGPointMake(CGRectGetMinX(r), r.origin.y);
CGPoint endPoint = CGPointMake(startPoint.x, r.origin.y + r.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
UIGraphicsPopContext();
}
+ (UIView *)makeGradientView:(CGRect)rect startColor:(NSString *)start endColor:(NSString *)end {
2012-07-15 15:06:06 -07:00
UIView *gradientView = [[UIView alloc] initWithFrame:rect];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, 1, rect.size.width, rect.size.height-1);
gradient.opacity = 0.7;
unsigned int color = 0;
unsigned int colorFade = 0;
if ([start class] == [NSNull class]) {
start = @"505050";
}
if ([end class] == [NSNull class]) {
end = @"303030";
}
NSScanner *scanner = [NSScanner scannerWithString:start];
[scanner scanHexInt:&color];
NSScanner *scannerFade = [NSScanner scannerWithString:end];
[scannerFade scanHexInt:&colorFade];
gradient.colors = [NSArray arrayWithObjects:(id)[UIColorFromRGB(color) CGColor], (id)[UIColorFromRGB(colorFade) CGColor], nil];
CALayer *whiteBackground = [CALayer layer];
whiteBackground.frame = CGRectMake(0, 1, rect.size.width, rect.size.height-1);
whiteBackground.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7].CGColor;
[gradientView.layer addSublayer:whiteBackground];
[gradientView.layer addSublayer:gradient];
CALayer *topBorder = [CALayer layer];
topBorder.frame = CGRectMake(0, 1, rect.size.width, 1);
topBorder.backgroundColor = [UIColorFromRGB(colorFade) colorWithAlphaComponent:0.7].CGColor;
topBorder.opacity = 1;
[gradientView.layer addSublayer:topBorder];
CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0, rect.size.height-1, rect.size.width, 1);
bottomBorder.backgroundColor = [UIColorFromRGB(colorFade) colorWithAlphaComponent:0.7].CGColor;
bottomBorder.opacity = 1;
[gradientView.layer addSublayer:bottomBorder];
return gradientView;
}
- (UIView *)makeFeedTitleGradient:(NSDictionary *)feed withRect:(CGRect)rect {
UIView *gradientView;
if (self.isRiverView || self.isSocialView || self.isSocialRiverView) {
gradientView = [NewsBlurAppDelegate
makeGradientView:rect
startColor:[feed objectForKey:@"favicon_fade"]
endColor:[feed objectForKey:@"favicon_color"]];
2012-07-15 15:06:06 -07:00
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = [feed objectForKey:@"feed_title"];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textAlignment = UITextAlignmentLeft;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
titleLabel.numberOfLines = 1;
titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:11.0];
titleLabel.shadowOffset = CGSizeMake(0, 1);
if ([[feed objectForKey:@"favicon_text_color"] class] != [NSNull class]) {
titleLabel.textColor = [[feed objectForKey:@"favicon_text_color"]
isEqualToString:@"white"] ?
[UIColor whiteColor] :
[UIColor blackColor];
titleLabel.shadowColor = [[feed objectForKey:@"favicon_text_color"]
isEqualToString:@"white"] ?
UIColorFromRGB(0x202020) :
UIColorFromRGB(0xd0d0d0);
} else {
titleLabel.textColor = [UIColor whiteColor];
titleLabel.shadowColor = [UIColor blackColor];
}
titleLabel.frame = CGRectMake(32, 1, rect.size.width-32, 20);
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [feed objectForKey:@"id"]];
UIImage *titleImage = [Utilities getImage:feedIdStr];
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:titleImage];
titleImageView.frame = CGRectMake(8, 3, 16.0, 16.0);
[titleLabel addSubview:titleImageView];
[gradientView addSubview:titleLabel];
[gradientView addSubview:titleImageView];
} else {
gradientView = [NewsBlurAppDelegate
makeGradientView:CGRectMake(0, -1, rect.size.width, 10)
// hard coding the 1024 as a hack for window.frame.size.width
startColor:[feed objectForKey:@"favicon_fade"]
endColor:[feed objectForKey:@"favicon_color"]];
}
gradientView.opaque = YES;
return gradientView;
}
- (UIView *)makeFeedTitle:(NSDictionary *)feed {
2012-07-15 15:06:06 -07:00
UILabel *titleLabel = [[UILabel alloc] init];
if (self.isSocialRiverView && [self.activeFolder isEqualToString:@"river_blurblogs"]) {
titleLabel.text = [NSString stringWithFormat:@" All Shared Stories"];
} else if (self.isSocialRiverView && [self.activeFolder isEqualToString:@"river_global"]) {
titleLabel.text = [NSString stringWithFormat:@" Global Shared Stories"];
} else if (self.isRiverView && [self.activeFolder isEqualToString:@"everything"]) {
titleLabel.text = [NSString stringWithFormat:@" All Stories"];
} else if (self.isRiverView && [self.activeFolder isEqualToString:@"saved_stories"]) {
titleLabel.text = [NSString stringWithFormat:@" Saved Stories"];
2012-08-08 10:57:38 -07:00
} else if (self.isRiverView) {
titleLabel.text = [NSString stringWithFormat:@" %@", self.activeFolder];
} else if (self.isSocialView) {
titleLabel.text = [NSString stringWithFormat:@" %@", [feed objectForKey:@"feed_title"]];
} else {
titleLabel.text = [NSString stringWithFormat:@" %@", [feed objectForKey:@"feed_title"]];
}
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textAlignment = UITextAlignmentLeft;
titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:15.0];
2013-02-28 17:07:51 -08:00
titleLabel.textColor = UIColorFromRGB(0x404040);
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
titleLabel.numberOfLines = 1;
2013-02-28 17:07:51 -08:00
titleLabel.shadowColor = UIColorFromRGB(0xF5F5F5);
titleLabel.shadowOffset = CGSizeMake(0, -1);
titleLabel.center = CGPointMake(0, -2);
[titleLabel sizeToFit];
if (!self.isSocialView) {
titleLabel.center = CGPointMake(28, -2);
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [feed objectForKey:@"id"]];
UIImage *titleImage;
if (self.isSocialRiverView && [self.activeFolder isEqualToString:@"river_global"]) {
titleImage = [UIImage imageNamed:@"ak-icon-global.png"];
} else if (self.isSocialRiverView && [self.activeFolder isEqualToString:@"river_blurblogs"]) {
titleImage = [UIImage imageNamed:@"ak-icon-blurblogs.png"];
} else if (self.isRiverView && [self.activeFolder isEqualToString:@"everything"]) {
titleImage = [UIImage imageNamed:@"ak-icon-allstories.png"];
} else if (self.isRiverView && [self.activeFolder isEqualToString:@"saved_stories"]) {
2013-02-21 14:44:34 -08:00
titleImage = [UIImage imageNamed:@"clock2.png"];
2012-08-08 10:57:38 -07:00
} else if (self.isRiverView) {
2013-02-21 14:44:34 -08:00
titleImage = [UIImage imageNamed:@"g_icn_folder.png"];
} else {
titleImage = [Utilities getImage:feedIdStr];
}
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:titleImage];
titleImageView.frame = CGRectMake(0.0, 2.0, 16.0, 16.0);
[titleLabel addSubview:titleImageView];
}
return titleLabel;
}
- (UIButton *)makeRightFeedTitle:(NSDictionary *)feed {
NSString *feedIdStr = [NSString stringWithFormat:@"%@", [feed objectForKey:@"id"]];
UIImage *titleImage = [Utilities getImage:feedIdStr];
titleImage = [Utilities roundCorneredImage:titleImage radius:6];
UIButton *titleImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
titleImageButton.bounds = CGRectMake(0, 0, 32, 32);
[titleImageButton setImage:titleImage forState:UIControlStateNormal];
return titleImageButton;
}
#pragma mark -
#pragma mark Classifiers
- (void)toggleAuthorClassifier:(NSString *)author feedId:(NSString *)feedId {
int authorScore = [[[[self.activeClassifiers objectForKey:feedId]
objectForKey:@"authors"]
objectForKey:author] intValue];
if (authorScore > 0) {
authorScore = -1;
} else if (authorScore < 0) {
authorScore = 0;
} else {
authorScore = 1;
}
NSMutableDictionary *feedClassifiers = [[self.activeClassifiers objectForKey:feedId]
mutableCopy];
NSMutableDictionary *authors = [[feedClassifiers objectForKey:@"authors"] mutableCopy];
[authors setObject:[NSNumber numberWithInt:authorScore] forKey:author];
[feedClassifiers setObject:authors forKey:@"authors"];
[self.activeClassifiers setObject:feedClassifiers forKey:feedId];
[self.storyPageControl refreshHeaders];
[self.trainerViewController refresh];
NSString *urlString = [NSString stringWithFormat:@"http://%@/classifier/save",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlString];
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:author
forKey:authorScore >= 1 ? @"like_author" :
authorScore <= -1 ? @"dislike_author" :
@"remove_like_author"];
[request setPostValue:feedId forKey:@"feed_id"];
[request setCompletionBlock:^{
[self.feedsViewController refreshFeedList:feedId];
}];
[request setDidFailSelector:@selector(requestFailed:)];
[request setDelegate:self];
[request startAsynchronous];
[self recalculateIntelligenceScores:feedId];
[self.feedDetailViewController.storyTitlesTable reloadData];
}
- (void)toggleTagClassifier:(NSString *)tag feedId:(NSString *)feedId {
NSLog(@"toggleTagClassifier: %@", tag);
int tagScore = [[[[self.activeClassifiers objectForKey:feedId]
objectForKey:@"tags"]
objectForKey:tag] intValue];
if (tagScore > 0) {
tagScore = -1;
} else if (tagScore < 0) {
tagScore = 0;
} else {
tagScore = 1;
}
NSMutableDictionary *feedClassifiers = [[self.activeClassifiers objectForKey:feedId]
mutableCopy];
NSMutableDictionary *tags = [[feedClassifiers objectForKey:@"tags"] mutableCopy];
[tags setObject:[NSNumber numberWithInt:tagScore] forKey:tag];
[feedClassifiers setObject:tags forKey:@"tags"];
[self.activeClassifiers setObject:feedClassifiers forKey:feedId];
[self.storyPageControl refreshHeaders];
[self.trainerViewController refresh];
NSString *urlString = [NSString stringWithFormat:@"http://%@/classifier/save",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlString];
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:tag
forKey:tagScore >= 1 ? @"like_tag" :
tagScore <= -1 ? @"dislike_tag" :
@"remove_like_tag"];
[request setPostValue:feedId forKey:@"feed_id"];
[request setCompletionBlock:^{
[self.feedsViewController refreshFeedList:feedId];
}];
[request setDidFailSelector:@selector(requestFailed:)];
[request setDelegate:self];
[request startAsynchronous];
[self recalculateIntelligenceScores:feedId];
[self.feedDetailViewController.storyTitlesTable reloadData];
}
- (void)toggleTitleClassifier:(NSString *)title feedId:(NSString *)feedId score:(int)score {
NSLog(@"toggle Title: %@ (%@) / %d", title, feedId, score);
int titleScore = [[[[self.activeClassifiers objectForKey:feedId]
objectForKey:@"titles"]
objectForKey:title] intValue];
if (score) {
titleScore = score;
} else {
if (titleScore > 0) {
titleScore = -1;
} else if (titleScore < 0) {
titleScore = 0;
} else {
titleScore = 1;
}
}
NSMutableDictionary *feedClassifiers = [[self.activeClassifiers objectForKey:feedId]
mutableCopy];
NSMutableDictionary *titles = [[feedClassifiers objectForKey:@"titles"] mutableCopy];
[titles setObject:[NSNumber numberWithInt:titleScore] forKey:title];
[feedClassifiers setObject:titles forKey:@"titles"];
[self.activeClassifiers setObject:feedClassifiers forKey:feedId];
[self.storyPageControl refreshHeaders];
[self.trainerViewController refresh];
NSString *urlString = [NSString stringWithFormat:@"http://%@/classifier/save",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlString];
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:title
forKey:titleScore >= 1 ? @"like_title" :
titleScore <= -1 ? @"dislike_title" :
@"remove_like_title"];
[request setPostValue:feedId forKey:@"feed_id"];
[request setCompletionBlock:^{
[self.feedsViewController refreshFeedList:feedId];
}];
[request setDidFailSelector:@selector(requestFailed:)];
[request setDelegate:self];
[request startAsynchronous];
[self recalculateIntelligenceScores:feedId];
[self.feedDetailViewController.storyTitlesTable reloadData];
}
- (void)toggleFeedClassifier:(NSString *)feedId {
int feedScore = [[[[self.activeClassifiers objectForKey:feedId]
objectForKey:@"feeds"]
objectForKey:feedId] intValue];
if (feedScore > 0) {
feedScore = -1;
} else if (feedScore < 0) {
feedScore = 0;
} else {
feedScore = 1;
}
NSMutableDictionary *feedClassifiers = [[self.activeClassifiers objectForKey:feedId]
mutableCopy];
NSMutableDictionary *feeds = [[feedClassifiers objectForKey:@"feeds"] mutableCopy];
[feeds setObject:[NSNumber numberWithInt:feedScore] forKey:feedId];
[feedClassifiers setObject:feeds forKey:@"feeds"];
[self.activeClassifiers setObject:feedClassifiers forKey:feedId];
[self.storyPageControl refreshHeaders];
[self.trainerViewController refresh];
NSString *urlString = [NSString stringWithFormat:@"http://%@/classifier/save",
NEWSBLUR_URL];
NSURL *url = [NSURL URLWithString:urlString];
__block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:feedId
forKey:feedScore >= 1 ? @"like_feed" :
feedScore <= -1 ? @"dislike_feed" :
@"remove_like_feed"];
[request setPostValue:feedId forKey:@"feed_id"];
[request setCompletionBlock:^{
[self.feedsViewController refreshFeedList:feedId];
}];
[request setDidFailSelector:@selector(requestFailed:)];
[request setDelegate:self];
[request startAsynchronous];
[self recalculateIntelligenceScores:feedId];
[self.feedDetailViewController.storyTitlesTable reloadData];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(@"Error: %@", error);
[self informError:error];
}
@end
@implementation UnreadCounts
@synthesize ps, nt, ng;
- (id)init {
if (self = [super init]) {
ps = 0;
nt = 0;
ng = 0;
}
return self;
}
- (void)addCounts:(UnreadCounts *)counts {
ps += counts.ps;
nt += counts.nt;
ng += counts.ng;
}
@end