diff --git a/clients/ios/Classes/AddSiteViewController.m b/clients/ios/Classes/AddSiteViewController.m index b79f93f63..9884f762f 100644 --- a/clients/ios/Classes/AddSiteViewController.m +++ b/clients/ios/Classes/AddSiteViewController.m @@ -331,7 +331,8 @@ - (NSArray *)folders { return _.without([appDelegate dictFoldersArray], - @[@"saved_stories", + @[@"saved_searches", + @"saved_stories", @"read_stories", @"river_blurblogs", @"river_global", diff --git a/clients/ios/Classes/FeedChooserViewController.m b/clients/ios/Classes/FeedChooserViewController.m index f9940063d..c578e9bc3 100644 --- a/clients/ios/Classes/FeedChooserViewController.m +++ b/clients/ios/Classes/FeedChooserViewController.m @@ -162,7 +162,7 @@ static const CGFloat kFolderTitleHeight = 36.0; NSArray *folderArray = [self.dictFolders.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; for (NSString *folderName in folderArray) { - if (![folderName hasPrefix:@"river_"] && ![folderName isEqualToString:@"read_stories"] && ![folderName isEqualToString:@"saved_stories"]) { + if (![folderName hasPrefix:@"river_"] && ![folderName isEqualToString:@"read_stories"] && ![folderName isEqualToString:@"saved_searches"] && ![folderName isEqualToString:@"saved_stories"]) { FeedChooserItem *folder = [FeedChooserItem makeFolderWithTitle:folderName]; [folders addObject:folder]; diff --git a/clients/ios/Classes/FeedDetailViewController.m b/clients/ios/Classes/FeedDetailViewController.m index fa814dd19..d45f249c9 100644 --- a/clients/ios/Classes/FeedDetailViewController.m +++ b/clients/ios/Classes/FeedDetailViewController.m @@ -1656,6 +1656,8 @@ feedTitle = @"Read Stories"; } else if ([storiesCollection.activeFolder isEqualToString:@"saved_stories"]) { feedTitle = @"Saved Stories"; + } else if ([storiesCollection.activeFolder isEqualToString:@"saved_searches"]) { + feedTitle = @"Saved Searches"; } else { feedTitle = storiesCollection.activeFolder; } diff --git a/clients/ios/Classes/FeedTableCell.h b/clients/ios/Classes/FeedTableCell.h index 222f7c425..2f8b448af 100644 --- a/clients/ios/Classes/FeedTableCell.h +++ b/clients/ios/Classes/FeedTableCell.h @@ -35,6 +35,7 @@ @property (assign, nonatomic) int savedStoriesCount; @property (assign, nonatomic) BOOL isSocial; @property (assign, nonatomic) BOOL isSaved; +@property (nonatomic) NSString *searchQuery; @property (nonatomic) NSString *negativeCountStr; @property (nonatomic) UnreadCountView *unreadCount; diff --git a/clients/ios/Classes/FolderTitleView.m b/clients/ios/Classes/FolderTitleView.m index 604807b51..61c8488b3 100644 --- a/clients/ios/Classes/FolderTitleView.m +++ b/clients/ios/Classes/FolderTitleView.m @@ -55,6 +55,19 @@ [self addSubview:unreadCount]; accessibilityCount = [NSString stringWithFormat:@", %@ stories", @(appDelegate.savedStoriesCount)]; + } else if ([folderName isEqual:@"saved_searches"]) { + NSInteger count = appDelegate.savedSearchesCount; + unreadCount = [[UnreadCountView alloc] initWithFrame:CGRectInset(rect, 0, 2)]; + unreadCount.appDelegate = appDelegate; + unreadCount.opaque = NO; + unreadCount.psCount = count; + unreadCount.blueCount = count; + + [unreadCount calculateOffsets:count nt:0]; + countWidth = [unreadCount offsetWidth]; + [self addSubview:unreadCount]; + + accessibilityCount = [NSString stringWithFormat:@", %@ searches", @(count)]; } else if (isFolderCollapsed) { UnreadCounts *counts = [appDelegate splitUnreadCountForFolder:folderName]; unreadCount = [[UnreadCountView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect))]; @@ -120,6 +133,8 @@ folderTitle = [@"Read Stories" uppercaseString]; } else if ([folderName isEqual:@"saved_stories"]) { folderTitle = [@"Saved Stories" uppercaseString]; + } else if ([folderName isEqual:@"saved_searches"]) { + folderTitle = [@"Saved Searches" uppercaseString]; } else { folderTitle = [[appDelegate.dictFoldersArray objectAtIndex:section] uppercaseString]; } @@ -231,6 +246,13 @@ folderImageViewX = 7; } allowLongPress = NO; + } else if ([folderName isEqual:@"saved_searches"]) { + folderImage = [[UIImage imageNamed:@"g_icn_search_black.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + folderImageViewX = 10; + } else { + folderImageViewX = 7; + } } else if ([folderName isEqual:@"saved_stories"]) { folderImage = [UIImage imageNamed:@"clock.png"]; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { diff --git a/clients/ios/Classes/MoveSiteViewController.m b/clients/ios/Classes/MoveSiteViewController.m index 27b500976..9d5a3aa78 100644 --- a/clients/ios/Classes/MoveSiteViewController.m +++ b/clients/ios/Classes/MoveSiteViewController.m @@ -220,6 +220,7 @@ if ([folder isEqualToString:@"river_blurblogs"]) continue; if ([folder isEqualToString:@"river_global"]) continue; if ([folder isEqualToString:@"read_stories"]) continue; + if ([folder isEqualToString:@"saved_searches"]) continue; if ([folder isEqualToString:@"saved_stories"]) continue; if ([[folder trim] isEqualToString:@""]) continue; if (appDelegate.storiesCollection.isRiverView) { diff --git a/clients/ios/Classes/NewsBlurAppDelegate.h b/clients/ios/Classes/NewsBlurAppDelegate.h index bda4a8ebd..fcf522a04 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.h +++ b/clients/ios/Classes/NewsBlurAppDelegate.h @@ -229,6 +229,7 @@ SFSafariViewControllerDelegate> { @property (readwrite) NSString * activeShareType; @property (readwrite) NSInteger feedDetailPortraitYCoordinate; @property (readwrite) NSInteger originalStoryCount; +@property (readonly) NSInteger savedSearchesCount; @property (readwrite) NSInteger savedStoriesCount; @property (readwrite) NSInteger totalUnfetchedStoryCount; @property (readwrite) NSInteger remainingUnfetchedStoryCount; @@ -254,6 +255,7 @@ SFSafariViewControllerDelegate> { @property (nonatomic, strong) NSMutableDictionary *dictFeeds; @property (nonatomic) NSMutableDictionary *dictActiveFeeds; @property (nonatomic) NSDictionary *dictSocialFeeds; +@property (nonatomic) NSDictionary *dictSavedSearches; @property (nonatomic) NSDictionary *dictSavedStoryTags; @property (nonatomic, strong) NSDictionary *dictSavedStoryFeedCounts; @property (nonatomic) NSDictionary *dictSocialProfile; @@ -373,6 +375,7 @@ SFSafariViewControllerDelegate> { - (void)hideShareView:(BOOL)resetComment; - (void)resetShareComments; - (BOOL)isSocialFeed:(NSString *)feedIdStr; +//- (BOOL)isSavedSearch:(NSString *)feedIdStr; - (BOOL)isSavedFeed:(NSString *)feedIdStr; - (NSInteger)savedStoriesCountForFeed:(NSString *)feedIdStr; - (BOOL)isSavedStoriesIntelligenceMode; @@ -418,6 +421,7 @@ SFSafariViewControllerDelegate> { - (void)failedMarkAsUnsaved:(NSDictionary *)params; - (NSInteger)adjustSavedStoryCount:(NSString *)tagName direction:(NSInteger)direction; - (NSArray *)updateStarredStoryCounts:(NSDictionary *)results; +- (NSArray *)updateSavedSearches:(NSDictionary *)results; - (void)renameFeed:(NSString *)newTitle; - (void)renameFolder:(NSString *)newTitle; diff --git a/clients/ios/Classes/NewsBlurAppDelegate.m b/clients/ios/Classes/NewsBlurAppDelegate.m index 23742e50c..a9fb56098 100644 --- a/clients/ios/Classes/NewsBlurAppDelegate.m +++ b/clients/ios/Classes/NewsBlurAppDelegate.m @@ -1654,6 +1654,10 @@ return NO; } +//- (BOOL)isSavedSearch:(NSString *)feedIdStr { +// return [feedIdStr startsWith:@"search:"]; +//} + - (BOOL)isSavedFeed:(NSString *)feedIdStr { return [feedIdStr startsWith:@"saved:"]; } @@ -1666,6 +1670,10 @@ return self.selectedIntelligence == 2; } +- (NSInteger)savedSearchesCount { + return self.dictSavedSearches.count; +} + - (NSArray *)allFeedIds { NSMutableArray *mutableFeedIds = [NSMutableArray array]; @@ -1817,6 +1825,7 @@ for (NSString *folderName in self.feedsViewController.activeFeedLocations) { if ([folderName isEqualToString:@"river_blurblogs"]) continue; if ([folderName isEqualToString:@"read_stories"]) continue; + if ([folderName isEqualToString:@"saved_searches"]) continue; if ([folderName isEqualToString:@"saved_stories"]) continue; NSArray *originalFolder = [self.dictFolders objectForKey:folderName]; NSArray *folderFeeds = [self.feedsViewController.activeFeedLocations objectForKey:folderName]; @@ -1832,6 +1841,9 @@ if ([folder isEqualToString:@"saved_stories"] || [folderName isEqualToString:@"saved_stories"]) { feedDetailView.storiesCollection.isSavedView = YES; [feedDetailView.storiesCollection setActiveFolder:@"saved_stories"]; + } else if ([folder isEqualToString:@"saved_searches"] || [folderName isEqualToString:@"saved_searches"]) { + feedDetailView.storiesCollection.isSavedView = YES; + [feedDetailView.storiesCollection setActiveFolder:@"saved_searches"]; } else if ([folder isEqualToString:@"read_stories"] || [folderName isEqualToString:@"read_stories"]) { feedDetailView.storiesCollection.isReadView = YES; [feedDetailView.storiesCollection setActiveFolder:@"read_stories"]; @@ -2287,6 +2299,8 @@ activity.title = [NSString stringWithFormat:@"Read %@", storiesCollection.activeSavedStoryTag]; } else if ([folder isEqualToString:@"read_stories"]) { activity.title = @"Re-read Stories"; + } else if ([folder isEqualToString:@"saved_searches"]) { + activity.title = @"Re-read Saved Searches"; } else if ([folder isEqualToString:@"saved_stories"]) { activity.title = @"Re-read Saved Stories"; } else { @@ -2939,6 +2953,28 @@ return savedStories; } +- (NSArray *)updateSavedSearches:(NSDictionary *)results { + NSArray *savedSearches = results[@"saved_searches"]; + NSMutableDictionary *savedSearchesDict = [NSMutableDictionary dictionary]; + NSMutableArray *feedIds = [NSMutableArray arrayWithCapacity:savedSearches.count]; + + for (NSDictionary *search in savedSearches) { + NSString *feedId = search[@"feed_id"]; + NSString *prefix = @"feed:"; + + if ([feedId hasPrefix:prefix]) { + feedId = [feedId substringFromIndex:prefix.length]; + } + + [feedIds addObject:feedId]; + savedSearchesDict[feedId] = search; + } + + self.dictSavedSearches = savedSearchesDict; + + return feedIds; +} + - (void)renameFeed:(NSString *)newTitle { NSMutableDictionary *newActiveFeed = [storiesCollection.activeFeed mutableCopy]; [newActiveFeed setObject:newTitle forKey:@"feed_title"]; @@ -3348,6 +3384,8 @@ } } else if ([storiesCollection.activeFolder isEqualToString:@"read_stories"]) { titleLabel.text = [NSString stringWithFormat:@" Read Stories"]; + } else if ([storiesCollection.activeFolder isEqualToString:@"saved_searches"]) { + titleLabel.text = [NSString stringWithFormat:@" Saved Searches"]; } else if ([storiesCollection.activeFolder isEqualToString:@"saved_stories"]) { titleLabel.text = [NSString stringWithFormat:@" Saved Stories"]; } else if (storiesCollection.isSocialView) { @@ -3386,6 +3424,8 @@ titleImage = [UIImage imageNamed:@"tag.png"]; } else if ([storiesCollection.activeFolder isEqualToString:@"read_stories"]) { titleImage = [UIImage imageNamed:@"g_icn_folder_read.png"]; + } else if ([storiesCollection.activeFolder isEqualToString:@"saved_searches"]) { + titleImage = [[UIImage imageNamed:@"g_icn_search_black.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; } else if ([storiesCollection.activeFolder isEqualToString:@"saved_stories"]) { titleImage = [UIImage imageNamed:@"clock.png"]; } else if (storiesCollection.isRiverView) { diff --git a/clients/ios/Classes/NewsBlurViewController.m b/clients/ios/Classes/NewsBlurViewController.m index 9065f8c6f..f69aad530 100644 --- a/clients/ios/Classes/NewsBlurViewController.m +++ b/clients/ios/Classes/NewsBlurViewController.m @@ -713,6 +713,9 @@ static NSArray *NewsBlurTopSectionNames; [allFolders setValue:socialFolder forKey:@"river_blurblogs"]; [allFolders setValue:[[NSMutableArray alloc] init] forKey:@"river_global"]; + NSArray *savedSearches = [appDelegate updateSavedSearches:results]; + [allFolders setValue:savedSearches forKey:@"saved_searches"]; + NSArray *savedStories = [appDelegate updateStarredStoryCounts:results]; [allFolders setValue:savedStories forKey:@"saved_stories"]; @@ -750,9 +753,9 @@ static NSArray *NewsBlurTopSectionNames; for (id feedId in folder) { NSString *feedIdStr = [NSString stringWithFormat:@"%@", feedId]; - NSDictionary *feed; + NSDictionary *feed = nil; - if ([appDelegate isSavedFeed:feedIdStr]) { + if (/*[appDelegate isSavedSearch:feedIdStr] ||*/ [appDelegate isSavedFeed:feedIdStr]) { feed = @{@"id" : feedId}; } else if ([appDelegate isSocialFeed:feedIdStr]) { feed = appDelegate.dictSocialFeeds[feedIdStr]; @@ -783,7 +786,13 @@ static NSArray *NewsBlurTopSectionNames; // Add Read Stories folder to bottom [appDelegate.dictFoldersArray removeObject:@"read_stories"]; [appDelegate.dictFoldersArray insertObject:@"read_stories" atIndex:appDelegate.dictFoldersArray.count]; - + + // Add Saved Searches folder to bottom + [appDelegate.dictFoldersArray removeObject:@"saved_searches"]; + if (savedSearches.count > 0) { + [appDelegate.dictFoldersArray insertObject:@"saved_searches" atIndex:appDelegate.dictFoldersArray.count]; + } + // Add Saved Stories folder to bottom [appDelegate.dictFoldersArray removeObject:@"saved_stories"]; if (appDelegate.savedStoriesCount) { @@ -1226,6 +1235,7 @@ static NSArray *NewsBlurTopSectionNames; NSString *folderName = [appDelegate.dictFoldersArray objectAtIndex:indexPath.section]; id feedId = [[appDelegate.dictFolders objectForKey:folderName] objectAtIndex:indexPath.row]; NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId]; + BOOL isSavedSearch = [folderName isEqualToString:@"saved_searches"]; BOOL isSocial = [appDelegate isSocialFeed:feedIdStr]; BOOL isSaved = [appDelegate isSavedFeed:feedIdStr]; BOOL isSavedStoriesFeed = self.appDelegate.isSavedStoriesIntelligenceMode && [self.appDelegate savedStoriesCountForFeed:feedIdStr] > 0; @@ -1272,12 +1282,20 @@ static NSArray *NewsBlurTopSectionNames; cell.feedTitle = [feed objectForKey:@"feed_title"]; cell.isSocial = isSocial; cell.isSaved = isSaved; + cell.searchQuery = nil; if (newCell) { [cell setupGestures]; } - if (isSavedStoriesFeed) { + if (isSavedSearch) { + cell.positiveCount = 0; + cell.neutralCount = 0; + cell.negativeCount = 0; + cell.savedStoriesCount = 0; + cell.searchQuery = appDelegate.dictSavedSearches[feedIdStr][@"query"]; + cell.feedTitle = [NSString stringWithFormat:@"\"%@\" in %@", cell.searchQuery, cell.feedTitle]; + } else if (isSavedStoriesFeed) { cell.positiveCount = 0; cell.neutralCount = 0; cell.negativeCount = 0; @@ -1472,6 +1490,7 @@ heightForHeaderInSection:(NSInteger)section { BOOL visibleFeeds = [[self.visibleFolders objectForKey:folderName] boolValue]; if (!visibleFeeds && section != NewsBlurTopSectionInfrequentSiteStories && section != NewsBlurTopSectionAllStories && section != NewsBlurTopSectionGlobalSharedStories && + ![folderName isEqualToString:@"saved_searches"] && ![folderName isEqualToString:@"saved_stories"] && ![folderName isEqualToString:@"read_stories"]) { return 0; @@ -1899,6 +1918,11 @@ heightForHeaderInSection:(NSInteger)section { cellForRowAtIndexPath:self.currentRowAtIndexPath]; if (cell) { NSString *folderName = [appDelegate.dictFoldersArray objectAtIndex:self.currentRowAtIndexPath.section]; + + if ([folderName isEqualToString:@"saved_searches"]) { + return; + } + id feedId = [[appDelegate.dictFolders objectForKey:folderName] objectAtIndex:self.currentRowAtIndexPath.row]; NSString *feedIdStr = [NSString stringWithFormat:@"%@",feedId]; NSDictionary *unreadCounts = [appDelegate.dictUnreadCounts objectForKey:feedIdStr]; diff --git a/clients/ios/Classes/StoriesCollection.m b/clients/ios/Classes/StoriesCollection.m index e528f0081..96fb90384 100644 --- a/clients/ios/Classes/StoriesCollection.m +++ b/clients/ios/Classes/StoriesCollection.m @@ -323,6 +323,8 @@ return activeSavedStoryTag; } else if ([activeFolder isEqualToString:@"read_stories"]) { return @"Read Stories"; + } else if ([activeFolder isEqualToString:@"saved_searches"]) { + return @"Saved Searches"; } else if ([activeFolder isEqualToString:@"saved_stories"]) { return @"Saved Stories"; } else { diff --git a/clients/ios/Classes/StoryPageControl.m b/clients/ios/Classes/StoryPageControl.m index ad98d016c..378a158bc 100644 --- a/clients/ios/Classes/StoryPageControl.m +++ b/clients/ios/Classes/StoryPageControl.m @@ -301,6 +301,8 @@ titleImage = [UIImage imageNamed:@"tag.png"]; } else if ([appDelegate.storiesCollection.activeFolder isEqualToString:@"read_stories"]) { titleImage = [UIImage imageNamed:@"g_icn_folder_read.png"]; + } else if ([appDelegate.storiesCollection.activeFolder isEqualToString:@"saved_searches"]) { + titleImage = [[UIImage imageNamed:@"g_icn_search_black.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; } else if ([appDelegate.storiesCollection.activeFolder isEqualToString:@"saved_stories"]) { titleImage = [UIImage imageNamed:@"clock.png"]; } else if (appDelegate.storiesCollection.isRiverView) {