react-native-firework-sdk 2.14.2 → 2.15.1

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.
Files changed (77) hide show
  1. package/android/gradle.properties +1 -1
  2. package/android/src/main/java/com/fireworksdk/bridge/components/storyblock/StoryBlockFragment.kt +14 -4
  3. package/android/src/main/java/com/fireworksdk/bridge/models/FWActionButtonDeserializer.kt +27 -0
  4. package/android/src/main/java/com/fireworksdk/bridge/models/FWActionButtonModel.kt +8 -0
  5. package/android/src/main/java/com/fireworksdk/bridge/models/FWActionButtonSerializer.kt +21 -0
  6. package/android/src/main/java/com/fireworksdk/bridge/models/FWLiveStreamEventDetailsModel.kt +2 -0
  7. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationDeserializer.kt +3 -0
  8. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationModel.kt +1 -0
  9. package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationSerializer.kt +2 -0
  10. package/android/src/main/java/com/fireworksdk/bridge/models/FWShape.kt +18 -0
  11. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedItemDetailsModel.kt +2 -0
  12. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlaybackDetails.kt +2 -0
  13. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +6 -0
  14. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +23 -1
  15. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelSerializer.kt +14 -0
  16. package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWEventName.kt +3 -1
  17. package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWLivestreamPlayerVersion.kt +6 -0
  18. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +4 -0
  19. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FireworkSDKInterface.kt +1 -0
  20. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +3 -3
  21. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +14 -0
  22. package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +156 -3
  23. package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +6 -0
  24. package/android/src/main/java/com/fireworksdk/bridge/utils/FWModelUtils.kt +32 -0
  25. package/ios/Components/StoryBlock.swift +12 -2
  26. package/ios/Components/VideoFeed.swift +14 -29
  27. package/ios/Components/VideoFeedManager.swift +0 -5
  28. package/ios/FireworkSdk.xcodeproj/project.pbxproj +0 -4
  29. package/ios/Models/NativeToRN/FireworkEventName.swift +3 -1
  30. package/ios/Models/RNToNative/RCTConvert+FireworkSDKModule.swift +13 -0
  31. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +42 -5
  32. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +2 -1
  33. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +16 -12
  34. package/ios/Modules/Shopping/ShoppingModule.swift +1 -1
  35. package/lib/commonjs/FireworkSDK.js +41 -14
  36. package/lib/commonjs/FireworkSDK.js.map +1 -1
  37. package/lib/commonjs/components/StoryBlock.js +21 -0
  38. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  39. package/lib/commonjs/components/VideoFeed.js +23 -0
  40. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  41. package/lib/commonjs/index.js +8 -0
  42. package/lib/commonjs/index.js.map +1 -1
  43. package/lib/commonjs/models/FWEventName.js +2 -0
  44. package/lib/commonjs/models/FWEventName.js.map +1 -1
  45. package/lib/commonjs/models/LivestreamPlayerDesignVersion.js +16 -0
  46. package/lib/commonjs/models/LivestreamPlayerDesignVersion.js.map +1 -0
  47. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  48. package/lib/module/FireworkSDK.js +38 -14
  49. package/lib/module/FireworkSDK.js.map +1 -1
  50. package/lib/module/components/StoryBlock.js +14 -0
  51. package/lib/module/components/StoryBlock.js.map +1 -1
  52. package/lib/module/components/VideoFeed.js +18 -0
  53. package/lib/module/components/VideoFeed.js.map +1 -1
  54. package/lib/module/index.js +2 -1
  55. package/lib/module/index.js.map +1 -1
  56. package/lib/module/models/FWEventName.js +2 -0
  57. package/lib/module/models/FWEventName.js.map +1 -1
  58. package/lib/module/models/LivestreamPlayerDesignVersion.js +9 -0
  59. package/lib/module/models/LivestreamPlayerDesignVersion.js.map +1 -0
  60. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  61. package/lib/typescript/FireworkSDK.d.ts +9 -2
  62. package/lib/typescript/index.d.ts +2 -1
  63. package/lib/typescript/models/FWEventName.d.ts +3 -1
  64. package/lib/typescript/models/LivestreamPlayerDesignVersion.d.ts +5 -0
  65. package/lib/typescript/models/StoryBlockConfiguration.d.ts +2 -7
  66. package/lib/typescript/modules/FireworkSDKModule.d.ts +3 -1
  67. package/package.json +1 -1
  68. package/react-native-firework-sdk.podspec +2 -2
  69. package/src/FireworkSDK.ts +44 -13
  70. package/src/components/StoryBlock.tsx +27 -1
  71. package/src/components/VideoFeed.tsx +29 -1
  72. package/src/index.ts +2 -0
  73. package/src/models/FWEventName.ts +2 -0
  74. package/src/models/LivestreamPlayerDesignVersion.ts +6 -0
  75. package/src/models/StoryBlockConfiguration.ts +2 -7
  76. package/src/modules/FireworkSDKModule.ts +5 -1
  77. package/ios/Utils/Extensions/NumberFormatter+AppLanguage.swift +0 -27
