react-native-firework-sdk 2.0.0 → 2.2.0-beta.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 (202) hide show
  1. package/FireworkVideoUI.xcframework/Info.plist +40 -0
  2. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  3. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Headers/FireworkVideoUI-Swift.h +280 -0
  4. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Headers/FireworkVideoUI.h +18 -0
  5. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
  6. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.abi.json +1327 -0
  7. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.private.swiftinterface +41 -0
  8. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  9. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.swiftinterface +41 -0
  10. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/module.modulemap +11 -0
  11. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  12. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Headers/FireworkVideoUI-Swift.h +556 -0
  13. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Headers/FireworkVideoUI.h +18 -0
  14. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
  15. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.abi.json +1327 -0
  16. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +41 -0
  17. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  18. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.swiftinterface +41 -0
  19. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.abi.json +1327 -0
  20. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +41 -0
  21. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  22. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +41 -0
  23. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/module.modulemap +11 -0
  24. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +245 -0
  25. package/README.md +1 -1
  26. package/android/build.gradle +5 -4
  27. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +6 -0
  28. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFragment.kt +129 -0
  29. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFrameLayout.kt +90 -0
  30. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdBadgeConfigModelDeserializer.kt +3 -3
  31. package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +5 -1
  32. package/android/src/main/java/com/fireworksdk/bridge/models/FWFontInfoModelDeserializer.kt +1 -1
  33. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +18 -5
  34. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +36 -8
  35. package/android/src/main/java/com/fireworksdk/bridge/models/FWSDKInitOptionsModelDeserializer.kt +3 -3
  36. package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResult.kt +17 -0
  37. package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResultDeserializer.kt +33 -0
  38. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedConfigModelDeserializer.kt +14 -12
  39. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
  40. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +11 -7
  41. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedSource.kt +1 -0
  42. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlaybackDetails.kt +8 -8
  43. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +1 -0
  44. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +19 -12
  45. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoShoppingProductDeserializer.kt +11 -11
  46. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +131 -45
  47. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +11 -3
  48. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +2 -2
  49. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWLiveStreamModule.kt +45 -4
  50. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +9 -1
  51. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +83 -50
  52. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +112 -36
  53. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +16 -6
  54. package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +26 -32
  55. package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +10 -0
  56. package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +48 -16
  57. package/android/src/main/res/layout/fw_bridge_story_block.xml +24 -0
  58. package/ios/Components/StoryBlock.swift +32 -2
  59. package/ios/Components/StoryBlockManager.m +33 -0
  60. package/ios/Components/StoryBlockManager.swift +4 -0
  61. package/ios/Components/VideoFeed.swift +16 -32
  62. package/ios/Components/VideoFeedManager.m +12 -6
  63. package/ios/Components/VideoFeedManager.swift +4 -0
  64. package/ios/Components/VideoPlayerConfiguration.swift +1 -0
  65. package/ios/FireworkSdk.xcodeproj/project.pbxproj +276 -212
  66. package/ios/FireworkVideoUI/FireworkVideoUI/FireworkVideoUI.docc/FireworkVideoUI.md +13 -0
  67. package/ios/FireworkVideoUI/FireworkVideoUI/FireworkVideoUI.h +18 -0
  68. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/AppLanguageManager.swift +147 -0
  69. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/Bundle+AppLanguage.swift +58 -0
  70. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/NumberFormatter+AppLanguage.swift +25 -0
  71. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/URLSession+AppLanguage.swift +69 -0
  72. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIImageView+AppLanguage.swift +91 -0
  73. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UILabel+AppLanguage.swift +98 -0
  74. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UITextField+AppLanguage.swift +97 -0
  75. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UITextView+AppLanguage.swift +97 -0
  76. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIView+AppLanguage.swift +38 -0
  77. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIViewController+AppLanguage.swift +46 -0
  78. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIWindow+AppLanguage.swift +26 -0
  79. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/LanguageUtil.swift +43 -0
  80. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/Foundation/NSObject+LayoutFlip.swift +42 -0
  81. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/CALayer+LayoutFlip.swift +160 -0
  82. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/UILabel+LayoutFlip.swift +35 -0
  83. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/UIView+LayoutFlip.swift +199 -0
  84. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/LayoutFlipManager.swift +59 -0
  85. package/ios/{Utils/DispatchQueue+FWOnce.swift → FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/Foundation/DispatchQueue+Once.swift} +5 -5
  86. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/Foundation/String+Base64.swift +18 -0
  87. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/UIKit/UIView+UIHierarchy.swift +46 -0
  88. package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Swizzle.swift +37 -0
  89. package/ios/FireworkVideoUI/FireworkVideoUI.xcodeproj/project.pbxproj +766 -0
  90. package/ios/FireworkVideoUI/FireworkVideoUI.xcworkspace/contents.xcworkspacedata +10 -0
  91. package/ios/FireworkVideoUI/FireworkVideoUI.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  92. package/ios/FireworkVideoUI/FireworkVideoUITests/FireworkVideoUITests.swift +37 -0
  93. package/ios/FireworkVideoUI/Podfile +15 -0
  94. package/ios/FireworkVideoUI/Podfile.lock +16 -0
  95. package/ios/Models/NativeToRN/FireworkEventName.swift +7 -1
  96. package/ios/Models/NativeToRN/FireworkSDK+Json.swift +5 -1
  97. package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
  98. package/ios/Models/RNToNative/RCTConvert+StoryBlock.swift +2 -1
  99. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +29 -1
  100. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +13 -101
  101. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +34 -16
  102. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
  103. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +48 -2
  104. package/ios/Modules/FireworkSDKModule/SDKInitOptions.swift +0 -1
  105. package/ios/Modules/LiveStream/LiveStreamModule.swift +1 -0
  106. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +7 -2
  107. package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
  108. package/ios/Modules/Shopping/ShoppingModule.m +2 -1
  109. package/ios/Modules/Shopping/ShoppingModule.swift +92 -34
  110. package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +22 -0
  111. package/ios/Support/MultiHostStreaming/Sources/MultiHostStreamingSDK.swift +17 -0
  112. package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +9 -8
  113. package/ios/Utils/FWSwizzleLoader.m +6 -1
  114. package/ios/Utils/FWSwizzleLoader.swift +13 -0
  115. package/ios/react_native_firework_sdk.h +1 -0
  116. package/ios/scripts/react_native_firework_sdk_pods.rb +27 -0
  117. package/lib/commonjs/FireworkSDK.js +55 -15
  118. package/lib/commonjs/FireworkSDK.js.map +1 -1
  119. package/lib/commonjs/LiveStream.js +2 -2
  120. package/lib/commonjs/LiveStream.js.map +1 -1
  121. package/lib/commonjs/VideoShopping.js +21 -38
  122. package/lib/commonjs/VideoShopping.js.map +1 -1
  123. package/lib/commonjs/components/StoryBlock.js +193 -128
  124. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  125. package/lib/commonjs/components/VideoFeed.js +17 -5
  126. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  127. package/lib/commonjs/index.js.map +1 -1
  128. package/lib/commonjs/models/FWEventName.js +3 -0
  129. package/lib/commonjs/models/FWEventName.js.map +1 -1
  130. package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
  131. package/lib/commonjs/models/VideoPlaybackEventName.js +3 -0
  132. package/lib/commonjs/models/VideoPlaybackEventName.js.map +1 -1
  133. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  134. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  135. package/lib/module/FireworkSDK.js +54 -15
  136. package/lib/module/FireworkSDK.js.map +1 -1
  137. package/lib/module/LiveStream.js +2 -2
  138. package/lib/module/LiveStream.js.map +1 -1
  139. package/lib/module/VideoShopping.js +21 -40
  140. package/lib/module/VideoShopping.js.map +1 -1
  141. package/lib/module/components/StoryBlock.js +183 -133
  142. package/lib/module/components/StoryBlock.js.map +1 -1
  143. package/lib/module/components/VideoFeed.js +16 -5
  144. package/lib/module/components/VideoFeed.js.map +1 -1
  145. package/lib/module/index.js.map +1 -1
  146. package/lib/module/models/FWEventName.js +3 -0
  147. package/lib/module/models/FWEventName.js.map +1 -1
  148. package/lib/module/models/ShoppingCTAResult.js +2 -0
  149. package/lib/module/models/VideoPlaybackEventName.js +3 -0
  150. package/lib/module/models/VideoPlaybackEventName.js.map +1 -1
  151. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  152. package/lib/module/modules/ShoppingModule.js.map +1 -1
  153. package/lib/typescript/FireworkSDK.d.ts +15 -8
  154. package/lib/typescript/LiveStream.d.ts +2 -2
  155. package/lib/typescript/VideoShopping.d.ts +10 -12
  156. package/lib/typescript/components/StoryBlock.d.ts +25 -24
  157. package/lib/typescript/components/VideoFeed.d.ts +7 -0
  158. package/lib/typescript/index.d.ts +6 -6
  159. package/lib/typescript/models/FWEventName.d.ts +3 -0
  160. package/lib/typescript/models/FWEvents.d.ts +14 -1
  161. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +12 -8
  162. package/lib/typescript/models/SDKInitOptions.d.ts +6 -1
  163. package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
  164. package/lib/typescript/models/StoryBlockSource.d.ts +1 -1
  165. package/lib/typescript/models/VideoFeedSource.d.ts +1 -1
  166. package/lib/typescript/models/VideoPlaybackDetails.d.ts +16 -0
  167. package/lib/typescript/models/VideoPlaybackEventName.d.ts +13 -1
  168. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +4 -0
  169. package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
  170. package/lib/typescript/modules/ShoppingModule.d.ts +2 -1
  171. package/package.json +8 -3
  172. package/react-native-firework-sdk.podspec +31 -24
  173. package/src/FireworkSDK.ts +54 -15
  174. package/src/LiveStream.ts +2 -2
  175. package/src/VideoShopping.ts +41 -54
  176. package/src/components/StoryBlock.tsx +210 -98
  177. package/src/components/VideoFeed.tsx +23 -4
  178. package/src/index.ts +15 -9
  179. package/src/models/FWEventName.ts +3 -0
  180. package/src/models/FWEvents.ts +14 -1
  181. package/src/models/ProductInfoViewConfiguration.ts +13 -8
  182. package/src/models/SDKInitOptions.ts +6 -1
  183. package/src/models/ShoppingCTAResult.ts +11 -0
  184. package/src/models/StoryBlockSource.ts +2 -1
  185. package/src/models/VideoFeedSource.ts +2 -1
  186. package/src/models/VideoPlaybackDetails.ts +16 -0
  187. package/src/models/VideoPlaybackEventName.ts +13 -1
  188. package/src/models/VideoPlayerConfiguration.ts +4 -0
  189. package/src/modules/FireworkSDKModule.ts +1 -2
  190. package/src/modules/ShoppingModule.ts +5 -5
  191. package/android/src/main/java/com/fireworksdk/bridge/constants/FWCommandConstant.kt +0 -6
  192. package/ios/Utils/FWSwizzleUtil.swift +0 -29
  193. package/ios/Utils/UIView+ParentViewController.swift +0 -21
  194. package/lib/commonjs/models/AddToCartResult.js +0 -2
  195. package/lib/module/models/AddToCartResult.js +0 -2
  196. package/lib/typescript/models/AddToCartResult.d.ts +0 -10
  197. package/src/models/AddToCartResult.ts +0 -10
  198. /package/ios/Utils/{String+Color.swift → Extensions/String+Color.swift} +0 -0
  199. /package/ios/Utils/{UIView+Constraints.swift → Extensions/UIView+Constraints.swift} +0 -0
  200. /package/ios/Utils/{UIViewController+AttachChild.swift → Extensions/UIViewController+AttachChild.swift} +0 -0
  201. /package/lib/commonjs/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
  202. /package/lib/module/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
