@shortkitsdk/react-native 0.2.40 → 0.2.42

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.
Binary file
@@ -160,6 +160,9 @@ class ShortKitBridge(
160
160
  item.articleUrl?.let { put("articleUrl", it) }
161
161
  item.commentCount?.let { put("commentCount", it) }
162
162
  item.fallbackUrl?.let { put("fallbackUrl", it) }
163
+ item.videoWidth?.let { put("videoWidth", it) }
164
+ item.videoHeight?.let { put("videoHeight", it) }
165
+ item.aspectRatio?.let { put("aspectRatio", it) }
163
166
  }
164
167
  obj.toString()
165
168
  } catch (_: Exception) {
@@ -502,12 +505,60 @@ class ShortKitBridge(
502
505
  streamingUrl = streamingUrl,
503
506
  thumbnailUrl = thumbnailUrl,
504
507
  captionTracks = emptyList(),
508
+ customMetadata = parseCustomMetadata(obj.optJSONObject("customMetadata")),
505
509
  author = obj.optString("author", null),
506
510
  articleUrl = obj.optString("articleUrl", null),
507
511
  fallbackUrl = obj.optString("fallbackUrl", null),
512
+ videoWidth = obj.optPositiveInt("videoWidth") ?: obj.optPositiveInt("width"),
513
+ videoHeight = obj.optPositiveInt("videoHeight") ?: obj.optPositiveInt("height"),
514
+ aspectRatio = obj.optPositiveDouble("aspectRatio"),
508
515
  )
509
516
  }
510
517
 
518
+ private fun JSONObject.optPositiveInt(key: String): Int? {
519
+ if (!has(key) || isNull(key)) return null
520
+ val value = when (val raw = opt(key)) {
521
+ is Number -> raw.toDouble()
522
+ is String -> raw.toDoubleOrNull()
523
+ else -> null
524
+ } ?: return null
525
+ val intValue = value.toInt()
526
+ return intValue.takeIf { value > 0.0 && intValue > 0 }
527
+ }
528
+
529
+ private fun JSONObject.optPositiveDouble(key: String): Double? {
530
+ if (!has(key) || isNull(key)) return null
531
+ val value = when (val raw = opt(key)) {
532
+ is Number -> raw.toDouble()
533
+ is String -> raw.toDoubleOrNull()
534
+ else -> null
535
+ } ?: return null
536
+ return value.takeIf { it > 0.0 && !it.isNaN() && !it.isInfinite() }
537
+ }
538
+
539
+ private fun parseCustomMetadata(obj: JSONObject?): Map<String, JsonValue>? {
540
+ obj ?: return null
541
+ val result = mutableMapOf<String, JsonValue>()
542
+ val keys = obj.keys()
543
+ while (keys.hasNext()) {
544
+ val key = keys.next()
545
+ result[key] = jsonAnyToJsonValue(obj.opt(key))
546
+ }
547
+ return result.ifEmpty { null }
548
+ }
549
+
550
+ private fun jsonAnyToJsonValue(value: Any?): JsonValue {
551
+ return when (value) {
552
+ null, JSONObject.NULL -> JsonValue.NullValue
553
+ is String -> JsonValue.StringValue(value)
554
+ is Number -> JsonValue.NumberValue(value.toDouble())
555
+ is Boolean -> JsonValue.BoolValue(value)
556
+ is JSONObject -> JsonValue.ObjectValue(parseCustomMetadata(value).orEmpty())
557
+ is JSONArray -> JsonValue.NullValue
558
+ else -> JsonValue.StringValue(value.toString())
559
+ }
560
+ }
561
+
511
562
  private fun buildCaptionTracksJSONArray(tracks: List<CaptionTrack>): JSONArray {
512
563
  val arr = JSONArray()
513
564
  for (track in tracks) {
@@ -1251,6 +1302,9 @@ class ShortKitBridge(
1251
1302
  item.articleUrl?.let { putString("articleUrl", it) }
1252
1303
  item.commentCount?.let { putInt("commentCount", it) }
1253
1304
  item.fallbackUrl?.let { putString("fallbackUrl", it) }
1305
+ item.videoWidth?.let { putInt("videoWidth", it) }
1306
+ item.videoHeight?.let { putInt("videoHeight", it) }
1307
+ item.aspectRatio?.let { putDouble("aspectRatio", it) }
1254
1308
  }
1255
1309
  }
1256
1310
 
@@ -162,7 +162,10 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
162
162
  val wSpec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY)
163
163
  val hSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY)
164
164
 