@@ -11,19 +11,35 @@ import com.firework.common.ad.AdBadgeTextType
11
11
  import com.firework.common.ad.AdOption
12
12
  import com.firework.common.cta.CtaDelay
13
13
  import com.firework.common.cta.CtaDelayUnit
14
+ import com.firework.common.cta.CtaStyle
14
15
  import com.firework.common.feed.FeedLayout
15
16
  import com.firework.common.feed.FeedResource
16
17
  import com.firework.common.feed.FeedTitlePosition
18
+ import com.firework.common.player.ActionButtonOption
17
19
  import com.firework.common.player.CloseButtonOption
18
20
  import com.firework.common.player.LivestreamCountDownOption
19
21
  import com.firework.common.player.MuteButtonOption
22
+ import com.firework.common.player.PipButtonOption
20
23
  import com.firework.common.player.PlaybackButtonOption
21
24
  import com.firework.common.player.PlayerUiOption
22
25
  import com.firework.common.player.VideoDetailsOption
26
+ import com.firework.common.widget.ActionButton
27
+ import com.firework.common.widget.Shape
23
28
  import com.firework.common.widget.WidgetImage
24
- import com.firework.viewoptions.*
29
+ import com.firework.viewoptions.BaseOption
30
+ import com.firework.viewoptions.CtaOption
31
+ import com.firework.viewoptions.LayoutOption
32
+ import com.firework.viewoptions.LogoConfig
33
+ import com.firework.viewoptions.PlayerOption
34
+ import com.firework.viewoptions.StoryBlockOption
35
+ import com.firework.viewoptions.TitleOption
36
+ import com.firework.viewoptions.ViewOptions
25
37
  import com.fireworksdk.bridge.FWInitializationProvider
26
- import com.fireworksdk.bridge.models.*
38
+ import com.fireworksdk.bridge.models.FWAdConfigurationModel
39
+ import com.fireworksdk.bridge.models.FWButtonInfoModel
40
+ import com.fireworksdk.bridge.models.FWFontInfoModel
41
+ import com.fireworksdk.bridge.models.FWShape
42
+ import com.fireworksdk.bridge.models.FWVideoFeedPropsModel
27
43
  import com.fireworksdk.bridge.models.enums.FWAppearanceMode
28
44
  import com.fireworksdk.bridge.models.enums.FWBadgeTextType
29
45
  import com.fireworksdk.bridge.models.enums.FWCtaDelayType
@@ -49,6 +65,7 @@ object FWConfigUtil {
49
65
  val playerUiOptionBuilder = getDefaultPlayerUiOptionBuilder()
50
66
  val videoDetailsOptionBuilder = getDefaultVideoDetailsOptionBuilder()
51
67
  val closeButtonOptionBuilder = getDefaultCloseButtonOptionBuilder()
68
+ val pipButtonOptionBuilder = getDefaultPipButtonOptionBuilder()
52
69
  val muteButtonOptionBuilder = getDefaultMuteButtonOptionBuilder()
53
70
  val playbackButtonOptionBuilder = getDefaultPlaybackButtonOptionBuilder()
54
71
  val baseOptionBuilder = getDefaultBaseOptionBuilder()
@@ -56,6 +73,8 @@ object FWConfigUtil {
56
73
  val ctaOptionBuilder = getDefaultCtaOptionBuilder()
57
74
  val adOptionBuilder = getDefaultAdOptionBuilder()
58
75
  val countDownOptionBuilder = getDefaultPlayerCountdownTimerOptionBuilder()
76
+ val actionButtonOption = getDefaultActionButtonOptionBuilder()
77
+ val storyblockOptionBuilder = getDefaultStoryblockOptionBuilder()
59
78
 
60
79
  when (videoFeedPropsModel.source) {
61
80
  FWVideoFeedSource.Discover -> {
@@ -323,6 +342,117 @@ object FWConfigUtil {
323
342
  else -> {}
324
343
  }
325
344
 
345
+ val ctaButtonStyle = videoFeedPropsModel.videoPlayerConfiguration?.ctaButtonStyle
346
+ ctaButtonStyle?.let { style ->
347
+ val background = if (!style.backgroundColor.isNullOrBlank()) {
348
+ FWColorUtil.parseColor(style.backgroundColor)
349
+ } else {
350
+ null
351
+ }
352
+
353
+ val fontSize = if (style.fontSize != null && style.fontSize > 0) {
354
+ FWCommonUtil.spToPx(style.fontSize.toFloat(), context).toFloat()
355
+ } else {
356
+ null
357
+ }
358
+
359
+ val textColor = if (!style.textColor.isNullOrBlank()) {
360
+ FWColorUtil.parseColor(style.textColor)
361
+ } else {
362
+ null
363
+ }
364
+
365
+ val shape = when (style.shape) {
366
+ FWShape.ROUND_RECTANGLE -> {
367
+ Shape.SHAPE_ROUND_RECTANGLE
368
+ }
369
+
370
+ FWShape.OVAL -> {
371
+ Shape.SHAPE_OVAL
372
+ }
373
+
374
+ else -> null
375
+ }
376
+ ctaOptionBuilder.ctaStyle(CtaStyle(
377
+ shape = shape,
378
+ backgroundColor = background,
379
+ textColor = textColor,
380
+ fontSize = fontSize
381
+ ))
382
+ }
383
+
384
+ val actionButtonStyle = videoFeedPropsModel.videoPlayerConfiguration?.actionButtonStyle
385
+ actionButtonStyle?.let { style ->
386
+ val background = if (!style.backgroundColor.isNullOrBlank()) {
387
+ FWColorUtil.parseColor(style.backgroundColor)
388
+ } else {
389
+ null
390
+ }
391
+
392
+ val textColor = if (!style.textColor.isNullOrBlank()) {
393
+ FWColorUtil.parseColor(style.textColor)
394
+ } else {
395
+ null
396
+ }
397
+
398
+ val dividingLineColor = if (!style.dividingLineColor.isNullOrBlank()) {
399
+ FWColorUtil.parseColor(style.dividingLineColor)
400
+ } else {
401
+ null
402
+ }
403
+
404
+ val shape = when (style.shape) {
405
+ FWShape.ROUND_RECTANGLE -> {
406
+ Shape.SHAPE_ROUND_RECTANGLE
407
+ }
408
+
409
+ FWShape.OVAL -> {
410
+ Shape.SHAPE_OVAL
411
+ }
412
+
413
+ else -> null
414
+ }
415
+ actionButtonOption.actionButton(ActionButton(
416
+ backgroundColor = background,
417
+ textColor = textColor,
418
+ shape = shape,
419
+ dividingLineColor = dividingLineColor
420
+ ))
421
+ }
422
+
423
+ val cancelButtonStyle = videoFeedPropsModel.videoPlayerConfiguration?.cancelButtonStyle
424
+ cancelButtonStyle?.let { style ->
425
+ val background = if (!style.backgroundColor.isNullOrBlank()) {
426
+ FWColorUtil.parseColor(style.backgroundColor)
427
+ } else {
428
+ null
429
+ }
430
+
431
+ val textColor = if (!style.textColor.isNullOrBlank()) {
432
+ FWColorUtil.parseColor(style.textColor)
433
+ } else {
434
+ null
435
+ }
436
+
437
+ val shape = when (style.shape) {
438
+ FWShape.ROUND_RECTANGLE -> {
439
+ Shape.SHAPE_ROUND_RECTANGLE
440
+ }
441
+
442
+ FWShape.OVAL -> {
443
+ Shape.SHAPE_OVAL
444
+ }
445
+
446
+ else -> null
447
+ }
448
+ actionButtonOption.cancelButton(ActionButton(
449
+ backgroundColor = background,
450
+ textColor = textColor,
451
+ shape = shape,
452
+ ))
453
+ }
454
+ playerOptionBuilder.actionButtonOption(actionButtonOption.build())
455
+
326
456
  val ctaDelay = videoFeedPropsModel.videoPlayerConfiguration?.ctaDelay
327
457
  ctaDelay?.let { delay ->
328
458
  delay.value ?: return@let
@@ -368,7 +498,7 @@ object FWConfigUtil {
368
498
 
369
499
  val showPlaybackButton = videoFeedPropsModel.videoPlayerConfiguration?.showPlaybackButton
370
500
  showPlaybackButton?.let {
371
- playerOptionBuilder.showPlayPauseButtonInReplay(it)
501
+ playerOptionBuilder.showPlayPauseButtonInVideo(it)
372
502
  }
373
503
 
374
504
  val showBranding = videoFeedPropsModel.videoPlayerConfiguration?.showBranding
@@ -384,6 +514,7 @@ object FWConfigUtil {
384
514
  val buttonConfiguration = videoFeedPropsModel.videoPlayerConfiguration?.buttonConfiguration
385
515
  videoDetailsOptionBuilder.buttonIcon(getWidgetImage(context, buttonConfiguration?.videoDetailButton))
386
516
  closeButtonOptionBuilder.icon(getWidgetImage(context, buttonConfiguration?.closeButton))
517
+ pipButtonOptionBuilder.icon(getWidgetImage(context, buttonConfiguration?.pipButton))
387
518
  muteButtonOptionBuilder.muteIcon(getWidgetImage(context, buttonConfiguration?.muteButton))
388
519
  .unmuteIcon(getWidgetImage(context, buttonConfiguration?.unmuteButton))
389
520
  playbackButtonOptionBuilder.playIcon(getWidgetImage(context, buttonConfiguration?.playButton))
@@ -391,6 +522,7 @@ object FWConfigUtil {
391
522
 
392
523
  playerUiOptionBuilder.videoDetailsOption(videoDetailsOptionBuilder.build())
393
524
  .closeButtonOption(closeButtonOptionBuilder.build())
525
+ .pipButtonOption(pipButtonOptionBuilder.build())
394
526
  .muteButtonOption(muteButtonOptionBuilder.build())
395
527
  .playbackButtonOption(playbackButtonOptionBuilder.build())
396
528
  playerOptionBuilder.playerUiOption(playerUiOptionBuilder.build())
@@ -425,6 +557,14 @@ object FWConfigUtil {
425
557
  else -> {}
426
558
  }
427
559
  playerOptionBuilder.livestreamCountDownOption(countDownOptionBuilder.build())
560
+ videoFeedPropsModel.videoPlayerConfiguration?.enableAutoPlay?.let { enableAutoplayOnStoryblock ->
561
+ storyblockOptionBuilder.enableAutoPlay(enableAutoplayOnStoryblock)}
562
+ videoFeedPropsModel.videoPlayerConfiguration?.showFullScreenIcon?.let { showFullScreenIcon ->
563
+ storyblockOptionBuilder.showFullScreenIcon(showFullScreenIcon)}
564
+ videoFeedPropsModel.videoPlayerConfiguration?.enableAutoPause?.let { enableAutoPause ->
565
+ storyblockOptionBuilder.enableAutoPause(enableAutoPause)}
566
+
567
+ playerOptionBuilder.shareUrlCustomCallBack(FWGlobalDataUtil.customShareUrlCallback)
428
568
 
429
569
  return ViewOptions.Builder()
430
570
  .layoutOption(layoutOptionBuilder.build())
@@ -434,6 +574,11 @@ object FWConfigUtil {
434
574
  .adBadgeOption(adBadgeOptionBuilder.build())
435
575
  .ctaOption(ctaOptionBuilder.build())
436
576
  .adOption(adOptionBuilder.build())
577
+ .storyBlockOption(storyblockOptionBuilder.build())
578
+ }
579
+
580
+ private fun getDefaultStoryblockOptionBuilder(): StoryBlockOption.Builder {
581
+ return StoryBlockOption.Builder()
437
582
  }
438
583
 
439
584
  private fun getDefaultLayoutOptionBuilder(): LayoutOption.Builder {
@@ -460,6 +605,10 @@ object FWConfigUtil {
460
605
  return LivestreamCountDownOption.Builder()
461
606
  }
462
607
 
608
+ private fun getDefaultActionButtonOptionBuilder(): ActionButtonOption.Builder {
609
+ return ActionButtonOption.Builder()
610
+ }
611
+
463
612
  private fun getDefaultVideoDetailsOptionBuilder(): VideoDetailsOption.Builder {
464
613
  return VideoDetailsOption.Builder()
465
614
  }
@@ -468,6 +617,10 @@ object FWConfigUtil {
468
617
  return CloseButtonOption.Builder()
469
618
  }
470
619
 
620
+ private fun getDefaultPipButtonOptionBuilder(): PipButtonOption.Builder {
621
+ return PipButtonOption.Builder()
622
+ }
623
+
471
624
  private fun getDefaultMuteButtonOptionBuilder(): MuteButtonOption.Builder {
472
625
  return MuteButtonOption.Builder()
473
626
  }
@@ -1,5 +1,6 @@
1
1
  package com.fireworksdk.bridge.utils
2
2
 
3
+ import com.firework.analyticsevents.VideoInfo
3
4
  import com.fireworksdk.bridge.models.FWAdBadgeConfigModel
4
5
  import com.fireworksdk.bridge.models.FWSdkInitResultModel
5
6
  import com.fireworksdk.bridge.models.enums.FWSwitchLanguageBehavior
@@ -23,4 +24,9 @@ object FWGlobalDataUtil {
23
24
  var switchLanguageBehavior = FWSwitchLanguageBehavior.RestartingActivity
24
25
 
25
26
  var initCompletedListener: (() -> Unit)? = null
27
+
28
+ var customShareUrlCallbackEnabled: Boolean = false
29
+
30
+ var customShareUrlCallback: (suspend (String, VideoInfo) -> String)? = null
31
+
26
32
  }
@@ -1,6 +1,7 @@
1
1
  package com.fireworksdk.bridge.utils
2
2
 
3
3
  import com.firework.analyticsevents.VideoInfo
4
+ import com.firework.analyticsevents.VideoType
4
5
  import com.firework.analyticsevents.cta.CtaButtonClickAnalyticsEvent
5
6
  import com.firework.analyticsevents.player.PlayerLifecycleAnalyticsEvent
6
7
  import com.firework.analyticsevents.share.ShareButtonAnalyticsEvent
@@ -8,6 +9,27 @@ import com.fireworksdk.bridge.models.FWLiveStreamEventDetailsModel
8
9
  import com.fireworksdk.bridge.models.FWVideoPlaybackDetails
9
10
 
10
11
  object FWModelUtils {
12
+
13
+ val VideoInfo.internalVideoType: String
14
+ get() = when (this.videoType) {
15
+ is VideoType.ShortVideo -> "video"
16
+ is VideoType.Ad -> "ad"
17
+ is VideoType.Livestream.Idle -> "livestream"
18
+ is VideoType.Livestream.Live -> "livestream"
19
+ is VideoType.Livestream.Replay -> "livestream"
20
+ is VideoType.Livestream.Completed -> "livestream"
21
+ }
22
+
23
+ val VideoInfo.internalLiveStreamStatus: String?
24
+ get() = when (this.videoType) {
25
+ is VideoType.ShortVideo -> null
26
+ is VideoType.Ad -> null
27
+ is VideoType.Livestream.Idle -> "idle"
28
+ is VideoType.Livestream.Live -> "live"
29
+ is VideoType.Livestream.Replay -> "replay"
30
+ is VideoType.Livestream.Completed -> "completed"
31
+ }
32
+
11
33
  fun convertVideoInfo2PlaybackDetails(videoInfo: VideoInfo): FWVideoPlaybackDetails {
12
34
  return FWVideoPlaybackDetails(
13
35
  badge = videoInfo.badge,
@@ -18,6 +40,8 @@ object FWModelUtils {
18
40
  playerWidth = videoInfo.playerWidth,
19
41
  id = videoInfo.id,
20
42
  feedId = videoInfo.feedId,
43
+ videoType = videoInfo.internalVideoType,
44
+ liveStreamStatus = videoInfo.internalLiveStreamStatus,
21
45
  )
22
46
  }
23
47
 
@@ -25,6 +49,8 @@ object FWModelUtils {
25
49
  return FWLiveStreamEventDetailsModel(
26
50
  id = videoInfo.id,
27
51
  feedId = videoInfo.feedId,
52
+ videoType = videoInfo.internalVideoType,
53
+ liveStreamStatus = videoInfo.internalLiveStreamStatus,
28
54
  )
29
55
  }
30
56
 
@@ -39,6 +65,8 @@ object FWModelUtils {
39
65
  id = event.videoInfo.id,
40
66
  actionUrl = event.actionUrl,
41
67
  feedId = event.videoInfo.feedId,
68
+ videoType = event.videoInfo.internalVideoType,
69
+ liveStreamStatus = event.videoInfo.internalLiveStreamStatus,
42
70
  )
43
71
  }
44
72
 
@@ -53,6 +81,8 @@ object FWModelUtils {
53
81
  id = event.videoInfo?.id,
54
82
  progress = event.progress,
55
83
  feedId = event.videoInfo?.feedId,
84
+ videoType = event.videoInfo?.internalVideoType,
85
+ liveStreamStatus = event.videoInfo?.internalLiveStreamStatus,
56
86
  )
57
87
  }
58
88
 
@@ -66,6 +96,8 @@ object FWModelUtils {
66
96
  playerWidth = event.videoInfo.playerWidth,
67
97
  id = event.videoInfo.id,
68
98
  feedId = event.videoInfo.feedId,
99
+ videoType = event.videoInfo.internalVideoType,
100
+ liveStreamStatus = event.videoInfo.internalLiveStreamStatus,
69
101
  )
70
102
  }
71
103
 
@@ -20,8 +20,8 @@ public protocol StoryBlockViewDelegate: AnyObject {
20
20
  func storyBlock(_ view: StoryBlock, didFailToLoadFeed error: StoryBlockError)
21
21
  }
22
22
 
23
+ // swiftlint:disable type_body_length
23
24
  @objc
24
- // swiftlint:disable:next type_body_length
25
25
  public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPictureControllerDelegate {
26
26
  @objc public var sourceType: StoryBlockSourceType = .discover
27
27
  @objc public var channel: String = ""
@@ -118,6 +118,8 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPict
118
118
  return
119
119
  }
120
120
 
121
+ storyBlockVC.view.flipIfNeeded()
122
+
121
123
  onStoryBlockGetFeedId?(["feedId": storyBlockVC.feedID])
122
124
 
123
125
  self.storyBlockVC = storyBlockVC
@@ -210,8 +212,10 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPict
210
212
  if let playerStyle = config.playerStyle {
211
213
  switch playerStyle {
212
214
  case .full:
215
+ resultConfig.playerStyle = .fullBleed
213
216
  resultConfig.fullScreenPlayerView.playerStyle = .fullBleed
214
- default:
217
+ case .fit:
218
+ resultConfig.playerStyle = .fit
215
219
  resultConfig.fullScreenPlayerView.playerStyle = .fit
216
220
  }
217
221
  }
@@ -307,6 +311,7 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPict
307
311
 
308
312
  if let buttonConfiguration = config.buttonConfiguration {
309
313
  if let videoDetailButtonDisplay = buttonConfiguration.videoDetailButton?.getButtonDisplayConfiguration() {
314
+ resultConfig.videoDetailButtonDisplayConfiguration = videoDetailButtonDisplay
310
315
  resultConfig.fullScreenPlayerView.videoDetailButtonDisplayConfiguration = videoDetailButtonDisplay
311
316
  }
312
317
 
@@ -315,18 +320,22 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPict
315
320
  }
316
321
 
317
322
  if let muteButtonDisplay = buttonConfiguration.muteButton?.getButtonDisplayConfiguration() {
323
+ resultConfig.muteButton.muteDisplay = muteButtonDisplay
318
324
  resultConfig.fullScreenPlayerView.muteButton.muteDisplay = muteButtonDisplay
319
325
  }
320
326
 
321
327
  if let unmuteButtonDisplay = buttonConfiguration.unmuteButton?.getButtonDisplayConfiguration() {
328
+ resultConfig.muteButton.unmuteDisplay = unmuteButtonDisplay
322
329
  resultConfig.fullScreenPlayerView.muteButton.unmuteDisplay = unmuteButtonDisplay
323
330
  }
324
331
 
325
332
  if let playButtonDisplay = buttonConfiguration.playButton?.getButtonDisplayConfiguration() {
333
+ resultConfig.playbackButton.playDisplay = playButtonDisplay
326
334
  resultConfig.fullScreenPlayerView.playbackButton.playDisplay = playButtonDisplay
327
335
  }
328
336
 
329
337
  if let pauseButtonDisplay = buttonConfiguration.pauseButton?.getButtonDisplayConfiguration() {
338
+ resultConfig.playbackButton.pauseDisplay = pauseButtonDisplay
330
339
  resultConfig.fullScreenPlayerView.playbackButton.pauseDisplay = pauseButtonDisplay
331
340
  }
332
341
  }
@@ -417,3 +426,4 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPict
417
426
  completionHandler(true)
418
427
  }
419
428
  }
429
+ // swiftlint:enable type_body_length
@@ -110,7 +110,7 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate, PictureInPictur
110
110
  }
111
111
 
112
112
  private var videoFeedLayout: VideoFeedLayout {
113
- var resultLayout: VideoFeedLayout?
113
+ let resultLayout: VideoFeedLayout
114
114
  switch mode {
115
115
  case .row:
116
116
  let layout = VideoFeedHorizontalLayout()
@@ -139,25 +139,27 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate, PictureInPictur
139
139
  }
140
140
  if let contentPadding = config.contentPadding {
141
141
  if let top = contentPadding.top {
142
- resultLayout?.contentInsets.top = top
142
+ resultLayout.contentInsets.top = top
143
143
  }
144
144
  if let right = contentPadding.right {
145
- resultLayout?.contentInsets.right = right
145
+ resultLayout.contentInsets.right = right
146
146
  }
147
147
  if let bottom = contentPadding.bottom {
148
- resultLayout?.contentInsets.bottom = bottom
148
+ resultLayout.contentInsets.bottom = bottom
149
149
  }
150
150
  if let left = contentPadding.left {
151
- resultLayout?.contentInsets.left = left
151
+ resultLayout.contentInsets.left = left
152
152
  }
153
153
  }
154
154
 
155
155
  if let itemSpacing = config.itemSpacing {
156
- resultLayout?.itemSpacing = itemSpacing
156
+ resultLayout.itemSpacing = itemSpacing
157
157
  }
158
158
  }
159
159
 
160
- return resultLayout ?? VideoFeedHorizontalLayout()
160
+ resultLayout.ignoresSafeAreaLayoutGuide = true
161
+
162
+ return resultLayout
161
163
  }
162
164
 
163
165
  private var isInPip: Bool = false
@@ -194,19 +196,12 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate, PictureInPictur
194
196
  return
195
197
  }
196
198
 
199
+ feedVC.view.flipIfNeeded()
200
+
197
201
  onVideoFeedGetFeedId?(["feedId": feedVC.feedID])
198
202
 
199
- var viewConfiguration = convertToVideoFeedContentConfiguration()
200
- if viewConfiguration.itemView.autoplay.isEnabled {
201
- viewConfiguration.itemView.autoplay.isEnabled = false
202
- feedVC.viewConfiguration = viewConfiguration
203
- DispatchQueue.main.async {
204
- viewConfiguration.itemView.autoplay.isEnabled = true
205
- feedVC.viewConfiguration = viewConfiguration
206
- }
207
- } else {
208
- feedVC.viewConfiguration = viewConfiguration
209
- }
203
+ let viewConfiguration = convertToVideoFeedContentConfiguration()
204
+ feedVC.viewConfiguration = viewConfiguration
210
205
 
211
206
  feedVC.isPictureInPictureEnabled = playerViewConfig?.enablePictureInPicture ?? false
212
207
 
@@ -214,16 +209,6 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate, PictureInPictur
214
209
  feedVC.pictureInPictureDelegate = self
215
210
  self.feedVC = feedVC
216
211
 
217
- if self.mode != .row, let subView = feedVC.view.subviews.first {
218
- let constraints = feedVC.view.constraints
219
- for constraint in constraints {
220
- if (constraint.firstItem as? NSObject) == subView || (constraint.secondItem as? NSObject) == subView {
221
- constraint.isActive = false
222
- }
223
- }
224
- NSLayoutConstraint.activate(subView.constraints(equalTo: feedVC.view))
225
- }
226
-
227
212
  parentVC.attachChild(feedVC, to: self)
228
213
  }
229
214
 
@@ -413,7 +398,7 @@ extension VideoFeed {
413
398
  switch playerStyle {
414
399
  case .full:
415
400
  vpcConfig.playerStyle = .fullBleed
416
- default:
401
+ case .fit:
417
402
  vpcConfig.playerStyle = .fit
418
403
  }
419
404
  }
@@ -42,9 +42,4 @@ class VideoFeedManager: RCTViewManager, VideoFeedDelegate {
42
42
  view.onVideoFeedLoadFinished?(error.jsObject)
43
43
  }
44
44
  }
