import SwiftUI #if canImport(UIKit) import UIKit #elseif canImport(AppKit) import AppKit #endif /// Lädt ein authentifiziertes Image vom Cardecky-Media-Endpoint und /// rendert es. Streamt erst beim ersten Mal, danach aus dem /// MediaCache (LRU 200 MB). struct RemoteImage: View { let mediaId: String let contentMode: ContentMode @Environment(\.mediaCache) private var mediaCache @State private var image: PlatformImage? @State private var failed = false init(mediaId: String, contentMode: ContentMode = .fit) { self.mediaId = mediaId self.contentMode = contentMode } var body: some View { Group { if let image { imageView(image) } else if failed { ContentUnavailableView("Bild konnte nicht geladen werden", systemImage: "photo.badge.exclamationmark") .foregroundStyle(CardsTheme.mutedForeground) } else { ProgressView() .tint(CardsTheme.primary) } } .task(id: mediaId) { await load() } } @ViewBuilder private func imageView(_ image: PlatformImage) -> some View { #if canImport(UIKit) Image(uiImage: image).resizable().aspectRatio(contentMode: contentMode) #elseif canImport(AppKit) Image(nsImage: image).resizable().aspectRatio(contentMode: contentMode) #endif } private func load() async { guard let cache = mediaCache else { failed = true; return } do { let data = try await cache.data(for: mediaId) if let img = PlatformImage(data: data) { image = img } else { failed = true } } catch { failed = true } } } #if canImport(UIKit) typealias PlatformImage = UIImage #elseif canImport(AppKit) typealias PlatformImage = NSImage #endif