diff --git a/Shared/Activity/ActivityManager.swift b/Shared/Activity/ActivityManager.swift
index 582983d15..f5a6c7f4b 100644
--- a/Shared/Activity/ActivityManager.swift
+++ b/Shared/Activity/ActivityManager.swift
@@ -10,18 +10,65 @@ import Foundation
import CoreSpotlight
import CoreServices
import Articles
+import Intents
class ActivityManager {
public static var shared = ActivityManager()
+ private var selectingActivity: NSUserActivity? = nil
+ private var readingActivity: NSUserActivity? = nil
+
+ func selectingToday() {
+ let title = NSLocalizedString("See articles for Today", comment: "Today")
+ selectingActivity = makeSmartFeedActivity(type: ActivityType.selectToday, title: title, identifier: "smartfeed.today")
+ selectingActivity!.becomeCurrent()
+ }
+
+ func selectingAllUnread() {
+ let title = NSLocalizedString("See articles in All Unread", comment: "All Unread")
+ selectingActivity = makeSmartFeedActivity(type: ActivityType.selectAllUnread, title: title, identifier: "smartfeed.allUnread")
+ selectingActivity!.becomeCurrent()
+ }
+
+ func selectingStarred() {
+ let title = NSLocalizedString("See articles in Starred", comment: "Starred")
+ selectingActivity = makeSmartFeedActivity(type: ActivityType.selectStarred, title: title, identifier: "smartfeed.starred")
+ selectingActivity!.becomeCurrent()
+ }
+
+ func reading(_ article: Article?) {
+ readingActivity?.invalidate()
+ readingActivity = nil
+ guard let article = article else { return }
+ readingActivity = makeReadArticleActivity(article)
+ readingActivity?.becomeCurrent()
+ }
+
+}
+
+// MARK: Private
+
+private extension ActivityManager {
+
+ func makeSmartFeedActivity(type: ActivityType, title: String, identifier: String) -> NSUserActivity {
+ let activity = NSUserActivity(activityType: type.rawValue)
+ activity.title = title
+ activity.suggestedInvocationPhrase = title
+ activity.keywords = Set(makeKeywords(title))
+ activity.isEligibleForPrediction = true
+ activity.isEligibleForSearch = true
+ activity.persistentIdentifier = identifier
+ return activity
+ }
+
func makeReadArticleActivity(_ article: Article) -> NSUserActivity {
let activity = NSUserActivity(activityType: ActivityType.readArticle.rawValue)
activity.title = article.title
- let feedNameKeywords = article.feed?.nameForDisplay.components(separatedBy: " ").filter { $0.count > 2 } ?? []
- let articleTitleKeywords = article.title?.components(separatedBy: " ").filter { $0.count > 2 } ?? []
+ let feedNameKeywords = makeKeywords(article.feed?.nameForDisplay)
+ let articleTitleKeywords = makeKeywords(article.title)
let keywords = feedNameKeywords + articleTitleKeywords
activity.keywords = Set(keywords)
@@ -51,4 +98,8 @@ class ActivityManager {
return activity
}
+ func makeKeywords(_ value: String?) -> [String] {
+ return value?.components(separatedBy: " ").filter { $0.count > 2 } ?? []
+ }
+
}
diff --git a/Shared/Activity/ActivityType.swift b/Shared/Activity/ActivityType.swift
index 26000f44a..3e2874441 100644
--- a/Shared/Activity/ActivityType.swift
+++ b/Shared/Activity/ActivityType.swift
@@ -9,5 +9,8 @@
import Foundation
enum ActivityType: String {
+ case selectToday = "com.ranchero.NetNewsWire.SelectToday"
+ case selectAllUnread = "com.ranchero.NetNewsWire.SelectAllUnread"
+ case selectStarred = "com.ranchero.NetNewsWire.SelectStarred"
case readArticle = "com.ranchero.NetNewsWire.ReadArticle"
}
diff --git a/iOS/AppCoordinator.swift b/iOS/AppCoordinator.swift
index 8b93ff480..fe55ec63e 100644
--- a/iOS/AppCoordinator.swift
+++ b/iOS/AppCoordinator.swift
@@ -90,6 +90,7 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
timelineFetcher = fetcher
}
masterFeedViewController.updateFeedSelection()
+ updateSelectingActivity(with: node)
}
}
@@ -203,8 +204,6 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
}
}
- private(set) var readActivity: NSUserActivity? = nil
-
override init() {
super.init()
@@ -248,6 +247,12 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
func handle(_ activity: NSUserActivity) {
guard let activityType = ActivityType(rawValue: activity.activityType) else { return }
switch activityType {
+ case .selectToday:
+ handleSelectToday()
+ case .selectAllUnread:
+ handleSelectAllUnread()
+ case .selectStarred:
+ handleSelectStarred()
case .readArticle:
handleReadArticle(activity)
}
@@ -361,6 +366,13 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
return nil
}
+ func indexPath(for object: AnyObject) -> IndexPath? {
+ guard let node = treeController.rootNode.descendantNodeRepresentingObject(object) else {
+ return nil
+ }
+ return indexPathFor(node)
+ }
+
func unreadCountFor(_ node: Node) -> Int {
// The coordinator supplies the unread count for the currently selected feed node
if let indexPath = currentMasterIndexPath, let selectedNode = nodeFor(indexPath), selectedNode == node {
@@ -510,7 +522,7 @@ class AppCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
func selectArticle(_ indexPath: IndexPath?) {
currentArticleIndexPath = indexPath
- updateReadArticleUserActivity()
+ ActivityManager.shared.reading(currentArticle)
if indexPath == nil {
if !rootSplitViewController.isCollapsed {
@@ -1173,14 +1185,35 @@ private extension AppCoordinator {
// MARK: NSUserActivity
- func updateReadArticleUserActivity() {
- readActivity?.invalidate()
- readActivity = nil
-
- guard let article = currentArticle else { return }
-
- readActivity = ActivityManager.shared.makeReadArticleActivity(article)
- readActivity?.becomeCurrent()
+ func updateSelectingActivity(with node: Node) {
+ switch true {
+ case node.representedObject === SmartFeedsController.shared.todayFeed:
+ ActivityManager.shared.selectingToday()
+ case node.representedObject === SmartFeedsController.shared.unreadFeed:
+ ActivityManager.shared.selectingAllUnread()
+ case node.representedObject === SmartFeedsController.shared.starredFeed:
+ ActivityManager.shared.selectingStarred()
+ default:
+ break
+ }
+ }
+
+ func handleSelectToday() {
+ if let indexPath = indexPath(for: SmartFeedsController.shared.todayFeed) {
+ selectFeed(indexPath)
+ }
+ }
+
+ func handleSelectAllUnread() {
+ if let indexPath = indexPath(for: SmartFeedsController.shared.unreadFeed) {
+ selectFeed(indexPath)
+ }
+ }
+
+ func handleSelectStarred() {
+ if let indexPath = indexPath(for: SmartFeedsController.shared.starredFeed) {
+ selectFeed(indexPath)
+ }
}
func handleReadArticle(_ activity: NSUserActivity) {
diff --git a/iOS/Resources/Info.plist b/iOS/Resources/Info.plist
index fcfc523d3..1594130c6 100644
--- a/iOS/Resources/Info.plist
+++ b/iOS/Resources/Info.plist
@@ -49,6 +49,9 @@
NSUserActivityTypes
+ com.ranchero.NetNewsWire.SelectAllUnread
+ com.ranchero.NetNewsWire.SelectStarred
+ com.ranchero.NetNewsWire.SelectToday
com.ranchero.NetNewsWire.ReadArticle
NSAppTransportSecurity