@@ -5,13 +5,26 @@ import kotlinx.android.parcel.Parcelize
5
5
 
6
6
  @Parcelize
7
7
  data class FWProductInfoViewConfiguration(
8
- var addToCartButton: AddToCartButtonStyle? = null,
8
+ val ctaButton: CtaButtonConfiguration? = null,
9
+ val linkButton: LinkButtonConfiguration? = null,
9
10
  ) : Parcelable {
10
11
 
11
12
  @Parcelize
12
- data class AddToCartButtonStyle(
13
- var backgroundColor: String? = null,
14
- var textColor: String? = null,
15
- var fontSize: Int? = null,
13
+ data class CtaButtonConfiguration(
14
+ val text: TextValue? = null,
15
+ val backgroundColor: String? = null,
16
+ val textColor: String? = null,
17
+ val fontSize: Int? = null,
18
+ ) : Parcelable {
19
+
20
+ enum class TextValue(val rawValue: String) {
21
+ AddToCart("addToCart"),
22
+ ShopNow("shopNow"),
23
+ }
24
+ }
25
+
26
+ @Parcelize
27
+ data class LinkButtonConfiguration(
28
+ val isHidden: Boolean? = null,
16
29
  ) : Parcelable
17
30
  }
@@ -4,32 +4,60 @@ import org.json.JSONObject
4
4
 
5
5
  object FWProductInfoViewConfigurationDeserializer {
6
6
 
7
- private const val ADD_TO_CART_BUTTON_STYLE = "addToCartButton"
7
+ private const val CTA_BUTTON = "ctaButton"
8
+ private const val LINK_BUTTON = "linkButton"
8
9
 
10
+ private const val TEXT_KEY = "text"
9
11
  private const val BACKGROUND_COLOR_KEY = "backgroundColor"
10
12
  private const val TEXT_COLOR_KEY = "textColor"
11
13
  private const val FONT_SIZE_KEY = "fontSize"
12
14
 
15
+ private const val IS_HIDDEN_KEY = "isHidden"
16
+
13
17
  fun deserialize(responseJson: JSONObject?): FWProductInfoViewConfiguration? {
14
18
  responseJson ?: return null
15
19
 
16
- val addToCartButton = deserializeAddToCartButtonStyle(responseJson.optJSONObject(ADD_TO_CART_BUTTON_STYLE))
20
+ val ctaButtonConfiguration = deserializeCtaButtonConfiguration(responseJson.optJSONObject(CTA_BUTTON))
21
+ val linkButtonConfiguration = deserializeLinkButtonConfiguration(responseJson.optJSONObject(LINK_BUTTON))
17
22
 
18
23
  return FWProductInfoViewConfiguration(
19
- addToCartButton = addToCartButton
24
+ ctaButton = ctaButtonConfiguration,
25
+ linkButton = linkButtonConfiguration,
20
26
  )
21
27
  }
22
28
 
23
- private fun deserializeAddToCartButtonStyle(addToCartButtonStyleJson: JSONObject?): FWProductInfoViewConfiguration.AddToCartButtonStyle {
24
- val backgroundColor = addToCartButtonStyleJson?.optString(BACKGROUND_COLOR_KEY)
25
- val textColor = addToCartButtonStyleJson?.optString(TEXT_COLOR_KEY)
26
- val fontSize = addToCartButtonStyleJson?.optInt(FONT_SIZE_KEY)
29
+ private fun deserializeCtaButtonConfiguration(ctaButtonConfiguration: JSONObject?): FWProductInfoViewConfiguration.CtaButtonConfiguration {
30
+ ctaButtonConfiguration ?: return FWProductInfoViewConfiguration.CtaButtonConfiguration()
31
+
32
+ val textString = if (ctaButtonConfiguration.has(TEXT_KEY)) ctaButtonConfiguration.optString(TEXT_KEY) else null
33
+ val backgroundColor = if (ctaButtonConfiguration.has(BACKGROUND_COLOR_KEY)) ctaButtonConfiguration.optString(BACKGROUND_COLOR_KEY) else null
34
+ val textColor = if (ctaButtonConfiguration.has(TEXT_COLOR_KEY)) ctaButtonConfiguration.optString(TEXT_COLOR_KEY) else null
35
+ val fontSize = if (ctaButtonConfiguration.has(FONT_SIZE_KEY)) ctaButtonConfiguration.optInt(FONT_SIZE_KEY) else null
27
36
 
28
- return FWProductInfoViewConfiguration.AddToCartButtonStyle(
37
+ var text = FWProductInfoViewConfiguration.CtaButtonConfiguration.TextValue.AddToCart
38
+ when (textString) {
39
+ FWProductInfoViewConfiguration.CtaButtonConfiguration.TextValue.ShopNow.rawValue -> {
40
+ text = FWProductInfoViewConfiguration.CtaButtonConfiguration.TextValue.ShopNow
41
+ }
42
+ else -> {}
43
+ }
44
+
45
+ return FWProductInfoViewConfiguration.CtaButtonConfiguration(
46
+ text = text,
29
47
  backgroundColor = backgroundColor,
30
48
  textColor = textColor,
31
49
  fontSize = fontSize,
32
50
  )
33
51
  }
34
52
 
53
+ private fun deserializeLinkButtonConfiguration(linkButtonConfigJson: JSONObject?): FWProductInfoViewConfiguration.LinkButtonConfiguration {
54
+ linkButtonConfigJson ?: return FWProductInfoViewConfiguration.LinkButtonConfiguration()
55
+
56
+ val isHidden = if (linkButtonConfigJson.has(IS_HIDDEN_KEY)) linkButtonConfigJson.optBoolean(IS_HIDDEN_KEY) else null
57
+
58
+ return FWProductInfoViewConfiguration.LinkButtonConfiguration(
59
+ isHidden = isHidden,
60
+ )
61
+ }
62
+
35
63
  }
@@ -11,9 +11,9 @@ object FWSDKInitOptionsModelDeserializer {
11
11
  fun deserialize(responseJson: JSONObject?): FWSDKInitOptionsModel? {
12
12
  responseJson?: return null
13
13
 
14
- val userId = responseJson.optString(USER_ID_KEY)
15
- val shareBaseURL = responseJson.optString(SHARE_BASE_URL_KEY)
16
- val videoLaunchBehavior = responseJson.optString(VIDEO_LAUNCH_BEHAVIOR_KEY)
14
+ val userId = if (responseJson.has(USER_ID_KEY)) responseJson.optString(USER_ID_KEY) else null
15
+ val shareBaseURL = if (responseJson.has(SHARE_BASE_URL_KEY)) responseJson.optString(SHARE_BASE_URL_KEY) else null
16
+ val videoLaunchBehavior = if (responseJson.has(VIDEO_LAUNCH_BEHAVIOR_KEY)) responseJson.optString(VIDEO_LAUNCH_BEHAVIOR_KEY) else null
17
17
 
18
18
  return FWSDKInitOptionsModel(
19
19
  userId = userId,
@@ -0,0 +1,17 @@
1
+ package com.fireworksdk.bridge.models
2
+
3
+ import android.os.Parcelable
4
+ import kotlinx.android.parcel.Parcelize
5
+
6
+ @Parcelize
7
+ data class FWShoppingCtaResult(
8
+ val res: Res? = null,
9
+ val tips: String? = null,
10
+ ) : Parcelable {
11
+
12
+ enum class Res(val rawValue: String) {
13
+ Success("success"),
14
+ Fail("fail"),
15
+ Loading("loading"),
16
+ }
17
+ }
@@ -0,0 +1,33 @@
1
+ package com.fireworksdk.bridge.models
2
+
3
+ import org.json.JSONObject
4
+
5
+ object FWShoppingCtaResultDeserializer {
6
+
7
+ private const val RES_KEY = "res"
8
+ private const val TIPS_KEY = "tips"
9
+
10
+
11
+ fun deserialize(responseJson: JSONObject?): FWShoppingCtaResult? {
12
+ responseJson?: return null
13
+
14
+ val resString = if (responseJson.has(RES_KEY)) responseJson.optString(RES_KEY) else null
15
+ val tips = if (responseJson.has(TIPS_KEY)) responseJson.optString(TIPS_KEY) else null
16
+
17
+ var res = FWShoppingCtaResult.Res.Success
18
+ when (resString) {
19
+ FWShoppingCtaResult.Res.Fail.rawValue -> {
20
+ res = FWShoppingCtaResult.Res.Fail
21
+ }
22
+ FWShoppingCtaResult.Res.Loading.rawValue -> {
23
+ res = FWShoppingCtaResult.Res.Loading
24
+ }
25
+ else -> {}
26
+ }
27
+
28
+ return FWShoppingCtaResult(
29
+ res = res,
30
+ tips = tips,
31
+ )
32
+ }
33
+ }
@@ -23,14 +23,14 @@ object FWVideoFeedConfigModelDeserializer {
23
23
  fun deserialize(responseJson: JSONObject?): FWVideoFeedConfigModel? {
24
24
  responseJson?: return null
25
25
 
26
- val backgroundColor = responseJson.optString(BACKGROUND_COLOR_KEY)
27
- val cornerRadius = responseJson.optInt(CORNER_RADIUS_KEY)
28
- val title = deserializeTitle(responseJson.optJSONObject(TITLE_KEY))
29
- val titlePosition = responseJson.optString(TITLE_POSITION_KEY)
30
- val playIcon = deserializePlayIcon(responseJson.optJSONObject(PLAY_ICON_KEY))
31
- val showAdBadge = responseJson.optBoolean(SHOW_AD_BADGE_KEY)
32
- val enableAutoplay = responseJson.optBoolean(ENABLE_AUTOPLAY_KEY)
33
- val gridColumns = responseJson.optInt(GRID_COLUMNS_KEY)
26
+ val backgroundColor = if (responseJson.has(BACKGROUND_COLOR_KEY)) responseJson.optString(BACKGROUND_COLOR_KEY) else null
27
+ val cornerRadius = if (responseJson.has(CORNER_RADIUS_KEY)) responseJson.optInt(CORNER_RADIUS_KEY) else null
28
+ val title = if (responseJson.has(TITLE_KEY)) deserializeTitle(responseJson.optJSONObject(TITLE_KEY)) else null
29
+ val titlePosition = if (responseJson.has(TITLE_POSITION_KEY)) responseJson.optString(TITLE_POSITION_KEY) else null
30
+ val playIcon = if (responseJson.has(PLAY_ICON_KEY)) deserializePlayIcon(responseJson.optJSONObject(PLAY_ICON_KEY)) else null
31
+ val showAdBadge = if (responseJson.has(SHOW_AD_BADGE_KEY)) responseJson.optBoolean(SHOW_AD_BADGE_KEY) else null
32
+ val enableAutoplay = if (responseJson.has(ENABLE_AUTOPLAY_KEY)) responseJson.optBoolean(ENABLE_AUTOPLAY_KEY) else null
33
+ val gridColumns = if (responseJson.has(GRID_COLUMNS_KEY)) responseJson.optInt(GRID_COLUMNS_KEY) else null
34
34
 
35
35
  return FWVideoFeedConfigModel(
36
36
  backgroundColor = backgroundColor,
@@ -45,10 +45,12 @@ object FWVideoFeedConfigModelDeserializer {
45
45
  }
46
46
 
47
47
  private fun deserializeTitle(titleJson: JSONObject?): FWVideoFeedConfigModel.FWTitleModel {
48
- val hidden = titleJson?.optBoolean(HIDDEN_KEY)
49
- val textColor = titleJson?.optString(TEXT_COLOR_KEY)
50
- val fontSize = titleJson?.optInt(FONT_SIZE_KEY)
51
- val fontInfo = FWFontInfoModelDeserializer.deserialize(titleJson?.optJSONObject(FONT_INFO_KEY))
48
+ titleJson ?: return FWVideoFeedConfigModel.FWTitleModel()
49
+
50
+ val hidden = if (titleJson.has(HIDDEN_KEY)) titleJson.optBoolean(HIDDEN_KEY) else null
51
+ val textColor = if (titleJson.has(TEXT_COLOR_KEY)) titleJson.optString(TEXT_COLOR_KEY) else null
52
+ val fontSize = if (titleJson.has(FONT_SIZE_KEY)) titleJson.optInt(FONT_SIZE_KEY) else null
53
+ val fontInfo = FWFontInfoModelDeserializer.deserialize(titleJson.optJSONObject(FONT_INFO_KEY))
52
54
 
53
55
  return FWVideoFeedConfigModel.FWTitleModel(
54
56
  hidden = hidden,
@@ -10,6 +10,7 @@ data class FWVideoFeedPropsModel(
10
10
  val channel: String? = null,
11
11
  val playlist: String? = null,
12
12
  val playlistGroup: String? = null,
13
+ val hashtagFilterExpression: String? = null,
13
14
  val mode: String? = null,
14
15
  val enablePictureInPicture: Boolean? = null,
15
16
  val videoFeedConfiguration: FWVideoFeedConfigModel? = null,
@@ -8,6 +8,7 @@ object FWVideoFeedPropsModelDeserializer {
8
8
  private const val CHANNEL_KEY = "channel"
9
9
  private const val PLAYLIST_KEY = "playlist"
10
10
  private const val PLAYLIST_GROUP_KEY = "playlistGroup"
11
+ private const val HASHTAG_FILTER_EXPRESSION_KEY = "hashtagFilterExpression"
11
12
  private const val MODE_KEY = "mode"
12
13
  private const val ENABLE_PIP_KEY = "enablePictureInPicture"
13
14
 
@@ -18,12 +19,14 @@ object FWVideoFeedPropsModelDeserializer {
18
19
  fun deserialize(responseJson: JSONObject?): FWVideoFeedPropsModel? {
19
20
  responseJson ?: return null
20
21
 
21
- val source = responseJson.optString(SOURCE_KEY)
22
- val channel = responseJson.optString(CHANNEL_KEY)
23
- val playlist = responseJson.optString(PLAYLIST_KEY)
24
- val playlistGroup = responseJson.optString(PLAYLIST_GROUP_KEY)
25
- val mode = responseJson.optString(MODE_KEY)
26
- val enablePictureInPicture = responseJson.optBoolean(ENABLE_PIP_KEY)
22
+ val source = if (responseJson.has(SOURCE_KEY)) responseJson.optString(SOURCE_KEY) else null
23
+ val channel = if (responseJson.has(CHANNEL_KEY)) responseJson.optString(CHANNEL_KEY) else null
24
+ val playlist = if (responseJson.has(PLAYLIST_KEY)) responseJson.optString(PLAYLIST_KEY) else null
25
+ val playlistGroup = if (responseJson.has(PLAYLIST_GROUP_KEY)) responseJson.optString(PLAYLIST_GROUP_KEY) else null
26
+ val hashtagFilterExpression = if (responseJson.has(HASHTAG_FILTER_EXPRESSION_KEY)) responseJson.optString(
27
+ HASHTAG_FILTER_EXPRESSION_KEY) else null
28
+ val mode = if (responseJson.has(MODE_KEY)) responseJson.optString(MODE_KEY) else null
29
+ val enablePictureInPicture = if (responseJson.has(ENABLE_PIP_KEY)) responseJson.optBoolean(ENABLE_PIP_KEY) else null
27
30
 
28
31
  val videoFeedConfiguration = FWVideoFeedConfigModelDeserializer.deserialize(
29
32
  responseJson.optJSONObject(VIDEO_FEED_CONFIGURATION_KEY)
@@ -31,7 +34,7 @@ object FWVideoFeedPropsModelDeserializer {
31
34
  val videoPlayerConfiguration = FWVideoPlayerConfigModelDeserializer.deserialize(
32
35
  responseJson.optJSONObject(VIDEO_PLAYER_CONFIGURATION_KEY)
33
36
  )
34
- val dynamicContentParametersObject = responseJson.optJSONObject(DYNAMIC_CONTENT_PARAMETERS_KEY)
37
+ val dynamicContentParametersObject = if (responseJson.has(DYNAMIC_CONTENT_PARAMETERS_KEY)) responseJson.optJSONObject(DYNAMIC_CONTENT_PARAMETERS_KEY) else null
35
38
  var dynamicContentParameters: Map<String, List<String>>? = null
36
39
 
37
40
  val keys = dynamicContentParametersObject?.keys()
@@ -57,6 +60,7 @@ object FWVideoFeedPropsModelDeserializer {
57
60
  channel = channel,
58
61
  playlist = playlist,
59
62
  playlistGroup = playlistGroup,
63
+ hashtagFilterExpression = hashtagFilterExpression,
60
64
  mode = mode,
61
65
  enablePictureInPicture= enablePictureInPicture,
62
66
  videoFeedConfiguration = videoFeedConfiguration,
@@ -6,4 +6,5 @@ enum class FWVideoFeedSource(val rawValue: String) {
6
6
  Playlist("playlist"),
7
7
  DynamicContent("dynamicContent"),
8
8
  PlaylistGroup("playlistGroup"),
9
+ HashtagPlaylist("hashtagPlaylist"),
9
10
  }
@@ -5,12 +5,12 @@ import kotlinx.android.parcel.Parcelize
5
5
 
6
6
  @Parcelize
7
7
  data class FWVideoPlaybackDetails(
8
- val autoplay: Boolean?,
9
- val badge: String?,
10
- val caption: String?,
11
- val duration: Long?,
12
- val hasCta: Boolean?,
13
- val height: Int?,
14
- val width: Int?,
15
- val videoId: String?
8
+ val badge: String? = null,
9
+ val caption: String? = null,
10
+ val duration: Double? = null,
11
+ val hasCta: Boolean? = null,
12
+ val height: Int? = null,
13
+ val width: Int? = null,
14
+ val videoId: String? = null,
15
+ val progress: Double? = null,
16
16
  ) : Parcelable
@@ -15,6 +15,7 @@ data class FWVideoPlayerConfigModel(
15
15
  val showBranding: Boolean? = null,
16
16
  val ctaDelay: FWCtaDelayModel? = null,
17
17
  val ctaHighlightDelay: FWCtaDelayModel? = null,
18
+ val shareBaseUrl: String? = null,
18
19
  ) : Parcelable {
19
20
 
20
21
  @Parcelize
@@ -14,6 +14,7 @@ object FWVideoPlayerConfigModelDeserializer {
14
14
  private const val SHOW_BRANDING_KEY = "showBranding"
15
15
  private const val CTA_DELAY_KEY = "ctaDelay"
16
16
  private const val CTA_HIGHLIGHT_DELAY_KEY = "ctaHighlightDelay"
17
+ private const val SHARE_BASE_URL_KEY = "shareBaseURL"
17
18
 
18
19
  private const val BACKGROUND_COLOR_KEY = "backgroundColor"
19
20
  private const val FONT_SIZE_KEY = "fontSize"
@@ -25,16 +26,17 @@ object FWVideoPlayerConfigModelDeserializer {
25
26
  fun deserialize(responseJson: JSONObject?): FWVideoPlayerConfigModel? {
26
27
  responseJson ?: return null
27
28
 
28
- val playerStyle = responseJson.optString(PLAYER_STYLE_KEY)
29
- val videoCompleteAction = responseJson.optString(VIDEO_COMPLETE_ACTION_KEY)
30
- val showShareButton = responseJson.optBoolean(SHOW_SHARE_BUTTON_KEY)
29
+ val playerStyle = if (responseJson.has(PLAYER_STYLE_KEY)) responseJson.optString(PLAYER_STYLE_KEY) else null
30
+ val videoCompleteAction = if (responseJson.has(VIDEO_COMPLETE_ACTION_KEY)) responseJson.optString(VIDEO_COMPLETE_ACTION_KEY) else null
31
+ val showShareButton = if (responseJson.has(SHOW_SHARE_BUTTON_KEY)) responseJson.optBoolean(SHOW_SHARE_BUTTON_KEY) else null
31
32
  val ctaButtonStyle = deserializeCtaButtonStyle(responseJson.optJSONObject(CTA_BUTTON_STYLE_KEY))
32
- val showMuteButton = responseJson.optBoolean(SHOW_MUTE_BUTTON_KEY)
33
- val showPlaybackButton = responseJson.optBoolean(SHOW_PLAYBACK_BUTTON_KEY)
34
- val launchBehavior = responseJson.optString(LAUNCH_BEHAVIOR_KEY)
35
- val showBranding = responseJson.optBoolean(SHOW_BRANDING_KEY)
33
+ val showMuteButton = if (responseJson.has(SHOW_MUTE_BUTTON_KEY)) responseJson.optBoolean(SHOW_MUTE_BUTTON_KEY) else null
34
+ val showPlaybackButton = if (responseJson.has(SHOW_PLAYBACK_BUTTON_KEY)) responseJson.optBoolean(SHOW_PLAYBACK_BUTTON_KEY) else null
35
+ val launchBehavior = if (responseJson.has(LAUNCH_BEHAVIOR_KEY)) responseJson.optString(LAUNCH_BEHAVIOR_KEY) else null
36
+ val showBranding = if (responseJson.has(SHOW_BRANDING_KEY)) responseJson.optBoolean(SHOW_BRANDING_KEY) else null
36
37
  val ctaDelay = deserializeCtaDelay(responseJson.optJSONObject(CTA_DELAY_KEY))
37
38
  val ctaHighlightDelay = deserializeCtaDelay(responseJson.optJSONObject(CTA_HIGHLIGHT_DELAY_KEY))
39
+ val shareBaseUrl = if (responseJson.has(SHARE_BASE_URL_KEY)) responseJson.optString(SHARE_BASE_URL_KEY) else null
38
40
 
39
41
  return FWVideoPlayerConfigModel(
40
42
  playerStyle = playerStyle,
@@ -47,13 +49,16 @@ object FWVideoPlayerConfigModelDeserializer {
47
49
  showBranding = showBranding,
48
50
  ctaDelay = ctaDelay,
49
51
  ctaHighlightDelay = ctaHighlightDelay,
52
+ shareBaseUrl = shareBaseUrl,
50
53
  )
51
54
  }
52
55
 
53
56
  private fun deserializeCtaButtonStyle(ctaButtonStyleJson: JSONObject?): FWVideoPlayerConfigModel.FWCtaButtonStyleModel {
54
- val backgroundColor = ctaButtonStyleJson?.optString(BACKGROUND_COLOR_KEY)
55
- val fontSize = ctaButtonStyleJson?.optInt(FONT_SIZE_KEY)
56
- val textColor = ctaButtonStyleJson?.optString(TEXT_COLOR_KEY)
57
+ ctaButtonStyleJson ?: return FWVideoPlayerConfigModel.FWCtaButtonStyleModel()
58
+
59
+ val backgroundColor = if (ctaButtonStyleJson.has(BACKGROUND_COLOR_KEY)) ctaButtonStyleJson.optString(BACKGROUND_COLOR_KEY) else null
60
+ val fontSize = if (ctaButtonStyleJson.has(FONT_SIZE_KEY)) ctaButtonStyleJson.optInt(FONT_SIZE_KEY) else null
61
+ val textColor = if (ctaButtonStyleJson.has(TEXT_COLOR_KEY)) ctaButtonStyleJson.optString(TEXT_COLOR_KEY) else null
57
62
 
58
63
  return FWVideoPlayerConfigModel.FWCtaButtonStyleModel(
59
64
  backgroundColor = backgroundColor,
@@ -63,8 +68,10 @@ object FWVideoPlayerConfigModelDeserializer {
63
68
  }
64
69
 
65
70
  private fun deserializeCtaDelay(ctaDelayJson: JSONObject?): FWVideoPlayerConfigModel.FWCtaDelayModel {
66
- val type = ctaDelayJson?.optString(TYPE_KEY)
67
- val value = ctaDelayJson?.optDouble(VALUE_KEY)
71
+ ctaDelayJson ?: return FWVideoPlayerConfigModel.FWCtaDelayModel()
72
+
73
+ val type = if (ctaDelayJson.has(TYPE_KEY)) ctaDelayJson.optString(TYPE_KEY) else null
74
+ val value = if (ctaDelayJson.has(VALUE_KEY)) ctaDelayJson.optDouble(VALUE_KEY) else null
68
75
 
69
76
  return FWVideoPlayerConfigModel.FWCtaDelayModel(
70
77
  type = type,
@@ -35,9 +35,9 @@ object FWVideoShoppingProductDeserializer {
35
35
 
36
36
  fun deserialize(responseJson: JSONObject?): FWVideoShoppingProduct? {
37
37
  responseJson ?: return null
38
- val productId = responseJson.optString(PRODUCT_ID_KEY)
39
- val name = responseJson.optString(NAME_KEY)
40
- val description = responseJson.optString(DESCRIPTION_KEY)
38
+ val productId = if (responseJson.has(PRODUCT_ID_KEY)) responseJson.optString(PRODUCT_ID_KEY) else null
39
+ val name = if (responseJson.has(NAME_KEY)) responseJson.optString(NAME_KEY) else null
40
+ val description = if (responseJson.has(DESCRIPTION_KEY)) responseJson.optString(DESCRIPTION_KEY) else null
41
41
  val units = deserializeUnits(responseJson.optJSONArray(UNITS_KEY))
42
42
  val isAvailable = responseJson.optBoolean(IS_AVAILABLE_KEY, true)
43
43
 
@@ -63,11 +63,11 @@ object FWVideoShoppingProductDeserializer {
63
63
 
64
64
  private fun deserializeUnit(unitsJsonObject: JSONObject?): FWVideoShoppingProduct.FWVideoProductUnit? {
65
65
  unitsJsonObject ?: return null
66
- val unitId = unitsJsonObject.optString(UNIT_ID_KEY)
67
- val name = unitsJsonObject.optString(NAME_KEY)
66
+ val unitId = if (unitsJsonObject.has(UNIT_ID_KEY)) unitsJsonObject.optString(UNIT_ID_KEY) else null
67
+ val name = if (unitsJsonObject.has(NAME_KEY)) unitsJsonObject.optString(NAME_KEY) else null
68
68
  val price = deserializePrice(unitsJsonObject.optJSONObject(PRICE_KEY))
69
- val url = unitsJsonObject.optString(URL_KEY)
70
- val imageUrl = unitsJsonObject.optString(IMAGE_URL_KEY)
69
+ val url = if (unitsJsonObject.has(URL_KEY)) unitsJsonObject.optString(URL_KEY) else null
70
+ val imageUrl = if (unitsJsonObject.has(IMAGE_URL_KEY)) unitsJsonObject.optString(IMAGE_URL_KEY) else null
71
71
  val options = deserializeOptions(unitsJsonObject.optJSONArray(OPTIONS_KEY))
72
72
  val isAvailable = unitsJsonObject.optBoolean(IS_AVAILABLE_KEY, true)
73
73
 
@@ -85,8 +85,8 @@ object FWVideoShoppingProductDeserializer {
85
85
 
86
86
  private fun deserializePrice(priceJsonObject: JSONObject?): FWVideoShoppingProduct.FWVideoProductPrice? {
87
87
  priceJsonObject ?: return null
88
- val amount = priceJsonObject.optDouble(AMOUNT_KEY)
89
- val currencyCode = priceJsonObject.optString(CURRENCY_CODE_KEY)
88
+ val amount = if (priceJsonObject.has(AMOUNT_KEY)) priceJsonObject.optDouble(AMOUNT_KEY) else null
89
+ val currencyCode = if (priceJsonObject.has(CURRENCY_CODE_KEY)) priceJsonObject.optString(CURRENCY_CODE_KEY) else null
90
90
 
91
91
  return FWVideoShoppingProduct.FWVideoProductPrice(
92
92
  amount = amount,
@@ -108,8 +108,8 @@ object FWVideoShoppingProductDeserializer {
108
108
 
109
109
  private fun deserializeOption(optionJsonObject: JSONObject?): FWVideoShoppingProduct.FWVideoProductOption? {
110
110
  optionJsonObject ?: return null
111
- val name = optionJsonObject.optString(NAME_KEY)
112
- val value = optionJsonObject.optString(VALUE_KEY)
111
+ val name = if (optionJsonObject.has(NAME_KEY)) optionJsonObject.optString(NAME_KEY) else null
112
+ val value = if (optionJsonObject.has(VALUE_KEY)) optionJsonObject.optString(VALUE_KEY) else null
113
113
 
114
114
  return FWVideoShoppingProduct.FWVideoProductOption(
115
115
  name = name,