iBook/ipad_app/Sources/Services/ImageCache.swift

66 lines
1.9 KiB
Swift

#if canImport(UIKit)
import UIKit
#endif
import SwiftUI
#if canImport(UIKit)
typealias PlatformImage = UIImage
#elseif canImport(AppKit)
import AppKit
typealias PlatformImage = NSImage
#endif
#if canImport(UIKit) || canImport(AppKit)
actor ImageCache {
static let shared = ImageCache()
private var cache: [String:PlatformImage] = [:]
func image(for id: String, in baseDir: URL) -> PlatformImage? {
if let c = cache[id] { return c }
let url = baseDir.appendingPathComponent("covers/\(id).jpg")
#if canImport(UIKit)
guard let img = PlatformImage(contentsOfFile: url.path) else { return nil }
#elseif canImport(AppKit)
guard let img = PlatformImage(contentsOf: url) else { return nil }
#endif
cache[id] = img
return img
}
}
#endif
#if os(iOS)
struct CoverImageView: View {
let book: BookMeta
let bundleDir: URL
#if canImport(UIKit) || canImport(AppKit)
@State private var uiImage: PlatformImage? = nil
#endif
var body: some View {
ZStack {
#if canImport(UIKit) || canImport(AppKit)
if let img = uiImage {
#if canImport(UIKit)
Image(uiImage: img).resizable().scaledToFit().cornerRadius(6)
#elseif canImport(AppKit)
Image(nsImage: img).resizable().scaledToFit().cornerRadius(6)
#endif
} else {
Rectangle().fill(Color.gray.opacity(0.2)).overlay(Text("No Cover").font(.caption))
}
#else
Rectangle().fill(Color.gray.opacity(0.2)).overlay(Text("No Cover").font(.caption))
#endif
}
#if canImport(UIKit) || canImport(AppKit)
.task {
if uiImage == nil, let img = await ImageCache.shared.image(for: book.id, in: bundleDir) {
uiImage = img
}
}
#endif
}
}
#endif