ζ-1 abgeschlossen: DeepLinkRouter + Web-Header-Hide
- DeepLinkRouter als pure-Logic-Enum aus RootView extrahiert (resolveToWebURL, isExplorePath, route) - 11 DeepLinkRouterTests grün: custom-scheme, https passthrough, Erkunden-vs-Lesen-Routing, Substring-Guard - WebShellScripts.hideWebHeader: WKUserScript injiziert at document.start CSS, das den zitare-Web-Header (body header:has(a.brand)) ausblendet. Native TabBar übernimmt globale Navigation, Content bleibt sichtbar. - Simulator-Verifikation: Quote rendert ohne doppelte Nav-Leiste, 17 (UI + Unit) Tests grün Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
75b5e7113f
commit
dd10f85cca
6 changed files with 166 additions and 36 deletions
|
|
@ -71,46 +71,16 @@ struct RootView: View {
|
|||
/// `https://zitare.com/q/<slug>` umgemappt.
|
||||
private func handle(url: URL) {
|
||||
Log.app.info("Deep-Link empfangen: \(url.absoluteString, privacy: .public)")
|
||||
|
||||
let resolved = resolveToWebURL(url)
|
||||
let path = resolved.path
|
||||
let routed = DeepLinkRouter.route(url, base: AppConfig.webBaseURL)
|
||||
reloadCounter += 1
|
||||
|
||||
if isExplorePath(path) {
|
||||
exploreTarget = WebTarget(url: resolved, reloadToken: reloadCounter)
|
||||
if routed.isExplore {
|
||||
exploreTarget = WebTarget(url: routed.url, reloadToken: reloadCounter)
|
||||
selectedTab = .explore
|
||||
} else {
|
||||
readTarget = WebTarget(url: resolved, reloadToken: reloadCounter)
|
||||
readTarget = WebTarget(url: routed.url, reloadToken: reloadCounter)
|
||||
selectedTab = .read
|
||||
}
|
||||
}
|
||||
|
||||
/// `zitare://quote/spitteler-...` → `https://zitare.com/q/spitteler-...`.
|
||||
/// `zitare://author/x` → `https://zitare.com/a/x`.
|
||||
/// `zitare://collection/x` → `https://zitare.com/c/x`.
|
||||
/// `https://zitare.com/<anything>` bleibt wie es ist.
|
||||
private func resolveToWebURL(_ url: URL) -> URL {
|
||||
if url.scheme == "zitare" {
|
||||
let host = url.host ?? ""
|
||||
let path = url.path
|
||||
switch host {
|
||||
case "quote":
|
||||
return AppConfig.webBaseURL.appendingPathComponent("q\(path)")
|
||||
case "author":
|
||||
return AppConfig.webBaseURL.appendingPathComponent("a\(path)")
|
||||
case "collection":
|
||||
return AppConfig.webBaseURL.appendingPathComponent("c\(path)")
|
||||
default:
|
||||
return AppConfig.webBaseURL
|
||||
}
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
private func isExplorePath(_ path: String) -> Bool {
|
||||
let prefixes = ["/explore", "/region", "/thema", "/rolle", "/epoche", "/sprache", "/search", "/t/"]
|
||||
return prefixes.contains { path == $0 || path.hasPrefix($0 + "/") }
|
||||
}
|
||||
}
|
||||
|
||||
enum AppTab: Hashable {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue