react-native-firework-sdk 1.0.0-beta

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 (190) hide show
  1. package/README.md +39 -0
  2. package/android/build.gradle +193 -0
  3. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  4. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/gradlew +185 -0
  7. package/android/gradlew.bat +89 -0
  8. package/android/publish.gradle +65 -0
  9. package/android/src/main/AndroidManifest.xml +16 -0
  10. package/android/src/main/java/com/reactnativefireworksdk/FireworkSDKPackage.kt +20 -0
  11. package/android/src/main/java/com/reactnativefireworksdk/components/videofeed/FWVideoFeed.kt +123 -0
  12. package/android/src/main/java/com/reactnativefireworksdk/constants/FWCommandConstant.kt +6 -0
  13. package/android/src/main/java/com/reactnativefireworksdk/constants/FWVideoPlayerConstant.kt +20 -0
  14. package/android/src/main/java/com/reactnativefireworksdk/manager/FWVideoFeedManager.kt +88 -0
  15. package/android/src/main/java/com/reactnativefireworksdk/models/FWEventName.kt +35 -0
  16. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedConfigModel.kt +27 -0
  17. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedItemDetailsModel.kt +11 -0
  18. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedMode.kt +7 -0
  19. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedSource.kt +7 -0
  20. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedTitlePosition.kt +7 -0
  21. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoPlaybackDetails.kt +19 -0
  22. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoPlayerConfigModel.kt +20 -0
  23. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoShoppingInterface.kt +13 -0
  24. package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoShoppingProduct.kt +34 -0
  25. package/android/src/main/java/com/reactnativefireworksdk/models/FireworkSDKInterface.kt +12 -0
  26. package/android/src/main/java/com/reactnativefireworksdk/module/FWVideoShoppingModule.kt +190 -0
  27. package/android/src/main/java/com/reactnativefireworksdk/module/FireworkSDKModule.kt +248 -0
  28. package/android/src/main/java/com/reactnativefireworksdk/pages/FWVideoShoppingCartActivity.kt +43 -0
  29. package/android/src/main/java/com/reactnativefireworksdk/utils/FWEventUtils.kt +127 -0
  30. package/android/src/main/java/com/reactnativefireworksdk/utils/FWJsonUtils.kt +57 -0
  31. package/android/src/main/java/com/reactnativefireworksdk/utils/FWLogUtils.kt +147 -0
  32. package/android/src/main/java/com/reactnativefireworksdk/utils/FWUrlUtils.kt +68 -0
  33. package/android/src/main/java/com/reactnativefireworksdk/utils/FWVideoPlayerUtils.kt +18 -0
  34. package/android/src/main/res/layout/fwrn_fragment_shoppingcart.xml +8 -0
  35. package/android/src/main/res/layout/fwrn_fragment_videofeed.xml +20 -0
  36. package/android/src/main/res/values/styles.xml +43 -0
  37. package/ios/Component/VideoFeed.swift +262 -0
  38. package/ios/Component/VideoFeedConfiguration.swift +32 -0
  39. package/ios/Component/VideoFeedManager.m +51 -0
  40. package/ios/Component/VideoFeedManager.swift +40 -0
  41. package/ios/Component/VideoPlayerConfiguration.swift +30 -0
  42. package/ios/FireworkSdk-Bridging-Header.h +6 -0
  43. package/ios/FireworkSdk.xcodeproj/project.pbxproj +291 -0
  44. package/ios/Models/FireworkJsEvent.swift +34 -0
  45. package/ios/Models/FireworkSDK+JsModel.swift +62 -0
  46. package/ios/Models/RCTConvert+FireworkSDKModule.swift +91 -0
  47. package/ios/Models/RCTConvert+Shopping.swift +49 -0
  48. package/ios/Models/RCTConvert+VideoFeed.swift +69 -0
  49. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+CTA.swift +17 -0
  50. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +74 -0
  51. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +19 -0
  52. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +106 -0
  53. package/ios/Modules/FireworkSDKModule/MobileADConfiguration.swift +17 -0
  54. package/ios/Modules/Shopping/CartViewController.swift +98 -0
  55. package/ios/Modules/Shopping/Product.swift +33 -0
  56. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +24 -0
  57. package/ios/Modules/Shopping/ShoppingModule.m +19 -0
  58. package/ios/Modules/Shopping/ShoppingModule.swift +214 -0
  59. package/ios/Utils/String+Color.swift +38 -0
  60. package/ios/Utils/UIView+Constraints.swift +91 -0
  61. package/ios/Utils/UIView+ParentViewController.swift +21 -0
  62. package/ios/Utils/UIViewController+AttachChild.swift +69 -0
  63. package/lib/commonjs/FireworkSDK.js +171 -0
  64. package/lib/commonjs/FireworkSDK.js.map +1 -0
  65. package/lib/commonjs/VideoShopping.js +146 -0
  66. package/lib/commonjs/VideoShopping.js.map +1 -0
  67. package/lib/commonjs/components/CartContainer.js +35 -0
  68. package/lib/commonjs/components/CartContainer.js.map +1 -0
  69. package/lib/commonjs/components/FWVideoFeed.js +18 -0
  70. package/lib/commonjs/components/FWVideoFeed.js.map +1 -0
  71. package/lib/commonjs/components/VideoFeed.js +82 -0
  72. package/lib/commonjs/components/VideoFeed.js.map +1 -0
  73. package/lib/commonjs/constants/FWErrorMessage.js +15 -0
  74. package/lib/commonjs/constants/FWErrorMessage.js.map +1 -0
  75. package/lib/commonjs/index.js +44 -0
  76. package/lib/commonjs/index.js.map +1 -0
  77. package/lib/commonjs/models/ADConfig.js +2 -0
  78. package/lib/commonjs/models/ADConfig.js.map +1 -0
  79. package/lib/commonjs/models/AddToCartResult.js +2 -0
  80. package/lib/commonjs/models/AddToCartResult.js.map +1 -0
  81. package/lib/commonjs/models/FWError.js +2 -0
  82. package/lib/commonjs/models/FWError.js.map +1 -0
  83. package/lib/commonjs/models/FWEvents.js +20 -0
  84. package/lib/commonjs/models/FWEvents.js.map +1 -0
  85. package/lib/commonjs/models/FeedItemDetails.js +2 -0
  86. package/lib/commonjs/models/FeedItemDetails.js.map +1 -0
  87. package/lib/commonjs/models/Product.js +2 -0
  88. package/lib/commonjs/models/Product.js.map +1 -0
  89. package/lib/commonjs/models/ProductInfoViewConfiguration.js +2 -0
  90. package/lib/commonjs/models/ProductInfoViewConfiguration.js.map +1 -0
  91. package/lib/commonjs/models/ProductUnit.js +2 -0
  92. package/lib/commonjs/models/ProductUnit.js.map +1 -0
  93. package/lib/commonjs/models/VideoFeedConfiguration.js +2 -0
  94. package/lib/commonjs/models/VideoFeedConfiguration.js.map +1 -0
  95. package/lib/commonjs/models/VideoPlaybackDetails.js +2 -0
  96. package/lib/commonjs/models/VideoPlaybackDetails.js.map +1 -0
  97. package/lib/commonjs/models/VideoPlaybackEventName.js +23 -0
  98. package/lib/commonjs/models/VideoPlaybackEventName.js.map +1 -0
  99. package/lib/commonjs/models/VideoPlayerConfiguration.js +2 -0
  100. package/lib/commonjs/models/VideoPlayerConfiguration.js.map +1 -0
  101. package/lib/commonjs/modules/FireworkSDKModule.js +20 -0
  102. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -0
  103. package/lib/commonjs/modules/ShoppingModule.js +20 -0
  104. package/lib/commonjs/modules/ShoppingModule.js.map +1 -0
  105. package/lib/module/FireworkSDK.js +153 -0
  106. package/lib/module/FireworkSDK.js.map +1 -0
  107. package/lib/module/VideoShopping.js +134 -0
  108. package/lib/module/VideoShopping.js.map +1 -0
  109. package/lib/module/components/CartContainer.js +18 -0
  110. package/lib/module/components/CartContainer.js.map +1 -0
  111. package/lib/module/components/FWVideoFeed.js +8 -0
  112. package/lib/module/components/FWVideoFeed.js.map +1 -0
  113. package/lib/module/components/VideoFeed.js +66 -0
  114. package/lib/module/components/VideoFeed.js.map +1 -0
  115. package/lib/module/constants/FWErrorMessage.js +7 -0
  116. package/lib/module/constants/FWErrorMessage.js.map +1 -0
  117. package/lib/module/index.js +10 -0
  118. package/lib/module/index.js.map +1 -0
  119. package/lib/module/models/ADConfig.js +2 -0
  120. package/lib/module/models/ADConfig.js.map +1 -0
  121. package/lib/module/models/AddToCartResult.js +2 -0
  122. package/lib/module/models/AddToCartResult.js.map +1 -0
  123. package/lib/module/models/FWError.js +2 -0
  124. package/lib/module/models/FWError.js.map +1 -0
  125. package/lib/module/models/FWEvents.js +13 -0
  126. package/lib/module/models/FWEvents.js.map +1 -0
  127. package/lib/module/models/FeedItemDetails.js +2 -0
  128. package/lib/module/models/FeedItemDetails.js.map +1 -0
  129. package/lib/module/models/Product.js +2 -0
  130. package/lib/module/models/Product.js.map +1 -0
  131. package/lib/module/models/ProductInfoViewConfiguration.js +2 -0
  132. package/lib/module/models/ProductInfoViewConfiguration.js.map +1 -0
  133. package/lib/module/models/ProductUnit.js +2 -0
  134. package/lib/module/models/ProductUnit.js.map +1 -0
  135. package/lib/module/models/VideoFeedConfiguration.js +2 -0
  136. package/lib/module/models/VideoFeedConfiguration.js.map +1 -0
  137. package/lib/module/models/VideoPlaybackDetails.js +2 -0
  138. package/lib/module/models/VideoPlaybackDetails.js.map +1 -0
  139. package/lib/module/models/VideoPlaybackEventName.js +16 -0
  140. package/lib/module/models/VideoPlaybackEventName.js.map +1 -0
  141. package/lib/module/models/VideoPlayerConfiguration.js +2 -0
  142. package/lib/module/models/VideoPlayerConfiguration.js.map +1 -0
  143. package/lib/module/modules/FireworkSDKModule.js +10 -0
  144. package/lib/module/modules/FireworkSDKModule.js.map +1 -0
  145. package/lib/module/modules/ShoppingModule.js +10 -0
  146. package/lib/module/modules/ShoppingModule.js.map +1 -0
  147. package/lib/typescript/FireworkSDK.d.ts +74 -0
  148. package/lib/typescript/VideoShopping.d.ts +54 -0
  149. package/lib/typescript/components/CartContainer.d.ts +3 -0
  150. package/lib/typescript/components/FWVideoFeed.d.ts +2 -0
  151. package/lib/typescript/components/VideoFeed.d.ts +53 -0
  152. package/lib/typescript/constants/FWErrorMessage.d.ts +2 -0
  153. package/lib/typescript/index.d.ts +25 -0
  154. package/lib/typescript/models/ADConfig.d.ts +10 -0
  155. package/lib/typescript/models/AddToCartResult.d.ts +10 -0
  156. package/lib/typescript/models/FWError.d.ts +10 -0
  157. package/lib/typescript/models/FWEvents.d.ts +55 -0
  158. package/lib/typescript/models/FeedItemDetails.d.ts +14 -0
  159. package/lib/typescript/models/Product.d.ts +19 -0
  160. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +18 -0
  161. package/lib/typescript/models/ProductUnit.d.ts +22 -0
  162. package/lib/typescript/models/VideoFeedConfiguration.d.ts +32 -0
  163. package/lib/typescript/models/VideoPlaybackDetails.d.ts +31 -0
  164. package/lib/typescript/models/VideoPlaybackEventName.d.ts +39 -0
  165. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +25 -0
  166. package/lib/typescript/modules/FireworkSDKModule.d.ts +12 -0
  167. package/lib/typescript/modules/ShoppingModule.d.ts +13 -0
  168. package/package.json +147 -0
  169. package/react-native-firework-sdk.podspec +22 -0
  170. package/src/FireworkSDK.ts +153 -0
  171. package/src/VideoShopping.ts +165 -0
  172. package/src/components/CartContainer.tsx +20 -0
  173. package/src/components/FWVideoFeed.tsx +10 -0
  174. package/src/components/VideoFeed.tsx +109 -0
  175. package/src/constants/FWErrorMessage.ts +11 -0
  176. package/src/index.tsx +109 -0
  177. package/src/models/ADConfig.ts +10 -0
  178. package/src/models/AddToCartResult.ts +10 -0
  179. package/src/models/FWError.ts +10 -0
  180. package/src/models/FWEvents.ts +63 -0
  181. package/src/models/FeedItemDetails.ts +14 -0
  182. package/src/models/Product.ts +20 -0
  183. package/src/models/ProductInfoViewConfiguration.ts +20 -0
  184. package/src/models/ProductUnit.ts +23 -0
  185. package/src/models/VideoFeedConfiguration.ts +35 -0
  186. package/src/models/VideoPlaybackDetails.ts +33 -0
  187. package/src/models/VideoPlaybackEventName.ts +40 -0
  188. package/src/models/VideoPlayerConfiguration.ts +26 -0
  189. package/src/modules/FireworkSDKModule.ts +27 -0
  190. package/src/modules/ShoppingModule.ts +29 -0
@@ -0,0 +1,123 @@
1
+ package com.reactnativefireworksdk.components.videofeed
2
+
3
+ import android.app.Activity
4
+ import android.graphics.Color
5
+ import android.util.AttributeSet
6
+ import android.view.LayoutInflater
7
+ import android.widget.RelativeLayout
8
+ import com.facebook.react.uimanager.ThemedReactContext
9
+ import com.loopnow.fireworklibrary.FeedType
10
+ import com.loopnow.fireworklibrary.models.FeedLayout
11
+ import com.loopnow.fireworklibrary.models.FeedTitlePosition
12
+ import com.loopnow.fireworklibrary.views.OnItemClickedListener
13
+ import com.loopnow.fireworklibrary.views.VideoFeedView
14
+ import com.reactnativefireworksdk.R
15
+ import com.reactnativefireworksdk.models.*
16
+ import com.reactnativefireworksdk.utils.FWEventUtils
17
+ import com.reactnativefireworksdk.utils.FWLogUtils
18
+ import com.reactnativefireworksdk.utils.FWVideoPlayerUtils
19
+
20
+
21
+ class FWVideoFeed(
22
+ context: ThemedReactContext,
23
+ attrs: AttributeSet?
24
+ ) : RelativeLayout(context, attrs) {
25
+
26
+ // private val reactContext: ReactContext = context.reactApplicationContext
27
+ private val activity: Activity = context.reactApplicationContext.currentActivity as Activity
28
+
29
+ private val videoFeedView: VideoFeedView
30
+ private var channelId: String? = null
31
+ private var playlistId: String? = null
32
+ private var feedType: FeedType? = null
33
+ private var feedLayout: FeedLayout? = null
34
+ private var titlePosition: FeedTitlePosition? = null
35
+
36
+ constructor(context: ThemedReactContext) : this(context, null)
37
+
38
+ init {
39
+ val view = LayoutInflater.from(activity).inflate(R.layout.fwrn_fragment_videofeed, this, true)
40
+ videoFeedView = view.findViewById(R.id.fwrn_integrated_videofeed)
41
+ videoFeedView.addOnItemClickedListener(object: OnItemClickedListener {
42
+ override fun onItemClicked(index: Int, title: String, id: String, videoDuration: Long) {
43
+ val fwVideoFeedItemDetailsModel = FWVideoFeedItemDetailsModel(index, id, videoDuration.toInt())
44
+ FWEventUtils.sendVideoFeedClickEvent(context.reactApplicationContext, fwVideoFeedItemDetailsModel)
45
+ }
46
+
47
+ override fun onItemClicked(index: Int) {
48
+ super.onItemClicked(index)
49
+ }
50
+
51
+ override fun onItemClicked(index: Int, feedId: Int): Boolean {
52
+ return super.onItemClicked(index, feedId)
53
+ }
54
+ })
55
+ }
56
+
57
+ fun setSource(source: String?) {
58
+ feedType = when {
59
+ source.equals(FWVideoFeedSource.Channel.rawValue) -> {
60
+ FeedType.CHANNEL
61
+ }
62
+ source.equals(FWVideoFeedSource.Playlist.rawValue) -> {
63
+ FeedType.PLAYLIST
64
+ }
65
+ else -> {
66
+ FeedType.DISCOVER
67
+ }
68
+ }
69
+ setFeed(channelId, playlistId, feedType)
70
+ }
71
+
72
+ fun setChannel(channel: String?) {
73
+ channelId = channel
74
+ setFeed(channelId, playlistId, feedType)
75
+ }
76
+
77
+ fun setPlaylist(playlist: String?) {
78
+ playlistId = playlist
79
+ setFeed(channelId, playlistId, feedType)
80
+ }
81
+
82
+ fun setMode(mode: String?) {
83
+ feedLayout = when {
84
+ mode.equals(FWVideoFeedMode.Column.rawValue) -> FeedLayout.VERTICAL
85
+ mode.equals(FWVideoFeedMode.Grid.rawValue) -> FeedLayout.GRID
86
+ else -> FeedLayout.HORIZONTAL
87
+ }
88
+ videoFeedView.setLayout(feedLayout)
89
+ }
90
+
91
+ fun setVideoFeedConfig(config: FWVideoFeedConfigModel?) {
92
+ val backgroundColor = config?.backgroundColor
93
+ if (!backgroundColor.isNullOrBlank()) {
94
+ videoFeedView.setBackgroundColor(Color.parseColor(backgroundColor))
95
+ }
96
+
97
+ videoFeedView.setTitleVisible(config?.title?.hidden != true)
98
+
99
+ titlePosition = when {
100
+ config?.titlePosition.equals(FWVideoFeedTitlePosition.Stacked.rawValue) -> FeedTitlePosition.BELOW
101
+ else -> FeedTitlePosition.ALIGN_BOTTOM
102
+ }
103
+ videoFeedView.setTitlePosition(titlePosition)
104
+ }
105
+
106
+ fun setVideoPlayerConfig(config: FWVideoPlayerConfigModel?) {
107
+ FWVideoPlayerUtils.setVideoPlayerConfig(config)
108
+ }
109
+
110
+ fun refresh() {
111
+ videoFeedView.refreshFeed()
112
+ }
113
+
114
+ private fun setFeed(channelId: String?, playlistId: String?, feedType: FeedType?) {
115
+ if (feedType == FeedType.CHANNEL && !channelId.isNullOrBlank()) {
116
+ videoFeedView.setFeed(channelId, null, FeedType.CHANNEL)
117
+ } else if (feedType == FeedType.PLAYLIST && !channelId.isNullOrBlank() && !playlistId.isNullOrBlank()) {
118
+ videoFeedView.setFeed(channelId, playlistId, FeedType.PLAYLIST)
119
+ } else {
120
+ videoFeedView.setFeed(null, null, FeedType.DISCOVER)
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,6 @@
1
+ package com.reactnativefireworksdk.constants
2
+
3
+ object FWCommandConstant {
4
+
5
+ const val FW_COMMAND_VIDEO_FEED_REFRESH = 1000000 // "fw_command_video_refresh"
6
+ }
@@ -0,0 +1,20 @@
1
+ package com.reactnativefireworksdk.constants
2
+
3
+ object FWVideoPlayerConstant {
4
+
5
+ /**
6
+ * When advanceToNext, player will play the next video,
7
+ * When the current video finishes playing.
8
+ * When loop, playing video will loop until user explicitly
9
+ * swipes away
10
+ * Default value is advanceToNext.
11
+ */
12
+ const val FW_VIDEO_COMPLETE_ACTION_LOOP = "loop"
13
+ const val FW_VIDEO_COMPLETE_ACTION_ADVANCE_TO_NEXT = "advanceToNext"
14
+
15
+ /**
16
+ * launch video player in full bleed ( full screen ) mode or fit bleed mode
17
+ */
18
+ const val FW_PLAYER_STYLE_FULL = "full"
19
+ const val FW_PLAYER_STYLE_FIT = "fit"
20
+ }
@@ -0,0 +1,88 @@
1
+ package com.reactnativefireworksdk.manager
2
+
3
+ import com.facebook.react.bridge.ReadableArray
4
+ import com.facebook.react.bridge.ReadableMap
5
+ import com.facebook.react.uimanager.SimpleViewManager
6
+ import com.facebook.react.uimanager.ThemedReactContext
7
+
8
+ import com.facebook.react.uimanager.annotations.ReactProp
9
+ import com.reactnativefireworksdk.constants.FWCommandConstant
10
+ import com.reactnativefireworksdk.models.FWVideoFeedConfigModel
11
+ import com.reactnativefireworksdk.models.FWVideoPlayerConfigModel
12
+ import com.reactnativefireworksdk.utils.FWJsonUtils
13
+ import com.facebook.react.common.MapBuilder
14
+ import com.reactnativefireworksdk.components.videofeed.FWVideoFeed
15
+ import com.reactnativefireworksdk.models.FWFeedViewEventName
16
+
17
+
18
+ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
19
+
20
+ override fun getName(): String {
21
+ return "FWVideoFeed"
22
+ }
23
+
24
+ override fun createViewInstance(reactContext: ThemedReactContext): FWVideoFeed {
25
+ // currentActivity cannot be null
26
+ return FWVideoFeed(reactContext)
27
+ }
28
+
29
+ @ReactProp(name = "source")
30
+ fun setSource(view: FWVideoFeed, source: String?) {
31
+ view.setSource(source)
32
+ }
33
+
34
+ @ReactProp(name = "channel")
35
+ fun setChannel(view: FWVideoFeed, channel: String?) {
36
+ view.setChannel(channel)
37
+ }
38
+
39
+ @ReactProp(name = "playlist")
40
+ fun setPlaylist(view: FWVideoFeed, playlist: String?) {
41
+ view.setPlaylist(playlist)
42
+ }
43
+
44
+ @ReactProp(name = "mode")
45
+ fun setMode(view: FWVideoFeed, mode: String?) {
46
+ view.setMode(mode)
47
+ }
48
+
49
+ @ReactProp(name = "videoFeedConfiguration")
50
+ fun setVideoFeedConfig(view: FWVideoFeed, config: ReadableMap?) {
51
+ val configMap = config?.toHashMap()
52
+ val videoFeedConfigModel = FWJsonUtils.fromMap(configMap, FWVideoFeedConfigModel::class.java)
53
+ view.setVideoFeedConfig(videoFeedConfigModel)
54
+ }
55
+
56
+ @ReactProp(name = "videoPlayerConfiguration")
57
+ fun setVideoPlayerConfig(view: FWVideoFeed, config: ReadableMap?) {
58
+ val configMap = config?.toHashMap()
59
+ val videoPlayerConfigModel = FWJsonUtils.fromMap(configMap, FWVideoPlayerConfigModel::class.java)
60
+ view.setVideoPlayerConfig(videoPlayerConfigModel)
61
+ }
62
+
63
+ override fun getCommandsMap(): MutableMap<String, Int> {
64
+ val map: MutableMap<String, Int> = HashMap()
65
+ map["refresh"] = FWCommandConstant.FW_COMMAND_VIDEO_FEED_REFRESH
66
+ return map
67
+ }
68
+
69
+ override fun receiveCommand(root: FWVideoFeed, commandId: Int, args: ReadableArray?) {
70
+ when (commandId) {
71
+ FWCommandConstant.FW_COMMAND_VIDEO_FEED_REFRESH -> {
72
+ root.refresh()
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * To map the "onVideoFeedLoadFinished" event name to the "onVideoFeedLoadFinished" callback prop in JavaScript
79
+ * first onVideoFeedLoadFinished is event name
80
+ * second onVideoFeedLoadFinished is callback prop in JavaScript
81
+ */
82
+ override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any>? {
83
+ return MapBuilder.builder<String, Any>()
84
+ .put(FWFeedViewEventName.VideoFeedLoadFinished.rawValue, MapBuilder.of("phasedRegistrationNames", MapBuilder.of("bubbled", FWFeedViewEventName.VideoFeedLoadFinished.rawValue)))
85
+ .build()
86
+ }
87
+
88
+ }
@@ -0,0 +1,35 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ enum class FWEventName(val rawValue: String) {
4
+ SDKIni("fw:sdk-init"),
5
+ CustomCTAClick("fw:custom-cta-click"),
6
+ VideoPlayback("fw:video-playback"),
7
+ VideoFeedClick("fw:video-feed-click"),
8
+ }
9
+
10
+ enum class FWSDKInitSubEventName(val rawValue: String) {
11
+ InitFailed("initFailed"),
12
+ }
13
+
14
+ enum class FWFeedViewEventName(val rawValue: String) {
15
+ VideoFeedLoadFinished("onVideoFeedLoadFinished"),
16
+ }
17
+
18
+ enum class FWVideoPlaybackSubEventName(val rawValue: String) {
19
+ Impression("fw:video:impression"),
20
+ Start("fw:video:start"),
21
+ FirstQuartile("fw:video:first-quartile"),
22
+ Midpoint("fw:video:midpoint"),
23
+ ThirdQuartile("fw:video:third-quartile"),
24
+ Complete("fw:video:complete"),
25
+ AdEnd("fw:video:ad-end"),
26
+ ClickCTA("fw:video:click-cta"),
27
+ ClickShare("fw:video:click-share"),
28
+ }
29
+
30
+ enum class FWVideoShoppingEventName(val rawValue: String) {
31
+ AddToCart("fw:shopping:add-to-cart"),
32
+ ClickCartIcon("fw:shopping:click-cart-icon"),
33
+ UpdateProductDetails("fw:shopping:update-product-details"),
34
+ WillDisplayProduct("fw:shopping:will-display-product"),
35
+ }
@@ -0,0 +1,27 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import android.os.Parcelable
4
+ import kotlinx.android.parcel.Parcelize
5
+
6
+ @Parcelize
7
+ data class FWVideoFeedConfigModel(
8
+ val backgroundColor: String?,
9
+ val cornerRadius: Int?,
10
+ val title: FWTitleModel?,
11
+ val titlePosition: String?,
12
+ val playIcon: FWPlayIconModel?
13
+ ) : Parcelable {
14
+
15
+ @Parcelize
16
+ data class FWTitleModel(
17
+ val hidden: Boolean?,
18
+ val textColor: String?,
19
+ val fontSize: Int?,
20
+ ) : Parcelable
21
+
22
+ @Parcelize
23
+ data class FWPlayIconModel(
24
+ val hidden: Boolean?,
25
+ val iconWidth: Int?,
26
+ ) : Parcelable
27
+ }
@@ -0,0 +1,11 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import android.os.Parcelable
4
+ import kotlinx.android.parcel.Parcelize
5
+
6
+ @Parcelize
7
+ data class FWVideoFeedItemDetailsModel(
8
+ val index: Int?,
9
+ val id: String?,
10
+ val videoDuration: Int?,
11
+ ) : Parcelable
@@ -0,0 +1,7 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ enum class FWVideoFeedMode(val rawValue: String) {
4
+ Row("row"),
5
+ Column("column"),
6
+ Grid("grid"),
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ enum class FWVideoFeedSource(val rawValue: String) {
4
+ Discover("discover"),
5
+ Channel("channel"),
6
+ Playlist("playlist"),
7
+ }
@@ -0,0 +1,7 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ enum class FWVideoFeedTitlePosition(val intValue: Int, val rawValue: String) {
4
+ Nested(1, "nested"),
5
+ Stacked(2, "stacked"),
6
+ }
7
+
@@ -0,0 +1,19 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import android.os.Parcelable
4
+ import com.fasterxml.jackson.annotation.JsonProperty
5
+ import kotlinx.android.parcel.Parcelize
6
+
7
+ @Parcelize
8
+ data class FWVideoPlaybackDetails(
9
+ val autoplay: Boolean?,
10
+ val badge: String?,
11
+ val caption: String?,
12
+ val duration: Long?,
13
+ @field:JsonProperty("has_cta")
14
+ val hasCta: Boolean?,
15
+ val height: Int?,
16
+ val width: Int?,
17
+ @field:JsonProperty("video_id")
18
+ val videoId: String?
19
+ ) : Parcelable
@@ -0,0 +1,20 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import android.os.Parcelable
4
+ import kotlinx.android.parcel.Parcelize
5
+
6
+ @Parcelize
7
+ data class FWVideoPlayerConfigModel(
8
+ val playerStyle: String?,
9
+ val videoCompleteAction: String?,
10
+ val showShareButton: Boolean?,
11
+ val ctaButtonStyle: FWCtaButtonStyleModel?
12
+ ) : Parcelable {
13
+
14
+ @Parcelize
15
+ data class FWCtaButtonStyleModel(
16
+ val backgroundColor: String?,
17
+ val fontSize: String?,
18
+ val textColor: String?,
19
+ ) : Parcelable
20
+ }
@@ -0,0 +1,13 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+
5
+ interface FWVideoShoppingInterface {
6
+
7
+ fun init()
8
+ fun updateVideoProduct(productMap: ReadableMap?, callbackId: Int?)
9
+ fun updateProductViewConfig(config: ReadableMap?, callbackId: Int?)
10
+ fun updateAddToCartStatus(res: String?, tip: String?, callbackId: Int?)
11
+ fun jumpToCartPage(callbackId: Int?)
12
+ fun exitCartPage()
13
+ }
@@ -0,0 +1,34 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import android.os.Parcelable
4
+ import kotlinx.android.parcel.Parcelize
5
+
6
+ @Parcelize
7
+ data class FWVideoShoppingProduct(
8
+ val productId: String?,
9
+ val name: String?,
10
+ val description: String?,
11
+ val units: List<FWVideoProductUnit>?
12
+ ) : Parcelable {
13
+
14
+ @Parcelize
15
+ data class FWVideoProductUnit(
16
+ val unitId: String?,
17
+ val name: String?,
18
+ val price: FWVideoProductPrice?,
19
+ val url: String?,
20
+ val options: List<FWVideoProductOption>?
21
+ ) : Parcelable
22
+
23
+ @Parcelize
24
+ data class FWVideoProductPrice(
25
+ val amount: Double?,
26
+ val currencyCode: String?
27
+ ) : Parcelable
28
+
29
+ @Parcelize
30
+ data class FWVideoProductOption(
31
+ val name: String?,
32
+ val value: String?
33
+ ) : Parcelable
34
+ }
@@ -0,0 +1,12 @@
1
+ package com.reactnativefireworksdk.models
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+
5
+ interface FireworkSDKInterface {
6
+
7
+ fun init(userId: String?, adConfig: ReadableMap?)
8
+ fun openVideoPlayer(url: String, config: ReadableMap?)
9
+ fun setShareBaseURL(url: String?)
10
+ fun setCustomCTAClickEnabled(value: Boolean?)
11
+ fun setVideoPlaybackEventEnabled(value: Boolean?)
12
+ }
@@ -0,0 +1,190 @@
1
+ package com.reactnativefireworksdk.module
2
+
3
+ import android.app.Activity
4
+ import com.facebook.react.bridge.*
5
+ import com.loopnow.fireworklibrary.baya.Baya
6
+ import com.loopnow.fireworklibrary.baya.UpdateCartStatus
7
+ import com.loopnow.fireworklibrary.models.Product
8
+ import com.reactnativefireworksdk.models.FWVideoShoppingInterface
9
+ import com.reactnativefireworksdk.models.FWVideoShoppingProduct
10
+ import com.reactnativefireworksdk.pages.FWVideoShoppingCartActivity
11
+ import com.reactnativefireworksdk.utils.FWEventUtils
12
+ import com.reactnativefireworksdk.utils.FWJsonUtils
13
+ import com.reactnativefireworksdk.utils.FWLogUtils
14
+
15
+ class FWVideoShoppingModule(
16
+ reactContext: ReactApplicationContext
17
+ ) : ReactContextBaseJavaModule(reactContext), FWVideoShoppingInterface {
18
+
19
+ private var addToCartHandler: Triple<Int, String, String>? = null
20
+ private var cartClickHandler: Pair<Int, Activity>? = null
21
+ private val updateProductHandler: HashMap<String, Product> = HashMap()
22
+
23
+ @ReactMethod
24
+ override fun init() {
25
+ cartListener()
26
+ productListener()
27
+ }
28
+
29
+ @ReactMethod
30
+ override fun updateVideoProduct(productMap: ReadableMap?, callbackId: Int?) {
31
+ FWLogUtils.d { "FWVideoShoppingModule updateVideoProduct: $callbackId, productMap: $productMap" }
32
+ if (callbackId == null) {
33
+ return
34
+ }
35
+
36
+ val configMap = productMap?.toHashMap()
37
+ val videoShoppingProduct = FWJsonUtils.fromMap(configMap, FWVideoShoppingProduct::class.java)
38
+ ?: return
39
+ val productId = videoShoppingProduct.productId
40
+ if (productId.isNullOrBlank()) {
41
+ return
42
+ }
43
+
44
+ val product = updateProductHandler[productId] ?: return
45
+
46
+ if (videoShoppingProduct.description != null) {
47
+ product.description = videoShoppingProduct.description
48
+ }
49
+
50
+ if (videoShoppingProduct.units != null) {
51
+ for (videoShoppingProductUnit in videoShoppingProduct.units) {
52
+ for (productUnit in product.units) {
53
+ if (videoShoppingProductUnit.unitId.equals(productUnit.externalId)) {
54
+ productUnit.name = videoShoppingProductUnit.name
55
+ productUnit.price?.amount = videoShoppingProductUnit.price?.amount
56
+ productUnit.price?.currencyCode = videoShoppingProductUnit.price?.currencyCode
57
+ }
58
+ }
59
+ }
60
+ }
61
+
62
+ updateProductHandler.remove(productId)
63
+
64
+ }
65
+
66
+ @ReactMethod
67
+ override fun updateProductViewConfig(config: ReadableMap?, callbackId: Int?) {
68
+ FWLogUtils.d { "FWVideoShoppingModule updateProductViewConfig: $callbackId, config: $config" }
69
+ }
70
+
71
+ @ReactMethod
72
+ override fun updateAddToCartStatus(res: String?, tip: String?, callbackId: Int?) {
73
+ FWLogUtils.d { "FWVideoShoppingModule updateAddToCartStatus: $callbackId, res: $res, tip: $tip, addToCartHandler: ${addToCartHandler?.first}" }
74
+ if (callbackId == null || addToCartHandler?.first != callbackId) {
75
+ return
76
+ }
77
+
78
+ val unitId = addToCartHandler?.third
79
+ if (unitId.isNullOrBlank()) {
80
+ return
81
+ }
82
+
83
+ UiThreadUtil.runOnUiThread {
84
+ when {
85
+ res.equals("success") -> {
86
+ Baya.updateCartStatus(UpdateCartStatus.Success(tip, unitId))
87
+ }
88
+ res.equals("fail") -> {
89
+ Baya.updateCartStatus(UpdateCartStatus.Error(tip, unitId))
90
+ }
91
+ res.equals("loading") -> {
92
+ Baya.updateCartStatus(UpdateCartStatus.Loading)
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ @ReactMethod
99
+ override fun jumpToCartPage(callbackId: Int?) {
100
+ FWLogUtils.d { "FWVideoShoppingModule jumpToCartPage: $callbackId" }
101
+ if (callbackId == null || cartClickHandler?.first != callbackId) {
102
+ return
103
+ }
104
+ val activity = cartClickHandler?.second ?: return
105
+
106
+ UiThreadUtil.runOnUiThread {
107
+ activity.startActivity(FWVideoShoppingCartActivity.createIntent(activity))
108
+ }
109
+ }
110
+
111
+ @ReactMethod
112
+ override fun exitCartPage() {
113
+ val activity = reactApplicationContext.currentActivity
114
+ UiThreadUtil.runOnUiThread {
115
+ activity?.finish()
116
+ }
117
+ }
118
+
119
+ private fun cartListener() {
120
+ Baya.cartInterface = object: Baya.CartInterface {
121
+
122
+ override fun updateCart(
123
+ activity: Activity,
124
+ productId: String,
125
+ unitId: String,
126
+ quantity: Int
127
+ ) {
128
+ FWLogUtils.d { "FWVideoShoppingModule updateCart, productId: $productId, unitId: $unitId" }
129
+ val callbackId = generateCallbackId()
130
+ addToCartHandler = Triple(callbackId, productId, unitId)
131
+ FWEventUtils.sendAddToCartClickEvent(reactApplicationContext, productId, unitId, callbackId)
132
+ }
133
+
134
+ override fun cartClicked(activity: Activity) {
135
+ FWLogUtils.d { "FWVideoShoppingModule cartClicked" }
136
+ val callbackId = generateCallbackId()
137
+ cartClickHandler = Pair(callbackId, activity)
138
+ FWEventUtils.sendCartIconClickEvent(reactApplicationContext, callbackId)
139
+ }
140
+ }
141
+ }
142
+
143
+ private fun productListener() {
144
+ Baya.productInterface = object: Baya.ProductInterface {
145
+ override fun hydrateProduct(id: String, product: Product) {
146
+ FWLogUtils.d { "FWVideoShoppingModule hydrateProduct, id: $id" }
147
+ val callbackId = generateCallbackId()
148
+ if (!id.isNullOrBlank()) {
149
+ updateProductHandler[id] = product
150
+ FWEventUtils.sendUpdateProductDetailsEvent(reactApplicationContext, id, callbackId)
151
+ }
152
+ }
153
+
154
+ override fun displayProductInfo(
155
+ productId: String,
156
+ unitId: String,
157
+ productWebUrl: String?
158
+ ): Boolean {
159
+ return false
160
+ }
161
+ }
162
+ }
163
+
164
+ @ReactMethod
165
+ fun addListener(eventName: String?) {
166
+ // Set up any upstream listeners or background tasks as necessary
167
+ FWLogUtils.d { "addListener: $eventName" }
168
+ }
169
+
170
+ @ReactMethod
171
+ fun removeListeners(count: Int?) {
172
+ // Remove upstream listeners, stop unnecessary background tasks
173
+ FWLogUtils.d { "removeListeners: $count" }
174
+ }
175
+
176
+ override fun getName(): String {
177
+ return "ShoppingModule"
178
+ }
179
+
180
+ companion object {
181
+ private var callbackId = 0
182
+
183
+ @JvmStatic
184
+ fun generateCallbackId(): Int {
185
+ callbackId += 1
186
+ return callbackId
187
+ }
188
+ }
189
+
190
+ }