diff --git a/clients/ios/Classes/FeedDetailCollectionCell.m b/clients/ios/Classes/FeedDetailCollectionCell.m index 064778dcf..9df350cd0 100644 --- a/clients/ios/Classes/FeedDetailCollectionCell.m +++ b/clients/ios/Classes/FeedDetailCollectionCell.m @@ -347,7 +347,7 @@ static UIFont *indicatorFont = nil; } int storyTitleX = leftMargin; if (cell.isSaved) { - UIImage *savedIcon = [UIImage imageNamed:@"clock"]; + UIImage *savedIcon = [UIImage imageNamed:@"saved-stories"]; [savedIcon drawInRect:CGRectMake(storyTitleX, storyTitleY - 1, 16, 16) blendMode:0 alpha:1]; storyTitleX += 22; } diff --git a/clients/ios/Classes/FeedDetailObjCViewController.m b/clients/ios/Classes/FeedDetailObjCViewController.m index 44db7fb87..715d28f27 100644 --- a/clients/ios/Classes/FeedDetailObjCViewController.m +++ b/clients/ios/Classes/FeedDetailObjCViewController.m @@ -1844,8 +1844,12 @@ typedef NS_ENUM(NSUInteger, MarkReadShowMenu) NSDictionary *story = [self getStoryAtRow:indexPath.row]; NSString *content = [story[@"story_content"] convertHTML]; - if (content.length < 50 && [story[@"story_title"] length] < 30) { + if (content.length < 10 && [story[@"story_title"] length] < 30) { + return height; + } else if (content.length < 50 && [story[@"story_title"] length] < 30) { return height + font.pointSize * 2; + } else if (content.length < 50 && [story[@"story_title"] length] < 40) { + return height + font.pointSize * 3; } else if (content.length < 50 && [story[@"story_title"] length] >= 30) { return height + font.pointSize * 5; } else if (content.length < 100) { @@ -2154,8 +2158,15 @@ didEndSwipingSwipingWithState:(MCSwipeTableViewCellState)state [self reloadStories]; } // Don't do this, as it causes a race condition with the marking read call - // [self.appDelegate.feedsViewController refreshFeedList]; +// [self.appDelegate.feedsViewController refreshFeedList]; + [self.appDelegate.feedsViewController reloadFeedTitlesTable]; [self.appDelegate showFeedsListAnimated:YES]; + + NSString *loadNextPref = [[NSUserDefaults standardUserDefaults] stringForKey:@"after_mark_read"]; + + if (![loadNextPref isEqualToString:@"stay"]) { + [self.appDelegate.feedsViewController selectNextFolderOrFeed]; + } }; [storiesCollection calculateStoryLocations]; diff --git a/clients/ios/Classes/FeedsObjCViewController.h b/clients/ios/Classes/FeedsObjCViewController.h index f8d96ef24..7dda6f8b7 100644 --- a/clients/ios/Classes/FeedsObjCViewController.h +++ b/clients/ios/Classes/FeedsObjCViewController.h @@ -93,6 +93,7 @@ UIGestureRecognizerDelegate, UISearchBarDelegate> { - (void)finishLoadingFeedListWithDict:(NSDictionary *)results finished:(BOOL)finished; - (void)didSelectSectionHeader:(UIButton *)button; - (void)didSelectSectionHeaderWithTag:(NSInteger)tag; +- (void)selectNextFolderOrFeed; - (IBAction)selectIntelligence; - (void)markFeedRead:(NSString *)feedId cutoffDays:(NSInteger)days; - (void)markFeedsRead:(NSArray *)feedIds cutoffDays:(NSInteger)days; diff --git a/clients/ios/Classes/FeedsObjCViewController.m b/clients/ios/Classes/FeedsObjCViewController.m index e3491c5d1..adaa59830 100644 --- a/clients/ios/Classes/FeedsObjCViewController.m +++ b/clients/ios/Classes/FeedsObjCViewController.m @@ -50,6 +50,8 @@ static NSArray *NewsBlurTopSectionNames; @property (nonatomic) NSDate *leftAppDate; @property (nonatomic, strong) NSMutableDictionary *rowHeights; @property (nonatomic, strong) NSMutableDictionary *folderTitleViews; +@property (nonatomic, strong) NSIndexPath *lastRowAtIndexPath; +@property (nonatomic) NSInteger lastSection; @end @@ -203,12 +205,18 @@ static NSArray *NewsBlurTopSectionNames; self.currentRowAtIndexPath = nil; self.currentSection = NewsBlurTopSectionAllStories; + self.lastRowAtIndexPath = nil; + self.lastSection = NewsBlurTopSectionAllStories; userAvatarButton.hidden = YES; self.noFocusMessage.hidden = YES; // [self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(handleGesture:)]; + [self addKeyCommandWithInput:UIKeyInputDownArrow modifierFlags:UIKeyModifierAlternate action:@selector(selectNextFeed:) discoverabilityTitle:@"Next Site" wantPriority:YES]; + [self addKeyCommandWithInput:UIKeyInputUpArrow modifierFlags:UIKeyModifierAlternate action:@selector(selectPreviousFeed:) discoverabilityTitle:@"Previous Site" wantPriority:YES]; + [self addKeyCommandWithInput:UIKeyInputDownArrow modifierFlags:UIKeyModifierShift action:@selector(selectNextFolder:) discoverabilityTitle:@"Next Folder" wantPriority:YES]; + [self addKeyCommandWithInput:UIKeyInputUpArrow modifierFlags:UIKeyModifierShift action:@selector(selectPreviousFolder:) discoverabilityTitle:@"Previous Folder" wantPriority:YES]; [self addKeyCommandWithInput:@"e" modifierFlags:UIKeyModifierCommand action:@selector(selectEverything:) discoverabilityTitle:@"Open All Stories"]; [self addKeyCommandWithInput:UIKeyInputLeftArrow modifierFlags:0 action:@selector(selectPreviousIntelligence:) discoverabilityTitle:@"Switch Views"]; [self addKeyCommandWithInput:UIKeyInputRightArrow modifierFlags:0 action:@selector(selectNextIntelligence:) discoverabilityTitle:@"Switch Views"]; @@ -1588,6 +1596,8 @@ static NSArray *NewsBlurTopSectionNames; // set the current row pointer self.currentRowAtIndexPath = indexPath; self.currentSection = -1; + self.lastRowAtIndexPath = indexPath; + self.lastSection = -1; NSString *folderName = appDelegate.dictFoldersArray[indexPath.section]; id feedId = [[appDelegate.dictFolders objectForKey:folderName] objectAtIndex:indexPath.row]; @@ -1876,6 +1886,8 @@ heightForHeaderInSection:(NSInteger)section { // reset pointer to the cells self.currentRowAtIndexPath = nil; self.currentSection = tag; + self.lastRowAtIndexPath = nil; + self.lastSection = tag; [self highlightSelection]; @@ -1890,6 +1902,124 @@ heightForHeaderInSection:(NSInteger)section { [appDelegate loadRiverFeedDetailView:appDelegate.feedDetailViewController withFolder:folder]; } +- (NSArray *)allIndexPaths { + NSMutableArray *array = [NSMutableArray array]; + + for (NSInteger section = 0; section < self.feedTitlesTable.numberOfSections; section++) { + for (NSInteger row = 0; row < [self.feedTitlesTable numberOfRowsInSection:section]; row++) { + [array addObject:[NSIndexPath indexPathForRow:row inSection:section]]; + } + } + + return array; +} + +- (void)selectNextFolderOrFeed { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + if (self.lastRowAtIndexPath != nil) { + [self selectNextFeed:nil]; + } else { + [self selectNextFolder:nil]; + } + }); +} + +- (void)selectNextFeed:(id)sender { + NSArray *indexPaths = [self allIndexPaths]; + NSIndexPath *indexPath = self.lastRowAtIndexPath; + + if (indexPath == nil) { + if (self.lastSection < 0) { + indexPath = indexPaths.firstObject; + } else { + indexPath = [NSIndexPath indexPathForRow:0 inSection:self.lastSection]; + } + } else { + NSInteger index = [indexPaths indexOfObject:indexPath]; + + if (index == NSNotFound) { + index = -1; + } + + index += 1; + + if (index >= indexPaths.count) { + index = 0; + } + + indexPath = indexPaths[index]; + } + + [self.feedTitlesTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle]; + [self tableView:self.feedTitlesTable didSelectRowAtIndexPath:indexPath]; +} + +- (void)selectPreviousFeed:(id)sender { + NSArray *indexPaths = [self allIndexPaths]; + NSIndexPath *indexPath = self.lastRowAtIndexPath; + + if (indexPath == nil) { + if (self.lastSection < 0) { + indexPath = indexPaths.firstObject; + } else { + indexPath = [NSIndexPath indexPathForRow:0 inSection:self.lastSection]; + } + } + + NSInteger index = [indexPaths indexOfObject:indexPath]; + + if (index == NSNotFound) { + index = 0; + } + + index -= 1; + + if (index < 0) { + index = indexPaths.count - 1; + } + + indexPath = indexPaths[index]; + + [self.feedTitlesTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle]; + [self tableView:self.feedTitlesTable didSelectRowAtIndexPath:indexPath]; +} + +- (void)selectNextFolder:(id)sender { + NSInteger section = self.lastSection; + + if (section < self.feedTitlesTable.numberOfSections - 1) { + section += 1; + } else { + section = 0; + } + + [self didSelectSectionHeaderWithTag:section]; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section]; + + if ([self.feedTitlesTable numberOfRowsInSection:section] > 0) { + [self.feedTitlesTable scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; + } +} + +- (void)selectPreviousFolder:(id)sender { + NSInteger section = self.lastSection; + + if (section > 0) { + section -= 1; + } else { + section = self.feedTitlesTable.numberOfSections - 1; + } + + [self didSelectSectionHeaderWithTag:section]; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section]; + + if ([self.feedTitlesTable numberOfRowsInSection:section] > 0) { + [self.feedTitlesTable scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; + } +} + - (void)selectEverything:(id)sender { [self didSelectSectionHeaderWithTag:NewsBlurTopSectionAllStories]; } diff --git a/clients/ios/Classes/FolderTitleView.m b/clients/ios/Classes/FolderTitleView.m index 76961e8b1..4b6c3f167 100644 --- a/clients/ios/Classes/FolderTitleView.m +++ b/clients/ios/Classes/FolderTitleView.m @@ -42,7 +42,8 @@ NSString *folderName = appDelegate.dictFoldersArray[section]; NSString *collapseKey = [NSString stringWithFormat:@"folderCollapsed:%@", folderName]; - bool isFolderCollapsed = [userPreferences boolForKey:collapseKey]; + BOOL isFolderCollapsed = [userPreferences boolForKey:collapseKey]; + BOOL isSavedStoriesFeed = self.appDelegate.isSavedStoriesIntelligenceMode; NSInteger countWidth = 0; NSString *accessibilityCount = @""; NSArray *folderComponents = [folderName componentsSeparatedByString:@" ▸ "]; @@ -77,7 +78,7 @@ [self addSubview:unreadCount]; accessibilityCount = [NSString stringWithFormat:@", %@ searches", @(count)]; - } else if (isFolderCollapsed) { + } else if (isFolderCollapsed && !isSavedStoriesFeed) { UnreadCounts *counts = [appDelegate splitUnreadCountForFolder:folderName]; unreadCount = [[UnreadCountView alloc] initWithFrame:CGRectMake(rect.origin.x, 0, CGRectGetWidth(rect), CGRectGetHeight(rect))]; unreadCount.appDelegate = appDelegate; @@ -287,7 +288,7 @@ [customView setAutoresizingMask:UIViewAutoresizingNone]; - if (isFolderCollapsed) { + if (isFolderCollapsed && !isSavedStoriesFeed) { [self insertSubview:customView belowSubview:unreadCount]; } else { [self addSubview:customView]; diff --git a/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m b/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m index fad0c3687..0e49853a8 100755 --- a/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m +++ b/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKAppSettingsViewController.m @@ -215,6 +215,8 @@ CGRect IASKCGRectSwap(CGRect rect); [dc addObserver:self selector:@selector(didChangeSettingViaIASK:) name:kIASKAppSettingChanged object:nil]; [self userDefaultsDidChange]; // force update in case of changes while we were hidden } + + self.overrideUserInterfaceStyle = ThemeManager.shared.isDarkTheme ? UIUserInterfaceStyleDark : UIUserInterfaceStyleLight; } - (CGSize)preferredContentSize { diff --git a/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m b/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m index 20130e4b6..cea0cdba7 100755 --- a/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m +++ b/clients/ios/Other Sources/InAppSettingsKit/Controllers/IASKSpecifierValuesViewController.m @@ -65,6 +65,8 @@ _selection.tableView = _tableView; } self.didFirstLayout = NO; + self.overrideUserInterfaceStyle = ThemeManager.shared.isDarkTheme ? UIUserInterfaceStyleDark : UIUserInterfaceStyleLight; + [super viewWillAppear:animated]; } diff --git a/clients/ios/Resources/Settings.bundle/Root.plist b/clients/ios/Resources/Settings.bundle/Root.plist index fc49570c4..a66021f2c 100644 --- a/clients/ios/Resources/Settings.bundle/Root.plist +++ b/clients/ios/Resources/Settings.bundle/Root.plist @@ -94,6 +94,26 @@ Key default_confirm_read_filter + + Type + PSMultiValueSpecifier + Title + After mark read + Titles + + Open the next site/folder + Stay on the feeds list + + DefaultValue + next + Values + + next + stay + + Key + after_mark_read + Type PSMultiValueSpecifier diff --git a/clients/ios/Resources/Settings.bundle/Root~ipad.plist b/clients/ios/Resources/Settings.bundle/Root~ipad.plist index 6857f9ac3..2b7685cdb 100644 --- a/clients/ios/Resources/Settings.bundle/Root~ipad.plist +++ b/clients/ios/Resources/Settings.bundle/Root~ipad.plist @@ -94,6 +94,26 @@ Key default_confirm_read_filter + + Type + PSMultiValueSpecifier + Title + After mark read + Titles + + Open the next site/folder + Stay on the feeds list + + DefaultValue + next + Values + + next + stay + + Key + after_mark_read + Type PSMultiValueSpecifier