forked from shadowfacts/Tusker
Add NSUserActivity's for timelines
This commit is contained in:
parent
e17e00583f
commit
32d6756762
|
@ -41,3 +41,50 @@ extension Timeline {
|
|||
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>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.show-timeline</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.check-notifications</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.new-post</string>
|
||||
</array>
|
||||
|
|
|
@ -44,9 +44,11 @@ class TimelineTableViewController: EnhancedTableViewController {
|
|||
|
||||
title = timeline.title
|
||||
tabBarItem.image = timeline.tabBarImage
|
||||
|
||||
|
||||
self.refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged)
|
||||
|
||||
userActivity = UserActivityManager.showTimelineActivity(timeline: timeline)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
|
|
@ -12,6 +12,9 @@ import Pachyderm
|
|||
class UserActivityManager {
|
||||
|
||||
// MARK: - Utils
|
||||
private static let encoder = PropertyListEncoder()
|
||||
private static let decoder = PropertyListDecoder()
|
||||
|
||||
private static func present(_ vc: UIViewController, animated: Bool = true) {
|
||||
UIApplication.shared.delegate?.window??.rootViewController?.present(vc, animated: animated)
|
||||
}
|
||||
|
@ -52,4 +55,66 @@ class UserActivityManager {
|
|||
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
|
||||
|
||||
enum UserActivityType: String {
|
||||
case newPost = "net.shadowfacts.tusker.activity.new-post"
|
||||
case checkNotifications = "net.shadowfacts.tusker.activity.check-notifications"
|
||||
case newPost = "net.shadowfacts.Tusker.activity.new-post"
|
||||
case checkNotifications = "net.shadowfacts.Tusker.activity.check-notifications"
|
||||
case showTimeline = "net.shadowfacts.Tusker.activity.show-timeline"
|
||||
}
|
||||
|
||||
extension UserActivityType {
|
||||
|
@ -20,6 +21,8 @@ extension UserActivityType {
|
|||
return UserActivityManager.handleNewPost
|
||||
case .checkNotifications:
|
||||
return UserActivityManager.handleCheckNotifications
|
||||
case .showTimeline:
|
||||
return UserActivityManager.handleShowTimeline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue