SPB Git forge
2commits 1branches 0releases
180.0 KBsize
maindefault branch
1 mo agolast push
Swift 100%
4.8 KB · 99 lines swift
Raw Blame History
1import SwiftUI2import WebKit3import AppKit45final class WebModel: ObservableObject {6    @Published var progress: Double = 07    @Published var loaded = false8    @Published var failed = false9    var webView: WKWebView?10    func reload() {11        failed = false; loaded = false; progress = 012        if let wv = webView { if wv.url == nil { wv.load(URLRequest(url: Ka.url)) } else { wv.reload() } }13    }14}1516struct WebView: NSViewRepresentable {17    @ObservedObject var model: WebModel1819    func makeCoordinator() -> Coordinator { Coordinator(model: model) }2021    func makeNSView(context: Context) -> WKWebView {22        let cfg = WKWebViewConfiguration()23        cfg.websiteDataStore = .default()          // cookie de session persistant24        cfg.defaultWebpagePreferences.allowsContentJavaScript = true25        let wv = WKWebView(frame: .zero, configuration: cfg)26        wv.navigationDelegate = context.coordinator27        wv.uiDelegate = context.coordinator28        wv.setValue(false, forKey: "drawsBackground")   // fond transparent → crème29        wv.customUserAgent = "AdminKa-macOS/1.0 (Groupe KA console)"30        context.coordinator.observe(wv)31        model.webView = wv32        wv.load(URLRequest(url: Ka.url))33        return wv34    }3536    func updateNSView(_ nsView: WKWebView, context: Context) {}3738    final class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {39        let model: WebModel40        private var obs: NSKeyValueObservation?41        init(model: WebModel) { self.model = model }4243        func observe(_ wv: WKWebView) {44            obs = wv.observe(\.estimatedProgress, options: [.new]) { [weak self] wv, _ in45                DispatchQueue.main.async { self?.model.progress = wv.estimatedProgress }46            }47        }48        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {49            DispatchQueue.main.async {50                withAnimation(.easeOut(duration: 0.35)) { self.model.loaded = true }51                self.model.failed = false52            }53        }54        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { fail(error) }55        func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { fail(error) }56        private func fail(_ error: Error) {57            if (error as NSError).code == NSURLErrorCancelled { return }58            DispatchQueue.main.async { self.model.failed = true }59        }6061        // liens externes → navigateur par défaut62        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,63                     decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {64            if let url = navigationAction.request.url, let host = url.host,65               navigationAction.navigationType == .linkActivated, host != Ka.url.host {66                NSWorkspace.shared.open(url); decisionHandler(.cancel); return67            }68            decisionHandler(.allow)69        }70        func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,71                     for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {72            if let url = navigationAction.request.url { NSWorkspace.shared.open(url) }73            return nil74        }7576        // --- Panneaux JS natifs (confirm() indispensable pour le mode BYPASS) ---77        func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String,78                     initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {79            let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = message; a.addButton(withTitle: "OK")80            a.runModal(); completionHandler()81        }82        func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String,83                     initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {84            let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = message85            a.addButton(withTitle: "OK"); a.addButton(withTitle: "Annuler")86            completionHandler(a.runModal() == .alertFirstButtonReturn)87        }88        func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String,89                     defaultText: String?, initiatedByFrame frame: WKFrameInfo,90                     completionHandler: @escaping (String?) -> Void) {91            let a = NSAlert(); a.messageText = "Admin-Ka"; a.informativeText = prompt92            a.addButton(withTitle: "OK"); a.addButton(withTitle: "Annuler")93            let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 260, height: 24)); tf.stringValue = defaultText ?? ""94            a.accessoryView = tf95            completionHandler(a.runModal() == .alertFirstButtonReturn ? tf.stringValue : nil)96        }97    }98}99