45
-
46
- // // MARK: - FireworkVideoFeedDelegate
47
- // func fireworkVideoDidTapVideoThumbnail(_ eventDetails: FeedEventDetails) {
48
- // view.onVideoFeedClick?(eventDetails.jsObject)
49
- // }
50
45
  }
@@ -7,7 +7,6 @@
7
7
  objects = {
8
8
 
9
9
  /* Begin PBXBuildFile section */
10
- 890B6B402BF5F9B4007E5762 /* NumberFormatter+AppLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 890B6B3F2BF5F9B4007E5762 /* NumberFormatter+AppLanguage.swift */; };
11
10
  891F4AF62A67E12800A9E8DA /* FWRNContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891F4AF52A67E12800A9E8DA /* FWRNContainerViewController.swift */; };
12
11
  891F4AF82A68DEDF00A9E8DA /* PushRNContainerParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891F4AF72A68DEDF00A9E8DA /* PushRNContainerParams.swift */; };
13
12
  891F4AFA2A68DF2B00A9E8DA /* RCTConvert+FWNavigatorModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 891F4AF92A68DF2B00A9E8DA /* RCTConvert+FWNavigatorModule.swift */; };
@@ -99,7 +98,6 @@
99
98
 
100
99
  /* Begin PBXFileReference section */
