Add NSUserActivity's for timelines
This commit is contained in:
parent
e17e00583f
commit
32d6756762
|
@ -41,3 +41,50 @@ extension Timeline {
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Timeline: Codable {
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
let type = try container.decode(String.self, forKey: .type)
|
||||||
|
switch type {
|
||||||
|
case "home":
|
||||||
|
self = .home
|
||||||
|
case "public":
|
||||||
|
self = .public(local: try container.decode(Bool.self, forKey: .local))
|
||||||
|
case "tag":
|
||||||
|
self = .tag(hashtag: try container.decode(String.self, forKey: .hashtag))
|
||||||
|
case "list":
|
||||||
|
self = .list(id: try container.decode(String.self, forKey: .listID))
|
||||||
|
case "direct":
|
||||||
|
self = .direct
|
||||||
|
default:
|
||||||
|
throw DecodingError.dataCorruptedError(forKey: CodingKeys.type, in: container, debugDescription: "Timeline type must be one of 'home', 'local', 'tag', 'list', or 'direct'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
switch self {
|
||||||
|
case .home:
|
||||||
|
try container.encode("home", forKey: .type)
|
||||||
|
case let .public(local):
|
||||||
|
try container.encode("public", forKey: .type)
|
||||||
|
try container.encode(local, forKey: .local)
|
||||||
|
case let .tag(hashtag):
|
||||||
|
try container.encode("tag", forKey: .type)
|
||||||
|
try container.encode(hashtag, forKey: .hashtag)
|
||||||
|
case let .list(id):
|
||||||
|
try container.encode("list", forKey: .type)
|
||||||
|
try container.encode(id, forKey: .listID)
|
||||||
|
case .direct:
|
||||||
|
try container.encode("direct", forKey: .type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case type
|
||||||
|
case local
|
||||||
|
case hashtag
|
||||||
|
case listID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSUserActivityTypes</key>
|
<key>NSUserActivityTypes</key>
|
||||||
<array>
|
<array>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.show-timeline</string>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.check-notifications</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.check-notifications</string>
|
||||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.new-post</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.new-post</string>
|
||||||
</array>
|
</array>
|
||||||
|
|
|
@ -47,6 +47,8 @@ class TimelineTableViewController: EnhancedTableViewController {
|
||||||
|
|
||||||
self.refreshControl = UIRefreshControl()
|
self.refreshControl = UIRefreshControl()
|
||||||
refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged)
|
refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged)
|
||||||
|
|
||||||
|
userActivity = UserActivityManager.showTimelineActivity(timeline: timeline)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
|
|
@ -12,6 +12,9 @@ import Pachyderm
|
||||||
class UserActivityManager {
|
class UserActivityManager {
|
||||||
|
|
||||||
// MARK: - Utils
|
// MARK: - Utils
|
||||||
|
private static let encoder = PropertyListEncoder()
|
||||||
|
private static let decoder = PropertyListDecoder()
|
||||||
|
|
||||||
private static func present(_ vc: UIViewController, animated: Bool = true) {
|
private static func present(_ vc: UIViewController, animated: Bool = true) {
|
||||||
UIApplication.shared.delegate?.window??.rootViewController?.present(vc, animated: animated)
|
UIApplication.shared.delegate?.window??.rootViewController?.present(vc, animated: animated)
|
||||||
}
|
}
|
||||||
|
@ -52,4 +55,66 @@ class UserActivityManager {
|
||||||
tabBarController.selectedIndex = 1
|
tabBarController.selectedIndex = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Show Timeline
|
||||||
|
static func showTimelineActivity(timeline: Timeline) -> NSUserActivity? {
|
||||||
|
guard let timelineData = try? encoder.encode(timeline) else { return nil }
|
||||||
|
|
||||||
|
let activity = NSUserActivity(type: .showTimeline)
|
||||||
|
activity.isEligibleForPrediction = true
|
||||||
|
activity.userInfo = ["timelineData": timelineData]
|
||||||
|
switch timeline {
|
||||||
|
case .home:
|
||||||
|
activity.title = NSLocalizedString("Show Home Timeline", comment: "home timeline shortcut title")
|
||||||
|
activity.suggestedInvocationPhrase = NSLocalizedString("Show my home timeline", comment: "home timeline shortcut invocation phrase")
|
||||||
|
case .public(local: true):
|
||||||
|
activity.title = NSLocalizedString("Show Local Timeline", comment: "local timeline shortcut title")
|
||||||
|
activity.suggestedInvocationPhrase = NSLocalizedString("Show my local timeline", comment: "local timeline shortcut invocation phrase")
|
||||||
|
case .public(local: false):
|
||||||
|
activity.title = NSLocalizedString("Show Federated Timeline", comment: "federated timeline shortcut title")
|
||||||
|
activity.suggestedInvocationPhrase = NSLocalizedString("Show my federated timeline", comment: "federated timeline invocation phrase")
|
||||||
|
case let .tag(hashtag):
|
||||||
|
activity.title = String(format: NSLocalizedString("Show #%@", comment: "show hashtag shortcut title"), hashtag)
|
||||||
|
activity.suggestedInvocationPhrase = String(format: NSLocalizedString("Show the %@ hashtag", comment: "hashtag shortcut invocation phrase"), hashtag)
|
||||||
|
case .list:
|
||||||
|
// todo: add title to list
|
||||||
|
activity.title = NSLocalizedString("Show List", comment: "list timeline shortcut title")
|
||||||
|
activity.suggestedInvocationPhrase = NSLocalizedString("Show my list", comment: "list timeline invocation phrase")
|
||||||
|
case .direct:
|
||||||
|
activity.title = NSLocalizedString("Show Direct Messages", comment: "direct message timeline shortcut title")
|
||||||
|
activity.suggestedInvocationPhrase = NSLocalizedString("Show my direct messages", comment: "direct message timeline invocation phrase")
|
||||||
|
}
|
||||||
|
return activity
|
||||||
|
}
|
||||||
|
|
||||||
|
static func handleShowTimeline(activity: NSUserActivity) {
|
||||||
|
guard let timelineData = activity.userInfo?["timelineData"] as? Data,
|
||||||
|
let timeline = try? decoder.decode(Timeline.self, from: timelineData) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let tabBarController = UIApplication.shared.keyWindow!.rootViewController! as! UITabBarController
|
||||||
|
tabBarController.selectedIndex = 0
|
||||||
|
let navigationController = tabBarController.viewControllers![0] as! UINavigationController
|
||||||
|
switch timeline {
|
||||||
|
case .home, .public(true), .public(false):
|
||||||
|
navigationController.popToRootViewController(animated: false)
|
||||||
|
let rootController = navigationController.viewControllers.first! as! SegmentedPageViewController
|
||||||
|
let index: Int
|
||||||
|
switch timeline {
|
||||||
|
case .home:
|
||||||
|
index = 0
|
||||||
|
case .public(false):
|
||||||
|
index = 1
|
||||||
|
case .public(true):
|
||||||
|
index = 2
|
||||||
|
default:
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
rootController.segmentedControl.selectedSegmentIndex = index
|
||||||
|
rootController.selectPage(at: index, animated: false)
|
||||||
|
default:
|
||||||
|
navigationController.pushViewController(TimelineTableViewController(for: timeline), animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum UserActivityType: String {
|
enum UserActivityType: String {
|
||||||
case newPost = "net.shadowfacts.tusker.activity.new-post"
|
case newPost = "net.shadowfacts.Tusker.activity.new-post"
|
||||||
case checkNotifications = "net.shadowfacts.tusker.activity.check-notifications"
|
case checkNotifications = "net.shadowfacts.Tusker.activity.check-notifications"
|
||||||
|
case showTimeline = "net.shadowfacts.Tusker.activity.show-timeline"
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UserActivityType {
|
extension UserActivityType {
|
||||||
|
@ -20,6 +21,8 @@ extension UserActivityType {
|
||||||
return UserActivityManager.handleNewPost
|
return UserActivityManager.handleNewPost
|
||||||
case .checkNotifications:
|
case .checkNotifications:
|
||||||
return UserActivityManager.handleCheckNotifications
|
return UserActivityManager.handleCheckNotifications
|
||||||
|
case .showTimeline:
|
||||||
|
return UserActivityManager.handleShowTimeline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue