mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +09:00
142 lines
6.4 KiB
Swift
142 lines
6.4 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Foundation
|
|
import Storage
|
|
|
|
import Shared
|
|
import XCGLogger
|
|
|
|
enum ShortcutType: String {
|
|
case newTab = "NewTab"
|
|
case newPrivateTab = "NewPrivateTab"
|
|
case openLastBookmark = "OpenLastBookmark"
|
|
case qrCode = "QRCode"
|
|
|
|
init?(fullType: String) {
|
|
guard let last = fullType.components(separatedBy: ".").last else { return nil }
|
|
|
|
self.init(rawValue: last)
|
|
}
|
|
|
|
var type: String {
|
|
return Bundle.main.bundleIdentifier! + ".\(self.rawValue)"
|
|
}
|
|
}
|
|
|
|
protocol QuickActionHandlerDelegate {
|
|
func handleShortCutItemType(_ type: ShortcutType, userData: [String: NSSecureCoding]?)
|
|
}
|
|
|
|
class QuickActions: NSObject {
|
|
|
|
fileprivate let log = Logger.browserLogger
|
|
|
|
static let QuickActionsVersion = "1.0"
|
|
static let QuickActionsVersionKey = "dynamicQuickActionsVersion"
|
|
|
|
static let TabURLKey = "url"
|
|
static let TabTitleKey = "title"
|
|
|
|
fileprivate let lastBookmarkTitle = NSLocalizedString("Open Last Bookmark", tableName: "3DTouchActions", comment: "String describing the action of opening the last added bookmark from the home screen Quick Actions via 3D Touch")
|
|
fileprivate let _lastTabTitle = NSLocalizedString("Open Last Tab", tableName: "3DTouchActions", comment: "String describing the action of opening the last tab sent to Firefox from the home screen Quick Actions via 3D Touch")
|
|
|
|
static var sharedInstance = QuickActions()
|
|
|
|
var launchedShortcutItem: UIApplicationShortcutItem?
|
|
|
|
// MARK: Administering Quick Actions
|
|
func addDynamicApplicationShortcutItemOfType(_ type: ShortcutType, fromShareItem shareItem: ShareItem, toApplication application: UIApplication) {
|
|
var userData = [QuickActions.TabURLKey: shareItem.url]
|
|
if let title = shareItem.title {
|
|
userData[QuickActions.TabTitleKey] = title
|
|
}
|
|
QuickActions.sharedInstance.addDynamicApplicationShortcutItemOfType(type, withUserData: userData, toApplication: application)
|
|
}
|
|
|
|
@discardableResult func addDynamicApplicationShortcutItemOfType(_ type: ShortcutType, withUserData userData: [AnyHashable: Any] = [AnyHashable: Any](), toApplication application: UIApplication) -> Bool {
|
|
// add the quick actions version so that it is always in the user info
|
|
var userData: [AnyHashable: Any] = userData
|
|
userData[QuickActions.QuickActionsVersionKey] = QuickActions.QuickActionsVersion
|
|
var dynamicShortcutItems = application.shortcutItems ?? [UIApplicationShortcutItem]()
|
|
switch type {
|
|
case .openLastBookmark:
|
|
let openLastBookmarkShortcut = UIMutableApplicationShortcutItem(type: ShortcutType.openLastBookmark.type,
|
|
localizedTitle: lastBookmarkTitle,
|
|
localizedSubtitle: userData[QuickActions.TabTitleKey] as? String,
|
|
icon: UIApplicationShortcutIcon(templateImageName: "quick_action_last_bookmark"),
|
|
userInfo: userData
|
|
)
|
|
if let index = (dynamicShortcutItems.index { $0.type == ShortcutType.openLastBookmark.type }) {
|
|
dynamicShortcutItems[index] = openLastBookmarkShortcut
|
|
} else {
|
|
dynamicShortcutItems.append(openLastBookmarkShortcut)
|
|
}
|
|
default:
|
|
log.warning("Cannot add static shortcut item of type \(type)")
|
|
return false
|
|
}
|
|
application.shortcutItems = dynamicShortcutItems
|
|
return true
|
|
}
|
|
|
|
func removeDynamicApplicationShortcutItemOfType(_ type: ShortcutType, fromApplication application: UIApplication) {
|
|
guard var dynamicShortcutItems = application.shortcutItems,
|
|
let index = (dynamicShortcutItems.index { $0.type == type.type }) else { return }
|
|
|
|
dynamicShortcutItems.remove(at: index)
|
|
application.shortcutItems = dynamicShortcutItems
|
|
}
|
|
|
|
// MARK: Handling Quick Actions
|
|
@discardableResult func handleShortCutItem(_ shortcutItem: UIApplicationShortcutItem, withBrowserViewController bvc: BrowserViewController ) -> Bool {
|
|
|
|
// Verify that the provided `shortcutItem`'s `type` is one handled by the application.
|
|
guard let shortCutType = ShortcutType(fullType: shortcutItem.type) else { return false }
|
|
|
|
DispatchQueue.main.async {
|
|
self.handleShortCutItemOfType(shortCutType, userData: shortcutItem.userInfo, browserViewController: bvc)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
fileprivate func handleShortCutItemOfType(_ type: ShortcutType, userData: [String: NSSecureCoding]?, browserViewController: BrowserViewController) {
|
|
switch type {
|
|
case .newTab:
|
|
handleOpenNewTab(withBrowserViewController: browserViewController, isPrivate: false)
|
|
case .newPrivateTab:
|
|
handleOpenNewTab(withBrowserViewController: browserViewController, isPrivate: true)
|
|
// even though we're removing OpenLastTab, it's possible that someone will use an existing last tab quick action to open the app
|
|
// the first time after upgrading, so we should still handle it
|
|
case .openLastBookmark:
|
|
if let urlToOpen = (userData?[QuickActions.TabURLKey] as? String)?.asURL {
|
|
handleOpenURL(withBrowserViewController: browserViewController, urlToOpen: urlToOpen)
|
|
}
|
|
case .qrCode:
|
|
handleQRCode(with: browserViewController)
|
|
}
|
|
}
|
|
|
|
fileprivate func handleOpenNewTab(withBrowserViewController bvc: BrowserViewController, isPrivate: Bool) {
|
|
bvc.openBlankNewTab(focusLocationField: true, isPrivate: isPrivate)
|
|
}
|
|
|
|
fileprivate func handleOpenURL(withBrowserViewController bvc: BrowserViewController, urlToOpen: URL) {
|
|
// open bookmark in a non-private browsing tab
|
|
bvc.switchToPrivacyMode(isPrivate: false)
|
|
|
|
// find out if bookmarked URL is currently open
|
|
// if so, open to that tab,
|
|
// otherwise, create a new tab with the bookmarked URL
|
|
bvc.switchToTabForURLOrOpen(urlToOpen, isPrivileged: true)
|
|
}
|
|
|
|
fileprivate func handleQRCode(with vc: QRCodeViewControllerDelegate & UIViewController) {
|
|
let qrCodeViewController = QRCodeViewController()
|
|
qrCodeViewController.qrCodeDelegate = vc
|
|
let controller = UINavigationController(rootViewController: qrCodeViewController)
|
|
vc.present(controller, animated: true, completion: nil)
|
|
}
|
|
}
|