react-native-firework-sdk 1.3.0-beta.2 → 1.3.0

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 (50) hide show
  1. package/android/build.gradle +2 -2
  2. package/android/src/main/AndroidManifest.xml +2 -2
  3. package/android/src/main/java/com/fireworksdk/bridge/{reactnative/FWInitializationProvider.kt → FWInitializationProvider.kt} +1 -1
  4. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedConfigModel.kt +3 -1
  5. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +1 -0
  6. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoShoppingProduct.kt +1 -0
  7. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +5 -2
  8. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +1 -1
  9. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +44 -30
  10. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +1 -1
  11. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +5 -5
  12. package/android/src/main/java/com/fireworksdk/bridge/utils/FWVideoPlayerUtils.kt +18 -0
  13. package/ios/Components/VideoFeed.swift +95 -35
  14. package/ios/Components/VideoFeedConfiguration.swift +15 -3
  15. package/ios/Components/VideoPlayerConfiguration.swift +3 -2
  16. package/ios/Models/RNToNative/RCTConvert+FireworkSDKModule.swift +24 -4
  17. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +1 -1
  18. package/ios/Modules/Shopping/CartViewController.swift +22 -39
  19. package/ios/Modules/Shopping/Product.swift +1 -0
  20. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +1 -6
  21. package/ios/Modules/Shopping/ShoppingModule.m +1 -0
  22. package/ios/Modules/Shopping/ShoppingModule.swift +28 -16
  23. package/lib/commonjs/VideoShopping.js +25 -9
  24. package/lib/commonjs/VideoShopping.js.map +1 -1
  25. package/lib/commonjs/components/VideoFeed.js +28 -3
  26. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  27. package/lib/commonjs/index.js.map +1 -1
  28. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  29. package/lib/module/VideoShopping.js +24 -9
  30. package/lib/module/VideoShopping.js.map +1 -1
  31. package/lib/module/components/VideoFeed.js +28 -3
  32. package/lib/module/components/VideoFeed.js.map +1 -1
  33. package/lib/module/index.js.map +1 -1
  34. package/lib/module/modules/ShoppingModule.js.map +1 -1
  35. package/lib/typescript/VideoShopping.d.ts +15 -1
  36. package/lib/typescript/components/VideoFeed.d.ts +1 -0
  37. package/lib/typescript/index.d.ts +3 -3
  38. package/lib/typescript/models/ProductUnit.d.ts +12 -0
  39. package/lib/typescript/models/VideoFeedConfiguration.d.ts +33 -5
  40. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +5 -1
  41. package/lib/typescript/modules/ShoppingModule.d.ts +1 -0
  42. package/package.json +2 -6
  43. package/react-native-firework-sdk.podspec +1 -1
  44. package/src/VideoShopping.ts +30 -3
  45. package/src/components/VideoFeed.tsx +22 -1
  46. package/src/index.tsx +4 -1
  47. package/src/models/ProductUnit.ts +13 -0
  48. package/src/models/VideoFeedConfiguration.ts +34 -5
  49. package/src/models/VideoPlayerConfiguration.ts +5 -1
  50. package/src/modules/ShoppingModule.ts +1 -0
