react-native-firework-sdk 2.8.6 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +1 -1
- package/android/build.gradle +2 -1
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/components/base/FWLoading.kt +22 -0
- package/android/src/main/java/com/fireworksdk/bridge/components/storyblock/StoryBlockFragment.kt +240 -18
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +19 -9
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationDeserializer.kt +49 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationModel.kt +13 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdConfigurationSerializer.kt +42 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoDeserializer.kt +21 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoModel.kt +6 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWButtonInfoSerializer.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationDeserializer.kt +33 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationModel.kt +10 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationSerializer.kt +25 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +7 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationSerializer.kt +13 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +3 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelSerializer.kt +2 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +3 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +7 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelSerializer.kt +4 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWErrorAction.kt +18 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWEventName.kt +3 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +50 -26
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +47 -8
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +0 -10
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +42 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +5 -3
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +24 -6
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +95 -0
- package/android/src/main/res/layout/fw_bridge_story_block.xml +6 -0
- package/android/src/main/res/layout/fw_loading.xml +14 -0
- package/ios/Components/VideoFeed.swift +1 -1
- package/ios/FireworkVideoUI/Podfile +1 -1
- package/ios/FireworkVideoUI/Podfile.lock +5 -5
- package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.h +20 -0
- package/ios/Modules/FWNavigatorModule/RNSScreenStackView+Window.m +84 -0
- package/lib/commonjs/VideoShopping.js +1 -4
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +32 -42
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +29 -11
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/utils/VideoFeedUtil.js +73 -0
- package/lib/commonjs/utils/VideoFeedUtil.js.map +1 -0
- package/lib/module/VideoShopping.js +1 -5
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +32 -40
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +28 -11
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js +2 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/VideoFeedUtil.js +65 -0
- package/lib/module/utils/VideoFeedUtil.js.map +1 -0
- package/lib/typescript/VideoShopping.d.ts +0 -1
- package/lib/typescript/components/StoryBlock.d.ts +15 -4
- package/lib/typescript/components/VideoFeed.d.ts +12 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/models/ButtonInfo.d.ts +0 -1
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +3 -3
- package/lib/typescript/models/StoryBlockConfiguration.d.ts +0 -2
- package/lib/typescript/models/VideoPlayerButtonConfiguration.d.ts +0 -6
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +0 -2
- package/lib/typescript/utils/VideoFeedUtil.d.ts +10 -0
- package/package.json +1 -1
- package/react-native-firework-sdk.podspec +1 -1
- package/src/VideoShopping.ts +1 -4
- package/src/components/StoryBlock.tsx +40 -44
- package/src/components/VideoFeed.tsx +32 -11
- package/src/index.ts +2 -0
- package/src/models/ButtonInfo.ts +0 -1
- package/src/models/ProductInfoViewConfiguration.ts +3 -3
- package/src/models/StoryBlockConfiguration.ts +0 -2
- package/src/models/VideoPlayerButtonConfiguration.ts +0 -6
- package/src/models/VideoPlayerConfiguration.ts +0 -2
- package/src/utils/VideoFeedUtil.ts +74 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWStatusBarUtil.kt +0 -28
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWStoryBlockUtil.kt +0 -30
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist
CHANGED
|
Binary file
|
package/android/build.gradle
CHANGED
|
@@ -40,7 +40,7 @@ android {
|
|
|
40
40
|
// LOG_LEVEL: VERBOSE(2), DEBUG(3), INFO(4), WARN(5), ERROR(6), ASSERT(7)
|
|
41
41
|
buildTypes {
|
|
42
42
|
debug {
|
|
43
|
-
buildConfigField 'int', 'LOG_LEVEL', '
|
|
43
|
+
buildConfigField 'int', 'LOG_LEVEL', '7'
|
|
44
44
|
consumerProguardFiles 'proguard-rules.pro', "devsupport.pro"
|
|
45
45
|
}
|
|
46
46
|
release {
|
|
@@ -143,5 +143,6 @@ dependencies {
|
|
|
143
143
|
|
|
144
144
|
def fireworkSdkVersion = getExtOrDefault('fwNativeVersion')
|
|
145
145
|
implementation "com.firework:sdk:$fireworkSdkVersion"
|
|
146
|
+
implementation "com.firework.feature:uiKit:$fireworkSdkVersion"
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.components.base
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.AttributeSet
|
|
5
|
+
import android.view.LayoutInflater
|
|
6
|
+
import android.view.ViewGroup
|
|
7
|
+
import android.widget.FrameLayout
|
|
8
|
+
import com.fireworksdk.bridge.R
|
|
9
|
+
|
|
10
|
+
class FWLoading(
|
|
11
|
+
context: Context,
|
|
12
|
+
attrs: AttributeSet?
|
|
13
|
+
) : FrameLayout(context, attrs) {
|
|
14
|
+
|
|
15
|
+
constructor(context: Context) : this(context, null)
|
|
16
|
+
|
|
17
|
+
init {
|
|
18
|
+
val v =
|
|
19
|
+
LayoutInflater.from(context).inflate(R.layout.fw_loading, this, false)
|
|
20
|
+
addView(v, LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
|
|
21
|
+
}
|
|
22
|
+
}
|
package/android/src/main/java/com/fireworksdk/bridge/components/storyblock/StoryBlockFragment.kt
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
package com.fireworksdk.bridge.components.storyblock
|
|
2
2
|
|
|
3
|
+
import android.graphics.Color
|
|
3
4
|
import android.graphics.Outline
|
|
4
5
|
import android.os.Bundle
|
|
6
|
+
import android.os.Handler
|
|
7
|
+
import android.os.Looper
|
|
5
8
|
import android.view.LayoutInflater
|
|
9
|
+
import android.view.SurfaceView
|
|
6
10
|
import android.view.View
|
|
7
11
|
import android.view.View.LAYOUT_DIRECTION_LOCALE
|
|
8
12
|
import android.view.ViewGroup
|
|
13
|
+
import android.view.ViewGroup.LayoutParams
|
|
9
14
|
import android.view.ViewOutlineProvider
|
|
10
15
|
import android.widget.FrameLayout
|
|
16
|
+
import com.firework.error.FwErrorListener
|
|
11
17
|
import com.firework.storyblock.FeedLoadListener
|
|
18
|
+
import com.firework.storyblock.FeedLoadState
|
|
12
19
|
import com.firework.storyblock.FwStoryBlockView
|
|
13
20
|
import com.fireworksdk.bridge.components.base.FWBaseFragment
|
|
21
|
+
import com.fireworksdk.bridge.components.base.FWLoading
|
|
14
22
|
import com.fireworksdk.bridge.databinding.FwBridgeStoryBlockBinding
|
|
15
23
|
import com.fireworksdk.bridge.models.FWVideoFeedPropsModel
|
|
16
24
|
import com.fireworksdk.bridge.models.FWVideoFeedPropsModelDeserializer
|
|
@@ -19,6 +27,7 @@ import com.fireworksdk.bridge.utils.FWCommonUtil
|
|
|
19
27
|
import com.fireworksdk.bridge.utils.FWConfigUtil
|
|
20
28
|
import com.fireworksdk.bridge.utils.FWLanguageUtil
|
|
21
29
|
import org.json.JSONObject
|
|
30
|
+
import java.lang.reflect.Method
|
|
22
31
|
|
|
23
32
|
class StoryBlockFragment : FWBaseFragment() {
|
|
24
33
|
|
|
@@ -26,7 +35,7 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
26
35
|
private val binding: FwBridgeStoryBlockBinding get() = _binding!!
|
|
27
36
|
|
|
28
37
|
private var feedLoadListener: FeedLoadListener? = null
|
|
29
|
-
private var
|
|
38
|
+
private var errorListener: FwErrorListener? = null
|
|
30
39
|
private var videoFeedPropsModel: FWVideoFeedPropsModel? = null
|
|
31
40
|
|
|
32
41
|
private var isStoryBlockInitializer = false
|
|
@@ -34,6 +43,15 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
34
43
|
|
|
35
44
|
private var fwStoryBlockView: FwStoryBlockView? = null
|
|
36
45
|
|
|
46
|
+
private val runnable = Runnable {
|
|
47
|
+
removeLoadingViewFromIvsPlayerView(fwStoryBlockView)
|
|
48
|
+
}
|
|
49
|
+
private var hasAdded = false
|
|
50
|
+
|
|
51
|
+
private var loaderContainer: FrameLayout? = null
|
|
52
|
+
|
|
53
|
+
private var needIvsLoading = false
|
|
54
|
+
|
|
37
55
|
override fun onCreateView(
|
|
38
56
|
inflater: LayoutInflater,
|
|
39
57
|
container: ViewGroup?,
|
|
@@ -47,15 +65,25 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
47
65
|
val model = FWVideoFeedPropsModelDeserializer.deserialize(videoFeedPropsModelJsonObject)
|
|
48
66
|
videoFeedPropsModel = model
|
|
49
67
|
}
|
|
68
|
+
val needIvsLoading = arguments?.getBoolean(NEED_IVS_LOADING) ?: false
|
|
69
|
+
this.needIvsLoading = needIvsLoading
|
|
70
|
+
|
|
71
|
+
loaderContainer = binding.fwLoadingWrapper.loaderContainer
|
|
50
72
|
|
|
51
73
|
val right = videoFeedPropsModel?.marginRight
|
|
52
74
|
if (right != null && right > 0) {
|
|
53
75
|
val layoutParams = FrameLayout.LayoutParams(
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
LayoutParams.MATCH_PARENT,
|
|
77
|
+
LayoutParams.MATCH_PARENT
|
|
56
78
|
)
|
|
57
79
|
layoutParams.setMargins(0, 0, FWCommonUtil.dpToPx(right.toFloat(), requireContext()), 0)
|
|
58
80
|
binding.storyBlockContainer.layoutParams = layoutParams
|
|
81
|
+
|
|
82
|
+
if (needIvsLoading) {
|
|
83
|
+
loaderContainer?.visibility = View.VISIBLE
|
|
84
|
+
loaderContainer?.layoutParams = layoutParams
|
|
85
|
+
loaderContainer?.setBackgroundColor(Color.BLACK)
|
|
86
|
+
}
|
|
59
87
|
}
|
|
60
88
|
|
|
61
89
|
FWLanguageUtil.getInstance(requireContext()).updateBaseContextLocale(requireContext())
|
|
@@ -73,6 +101,7 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
73
101
|
|
|
74
102
|
|
|
75
103
|
override fun onDestroyView() {
|
|
104
|
+
fwStoryBlockView?.destroy()
|
|
76
105
|
_binding = null
|
|
77
106
|
super.onDestroyView()
|
|
78
107
|
}
|
|
@@ -81,9 +110,9 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
81
110
|
val viewOptionsBuilder = FWConfigUtil.generateViewOptionsBuilder(context, videoFeedPropsModel)
|
|
82
111
|
fwStoryBlockView?.init(
|
|
83
112
|
childFragmentManager,
|
|
84
|
-
|
|
113
|
+
viewLifecycleOwner,
|
|
85
114
|
viewOptionsBuilder.build(),
|
|
86
|
-
|
|
115
|
+
true
|
|
87
116
|
)
|
|
88
117
|
isStoryBlockInitializer = true
|
|
89
118
|
|
|
@@ -92,8 +121,8 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
92
121
|
binding.root.requestLayout()
|
|
93
122
|
}
|
|
94
123
|
// must call it after init()
|
|
95
|
-
|
|
96
|
-
|
|
124
|
+
setFeedLoadListener(feedLoadListener)
|
|
125
|
+
setOnErrorListener(errorListener)
|
|
97
126
|
}
|
|
98
127
|
|
|
99
128
|
// may be called before onCreateView
|
|
@@ -110,15 +139,23 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
110
139
|
fun setFeedLoadListener(feedLoadListener: FeedLoadListener?) {
|
|
111
140
|
this.feedLoadListener = feedLoadListener
|
|
112
141
|
if (isStoryBlockInitializer) {
|
|
113
|
-
fwStoryBlockView?.setFeedLoadListener
|
|
142
|
+
fwStoryBlockView?.setFeedLoadListener { feedLoadState ->
|
|
143
|
+
feedLoadListener?.onFeedLoadStateChanged(feedLoadState)
|
|
144
|
+
if (feedLoadState !== FeedLoadState.Loading) {
|
|
145
|
+
hideLoading()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
114
148
|
}
|
|
115
149
|
}
|
|
116
150
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
151
|
+
fun setOnErrorListener(errorListener: FwErrorListener?) {
|
|
152
|
+
errorListener ?: return
|
|
153
|
+
this.errorListener = errorListener
|
|
120
154
|
if (isStoryBlockInitializer) {
|
|
121
|
-
fwStoryBlockView?.
|
|
155
|
+
fwStoryBlockView?.setOnErrorListener { fwError ->
|
|
156
|
+
hideLoading()
|
|
157
|
+
errorListener.onFwError(fwError)
|
|
158
|
+
}
|
|
122
159
|
}
|
|
123
160
|
}
|
|
124
161
|
|
|
@@ -130,29 +167,150 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
130
167
|
fwStoryBlockView?.pause()
|
|
131
168
|
}
|
|
132
169
|
|
|
133
|
-
fun
|
|
134
|
-
fwStoryBlockView?.
|
|
170
|
+
fun onViewportEntered() {
|
|
171
|
+
fwStoryBlockView?.onViewportEntered()
|
|
172
|
+
if (hasAdded && needIvsLoading) {
|
|
173
|
+
hasAdded = false
|
|
174
|
+
removeLoadingViewFromIvsPlayerView()
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fun onViewportLeft() {
|
|
179
|
+
fwStoryBlockView?.onViewportLeft()
|
|
180
|
+
if (!hasAdded && needIvsLoading) {
|
|
181
|
+
hasAdded = true
|
|
182
|
+
addLoadingViewToIvsPlayerView()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private fun addLoadingViewToIvsPlayerView() {
|
|
187
|
+
Handler(Looper.getMainLooper()).removeCallbacks(runnable)
|
|
188
|
+
|
|
189
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
190
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
191
|
+
for (view in ivsPlayerViewList) {
|
|
192
|
+
val loading = FWLoading(view.context)
|
|
193
|
+
loading.setBackgroundColor(Color.BLACK)
|
|
194
|
+
view.addView(loading, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
private fun removeLoadingViewFromIvsPlayerView() {
|
|
199
|
+
val storyBlockView = fwStoryBlockView
|
|
200
|
+
storyBlockView ?: return
|
|
201
|
+
|
|
202
|
+
Handler(Looper.getMainLooper()).removeCallbacks(runnable)
|
|
203
|
+
Handler(Looper.getMainLooper()).postDelayed(runnable, 1000)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
fun hideIvsPlayerView() {
|
|
208
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
209
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
210
|
+
hideIvsPlayerSurfaceView(ivsPlayerViewList)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
fun showIvsPlayerView() {
|
|
214
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
215
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
216
|
+
showIvsPlayerSurfaceView(ivsPlayerViewList)
|
|
135
217
|
}
|
|
136
218
|
|
|
137
|
-
fun
|
|
138
|
-
|
|
219
|
+
fun removeIvsPlayerView() {
|
|
220
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
221
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
222
|
+
removeIvsPlayerSurfaceView(ivsPlayerViewList)
|
|
139
223
|
}
|
|
140
224
|
|
|
141
|
-
fun
|
|
142
|
-
|
|
225
|
+
fun playIvsPlayer() {
|
|
226
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
227
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
228
|
+
playIvsPlayerView(ivsPlayerViewList)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
fun pauseIvsPlayer() {
|
|
232
|
+
val ivsPlayerViewList = mutableListOf<ViewGroup>()
|
|
233
|
+
searchVisibleIvsPlayerView(fwStoryBlockView, ivsPlayerViewList)
|
|
234
|
+
pauseIvsPlayerView(ivsPlayerViewList)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private fun searchVisibleIvsPlayerView(viewGroup: ViewGroup?, list: MutableList<ViewGroup>) {
|
|
238
|
+
viewGroup ?: return
|
|
239
|
+
|
|
240
|
+
val childCount = viewGroup.childCount
|
|
241
|
+
for (index in 0 until childCount) {
|
|
242
|
+
val view = viewGroup.getChildAt(index)
|
|
243
|
+
if (view is ViewGroup) {
|
|
244
|
+
val className = view.javaClass.name
|
|
245
|
+
if (className.equals("com.amazonaws.ivs.player.PlayerView")
|
|
246
|
+
|| className.equals("com.amazonaws.ivs.player.CustomPlayerView")) {
|
|
247
|
+
list.add(view)
|
|
248
|
+
} else {
|
|
249
|
+
searchVisibleIvsPlayerView(view, list)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private fun hideIvsPlayerSurfaceView(list: List<ViewGroup>?) {
|
|
256
|
+
list ?: return
|
|
257
|
+
for (viewGroup in list) {
|
|
258
|
+
val childCount = viewGroup.childCount
|
|
259
|
+
for (index in 0 until childCount) {
|
|
260
|
+
val view = viewGroup.getChildAt(index)
|
|
261
|
+
if (view is SurfaceView) {
|
|
262
|
+
view.visibility = View.INVISIBLE
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private fun showIvsPlayerSurfaceView(list: List<ViewGroup>?) {
|
|
269
|
+
list ?: return
|
|
270
|
+
for (viewGroup in list) {
|
|
271
|
+
val childCount = viewGroup.childCount
|
|
272
|
+
for (index in 0 until childCount) {
|
|
273
|
+
val view = viewGroup.getChildAt(index)
|
|
274
|
+
if (view is SurfaceView) {
|
|
275
|
+
view.visibility = View.VISIBLE
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private fun removeIvsPlayerSurfaceView(list: List<ViewGroup>?) {
|
|
282
|
+
list ?: return
|
|
283
|
+
for (viewGroup in list) {
|
|
284
|
+
val childCount = viewGroup.childCount
|
|
285
|
+
for (index in 0 until childCount) {
|
|
286
|
+
val view = viewGroup.getChildAt(index)
|
|
287
|
+
if (view is SurfaceView) {
|
|
288
|
+
viewGroup.removeView(view)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
fun openFullscreen() {
|
|
295
|
+
fwStoryBlockView?.openFullscreen()
|
|
143
296
|
}
|
|
144
297
|
|
|
145
298
|
companion object {
|
|
146
299
|
private const val VIDEO_FEED_PROPS_MODEL = "videoFeedPropsModel"
|
|
300
|
+
private const val NEED_IVS_LOADING = "needIvsLoading"
|
|
147
301
|
|
|
148
302
|
fun newInstance(
|
|
149
303
|
videoFeedPropsModel: FWVideoFeedPropsModel?,
|
|
304
|
+
needIvsLoading: Boolean? = false,
|
|
150
305
|
): StoryBlockFragment {
|
|
151
306
|
return StoryBlockFragment().apply {
|
|
152
307
|
arguments = Bundle().apply {
|
|
153
308
|
videoFeedPropsModel?.let {
|
|
154
309
|
putString(VIDEO_FEED_PROPS_MODEL, FWVideoFeedPropsModelSerializer.serialize(it).toString())
|
|
155
310
|
}
|
|
311
|
+
needIvsLoading?.let {
|
|
312
|
+
putBoolean(NEED_IVS_LOADING, needIvsLoading)
|
|
313
|
+
}
|
|
156
314
|
}
|
|
157
315
|
}
|
|
158
316
|
}
|
|
@@ -172,6 +330,70 @@ class StoryBlockFragment : FWBaseFragment() {
|
|
|
172
330
|
}
|
|
173
331
|
binding.storyBlockContainer.outlineProvider = outlineProvider
|
|
174
332
|
binding.storyBlockContainer.clipToOutline = true
|
|
333
|
+
|
|
334
|
+
loaderContainer?.outlineProvider = outlineProvider
|
|
335
|
+
loaderContainer?.clipToOutline = true
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private fun pauseIvsPlayerView(list: List<ViewGroup>?) {
|
|
340
|
+
list ?: return
|
|
341
|
+
for (view in list) {
|
|
342
|
+
if (view.javaClass.name.equals("com.amazonaws.ivs.player.CustomPlayerView")) {
|
|
343
|
+
val filed = view.javaClass.getDeclaredField("player")
|
|
344
|
+
filed.isAccessible = true
|
|
345
|
+
val player = filed.get(view)
|
|
346
|
+
val pauseMethod: Method = player.javaClass.getDeclaredMethod("pause")
|
|
347
|
+
pauseMethod.invoke(player)
|
|
348
|
+
} else if (view.javaClass.name.equals("com.amazonaws.ivs.player.PlayerView")) {
|
|
349
|
+
val getPlayerMethod: Method = view.javaClass.getDeclaredMethod("getPlayer")
|
|
350
|
+
val player = getPlayerMethod.invoke(view)
|
|
351
|
+
val pauseMethod: Method = player.javaClass.getDeclaredMethod("pause")
|
|
352
|
+
pauseMethod.invoke(player)
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private fun playIvsPlayerView(list: List<ViewGroup>?) {
|
|
358
|
+
list ?: return
|
|
359
|
+
for (view in list) {
|
|
360
|
+
if (view.javaClass.name.equals("com.amazonaws.ivs.player.CustomPlayerView")) {
|
|
361
|
+
val filed = view.javaClass.getDeclaredField("player")
|
|
362
|
+
filed.isAccessible = true
|
|
363
|
+
val player = filed.get(view)
|
|
364
|
+
val pauseMethod: Method = player.javaClass.getDeclaredMethod("play")
|
|
365
|
+
pauseMethod.invoke(player)
|
|
366
|
+
} else if (view.javaClass.name.equals("com.amazonaws.ivs.player.PlayerView")) {
|
|
367
|
+
val getPlayerMethod: Method = view.javaClass.getDeclaredMethod("getPlayer")
|
|
368
|
+
val player = getPlayerMethod.invoke(view)
|
|
369
|
+
val playMethod: Method = player.javaClass.getDeclaredMethod("play")
|
|
370
|
+
playMethod.invoke(player)
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private fun removeLoadingViewFromIvsPlayerView(viewGroup: ViewGroup?) {
|
|
376
|
+
viewGroup ?: return
|
|
377
|
+
|
|
378
|
+
val childCount = viewGroup.childCount
|
|
379
|
+
for (index in 0 until childCount) {
|
|
380
|
+
val view = viewGroup.getChildAt(index)
|
|
381
|
+
if (view is ViewGroup) {
|
|
382
|
+
val className = view.javaClass.name
|
|
383
|
+
if (className.equals("com.fireworksdk.bridge.components.base.FWLoading")) {
|
|
384
|
+
viewGroup.removeView(view)
|
|
385
|
+
} else {
|
|
386
|
+
removeLoadingViewFromIvsPlayerView(view)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
private fun hideLoading() {
|
|
393
|
+
if (loaderContainer?.visibility == View.VISIBLE) {
|
|
394
|
+
Handler(Looper.getMainLooper()).postDelayed({
|
|
395
|
+
loaderContainer?.visibility = View.GONE
|
|
396
|
+
}, 1000)
|
|
175
397
|
}
|
|
176
398
|
}
|
|
177
399
|
}
|
|
@@ -4,6 +4,7 @@ import android.content.Context
|
|
|
4
4
|
import android.util.AttributeSet
|
|
5
5
|
import android.view.ViewGroup
|
|
6
6
|
import android.widget.FrameLayout
|
|
7
|
+
import com.firework.error.FwErrorListener
|
|
7
8
|
import com.firework.videofeed.FeedViewStateListener
|
|
8
9
|
import com.firework.videofeed.FwVideoFeedView
|
|
9
10
|
import com.fireworksdk.bridge.models.*
|
|
@@ -52,17 +53,26 @@ class FWVideoFeed(
|
|
|
52
53
|
|
|
53
54
|
fun setOnFeedViewStateListener(feedViewStateListener: FeedViewStateListener?) {
|
|
54
55
|
this.feedViewStateListener = feedViewStateListener
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
56
|
+
videoFeedView.setOnFeedViewStateListener { feedViewState ->
|
|
57
|
+
if (!onWindowFocusChanged) {
|
|
58
|
+
videoFeedView.dispatchWindowFocusChanged(true)
|
|
59
|
+
onWindowFocusChanged = true
|
|
60
|
+
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
feedViewStateListener?.onLoadStateChanged(
|
|
63
|
+
feedViewState
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
fun setOnErrorListener(errorListener: FwErrorListener?) {
|
|
69
|
+
videoFeedView.setOnErrorListener { error ->
|
|
70
|
+
if (!onWindowFocusChanged) {
|
|
71
|
+
videoFeedView.dispatchWindowFocusChanged(true)
|
|
72
|
+
onWindowFocusChanged = true
|
|
65
73
|
}
|
|
74
|
+
|
|
75
|
+
errorListener?.onFwError(error)
|
|
66
76
|
}
|
|
67
77
|
}
|
|
68
78
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject
|
|
4
|
+
|
|
5
|
+
object FWAdConfigurationDeserializer {
|
|
6
|
+
|
|
7
|
+
private const val VAST_ATTRIBUTES_KEY = "vastAttributes"
|
|
8
|
+
private const val REQUIRES_ADS_KEY = "requiresAds"
|
|
9
|
+
private const val ADS_FETCH_TIMEOUT_KEY = "adsFetchTimeout"
|
|
10
|
+
|
|
11
|
+
private const val NAME_KEY = "name"
|
|
12
|
+
private const val VALUE_KEY = "value"
|
|
13
|
+
|
|
14
|
+
fun deserialize(responseJson: JSONObject?): FWAdConfigurationModel? {
|
|
15
|
+
responseJson ?: return null
|
|
16
|
+
|
|
17
|
+
val vastAttributesJsonArray = if (responseJson.has(VAST_ATTRIBUTES_KEY)) responseJson.optJSONArray(VAST_ATTRIBUTES_KEY) else null
|
|
18
|
+
var vastAttributes: MutableList<FWAdConfigurationModel.FWVastAttributeModel>? = null
|
|
19
|
+
if (vastAttributesJsonArray != null) {
|
|
20
|
+
vastAttributes = mutableListOf()
|
|
21
|
+
(0 until vastAttributesJsonArray.length()).forEach {
|
|
22
|
+
val item = vastAttributesJsonArray.getJSONObject(it)
|
|
23
|
+
val vastAttribute = deserializeVastAttribute(item)
|
|
24
|
+
if (vastAttribute != null) {
|
|
25
|
+
vastAttributes.add(vastAttribute)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
val requiresAds = responseJson.optBoolean(REQUIRES_ADS_KEY, false)
|
|
31
|
+
val adsFetchTimeout = if (!responseJson.isNull(ADS_FETCH_TIMEOUT_KEY)) responseJson.optInt(ADS_FETCH_TIMEOUT_KEY) else null
|
|
32
|
+
|
|
33
|
+
return FWAdConfigurationModel(
|
|
34
|
+
vastAttributes = vastAttributes,
|
|
35
|
+
requiresAds = requiresAds,
|
|
36
|
+
adsFetchTimeout = adsFetchTimeout,
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private fun deserializeVastAttribute(responseJson: JSONObject?): FWAdConfigurationModel.FWVastAttributeModel? {
|
|
41
|
+
responseJson ?: return null
|
|
42
|
+
val name = if (responseJson.has(NAME_KEY)) responseJson.optString(NAME_KEY) else null
|
|
43
|
+
val value = if (responseJson.has(VALUE_KEY)) responseJson.optString(VALUE_KEY) else null
|
|
44
|
+
return FWAdConfigurationModel.FWVastAttributeModel(
|
|
45
|
+
name = name,
|
|
46
|
+
value =value
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
data class FWAdConfigurationModel(
|
|
4
|
+
val vastAttributes: List<FWVastAttributeModel>? = null,
|
|
5
|
+
val requiresAds: Boolean? = null,
|
|
6
|
+
val adsFetchTimeout: Int? = null
|
|
7
|
+
) {
|
|
8
|
+
|
|
9
|
+
data class FWVastAttributeModel(
|
|
10
|
+
val name: String? = null,
|
|
11
|
+
val value: String? = null
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
import org.json.JSONArray
|
|
4
|
+
import org.json.JSONObject
|
|
5
|
+
|
|
6
|
+
object FWAdConfigurationSerializer {
|
|
7
|
+
|
|
8
|
+
private const val VAST_ATTRIBUTES_KEY = "vastAttributes"
|
|
9
|
+
private const val REQUIRES_ADS_KEY = "requiresAds"
|
|
10
|
+
private const val ADS_FETCH_TIMEOUT_KEY = "adsFetchTimeout"
|
|
11
|
+
|
|
12
|
+
private const val NAME_KEY = "name"
|
|
13
|
+
private const val VALUE_KEY = "value"
|
|
14
|
+
|
|
15
|
+
fun serialize(model: FWAdConfigurationModel?): JSONObject? {
|
|
16
|
+
model ?: return null
|
|
17
|
+
val jsonObject = JSONObject()
|
|
18
|
+
|
|
19
|
+
val list = model.vastAttributes
|
|
20
|
+
if (list != null) {
|
|
21
|
+
val vastAttributesJsonArray = JSONArray()
|
|
22
|
+
for (item in model.vastAttributes) {
|
|
23
|
+
val vastAttributes = serializeVastAttribute(item)
|
|
24
|
+
vastAttributesJsonArray.put(vastAttributes)
|
|
25
|
+
}
|
|
26
|
+
jsonObject.put(VAST_ATTRIBUTES_KEY, vastAttributesJsonArray)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
jsonObject.put(REQUIRES_ADS_KEY, model.requiresAds)
|
|
30
|
+
jsonObject.put(ADS_FETCH_TIMEOUT_KEY, model.adsFetchTimeout)
|
|
31
|
+
return jsonObject
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private fun serializeVastAttribute(model: FWAdConfigurationModel.FWVastAttributeModel?): JSONObject? {
|
|
35
|
+
model ?: return null
|
|
36
|
+
val jsonObject = JSONObject()
|
|
37
|
+
jsonObject.put(NAME_KEY, model.name)
|
|
38
|
+
jsonObject.put(VALUE_KEY, model.value)
|
|
39
|
+
|
|
40
|
+
return jsonObject
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject
|
|
4
|
+
|
|
5
|
+
object FWButtonInfoDeserializer {
|
|
6
|
+
|
|
7
|
+
private const val IMAGE_NAME_KEY = "imageName"
|
|
8
|
+
private const val TINT_COLOR_KEY = "tintColor"
|
|
9
|
+
|
|
10
|
+
fun deserialize(responseJson: JSONObject?): FWButtonInfoModel? {
|
|
11
|
+
responseJson ?: return null
|
|
12
|
+
|
|
13
|
+
val imageName = if (responseJson.has(IMAGE_NAME_KEY)) responseJson.optString(IMAGE_NAME_KEY) else null
|
|
14
|
+
val tintColor = if (responseJson.has(TINT_COLOR_KEY)) responseJson.optString(TINT_COLOR_KEY) else null
|
|
15
|
+
|
|
16
|
+
return FWButtonInfoModel(
|
|
17
|
+
imageName = imageName,
|
|
18
|
+
tintColor = tintColor
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject
|
|
4
|
+
|
|
5
|
+
object FWButtonInfoSerializer {
|
|
6
|
+
|
|
7
|
+
private const val IMAGE_NAME_KEY = "imageName"
|
|
8
|
+
private const val TINT_COLOR_KEY = "tintColor"
|
|
9
|
+
|
|
10
|
+
fun serialize(model: FWButtonInfoModel?): JSONObject? {
|
|
11
|
+
model ?: return null
|
|
12
|
+
val jsonObject = JSONObject()
|
|
13
|
+
jsonObject.put(IMAGE_NAME_KEY, model.imageName)
|
|
14
|
+
jsonObject.put(TINT_COLOR_KEY, model.tintColor)
|
|
15
|
+
return jsonObject
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
import org.json.JSONObject
|
|
4
|
+
|
|
5
|
+
object FWPlayerButtonConfigurationDeserializer {
|
|
6
|
+
|
|
7
|
+
private const val VIDEO_DETAIL_BUTTON_KEY = "videoDetailButton"
|
|
8
|
+
private const val CLOSE_BUTTON_KEY = "closeButton"
|
|
9
|
+
private const val MUTE_BUTTON_KEY = "muteButton"
|
|
10
|
+
private const val UNMUTE_BUTTON_KEY = "unmuteButton"
|
|
11
|
+
private const val PLAY_BUTTON_KEY = "playButton"
|
|
12
|
+
private const val PAUSE_BUTTON_KEY = "pauseButton"
|
|
13
|
+
|
|
14
|
+
fun deserialize(responseJson: JSONObject?): FWPlayerButtonConfigurationModel? {
|
|
15
|
+
responseJson ?: return null
|
|
16
|
+
|
|
17
|
+
val videoDetailButtonJsonObject = responseJson.optJSONObject(VIDEO_DETAIL_BUTTON_KEY)
|
|
18
|
+
val closeButtonJsonObject = responseJson.optJSONObject(CLOSE_BUTTON_KEY)
|
|
19
|
+
val muteButtonJsonObject = responseJson.optJSONObject(MUTE_BUTTON_KEY)
|
|
20
|
+
val unmuteButtonJsonObject = responseJson.optJSONObject(UNMUTE_BUTTON_KEY)
|
|
21
|
+
val playButtonJsonObject = responseJson.optJSONObject(PLAY_BUTTON_KEY)
|
|
22
|
+
val pauseButtonJsonObject = responseJson.optJSONObject(PAUSE_BUTTON_KEY)
|
|
23
|
+
|
|
24
|
+
return FWPlayerButtonConfigurationModel(
|
|
25
|
+
videoDetailButton = FWButtonInfoDeserializer.deserialize(videoDetailButtonJsonObject),
|
|
26
|
+
closeButton = FWButtonInfoDeserializer.deserialize(closeButtonJsonObject),
|
|
27
|
+
muteButton = FWButtonInfoDeserializer.deserialize(muteButtonJsonObject),
|
|
28
|
+
unmuteButton = FWButtonInfoDeserializer.deserialize(unmuteButtonJsonObject),
|
|
29
|
+
playButton = FWButtonInfoDeserializer.deserialize(playButtonJsonObject),
|
|
30
|
+
pauseButton = FWButtonInfoDeserializer.deserialize(pauseButtonJsonObject),
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
}
|
package/android/src/main/java/com/fireworksdk/bridge/models/FWPlayerButtonConfigurationModel.kt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.fireworksdk.bridge.models
|
|
2
|
+
|
|
3
|
+
data class FWPlayerButtonConfigurationModel(
|
|
4
|
+
val videoDetailButton: FWButtonInfoModel? = null,
|
|
5
|
+
val closeButton: FWButtonInfoModel? = null,
|
|
6
|
+
val muteButton: FWButtonInfoModel? = null,
|
|
7
|
+
val unmuteButton: FWButtonInfoModel? = null,
|
|
8
|
+
val playButton: FWButtonInfoModel? = null,
|
|
9
|
+
val pauseButton: FWButtonInfoModel? = null,
|
|
10
|
+
)
|