feat(KAN-55): support app links, file selection and clipboard

This commit is contained in:
2026-09-18 14:15:26 +02:00
48 changed files with 1867 additions and 12 deletions
@@ -39,6 +39,7 @@ final class WorkspaceViewController: UIViewController, WKNavigationDelegate, WKU
private let connectButton = UIButton(type: .system)
private let resumeButton = UIButton(type: .system)
private let toolbar = UIToolbar()
private var historyObservation: NSKeyValueObservation?
private var backButton: UIBarButtonItem!
private var appearance: UISegmentedControl!
@@ -192,6 +193,7 @@ final class WorkspaceViewController: UIViewController, WKNavigationDelegate, WKU
guard let data = try? JSONEncoder().encode(selected) else { status.text = text("storageError"); return }
defaults.set(data, forKey: serverKey)
timeout?.cancel()
historyObservation = nil
workspace?.stopLoading()
workspace?.navigationDelegate = nil
workspace?.removeFromSuperview()
@@ -215,6 +217,9 @@ final class WorkspaceViewController: UIViewController, WKNavigationDelegate, WKU
webview.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
])
workspace = webview
historyObservation = webview.observe(\.canGoBack, options: [.initial, .new]) { [weak self] view, _ in
self?.backButton.isEnabled = view.canGoBack
}
view.endEditing(true)
address.text = url.absoluteString
beginNavigation()
@@ -261,8 +266,17 @@ final class WorkspaceViewController: UIViewController, WKNavigationDelegate, WKU
@objc private func goBack() { if workspace?.canGoBack == true { workspace?.goBack() } }
func webView(_ webView: WKWebView, decidePolicyFor action: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard webView === workspace, let url = action.request.url,
server?.allows(url) == true else { decisionHandler(.cancel); return }
guard webView === workspace, let url = action.request.url else { decisionHandler(.cancel); return }
guard server?.allows(url) == true else {
decisionHandler(.cancel)
if action.navigationType == .linkActivated,
action.sourceFrame.isMainFrame,
action.targetFrame == nil || action.targetFrame?.isMainFrame == true,
WorkspaceServer.allowsExternal(url) {
UIApplication.shared.open(url)
}
return
}
if action.targetFrame == nil {
decisionHandler(.cancel)
webView.load(action.request)