// // CachedAsyncImage.swift // Mobile Music Assistant // // Created by Sven Hanold on 26.03.26. // import SwiftUI /// AsyncImage with URLCache support for album covers struct CachedAsyncImage: View { let url: URL? let content: (Image) -> Content let placeholder: () -> Placeholder @State private var image: UIImage? @State private var isLoading = false init( url: URL?, @ViewBuilder content: @escaping (Image) -> Content, @ViewBuilder placeholder: @escaping () -> Placeholder ) { self.url = url self.content = content self.placeholder = placeholder } var body: some View { Group { if let image { content(Image(uiImage: image)) } else { placeholder() .task { await loadImage() } } } } private func loadImage() async { guard let url, !isLoading else { return } isLoading = true defer { isLoading = false } // Configure URLCache if needed configureURLCache() do { let (data, _) = try await URLSession.shared.data(from: url) if let uiImage = UIImage(data: data) { await MainActor.run { image = uiImage } } } catch { print("Failed to load image: \(error.localizedDescription)") } } private func configureURLCache() { let cache = URLCache.shared if cache.diskCapacity < 50_000_000 { URLCache.shared = URLCache( memoryCapacity: 10_000_000, // 10 MB diskCapacity: 50_000_000 // 50 MB ) } } } // MARK: - Convenience Initializers extension CachedAsyncImage where Content == Image, Placeholder == Color { init(url: URL?) { self.init( url: url, content: { $0.resizable() }, placeholder: { Color.gray.opacity(0.2) } ) } }