101
100
  1F6F718A2771B48100224AF3 /* FireworkSdk-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FireworkSdk-Bridging-Header.h"; sourceTree = "<group>"; };
102
- 890B6B3F2BF5F9B4007E5762 /* NumberFormatter+AppLanguage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NumberFormatter+AppLanguage.swift"; sourceTree = "<group>"; };
103
101
  891F4AF52A67E12800A9E8DA /* FWRNContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FWRNContainerViewController.swift; sourceTree = "<group>"; };
104
102
  891F4AF72A68DEDF00A9E8DA /* PushRNContainerParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushRNContainerParams.swift; sourceTree = "<group>"; };
105
103
  891F4AF92A68DF2B00A9E8DA /* RCTConvert+FWNavigatorModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RCTConvert+FWNavigatorModule.swift"; sourceTree = "<group>"; };
@@ -185,7 +183,6 @@
185
183
  898873122A0A8E7E0089CD1C /* Extensions */ = {
186
184
  isa = PBXGroup;
187
185
  children = (
188
- 890B6B3F2BF5F9B4007E5762 /* NumberFormatter+AppLanguage.swift */,
189
186
  89C105642BAD2C1D00E47CDD /* UIWindowScene+Swizzle.swift */,
190
187
  898873132A0A8E7E0089CD1C /* UIViewController+AttachChild.swift */,
191
188
  898873142A0A8E7E0089CD1C /* UIView+Constraints.swift */,
@@ -427,7 +424,6 @@
427
424
  8988735B2A0A8E7E0089CD1C /* FireworkSDKModule.m in Sources */,
428
425
  8988736A2A0A8E7E0089CD1C /* VideoFeedConfiguration.swift in Sources */,
429
426
  8975238D2817DEF80070EBB6 /* (null) in Sources */,
430
- 890B6B402BF5F9B4007E5762 /* NumberFormatter+AppLanguage.swift in Sources */,
431
427
  8975238C2817DEF80070EBB6 /* (null) in Sources */,
432
428
  8988736B2A0A8E7E0089CD1C /* VideoFeed.swift in Sources */,
433
429
  891F4AF62A67E12800A9E8DA /* FWRNContainerViewController.swift in Sources */,
@@ -19,7 +19,9 @@ enum FWEventName: String, CaseIterable {
19
19
  case appLanguageUpdated = "fw:app-language-updated" // emitted in JS side
20
20
  case nativeAppLanguageUpdated = "fw:native-app-language-updated" // emitted in native side
21
21
  case logMessage = "fw:log-message"
22
- case productInfoViewConfigurationUpdated = "fw:product-info-view-configuration-updated" // emitted in JS side
22
+ case productInfoViewConfigurationUpdated = "fw:product-info-view-configuration-updated" // emitted in JS side
23
+ case livestreamPlayerDesignVersionUpdated = "fw:livestream-player-design-version-updated" // emitted in JS side
24
+ case dataTrackingLevelUpdated = "fw:data-tracking-level-updated" // emitted in JS side
23
25
  }
24
26
 
25
27
  enum VideoPlaybackSubEventName: String {
@@ -126,4 +126,17 @@ extension RCTConvert {
126
126
  return nil
127
127
  }
128
128
  }
129
+
130
+ static func livestreamPlayerDesignVersion(
131
+ _ version: String
132
+ ) -> FireworkVideo.LivestreamPlayerDesignVersion? {
133
+ switch version {
134
+ case "v1":
135
+ return FireworkVideo.LivestreamPlayerDesignVersion.v1
136
+ case "v2":
137
+ return FireworkVideo.LivestreamPlayerDesignVersion.v2
138
+ default:
139
+ return nil
140
+ }
141
+ }
129
142
  }
@@ -128,6 +128,36 @@ extension FireworkSDKModule: FireworkVideoPlaybackDelegate {
128
128
  "info": videoPlayback.jsObject
129
129
  ])
