diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 278c9a4f..9851b6f2 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -110,6 +110,7 @@ D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; }; D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; }; D667383C23299340000A2373 /* InstanceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667383B23299340000A2373 /* InstanceType.swift */; }; + D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */; }; D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; }; D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */; }; D667E5E921349EE50057A976 /* ProfileHeaderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E821349EE50057A976 /* ProfileHeaderTableViewCell.xib */; }; @@ -367,6 +368,7 @@ D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visibility+Helpers.swift"; sourceTree = ""; }; D667383B23299340000A2373 /* InstanceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceType.swift; sourceTree = ""; }; + D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShortcutItems.swift; sourceTree = ""; }; D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = ""; }; D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = ""; }; D667E5E821349EE50057A976 /* ProfileHeaderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProfileHeaderTableViewCell.xib; sourceTree = ""; }; @@ -706,6 +708,7 @@ D62D2425217ABF63005076CC /* UserActivityType.swift */, D62D2421217AA7E1005076CC /* UserActivityManager.swift */, D62D2423217ABF3F005076CC /* NSUserActivity+Extensions.swift */, + D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */, ); path = Shortcuts; sourceTree = ""; @@ -1572,6 +1575,7 @@ D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */, D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */, D6A3BC852321F6C100FD64D5 /* AccountListTableViewController.swift in Sources */, + D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */, D646C956213B365700269FB5 /* LargeImageExpandAnimationController.swift in Sources */, 0454DDB122B467AA00B8BB8E /* GalleryShrinkAnimationController.swift in Sources */, D667E5F82135C3040057A976 /* Mastodon+Equatable.swift in Sources */, diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index 4b5272c2..4a8560ba 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -14,6 +14,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + AppShortcutItem.createItems(for: application) + window = UIWindow(frame: UIScreen.main.bounds) if LocalData.shared.onboardingComplete { @@ -26,9 +28,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { window!.makeKeyAndVisible() + if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem { + AppShortcutItem.handle(shortcutItem) + } + return true } - + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { if url.host == "x-callback-url" { return XCBManager.handle(url: url) @@ -57,6 +63,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return userActivity.handleResume() } + func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { + completionHandler(AppShortcutItem.handle(shortcutItem)) + } + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. diff --git a/Tusker/Shortcuts/AppShortcutItems.swift b/Tusker/Shortcuts/AppShortcutItems.swift new file mode 100644 index 00000000..0e9dea80 --- /dev/null +++ b/Tusker/Shortcuts/AppShortcutItems.swift @@ -0,0 +1,65 @@ +// +// AppShortcutItems.swift +// Tusker +// +// Created by Shadowfacts on 9/19/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit + +enum AppShortcutItem: String, CaseIterable { + case showHomeTimeline + case showNotifications + case composePost + + var title: String { + switch self { + case .showHomeTimeline: + return NSLocalizedString("Home", comment: "home app shortcut title") + case .showNotifications: + return NSLocalizedString("Notifications", comment: "notifications app shortcut title") + case .composePost: + return NSLocalizedString("Compose Post", comment: "compose post app shortcut title") + } + } + + var icon: UIApplicationShortcutIcon { + switch self { + case .showHomeTimeline: + return .init(type: .home) + case .showNotifications: + return .init(systemImageName: "bell.fill") + case .composePost: + return .init(type: .compose) + } + } + + func handle() { + let tab: MainTabBarViewController.Tab + switch self { + case .showHomeTimeline: + tab = .timelines + case .showNotifications: + tab = .notifications + case .composePost: + tab = .compose + } + let controller = (UIApplication.shared.delegate!.window!!.rootViewController as! MainTabBarViewController) + controller.select(tab: tab) + } +} + +extension AppShortcutItem { + static func createItems(for application: UIApplication) { + application.shortcutItems = allCases.map { + return UIApplicationShortcutItem(type: $0.rawValue, localizedTitle: $0.title, localizedSubtitle: nil, icon: $0.icon, userInfo: nil) + } + } + + static func handle(_ shortcutItem: UIApplicationShortcutItem) -> Bool { + guard let type = AppShortcutItem(rawValue: shortcutItem.type) else { return false } + type.handle() + return true + } +}