@@ -38,7 +38,7 @@ android {
38
38
  defaultConfig {
39
39
  minSdkVersion 21
40
40
  targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
41
- versionCode 100002
41
+ versionCode 1
42
42
  versionName "1.0.0"
43
43
  }
44
44
 
@@ -168,7 +168,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
168
168
  dependencies {
169
169
 
170
170
  // optional 1: firework sdk release verison
171
- def firework_sdk_version = 'v5.12.2'
171
+ def firework_sdk_version = 'v5.13.2'
172
172
  implementation "com.github.loopsocial:firework_sdk:$firework_sdk_version"
173
173
 
174
174
  // optional 2: firework sdk local version,
@@ -12,8 +12,8 @@
12
12
  android:theme="@style/Theme.AppCompat.Light.NoActionBar"
13
13
  />
14
14
  <provider
15
- android:authorities="com.fireworksdk.bridge.reactnative"
16
- android:name=".reactnative.FWInitializationProvider"
15
+ android:authorities="${applicationId}.fwBridgeProvider"
16
+ android:name="com.fireworksdk.bridge.FWInitializationProvider"
17
17
  android:exported="false"
18
18
  />
19
19
  <meta-data
@@ -1,4 +1,4 @@
1
- package com.fireworksdk.bridge.reactnative
1
+ package com.fireworksdk.bridge
2
2
 
3
3
  import android.app.Activity
4
4
  import android.app.Application
@@ -11,7 +11,9 @@ data class FWVideoFeedConfigModel(
11
11
  var titlePosition: String? = null,
12
12
  var playIcon: FWPlayIconModel? = null,
13
13
  var showAdBadge: Boolean? = null,
14
- var customLayoutName: String? = null
14
+ var customLayoutName: String? = null,
15
+ var enableAutoplay: Boolean? = null,
16
+ val gridColumns: Int? = null,
15
17
  ) : Parcelable {
16
18
 
17
19
  @Parcelize
@@ -12,6 +12,7 @@ data class FWVideoPlayerConfigModel(
12
12
  var showMuteButton: Boolean? = null,
13
13
  var showPlaybackButton: Boolean? = null,
14
14
  var launchBehavior: String? = null,
15
+ var showBranding: Boolean? = null,
15
16
  ) : Parcelable {
16
17
 
17
18
  @Parcelize
@@ -17,6 +17,7 @@ data class FWVideoShoppingProduct(
17
17
  val name: String?,
18
18
  val price: FWVideoProductPrice?,
19
19
  val url: String?,
20
+ val imageUrl: String?,
20
21
  val options: List<FWVideoProductOption>?
21
22
  ) : Parcelable
22
23
 
@@ -78,6 +78,9 @@ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
78
78
  FWLogUtils.d { "VideoContentStatus.ContentLoaded" }
79
79
  FWEventUtils.receiveVideoFeedLoadFinishedSuccessEvent(reactContext, videoFeedView.id)
80
80
  }
81
+ else -> {
82
+ FWLogUtils.d { "VideoContentStatus: $status" }
83
+ }
81
84
  }
82
85
  }
83
86
  })
@@ -86,13 +89,13 @@ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
86
89
  private fun addPlaylistGroupFeedListener(reactContext: ThemedReactContext, videoFeed: FWVideoFeed?) {
87
90
  val playlistGroupFeedView = videoFeed?.playlistGroupFeedView
88
91
  playlistGroupFeedView?.itemClickHandler = object : OnPlaylistGroupItemClickedListener {
89
- override fun onItemClicked(index: Int, id: String?): Boolean {
92
+ override fun onItemClicked(index: Int, title: String, id: String): Boolean {
90
93
  val fwVideoFeedItemDetailsModel = FWVideoFeedItemDetailsModel(
91
94
  index,
92
95
  id,
93
96
  0,
94
97
  videoFeed?.videoFeedPropsModel?.source,
95
- "",
98
+ title,
96
99
  videoFeed?.videoFeedPropsModel?.playlistGroup,
97
100
  videoFeed?.videoFeedPropsModel?.playlist,
98
101
  videoFeed?.videoFeedPropsModel?.channel,
@@ -2,7 +2,7 @@ package com.fireworksdk.bridge.reactnative.module
2
2
 
3
3
  import android.app.Activity
4
4
  import com.facebook.react.bridge.*
5
- import com.fireworksdk.bridge.reactnative.FWInitializationProvider
5
+ import com.fireworksdk.bridge.FWInitializationProvider
6
6
  import com.fireworksdk.bridge.reactnative.models.FWNavigatorInterface
7
7
  import com.fireworksdk.bridge.reactnative.utils.FWEventUtils
8
8
  import com.fireworksdk.bridge.utils.FWLogUtils
@@ -10,8 +10,7 @@ import com.fireworksdk.bridge.utils.FWLogUtils
10
10
  import com.google.gson.reflect.TypeToken
11
11
  import com.loopnow.fireworklibrary.baya.Baya
12
12
  import com.loopnow.fireworklibrary.baya.UpdateCartStatus
13
- import com.loopnow.fireworklibrary.data.Product
14
- import com.loopnow.fireworklibrary.utils.Util
13
+ import com.loopnow.fireworklibrary.data.ProductBuilder
15
14
 
16
15
 
17
16
  class FWVideoShoppingModule(
@@ -20,7 +19,7 @@ class FWVideoShoppingModule(
20
19
 
21
20
  private var addToCartHandler: Triple<Int, String, String>? = null
22
21
  private var cartClickHandler: Pair<Int, Activity>? = null
23
- private val updateProductHandler: HashMap<String, List<Product>> = HashMap()
22
+ private val updateProductHandler: HashMap<String, List<ProductBuilder>> = HashMap()
24
23
 
25
24
  @ReactMethod
26
25
  override fun init() {
@@ -45,37 +44,52 @@ class FWVideoShoppingModule(
45
44
  }
46
45
 
47
46
  val products = updateProductHandler[videoId] ?: return
48
-
49
- for (product in products) {
50
- for (videoShoppingProduct in videoShoppingProducts) {
51
- if (product.extId == videoShoppingProduct.productId) {
52
-
53
- if (videoShoppingProduct.name != null) {
54
- product.name = videoShoppingProduct.name
55
- }
56
-
57
- if (videoShoppingProduct.description != null) {
58
- product.description = videoShoppingProduct.description
59
- }
60
-
61
- if (videoShoppingProduct.units != null) {
62
- for (videoShoppingProductUnit in videoShoppingProduct.units) {
63
- for (productUnit in product.productUnits) {
64
- if (videoShoppingProductUnit.unitId.equals(productUnit.extId)) {
65
- productUnit.name = videoShoppingProductUnit.name
66
- productUnit.price = videoShoppingProductUnit.price?.amount
67
- productUnit.currencyCode = videoShoppingProductUnit.price?.currencyCode
68
- productUnit.priceLiteral = Util.getPriceLocaleFormatter(productUnit.price, productUnit.currencyCode)
69
- }
70
- }
47
+ val newProducts = products.map { product ->
48
+ val vps = videoShoppingProducts.filter { vp ->
49
+ vp.productId == product.externalId
50
+ }
51
+ if (vps.isNullOrEmpty()) {
52
+ product.copy()
53
+ } else {
54
+ val videoShoppingProduct = vps[0]
55
+
56
+ product.copy(
57
+ name = videoShoppingProduct.name ?: product.name,
58
+ description = videoShoppingProduct.description ?: product.description,
59
+ units = product.units?.map { productBuilderUnit ->
60
+ val vpUs = videoShoppingProduct.units?.filter { vpU ->
61
+ vpU.unitId == productBuilderUnit.externalId
62
+ }
63
+ if (vpUs.isNullOrEmpty()) {
64
+ productBuilderUnit.copy()
65
+ } else {
66
+ val videoShoppingProductUnit = vpUs[0]
67
+
68
+ productBuilderUnit.copy(
69
+ image = productBuilderUnit.image?.copy(
70
+ url = videoShoppingProductUnit.imageUrl ?: productBuilderUnit.image?.url,
71
+ ),
72
+ url = videoShoppingProductUnit.url ?: productBuilderUnit.url,
73
+ name = videoShoppingProductUnit.name ?: productBuilderUnit.name,
74
+ price = productBuilderUnit.price?.copy(
75
+ amount = videoShoppingProductUnit.price?.amount?.toString() ?: productBuilderUnit.price?.amount,
76
+ currencyCode = videoShoppingProductUnit.price?.currencyCode ?: productBuilderUnit.price?.currencyCode,
77
+ ),
78
+ options = videoShoppingProductUnit.options?.map {
79
+ ProductBuilder.ProductBuilderUnit.ProductBuilderUnitOption(
80
+ name = it.name,
81
+ value = it.value,
82
+ )
83
+ } ?: productBuilderUnit.options
84
+ )
71
85
  }
72
86
  }
73
-
74
- }
87
+ )
75
88
  }
76
89
  }
90
+
77
91
  UiThreadUtil.runOnUiThread {
78
- Baya.updateProductsComplete(videoId)
92
+ Baya.updateProductsComplete(videoId, newProducts)
79
93
  }
80
94
  updateProductHandler.remove(videoId)
81
95
  }
@@ -161,7 +175,7 @@ class FWVideoShoppingModule(
161
175
 
162
176
  private fun productListener() {
163
177
  Baya.productInterface = object: Baya.ProductInterface {
164
- override fun hydrateProducts(videoId: String, products: List<Product>) {
178
+ override fun hydrateProducts(videoId: String, products: List<ProductBuilder>) {
165
179
  FWLogUtils.d { "FWVideoShoppingModule hydrateProducts, videoId: $videoId" }
166
180
  if (videoId.isNullOrBlank() || products.isNullOrEmpty()) {
167
181
  return
@@ -11,7 +11,7 @@ import com.fireworksdk.bridge.utils.*
11
11
  import org.json.JSONObject
12
12
  import com.facebook.react.bridge.ReactMethod
13
13
  import com.fireworksdk.bridge.models.FWAdBadgeConfigModel
14
- import com.fireworksdk.bridge.reactnative.FWInitializationProvider
14
+ import com.fireworksdk.bridge.FWInitializationProvider
15
15
  import com.fireworksdk.bridge.reactnative.models.FireworkSDKInterface
16
16
  import com.fireworksdk.bridge.reactnative.pages.FWContainerActivity
17
17
  import com.fireworksdk.bridge.reactnative.utils.FWEventUtils
@@ -5,12 +5,12 @@ import com.facebook.react.bridge.*
5
5
  import com.facebook.react.modules.core.DeviceEventManagerModule
6
6
  import com.facebook.react.uimanager.events.RCTEventEmitter
7
7
  import com.fireworksdk.bridge.models.*
8
- import com.fireworksdk.bridge.reactnative.FWInitializationProvider
8
+ import com.fireworksdk.bridge.FWInitializationProvider
9
9
  import com.fireworksdk.bridge.reactnative.module.FireworkSDKModule
10
10
  import com.fireworksdk.bridge.reactnative.pages.FWContainerActivity
11
11
  import com.fireworksdk.bridge.utils.FWDateUtils
12
12
  import com.fireworksdk.bridge.utils.FWLogUtils
13
- import com.loopnow.fireworklibrary.data.Product
13
+ import com.loopnow.fireworklibrary.data.ProductBuilder
14
14
  import java.util.*
15
15
 
16
16
  object FWEventUtils {
@@ -19,7 +19,7 @@ object FWEventUtils {
19
19
  FWLogUtils.d { "FWNavigatorModule pushNativeContainer: $props" }
20
20
  val activity = FWInitializationProvider.INSTANCE.resumedActivity
21
21
 
22
- if (activity == null) {
22
+ if (activity == null || FireworkSDKModule.appComponentName.isNullOrBlank()) {
23
23
  promise?.resolve(false)
24
24
  return
25
25
  }
@@ -147,13 +147,13 @@ object FWEventUtils {
147
147
  sendEvent(reactContext, FWVideoShoppingEventName.ClickCartIcon.rawValue, eventMap)
148
148
  }
149
149
 
150
- fun sendUpdateProductsDetailsEvent(reactContext: ReactContext, products: List<Product>?, videoId: String?) {
150
+ fun sendUpdateProductsDetailsEvent(reactContext: ReactContext, products: List<ProductBuilder>?, videoId: String?) {
151
151
  val eventMap = Arguments.createMap()
152
152
 
153
153
  val productArray = Arguments.createArray()
154
154
  if (!products.isNullOrEmpty()) {
155
155
  for (product in products) {
156
- productArray.pushString(product.extId)
156
+ productArray.pushString(product.externalId)
157
157
  }
158
158
  }
159
159
 
@@ -65,6 +65,14 @@ object FWVideoPlayerUtils {
65
65
  }
66
66
  feedView?.setTitlePosition(titlePosition)
67
67
  VideoFeedProperties.displayAdLabel = config?.showAdBadge == true
68
+ feedView?.viewModel?.apply {
69
+ val columns = config?.gridColumns ?: 0
70
+ gridColumns = if (columns > 0) {
71
+ columns
72
+ } else {
73
+ 2
74
+ }
75
+ }
68
76
  }
69
77
 
70
78
  fun setVideoFeedConfig(context: Context, feedView: VideoFeedView?, config: FWVideoFeedConfigModel?) {
@@ -87,10 +95,20 @@ object FWVideoPlayerUtils {
87
95
  else -> FeedTitlePosition.ALIGN_BOTTOM
88
96
  }
89
97
  feedView?.setTitlePosition(titlePosition)
98
+ feedView?.setAutoPlayOnFeed(config?.enableAutoplay == true)
90
99
  VideoFeedProperties.displayAdLabel = config?.showAdBadge == true
100
+ feedView?.viewModel?.apply {
101
+ val columns = config?.gridColumns ?: 0
102
+ gridColumns = if (columns > 0) {
103
+ columns
104
+ } else {
105
+ 2
106
+ }
107
+ }
91
108
  }
92
109
 
93
110
  fun setVideoPlayerConfig(config: FWVideoPlayerConfigModel?) {
111
+ VideoPlayerProperties.branding = config?.showBranding != false
94
112
  VideoPlayerProperties.share = config?.showShareButton != false
95
113
  VideoPlayerProperties.loop = config?.videoCompleteAction != FWVideoPlayerConstant.FW_VIDEO_COMPLETE_ACTION_ADVANCE_TO_NEXT
96
114
  // VideoPlayerProperties.autoPlayOnComplete = config?.videoCompleteAction != FWVideoPlayerConstant.FW_VIDEO_COMPLETE_ACTION_LOOP
@@ -11,22 +11,7 @@ import FireworkVideo
11
11
 
12
12
  @objc
13
13
  public enum VideoFeedMode: Int {
14
- case row, colume, grid
15
-
16
- fileprivate var videoFeedLayout: VideoFeedLayout {
17
- switch self {
18
- case .row:
19
- return VideoFeedHorizontalLayout()
20
- case .colume:
21
- let layout = VideoFeedGridLayout()
22
- layout.numberOfColumns = 1
23
- return layout
24
- case .grid:
25
- let layout = VideoFeedGridLayout()
26
- layout.numberOfColumns = 2
27
- return layout
28
- }
29
- }
14
+ case row, column, grid
30
15
  }
31
16
 
32
17
  @objc
@@ -55,7 +40,8 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
55
40
  guard let feedVC = feedVC else {
56
41
  return
57
42
  }
58
- feedVC.viewConfiguration = convertToVideoFeedConentConfiguration()
43
+ feedVC.viewConfiguration = convertToVideoFeedContentConfiguration()
44
+ feedVC.layout = videoFeedLayout
59
45
  }
60
46
  }
61
47
  @objc public var playerViewConfig: VideoPlayerConfiguration? {
@@ -63,7 +49,7 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
63
49
  guard let feedVC = feedVC else {
64
50
  return
65
51
  }
66
- feedVC.viewConfiguration = convertToVideoFeedConentConfiguration()
52
+ feedVC.viewConfiguration = convertToVideoFeedContentConfiguration()
67
53
  }
68
54
  }
69
55
  @objc var onVideoFeedLoadFinished: RCTBubblingEventBlock?
@@ -87,6 +73,60 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
87
73
  return .dynamicContent(channelID: channel, parameters: parameters ?? [:])
88
74
  }
89
75
  }
76
+
77
+ private var videoFeedLayout: VideoFeedLayout {
78
+ var resultLayout: VideoFeedLayout?
79
+ switch mode {
80
+ case .row:
81
+ let layout = VideoFeedHorizontalLayout()
82
+ resultLayout = layout
83
+ break
84
+ case .column:
85
+ let layout = VideoFeedGridLayout()
86
+ layout.numberOfColumns = 1
87
+ resultLayout = layout
88
+ break
89
+ case .grid:
90
+ let layout = VideoFeedGridLayout()
91
+ if let gridColumns = feedViewConfig?.gridColumns,
92
+ gridColumns > 0 {
93
+ layout.numberOfColumns = gridColumns
94
+ } else {
95
+ layout.numberOfColumns = 2
96
+ }
97
+ resultLayout = layout
98
+ break
99
+ }
100
+ if let config = feedViewConfig {
101
+ if let aspectRatio = config.aspectRatio {
102
+ if let horizontalLayout = resultLayout as? VideoFeedHorizontalLayout {
103
+ horizontalLayout.itemWidthRatio = aspectRatio
104
+ } else if let gridLayout = resultLayout as? VideoFeedGridLayout {
105
+ gridLayout.itemWidthRatio = aspectRatio
106
+ }
107
+ }
108
+ if let contentPadding = config.contentPadding {
109
+ if let top = contentPadding.top {
110
+ resultLayout?.contentInsets.top = top
111
+ }
112
+ if let right = contentPadding.right {
113
+ resultLayout?.contentInsets.right = right
114
+ }
115
+ if let bottom = contentPadding.bottom {
116
+ resultLayout?.contentInsets.bottom = bottom
117
+ }
118
+ if let left = contentPadding.left {
119
+ resultLayout?.contentInsets.left = left
120
+ }
121
+ }
122
+
123
+ if let itemSpacing = config.itemSpacing {
124
+ resultLayout?.itemSpacing = itemSpacing
125
+ }
126
+ }
127
+
128
+ return resultLayout ?? VideoFeedHorizontalLayout()
129
+ }
90
130
 
91
131
  public override func layoutSubviews() {
92
132
  super.layoutSubviews()
@@ -103,11 +143,23 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
103
143
  }
104
144
 
105
145
  let feedVC = VideoFeedViewController(
106
- layout: mode.videoFeedLayout,
146
+ layout: videoFeedLayout,
107
147
  source: source
108
148
  )
109
-
110
- feedVC.viewConfiguration = convertToVideoFeedConentConfiguration()
149
+
150
+ var viewConfiguration = convertToVideoFeedContentConfiguration()
151
+ if viewConfiguration.itemView.autoplay.isEnabled {
152
+ viewConfiguration.itemView.autoplay.isEnabled = false
153
+ feedVC.viewConfiguration = viewConfiguration
154
+ DispatchQueue.main.async {
155
+ if feedVC.viewConfiguration == viewConfiguration {
156
+ viewConfiguration.itemView.autoplay.isEnabled = true
157
+ feedVC.viewConfiguration = viewConfiguration
158
+ }
159
+ }
160
+ } else {
161
+ feedVC.viewConfiguration = viewConfiguration
162
+ }
111
163
  feedVC.delegate = self
112
164
  self.feedVC = feedVC
113
165
 
@@ -157,14 +209,14 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
157
209
  }
158
210
 
159
211
  extension VideoFeed {
160
- private func convertToVideoFeedConentConfiguration() -> VideoFeedContentConfiguration {
212
+ private func convertToVideoFeedContentConfiguration() -> VideoFeedContentConfiguration {
161
213
  var videoConfig = VideoFeedContentConfiguration()
162
214
  //set default value so that behavior will the same with Android
163
215
  videoConfig.itemView.title.isHidden = false
164
216
  videoConfig.itemView.titleLayoutConfiguration.titlePosition = .nested
165
217
 
166
- let vfcConfig = VideoFeed.convertToVideoFeedItemConentConfiguration(feedViewConfig)
167
- let vpcConfig = VideoFeed.convertToVideoPlayerConentConfiguration(playerViewConfig)
218
+ let vfcConfig = VideoFeed.convertToVideoFeedItemContentConfiguration(feedViewConfig)
219
+ let vpcConfig = VideoFeed.convertToVideoPlayerContentConfiguration(playerViewConfig)
168
220
  if let vfcConfig = vfcConfig {
169
221
  videoConfig.itemView = vfcConfig
170
222
  }
@@ -188,7 +240,7 @@ extension VideoFeed {
188
240
  return videoConfig
189
241
  }
190
242
 
191
- private static func convertToVideoFeedItemConentConfiguration(_ config: VideoFeedConfiguration?) -> VideoFeedItemContentConfiguration? {
243
+ private static func convertToVideoFeedItemContentConfiguration(_ config: VideoFeedConfiguration?) -> VideoFeedItemContentConfiguration? {
192
244
  guard let config = config else {
193
245
  return nil
194
246
  }
@@ -199,7 +251,7 @@ extension VideoFeed {
199
251
  vfcConfig.titleLayoutConfiguration.titlePosition = .nested
200
252
 
201
253
  if let cornerRadius = config.cornerRadius {
202
- vfcConfig.cornerRadius = CGFloat(cornerRadius)
254
+ vfcConfig.cornerRadius = cornerRadius
203
255
  }
204
256
  if let title = config.title {
205
257
  if let hidden = title.hidden {
@@ -209,7 +261,7 @@ extension VideoFeed {
209
261
  vfcConfig.title.textColor = textcolor.uicolor()
210
262
  }
211
263
  if let fontSize = title.fontSize {
212
- vfcConfig.title.font = UIFont.systemFont(ofSize: CGFloat(fontSize))
264
+ vfcConfig.title.font = UIFont.systemFont(ofSize: fontSize)
213
265
  }
214
266
  }
215
267
  if let playIcon = config.playIcon {
@@ -217,7 +269,7 @@ extension VideoFeed {
217
269
  vfcConfig.playIcon.isHidden = hidden
218
270
  }
219
271
  if let iconWidth = playIcon.iconWidth {
220
- vfcConfig.playIcon.iconWidth = CGFloat(iconWidth)
272
+ vfcConfig.playIcon.iconWidth = iconWidth
221
273
  }
222
274
  }
223
275
  if let position = config.titlePosition {
@@ -234,11 +286,15 @@ extension VideoFeed {
234
286
  if let showAdBadge = config.showAdBadge {
235
287
  vfcConfig.sponsored.isHidden = !showAdBadge
236
288
  }
289
+
290
+ if let enableAutoplay = config.enableAutoplay {
291
+ vfcConfig.autoplay.isEnabled = enableAutoplay
292
+ }
237
293
 
238
294
  return vfcConfig
239
295
  }
240
296
 
241
- private static func convertToVideoPlayerConentConfiguration(_ config: VideoPlayerConfiguration?) -> VideoPlayerContentConfiguration? {
297
+ private static func convertToVideoPlayerContentConfiguration(_ config: VideoPlayerConfiguration?) -> VideoPlayerContentConfiguration? {
242
298
  guard let config = config else {
243
299
  return nil
244
300
  }
@@ -265,13 +321,13 @@ extension VideoFeed {
265
321
  }
266
322
  if let ctaButtonStyle = config.ctaButtonStyle {
267
323
  if let backgroundColor = ctaButtonStyle.backgroundColor {
268
- vpcConfig.ctaButton.backgroundColor = backgroundColor.uicolor()
324
+ vpcConfig.ctaButton.contentConfiguration.backgroundColor = backgroundColor.uicolor()
269
325
  }
270
326
  if let textcolor = ctaButtonStyle.textColor {
271
- vpcConfig.ctaButton.textColor = textcolor.uicolor()
327
+ vpcConfig.ctaButton.contentConfiguration.textColor = textcolor.uicolor()
272
328
  }
273
329
  if let fontSize = ctaButtonStyle.fontSize {
274
- vpcConfig.ctaButton.font = UIFont.systemFont(ofSize: CGFloat(fontSize))
330
+ vpcConfig.ctaButton.contentConfiguration.font = UIFont.systemFont(ofSize: fontSize)
275
331
  }
276
332
  }
277
333
  if let showPlaybackButton = config.showPlaybackButton {
@@ -279,9 +335,13 @@ extension VideoFeed {
279
335
  }
280
336
  if let showMuteButton = config.showMuteButton {
281
337
  vpcConfig.muteButton.isHidden = !showMuteButton
282
- if let launchBehavior = config.launchBehavior {
283
- vpcConfig.onFirstLaunch = launchBehavior.behavior()
284
- }
338
+ }
339
+ if let launchBehavior = config.launchBehavior {
340
+ vpcConfig.onFirstLaunch = launchBehavior.behavior()
341
+ }
342
+
343
+ if let showBranding = config.showBranding {
344
+ vpcConfig.videoDetail.fireworkAttribution.isHidden = !showBranding
285
345
  }
286
346
 
287
347
  return vpcConfig
@@ -10,22 +10,34 @@ import Foundation
10
10
  @objc
11
11
  public class VideoFeedConfiguration: NSObject, Codable {
12
12
  var backgroundColor: String?
13
- var cornerRadius: Int?
13
+ var cornerRadius: Double?
14
14
  var title: VideoFeedTitleConfiguration?
15
15
  var titlePosition: VideoFeedTitlePosition?
16
16
  var playIcon: VideoFeedPlayIconConfiguration?
17
17
  var showSponsored: Bool?
18
18
  var showAdBadge: Bool?
19
+ var aspectRatio: Double?
20
+ var contentPadding: VideoFeedContentPadding?;
21
+ var itemSpacing: Double?
22
+ var enableAutoplay: Bool?
23
+ var gridColumns: Int?
19
24
 
20
25
  class VideoFeedTitleConfiguration: NSObject, Codable {
21
26
  public var hidden: Bool?
22
27
  public var textColor: String?
23
- public var fontSize: Int?
28
+ public var fontSize: Double?
24
29
  }
25
30
 
26
31
  class VideoFeedPlayIconConfiguration: NSObject, Codable {
27
32
  public var hidden: Bool?
28
- public var iconWidth: Int?
33
+ public var iconWidth: Double?
34
+ }
35
+
36
+ class VideoFeedContentPadding: NSObject, Codable {
37
+ public var top: Double?
38
+ public var right: Double?
39
+ public var bottom: Double?
40
+ public var left: Double?
29
41
  }
30
42
 
31
43
  enum VideoFeedTitlePosition: String, Codable {
@@ -16,7 +16,8 @@ public class VideoPlayerConfiguration: NSObject, Codable {
16
16
  var showPlaybackButton: Bool?
17
17
  var showMuteButton: Bool?
18
18
  var launchBehavior: VideoLaunchBehavior?
19
-
19
+ var showBranding: Bool?
20
+
20
21
  public enum VideoPlayerStyle: String, Codable {
21
22
  case full, fit
22
23
  }
@@ -28,7 +29,7 @@ public class VideoPlayerConfiguration: NSObject, Codable {
28
29
  public class VideoPlayerCTAStyle: NSObject, Codable {
29
30
  var backgroundColor: String?
30
31
  var textColor: String?
31
- var fontSize: Int?
32
+ var fontSize: Double?
32
33
  }
33
34
 
34
35
  public enum VideoLaunchBehavior: String, Codable {
@@ -16,14 +16,34 @@ extension RCTConvert {
16
16
  if let style = videoPlayerStyle(config["playerStyle"] as? String) {
17
17
  finalConfig.playerStyle = style
18
18
  }
19
+
19
20
  if let action = videoCompleteAction(config["videoCompleteAction"] as? String) {
20
21
  finalConfig.videoCompleteAction = action
21
22
  }
23
+
22
24
  if let showShareButton = config["showShareButton"] as? Bool {
23
- finalConfig.shareButton.isHidden = showShareButton
25
+ finalConfig.shareButton.isHidden = !showShareButton
24
26
  }
27
+
25
28
  if let ctaStyle = ctaButtonStyle(config["ctaButtonStyle"] as? Dictionary) {
26
- finalConfig.ctaButton = ctaStyle
29
+ finalConfig.ctaButton.contentConfiguration = ctaStyle
30
+ }
31
+
32
+ if let showPlaybackButton = config["showPlaybackButton"] as? Bool {
33
+ finalConfig.playbackButton.isHidden = !showPlaybackButton
34
+ }
35
+
36
+ if let showMuteButton = config["showMuteButton"] as? Bool {
37
+ finalConfig.muteButton.isHidden = !showMuteButton
38
+ }
39
+
40
+ if let launchBehaviorString = config["launchBehavior"] as? String,
41
+ let launchBehavior = VideoPlayerConfiguration.VideoLaunchBehavior(rawValue: launchBehaviorString) {
42
+ finalConfig.onFirstLaunch = launchBehavior.behavior()
43
+ }
44
+
45
+ if let showBranding = config["showBranding"] as? Bool {
46
+ finalConfig.videoDetail.fireworkAttribution.isHidden = !showBranding
27
47
  }
28
48
 
29
49
  return finalConfig
@@ -62,8 +82,8 @@ extension RCTConvert {
62
82
  if let textColor = rStyle["textColor"] as? String {
63
83
  btnContentConfig.textColor = textColor.uicolor()
64
84
  }
65
- if let fontSize = rStyle["fontSize"] as? Float {
66
- btnContentConfig.font = UIFont.systemFont(ofSize: CGFloat(fontSize))
85
+ if let fontSize = rStyle["fontSize"] as? Double {
86
+ btnContentConfig.font = UIFont.systemFont(ofSize: fontSize)
67
87
  }
68
88
 
69
89
  return btnContentConfig
@@ -20,7 +20,7 @@ extension VideFeedSourceType {
20
20
  extension VideoFeedMode {
21
21
  static var feedModeMapper: [String: VideoFeedMode] {
22
22
  ["row": .row,
23
- "column": .colume,
23
+ "column": .column,
24
24
  "grid": .grid]
25
25
  }
26
26
  }