72 lines
1.9 KiB
Swift
72 lines
1.9 KiB
Swift
//
|
|
// ImageView.swift
|
|
// furumi_macos
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct ImageView: View {
|
|
let urlString: String?
|
|
let width: CGFloat
|
|
let height: CGFloat
|
|
let systemPlaceholder: String
|
|
|
|
@Environment(AuthManager.self) private var authManager
|
|
@State private var loadedImage: Image?
|
|
|
|
var body: some View {
|
|
Group {
|
|
if let loadedImage {
|
|
loadedImage
|
|
.resizable()
|
|
.scaledToFill()
|
|
.sized(width: width, height: height)
|
|
.clipped()
|
|
.clipShape(RoundedRectangle(cornerRadius: 10))
|
|
} else {
|
|
placeholder
|
|
.sized(width: width, height: height)
|
|
}
|
|
}
|
|
.task(id: urlString) {
|
|
await loadImage()
|
|
}
|
|
}
|
|
|
|
private func loadImage() async {
|
|
loadedImage = nil
|
|
guard let urlString, let url = URL(string: urlString) else { return }
|
|
|
|
var req = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad)
|
|
if let auth = authManager.session?.tokens.authorizationHeader {
|
|
req.setValue(auth, forHTTPHeaderField: "Authorization")
|
|
}
|
|
|
|
guard let (data, _) = try? await URLSession.shared.data(for: req),
|
|
let nsImage = NSImage(data: data) else { return }
|
|
|
|
loadedImage = Image(nsImage: nsImage)
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var placeholder: some View {
|
|
ZStack {
|
|
RoundedRectangle(cornerRadius: 10)
|
|
.fill(Color.secondary.opacity(0.12))
|
|
Image(systemName: systemPlaceholder)
|
|
.foregroundColor(.accentColor)
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension View {
|
|
@ViewBuilder
|
|
func sized(width: CGFloat, height: CGFloat) -> some View {
|
|
if width.isFinite {
|
|
self.frame(width: width, height: height)
|
|
} else {
|
|
self.frame(maxWidth: .infinity, minHeight: height, maxHeight: height)
|
|
}
|
|
}
|
|
}
|