@onekeyfe/react-native-native-list 3.0.113 → 3.0.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -57
- package/android/src/main/java/com/onekey/nativelist/NativeListAdapter.kt +1 -17
- package/android/src/main/java/com/onekey/nativelist/NativeListRowView.kt +34 -545
- package/android/src/main/java/com/onekey/nativelist/NativeListView.kt +2 -26
- package/ios/NativeListCell.swift +20 -504
- package/ios/NativeListDesignAssets.swift +0 -8
- package/ios/RNCNativeListView.swift +7 -85
- package/lib/module/validation.js +1 -129
- package/lib/module/web/NativeListWebEngine.js +5 -357
- package/lib/typescript/src/models.d.ts +2 -82
- package/lib/typescript/src/web/NativeListWebEngine.d.ts +1 -26
- package/package.json +2 -2
- package/src/models.ts +3 -121
- package/src/validation.ts +0 -206
- package/src/web/NativeListWebEngine.ts +4 -578
- package/ios/Resources/NativeListIcons.xcassets/onekey_badge_verified_solid.imageset/Contents.json +0 -1
- package/ios/Resources/NativeListIcons.xcassets/onekey_badge_verified_solid.imageset/icon.svg +0 -1
package/ios/NativeListCell.swift
CHANGED
|
@@ -4,73 +4,6 @@ import CoreText
|
|
|
4
4
|
import OneKeyImage
|
|
5
5
|
import UIKit
|
|
6
6
|
|
|
7
|
-
// Market/TokenListSkeleton: source geometry and the native Skeleton's 3s shimmer.
|
|
8
|
-
private final class NativeListMarketSkeleton: UIView {
|
|
9
|
-
private let marks = (0..<5).map { _ in UIView() }
|
|
10
|
-
private let gradients = (0..<5).map { _ in CAGradientLayer() }
|
|
11
|
-
|
|
12
|
-
init(background: UIColor) {
|
|
13
|
-
super.init(frame: .zero)
|
|
14
|
-
var white: CGFloat = 1
|
|
15
|
-
background.getWhite(&white, alpha: nil)
|
|
16
|
-
let base = UIColor(nativeListHex: white < 0.5 ? "#111111" : "#FAFAFA", fallback: .white)
|
|
17
|
-
let highlight = UIColor(nativeListHex: white < 0.5 ? "#333333" : "#CDCDCD", fallback: .lightGray)
|
|
18
|
-
for (index, mark) in marks.enumerated() {
|
|
19
|
-
mark.backgroundColor = base
|
|
20
|
-
mark.clipsToBounds = true
|
|
21
|
-
mark.layer.cornerRadius = index == 0 ? 16 : 8
|
|
22
|
-
let gradient = gradients[index]
|
|
23
|
-
gradient.cornerRadius = mark.layer.cornerRadius
|
|
24
|
-
gradient.colors = [base.cgColor, highlight.cgColor, base.cgColor]
|
|
25
|
-
gradient.locations = [0, 0.5, 1]
|
|
26
|
-
gradient.startPoint = CGPoint(x: 0, y: 0.5)
|
|
27
|
-
gradient.endPoint = CGPoint(x: 1, y: 0.5)
|
|
28
|
-
mark.layer.addSublayer(gradient)
|
|
29
|
-
addSubview(mark)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
|
34
|
-
|
|
35
|
-
override func layoutSubviews() {
|
|
36
|
-
super.layoutSubviews()
|
|
37
|
-
let frames = [
|
|
38
|
-
CGRect(x: 0, y: 0, width: 32, height: 32),
|
|
39
|
-
CGRect(x: 44, y: 0, width: 80, height: 16),
|
|
40
|
-
CGRect(x: 44, y: 20, width: 60, height: 12),
|
|
41
|
-
CGRect(x: bounds.width - 168, y: 7, width: 80, height: 18),
|
|
42
|
-
CGRect(x: bounds.width - 80, y: 7, width: 80, height: 18),
|
|
43
|
-
]
|
|
44
|
-
CATransaction.begin()
|
|
45
|
-
CATransaction.setDisableActions(true)
|
|
46
|
-
for (index, frame) in frames.enumerated() {
|
|
47
|
-
marks[index].frame = frame
|
|
48
|
-
gradients[index].frame = marks[index].bounds
|
|
49
|
-
}
|
|
50
|
-
CATransaction.commit()
|
|
51
|
-
updateAnimation()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
override func didMoveToWindow() {
|
|
55
|
-
super.didMoveToWindow()
|
|
56
|
-
updateAnimation()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private func updateAnimation() {
|
|
60
|
-
for gradient in gradients {
|
|
61
|
-
guard window != nil else { gradient.removeAllAnimations(); continue }
|
|
62
|
-
guard gradient.bounds.width > 0, gradient.animation(forKey: "shimmer") == nil else { continue }
|
|
63
|
-
let animation = CABasicAnimation(keyPath: "transform.translation.x")
|
|
64
|
-
animation.fromValue = -gradient.bounds.width
|
|
65
|
-
animation.toValue = gradient.bounds.width
|
|
66
|
-
animation.duration = 3
|
|
67
|
-
animation.repeatCount = .infinity
|
|
68
|
-
animation.timingFunction = CAMediaTimingFunction(name: .linear)
|
|
69
|
-
gradient.add(animation, forKey: "shimmer")
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
7
|
final class NativeListActionOrigin {
|
|
75
8
|
weak var sourceView: UIView?
|
|
76
9
|
weak var ownerCell: NativeListCell?
|
|
@@ -103,17 +36,13 @@ private final class NativeListAccessoryButton: UIButton {
|
|
|
103
36
|
didSet { invalidateIntrinsicContentSize(); setNeedsLayout() }
|
|
104
37
|
}
|
|
105
38
|
|
|
106
|
-
var marketLineHeight: CGFloat? {
|
|
107
|
-
didSet { invalidateIntrinsicContentSize(); setNeedsLayout() }
|
|
108
|
-
}
|
|
109
|
-
|
|
110
39
|
private var sourcePixelScale: CGFloat {
|
|
111
40
|
max(1, window?.screen.scale ?? traitCollection.displayScale)
|
|
112
41
|
}
|
|
113
42
|
|
|
114
43
|
override var intrinsicContentSize: CGSize {
|
|
115
44
|
var size = super.intrinsicContentSize
|
|
116
|
-
guard selectorSummaryLineHeight != nil
|
|
45
|
+
guard selectorSummaryLineHeight != nil, let title = attributedTitle(for: .normal) else { return size }
|
|
117
46
|
let width = title.boundingRect(
|
|
118
47
|
with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude),
|
|
119
48
|
options: [.usesLineFragmentOrigin, .usesFontLeading],
|
|
@@ -125,21 +54,6 @@ private final class NativeListAccessoryButton: UIButton {
|
|
|
125
54
|
|
|
126
55
|
override func layoutSubviews() {
|
|
127
56
|
super.layoutSubviews()
|
|
128
|
-
if let lineHeight = marketLineHeight, let titleLabel, let title = attributedTitle(for: .normal) {
|
|
129
|
-
let measured = title.boundingRect(
|
|
130
|
-
with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude),
|
|
131
|
-
options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil
|
|
132
|
-
).width
|
|
133
|
-
let width = min(bounds.width, ceil(measured * sourcePixelScale) / sourcePixelScale)
|
|
134
|
-
let x = contentHorizontalAlignment == .trailing ? bounds.width - width
|
|
135
|
-
: contentHorizontalAlignment == .leading ? 0 : (bounds.width - width) / 2
|
|
136
|
-
titleLabel.frame = CGRect(
|
|
137
|
-
x: floor(x * sourcePixelScale) / sourcePixelScale,
|
|
138
|
-
y: (bounds.height - lineHeight) / 2,
|
|
139
|
-
width: width, height: lineHeight
|
|
140
|
-
)
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
57
|
guard let lineHeight = selectorSummaryLineHeight, let titleLabel else { return }
|
|
144
58
|
// OneKey patch: position the final source line box after UIKit has measured the button.
|
|
145
59
|
let top = ceil((bounds.height - lineHeight) / 2 * sourcePixelScale) / sourcePixelScale
|
|
@@ -448,8 +362,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
448
362
|
private let metricSubtitleLabel = UILabel()
|
|
449
363
|
private let metricCompositeStack = UIStackView()
|
|
450
364
|
private let badgeLabel = NativeListInsetLabel()
|
|
451
|
-
private let marketBadgeButtons = (0..<3).map { _ in UIButton(type: .system) }
|
|
452
|
-
private let marketBadgeImages = (0..<3).map { _ in OneKeyImageReusableView(frame: .zero) }
|
|
453
365
|
private let actionStack = UIStackView()
|
|
454
366
|
private let actionButtons = (0..<3).map { _ in UIButton(type: .system) }
|
|
455
367
|
private let trailingStack = UIStackView()
|
|
@@ -500,7 +412,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
500
412
|
private var boundCheckboxData: [String: Any]?
|
|
501
413
|
private var boundCheckboxTarget: NativeSelectionTarget?
|
|
502
414
|
private var leadingActionKey: String?
|
|
503
|
-
private var marketBadgeActionKeys: [String?] = []
|
|
504
415
|
private var restingBackgroundColor: UIColor = .clear
|
|
505
416
|
private var pressedBackgroundColor = UIColor(
|
|
506
417
|
nativeListHex: "#E8E8E8",
|
|
@@ -701,23 +612,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
701
612
|
titleRowStack.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
|
702
613
|
titleRowStack.addArrangedSubview(titleLabel)
|
|
703
614
|
titleRowStack.addArrangedSubview(badgeLabel)
|
|
704
|
-
marketBadgeButtons.enumerated().forEach { index, button in
|
|
705
|
-
button.tag = index
|
|
706
|
-
button.addTarget(self, action: #selector(marketBadgePressed(_:)), for: .touchUpInside)
|
|
707
|
-
button.titleLabel?.font = nativeListFont(ofSize: 11, weight: .medium)
|
|
708
|
-
button.layer.cornerRadius = 4
|
|
709
|
-
button.clipsToBounds = true
|
|
710
|
-
let image = marketBadgeImages[index]
|
|
711
|
-
image.isUserInteractionEnabled = false
|
|
712
|
-
image.translatesAutoresizingMaskIntoConstraints = false
|
|
713
|
-
button.addSubview(image)
|
|
714
|
-
NSLayoutConstraint.activate([
|
|
715
|
-
image.centerYAnchor.constraint(equalTo: button.centerYAnchor),
|
|
716
|
-
image.widthAnchor.constraint(equalToConstant: 14),
|
|
717
|
-
image.heightAnchor.constraint(equalToConstant: 14),
|
|
718
|
-
])
|
|
719
|
-
titleRowStack.addArrangedSubview(button)
|
|
720
|
-
}
|
|
721
615
|
titleLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
722
616
|
titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
723
617
|
badgeLabel.setContentHuggingPriority(.required, for: .horizontal)
|
|
@@ -949,7 +843,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
949
843
|
case "activity": bindActivity(item, theme: theme)
|
|
950
844
|
case "message": bindMessage(item, theme: theme)
|
|
951
845
|
case "dataRow": bindDataRow(item, theme: theme, checkboxState)
|
|
952
|
-
case "market": bindMarket(item, theme: theme)
|
|
953
846
|
case "mediaTile": bindMediaTile(item, theme: theme)
|
|
954
847
|
case "metricCard": bindMetricCard(item, theme: theme)
|
|
955
848
|
case "sectionHeader": bindSectionHeader(item, theme: theme, layout: layout, checkboxState)
|
|
@@ -1148,7 +1041,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
1148
1041
|
selectorConstraints.removeAll()
|
|
1149
1042
|
selectorImages.forEach { $0.prepareForReuse() }
|
|
1150
1043
|
selectorImages.removeAll()
|
|
1151
|
-
marketBadgeImages.forEach { $0.prepareForReuse(); $0.isHidden = true }
|
|
1152
1044
|
selectorFullWidthBackground.removeFromSuperlayer()
|
|
1153
1045
|
selectorBorder?.removeFromSuperlayer()
|
|
1154
1046
|
selectorBorder = nil
|
|
@@ -1231,7 +1123,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
1231
1123
|
$0.isHidden = true
|
|
1232
1124
|
$0.alpha = 1
|
|
1233
1125
|
$0.layer.cornerRadius = 0
|
|
1234
|
-
$0.layer.mask = nil
|
|
1235
1126
|
}
|
|
1236
1127
|
leadingContainer.clipsToBounds = true
|
|
1237
1128
|
leadingContainer.layer.borderWidth = 0
|
|
@@ -1287,19 +1178,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
1287
1178
|
badgeLabel.backgroundColor = .clear
|
|
1288
1179
|
badgeLabel.layer.cornerRadius = 0
|
|
1289
1180
|
badgeLabel.clipsToBounds = false
|
|
1290
|
-
marketBadgeButtons.forEach {
|
|
1291
|
-
$0.isHidden = true
|
|
1292
|
-
$0.isEnabled = true
|
|
1293
|
-
$0.isUserInteractionEnabled = false
|
|
1294
|
-
$0.setTitle(nil, for: .normal)
|
|
1295
|
-
$0.setImage(nil, for: .normal)
|
|
1296
|
-
$0.setTitleColor(nil, for: .normal)
|
|
1297
|
-
$0.tintColor = nil
|
|
1298
|
-
$0.backgroundColor = .clear
|
|
1299
|
-
$0.contentEdgeInsets = .zero
|
|
1300
|
-
$0.imageEdgeInsets = .zero
|
|
1301
|
-
$0.titleEdgeInsets = .zero
|
|
1302
|
-
}
|
|
1303
1181
|
[titleLabel, subtitleLabel, tertiaryLabel, statusLabel, metricSubtitleLabel, badgeLabel, actionStack]
|
|
1304
1182
|
.forEach { $0.isHidden = true }
|
|
1305
1183
|
separatorView.isHidden = true
|
|
@@ -1310,9 +1188,7 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
1310
1188
|
$0.backgroundColor = .clear
|
|
1311
1189
|
}
|
|
1312
1190
|
accessoryButtons.enumerated().forEach { index, button in
|
|
1313
|
-
button.isUserInteractionEnabled = true
|
|
1314
1191
|
button.selectorSummaryLineHeight = nil
|
|
1315
|
-
button.marketLineHeight = nil
|
|
1316
1192
|
button.titleLabel?.font = nativeListFont(
|
|
1317
1193
|
ofSize: index == 0 ? 16 : 14,
|
|
1318
1194
|
weight: index == 0 ? .medium : .regular
|
|
@@ -1357,7 +1233,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
1357
1233
|
boundCheckboxData = nil
|
|
1358
1234
|
boundCheckboxTarget = nil
|
|
1359
1235
|
leadingActionKey = nil
|
|
1360
|
-
marketBadgeActionKeys = []
|
|
1361
1236
|
layer.maskedCorners = []
|
|
1362
1237
|
layer.cornerRadius = 0
|
|
1363
1238
|
layer.cornerCurve = .circular
|
|
@@ -2139,281 +2014,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
2139
2014
|
}
|
|
2140
2015
|
}
|
|
2141
2016
|
|
|
2142
|
-
private func marketFontWeight(_ value: String, fallback: NativeListFontWeight) -> NativeListFontWeight {
|
|
2143
|
-
switch value {
|
|
2144
|
-
case "regular": return .regular
|
|
2145
|
-
case "semibold": return .semibold
|
|
2146
|
-
case "bold": return .bold
|
|
2147
|
-
case "medium": return .medium
|
|
2148
|
-
default: return fallback
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
|
|
2152
|
-
private func marketTextAlignment(_ value: String) -> NSTextAlignment {
|
|
2153
|
-
switch value {
|
|
2154
|
-
case "center": return .center
|
|
2155
|
-
case "start": return effectiveUserInterfaceLayoutDirection == .rightToLeft ? .right : .left
|
|
2156
|
-
case "end": return effectiveUserInterfaceLayoutDirection == .rightToLeft ? .left : .right
|
|
2157
|
-
default: return .natural
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
|
|
2161
|
-
private func applyMarketTextStyle(
|
|
2162
|
-
_ label: UILabel,
|
|
2163
|
-
data: [String: Any]?,
|
|
2164
|
-
theme: [String: Any]?,
|
|
2165
|
-
defaultSize: CGFloat,
|
|
2166
|
-
defaultLineHeight: CGFloat,
|
|
2167
|
-
defaultWeight: NativeListFontWeight,
|
|
2168
|
-
defaultColor: UIColor,
|
|
2169
|
-
defaultAlignment: NSTextAlignment = .natural
|
|
2170
|
-
) {
|
|
2171
|
-
let size = CGFloat(data?.double("fontSize", default: Double(defaultSize)) ?? Double(defaultSize))
|
|
2172
|
-
let lineHeight = CGFloat(data?.double("lineHeight", default: Double(defaultLineHeight)) ?? Double(defaultLineHeight))
|
|
2173
|
-
label.font = nativeListTabularFont(ofSize: size, weight: marketFontWeight(data?.string("fontWeight") ?? "", fallback: defaultWeight))
|
|
2174
|
-
label.textColor = data?["color"].flatMap { $0 as? String }.map { UIColor(nativeListHex: $0, fallback: defaultColor) } ?? defaultColor
|
|
2175
|
-
label.textAlignment = data?["alignment"] == nil
|
|
2176
|
-
? defaultAlignment
|
|
2177
|
-
: marketTextAlignment(data?.string("alignment") ?? "")
|
|
2178
|
-
label.numberOfLines = min(2, max(1, data?.int("lines", default: 1) ?? 1))
|
|
2179
|
-
setLineHeight(label, text: label.text ?? "", lineHeight: lineHeight)
|
|
2180
|
-
}
|
|
2181
|
-
|
|
2182
|
-
private func applyMarketButtonStyle(
|
|
2183
|
-
_ button: UIButton,
|
|
2184
|
-
data: [String: Any]?,
|
|
2185
|
-
defaultSize: CGFloat,
|
|
2186
|
-
defaultLineHeight: CGFloat,
|
|
2187
|
-
defaultWeight: NativeListFontWeight,
|
|
2188
|
-
color: UIColor,
|
|
2189
|
-
defaultAlignment: UIControl.ContentHorizontalAlignment
|
|
2190
|
-
) {
|
|
2191
|
-
let size = CGFloat(data?.double("fontSize", default: Double(defaultSize)) ?? Double(defaultSize))
|
|
2192
|
-
let lineHeight = CGFloat(data?.double("lineHeight", default: Double(defaultLineHeight)) ?? Double(defaultLineHeight))
|
|
2193
|
-
setButtonLine(
|
|
2194
|
-
button,
|
|
2195
|
-
text: button.title(for: .normal) ?? "",
|
|
2196
|
-
font: nativeListTabularFont(ofSize: size, weight: marketFontWeight(data?.string("fontWeight") ?? "", fallback: defaultWeight)),
|
|
2197
|
-
color: data?["color"].flatMap { $0 as? String }.map { UIColor(nativeListHex: $0, fallback: color) } ?? color,
|
|
2198
|
-
lineHeight: lineHeight
|
|
2199
|
-
)
|
|
2200
|
-
if data?["alignment"] == nil {
|
|
2201
|
-
button.contentHorizontalAlignment = defaultAlignment
|
|
2202
|
-
} else {
|
|
2203
|
-
button.contentHorizontalAlignment = data?.string("alignment") == "start"
|
|
2204
|
-
? .leading
|
|
2205
|
-
: data?.string("alignment") == "end" ? .trailing : .center
|
|
2206
|
-
}
|
|
2207
|
-
button.titleLabel?.numberOfLines = min(2, max(1, data?.int("lines", default: 1) ?? 1))
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
private func marketAttributedText(
|
|
2211
|
-
_ text: String,
|
|
2212
|
-
segments: [[String: Any]],
|
|
2213
|
-
style: [String: Any]?,
|
|
2214
|
-
defaultSize: CGFloat,
|
|
2215
|
-
defaultLineHeight: CGFloat,
|
|
2216
|
-
defaultWeight: NativeListFontWeight,
|
|
2217
|
-
color: UIColor,
|
|
2218
|
-
defaultAlignment: NSTextAlignment
|
|
2219
|
-
) -> NSAttributedString {
|
|
2220
|
-
let size = CGFloat(style?.double("fontSize", default: Double(defaultSize)) ?? Double(defaultSize))
|
|
2221
|
-
let lineHeight = CGFloat(style?.double("lineHeight", default: Double(defaultLineHeight)) ?? Double(defaultLineHeight))
|
|
2222
|
-
let paragraph = NSMutableParagraphStyle()
|
|
2223
|
-
paragraph.minimumLineHeight = lineHeight
|
|
2224
|
-
paragraph.maximumLineHeight = lineHeight
|
|
2225
|
-
paragraph.alignment = style?["alignment"] == nil
|
|
2226
|
-
? defaultAlignment
|
|
2227
|
-
: marketTextAlignment(style?.string("alignment") ?? "")
|
|
2228
|
-
let weight = marketFontWeight(style?.string("fontWeight") ?? "", fallback: defaultWeight)
|
|
2229
|
-
let resolvedColor = style?["color"].flatMap { $0 as? String }.map { UIColor(nativeListHex: $0, fallback: color) } ?? color
|
|
2230
|
-
let result = NSMutableAttributedString(string: "")
|
|
2231
|
-
let source = segments.isEmpty ? [["text": text]] : segments
|
|
2232
|
-
for segment in source {
|
|
2233
|
-
let segmentSize = segment.string("style") == "subscript" ? ceil(size * 0.6) : size
|
|
2234
|
-
result.append(NSAttributedString(string: segment.string("text"), attributes: [
|
|
2235
|
-
.font: nativeListTabularFont(ofSize: segmentSize, weight: weight),
|
|
2236
|
-
.foregroundColor: resolvedColor,
|
|
2237
|
-
.kern: 0,
|
|
2238
|
-
.paragraphStyle: paragraph,
|
|
2239
|
-
.baselineOffset: max(0, (lineHeight - nativeListTabularFont(ofSize: size, weight: weight).lineHeight) / 2),
|
|
2240
|
-
]))
|
|
2241
|
-
}
|
|
2242
|
-
return result
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
private func marketLeading(_ item: NativeListItem, style: [String: Any]?) -> [String: Any]? {
|
|
2246
|
-
guard var visual = item.data.dictionary("leading") else { return nil }
|
|
2247
|
-
guard let imageStyle = style?.dictionary("image") else { return visual }
|
|
2248
|
-
if let shape = imageStyle["shape"] as? String { visual["shape"] = shape }
|
|
2249
|
-
if let contentFit = imageStyle["contentFit"] as? String, var image = visual.dictionary("image") {
|
|
2250
|
-
image["contentFit"] = contentFit
|
|
2251
|
-
visual["image"] = image
|
|
2252
|
-
}
|
|
2253
|
-
return visual
|
|
2254
|
-
}
|
|
2255
|
-
|
|
2256
|
-
private func bindMarket(_ item: NativeListItem, theme: [String: Any]?) {
|
|
2257
|
-
let variant = item.data.string("variant")
|
|
2258
|
-
let style = item.data.dictionary("style")
|
|
2259
|
-
let imageStyle = style?.dictionary("image")
|
|
2260
|
-
let imageWidth = CGFloat(imageStyle?.double("width", default: variant == "stock" ? 40 : 32) ?? (variant == "stock" ? 40 : 32))
|
|
2261
|
-
let imageHeight = CGFloat(imageStyle?.double("height", default: variant == "stock" ? 40 : 32) ?? (variant == "stock" ? 40 : 32))
|
|
2262
|
-
let horizontalPadding = CGFloat(style?.double("horizontalPadding", default: variant == "perp" ? 16 : 20) ?? (variant == "perp" ? 16 : 20))
|
|
2263
|
-
let verticalPadding = CGFloat(style?.double("verticalPadding", default: 12) ?? 12)
|
|
2264
|
-
rootLeadingConstraint.constant = horizontalPadding
|
|
2265
|
-
rootTrailingConstraint.constant = -horizontalPadding
|
|
2266
|
-
rootTopConstraint.constant = verticalPadding
|
|
2267
|
-
rootBottomConstraint.constant = -verticalPadding
|
|
2268
|
-
rootStack.spacing = CGFloat(style?.double("leadingGap", default: variant == "perp" ? 8 : 14) ?? (variant == "perp" ? 8 : 14))
|
|
2269
|
-
leadingWidth.constant = imageWidth
|
|
2270
|
-
leadingHeight.constant = imageHeight
|
|
2271
|
-
if let visual = marketLeading(item, style: style) {
|
|
2272
|
-
addLeading(visual, key: item.key)
|
|
2273
|
-
let radius = CGFloat(imageStyle?.double("cornerRadius", default: imageStyle?.string("shape") == "square" ? 0 : imageStyle?.string("shape") == "rounded" ? 8 : Double(min(imageWidth, imageHeight) / 2)) ?? Double(min(imageWidth, imageHeight) / 2))
|
|
2274
|
-
leadingContainer.layer.cornerRadius = radius
|
|
2275
|
-
leadingImages.first?.layer.cornerRadius = radius
|
|
2276
|
-
if let image = leadingImages.first, !visual.string("borderColor").isEmpty {
|
|
2277
|
-
// Match Token's border box: the bitmap occupies the one-point inset.
|
|
2278
|
-
leadingContainer.layer.borderWidth = 1
|
|
2279
|
-
leadingContainer.layer.borderColor = UIColor(nativeListHex: visual.string("borderColor"), fallback: .clear).cgColor
|
|
2280
|
-
for constraint in leadingSlotConstraints where constraint.firstItem === image {
|
|
2281
|
-
switch constraint.firstAttribute {
|
|
2282
|
-
case .leading, .top: constraint.constant = 1
|
|
2283
|
-
case .trailing, .bottom: constraint.constant = -1
|
|
2284
|
-
default: break
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
image.layer.cornerRadius = 0
|
|
2288
|
-
let mask = CAShapeLayer()
|
|
2289
|
-
mask.path = UIBezierPath(roundedRect: CGRect(x: -1, y: -1, width: imageWidth, height: imageHeight), cornerRadius: radius).cgPath
|
|
2290
|
-
image.layer.mask = mask
|
|
2291
|
-
}
|
|
2292
|
-
if let diagnostic = item.data.dictionary("diagnostics")?.string("imageBindActionKey"), !diagnostic.isEmpty,
|
|
2293
|
-
visual.dictionary("image") != nil || visual.dictionary("networkImage") != nil {
|
|
2294
|
-
onAction?(item, diagnostic, nil, nil)
|
|
2295
|
-
}
|
|
2296
|
-
}
|
|
2297
|
-
rootStack.addArrangedSubview(mainStack)
|
|
2298
|
-
rootStack.setCustomSpacing(0, after: mainStack)
|
|
2299
|
-
mainStack.spacing = CGFloat(style?.double("lineGap", default: 0) ?? 0)
|
|
2300
|
-
titleRowStack.spacing = CGFloat(style?.double("titleBadgeGap", default: 4) ?? 4)
|
|
2301
|
-
show(titleLabel, item.data.string("title"), lines: style?.dictionary("title")?.int("lines", default: 1) ?? 1)
|
|
2302
|
-
applyMarketTextStyle(titleLabel, data: style?.dictionary("title"), theme: theme, defaultSize: 16, defaultLineHeight: 24, defaultWeight: .medium, defaultColor: nativeListColor(theme, "primaryText", "#202020"))
|
|
2303
|
-
let badges = Array(item.data.dictionaries("badges").prefix(marketBadgeButtons.count))
|
|
2304
|
-
marketBadgeActionKeys = badges.map { $0["actionKey"] as? String }
|
|
2305
|
-
for (index, badge) in badges.enumerated() {
|
|
2306
|
-
let button = marketBadgeButtons[index]
|
|
2307
|
-
let hasBuiltInIcon = badge.string("iconName") == "verified"
|
|
2308
|
-
let hasRemoteIcon = badge.dictionary("icon") != nil
|
|
2309
|
-
let hasIcon = hasBuiltInIcon || hasRemoteIcon
|
|
2310
|
-
let text = badge.string("text")
|
|
2311
|
-
let toneColor: UIColor
|
|
2312
|
-
switch badge.string("tone") {
|
|
2313
|
-
case "success": toneColor = nativeListColor(theme, "positive", "#218358")
|
|
2314
|
-
case "danger": toneColor = nativeListColor(theme, "negative", "#CE2C31")
|
|
2315
|
-
case "info": toneColor = nativeListColor(theme, "info", "#0D74CE")
|
|
2316
|
-
case "warning": toneColor = nativeListColor(theme, "primaryText", "#202020")
|
|
2317
|
-
default: toneColor = nativeListColor(theme, "secondaryText", "#646464")
|
|
2318
|
-
}
|
|
2319
|
-
let foreground = UIColor(
|
|
2320
|
-
nativeListHex: badge.string("textColor", default: ""),
|
|
2321
|
-
fallback: toneColor
|
|
2322
|
-
)
|
|
2323
|
-
button.isHidden = false
|
|
2324
|
-
button.isEnabled = true
|
|
2325
|
-
button.isUserInteractionEnabled = !badge.string("actionKey").isEmpty
|
|
2326
|
-
button.accessibilityTraits = button.isUserInteractionEnabled ? .button : .staticText
|
|
2327
|
-
button.setTitle(text, for: .normal)
|
|
2328
|
-
button.setTitleColor(foreground, for: .normal)
|
|
2329
|
-
button.tintColor = foreground
|
|
2330
|
-
button.backgroundColor = UIColor(
|
|
2331
|
-
nativeListHex: badge.string("backgroundColor", default: ""),
|
|
2332
|
-
fallback: hasIcon && text.isEmpty
|
|
2333
|
-
? .clear
|
|
2334
|
-
: nativeListColor(theme, "strongBackground", "#0000000F")
|
|
2335
|
-
)
|
|
2336
|
-
let iconOnly = hasIcon && text.isEmpty
|
|
2337
|
-
let iconSize: CGFloat = hasBuiltInIcon ? 16 : 14
|
|
2338
|
-
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: iconOnly ? 0 : hasRemoteIcon ? 20 : hasIcon ? 3 : 5, bottom: 0, right: iconOnly ? 0 : 5)
|
|
2339
|
-
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: text.isEmpty ? 0 : 3)
|
|
2340
|
-
button.titleEdgeInsets = .zero
|
|
2341
|
-
button.imageView?.contentMode = .scaleAspectFit
|
|
2342
|
-
if hasBuiltInIcon {
|
|
2343
|
-
button.setImage(
|
|
2344
|
-
nativeListIcon(named: "BadgeVerifiedSolid", size: CGSize(width: iconSize, height: iconSize)),
|
|
2345
|
-
for: .normal
|
|
2346
|
-
)
|
|
2347
|
-
}
|
|
2348
|
-
let height = button.heightAnchor.constraint(equalToConstant: 18)
|
|
2349
|
-
let textWidth = (text as NSString).size(
|
|
2350
|
-
withAttributes: [.font: nativeListFont(ofSize: 11, weight: .medium)]
|
|
2351
|
-
).width
|
|
2352
|
-
let width = button.widthAnchor.constraint(equalToConstant: iconOnly ? iconSize : ceil(textWidth) + (hasIcon ? iconSize + 11 : 10))
|
|
2353
|
-
NSLayoutConstraint.activate([width, height])
|
|
2354
|
-
selectorConstraints.append(contentsOf: [width, height])
|
|
2355
|
-
if let icon = badge.dictionary("icon") {
|
|
2356
|
-
marketBadgeImages[index].isHidden = false
|
|
2357
|
-
marketBadgeImages[index].layer.cornerRadius = 7
|
|
2358
|
-
marketBadgeImages[index].clipsToBounds = true
|
|
2359
|
-
let imageLeading = marketBadgeImages[index].leadingAnchor.constraint(equalTo: button.leadingAnchor, constant: text.isEmpty ? 0 : 4)
|
|
2360
|
-
imageLeading.isActive = true
|
|
2361
|
-
selectorConstraints.append(imageLeading)
|
|
2362
|
-
bindImage(icon, into: marketBadgeImages[index], token: item.key, slot: 20 + index, variant: "generic")
|
|
2363
|
-
}
|
|
2364
|
-
button.accessibilityLabel = badge.string("accessibilityLabel", default: badge.string("text"))
|
|
2365
|
-
}
|
|
2366
|
-
if !item.data.string("subtitle").isEmpty || !item.data.dictionaries("subtitleSegments").isEmpty {
|
|
2367
|
-
show(subtitleLabel, item.data.string("subtitle"), lines: style?.dictionary("subtitle")?.int("lines", default: 1) ?? 1)
|
|
2368
|
-
applyMarketTextStyle(subtitleLabel, data: style?.dictionary("subtitle"), theme: theme, defaultSize: 14, defaultLineHeight: 20, defaultWeight: .regular, defaultColor: nativeListColor(theme, "secondaryText", "#646464"))
|
|
2369
|
-
if !item.data.dictionaries("subtitleSegments").isEmpty {
|
|
2370
|
-
subtitleLabel.attributedText = marketAttributedText(item.data.string("subtitle"), segments: item.data.dictionaries("subtitleSegments"), style: style?.dictionary("subtitle"), defaultSize: 14, defaultLineHeight: 20, defaultWeight: .regular, color: nativeListColor(theme, "secondaryText", "#646464"), defaultAlignment: .natural)
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
2373
|
-
rootStack.addArrangedSubview(trailingStack)
|
|
2374
|
-
trailingStack.axis = .horizontal
|
|
2375
|
-
trailingStack.alignment = .center
|
|
2376
|
-
trailingStack.spacing = CGFloat(style?.double("trailingGap", default: 8) ?? 8)
|
|
2377
|
-
updateMarketQuote(item, theme: theme)
|
|
2378
|
-
}
|
|
2379
|
-
|
|
2380
|
-
func updateMarketQuote(_ item: NativeListItem, theme: [String: Any]?) {
|
|
2381
|
-
guard currentItem?.key == item.key, item.type == "market" else { return }
|
|
2382
|
-
currentItem = item
|
|
2383
|
-
NSLayoutConstraint.deactivate(accessorySizeConstraints)
|
|
2384
|
-
accessorySizeConstraints.removeAll()
|
|
2385
|
-
let style = item.data.dictionary("style")
|
|
2386
|
-
let price = accessoryButtons[0]
|
|
2387
|
-
price.isUserInteractionEnabled = false
|
|
2388
|
-
price.isHidden = false
|
|
2389
|
-
price.setTitle(item.data.string("price"), for: .normal)
|
|
2390
|
-
applyMarketButtonStyle(price, data: style?.dictionary("price"), defaultSize: 16, defaultLineHeight: 24, defaultWeight: .medium, color: nativeListColor(theme, "primaryText", "#202020"), defaultAlignment: .trailing)
|
|
2391
|
-
if !item.data.dictionaries("priceSegments").isEmpty {
|
|
2392
|
-
price.setAttributedTitle(marketAttributedText(item.data.string("price"), segments: item.data.dictionaries("priceSegments"), style: style?.dictionary("price"), defaultSize: 16, defaultLineHeight: 24, defaultWeight: .medium, color: nativeListColor(theme, "primaryText", "#202020"), defaultAlignment: marketTextAlignment("end")), for: .normal)
|
|
2393
|
-
}
|
|
2394
|
-
let changeData = item.data.dictionary("change") ?? [:]
|
|
2395
|
-
let change = accessoryButtons[1]
|
|
2396
|
-
change.isUserInteractionEnabled = false
|
|
2397
|
-
change.isHidden = false
|
|
2398
|
-
change.setTitle(changeData.string("text"), for: .normal)
|
|
2399
|
-
let defaultChangeColor = nativeListColor(theme, "inverseText", "#FFFFFF")
|
|
2400
|
-
applyMarketButtonStyle(change, data: style?.dictionary("change"), defaultSize: 14, defaultLineHeight: 20, defaultWeight: .medium, color: UIColor(nativeListHex: changeData.string("textColor", default: "#FFFFFF"), fallback: defaultChangeColor), defaultAlignment: .center)
|
|
2401
|
-
if !changeData.dictionaries("textSegments").isEmpty {
|
|
2402
|
-
let changeTextColor = UIColor(nativeListHex: changeData.string("textColor", default: ""), fallback: defaultChangeColor)
|
|
2403
|
-
change.setAttributedTitle(marketAttributedText(changeData.string("text"), segments: changeData.dictionaries("textSegments"), style: style?.dictionary("change"), defaultSize: 14, defaultLineHeight: 20, defaultWeight: .medium, color: changeTextColor, defaultAlignment: .center), for: .normal)
|
|
2404
|
-
}
|
|
2405
|
-
let toneKey = changeData.string("tone") == "positive" ? "positive" : changeData.string("tone") == "negative" ? "negative" : "secondaryText"
|
|
2406
|
-
change.backgroundColor = UIColor(nativeListHex: changeData.string("backgroundColor", default: ""), fallback: nativeListColor(theme, toneKey, changeData.string("tone") == "positive" ? "#218358" : changeData.string("tone") == "negative" ? "#CE2C31" : "#8D8D8D"))
|
|
2407
|
-
change.layer.cornerRadius = CGFloat(style?.double("changeCornerRadius", default: 8) ?? 8)
|
|
2408
|
-
change.clipsToBounds = true
|
|
2409
|
-
let width = change.widthAnchor.constraint(equalToConstant: CGFloat(style?.double("changeWidth", default: 80) ?? 80))
|
|
2410
|
-
let height = change.heightAnchor.constraint(equalToConstant: CGFloat(style?.double("changeHeight", default: 32) ?? 32))
|
|
2411
|
-
width.isActive = true
|
|
2412
|
-
height.isActive = true
|
|
2413
|
-
accessorySizeConstraints.append(contentsOf: [width, height])
|
|
2414
|
-
accessibilityLabel = item.data.string("accessibilityLabel", default: [item.data.string("title"), item.data.string("subtitle"), item.data.string("price"), changeData.string("text")].filter { !$0.isEmpty }.joined(separator: ", "))
|
|
2415
|
-
}
|
|
2416
|
-
|
|
2417
2017
|
private func bindMediaTile(_ item: NativeListItem, theme: [String: Any]?) {
|
|
2418
2018
|
rootStack.axis = .vertical
|
|
2419
2019
|
rootStack.alignment = .fill
|
|
@@ -3030,76 +2630,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3030
2630
|
rootStack.alignment = .center
|
|
3031
2631
|
rootStack.distribution = .fill
|
|
3032
2632
|
let variant = item.data.string("variant")
|
|
3033
|
-
let isMarket = item.data.string("presentation") == "market"
|
|
3034
|
-
if isMarket {
|
|
3035
|
-
rootLeadingConstraint.constant = 20
|
|
3036
|
-
rootTrailingConstraint.constant = -20
|
|
3037
|
-
rootTopConstraint.constant = 12
|
|
3038
|
-
rootBottomConstraint.constant = -12
|
|
3039
|
-
}
|
|
3040
|
-
if variant == "loading" && item.data.string("loadingStyle") == "skeleton" {
|
|
3041
|
-
rootLeadingConstraint.constant = 20
|
|
3042
|
-
rootTrailingConstraint.constant = -20
|
|
3043
|
-
rootTopConstraint.constant = 12
|
|
3044
|
-
rootBottomConstraint.constant = -12
|
|
3045
|
-
let skeleton = NativeListMarketSkeleton(background: nativeListColor(theme, "background", "#FFFFFF"))
|
|
3046
|
-
skeleton.translatesAutoresizingMaskIntoConstraints = false
|
|
3047
|
-
skeleton.heightAnchor.constraint(equalToConstant: 32).isActive = true
|
|
3048
|
-
rootStack.addArrangedSubview(skeleton)
|
|
3049
|
-
selectorViews.append(skeleton)
|
|
3050
|
-
return
|
|
3051
|
-
}
|
|
3052
|
-
if variant == "loading" && item.data.string("loadingStyle") == "spinner" {
|
|
3053
|
-
rootTopConstraint.constant = 16
|
|
3054
|
-
rootBottomConstraint.constant = -16
|
|
3055
|
-
rootStack.addArrangedSubview(mainStack)
|
|
3056
|
-
mainStack.alignment = .center
|
|
3057
|
-
mainStack.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
3058
|
-
let indicator = UIActivityIndicatorView(style: .medium)
|
|
3059
|
-
indicator.color = nativeListColor(theme, "icon", "#0000009B")
|
|
3060
|
-
indicator.startAnimating()
|
|
3061
|
-
mainStack.addArrangedSubview(indicator)
|
|
3062
|
-
selectorViews.append(indicator)
|
|
3063
|
-
return
|
|
3064
|
-
}
|
|
3065
|
-
if isMarket && variant == "noMatch" {
|
|
3066
|
-
rootTopConstraint.constant = 32
|
|
3067
|
-
rootBottomConstraint.constant = -32
|
|
3068
|
-
rootStack.addArrangedSubview(mainStack)
|
|
3069
|
-
mainStack.alignment = .center
|
|
3070
|
-
mainStack.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
3071
|
-
titleLabel.font = nativeListFont(ofSize: 16)
|
|
3072
|
-
titleLabel.textColor = nativeListColor(theme, "secondaryText", "#646464")
|
|
3073
|
-
titleLabel.textAlignment = .center
|
|
3074
|
-
show(titleLabel, item.data.string("message"), lines: 1)
|
|
3075
|
-
setLineHeight(titleLabel, text: item.data.string("message"), lineHeight: 24)
|
|
3076
|
-
return
|
|
3077
|
-
}
|
|
3078
|
-
if isMarket && variant == "end" {
|
|
3079
|
-
rootTopConstraint.constant = 16
|
|
3080
|
-
rootBottomConstraint.constant = -16
|
|
3081
|
-
rootStack.addArrangedSubview(mainStack)
|
|
3082
|
-
mainStack.alignment = .center
|
|
3083
|
-
mainStack.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
3084
|
-
let indicator = UIStackView()
|
|
3085
|
-
indicator.axis = .horizontal
|
|
3086
|
-
indicator.alignment = .center
|
|
3087
|
-
indicator.spacing = 8
|
|
3088
|
-
for width in [CGFloat(80), 4, 80] {
|
|
3089
|
-
let mark = UIView()
|
|
3090
|
-
mark.translatesAutoresizingMaskIntoConstraints = false
|
|
3091
|
-
mark.backgroundColor = nativeListColor(theme, "separator", "#0000001F")
|
|
3092
|
-
mark.layer.cornerRadius = width == 4 ? 2 : 0
|
|
3093
|
-
NSLayoutConstraint.activate([
|
|
3094
|
-
mark.widthAnchor.constraint(equalToConstant: width),
|
|
3095
|
-
mark.heightAnchor.constraint(equalToConstant: width == 4 ? 4 : 1),
|
|
3096
|
-
])
|
|
3097
|
-
indicator.addArrangedSubview(mark)
|
|
3098
|
-
}
|
|
3099
|
-
mainStack.addArrangedSubview(indicator)
|
|
3100
|
-
selectorViews.append(indicator)
|
|
3101
|
-
return
|
|
3102
|
-
}
|
|
3103
2633
|
// OneKey patch: deprecated-wallet warnings stay inside the scrolling list.
|
|
3104
2634
|
if variant == "warning" {
|
|
3105
2635
|
rootStack.addArrangedSubview(mainStack)
|
|
@@ -3131,10 +2661,10 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3131
2661
|
return
|
|
3132
2662
|
}
|
|
3133
2663
|
if variant == "loading" {
|
|
3134
|
-
leadingWidth.constant =
|
|
3135
|
-
leadingHeight.constant =
|
|
2664
|
+
leadingWidth.constant = 40
|
|
2665
|
+
leadingHeight.constant = 40
|
|
3136
2666
|
leadingContainer.backgroundColor = nativeListColor(theme, "strongBackground", "#F0F0F0")
|
|
3137
|
-
leadingContainer.layer.cornerRadius =
|
|
2667
|
+
leadingContainer.layer.cornerRadius = 20
|
|
3138
2668
|
rootStack.addArrangedSubview(leadingContainer)
|
|
3139
2669
|
configureSkeleton(skeletonPrimary, width: 120, height: 12, theme: theme)
|
|
3140
2670
|
configureSkeleton(skeletonSecondary, width: 80, height: 12, theme: theme)
|
|
@@ -3546,8 +3076,8 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3546
3076
|
let paragraphStyle = NSMutableParagraphStyle()
|
|
3547
3077
|
paragraphStyle.minimumLineHeight = lineHeight
|
|
3548
3078
|
paragraphStyle.maximumLineHeight = lineHeight
|
|
3549
|
-
if currentItem?.
|
|
3550
|
-
//
|
|
3079
|
+
if currentItem?.data.string("presentation") == "walletSidebar" {
|
|
3080
|
+
// OneKey patch: attributed paragraphs must preserve wallet name alignment and tail ellipsis.
|
|
3551
3081
|
paragraphStyle.alignment = label.textAlignment
|
|
3552
3082
|
paragraphStyle.lineBreakMode = label.lineBreakMode
|
|
3553
3083
|
}
|
|
@@ -3556,15 +3086,15 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3556
3086
|
.foregroundColor: label.textColor as Any,
|
|
3557
3087
|
.paragraphStyle: paragraphStyle,
|
|
3558
3088
|
]
|
|
3559
|
-
if
|
|
3089
|
+
if (currentItem?.data["height"] != nil && (["accountSelector", "walletSidebar"].contains(currentItem?.data.string("presentation") ?? "") || currentItem?.type == "sectionHeader" && currentItem?.data.string("presentation") == "networkSelector")) || currentItem?.type == "system" && currentItem?.data.string("variant") == "warning" {
|
|
3560
3090
|
// OneKey patch: React Native centers font metrics inside explicit line heights.
|
|
3561
3091
|
let baselineOffset = max(0, (lineHeight - label.font.lineHeight) / 2)
|
|
3562
3092
|
// OneKey patch: TextKit's 14/20 headings align their baseline to the upper physical pixel.
|
|
3563
|
-
let isSelectorHeading =
|
|
3093
|
+
let isSelectorHeading = currentItem?.type == "sectionHeader" && currentItem?.data.string("presentation") == "networkSelector" && lineHeight == 20
|
|
3564
3094
|
let scale = window?.screen.scale ?? traitCollection.displayScale
|
|
3565
3095
|
attributes[.baselineOffset] = isSelectorHeading && scale > 0 ? ceil(baselineOffset * scale) / scale : baselineOffset
|
|
3566
3096
|
}
|
|
3567
|
-
if letterSpacing != 0
|
|
3097
|
+
if letterSpacing != 0 { attributes[.kern] = letterSpacing }
|
|
3568
3098
|
label.attributedText = NSAttributedString(string: text, attributes: attributes)
|
|
3569
3099
|
}
|
|
3570
3100
|
|
|
@@ -3582,10 +3112,8 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3582
3112
|
let isSelectorValue = currentItem?.data.string("presentation") == "networkSelector" && currentItem?.data["height"] != nil && currentItem?.data.string("variant") != "summary"
|
|
3583
3113
|
let isSelectorSummary = currentItem?.type == "sectionHeader" && currentItem?.data.string("presentation") == "networkSelector" && currentItem?.data["height"] != nil && currentItem?.data.string("variant") == "summary"
|
|
3584
3114
|
(button as? NativeListAccessoryButton)?.selectorSummaryLineHeight = isSelectorSummary ? lineHeight : nil
|
|
3585
|
-
(button as? NativeListAccessoryButton)?.marketLineHeight = currentItem?.type == "market" ? lineHeight : nil
|
|
3586
3115
|
// OneKey patch: summary text uses its source line box; currency retains trailing alignment.
|
|
3587
|
-
|
|
3588
|
-
paragraphStyle.alignment = isSelectorValue ? .right : isSelectorSummary || currentItem?.type == "market" ? .natural : .center
|
|
3116
|
+
paragraphStyle.alignment = isSelectorValue ? .right : isSelectorSummary ? .natural : .center
|
|
3589
3117
|
if isSelectorSummary {
|
|
3590
3118
|
button.contentHorizontalAlignment = .leading
|
|
3591
3119
|
button.titleLabel?.textAlignment = .natural
|
|
@@ -3594,16 +3122,17 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3594
3122
|
button.contentHorizontalAlignment = .trailing
|
|
3595
3123
|
button.titleLabel?.textAlignment = .right
|
|
3596
3124
|
}
|
|
3597
|
-
let baselineOffset: CGFloat = currentItem?.type == "
|
|
3598
|
-
var attributes: [NSAttributedString.Key: Any] = [
|
|
3599
|
-
.font: font,
|
|
3600
|
-
.foregroundColor: color,
|
|
3601
|
-
.paragraphStyle: paragraphStyle,
|
|
3602
|
-
.baselineOffset: currentItem?.type == "market" && lineHeight == 20 && font.pointSize == 14 ? ceil(baselineOffset * max(1, traitCollection.displayScale)) / max(1, traitCollection.displayScale) : baselineOffset,
|
|
3603
|
-
]
|
|
3604
|
-
if currentItem?.type == "market" { attributes[.kern] = 0 }
|
|
3125
|
+
let baselineOffset: CGFloat = currentItem?.type == "sectionHeader" && currentItem?.data.string("presentation") == "networkSelector" && currentItem?.data["height"] != nil ? max(0, (lineHeight - font.lineHeight) / 2) : 0
|
|
3605
3126
|
button.setAttributedTitle(
|
|
3606
|
-
NSAttributedString(
|
|
3127
|
+
NSAttributedString(
|
|
3128
|
+
string: text,
|
|
3129
|
+
attributes: [
|
|
3130
|
+
.font: font,
|
|
3131
|
+
.foregroundColor: color,
|
|
3132
|
+
.paragraphStyle: paragraphStyle,
|
|
3133
|
+
.baselineOffset: baselineOffset,
|
|
3134
|
+
]
|
|
3135
|
+
),
|
|
3607
3136
|
for: .normal
|
|
3608
3137
|
)
|
|
3609
3138
|
}
|
|
@@ -3865,19 +3394,6 @@ final class NativeListCell: UICollectionViewCell {
|
|
|
3865
3394
|
)
|
|
3866
3395
|
}
|
|
3867
3396
|
|
|
3868
|
-
@objc private func marketBadgePressed(_ sender: UIButton) {
|
|
3869
|
-
guard let item = currentItem,
|
|
3870
|
-
marketBadgeActionKeys.indices.contains(sender.tag),
|
|
3871
|
-
let actionKey = marketBadgeActionKeys[sender.tag],
|
|
3872
|
-
!actionKey.isEmpty else { return }
|
|
3873
|
-
onAction?(
|
|
3874
|
-
item,
|
|
3875
|
-
actionKey,
|
|
3876
|
-
nil,
|
|
3877
|
-
actionOrigin(sourceView: sender, source: "marketBadge", slot: sender.tag)
|
|
3878
|
-
)
|
|
3879
|
-
}
|
|
3880
|
-
|
|
3881
3397
|
@objc private func footerActionPressed(_ sender: UIButton) {
|
|
3882
3398
|
guard let item = currentItem, footerActionKeys.indices.contains(sender.tag) else { return }
|
|
3883
3399
|
onAction?(
|