react-native-firework-sdk 2.0.0 → 2.1.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/android/build.gradle +5 -3
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFragment.kt +129 -0
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFrameLayout.kt +84 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +2 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +18 -5
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +33 -9
- package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResult.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResultDeserializer.kt +33 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +126 -45
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +6 -3
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +2 -2
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +9 -1
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +81 -50
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +9 -2
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +4 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +48 -16
- package/android/src/main/res/layout/fw_bridge_story_block.xml +24 -0
- package/ios/Components/StoryBlock.swift +33 -2
- package/ios/Components/StoryBlockManager.m +32 -0
- package/ios/Components/VideoFeed.swift +9 -29
- package/ios/Components/VideoFeedManager.m +11 -6
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +378 -104
- package/ios/Models/NativeToRN/FireworkEventName.swift +3 -1
- package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
- package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +27 -0
- package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +5 -1
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +30 -0
- package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +13 -0
- package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
- package/ios/Modules/Shopping/ShoppingModule.m +2 -1
- package/ios/Modules/Shopping/ShoppingModule.swift +106 -30
- package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
- package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
- package/ios/Utils/AppLanguage/Bundle+FWSwizzle.swift +58 -0
- package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +139 -0
- package/ios/Utils/AppLanguage/FWLanguageUtil.swift +43 -0
- package/ios/Utils/AppLanguage/NumberFormatter+FWSwizzle.swift +25 -0
- package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +91 -0
- package/ios/Utils/AppLanguage/UILabel+FWSwizzle.swift +98 -0
- package/ios/Utils/AppLanguage/UITextField+FWSwizzle.swift +97 -0
- package/ios/Utils/AppLanguage/UITextView+FWSwizzle.swift +97 -0
- package/ios/Utils/AppLanguage/UIView+FWSwizzle.swift +38 -0
- package/ios/Utils/AppLanguage/UIViewController+FWSwizzle.swift +32 -0
- package/ios/Utils/AppLanguage/UIWindow+FWSwizzle.swift +26 -0
- package/ios/Utils/AppLanguage/URLSession+FWSwizzle.swift +69 -0
- package/ios/Utils/{DispatchQueue+FWOnce.swift → Extensions/DispatchQueue+FWOnce.swift} +3 -3
- package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +6 -8
- package/ios/Utils/Extensions/UIView+FWUIHierarchy.swift +47 -0
- package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.h +25 -0
- package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.m +75 -0
- package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.h +21 -0
- package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.m +124 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.h +11 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.m +86 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.h +16 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.m +55 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.h +18 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.m +39 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.h +54 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.m +141 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.h +16 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.m +20 -0
- package/ios/Utils/FWRTL/Classes/Utils/FWRTLDefinitions.h +52 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.h +19 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.m +49 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.h +21 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.m +38 -0
- package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.h +18 -0
- package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.m +43 -0
- package/ios/Utils/FWSwizzleLoader.m +6 -1
- package/ios/Utils/FWSwizzleLoader.swift +13 -0
- package/ios/Utils/FWSwizzleUtil.swift +17 -9
- package/ios/react_native_firework_sdk.h +1 -0
- package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
- package/lib/commonjs/FireworkSDK.js +21 -4
- package/lib/commonjs/FireworkSDK.js.map +1 -1
- package/lib/commonjs/VideoShopping.js +20 -37
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +190 -125
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +11 -1
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/FWEventName.js +2 -0
- package/lib/commonjs/models/FWEventName.js.map +1 -1
- package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
- package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
- package/lib/module/FireworkSDK.js +21 -4
- package/lib/module/FireworkSDK.js.map +1 -1
- package/lib/module/VideoShopping.js +20 -39
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +179 -131
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +10 -1
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/FWEventName.js +2 -0
- package/lib/module/models/FWEventName.js.map +1 -1
- package/lib/module/models/ShoppingCTAResult.js +2 -0
- package/lib/module/modules/FireworkSDKModule.js.map +1 -1
- package/lib/module/modules/ShoppingModule.js.map +1 -1
- package/lib/typescript/FireworkSDK.d.ts +7 -4
- package/lib/typescript/VideoShopping.d.ts +9 -11
- package/lib/typescript/components/StoryBlock.d.ts +19 -25
- package/lib/typescript/index.d.ts +6 -6
- package/lib/typescript/models/FWEventName.d.ts +2 -0
- package/lib/typescript/models/FWEvents.d.ts +14 -1
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +36 -1
- package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
- package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
- package/lib/typescript/modules/ShoppingModule.d.ts +2 -1
- package/package.json +2 -2
- package/react-native-firework-sdk.podspec +26 -24
- package/src/FireworkSDK.ts +18 -5
- package/src/VideoShopping.ts +40 -53
- package/src/components/StoryBlock.tsx +199 -96
- package/src/components/VideoFeed.tsx +11 -0
- package/src/index.ts +15 -7
- package/src/models/FWEventName.ts +2 -0
- package/src/models/FWEvents.ts +14 -1
- package/src/models/ProductInfoViewConfiguration.ts +38 -1
- package/src/models/ShoppingCTAResult.ts +11 -0
- package/src/modules/FireworkSDKModule.ts +1 -2
- package/src/modules/ShoppingModule.ts +5 -5
- package/android/src/main/java/com/fireworksdk/bridge/constants/FWCommandConstant.kt +0 -6
- package/ios/Utils/UIView+ParentViewController.swift +0 -21
- package/lib/commonjs/models/AddToCartResult.js +0 -2
- package/lib/module/models/AddToCartResult.js +0 -2
- package/lib/typescript/models/AddToCartResult.d.ts +0 -10
- package/src/models/AddToCartResult.ts +0 -10
- /package/ios/Utils/{String+Color.swift → Extensions/String+Color.swift} +0 -0
- /package/ios/Utils/{UIView+Constraints.swift → Extensions/UIView+Constraints.swift} +0 -0
- /package/ios/Utils/{UIViewController+AttachChild.swift → Extensions/UIViewController+AttachChild.swift} +0 -0
- /package/lib/commonjs/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
- /package/lib/module/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt
CHANGED
|
@@ -7,7 +7,6 @@ import com.facebook.react.uimanager.SimpleViewManager
|
|
|
7
7
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
8
8
|
|
|
9
9
|
import com.facebook.react.uimanager.annotations.ReactProp
|
|
10
|
-
import com.fireworksdk.bridge.constants.FWCommandConstant
|
|
11
10
|
import com.facebook.react.common.MapBuilder
|
|
12
11
|
import com.firework.videofeed.FeedItemClickListener
|
|
13
12
|
import com.firework.videofeed.FeedViewState
|
|
@@ -148,7 +147,7 @@ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
|
|
|
148
147
|
|
|
149
148
|
override fun getCommandsMap(): MutableMap<String, Int> {
|
|
150
149
|
val map: MutableMap<String, Int> = HashMap()
|
|
151
|
-
map["refresh"] =
|
|
150
|
+
map["refresh"] = COMMAND_REFRESH
|
|
152
151
|
return map
|
|
153
152
|
}
|
|
154
153
|
|
|
@@ -156,7 +155,7 @@ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
|
|
|
156
155
|
super.receiveCommand(root, commandId, args)
|
|
157
156
|
FWLogUtils.d { "FWVideoFeedManager receiveCommand commandId: $commandId" }
|
|
158
157
|
when (commandId?.toInt()) {
|
|
159
|
-
|
|
158
|
+
COMMAND_REFRESH -> {
|
|
160
159
|
FWLogUtils.d { "FWVideoFeedManager call refresh" }
|
|
161
160
|
root.refresh()
|
|
162
161
|
}
|
|
@@ -175,4 +174,8 @@ class FWVideoFeedManager : SimpleViewManager<FWVideoFeed>() {
|
|
|
175
174
|
.build()
|
|
176
175
|
}
|
|
177
176
|
|
|
177
|
+
companion object {
|
|
178
|
+
private const val COMMAND_REFRESH = 1000001
|
|
179
|
+
}
|
|
180
|
+
|
|
178
181
|
}
|
package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt
CHANGED
|
@@ -8,8 +8,8 @@ interface FWVideoShoppingInterface {
|
|
|
8
8
|
|
|
9
9
|
fun init()
|
|
10
10
|
fun updateVideoProducts(productArray: ReadableArray?, callbackId: String?)
|
|
11
|
-
fun
|
|
12
|
-
fun
|
|
11
|
+
fun setProductInfoViewConfiguration(config: ReadableMap?)
|
|
12
|
+
fun updateShoppingCTAResult(result: ReadableMap?, callbackId: Int?)
|
|
13
13
|
fun jumpToCartPage(callbackId: Int?, props: ReadableMap?)
|
|
14
14
|
fun setCartIconVisible(visible: Boolean?)
|
|
15
15
|
fun setCartItemCount(count: Int?)
|
package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt
CHANGED
|
@@ -3,10 +3,10 @@ package com.fireworksdk.bridge.reactnative.module
|
|
|
3
3
|
import android.app.Activity
|
|
4
4
|
import com.facebook.react.bridge.*
|
|
5
5
|
import com.firework.sdk.FireworkSdk
|
|
6
|
-
import com.firework.videofeed.PlayerActivity
|
|
7
6
|
import com.fireworksdk.bridge.FWInitializationProvider
|
|
8
7
|
import com.fireworksdk.bridge.reactnative.models.FWNavigatorInterface
|
|
9
8
|
import com.fireworksdk.bridge.reactnative.utils.FWEventUtils
|
|
9
|
+
import com.fireworksdk.bridge.utils.FWGlobalDataUtil
|
|
10
10
|
import com.fireworksdk.bridge.utils.FWLogUtils
|
|
11
11
|
|
|
12
12
|
|
|
@@ -30,6 +30,14 @@ class FWNavigatorModule(
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (isTaskRoot(activity)) {
|
|
33
|
+
if (FWGlobalDataUtil.storyBlockFragment?.isFullScreen() == true) {
|
|
34
|
+
UiThreadUtil.runOnUiThread {
|
|
35
|
+
FWGlobalDataUtil.storyBlockFragment?.toggleFullScreen()
|
|
36
|
+
}
|
|
37
|
+
promise.resolve(true)
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
promise.resolve(false)
|
|
34
42
|
return
|
|
35
43
|
}
|
package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt
CHANGED
|
@@ -7,12 +7,9 @@ import com.firework.common.product.CurrencyCode
|
|
|
7
7
|
import com.firework.common.product.Product
|
|
8
8
|
import com.firework.error.shopping.ShoppingError
|
|
9
9
|
import com.firework.sdk.FireworkSdk
|
|
10
|
-
import com.firework.shopping
|
|
11
|
-
import com.firework.shopping.Shopping
|
|
10
|
+
import com.firework.shopping.*
|
|
12
11
|
import com.fireworksdk.bridge.FWInitializationProvider
|
|
13
|
-
import com.fireworksdk.bridge.models
|
|
14
|
-
import com.fireworksdk.bridge.models.FWVideoShoppingProduct
|
|
15
|
-
import com.fireworksdk.bridge.models.FWVideoShoppingProductDeserializer
|
|
12
|
+
import com.fireworksdk.bridge.models.*
|
|
16
13
|
import com.fireworksdk.bridge.reactnative.models.FWVideoShoppingInterface
|
|
17
14
|
import com.fireworksdk.bridge.reactnative.utils.FWEventUtils
|
|
18
15
|
import com.fireworksdk.bridge.utils.FWDateUtils
|
|
@@ -28,7 +25,7 @@ class FWVideoShoppingModule(
|
|
|
28
25
|
reactContext: ReactApplicationContext
|
|
29
26
|
) : ReactContextBaseJavaModule(reactContext), FWVideoShoppingInterface {
|
|
30
27
|
|
|
31
|
-
private var
|
|
28
|
+
private var ctaHandler: Triple<Int, String, String>? = null
|
|
32
29
|
private var cartClickHandler: Pair<Int, Activity>? = null
|
|
33
30
|
private val updateProductHandler: HashMap<String, List<Product>> = HashMap()
|
|
34
31
|
private val updateProductHydratorHandler: HashMap<String, ProductHydrator> = HashMap()
|
|
@@ -129,47 +126,80 @@ class FWVideoShoppingModule(
|
|
|
129
126
|
}
|
|
130
127
|
|
|
131
128
|
@ReactMethod
|
|
132
|
-
override fun
|
|
133
|
-
FWLogUtils.d { "FWVideoShoppingModule
|
|
129
|
+
override fun setProductInfoViewConfiguration(config: ReadableMap?) {
|
|
130
|
+
FWLogUtils.d { "FWVideoShoppingModule setProductInfoViewConfiguration: $callbackId, config: $config" }
|
|
134
131
|
val configMap = config?.toHashMap() ?: hashMapOf()
|
|
135
132
|
val jsonObject = JSONObject(configMap)
|
|
136
133
|
val configModel = FWProductInfoViewConfigurationDeserializer.deserialize(jsonObject)
|
|
137
|
-
FWLogUtils.d { "FWVideoShoppingModule
|
|
134
|
+
FWLogUtils.d { "FWVideoShoppingModule setProductInfoViewConfiguration: $callbackId, configModel: $configModel" }
|
|
135
|
+
|
|
136
|
+
if (configModel == null) {
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
val isLinkButtonHidden = configModel.linkButton?.isHidden == true
|
|
141
|
+
var text = ShoppingCtaButtonOptions.Text.ADD_TO_CART
|
|
142
|
+
when (configModel.ctaButton?.text) {
|
|
143
|
+
FWProductInfoViewConfiguration.CtaButtonConfiguration.TextValue.ShopNow -> {
|
|
144
|
+
text = ShoppingCtaButtonOptions.Text.SHOP_NOW
|
|
145
|
+
}
|
|
146
|
+
else -> {}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
FireworkSdk.shopping.setShoppingViewOptions(
|
|
150
|
+
ShoppingViewOptions(
|
|
151
|
+
ProductDetailsOptions(
|
|
152
|
+
linkButtonOptions = LinkButtonOptions(isVisible = !isLinkButtonHidden),
|
|
153
|
+
shoppingCtaButtonOptions = ShoppingCtaButtonOptions(text = text),
|
|
154
|
+
),
|
|
155
|
+
),
|
|
156
|
+
)
|
|
138
157
|
}
|
|
139
158
|
|
|
140
159
|
@ReactMethod
|
|
141
|
-
override fun
|
|
142
|
-
FWLogUtils.d { "FWVideoShoppingModule
|
|
143
|
-
|
|
160
|
+
override fun updateShoppingCTAResult(result: ReadableMap?, callbackId: Int?) {
|
|
161
|
+
FWLogUtils.d { "FWVideoShoppingModule updateShoppingCTAResult: $callbackId, result: $result, ctaHandler: ${ctaHandler?.first}" }
|
|
162
|
+
val resultMap = result?.toHashMap() ?: hashMapOf()
|
|
163
|
+
val jsonObject = JSONObject(resultMap)
|
|
164
|
+
val resultModel = FWShoppingCtaResultDeserializer.deserialize(jsonObject)
|
|
165
|
+
FWLogUtils.d { "FWVideoShoppingModule updateShoppingCTAResult: $callbackId, resultModel: $resultModel" }
|
|
166
|
+
|
|
167
|
+
if (resultModel == null) {
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (callbackId == null || ctaHandler?.first != callbackId) {
|
|
144
172
|
return
|
|
145
173
|
}
|
|
146
174
|
|
|
147
|
-
val productId =
|
|
175
|
+
val productId = ctaHandler?.second
|
|
148
176
|
productId ?: return
|
|
149
177
|
|
|
150
|
-
val unitId =
|
|
178
|
+
val unitId = ctaHandler?.third
|
|
151
179
|
if (unitId.isNullOrBlank()) {
|
|
152
180
|
return
|
|
153
181
|
}
|
|
154
182
|
|
|
155
|
-
when {
|
|
156
|
-
|
|
157
|
-
val
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
183
|
+
when (resultModel.res) {
|
|
184
|
+
FWShoppingCtaResult.Res.Success -> {
|
|
185
|
+
val numberOfItemsInCart = FireworkSdk.shopping.numberOfItemsInCart
|
|
186
|
+
FireworkSdk.shopping.setCtaButtonStatus(Shopping.CtaButtonStatus.Success)
|
|
187
|
+
FireworkSdk.shopping.numberOfItemsInCart = numberOfItemsInCart
|
|
188
|
+
}
|
|
189
|
+
FWShoppingCtaResult.Res.Fail -> {
|
|
190
|
+
FireworkSdk.shopping.setCtaButtonStatus(Shopping.CtaButtonStatus.Error)
|
|
163
191
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
FireworkSdk.shopping.setAddToCartStatus(status)
|
|
167
|
-
Toast.makeText(currentActivity, tip, Toast.LENGTH_LONG).show()
|
|
192
|
+
FWShoppingCtaResult.Res.Loading -> {
|
|
193
|
+
FireworkSdk.shopping.setCtaButtonStatus(Shopping.CtaButtonStatus.Loading)
|
|
168
194
|
}
|
|
169
|
-
|
|
170
|
-
|
|
195
|
+
else -> {
|
|
196
|
+
// throw IllegalStateException("Not allowed: ${resultModel.res}")
|
|
171
197
|
}
|
|
172
198
|
}
|
|
199
|
+
|
|
200
|
+
if (!resultModel.tips.isNullOrBlank()) {
|
|
201
|
+
Toast.makeText(currentActivity, resultModel.tips, Toast.LENGTH_LONG).show()
|
|
202
|
+
}
|
|
173
203
|
}
|
|
174
204
|
|
|
175
205
|
@ReactMethod
|
|
@@ -196,33 +226,32 @@ class FWVideoShoppingModule(
|
|
|
196
226
|
}
|
|
197
227
|
|
|
198
228
|
private fun cartListener() {
|
|
199
|
-
FireworkSdk.shopping.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
229
|
+
FireworkSdk.shopping.setOnCartClickListener(object : Shopping.OnCartClickListener {
|
|
230
|
+
override fun onCartClick() {
|
|
231
|
+
FWLogUtils.d { "FWVideoShoppingModule cartClicked" }
|
|
232
|
+
val activity = FWInitializationProvider.INSTANCE.resumedActivity
|
|
233
|
+
activity ?: return
|
|
234
|
+
val callbackId = generateCallbackId()
|
|
235
|
+
cartClickHandler = Pair(callbackId, activity)
|
|
236
|
+
FWEventUtils.sendCartIconClickEvent(reactApplicationContext, callbackId)
|
|
237
|
+
}
|
|
238
|
+
})
|
|
203
239
|
|
|
204
|
-
|
|
240
|
+
FireworkSdk.shopping.setOnCtaButtonClicked { productId, unitId, productWebUrl ->
|
|
241
|
+
FWLogUtils.d { "FWVideoShoppingModule updateCart, productId: $productId, unitId: $unitId" }
|
|
205
242
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
243
|
+
FireworkSdk.shopping.setCtaButtonStatus(Shopping.CtaButtonStatus.Loading)
|
|
244
|
+
|
|
245
|
+
val callbackId = generateCallbackId()
|
|
246
|
+
ctaHandler = Triple(callbackId, productId, unitId)
|
|
247
|
+
FWEventUtils.sendShoppingCtaButtonClickEvent(reactApplicationContext, productId, unitId, productWebUrl, callbackId)
|
|
248
|
+
}
|
|
210
249
|
|
|
211
|
-
override fun onCartClicked() {
|
|
212
|
-
FWLogUtils.d { "FWVideoShoppingModule cartClicked" }
|
|
213
|
-
val activity = FWInitializationProvider.INSTANCE.resumedActivity
|
|
214
|
-
activity ?: return
|
|
215
|
-
val callbackId = generateCallbackId()
|
|
216
|
-
cartClickHandler = Pair(callbackId, activity)
|
|
217
|
-
FWEventUtils.sendCartIconClickEvent(reactApplicationContext, callbackId)
|
|
218
|
-
}
|
|
219
|
-
},
|
|
220
|
-
)
|
|
221
250
|
FireworkSdk.shopping.setOnShoppingErrorListener(
|
|
222
251
|
object : Shopping.OnShoppingErrorListener {
|
|
223
252
|
override fun onShoppingError(error: ShoppingError) {
|
|
224
253
|
when (error) {
|
|
225
|
-
is ShoppingError.
|
|
254
|
+
is ShoppingError.CtaButtonClickError.Timeout -> {
|
|
226
255
|
}
|
|
227
256
|
else -> {}
|
|
228
257
|
}
|
|
@@ -232,7 +261,7 @@ class FWVideoShoppingModule(
|
|
|
232
261
|
}
|
|
233
262
|
|
|
234
263
|
private fun productListener() {
|
|
235
|
-
FireworkSdk.shopping.
|
|
264
|
+
FireworkSdk.shopping.setOnProductHydrationListener(object : Shopping.OnProductHydrationListener {
|
|
236
265
|
override fun onProductHydration(products: List<Product>, hydrator: ProductHydrator) {
|
|
237
266
|
FWLogUtils.d { "FWVideoShoppingModule hydrateProducts, hydrator: ${hydrator.hashCode()}" }
|
|
238
267
|
if (products.isEmpty()) {
|
|
@@ -243,8 +272,10 @@ class FWVideoShoppingModule(
|
|
|
243
272
|
updateProductHydratorHandler[callbackId] = hydrator
|
|
244
273
|
FWEventUtils.sendUpdateProductsDetailsEvent(reactApplicationContext, products, callbackId)
|
|
245
274
|
}
|
|
275
|
+
})
|
|
246
276
|
|
|
247
|
-
|
|
277
|
+
FireworkSdk.shopping.setOnProductLinkClickListener(object : Shopping.OnProductLinkClickListener {
|
|
278
|
+
override fun onProductLinkClick(
|
|
248
279
|
productId: String,
|
|
249
280
|
unitId: String,
|
|
250
281
|
productWebUrl: String?
|
|
@@ -135,12 +135,13 @@ object FWEventUtils {
|
|
|
135
135
|
sendEvent(reactContext, FWEventName.VideoPlayback.rawValue, eventMap)
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
fun
|
|
138
|
+
fun sendShoppingCtaButtonClickEvent(reactContext: ReactContext, productId: String?, unitId: String?, url: String?, callbackId: Int?) {
|
|
139
139
|
val eventMap = Arguments.createMap()
|
|
140
140
|
eventMap.putString("productId", productId)
|
|
141
141
|
eventMap.putString("unitId", unitId)
|
|
142
|
+
eventMap.putString("url", url)
|
|
142
143
|
eventMap.putInt("callbackId", callbackId?:0)
|
|
143
|
-
sendEvent(reactContext, FWVideoShoppingEventName.
|
|
144
|
+
sendEvent(reactContext, FWVideoShoppingEventName.CtaButtonClick.rawValue, eventMap)
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
fun sendCartIconClickEvent(reactContext: ReactContext, callbackId: Int?) {
|
|
@@ -205,6 +206,12 @@ object FWEventUtils {
|
|
|
205
206
|
receiveEvent(reactContext, targetTag, FWStoryBlockEventName.StoryBlockLoadFinished.rawValue, eventMap)
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
fun receiveStoryBlockFullScreenStateChangedEvent(reactContext: ReactContext, targetTag: Int, isFullScreen: Boolean) {
|
|
210
|
+
val eventMap = Arguments.createMap()
|
|
211
|
+
eventMap.putBoolean("isFullScreen", isFullScreen)
|
|
212
|
+
receiveEvent(reactContext, targetTag, FWStoryBlockEventName.StoryBlockFullScreenStateChanged.rawValue, eventMap)
|
|
213
|
+
}
|
|
214
|
+
|
|
208
215
|
private fun receiveEvent(reactContext: ReactContext, targetTag: Int, eventName: String, event: WritableMap?) {
|
|
209
216
|
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
|
|
210
217
|
targetTag,
|
|
@@ -324,7 +324,7 @@ object FWConfigUtil {
|
|
|
324
324
|
|
|
325
325
|
return AdBadgeOption.Builder()
|
|
326
326
|
// .adBadgeBackColor(Color.parseColor("#FF6200EE"))
|
|
327
|
-
.adBadgeTextColor(Color.parseColor("#FFFFFFFF"))
|
|
327
|
+
// .adBadgeTextColor(Color.parseColor("#FFFFFFFF"))
|
|
328
328
|
.adBadgeLabel(AdBadgeTextType.SPONSORED)
|
|
329
329
|
.adBadgeIsHidden(false)
|
|
330
330
|
.adBadgeShowOnThumbnails(false)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package com.fireworksdk.bridge.utils
|
|
2
2
|
|
|
3
|
+
import com.fireworksdk.bridge.components.videofeed.StoryBlockFragment
|
|
3
4
|
import com.fireworksdk.bridge.models.FWAdBadgeConfigModel
|
|
5
|
+
import com.fireworksdk.bridge.models.weakProperty
|
|
4
6
|
|
|
5
7
|
object FWGlobalDataUtil {
|
|
6
8
|
|
|
@@ -11,4 +13,6 @@ object FWGlobalDataUtil {
|
|
|
11
13
|
var videoPlaybackEventEnabled: Boolean = false
|
|
12
14
|
|
|
13
15
|
var customClickLinkButtonEnabled: Boolean = false
|
|
16
|
+
|
|
17
|
+
var storyBlockFragment by weakProperty<StoryBlockFragment?>()
|
|
14
18
|
}
|
|
@@ -10,40 +10,66 @@ object FWLanguageUtil {
|
|
|
10
10
|
private const val LOCALE_SP = "fw_locale_sp"
|
|
11
11
|
private const val LOCALE_KEY = "fw_locale_key"
|
|
12
12
|
|
|
13
|
-
private
|
|
13
|
+
private var systemLocale: Locale? = null
|
|
14
|
+
|
|
15
|
+
private fun readLocaleFromSp(context: Context) {
|
|
14
16
|
locale = context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
15
17
|
.getString(LOCALE_KEY, null)
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
fun changeLanguage(context: Context, l: String?): Boolean {
|
|
19
|
-
|
|
21
|
+
readLocaleFromSp(context)
|
|
22
|
+
val sharedPreferences =
|
|
23
|
+
context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
24
|
+
if (l.isNullOrBlank()) {
|
|
25
|
+
if (locale.isNullOrBlank()) {
|
|
26
|
+
return true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
locale = null
|
|
30
|
+
sharedPreferences.edit().apply {
|
|
31
|
+
remove(LOCALE_KEY)
|
|
32
|
+
}.commit()
|
|
33
|
+
|
|
34
|
+
// change sdk locale to system locale
|
|
35
|
+
// val sysLocale = getSystemLocale()
|
|
36
|
+
// if (sysLocale.country.isNullOrBlank()) {
|
|
37
|
+
// FwSDK.changeAppLocale(context, sysLocale.language)
|
|
38
|
+
// } else {
|
|
39
|
+
// FwSDK.changeAppLocale(context, "${sysLocale.language}-${sysLocale.country}")
|
|
40
|
+
// }
|
|
41
|
+
|
|
42
|
+
restartActivity(context)
|
|
43
|
+
return true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!isValidLocale(l)) {
|
|
20
47
|
return false
|
|
21
48
|
}
|
|
22
49
|
|
|
23
|
-
if (
|
|
50
|
+
if (locale == l) {
|
|
24
51
|
return true
|
|
25
52
|
}
|
|
26
53
|
|
|
27
54
|
locale = l
|
|
28
55
|
|
|
29
56
|
// save to sp
|
|
30
|
-
val sharedPreferences =
|
|
31
|
-
context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
32
57
|
sharedPreferences.edit().apply {
|
|
33
58
|
putString(LOCALE_KEY, l)
|
|
34
59
|
}.apply()
|
|
35
60
|
|
|
36
|
-
|
|
37
|
-
context.recreate()
|
|
38
|
-
}
|
|
61
|
+
restartActivity(context)
|
|
39
62
|
|
|
40
63
|
return true
|
|
41
64
|
}
|
|
42
65
|
|
|
43
|
-
fun updateBaseContextLocale(context: Context
|
|
44
|
-
|
|
66
|
+
fun updateBaseContextLocale(context: Context): Context {
|
|
67
|
+
if (systemLocale == null) {
|
|
68
|
+
systemLocale = Locale.getDefault()
|
|
69
|
+
}
|
|
70
|
+
|
|
45
71
|
if (locale.isNullOrBlank()) {
|
|
46
|
-
|
|
72
|
+
readLocaleFromSp(context)
|
|
47
73
|
}
|
|
48
74
|
locale?.let {
|
|
49
75
|
val locale = getLocale(it)
|
|
@@ -51,7 +77,10 @@ object FWLanguageUtil {
|
|
|
51
77
|
|
|
52
78
|
return updateResourcesLocale(context, locale)
|
|
53
79
|
}
|
|
54
|
-
|
|
80
|
+
|
|
81
|
+
val l = getSystemLocale()
|
|
82
|
+
Locale.setDefault(l)
|
|
83
|
+
return updateResourcesLocale(context, l)
|
|
55
84
|
}
|
|
56
85
|
|
|
57
86
|
private fun updateResourcesLocale(context: Context, locale: Locale): Context {
|
|
@@ -78,11 +107,14 @@ object FWLanguageUtil {
|
|
|
78
107
|
return Locale(locale)
|
|
79
108
|
}
|
|
80
109
|
|
|
81
|
-
private fun
|
|
82
|
-
if (
|
|
83
|
-
|
|
110
|
+
private fun restartActivity(context: Context) {
|
|
111
|
+
if (context is Activity) {
|
|
112
|
+
context.recreate()
|
|
84
113
|
}
|
|
85
|
-
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private fun getSystemLocale(): Locale {
|
|
117
|
+
return systemLocale ?: Locale.getDefault()
|
|
86
118
|
}
|
|
87
119
|
|
|
88
120
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
4
|
+
android:layout_width="match_parent"
|
|
5
|
+
android:layout_height="match_parent"
|
|
6
|
+
android:layout_gravity="center"
|
|
7
|
+
android:layout_marginVertical="16dp">
|
|
8
|
+
|
|
9
|
+
<FrameLayout
|
|
10
|
+
android:id="@+id/story_block_container"
|
|
11
|
+
android:layout_width="0dp"
|
|
12
|
+
android:layout_height="0dp"
|
|
13
|
+
app:layout_constraintBottom_toBottomOf="parent"
|
|
14
|
+
app:layout_constraintEnd_toEndOf="parent"
|
|
15
|
+
app:layout_constraintStart_toStartOf="parent"
|
|
16
|
+
app:layout_constraintTop_toTopOf="parent">
|
|
17
|
+
|
|
18
|
+
<com.firework.storyblock.FwStoryBlockView
|
|
19
|
+
android:id="@+id/story_block"
|
|
20
|
+
android:layout_width="match_parent"
|
|
21
|
+
android:layout_height="match_parent" />
|
|
22
|
+
|
|
23
|
+
</FrameLayout>
|
|
24
|
+
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@@ -25,6 +25,7 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
|
|
|
25
25
|
@objc public var playlist: String = ""
|
|
26
26
|
@objc public var dynamicContentParameters: [String: [String]] = [:]
|
|
27
27
|
@objc public var enablePictureInPicture: Bool = false
|
|
28
|
+
@objc public var adConfiguration: AdConfiguration?
|
|
28
29
|
|
|
29
30
|
public weak var delegate: StoryBlockViewDelegate?
|
|
30
31
|
|
|
@@ -61,18 +62,32 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
private func embed() {
|
|
64
|
-
guard let parentVC =
|
|
65
|
+
guard let parentVC = fwParentViewController else {
|
|
65
66
|
return
|
|
66
67
|
}
|
|
67
68
|
guard self.storyBlockVC == nil else {
|
|
68
69
|
return
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
var resultStoryBlockVC: StoryBlockViewController?
|
|
73
|
+
if let fireworkVideoAdConfiguration = RCTConvert.getFireworkVideoAdConfiguration(adConfiguration) {
|
|
74
|
+
resultStoryBlockVC = StoryBlockViewController(source: source, adConfiguration: fireworkVideoAdConfiguration)
|
|
75
|
+
} else {
|
|
76
|
+
resultStoryBlockVC = StoryBlockViewController(source: source)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
guard let storyBlockVC = resultStoryBlockVC else {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
72
83
|
if self.enablePictureInPicture {
|
|
73
84
|
storyBlockVC.isPictureInPictureEnabled = true
|
|
74
85
|
}
|
|
75
86
|
|
|
87
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip {
|
|
88
|
+
storyBlockVC.view.fwrtl_viewType = FWRTLViewTypeFlip
|
|
89
|
+
}
|
|
90
|
+
|
|
76
91
|
storyBlockVC.delegate = self
|
|
77
92
|
self.storyBlockVC = storyBlockVC
|
|
78
93
|
parentVC.attachChild(storyBlockVC, to: self)
|
|
@@ -89,6 +104,22 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
|
|
|
89
104
|
self.storyBlockVC = nil
|
|
90
105
|
}
|
|
91
106
|
|
|
107
|
+
@objc
|
|
108
|
+
public func play() {
|
|
109
|
+
guard let storyBlockVC = self.storyBlockVC else {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
storyBlockVC.play()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@objc
|
|
116
|
+
public func pause() {
|
|
117
|
+
guard let storyBlockVC = self.storyBlockVC else {
|
|
118
|
+
return
|
|
119
|
+
}
|
|
120
|
+
storyBlockVC.pause()
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
public func storyBlockDidLoadFeed(_ viewController: StoryBlockViewController) {
|
|
93
124
|
guard let delegate = self.delegate else {
|
|
94
125
|
return
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
#import <React/RCTBridgeModule.h>
|
|
9
9
|
#import <React/RCTViewManager.h>
|
|
10
10
|
#import <React/RCTUIManager.h>
|
|
11
|
+
|
|
12
|
+
#if __has_include(<react_native_firework_sdk/react_native_firework_sdk-Swift.h>)
|
|
13
|
+
#import <react_native_firework_sdk/react_native_firework_sdk-Swift.h>
|
|
14
|
+
#else
|
|
11
15
|
#import "react_native_firework_sdk-Swift.h"
|
|
16
|
+
#endif
|
|
17
|
+
|
|
12
18
|
|
|
13
19
|
@interface RCT_EXTERN_REMAP_MODULE(FWStoryBlock, StoryBlockManager, NSObject)
|
|
14
20
|
|
|
@@ -23,8 +29,34 @@ RCT_EXPORT_VIEW_PROPERTY(playlist, NSString)
|
|
|
23
29
|
RCT_EXPORT_VIEW_PROPERTY(dynamicContentParameters, NSDictionary)
|
|
24
30
|
RCT_EXPORT_VIEW_PROPERTY(enablePictureInPicture, BOOL)
|
|
25
31
|
|
|
32
|
+
RCT_CUSTOM_VIEW_PROPERTY(adConfiguration, AdConfiguration, StoryBlock) {
|
|
33
|
+
AdConfiguration *config = [RCTConvert adConfiguration:json];
|
|
34
|
+
view.adConfiguration = config;
|
|
35
|
+
}
|
|
26
36
|
|
|
27
37
|
RCT_EXPORT_VIEW_PROPERTY(onStoryBlockLoadFinished, RCTBubblingEventBlock)
|
|
28
38
|
|
|
39
|
+
RCT_EXPORT_METHOD(play:(nonnull NSNumber *)reactTag) {
|
|
40
|
+
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
|
41
|
+
StoryBlock *view = (StoryBlock *)(viewRegistry[reactTag]);
|
|
42
|
+
if (!view || ![view isKindOfClass:[StoryBlock class]]) {
|
|
43
|
+
RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
[view play];
|
|
47
|
+
}];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
RCT_EXPORT_METHOD(pause:(nonnull NSNumber *)reactTag) {
|
|
51
|
+
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
|
52
|
+
StoryBlock *view = (StoryBlock *)(viewRegistry[reactTag]);
|
|
53
|
+
if (!view || ![view isKindOfClass:[StoryBlock class]]) {
|
|
54
|
+
RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
[view pause];
|
|
58
|
+
}];
|
|
59
|
+
}
|
|
60
|
+
|
|
29
61
|
@end
|
|
30
62
|
|
|
@@ -130,29 +130,6 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
130
130
|
return resultLayout ?? VideoFeedHorizontalLayout()
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
private var fireworkVideoAdConfiguration: FireworkVideo.AdConfiguration? {
|
|
134
|
-
guard let feedAdConfiguration = adConfiguration else {
|
|
135
|
-
return nil
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
var resultAdConfiguration = FireworkVideo.AdConfiguration()
|
|
139
|
-
if let requiresAds = feedAdConfiguration.requiresAds {
|
|
140
|
-
resultAdConfiguration.requiresAds = requiresAds
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if let adsFetchTimeout = feedAdConfiguration.adsFetchTimeout {
|
|
144
|
-
resultAdConfiguration.adsFetchTimeout = adsFetchTimeout
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if let vastAttributes = feedAdConfiguration.vastAttributes {
|
|
148
|
-
resultAdConfiguration.vastAttributes = vastAttributes.map({ attribute in
|
|
149
|
-
return URLQueryItem(name: attribute.name ?? "", value: attribute.value ?? "")
|
|
150
|
-
})
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return resultAdConfiguration
|
|
154
|
-
}
|
|
155
|
-
|
|
156
133
|
public override func layoutSubviews() {
|
|
157
134
|
super.layoutSubviews()
|
|
158
135
|
|
|
@@ -160,12 +137,15 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
160
137
|
}
|
|
161
138
|
|
|
162
139
|
private func embed() {
|
|
163
|
-
guard let parentVC =
|
|
140
|
+
guard let parentVC = fwParentViewController else {
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
guard self.feedVC == nil else {
|
|
164
144
|
return
|
|
165
145
|
}
|
|
166
146
|
|
|
167
147
|
var resultFeedVC: VideoFeedViewController?
|
|
168
|
-
if let fireworkVideoAdConfiguration =
|
|
148
|
+
if let fireworkVideoAdConfiguration = RCTConvert.getFireworkVideoAdConfiguration(adConfiguration) {
|
|
169
149
|
resultFeedVC = VideoFeedViewController(
|
|
170
150
|
layout: videoFeedLayout,
|
|
171
151
|
source: source,
|
|
@@ -204,12 +184,14 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
204
184
|
feedVC.viewConfiguration = viewConfiguration
|
|
205
185
|
}
|
|
206
186
|
|
|
207
|
-
// swiftlint:disable:next notification_center_detachment
|
|
208
|
-
NotificationCenter.default.removeObserver(self)
|
|
209
187
|
if self.enablePictureInPicture || feedViewConfig?.enablePictureInPicture == true {
|
|
210
188
|
feedVC.isPictureInPictureEnabled = true
|
|
211
189
|
}
|
|
212
190
|
|
|
191
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip {
|
|
192
|
+
feedVC.view.fwrtl_viewType = FWRTLViewTypeFlip
|
|
193
|
+
}
|
|
194
|
+
|
|
213
195
|
feedVC.delegate = self
|
|
214
196
|
self.feedVC = feedVC
|
|
215
197
|
parentVC.attachChild(feedVC, to: self)
|
|
@@ -217,8 +199,6 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
217
199
|
|
|
218
200
|
public override func removeFromSuperview() {
|
|
219
201
|
super.removeFromSuperview()
|
|
220
|
-
// swiftlint:disable:next notification_center_detachment
|
|
221
|
-
NotificationCenter.default.removeObserver(self)
|
|
222
202
|
|
|
223
203
|
guard let feedVC = self.feedVC else {
|
|
224
204
|
return
|