Files
iOS/Sources/App/macOS/MacRootView.swift
Bruno Pantaleão 0008727ff3 WIP
2026-06-15 09:36:28 +02:00

93 lines
3.4 KiB
Swift

// Native macOS root view (target: App-macOS).
//
// Lets you point the native app at a Home Assistant instance and renders its
// frontend in a native WKWebView. Login happens through the HA web UI and
// persists in the web view's default data store. Once `Shared` is available on
// macOS, the manual URL field is replaced by real server management/onboarding.
#if os(macOS)
import SwiftUI
struct MacRootView: View {
@AppStorage("mac.lastServerURL") private var savedURLString: String = ""
@State private var draftURLString: String = ""
@State private var loadedURL: URL?
var body: some View {
Group {
if let loadedURL {
MacWebViewHost(url: loadedURL)
.id(loadedURL)
} else {
connectForm
}
}
.frame(minWidth: 720, minHeight: 520)
.toolbar {
if loadedURL != nil {
ToolbarItem(placement: .navigation) {
Button {
loadedURL = nil
} label: {
Label("Change server", systemImage: "arrow.left")
}
}
ToolbarItem {
Button {
NotificationCenter.default.post(name: .macWebReload, object: nil)
} label: {
Label("Reload", systemImage: "arrow.clockwise")
}
.keyboardShortcut("r", modifiers: .command)
}
}
}
.onAppear {
// Optional override (kiosk-less MDM / testing): HA_MAC_DEFAULT_URL.
let envURL = ProcessInfo.processInfo.environment["HA_MAC_DEFAULT_URL"] ?? ""
let initial = envURL.isEmpty ? savedURLString : envURL
draftURLString = initial
loadedURL = Self.normalized(initial)
MacTrace.write("onAppear initial='\(initial)' normalized=\(loadedURL?.absoluteString ?? "nil")")
}
}
private var connectForm: some View {
VStack(spacing: 16) {
Image(systemName: "house")
.font(.system(size: 48))
.foregroundStyle(.secondary)
Text(verbatim: "Home Assistant")
.font(.title.bold())
Text(verbatim: "Enter your Home Assistant URL")
.foregroundStyle(.secondary)
HStack {
TextField("https://homeassistant.local:8123", text: $draftURLString)
.textFieldStyle(.roundedBorder)
.frame(width: 320)
.onSubmit(connect)
Button("Connect", action: connect)
.keyboardShortcut(.defaultAction)
.disabled(Self.normalized(draftURLString) == nil)
}
}
.padding(40)
}
private func connect() {
guard let url = Self.normalized(draftURLString) else { return }
savedURLString = url.absoluteString
loadedURL = url
}
/// Accepts bare hosts ("homeassistant.local:8123") and full URLs, defaulting to https.
static func normalized(_ raw: String) -> URL? {
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return nil }
let withScheme = trimmed.contains("://") ? trimmed : "https://\(trimmed)"
guard let url = URL(string: withScheme), url.host != nil else { return nil }
return url
}
}
#endif