State restoration
This commit is contained in:
parent
afa2a7b771
commit
ebdd06738a
|
@ -50,6 +50,13 @@ class BrowserNavigationController: UIViewController {
|
||||||
.slide
|
.slide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var userActivity: NSUserActivity? {
|
||||||
|
get {
|
||||||
|
currentBrowserVC?.userActivity
|
||||||
|
}
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
|
||||||
private var cancellables = [AnyCancellable]()
|
private var cancellables = [AnyCancellable]()
|
||||||
|
|
||||||
init(navigator: NavigationManager) {
|
init(navigator: NavigationManager) {
|
||||||
|
@ -75,6 +82,9 @@ class BrowserNavigationController: UIViewController {
|
||||||
currentBrowserVC.scrollViewDelegate = self
|
currentBrowserVC.scrollViewDelegate = self
|
||||||
embedChild(currentBrowserVC, in: browserContainer)
|
embedChild(currentBrowserVC, in: browserContainer)
|
||||||
|
|
||||||
|
backBrowserVCs = navigator.backStack.map(createBrowserVC(url:))
|
||||||
|
forwardBrowserVCs = navigator.forwardStack.map(createBrowserVC(url:))
|
||||||
|
|
||||||
navBarView = NavigationBarView(navigator: navigator)
|
navBarView = NavigationBarView(navigator: navigator)
|
||||||
navBarView.translatesAutoresizingMaskIntoConstraints = false
|
navBarView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
view.addSubview(navBarView)
|
view.addSubview(navBarView)
|
||||||
|
|
|
@ -45,6 +45,9 @@ class BrowserWebViewController: UIViewController {
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
|
||||||
|
userActivity = NSUserActivity(geminiURL: url)
|
||||||
|
userActivity!.isEligibleForPrediction = true
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
|
@ -358,8 +361,19 @@ extension BrowserWebViewController: WKUIDelegate {
|
||||||
return SFSafariViewController(url: url)
|
return SFSafariViewController(url: url)
|
||||||
}
|
}
|
||||||
} actionProvider: { (_) in
|
} actionProvider: { (_) in
|
||||||
|
guard #available(iOS 15.0, *),
|
||||||
|
url.scheme == "gemini" else {
|
||||||
return nil
|
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)
|
completionHandler(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>NSUserActivityTypes</key>
|
||||||
|
<array>
|
||||||
|
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
|
||||||
|
</array>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
|
|
|
@ -24,19 +24,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the 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).
|
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||||
|
|
||||||
let initialURL: URL
|
navigationManager = createNavigationManager(for: session, with: connectionOptions)
|
||||||
|
|
||||||
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.delegate = self
|
navigationManager.delegate = self
|
||||||
|
|
||||||
// Create the SwiftUI view that provides the window contents.
|
// Create the SwiftUI view that provides the window contents.
|
||||||
|
@ -94,6 +82,36 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
// to restore the scene back to its current state.
|
// 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!)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SceneDelegate: NavigationManagerDelegate {
|
extension SceneDelegate: NavigationManagerDelegate {
|
||||||
|
|
|
@ -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 */; };
|
D688F64A258C17F3003A0A73 /* SymbolCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F649258C17F3003A0A73 /* SymbolCache.swift */; };
|
||||||
D688F65A258C2256003A0A73 /* BrowserNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F659258C2256003A0A73 /* BrowserNavigationController.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 */; };
|
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 */; };
|
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A64D25217C6F00348C4B /* Preferences.swift */; };
|
||||||
D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; };
|
D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; };
|
||||||
D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = "<group>"; };
|
||||||
|
@ -612,6 +614,7 @@
|
||||||
D653F40C26799F2F004E32B1 /* HomepagePrefView.swift */,
|
D653F40C26799F2F004E32B1 /* HomepagePrefView.swift */,
|
||||||
D653F40A267996FF004E32B1 /* ActivityItemSource.swift */,
|
D653F40A267996FF004E32B1 /* ActivityItemSource.swift */,
|
||||||
D653F40E2679A0AB004E32B1 /* SetHomepageActivity.swift */,
|
D653F40E2679A0AB004E32B1 /* SetHomepageActivity.swift */,
|
||||||
|
D68C1DFF2703EA13002D642B /* UserActivities.swift */,
|
||||||
D688F618258AD231003A0A73 /* Resources */,
|
D688F618258AD231003A0A73 /* Resources */,
|
||||||
D6376A6E26DDAF57005AD89C /* Vendor */,
|
D6376A6E26DDAF57005AD89C /* Vendor */,
|
||||||
D6E152AA24BFFDF600FDF9D3 /* Assets.xcassets */,
|
D6E152AA24BFFDF600FDF9D3 /* Assets.xcassets */,
|
||||||
|
@ -1142,6 +1145,7 @@
|
||||||
D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */,
|
D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */,
|
||||||
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
|
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
|
||||||
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
|
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
|
||||||
|
D68C1E002703EA13002D642B /* UserActivities.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue