tonsite url handling

This commit is contained in:
Isaac 2024-07-16 08:10:10 +08:00
parent 8cc282e2c3
commit db1541b2c4
4 changed files with 88 additions and 27 deletions

View File

@ -419,6 +419,7 @@ plist_fragment(
<key>CFBundleURLSchemes</key>
<array>
<string>tg</string>
<string>tonsite</string>
</array>
</dict>
</array>

View File

@ -10,7 +10,7 @@ import AccountContext
import WebKit
import AppBundle
private final class IpfsSchemeHandler: NSObject, WKURLSchemeHandler {
/*private final class IpfsSchemeHandler: NSObject, WKURLSchemeHandler {
private final class PendingTask {
let sourceTask: any WKURLSchemeTask
var urlSessionTask: URLSessionTask?
@ -71,6 +71,81 @@ private final class IpfsSchemeHandler: NSObject, WKURLSchemeHandler {
self.pendingTasks.append(PendingTask(sourceTask: urlSchemeTask))
}
func webView(_ webView: WKWebView, stop urlSchemeTask: any WKURLSchemeTask) {
if let index = self.pendingTasks.firstIndex(where: { $0.sourceTask === urlSchemeTask }) {
let task = self.pendingTasks[index]
self.pendingTasks.remove(at: index)
task.cancel()
}
}
}*/
private final class TonSchemeHandler: NSObject, WKURLSchemeHandler {
private final class PendingTask {
let sourceTask: any WKURLSchemeTask
var urlSessionTask: URLSessionTask?
let isCompleted = Atomic<Bool>(value: false)
init(sourceTask: any WKURLSchemeTask) {
self.sourceTask = sourceTask
var mappedHost: String = ""
if let host = sourceTask.request.url?.host {
mappedHost = host
mappedHost = mappedHost.replacingOccurrences(of: "-", with: "-h")
mappedHost = mappedHost.replacingOccurrences(of: ".", with: "-d")
}
var mappedPath = ""
if let path = sourceTask.request.url?.path, !path.isEmpty {
mappedPath = path
if !path.hasPrefix("/") {
mappedPath = "/\(mappedPath)"
}
}
let mappedUrl = "https://\(mappedHost).magic.org\(mappedPath)"
let isCompleted = self.isCompleted
self.urlSessionTask = URLSession.shared.dataTask(with: URLRequest(url: URL(string: mappedUrl)!), completionHandler: { data, response, error in
if isCompleted.swap(true) {
return
}
if let error {
sourceTask.didFailWithError(error)
} else {
if let response {
sourceTask.didReceive(response)
}
if let data {
sourceTask.didReceive(data)
}
sourceTask.didFinish()
}
})
self.urlSessionTask?.resume()
}
func cancel() {
if let urlSessionTask = self.urlSessionTask {
self.urlSessionTask = nil
if !self.isCompleted.swap(true) {
switch urlSessionTask.state {
case .running, .suspended:
urlSessionTask.cancel()
default:
break
}
}
}
}
}
private var pendingTasks: [PendingTask] = []
func webView(_ webView: WKWebView, start urlSchemeTask: any WKURLSchemeTask) {
self.pendingTasks.append(PendingTask(sourceTask: urlSchemeTask))
}
func webView(_ webView: WKWebView, stop urlSchemeTask: any WKURLSchemeTask) {
if let index = self.pendingTasks.firstIndex(where: { $0.sourceTask === urlSchemeTask }) {
let task = self.pendingTasks[index]
@ -95,10 +170,7 @@ final class BrowserWebContent: UIView, BrowserContent, UIScrollViewDelegate {
init(context: AccountContext, url: String) {
let configuration = WKWebViewConfiguration()
if context.sharedContext.immediateExperimentalUISettings.browserExperiment {
configuration.setURLSchemeHandler(IpfsSchemeHandler(), forURLScheme: "ipns")
configuration.setURLSchemeHandler(IpfsSchemeHandler(), forURLScheme: "ipfs")
}
configuration.setURLSchemeHandler(TonSchemeHandler(), forURLScheme: "tonsite")
self.webView = WKWebView(frame: CGRect(), configuration: configuration)
self.webView.allowsLinkPreview = false

View File

@ -251,16 +251,10 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|> deliverOnMainQueue).startStandalone(next: handleResolvedUrl)
}
if context.sharedContext.immediateExperimentalUISettings.browserExperiment {
if let scheme = parsedUrl.scheme, (scheme == "tg" || scheme == context.sharedContext.applicationBindings.appSpecificScheme) {
if parsedUrl.host == "ipfs" {
if let value = URL(string: "ipfs:/" + parsedUrl.path) {
parsedUrl = value
}
} else if parsedUrl.host == "ton" {
if let value = URL(string: "ton:/" + parsedUrl.path) {
parsedUrl = value
}
if let scheme = parsedUrl.scheme, (scheme == "tg" || scheme == context.sharedContext.applicationBindings.appSpecificScheme) {
if parsedUrl.host == "tonsite" {
if let value = URL(string: "tonsite:/" + parsedUrl.path) {
parsedUrl = value
}
}
}
@ -1008,10 +1002,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
if parsedUrl.scheme == "http" || parsedUrl.scheme == "https" {
isInternetUrl = true
}
if context.sharedContext.immediateExperimentalUISettings.browserExperiment {
if parsedUrl.scheme == "ipfs" || parsedUrl.scheme == "ipns" || parsedUrl.scheme == "ton" {
isInternetUrl = true
}
if parsedUrl.scheme == "tonsite" {
isInternetUrl = true
}
if isInternetUrl {
@ -1045,7 +1037,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
let _ = (settings
|> deliverOnMainQueue).startStandalone(next: { settings in
if settings.defaultWebBrowser == nil {
if isCompact && context.sharedContext.immediateExperimentalUISettings.browserExperiment {
//TODO:release check !isCompact
if isCompact || "".isEmpty {
let controller = BrowserScreen(context: context, subject: .webPage(url: parsedUrl.absoluteString))
navigationController?.pushViewController(controller)
} else {

View File

@ -130,13 +130,8 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
if !pathComponents.isEmpty && !pathComponents[0].isEmpty {
let peerName: String = pathComponents[0]
if sharedContext.immediateExperimentalUISettings.browserExperiment {
if query.hasPrefix("ipfs/") {
return .externalUrl(url: "ipfs://" + String(query[query.index(query.startIndex, offsetBy: "ipfs/".count)...]))
}
if query.hasPrefix("ton/") {
return .externalUrl(url: "ton://" + String(query[query.index(query.startIndex, offsetBy: "ton/".count)...]))
}
if query.hasPrefix("tonsite/") {
return .externalUrl(url: "tonsite://" + String(query[query.index(query.startIndex, offsetBy: "tonsite/".count)...]))
}
if pathComponents[0].hasPrefix("+") || pathComponents[0].hasPrefix("%20") {