@shortkitsdk/react-native 0.2.30 → 0.2.31
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/android/libs/shortkit-release.aar +0 -0
- package/ios/ShortKitFeedView.swift +1 -12
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Info.plist +2 -2
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json +4646 -954
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/ShortKitSDK +0 -0
- package/ios/ShortKitSDK.xcframework/ios-arm64/ShortKitSDK.framework/_CodeSignature/CodeResources +9 -9
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Info.plist +2 -2
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +4646 -954
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +4646 -954
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +76 -7
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/ShortKitSDK +0 -0
- package/ios/ShortKitSDK.xcframework/ios-arm64_x86_64-simulator/ShortKitSDK.framework/_CodeSignature/CodeResources +17 -17
- package/ios/ShortKitWidgetNativeView.swift +23 -0
- package/ios/ShortKitWidgetNativeViewManager.mm +1 -0
- package/package.json +1 -1
- package/src/ShortKitWidget.tsx +47 -2
- package/src/specs/NativeShortKitModule.ts +7 -0
- package/src/specs/ShortKitWidgetViewNativeComponent.ts +6 -0
- package/src/types.ts +11 -0
- package/ios/DebugPanelView.swift +0 -302
package/ios/DebugPanelView.swift
DELETED
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import UIKit
|
|
2
|
-
import Combine
|
|
3
|
-
import ShortKitSDK
|
|
4
|
-
|
|
5
|
-
private enum AdjacentSlot {
|
|
6
|
-
case previous, next
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
final class DebugPanelView: UIView {
|
|
10
|
-
static let panelWidth: CGFloat = 310
|
|
11
|
-
static let panelHeight: CGFloat = 296 // +20 for collapsed header row
|
|
12
|
-
static let expandedExtraHeight: CGFloat = 80 // 4 labels × ~20pt
|
|
13
|
-
|
|
14
|
-
/// Currently selected swipe curve — FeedViewController reads SwipeCurve.selected.
|
|
15
|
-
static var selectedSwipeCurve: SwipeCurve {
|
|
16
|
-
get { SwipeCurve.selected }
|
|
17
|
-
set { SwipeCurve.selected = newValue }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
private let stackView = UIStackView()
|
|
21
|
-
private let headerLabel = UILabel()
|
|
22
|
-
private let curveSegment = UISegmentedControl()
|
|
23
|
-
private let positionLabel = UILabel()
|
|
24
|
-
private let intentTtffLabel = UILabel()
|
|
25
|
-
private let transitionTtffLabel = UILabel()
|
|
26
|
-
private let prerollBufferLabel = UILabel()
|
|
27
|
-
private let videoQualityLabel = UILabel()
|
|
28
|
-
private let thumbnailLabel = UILabel()
|
|
29
|
-
private let prefetchLabel = UILabel()
|
|
30
|
-
private let bitrateLabel = UILabel()
|
|
31
|
-
private let rebufferLabel = UILabel()
|
|
32
|
-
private let loopWatchLabel = UILabel()
|
|
33
|
-
|
|
34
|
-
// Adjacent players section
|
|
35
|
-
private let adjacentHeader = UILabel()
|
|
36
|
-
private let prevHeaderLabel = UILabel()
|
|
37
|
-
private let prevDetailLabel = UILabel()
|
|
38
|
-
private let nextHeaderLabel = UILabel()
|
|
39
|
-
private let nextDetailLabel = UILabel()
|
|
40
|
-
private let separatorView = UIView()
|
|
41
|
-
private var adjacentLabels: [UIView] = []
|
|
42
|
-
private var isAdjacentExpanded = false
|
|
43
|
-
private var prevCancellable: AnyCancellable?
|
|
44
|
-
private var nextCancellable: AnyCancellable?
|
|
45
|
-
|
|
46
|
-
private var cancellable: AnyCancellable?
|
|
47
|
-
private var dragOffset: CGPoint = .zero
|
|
48
|
-
|
|
49
|
-
override init(frame: CGRect) {
|
|
50
|
-
super.init(frame: frame)
|
|
51
|
-
setupViews()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
required init?(coder: NSCoder) {
|
|
55
|
-
fatalError("init(coder:) has not been implemented")
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private func setupViews() {
|
|
59
|
-
backgroundColor = UIColor.black.withAlphaComponent(0.75)
|
|
60
|
-
layer.cornerRadius = 10
|
|
61
|
-
clipsToBounds = true
|
|
62
|
-
|
|
63
|
-
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
|
|
64
|
-
addGestureRecognizer(pan)
|
|
65
|
-
|
|
66
|
-
let labels = [headerLabel, positionLabel, intentTtffLabel, transitionTtffLabel, prerollBufferLabel, videoQualityLabel, thumbnailLabel, prefetchLabel, bitrateLabel, rebufferLabel, loopWatchLabel]
|
|
67
|
-
for label in labels {
|
|
68
|
-
label.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .regular)
|
|
69
|
-
label.textColor = .white
|
|
70
|
-
label.numberOfLines = 1
|
|
71
|
-
}
|
|
72
|
-
headerLabel.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .bold)
|
|
73
|
-
|
|
74
|
-
stackView.axis = .vertical
|
|
75
|
-
stackView.spacing = 4
|
|
76
|
-
stackView.alignment = .leading
|
|
77
|
-
stackView.translatesAutoresizingMaskIntoConstraints = false
|
|
78
|
-
addSubview(stackView)
|
|
79
|
-
|
|
80
|
-
for label in labels {
|
|
81
|
-
stackView.addArrangedSubview(label)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Swipe curve picker
|
|
85
|
-
for (i, curve) in SwipeCurve.allCases.enumerated() {
|
|
86
|
-
curveSegment.insertSegment(withTitle: curve.label, at: i, animated: false)
|
|
87
|
-
}
|
|
88
|
-
curveSegment.selectedSegmentIndex = SwipeCurve.quarticOut.rawValue
|
|
89
|
-
curveSegment.setTitleTextAttributes([.foregroundColor: UIColor.white, .font: UIFont.monospacedSystemFont(ofSize: 10, weight: .medium)], for: .normal)
|
|
90
|
-
curveSegment.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .selected)
|
|
91
|
-
curveSegment.backgroundColor = UIColor.white.withAlphaComponent(0.15)
|
|
92
|
-
curveSegment.selectedSegmentTintColor = UIColor.white.withAlphaComponent(0.9)
|
|
93
|
-
curveSegment.addTarget(self, action: #selector(curveChanged), for: .valueChanged)
|
|
94
|
-
stackView.addArrangedSubview(curveSegment)
|
|
95
|
-
|
|
96
|
-
// Separator
|
|
97
|
-
separatorView.backgroundColor = UIColor.white.withAlphaComponent(0.3)
|
|
98
|
-
separatorView.translatesAutoresizingMaskIntoConstraints = false
|
|
99
|
-
separatorView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
|
|
100
|
-
stackView.addArrangedSubview(separatorView)
|
|
101
|
-
|
|
102
|
-
// Adjacent header (tap target)
|
|
103
|
-
adjacentHeader.font = UIFont.monospacedSystemFont(ofSize: 12, weight: .bold)
|
|
104
|
-
adjacentHeader.textColor = .white
|
|
105
|
-
adjacentHeader.text = "▶ Adjacent Players"
|
|
106
|
-
adjacentHeader.isUserInteractionEnabled = true
|
|
107
|
-
adjacentHeader.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(toggleAdjacent)))
|
|
108
|
-
stackView.addArrangedSubview(adjacentHeader)
|
|
109
|
-
|
|
110
|
-
// Adjacent player labels (initially hidden)
|
|
111
|
-
let adjLabels = [prevHeaderLabel, prevDetailLabel, nextHeaderLabel, nextDetailLabel]
|
|
112
|
-
for label in adjLabels {
|
|
113
|
-
label.font = UIFont.monospacedSystemFont(ofSize: 11, weight: .regular)
|
|
114
|
-
label.textColor = UIColor.white.withAlphaComponent(0.85)
|
|
115
|
-
label.numberOfLines = 1
|
|
116
|
-
label.isHidden = true
|
|
117
|
-
stackView.addArrangedSubview(label)
|
|
118
|
-
}
|
|
119
|
-
adjacentLabels = adjLabels
|
|
120
|
-
|
|
121
|
-
prevHeaderLabel.text = "▲ Prev — not assigned"
|
|
122
|
-
prevDetailLabel.text = ""
|
|
123
|
-
nextHeaderLabel.text = "▼ Next — not assigned"
|
|
124
|
-
nextDetailLabel.text = ""
|
|
125
|
-
|
|
126
|
-
NSLayoutConstraint.activate([
|
|
127
|
-
stackView.topAnchor.constraint(equalTo: topAnchor, constant: 10),
|
|
128
|
-
stackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 12),
|
|
129
|
-
stackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -12),
|
|
130
|
-
])
|
|
131
|
-
|
|
132
|
-
// Initial state
|
|
133
|
-
update(DebugMetrics())
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
|
|
137
|
-
guard let parent = superview else { return }
|
|
138
|
-
switch gesture.state {
|
|
139
|
-
case .began:
|
|
140
|
-
dragOffset = gesture.location(in: self)
|
|
141
|
-
case .changed:
|
|
142
|
-
let location = gesture.location(in: parent)
|
|
143
|
-
var newCenter = CGPoint(
|
|
144
|
-
x: location.x - dragOffset.x + bounds.width / 2,
|
|
145
|
-
y: location.y - dragOffset.y + bounds.height / 2
|
|
146
|
-
)
|
|
147
|
-
// Keep panel within parent bounds
|
|
148
|
-
let hw = bounds.width / 2, hh = bounds.height / 2
|
|
149
|
-
newCenter.x = max(hw, min(parent.bounds.width - hw, newCenter.x))
|
|
150
|
-
newCenter.y = max(hh, min(parent.bounds.height - hh, newCenter.y))
|
|
151
|
-
center = newCenter
|
|
152
|
-
default:
|
|
153
|
-
break
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
@objc private func curveChanged(_ sender: UISegmentedControl) {
|
|
158
|
-
guard let curve = SwipeCurve(rawValue: sender.selectedSegmentIndex) else { return }
|
|
159
|
-
Self.selectedSwipeCurve = curve
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
@objc private func toggleAdjacent() {
|
|
163
|
-
isAdjacentExpanded.toggle()
|
|
164
|
-
adjacentHeader.text = isAdjacentExpanded ? "▼ Adjacent Players" : "▶ Adjacent Players"
|
|
165
|
-
|
|
166
|
-
UIView.animate(withDuration: 0.25) {
|
|
167
|
-
for label in self.adjacentLabels {
|
|
168
|
-
label.isHidden = !self.isAdjacentExpanded
|
|
169
|
-
label.alpha = self.isAdjacentExpanded ? 1 : 0
|
|
170
|
-
}
|
|
171
|
-
// Resize panel
|
|
172
|
-
var newFrame = self.frame
|
|
173
|
-
let baseHeight = Self.panelHeight
|
|
174
|
-
newFrame.size.height = self.isAdjacentExpanded
|
|
175
|
-
? baseHeight + Self.expandedExtraHeight
|
|
176
|
-
: baseHeight
|
|
177
|
-
self.frame = newFrame
|
|
178
|
-
self.layoutIfNeeded()
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
func subscribe(to subject: CurrentValueSubject<DebugMetrics, Never>) {
|
|
183
|
-
cancellable = subject
|
|
184
|
-
.receive(on: DispatchQueue.main)
|
|
185
|
-
.sink { [weak self] metrics in
|
|
186
|
-
self?.update(metrics)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
func subscribeAdjacent(
|
|
191
|
-
prev: CurrentValueSubject<DebugMetrics, Never>,
|
|
192
|
-
next: CurrentValueSubject<DebugMetrics, Never>
|
|
193
|
-
) {
|
|
194
|
-
prevCancellable = prev
|
|
195
|
-
.receive(on: DispatchQueue.main)
|
|
196
|
-
.sink { [weak self] metrics in
|
|
197
|
-
self?.updateAdjacent(metrics, slot: .previous)
|
|
198
|
-
}
|
|
199
|
-
nextCancellable = next
|
|
200
|
-
.receive(on: DispatchQueue.main)
|
|
201
|
-
.sink { [weak self] metrics in
|
|
202
|
-
self?.updateAdjacent(metrics, slot: .next)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
private func updateAdjacent(_ m: DebugMetrics, slot: AdjacentSlot) {
|
|
207
|
-
let headerLabel = slot == .previous ? prevHeaderLabel : nextHeaderLabel
|
|
208
|
-
let detailLabel = slot == .previous ? prevDetailLabel : nextDetailLabel
|
|
209
|
-
let arrow = slot == .previous ? "▲ Prev" : "▼ Next"
|
|
210
|
-
|
|
211
|
-
guard m.contentId != nil else {
|
|
212
|
-
headerLabel.text = "\(arrow) — not assigned"
|
|
213
|
-
detailLabel.text = ""
|
|
214
|
-
return
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
let id = m.contentId.map { String($0.prefix(8)) } ?? "—"
|
|
218
|
-
let stateIcon: String
|
|
219
|
-
switch m.playerState {
|
|
220
|
-
case .playing: stateIcon = "▶"
|
|
221
|
-
case .paused: stateIcon = "⏸"
|
|
222
|
-
case .buffering: stateIcon = "⏳"
|
|
223
|
-
default: stateIcon = "○"
|
|
224
|
-
}
|
|
225
|
-
headerLabel.text = "\(arrow) #\(m.feedIndex) \(id) \(stateIcon) \(m.playerState)"
|
|
226
|
-
|
|
227
|
-
let buf = String(format: "%.1f", m.bufferAhead)
|
|
228
|
-
let preroll = m.prerollCompleted ? "✓" : "✗"
|
|
229
|
-
let mbps = m.observedBitrateBps / 1_000_000
|
|
230
|
-
var detail = " buf: \(buf)s preroll: \(preroll)"
|
|
231
|
-
if mbps > 0 {
|
|
232
|
-
detail += String(format: " %.1f Mbps", mbps)
|
|
233
|
-
}
|
|
234
|
-
if m.videoWidth > 0 {
|
|
235
|
-
let codec = m.codec ?? ""
|
|
236
|
-
detail += " \(m.videoWidth)×\(m.videoHeight) \(codec)"
|
|
237
|
-
}
|
|
238
|
-
detailLabel.text = detail
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
private func update(_ m: DebugMetrics) {
|
|
242
|
-
let id = m.contentId.map { String($0.prefix(8)) } ?? "—"
|
|
243
|
-
let stateIcon: String
|
|
244
|
-
switch m.playerState {
|
|
245
|
-
case .playing: stateIcon = "▶"
|
|
246
|
-
case .paused: stateIcon = "⏸"
|
|
247
|
-
case .buffering: stateIcon = "⏳"
|
|
248
|
-
case .seeking: stateIcon = "⏩"
|
|
249
|
-
case .error: stateIcon = "⚠️"
|
|
250
|
-
default: stateIcon = "○"
|
|
251
|
-
}
|
|
252
|
-
headerLabel.text = "#\(m.feedIndex) \(id) \(stateIcon) \(m.playerState)"
|
|
253
|
-
|
|
254
|
-
let cur = String(format: "%.1f", m.currentTime)
|
|
255
|
-
let dur = String(format: "%.1f", m.duration)
|
|
256
|
-
positionLabel.text = "Position: \(cur)s / \(dur)s"
|
|
257
|
-
|
|
258
|
-
if let intent = m.intentToFrameMs {
|
|
259
|
-
intentTtffLabel.text = "Intent: \(intent)ms"
|
|
260
|
-
} else {
|
|
261
|
-
intentTtffLabel.text = "Intent: N/A"
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if let transition = m.transitionToFrameMs {
|
|
265
|
-
let net = m.networkMs.map { "\($0)" } ?? "?"
|
|
266
|
-
let dec = m.decodeMs.map { "\($0)" } ?? "?"
|
|
267
|
-
transitionTtffLabel.text = "Transition: \(transition)ms (net: \(net) + dec: \(dec))"
|
|
268
|
-
} else {
|
|
269
|
-
transitionTtffLabel.text = "Transition: measuring..."
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
let preroll = m.prerollCompleted ? "✓" : "✗"
|
|
273
|
-
let buffer = String(format: "%.1f", m.bufferAhead)
|
|
274
|
-
prerollBufferLabel.text = "Preroll: \(preroll) Buffer: \(buffer)s"
|
|
275
|
-
|
|
276
|
-
let codec = m.codec ?? "—"
|
|
277
|
-
if m.videoWidth > 0 {
|
|
278
|
-
videoQualityLabel.text = "Video: \(m.videoWidth)×\(m.videoHeight) \(codec)"
|
|
279
|
-
} else {
|
|
280
|
-
videoQualityLabel.text = "Video: —"
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
thumbnailLabel.text = "Thumbnail: \(m.thumbnailVisible ? "visible" : "removed")"
|
|
284
|
-
prefetchLabel.text = "Prefetch: \(m.thumbsCachedAhead)/\(m.metadataAhead) thumbs \(m.metadataAhead) meta"
|
|
285
|
-
|
|
286
|
-
let obsMbps = m.observedBitrateBps / 1_000_000
|
|
287
|
-
let indMbps = m.indicatedBitrateBps / 1_000_000
|
|
288
|
-
if obsMbps > 0 {
|
|
289
|
-
bitrateLabel.text = String(format: "Bitrate: %.1f Mbps (ind: %.1f)", obsMbps, indMbps)
|
|
290
|
-
} else {
|
|
291
|
-
bitrateLabel.text = "Bitrate: —"
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if let lastMs = m.lastRebufferDurationMs {
|
|
295
|
-
rebufferLabel.text = "Rebuffers: \(m.rebufferCount) (last: \(lastMs)ms)"
|
|
296
|
-
} else {
|
|
297
|
-
rebufferLabel.text = "Rebuffers: \(m.rebufferCount)"
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
loopWatchLabel.text = "Loops: \(m.loopCount)"
|
|
301
|
-
}
|
|
302
|
-
}
|