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.
- package/README.md +39 -0
- package/android/build.gradle +193 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradle.properties +5 -0
- package/android/gradlew +185 -0
- package/android/gradlew.bat +89 -0
- package/android/publish.gradle +65 -0
- package/android/src/main/AndroidManifest.xml +16 -0
- package/android/src/main/java/com/reactnativefireworksdk/FireworkSDKPackage.kt +20 -0
- package/android/src/main/java/com/reactnativefireworksdk/components/videofeed/FWVideoFeed.kt +123 -0
- package/android/src/main/java/com/reactnativefireworksdk/constants/FWCommandConstant.kt +6 -0
- package/android/src/main/java/com/reactnativefireworksdk/constants/FWVideoPlayerConstant.kt +20 -0
- package/android/src/main/java/com/reactnativefireworksdk/manager/FWVideoFeedManager.kt +88 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWEventName.kt +35 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedConfigModel.kt +27 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedItemDetailsModel.kt +11 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedMode.kt +7 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedSource.kt +7 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoFeedTitlePosition.kt +7 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoPlaybackDetails.kt +19 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoPlayerConfigModel.kt +20 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoShoppingInterface.kt +13 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FWVideoShoppingProduct.kt +34 -0
- package/android/src/main/java/com/reactnativefireworksdk/models/FireworkSDKInterface.kt +12 -0
- package/android/src/main/java/com/reactnativefireworksdk/module/FWVideoShoppingModule.kt +190 -0
- package/android/src/main/java/com/reactnativefireworksdk/module/FireworkSDKModule.kt +248 -0
- package/android/src/main/java/com/reactnativefireworksdk/pages/FWVideoShoppingCartActivity.kt +43 -0
- package/android/src/main/java/com/reactnativefireworksdk/utils/FWEventUtils.kt +127 -0
- package/android/src/main/java/com/reactnativefireworksdk/utils/FWJsonUtils.kt +57 -0
- package/android/src/main/java/com/reactnativefireworksdk/utils/FWLogUtils.kt +147 -0
- package/android/src/main/java/com/reactnativefireworksdk/utils/FWUrlUtils.kt +68 -0
- package/android/src/main/java/com/reactnativefireworksdk/utils/FWVideoPlayerUtils.kt +18 -0
- package/android/src/main/res/layout/fwrn_fragment_shoppingcart.xml +8 -0
- package/android/src/main/res/layout/fwrn_fragment_videofeed.xml +20 -0
- package/android/src/main/res/values/styles.xml +43 -0
- package/ios/Component/VideoFeed.swift +262 -0
- package/ios/Component/VideoFeedConfiguration.swift +32 -0
- package/ios/Component/VideoFeedManager.m +51 -0
- package/ios/Component/VideoFeedManager.swift +40 -0
- package/ios/Component/VideoPlayerConfiguration.swift +30 -0
- package/ios/FireworkSdk-Bridging-Header.h +6 -0
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +291 -0
- package/ios/Models/FireworkJsEvent.swift +34 -0
- package/ios/Models/FireworkSDK+JsModel.swift +62 -0
- package/ios/Models/RCTConvert+FireworkSDKModule.swift +91 -0
- package/ios/Models/RCTConvert+Shopping.swift +49 -0
- package/ios/Models/RCTConvert+VideoFeed.swift +69 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule+CTA.swift +17 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +74 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +19 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +106 -0
- package/ios/Modules/FireworkSDKModule/MobileADConfiguration.swift +17 -0
- package/ios/Modules/Shopping/CartViewController.swift +98 -0
- package/ios/Modules/Shopping/Product.swift +33 -0
- package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +24 -0
- package/ios/Modules/Shopping/ShoppingModule.m +19 -0
- package/ios/Modules/Shopping/ShoppingModule.swift +214 -0
- package/ios/Utils/String+Color.swift +38 -0
- package/ios/Utils/UIView+Constraints.swift +91 -0
- package/ios/Utils/UIView+ParentViewController.swift +21 -0
- package/ios/Utils/UIViewController+AttachChild.swift +69 -0
- package/lib/commonjs/FireworkSDK.js +171 -0
- package/lib/commonjs/FireworkSDK.js.map +1 -0
- package/lib/commonjs/VideoShopping.js +146 -0
- package/lib/commonjs/VideoShopping.js.map +1 -0
- package/lib/commonjs/components/CartContainer.js +35 -0
- package/lib/commonjs/components/CartContainer.js.map +1 -0
- package/lib/commonjs/components/FWVideoFeed.js +18 -0
- package/lib/commonjs/components/FWVideoFeed.js.map +1 -0
- package/lib/commonjs/components/VideoFeed.js +82 -0
- package/lib/commonjs/components/VideoFeed.js.map +1 -0
- package/lib/commonjs/constants/FWErrorMessage.js +15 -0
- package/lib/commonjs/constants/FWErrorMessage.js.map +1 -0
- package/lib/commonjs/index.js +44 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/models/ADConfig.js +2 -0
- package/lib/commonjs/models/ADConfig.js.map +1 -0
- package/lib/commonjs/models/AddToCartResult.js +2 -0
- package/lib/commonjs/models/AddToCartResult.js.map +1 -0
- package/lib/commonjs/models/FWError.js +2 -0
- package/lib/commonjs/models/FWError.js.map +1 -0
- package/lib/commonjs/models/FWEvents.js +20 -0
- package/lib/commonjs/models/FWEvents.js.map +1 -0
- package/lib/commonjs/models/FeedItemDetails.js +2 -0
- package/lib/commonjs/models/FeedItemDetails.js.map +1 -0
- package/lib/commonjs/models/Product.js +2 -0
- package/lib/commonjs/models/Product.js.map +1 -0
- package/lib/commonjs/models/ProductInfoViewConfiguration.js +2 -0
- package/lib/commonjs/models/ProductInfoViewConfiguration.js.map +1 -0
- package/lib/commonjs/models/ProductUnit.js +2 -0
- package/lib/commonjs/models/ProductUnit.js.map +1 -0
- package/lib/commonjs/models/VideoFeedConfiguration.js +2 -0
- package/lib/commonjs/models/VideoFeedConfiguration.js.map +1 -0
- package/lib/commonjs/models/VideoPlaybackDetails.js +2 -0
- package/lib/commonjs/models/VideoPlaybackDetails.js.map +1 -0
- package/lib/commonjs/models/VideoPlaybackEventName.js +23 -0
- package/lib/commonjs/models/VideoPlaybackEventName.js.map +1 -0
- package/lib/commonjs/models/VideoPlayerConfiguration.js +2 -0
- package/lib/commonjs/models/VideoPlayerConfiguration.js.map +1 -0
- package/lib/commonjs/modules/FireworkSDKModule.js +20 -0
- package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -0
- package/lib/commonjs/modules/ShoppingModule.js +20 -0
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -0
- package/lib/module/FireworkSDK.js +153 -0
- package/lib/module/FireworkSDK.js.map +1 -0
- package/lib/module/VideoShopping.js +134 -0
- package/lib/module/VideoShopping.js.map +1 -0
- package/lib/module/components/CartContainer.js +18 -0
- package/lib/module/components/CartContainer.js.map +1 -0
- package/lib/module/components/FWVideoFeed.js +8 -0
- package/lib/module/components/FWVideoFeed.js.map +1 -0
- package/lib/module/components/VideoFeed.js +66 -0
- package/lib/module/components/VideoFeed.js.map +1 -0
- package/lib/module/constants/FWErrorMessage.js +7 -0
- package/lib/module/constants/FWErrorMessage.js.map +1 -0
- package/lib/module/index.js +10 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/models/ADConfig.js +2 -0
- package/lib/module/models/ADConfig.js.map +1 -0
- package/lib/module/models/AddToCartResult.js +2 -0
- package/lib/module/models/AddToCartResult.js.map +1 -0
- package/lib/module/models/FWError.js +2 -0
- package/lib/module/models/FWError.js.map +1 -0
- package/lib/module/models/FWEvents.js +13 -0
- package/lib/module/models/FWEvents.js.map +1 -0
- package/lib/module/models/FeedItemDetails.js +2 -0
- package/lib/module/models/FeedItemDetails.js.map +1 -0
- package/lib/module/models/Product.js +2 -0
- package/lib/module/models/Product.js.map +1 -0
- package/lib/module/models/ProductInfoViewConfiguration.js +2 -0
- package/lib/module/models/ProductInfoViewConfiguration.js.map +1 -0
- package/lib/module/models/ProductUnit.js +2 -0
- package/lib/module/models/ProductUnit.js.map +1 -0
- package/lib/module/models/VideoFeedConfiguration.js +2 -0
- package/lib/module/models/VideoFeedConfiguration.js.map +1 -0
- package/lib/module/models/VideoPlaybackDetails.js +2 -0
- package/lib/module/models/VideoPlaybackDetails.js.map +1 -0
- package/lib/module/models/VideoPlaybackEventName.js +16 -0
- package/lib/module/models/VideoPlaybackEventName.js.map +1 -0
- package/lib/module/models/VideoPlayerConfiguration.js +2 -0
- package/lib/module/models/VideoPlayerConfiguration.js.map +1 -0
- package/lib/module/modules/FireworkSDKModule.js +10 -0
- package/lib/module/modules/FireworkSDKModule.js.map +1 -0
- package/lib/module/modules/ShoppingModule.js +10 -0
- package/lib/module/modules/ShoppingModule.js.map +1 -0
- package/lib/typescript/FireworkSDK.d.ts +74 -0
- package/lib/typescript/VideoShopping.d.ts +54 -0
- package/lib/typescript/components/CartContainer.d.ts +3 -0
- package/lib/typescript/components/FWVideoFeed.d.ts +2 -0
- package/lib/typescript/components/VideoFeed.d.ts +53 -0
- package/lib/typescript/constants/FWErrorMessage.d.ts +2 -0
- package/lib/typescript/index.d.ts +25 -0
- package/lib/typescript/models/ADConfig.d.ts +10 -0
- package/lib/typescript/models/AddToCartResult.d.ts +10 -0
- package/lib/typescript/models/FWError.d.ts +10 -0
- package/lib/typescript/models/FWEvents.d.ts +55 -0
- package/lib/typescript/models/FeedItemDetails.d.ts +14 -0
- package/lib/typescript/models/Product.d.ts +19 -0
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +18 -0
- package/lib/typescript/models/ProductUnit.d.ts +22 -0
- package/lib/typescript/models/VideoFeedConfiguration.d.ts +32 -0
- package/lib/typescript/models/VideoPlaybackDetails.d.ts +31 -0
- package/lib/typescript/models/VideoPlaybackEventName.d.ts +39 -0
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +25 -0
- package/lib/typescript/modules/FireworkSDKModule.d.ts +12 -0
- package/lib/typescript/modules/ShoppingModule.d.ts +13 -0
- package/package.json +147 -0
- package/react-native-firework-sdk.podspec +22 -0
- package/src/FireworkSDK.ts +153 -0
- package/src/VideoShopping.ts +165 -0
- package/src/components/CartContainer.tsx +20 -0
- package/src/components/FWVideoFeed.tsx +10 -0
- package/src/components/VideoFeed.tsx +109 -0
- package/src/constants/FWErrorMessage.ts +11 -0
- package/src/index.tsx +109 -0
- package/src/models/ADConfig.ts +10 -0
- package/src/models/AddToCartResult.ts +10 -0
- package/src/models/FWError.ts +10 -0
- package/src/models/FWEvents.ts +63 -0
- package/src/models/FeedItemDetails.ts +14 -0
- package/src/models/Product.ts +20 -0
- package/src/models/ProductInfoViewConfiguration.ts +20 -0
- package/src/models/ProductUnit.ts +23 -0
- package/src/models/VideoFeedConfiguration.ts +35 -0
- package/src/models/VideoPlaybackDetails.ts +33 -0
- package/src/models/VideoPlaybackEventName.ts +40 -0
- package/src/models/VideoPlayerConfiguration.ts +26 -0
- package/src/modules/FireworkSDKModule.ts +27 -0
- 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,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,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
|
+
}
|