diff --git a/Shared/Activity/ActivityManager.swift b/Shared/Activity/ActivityManager.swift index bf5bd9983..dafc7e854 100644 --- a/Shared/Activity/ActivityManager.swift +++ b/Shared/Activity/ActivityManager.swift @@ -15,8 +15,9 @@ import Intents class ActivityManager { - private var selectingActivity: NSUserActivity? = nil - private var readingActivity: NSUserActivity? = nil + private var nextUnreadActivity: NSUserActivity? + private var selectingActivity: NSUserActivity? + private var readingActivity: NSUserActivity? var stateRestorationActivity: NSUserActivity? { if readingActivity != nil { @@ -30,31 +31,38 @@ class ActivityManager { } func invalidateCurrentActivities() { - readingActivity?.invalidate() - readingActivity = nil - selectingActivity?.invalidate() - selectingActivity = nil + invalidateReading() + invalidateSelecting() + invalidateNextUnread() } func selectingToday() { - let title = NSLocalizedString("See articles for Today", comment: "Today") + invalidateCurrentActivities() + + let title = NSLocalizedString("See articles for “Today”", comment: "Today") selectingActivity = makeSelectingActivity(type: ActivityType.selectToday, title: title, identifier: "smartfeed.today") selectingActivity!.becomeCurrent() } func selectingAllUnread() { - let title = NSLocalizedString("See articles in All Unread", comment: "All Unread") + invalidateCurrentActivities() + + let title = NSLocalizedString("See articles in “All Unread”", comment: "All Unread") selectingActivity = makeSelectingActivity(type: ActivityType.selectAllUnread, title: title, identifier: "smartfeed.allUnread") selectingActivity!.becomeCurrent() } func selectingStarred() { - let title = NSLocalizedString("See articles in Starred", comment: "Starred") + invalidateCurrentActivities() + + let title = NSLocalizedString("See articles in “Starred”", comment: "Starred") selectingActivity = makeSelectingActivity(type: ActivityType.selectStarred, title: title, identifier: "smartfeed.starred") selectingActivity!.becomeCurrent() } func selectingFolder(_ folder: Folder) { + invalidateCurrentActivities() + let localizedText = NSLocalizedString("See articles in “%@”", comment: "See articles in Folder") let title = NSString.localizedStringWithFormat(localizedText as NSString, folder.nameForDisplay) as String selectingActivity = makeSelectingActivity(type: ActivityType.selectFolder, title: title, identifier: ActivityManager.identifer(for: folder)) @@ -69,6 +77,8 @@ class ActivityManager { } func selectingFeed(_ feed: Feed) { + invalidateCurrentActivities() + let localizedText = NSLocalizedString("See articles in “%@”", comment: "See articles in Feed") let title = NSString.localizedStringWithFormat(localizedText as NSString, feed.nameForDisplay) as String selectingActivity = makeSelectingActivity(type: ActivityType.selectFeed, title: title, identifier: ActivityManager.identifer(for: feed)) @@ -83,14 +93,36 @@ class ActivityManager { selectingActivity!.becomeCurrent() } + func invalidateSelecting() { + selectingActivity?.invalidate() + selectingActivity = nil + } + + func selectingNextUnread() { + guard nextUnreadActivity == nil else { return } + let title = NSLocalizedString("See first unread article", comment: "First Unread") + nextUnreadActivity = makeSelectingActivity(type: ActivityType.nextUnread, title: title, identifier: "action.nextUnread") + nextUnreadActivity!.becomeCurrent() + } + + func invalidateNextUnread() { + nextUnreadActivity?.invalidate() + nextUnreadActivity = nil + } + func reading(_ article: Article?) { - readingActivity?.invalidate() - readingActivity = nil + invalidateReading() + invalidateNextUnread() guard let article = article else { return } readingActivity = makeReadArticleActivity(article) readingActivity?.becomeCurrent() } + func invalidateReading() { + nextUnreadActivity?.invalidate() + nextUnreadActivity = nil + } + static func cleanUp(_ account: Account) { var ids = [String]() diff --git a/Shared/Activity/ActivityType.swift b/Shared/Activity/ActivityType.swift index 84f5e603d..be0254fb4 100644 --- a/Shared/Activity/ActivityType.swift +++ b/Shared/Activity/ActivityType.swift @@ -14,5 +14,6 @@ enum ActivityType: String { case selectStarred = "com.ranchero.NetNewsWire.SelectStarred" case selectFolder = "com.ranchero.NetNewsWire.SelectFolder" case selectFeed = "com.ranchero.NetNewsWire.SelectFeed" + case nextUnread = "com.ranchero.NetNewsWire.NextUnread" case readArticle = "com.ranchero.NetNewsWire.ReadArticle" } diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index c34f225df..feaa5bb6f 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -269,6 +269,8 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { handleSelectFolder(activity) case .selectFeed: handleSelectFeed(activity) + case .nextUnread: + selectFirstUnreadInAllUnread() case .readArticle: handleReadArticle(activity) } @@ -609,7 +611,9 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } func selectFirstUnread() { - selectFirstUnreadArticleInTimeline() + if selectFirstUnreadArticleInTimeline() { + activityManager.selectingNextUnread() + } } func selectNextUnread() { @@ -621,12 +625,15 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider { } if selectNextUnreadArticleInTimeline() { + activityManager.selectingNextUnread() return } selectNextUnreadFeedFetcher() - selectNextUnreadArticleInTimeline() - + if selectNextUnreadArticleInTimeline() { + activityManager.selectingNextUnread() + } + } func markAllAsRead(_ articles: [Article]) {