diff --git a/crypto/Sparkline.swift b/crypto/Sparkline.swift
index e99281a..31201e5 100644
--- a/crypto/Sparkline.swift
+++ b/crypto/Sparkline.swift
@@ -46,6 +46,9 @@ struct Sparkline: View {
var areaOpacity: Double = 0.25
/// Отступ справа в диаметрах точки: линия обрывается, не доходя до края.
var trailingRoom: CGFloat = 1.4
+ /// В карточке-герое график уходит под края виджета и левая кромка заливки
+ /// не видна. Отдельно стоящий график гасит её, иначе получается срез.
+ var isFullBleed: Bool = true
/// Больше точек глазом уже не различить, а форма тяжелеет.
private static let maxPoints = 96
@@ -66,12 +69,7 @@ struct Sparkline: View {
startPoint: .top, endPoint: .bottom
)
)
- .mask(
- LinearGradient(
- colors: [.white, .white.opacity(0.25)],
- startPoint: .leading, endPoint: .trailing
- )
- )
+ .mask(areaMask)
// Гало точки лежит под линией, ядро — над ней.
if showPulse, let last = points.last {
@@ -104,6 +102,24 @@ struct Sparkline: View {
}
}
+ /// Горизонтальная маска заливки: свечение сосредоточено слева, как в макете.
+ private var areaMask: LinearGradient {
+ LinearGradient(
+ gradient: Gradient(stops: isFullBleed
+ ? [
+ .init(color: .white, location: 0),
+ .init(color: .white.opacity(0.25), location: 1),
+ ]
+ : [
+ .init(color: .white.opacity(0), location: 0),
+ .init(color: .white, location: 0.3),
+ .init(color: .white.opacity(0.3), location: 1),
+ ]),
+ startPoint: .leading,
+ endPoint: .trailing
+ )
+ }
+
// MARK: - Геометрия
private func points(in size: CGSize) -> [CGPoint] {
diff --git a/crypto/WidgetCards.swift b/crypto/WidgetCards.swift
index 0a1c21c..8f92529 100644
--- a/crypto/WidgetCards.swift
+++ b/crypto/WidgetCards.swift
@@ -47,7 +47,7 @@ struct HeroCard: View {
values: quote.series,
positive: thumb.isPositive,
lineWidth: 2,
- pulseSize: iconSize * 0.52
+ pulseSize: chartHeight * 0.26
)
} else {
// Нет истории — держим ритм макета ровной линией.
@@ -76,7 +76,14 @@ struct CryptoRow: View {
let compact: Bool
private var thumb: SymbolThumb { quote.thumb }
- private var iconSize: CGFloat { compact ? 24 : 26 }
+ private var iconSize: CGFloat { compact ? 21 : 23 }
+
+ /// График занимает почти весь зазор между названием и ценой: на узком
+ /// поле линия выглядит сплюснутой, поэтому тянем её вширь.
+ /// В большом виджете строк больше — там график ниже.
+ private var chartSize: CGSize {
+ compact ? CGSize(width: 92, height: 28) : CGSize(width: 88, height: 26)
+ }
var body: some View {
HStack(spacing: 8) {
@@ -91,6 +98,8 @@ struct CryptoRow: View {
}
.font(.system(size: compact ? 12 : 13, weight: .bold))
.lineLimit(1)
+ // Длинные тикеры вроде MATIC/USDT сжимаются, а не обрезаются.
+ .minimumScaleFactor(0.8)
Text(thumb.quoteCurrencyName)
.font(.system(size: compact ? 9 : 10, weight: .medium))
@@ -107,9 +116,10 @@ struct CryptoRow: View {
lineWidth: 1.5,
pulseSize: 7,
areaOpacity: 0.16,
- trailingRoom: 0.6
+ trailingRoom: 0.6,
+ isFullBleed: false
)
- .frame(width: compact ? 46 : 56, height: 22)
+ .frame(width: chartSize.width, height: chartSize.height)
}
VStack(alignment: .trailing, spacing: 2) {
diff --git a/crypto/WidgetComponents.swift b/crypto/WidgetComponents.swift
index 8f9d16b..c65cfa1 100644
--- a/crypto/WidgetComponents.swift
+++ b/crypto/WidgetComponents.swift
@@ -9,8 +9,12 @@ struct PairHeader: View {
let iconSize: CGFloat
let titleSize: CGFloat
+ /// Знак и отступы привязаны к кеглю заголовка, а не к иконке: размер
+ /// иконки подбирается отдельно и не должен тянуть за собой логотип.
+ private var markSize: CGFloat { titleSize * 1.05 }
+
var body: some View {
- HStack(spacing: iconSize * 0.3) {
+ HStack(spacing: titleSize * 0.55) {
CoinIconView(currency: thumb.quoteCurrency, data: icon, size: iconSize)
HStack(spacing: 1) {
@@ -30,7 +34,7 @@ struct PairHeader: View {
Spacer(minLength: 4)
- RapiraMark(size: iconSize * 0.52)
+ RapiraMark(size: markSize)
}
}
}
diff --git a/crypto/WidgetViews.swift b/crypto/WidgetViews.swift
index 4fa9563..af02ae0 100644
--- a/crypto/WidgetViews.swift
+++ b/crypto/WidgetViews.swift
@@ -16,10 +16,10 @@ struct SmallWidgetView: View {
quote: hero,
updatedAt: entry.date,
horizontalPadding: padding,
- iconSize: 24,
+ iconSize: 20,
titleSize: 13,
priceSize: 21,
- chartHeight: 38,
+ chartHeight: 40,
showFullDate: false,
showAbsolute: false
)
@@ -98,10 +98,10 @@ struct LargeWidgetView: View {
quote: hero,
updatedAt: entry.date,
horizontalPadding: padding,
- iconSize: 36,
+ iconSize: 28,
titleSize: 19,
priceSize: 32,
- chartHeight: 72
+ chartHeight: 70
)
if !rest.isEmpty {
diff --git a/rapira-market-widget.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/rapira-market-widget.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..0c67376
--- /dev/null
+++ b/rapira-market-widget.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/rapira-market-widget.xcodeproj/project.xcworkspace/xcuserdata/robonen.xcuserdatad/WorkspaceSettings.xcsettings b/rapira-market-widget.xcodeproj/project.xcworkspace/xcuserdata/robonen.xcuserdatad/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..723a561
--- /dev/null
+++ b/rapira-market-widget.xcodeproj/project.xcworkspace/xcuserdata/robonen.xcuserdatad/WorkspaceSettings.xcsettings
@@ -0,0 +1,16 @@
+
+
+
+
+ BuildLocationStyle
+ UseAppPreferences
+ CompilationCachingSetting
+ Default
+ CustomBuildLocationType
+ RelativeToDerivedData
+ DerivedDataLocationStyle
+ Default
+ ShowSharedSchemesAutomaticallyEnabled
+
+
+
diff --git a/rapira-market-widget.xcodeproj/xcuserdata/robonen.xcuserdatad/xcschemes/xcschememanagement.plist b/rapira-market-widget.xcodeproj/xcuserdata/robonen.xcuserdatad/xcschemes/xcschememanagement.plist
index 5f36630..49b9324 100644
--- a/rapira-market-widget.xcodeproj/xcuserdata/robonen.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/rapira-market-widget.xcodeproj/xcuserdata/robonen.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,7 +7,7 @@
cryptoExtension.xcscheme_^#shared#^_
orderHint
- 1
+ 0
rapira-market-widget.xcscheme_^#shared#^_