feat: v2
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user