State restoration
This commit is contained in:
parent
afa2a7b771
commit
ebdd06738a
|
@ -50,6 +50,13 @@ class BrowserNavigationController: UIViewController {
|
|||
.slide
|
||||
}
|
||||
|
||||
override var userActivity: NSUserActivity? {
|
||||
get {
|
||||
currentBrowserVC?.userActivity
|
||||
}
|
||||
set {}
|
||||
}
|
||||
|
||||
private var cancellables = [AnyCancellable]()
|
||||
|
||||
init(navigator: NavigationManager) {
|
||||
|
@ -75,6 +82,9 @@ class BrowserNavigationController: UIViewController {
|
|||
currentBrowserVC.scrollViewDelegate = self
|
||||
embedChild(currentBrowserVC, in: browserContainer)
|
||||
|
||||
backBrowserVCs = navigator.backStack.map(createBrowserVC(url:))
|
||||
forwardBrowserVCs = navigator.forwardStack.map(createBrowserVC(url:))
|
||||
|
||||
navBarView = NavigationBarView(navigator: navigator)
|
||||
navBarView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(navBarView)
|
||||
|
|
|
@ -45,6 +45,9 @@ class BrowserWebViewController: UIViewController {
|
|||
self.url = url
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
|
||||
userActivity = NSUserActivity(geminiURL: url)
|
||||
userActivity!.isEligibleForPrediction = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
@ -358,7 +361,18 @@ extension BrowserWebViewController: WKUIDelegate {
|
|||
return SFSafariViewController(url: url)
|
||||
}
|
||||
} actionProvider: { (_) in
|
||||
return nil
|
||||
guard #available(iOS 15.0, *),
|
||||
url.scheme == "gemini" else {
|
||||
return nil
|
||||
}
|
||||
return UIMenu(children: [
|
||||
UIWindowScene.ActivationAction({ (_) in
|
||||
let options = UIWindowScene.ActivationRequestOptions()
|
||||
// automatic presents in the prominent style even when a fullscreen window is the only existing one
|
||||
options.preferredPresentationStyle = .standard
|
||||
return UIWindowScene.ActivationConfiguration(userActivity: NSUserActivity(geminiURL: url), options: options, preview: nil)
|
||||
})
|
||||
])
|
||||
}
|
||||
completionHandler(config)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
|
|
@ -23,20 +23,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
|
||||
let initialURL: URL
|
||||
|
||||
if let context = connectionOptions.urlContexts.first {
|
||||
initialURL = context.url
|
||||
} else {
|
||||
if ProcessInfo.processInfo.environment.keys.contains("DEFAULT_URL") {
|
||||
initialURL = URL(string: ProcessInfo.processInfo.environment["DEFAULT_URL"]!)!
|
||||
} else {
|
||||
initialURL = Preferences.shared.homepage
|
||||
}
|
||||
}
|
||||
|
||||
navigationManager = NavigationManager(url: initialURL)
|
||||
navigationManager = createNavigationManager(for: session, with: connectionOptions)
|
||||
navigationManager.delegate = self
|
||||
|
||||
// Create the SwiftUI view that provides the window contents.
|
||||
|
@ -93,6 +81,36 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
}
|
||||
|
||||
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
|
||||
return NSUserActivity(navigationManager: navigationManager)
|
||||
}
|
||||
|
||||
private func createNavigationManager(for session: UISceneSession, with connectionOptions: UIScene.ConnectionOptions) -> NavigationManager {
|
||||
var initialURL: URL? = nil
|
||||
|
||||
if let activity = session.stateRestorationActivity ?? connectionOptions.userActivities.first {
|
||||
if let manager = activity.navigationManager {
|
||||
return manager
|
||||
} else if let url = activity.geminiURL {
|
||||
initialURL = url
|
||||
}
|
||||
}
|
||||
|
||||
if initialURL == nil {
|
||||
initialURL = connectionOptions.urlContexts.first?.url
|
||||
}
|
||||
|
||||
if initialURL == nil {
|
||||
if ProcessInfo.processInfo.environment.keys.contains("DEFAULT_URL") {
|
||||
initialURL = URL(string: ProcessInfo.processInfo.environment["DEFAULT_URL"]!)!
|
||||
} else {
|
||||
initialURL = Preferences.shared.homepage
|
||||
}
|
||||
}
|
||||
|
||||
return NavigationManager(url: initialURL!)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// UserActivities.swift
|
||||
// Gemini-iOS
|
||||
//
|
||||
// Created by Shadowfacts on 9/28/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import BrowserCore
|
||||
|
||||
private let type = "space.vaccor.Gemini.activity.browse"
|
||||
|
||||
extension NSUserActivity {
|
||||
convenience init(geminiURL url: URL) {
|
||||
self.init(activityType: type)
|
||||
self.userInfo = [
|
||||
"url": url,
|
||||
]
|
||||
}
|
||||
|
||||
convenience init(navigationManager manager: NavigationManager) {
|
||||
self.init(activityType: type)
|
||||
self.userInfo = [
|
||||
"url": manager.currentURL,
|
||||
"back": manager.backStack,
|
||||
"forward": manager.forwardStack,
|
||||
]
|
||||
}
|
||||
|
||||
var navigationManager: NavigationManager? {
|
||||
guard activityType == type,
|
||||
let url = userInfo?["url"] as? URL else { return nil }
|
||||
let back = userInfo?["back"] as? [URL] ?? []
|
||||
let forward = userInfo?["forward"] as? [URL] ?? []
|
||||
let manager = NavigationManager(url: url)
|
||||
manager.backStack = back
|
||||
manager.forwardStack = forward
|
||||
return manager
|
||||
}
|
||||
|
||||
var geminiURL: URL? {
|
||||
guard activityType == type,
|
||||
let url = userInfo?["url"] as? URL else { return nil }
|
||||
return url
|
||||
}
|
||||
}
|
|
@ -51,6 +51,7 @@
|
|||
D688F64A258C17F3003A0A73 /* SymbolCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F649258C17F3003A0A73 /* SymbolCache.swift */; };
|
||||
D688F65A258C2256003A0A73 /* BrowserNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F659258C2256003A0A73 /* BrowserNavigationController.swift */; };
|
||||
D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F662258C2479003A0A73 /* UIViewController+Children.swift */; };
|
||||
D68C1E002703EA13002D642B /* UserActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1DFF2703EA13002D642B /* UserActivities.swift */; };
|
||||
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A64D25217C6F00348C4B /* Preferences.swift */; };
|
||||
D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; };
|
||||
D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */; };
|
||||
|
@ -321,6 +322,7 @@
|
|||
D688F649258C17F3003A0A73 /* SymbolCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolCache.swift; sourceTree = "<group>"; };
|
||||
D688F659258C2256003A0A73 /* BrowserNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserNavigationController.swift; sourceTree = "<group>"; };
|
||||
D688F662258C2479003A0A73 /* UIViewController+Children.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Children.swift"; sourceTree = "<group>"; };
|
||||
D68C1DFF2703EA13002D642B /* UserActivities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivities.swift; sourceTree = "<group>"; };
|
||||
D691A64D25217C6F00348C4B /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||
D691A66625217FD800348C4B /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
|
||||
D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = "<group>"; };
|
||||
|
@ -612,6 +614,7 @@
|
|||
D653F40C26799F2F004E32B1 /* HomepagePrefView.swift */,
|
||||
D653F40A267996FF004E32B1 /* ActivityItemSource.swift */,
|
||||
D653F40E2679A0AB004E32B1 /* SetHomepageActivity.swift */,
|
||||
D68C1DFF2703EA13002D642B /* UserActivities.swift */,
|
||||
D688F618258AD231003A0A73 /* Resources */,
|
||||
D6376A6E26DDAF57005AD89C /* Vendor */,
|
||||
D6E152AA24BFFDF600FDF9D3 /* Assets.xcassets */,
|
||||
|
@ -1142,6 +1145,7 @@
|
|||
D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */,
|
||||
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
|
||||
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
|
||||
D68C1E002703EA13002D642B /* UserActivities.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue