60 lines
1.9 KiB
Swift
60 lines
1.9 KiB
Swift
import SwiftUI
|
||
import AppKit
|
||
|
||
/// Иконка монеты из готовых данных (виджет получает их от провайдера).
|
||
/// Без данных — кружок с первой буквой в фирменном цвете монеты.
|
||
struct CoinIconView: View {
|
||
let currency: String
|
||
let data: Data?
|
||
let size: CGFloat
|
||
|
||
var body: some View {
|
||
Group {
|
||
if let data, let image = NSImage(data: data) {
|
||
Image(nsImage: image)
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fit)
|
||
.clipShape(Circle())
|
||
} else {
|
||
fallback
|
||
}
|
||
}
|
||
.frame(width: size, height: size)
|
||
.overlay(Circle().strokeBorder(.white.opacity(0.08), lineWidth: 1))
|
||
}
|
||
|
||
private var fallback: some View {
|
||
ZStack {
|
||
Circle()
|
||
.fill(
|
||
LinearGradient(
|
||
colors: [
|
||
CoinPalette.color(for: currency),
|
||
CoinPalette.color(for: currency).opacity(0.65),
|
||
],
|
||
startPoint: .top,
|
||
endPoint: .bottom
|
||
)
|
||
)
|
||
Text(String(currency.prefix(1)))
|
||
.font(.system(size: size * 0.44, weight: .bold, design: .rounded))
|
||
.foregroundStyle(.white)
|
||
}
|
||
}
|
||
}
|
||
|
||
/// Иконка с самостоятельной загрузкой через общий кэш — для окна настроек.
|
||
struct RemoteCoinIcon: View {
|
||
let currency: String
|
||
var size: CGFloat = 30
|
||
|
||
@State private var data: Data?
|
||
|
||
var body: some View {
|
||
CoinIconView(currency: currency, data: data, size: size)
|
||
.task(id: currency) {
|
||
data = await IconStore.shared.data(for: currency)
|
||
}
|
||
}
|
||
}
|