Initial Commit

This commit is contained in:
2026-03-27 09:21:41 +01:00
commit e9b6412d71
40 changed files with 6801 additions and 0 deletions
@@ -0,0 +1,84 @@
//
// CachedAsyncImage.swift
// Mobile Music Assistant
//
// Created by Sven Hanold on 26.03.26.
//
import SwiftUI
/// AsyncImage with URLCache support for album covers
struct CachedAsyncImage<Content: View, Placeholder: View>: 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) }
)
}
}