130
130
  }
131
+
132
+ func fireworkVideoDidClose(_ videoPlayback: VideoPlaybackDetails) {
133
+ guard enableVideoPlayBackEvent else { return }
134
+ sendEvent(
135
+ withName: FWEventName.videoPlayback.rawValue,
136
+ body: [
137
+ "eventName": VideoPlaybackSubEventName.complete.rawValue,
138
+ "info": videoPlayback.jsObject
139
+ ])
140
+ }
141
+
142
+ func fireworkVideoDidAutomaticallyPause(_ videoPlayback: VideoPlaybackDetails) {
143
+ guard enableVideoPlayBackEvent else { return }
144
+ sendEvent(
145
+ withName: FWEventName.videoPlayback.rawValue,
146
+ body: [
147
+ "eventName": VideoPlaybackSubEventName.pause.rawValue,
148
+ "info": videoPlayback.jsObject
149
+ ])
150
+ }
151
+
152
+ func fireworkVideoDidAutomaticallyResume(_ videoPlayback: VideoPlaybackDetails) {
153
+ guard enableVideoPlayBackEvent else { return }
154
+ sendEvent(
155
+ withName: FWEventName.videoPlayback.rawValue,
156
+ body: [
157
+ "eventName": VideoPlaybackSubEventName.resume.rawValue,
158
+ "info": videoPlayback.jsObject
159
+ ])
160
+ }
131
161
  }
