import Foundation import SwiftUI import WebKit /// Konfiguration für ``WebShellView``. /// /// Beispiel: /// /// ```swift /// WebShellView( /// target: WebTarget(url: URL(string: "https://seepuls.mana.how")!), /// config: WebShellConfig( /// allowedHosts: ["seepuls.mana.how", "*.mana.how", "mana.how"], /// userAgent: "SeepulsNative/0.1 (iOS)" /// ) /// ) /// ``` /// /// Apps mit eigenem Theme injizieren `background` / `progressTint` / /// `warning` etc. — default werden System-Farben benutzt. public struct WebShellConfig: Sendable { /// Liste erlaubter Hosts. Unterstützt: /// - exakte Hosts: `"seepuls.mana.how"` /// - Wildcard-Subdomains: `"*.mana.how"` /// /// Pfade auf nicht-gelisteten Hosts werden via `OpenURLAction` an /// den System-Browser delegiert. Ein leeres Array bedeutet /// **alles extern** — selten gewünscht, aber explizit erlaubt. public let allowedHosts: [String] /// `applicationNameForUserAgent`. WKWebView hängt das an seinen /// Standard-UA an, ersetzt ihn nicht. Konvention im mana-Ökosystem: /// `"Native/ ()"`. public let userAgent: String /// Hintergrund hinter dem WKWebView (verhindert Flash vor first /// paint). Default: `.clear`. Caller setzt typischerweise auf /// App-Theme-Background. public let backgroundColor: Color /// Tint der Fortschritts-Linie oben (Linear-ProgressView). Default: /// `.accentColor`. public let progressTint: Color /// Hintergrund der Fehler-Snackbar. Default: `.gray.opacity(0.15)`. public let errorBackgroundColor: Color /// Vordergrund der Fehler-Snackbar (Icon + Text). Default: `.primary`. public let errorForegroundColor: Color /// Icon-Farbe (Warn-Dreieck) in der Fehler-Snackbar. Default: `.orange`. public let errorIconColor: Color /// User-Scripts, die in `WKUserContentController` injiziert werden /// (Reihenfolge bleibt erhalten). Häufig genutzt: Theme-Sync, /// Web-Nav-Verstecken. Siehe ``WebShellScripts`` für Default-Helfer. public let userScripts: [WKUserScript] public init( allowedHosts: [String], userAgent: String, backgroundColor: Color = .clear, progressTint: Color = .accentColor, errorBackgroundColor: Color = Color.gray.opacity(0.15), errorForegroundColor: Color = .primary, errorIconColor: Color = .orange, userScripts: [WKUserScript] = [] ) { self.allowedHosts = allowedHosts self.userAgent = userAgent self.backgroundColor = backgroundColor self.progressTint = progressTint self.errorBackgroundColor = errorBackgroundColor self.errorForegroundColor = errorForegroundColor self.errorIconColor = errorIconColor self.userScripts = userScripts } /// Prüft, ob ein Host in dieser Konfiguration erlaubt ist. /// Unterstützt `*.`-Wildcards (subdomain-suffix + Root selbst). public func isAllowed(host: String) -> Bool { for pattern in allowedHosts { if pattern.hasPrefix("*.") { let suffix = String(pattern.dropFirst(1)) // ".mana.how" if host.hasSuffix(suffix) { return true } let root = String(suffix.dropFirst(1)) // "mana.how" if host == root { return true } } else if host == pattern { return true } } return false } }