Zum Inhalt

apple/PhysarumApp/Sources/UI/ErrorAlert.swift

import SwiftUI
#if canImport(UIKit)
import UIKit
#endif

extension View {
    /// Mounts the single app-wide error alert, driven by the shared presenter.
    func errorAlert(_ presenter: ErrorPresenter) -> some View {
        modifier(ErrorAlertModifier(presenter: presenter))
    }
}

private struct ErrorAlertModifier: ViewModifier {
    @Bindable var presenter: ErrorPresenter

    func body(content: Content) -> some View {
        content.alert(
            presenter.current?.title ?? "",
            isPresented: Binding(
                get: { presenter.current != nil },
                set: { if !$0 { presenter.dismiss() } }
            ),
            presenting: presenter.current
        ) { err in
            if err.recovery == .openSettings, let url = Self.settingsURL {
                Button("Open Settings") { Self.open(url) }
                Button("OK", role: .cancel) { presenter.dismiss() }
            } else {
                Button("OK", role: .cancel) { presenter.dismiss() }
            }
        } message: { err in
            Text(err.message)
        }
    }

    private static var settingsURL: URL? {
        #if os(iOS)
        return URL(string: UIApplication.openSettingsURLString)
        #elseif os(macOS)
        return URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone")
        #else
        return nil
        #endif
    }

    private static func open(_ url: URL) {
        #if os(iOS)
        UIApplication.shared.open(url)
        #elseif os(macOS)
        NSWorkspace.shared.open(url)
        #endif
    }
}