165
- // Re-pin container
165
+ // Re-pin container — update layoutParams so subsequent layout traversals
166
+ // (scroll events, player binding, etc.) don't re-expand back to the
167
+ // first-pass full-screen size that was recorded at embed time.
168
+ fragmentContainer.layoutParams = LayoutParams(w, h)
166
169
  fragmentContainer.measure(wSpec, hSpec)
167
170
  fragmentContainer.layout(0, 0, w, h)
168
171
 
@@ -184,6 +187,27 @@ class ShortKitFeedView(context: Context) : FrameLayout(context) {
184
187
  }
185
188
  }
186
189
 
190
+ /**
191
+ * Keep rnWidth/rnHeight current so constrainRunnable always re-pins to the
192
+ * correct dimensions if Fabric updates the view size (e.g. rotation) after
193
+ * the fragment has been embedded.
194
+ */
195
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
196
+ super.onSizeChanged(w, h, oldw, oldh)
197
+ if (w > 0 && h > 0) {
198
+ rnWidth = w
199
+ rnHeight = h
200
+ if (feedFragment != null) {
201
+ // Fire immediately on size change so the correction lands within
202
+ // ~1ms rather than waiting 200ms. The embed fires with first-pass
203
+ // dimensions (before safe-area insets are applied) and this fires
204
+ // when the correct second-pass dimensions arrive — roughly 20ms
205
+ // later, which is 1-2 frames during the screen-push animation.
206
+ handler.removeCallbacks(constrainRunnable)
207
+ handler.post(constrainRunnable)
208
+ }
209
+ }
210
+ }
187
211
 
188
212
  // -----------------------------------------------------------------------
189
213
  // Lifecycle