132
162
 
133
163
  extension FireworkSDKModule: FireworkVideoFeedDelegate {
@@ -138,10 +168,17 @@ extension FireworkSDKModule: FireworkVideoFeedDelegate {
138
168
  }
139
169
 
140
170
  extension FireworkSDKModule {
141
- @objc(setDataTrackingLevel:)
142
- func setDataTrackingLevel(_ level: String) {
143
- if let dataTrackingLevel = RCTConvert.dataTrackingLevel(level) {
144
- FireworkVideoSDK.dataTrackingLevel = dataTrackingLevel
145
- }
171
+ @objc(setDataTrackingLevel:resolver:rejecter:)
172
+ func setDataTrackingLevel(
173
+ _ level: String,
174
+ resolver: @escaping RCTPromiseResolveBlock,
175
+ rejecter: @escaping RCTPromiseRejectBlock
176
+ ) {
177
+ if let dataTrackingLevel = RCTConvert.dataTrackingLevel(level) {
178
+ FireworkVideoSDK.dataTrackingLevel = dataTrackingLevel
179
+ resolver(true)
180
+ } else {
181
+ resolver(false)
182
+ }
146
183
  }
147
184
  }
@@ -22,6 +22,7 @@ RCT_EXTERN_METHOD(trackPurchase:(NSDictionary *)parameters)
22
22
  RCT_EXTERN_METHOD(changeAppLanguage:(NSString * __nullable)language resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
23
23
  RCT_EXTERN_METHOD(pausePlayer:(NSString *)callbackId)
24
24
  RCT_EXTERN_METHOD(resumePlayer:(NSString *)callbackId)
25
- RCT_EXTERN_METHOD(setDataTrackingLevel:(NSString *)level)
25
+ RCT_EXTERN_METHOD(setDataTrackingLevel:(NSString *)level resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
26
+ RCT_EXTERN_METHOD(setLivestreamPlayerDesignVersion:(NSString *)version resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
26
27
 
27
28
  @end