@@ -127,7 +127,7 @@ import ShortKitSDK
127
127
  if !hasPushedInitialProps {
128
128
  let props = buildInitialProps(item: item, json: json)
129
129
  if let surface {
130
- surface.setProperties(props)
130
+ surface.setProperties(propsWithCurrentPlaybackState(props))
131
131
  hasPushedInitialProps = true
132
132
  } else {
133
133
  pendingProps = props
@@ -412,7 +412,7 @@ import ShortKitSDK
412
412
 
413
413
  // Flush any props that arrived before surface was ready
414
414
  if let pending = pendingProps {
415
- surf.setProperties(pending)
415
+ surf.setProperties(propsWithCurrentPlaybackState(pending))
416
416
  pendingProps = nil
417
417
  hasPushedInitialProps = true
418
418
  }
@@ -438,6 +438,14 @@ import ShortKitSDK
438
438
 
439
439
  // MARK: - Helpers
440
440
 
441
+ private func propsWithCurrentPlaybackState(_ props: [String: Any]) -> [String: Any] {
442
+ var refreshed = props
443
+ refreshed["isActive"] = isActive
444
+ refreshed["playerState"] = cachedPlayerState
445
+ refreshed["isMuted"] = cachedIsMuted
446
+ return refreshed
447
+ }
448
+
441
449
  private static func playerStateString(_ state: PlayerState) -> String {
442
450
  switch state {
443
451
  case .idle: return "idle"
@@ -8,32 +8,32 @@
8
8
  <key>BinaryPath</key>
9
9
  <string>ShortKitSDK.framework/ShortKitSDK</string>
10
10
  <key>LibraryIdentifier</key>
11
- <string>ios-arm64_x86_64-simulator</string>
11
+ <string>ios-arm64</string>
12
12
  <key>LibraryPath</key>
13
13
  <string>ShortKitSDK.framework</string>
14
14
  <key>SupportedArchitectures</key>
15
15
  <array>
16
16
  <string>arm64</string>
17
- <string>x86_64</string>
18
17
  </array>
19
18
  <key>SupportedPlatform</key>
20
19
  <string>ios</string>
21
- <key>SupportedPlatformVariant</key>
22
- <string>simulator</string>
23
20
  </dict>
24
21
  <dict>
25
22
  <key>BinaryPath</key>
26
23
  <string>ShortKitSDK.framework/ShortKitSDK</string>
27
24
  <key>LibraryIdentifier</key>
28
- <string>ios-arm64</string>
25
+ <string>ios-arm64_x86_64-simulator</string>
29
26
  <key>LibraryPath</key>
30
27
  <string>ShortKitSDK.framework</string>
31
28
  <key>SupportedArchitectures</key>
32
29
  <array>
33
30
  <string>arm64</string>
31
+ <string>x86_64</string>
34
32
  </array>
35
33
  <key>SupportedPlatform</key>
36
34
  <string>ios</string>
35
+ <key>SupportedPlatformVariant</key>
36
+ <string>simulator</string>
37
37
  </dict>
38
38
  </array>
39
39
  <key>CFBundlePackageType</key>
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.40</string>
14
+ <string>0.2.42</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.40</string>
16
+ <string>0.2.42</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.40\""
53534
+ "value": "\"0.2.42\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -10,11 +10,11 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- 23w227OWxjyMmGQaLZT1I5SzVXU=
13
+ WYwIj+FGMh7YF5ujxHC/klHgUnc=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.abi.json</key>
16
16
  <data>
17
- hGf1d05M6JqCtRSCa1YzvqrWqFw=
17
+ tozRG9zh+x9rx3eAHry35nYt4pM=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
20
20
  <data>
@@ -50,7 +50,7 @@
50
50
  <dict>
51
51
  <key>hash2</key>
52
52
  <data>
53
- 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
53
+ SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
54
54
  </data>
55
55
  </dict>
56
56
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios.private.swiftinterface</key>
@@ -11,9 +11,9 @@
11
11
  <key>CFBundlePackageType</key>
12
12
  <string>FMWK</string>
13
13
  <key>CFBundleVersion</key>
14
- <string>0.2.40</string>
14
+ <string>0.2.42</string>
15
15
  <key>CFBundleShortVersionString</key>
16
- <string>0.2.40</string>
16
+ <string>0.2.42</string>
17
17
  <key>MinimumOSVersion</key>
18
18
  <string>16.0</string>
19
19
  </dict>
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.40\""
53534
+ "value": "\"0.2.42\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -53531,7 +53531,7 @@
53531
53531
  "kind": "StringLiteral",
53532
53532
  "offset": 154,
53533
53533
  "length": 8,
53534
- "value": "\"0.2.40\""
53534
+ "value": "\"0.2.42\""
53535
53535
  },
53536
53536
  {
53537
53537
  "filePath": "\/Users\/michaelseleman\/shortkit\/swift_sdk\/Sources\/ShortKit\/ShortKit.swift",
@@ -10,11 +10,11 @@
10
10
  </data>
11
11
  <key>Info.plist</key>
12
12
  <data>
13
- 23w227OWxjyMmGQaLZT1I5SzVXU=
13
+ WYwIj+FGMh7YF5ujxHC/klHgUnc=
14
14
  </data>
15
15
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
16
16
  <data>
17
- hGf1d05M6JqCtRSCa1YzvqrWqFw=
17
+ tozRG9zh+x9rx3eAHry35nYt4pM=
18
18
  </data>
19
19
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
20
20
  <data>
@@ -30,7 +30,7 @@
30
30
  </data>
31
31
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json</key>
32
32
  <data>
33
- hGf1d05M6JqCtRSCa1YzvqrWqFw=
33
+ tozRG9zh+x9rx3eAHry35nYt4pM=
34
34
  </data>
35
35
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
36
36
  <data>
@@ -66,7 +66,7 @@
66
66
  <dict>
67
67
  <key>hash2</key>
68
68
  <data>
69
- 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
69
+ SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
70
70
  </data>
71
71
  </dict>
72
72
  <key>Modules/ShortKitSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface</key>
@@ -94,7 +94,7 @@
94
94
  <dict>
95
95
  <key>hash2</key>
96
96
  <data>
97
- 6ykDmHgBfxYifZSz+fro3Yvp/b++qes+KaY7NMNET70=
97
+ SzEj0TFMLukykfaw3Vh0cjVfyWUnkYbtJO3MrTBkLeQ=
98
98
  </data>
99
99
  </dict>
100
100
  <key>Modules/ShortKitSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface</key>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shortkitsdk/react-native",
3
- "version": "0.2.40",
3
+ "version": "0.2.42",
4
4
  "description": "ShortKit React Native SDK — short-form video feed",
5
5
  "react-native": "src/index",
6
6
  "source": "src/index",
package/src/types.ts CHANGED
@@ -103,6 +103,12 @@ export interface ContentItem {
103
103
  commentCount?: number;
104
104
  fallbackUrl?: string;
105
105
  downloadUrl?: string;
106
+ /** Source video width in pixels, when known before playback starts. */
107
+ videoWidth?: number;
108
+ /** Source video height in pixels, when known before playback starts. */
109
+ videoHeight?: number;
110
+ /** Source video width / height ratio, when dimensions are not available. */
111
+ aspectRatio?: number;
106
112
  }
107
113
 
108
114
  export type DownloadStatus = 'idle' | 'downloading' | 'completed' | 'failed';