react-native-firework-sdk 1.9.0-beta.3 → 1.9.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 +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +47 -14
- package/ios/Components/StoryBlock.swift +28 -1
- package/ios/Components/StoryBlockManager.m +32 -0
- package/ios/Components/VideoFeed.swift +1 -24
- package/ios/Components/VideoFeedManager.m +11 -6
- package/ios/FireworkSdk-Bridging-Header.h +0 -6
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +4 -0
- package/ios/Models/NativeToRN/FireworkEventName.swift +2 -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 +4 -4
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -1
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +4 -4
- 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 +103 -30
- package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
- package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
- package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +23 -2
- package/ios/Utils/AppLanguage/FWLanguageUtil.swift +5 -1
- package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +3 -3
- package/ios/Utils/FWSwizzleLoader.m +5 -0
- package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
- package/lib/commonjs/FWNavigator.js +2 -2
- package/lib/commonjs/FWNavigator.js.map +1 -1
- package/lib/commonjs/FireworkSDK.js +14 -1
- package/lib/commonjs/FireworkSDK.js.map +1 -1
- package/lib/commonjs/VideoShopping.js +71 -22
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +156 -106
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +29 -15
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/FWEventName.js +1 -0
- package/lib/commonjs/models/FWEventName.js.map +1 -1
- package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
- package/lib/commonjs/models/ShoppingCTAResult.js.map +1 -0
- package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
- package/lib/module/FWNavigator.js +5 -2
- package/lib/module/FWNavigator.js.map +1 -1
- package/lib/module/FireworkSDK.js +14 -1
- package/lib/module/FireworkSDK.js.map +1 -1
- package/lib/module/VideoShopping.js +70 -23
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +146 -103
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +36 -12
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/FWEventName.js +1 -0
- package/lib/module/models/FWEventName.js.map +1 -1
- package/lib/module/models/ShoppingCTAResult.js +2 -0
- package/lib/module/models/ShoppingCTAResult.js.map +1 -0
- package/lib/module/modules/FireworkSDKModule.js.map +1 -1
- package/lib/module/modules/ShoppingModule.js.map +1 -1
- package/lib/typescript/FWNavigator.d.ts +5 -2
- package/lib/typescript/FireworkSDK.d.ts +14 -3
- package/lib/typescript/VideoShopping.d.ts +26 -5
- package/lib/typescript/components/StoryBlock.d.ts +21 -11
- package/lib/typescript/components/VideoFeed.d.ts +20 -4
- package/lib/typescript/index.d.ts +6 -5
- package/lib/typescript/models/AddToCartResult.d.ts +4 -0
- package/lib/typescript/models/FWEventName.d.ts +1 -0
- package/lib/typescript/models/FWEvents.d.ts +27 -0
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +35 -0
- package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
- package/lib/typescript/models/VideoFeedConfiguration.d.ts +2 -1
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +2 -0
- package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
- package/lib/typescript/modules/ShoppingModule.d.ts +2 -0
- package/package.json +5 -4
- package/react-native-firework-sdk.podspec +14 -9
- package/src/FWNavigator.ts +5 -2
- package/src/FireworkSDK.ts +15 -4
- package/src/VideoShopping.ts +107 -32
- package/src/components/StoryBlock.tsx +158 -84
- package/src/components/VideoFeed.tsx +28 -11
- package/src/index.ts +15 -1
- package/src/models/AddToCartResult.ts +4 -0
- package/src/models/FWEventName.ts +1 -0
- package/src/models/FWEvents.ts +28 -0
- package/src/models/ProductInfoViewConfiguration.ts +37 -0
- package/src/models/ShoppingCTAResult.ts +11 -0
- package/src/models/VideoFeedConfiguration.ts +2 -1
- package/src/models/VideoPlayerConfiguration.ts +2 -0
- package/src/modules/FireworkSDKModule.ts +1 -2
- package/src/modules/ShoppingModule.ts +6 -1
- package/ios/scripts/firework_sdk_pods.rb +0 -3
package/android/build.gradle
CHANGED
|
@@ -167,7 +167,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
|
|
|
167
167
|
|
|
168
168
|
dependencies {
|
|
169
169
|
|
|
170
|
-
def firework_sdk_version = 'v5.14.
|
|
170
|
+
def firework_sdk_version = 'v5.14.15'
|
|
171
171
|
implementation "com.github.loopsocial:firework_sdk:$firework_sdk_version"
|
|
172
172
|
|
|
173
173
|
// noinspection GradleDynamicVersion
|
|
@@ -11,17 +11,44 @@ object FWLanguageUtil {
|
|
|
11
11
|
private const val LOCALE_SP = "fw_locale_sp"
|
|
12
12
|
private const val LOCALE_KEY = "fw_locale_key"
|
|
13
13
|
|
|
14
|
-
private
|
|
14
|
+
private var systemLocale: Locale? = null
|
|
15
|
+
|
|
16
|
+
private fun readLocaleFromSp(context: Context) {
|
|
15
17
|
locale = context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
16
18
|
.getString(LOCALE_KEY, null)
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
fun changeLanguage(context: Context, l: String?): Boolean {
|
|
20
|
-
|
|
22
|
+
readLocaleFromSp(context)
|
|
23
|
+
val sharedPreferences =
|
|
24
|
+
context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
25
|
+
if (l.isNullOrBlank()) {
|
|
26
|
+
if (locale.isNullOrBlank()) {
|
|
27
|
+
return true
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
locale = null
|
|
31
|
+
sharedPreferences.edit().apply {
|
|
32
|
+
remove(LOCALE_KEY)
|
|
33
|
+
}.commit()
|
|
34
|
+
|
|
35
|
+
// change sdk locale to system locale
|
|
36
|
+
val sysLocale = getSystemLocale()
|
|
37
|
+
if (sysLocale.country.isNullOrBlank()) {
|
|
38
|
+
FwSDK.changeAppLocale(context, sysLocale.language)
|
|
39
|
+
} else {
|
|
40
|
+
FwSDK.changeAppLocale(context, "${sysLocale.language}-${sysLocale.country}")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
restartActivity(context)
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!isValidLocale(l)) {
|
|
21
48
|
return false
|
|
22
49
|
}
|
|
23
50
|
|
|
24
|
-
if (
|
|
51
|
+
if (locale == l) {
|
|
25
52
|
return true
|
|
26
53
|
}
|
|
27
54
|
|
|
@@ -29,22 +56,22 @@ object FWLanguageUtil {
|
|
|
29
56
|
FwSDK.changeAppLocale(context, l)
|
|
30
57
|
|
|
31
58
|
// save to sp
|
|
32
|
-
val sharedPreferences =
|
|
33
|
-
context.getSharedPreferences(LOCALE_SP, Context.MODE_PRIVATE)
|
|
34
59
|
sharedPreferences.edit().apply {
|
|
35
60
|
putString(LOCALE_KEY, l)
|
|
36
61
|
}.apply()
|
|
37
62
|
|
|
38
|
-
|
|
39
|
-
context.recreate()
|
|
40
|
-
}
|
|
63
|
+
restartActivity(context)
|
|
41
64
|
|
|
42
65
|
return true
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
fun updateBaseContextLocale(context: Context): Context {
|
|
69
|
+
if (systemLocale == null) {
|
|
70
|
+
systemLocale = Locale.getDefault()
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
if (locale.isNullOrBlank()) {
|
|
47
|
-
|
|
74
|
+
readLocaleFromSp(context)
|
|
48
75
|
}
|
|
49
76
|
locale?.let {
|
|
50
77
|
val localeStrings = it.split("-")
|
|
@@ -57,7 +84,10 @@ object FWLanguageUtil {
|
|
|
57
84
|
|
|
58
85
|
return updateResourcesLocale(context, locale)
|
|
59
86
|
}
|
|
60
|
-
|
|
87
|
+
|
|
88
|
+
val l = getSystemLocale()
|
|
89
|
+
Locale.setDefault(l)
|
|
90
|
+
return updateResourcesLocale(context, l)
|
|
61
91
|
}
|
|
62
92
|
|
|
63
93
|
private fun updateResourcesLocale(context: Context, locale: Locale): Context {
|
|
@@ -80,11 +110,14 @@ object FWLanguageUtil {
|
|
|
80
110
|
return list.contains(Locale(locale))
|
|
81
111
|
}
|
|
82
112
|
|
|
83
|
-
private fun
|
|
84
|
-
if (
|
|
85
|
-
|
|
113
|
+
private fun restartActivity(context: Context) {
|
|
114
|
+
if (context is Activity) {
|
|
115
|
+
context.recreate()
|
|
86
116
|
}
|
|
87
|
-
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private fun getSystemLocale(): Locale {
|
|
120
|
+
return systemLocale ?: Locale.getDefault()
|
|
88
121
|
}
|
|
89
122
|
|
|
90
123
|
}
|
|
@@ -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
|
|
|
@@ -68,7 +69,17 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
|
|
|
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
|
}
|
|
@@ -93,6 +104,22 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
|
|
|
93
104
|
self.storyBlockVC = nil
|
|
94
105
|
}
|
|
95
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
|
+
|
|
96
123
|
public func storyBlockDidLoadFeed(_ viewController: StoryBlockViewController) {
|
|
97
124
|
guard let delegate = self.delegate else {
|
|
98
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
|
|
|
@@ -128,29 +128,6 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
128
128
|
return resultLayout ?? VideoFeedHorizontalLayout()
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
private var fireworkVideoAdConfiguration: FireworkVideo.AdConfiguration? {
|
|
132
|
-
guard let feedAdConfiguration = adConfiguration else {
|
|
133
|
-
return nil
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
var resultAdConfiguration = FireworkVideo.AdConfiguration()
|
|
137
|
-
if let requiresAds = feedAdConfiguration.requiresAds {
|
|
138
|
-
resultAdConfiguration.requiresAds = requiresAds
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if let adsFetchTimeout = feedAdConfiguration.adsFetchTimeout {
|
|
142
|
-
resultAdConfiguration.adsFetchTimeout = adsFetchTimeout
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if let vastAttributes = feedAdConfiguration.vastAttributes {
|
|
146
|
-
resultAdConfiguration.vastAttributes = vastAttributes.map({ attribute in
|
|
147
|
-
return URLQueryItem(name: attribute.name ?? "", value: attribute.value ?? "")
|
|
148
|
-
})
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return resultAdConfiguration
|
|
152
|
-
}
|
|
153
|
-
|
|
154
131
|
public override func layoutSubviews() {
|
|
155
132
|
super.layoutSubviews()
|
|
156
133
|
|
|
@@ -167,7 +144,7 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
|
|
|
167
144
|
}
|
|
168
145
|
|
|
169
146
|
var resultFeedVC: VideoFeedViewController?
|
|
170
|
-
if let fireworkVideoAdConfiguration =
|
|
147
|
+
if let fireworkVideoAdConfiguration = RCTConvert.getFireworkVideoAdConfiguration(adConfiguration) {
|
|
171
148
|
resultFeedVC = VideoFeedViewController(
|
|
172
149
|
layout: videoFeedLayout,
|
|
173
150
|
source: source,
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
#import <React/RCTBridgeModule.h>
|
|
10
10
|
#import <React/RCTViewManager.h>
|
|
11
11
|
#import <React/RCTUIManager.h>
|
|
12
|
+
|
|
13
|
+
#if __has_include(<react_native_firework_sdk/react_native_firework_sdk-Swift.h>)
|
|
14
|
+
#import <react_native_firework_sdk/react_native_firework_sdk-Swift.h>
|
|
15
|
+
#else
|
|
12
16
|
#import "react_native_firework_sdk-Swift.h"
|
|
17
|
+
#endif
|
|
13
18
|
|
|
14
19
|
@interface RCT_EXTERN_REMAP_MODULE(FWVideoFeed, VideoFeedManager, NSObject)
|
|
15
20
|
|
|
@@ -51,12 +56,12 @@ RCT_EXPORT_VIEW_PROPERTY(onVideoFeedLoadFinished, RCTBubblingEventBlock)
|
|
|
51
56
|
|
|
52
57
|
RCT_EXPORT_METHOD(refresh:(nonnull NSNumber *)reactTag) {
|
|
53
58
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
VideoFeed *view = (VideoFeed *)(viewRegistry[reactTag]);
|
|
60
|
+
if (!view || ![view isKindOfClass:[VideoFeed class]]) {
|
|
61
|
+
RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
[view refresh];
|
|
60
65
|
}];
|
|
61
66
|
}
|
|
62
67
|
|
|
@@ -6,9 +6,3 @@
|
|
|
6
6
|
#import <React/RCTLog.h>
|
|
7
7
|
#import <React/RCTRootView.h>
|
|
8
8
|
#import <React/RCTBridge+Private.h>
|
|
9
|
-
#import "FWSwizzleLoader.h"
|
|
10
|
-
#import "FWRTLManager.h"
|
|
11
|
-
#import "UIView+FWRTL.h"
|
|
12
|
-
#import "UIWindow+FWRTL.h"
|
|
13
|
-
#import "UIView+FWRTL.h"
|
|
14
|
-
#import "UIImage+FWRTL.h"
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
894FADAF29BAD4C4000FB51A /* LiveStreamModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894FAD6F29BAD4C4000FB51A /* LiveStreamModule.swift */; };
|
|
72
72
|
894FADB029BAD4C4000FB51A /* LiveStreamModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 894FAD7029BAD4C4000FB51A /* LiveStreamModule.m */; };
|
|
73
73
|
8966951029BC465600B91A3D /* UIView+FWSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8966950F29BC465600B91A3D /* UIView+FWSwizzle.swift */; };
|
|
74
|
+
8967687F29C8209A009A9463 /* ShoppingCTAResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8967687E29C8209A009A9463 /* ShoppingCTAResult.swift */; };
|
|
74
75
|
/* End PBXBuildFile section */
|
|
75
76
|
|
|
76
77
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -164,6 +165,7 @@
|
|
|
164
165
|
894FAD7029BAD4C4000FB51A /* LiveStreamModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveStreamModule.m; sourceTree = "<group>"; };
|
|
165
166
|
894FADB229BAD571000FB51A /* libFireworkSdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFireworkSdk.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
166
167
|
8966950F29BC465600B91A3D /* UIView+FWSwizzle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+FWSwizzle.swift"; sourceTree = "<group>"; };
|
|
168
|
+
8967687E29C8209A009A9463 /* ShoppingCTAResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCTAResult.swift; sourceTree = "<group>"; };
|
|
167
169
|
897523632817DEF80070EBB6 /* react_native_firework_sdk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = react_native_firework_sdk.h; sourceTree = "<group>"; };
|
|
168
170
|
/* End PBXFileReference section */
|
|
169
171
|
|
|
@@ -389,6 +391,7 @@
|
|
|
389
391
|
894FAD6429BAD4C4000FB51A /* ProductInfoViewConfiguration.swift */,
|
|
390
392
|
894FAD6529BAD4C4000FB51A /* Product.swift */,
|
|
391
393
|
894FAD6629BAD4C4000FB51A /* ShoppingModule.swift */,
|
|
394
|
+
8967687E29C8209A009A9463 /* ShoppingCTAResult.swift */,
|
|
392
395
|
);
|
|
393
396
|
path = Shopping;
|
|
394
397
|
sourceTree = "<group>";
|
|
@@ -530,6 +533,7 @@
|
|
|
530
533
|
894FAD9429BAD4C4000FB51A /* RCTConvert+VideoFeed.swift in Sources */,
|
|
531
534
|
894FAD8A29BAD4C4000FB51A /* NumberFormatter+FWSwizzle.swift in Sources */,
|
|
532
535
|
894FAD9229BAD4C4000FB51A /* RCTConvert+FireworkSDKModule.swift in Sources */,
|
|
536
|
+
8967687F29C8209A009A9463 /* ShoppingCTAResult.swift in Sources */,
|
|
533
537
|
894FAD9F29BAD4C4000FB51A /* VideoFeedManager.m in Sources */,
|
|
534
538
|
894FAD9A29BAD4C4000FB51A /* StoryBlockManager.swift in Sources */,
|
|
535
539
|
894FAD8829BAD4C4000FB51A /* FWLanguageUtil.swift in Sources */,
|
|
@@ -35,9 +35,10 @@ enum VideoPlaybackSubEventName: String {
|
|
|
35
35
|
enum ShoppingEventName: String, CaseIterable {
|
|
36
36
|
case updateProductDetails = "fw:shopping:update-product-details"
|
|
37
37
|
case willDisplayProduct = "fw:shopping:will-display-product"
|
|
38
|
-
case
|
|
38
|
+
case ctaButtonClick = "fw:shopping:cta-button-click"
|
|
39
39
|
case clickCartIcon = "fw:shopping:click-cart-icon"
|
|
40
40
|
case logMessage = "fw:log-message"
|
|
41
|
+
case customLinkButtonClick = "fw:shopping:custom-link-button-click"
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
/// Live stream event
|
|
@@ -63,4 +63,25 @@ extension RCTConvert {
|
|
|
63
63
|
|
|
64
64
|
return result
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
static func buildShoppingCTAResult(_ result: [String: Any]?)
|
|
68
|
+
-> ShoppingCTAResult? {
|
|
69
|
+
guard let rResult = result else {
|
|
70
|
+
return nil
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let jsonData = try? JSONSerialization.data(withJSONObject: rResult, options: .prettyPrinted)
|
|
74
|
+
guard let rJsonData = jsonData else {
|
|
75
|
+
return nil
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var ctaResult: ShoppingCTAResult?
|
|
79
|
+
do {
|
|
80
|
+
ctaResult = try JSONDecoder().decode(ShoppingCTAResult.self, from: rJsonData)
|
|
81
|
+
} catch let error {
|
|
82
|
+
print(error.localizedDescription)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return ctaResult
|
|
86
|
+
}
|
|
66
87
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
import Foundation
|
|
9
|
+
import FireworkVideo
|
|
9
10
|
|
|
10
11
|
extension VideFeedSourceType {
|
|
11
12
|
static var sourceTypeMapper: [String: VideFeedSourceType] {
|
|
@@ -87,4 +88,30 @@ extension RCTConvert {
|
|
|
87
88
|
|
|
88
89
|
return try? JSONDecoder().decode(AdConfiguration.self, from: rJsonData)
|
|
89
90
|
}
|
|
91
|
+
|
|
92
|
+
@nonobjc
|
|
93
|
+
public static func getFireworkVideoAdConfiguration(
|
|
94
|
+
_ adConfiguration: AdConfiguration?
|
|
95
|
+
) -> FireworkVideo.AdConfiguration? {
|
|
96
|
+
guard let feedAdConfiguration = adConfiguration else {
|
|
97
|
+
return nil
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var resultAdConfiguration = FireworkVideo.AdConfiguration()
|
|
101
|
+
if let requiresAds = feedAdConfiguration.requiresAds {
|
|
102
|
+
resultAdConfiguration.requiresAds = requiresAds
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if let adsFetchTimeout = feedAdConfiguration.adsFetchTimeout {
|
|
106
|
+
resultAdConfiguration.adsFetchTimeout = adsFetchTimeout
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if let vastAttributes = feedAdConfiguration.vastAttributes {
|
|
110
|
+
resultAdConfiguration.vastAttributes = vastAttributes.map({ attribute in
|
|
111
|
+
return URLQueryItem(name: attribute.name ?? "", value: attribute.value ?? "")
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return resultAdConfiguration
|
|
116
|
+
}
|
|
90
117
|
}
|
|
@@ -9,7 +9,7 @@ import FireworkVideo
|
|
|
9
9
|
|
|
10
10
|
private let FWExitButtonImageNames: [String] = [
|
|
11
11
|
"closeX",
|
|
12
|
-
"down-arrow-light"
|
|
12
|
+
"down-arrow-light"
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
private struct PlayerInfo {
|
|
@@ -213,7 +213,7 @@ class FWNavigatorModule: RCTEventEmitter, FWNavigator {
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
extension FWNavigatorModule {
|
|
216
|
+
extension FWNavigatorModule {
|
|
217
217
|
private static func getExitButton(view: UIView) -> UIButton? {
|
|
218
218
|
if let button = view as? UIButton, let image = button.image(for: .normal) {
|
|
219
219
|
let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
|
|
@@ -222,13 +222,13 @@ extension FWNavigatorModule {
|
|
|
222
222
|
if image.isEqual(targetImage) {
|
|
223
223
|
return button
|
|
224
224
|
}
|
|
225
|
-
|
|
225
|
+
|
|
226
226
|
if let cgImage = image.cgImage,
|
|
227
227
|
let targetCgImage = targetImage?.cgImage,
|
|
228
228
|
cgImage == targetCgImage {
|
|
229
229
|
return button
|
|
230
230
|
}
|
|
231
|
-
|
|
231
|
+
|
|
232
232
|
if let ciImage = image.ciImage,
|
|
233
233
|
let targetCiImage = targetImage?.ciImage,
|
|
234
234
|
ciImage == targetCiImage {
|
|
@@ -19,6 +19,6 @@ RCT_EXTERN_METHOD(setVideoPlaybackEventEnabled:(BOOL)enabled)
|
|
|
19
19
|
RCT_EXTERN_METHOD(setAdBadgeConfiguration:(NSDictionary *)config resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
20
20
|
RCT_EXTERN_METHOD(setAppComponentName:(NSString *)name resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
21
21
|
RCT_EXTERN_METHOD(trackPurchase:(NSDictionary *)parameters)
|
|
22
|
-
RCT_EXTERN_METHOD(changeAppLanguage:(NSString *)language resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
22
|
+
RCT_EXTERN_METHOD(changeAppLanguage:(NSString * __nullable)language resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
23
23
|
|
|
24
24
|
@end
|
|
@@ -62,6 +62,8 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
|
|
|
62
62
|
FireworkVideoSDK.ctaDelegate = self
|
|
63
63
|
FireworkVideoSDK.eventTracking.videoPlaybackDelegate = self
|
|
64
64
|
FireworkVideoSDK.eventTracking.feedDelegate = self
|
|
65
|
+
|
|
66
|
+
FWAppLanguageManager.shared.initializeManager()
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
@objc(openVideoPlayer:config:)
|
|
@@ -161,20 +163,18 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
|
|
|
161
163
|
|
|
162
164
|
@objc(changeAppLanguage:resolver:rejecter:)
|
|
163
165
|
func changeAppLanguage(
|
|
164
|
-
_ language: String
|
|
166
|
+
_ language: String?, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
165
167
|
) {
|
|
166
168
|
#if DEBUG
|
|
167
169
|
let formatter = DateFormatter()
|
|
168
170
|
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
|
|
169
|
-
let message = "[iOS] Call changeAppLanguage: \(language) \(formatter.string(from: Date()))"
|
|
171
|
+
let message = "[iOS] Call changeAppLanguage: \(language ?? "") \(formatter.string(from: Date()))"
|
|
170
172
|
sendEvent(withName: FWEventName.logMessage.rawValue, body: ["message": message])
|
|
171
173
|
#endif
|
|
172
174
|
|
|
173
175
|
DispatchQueue.main.async {
|
|
174
176
|
let result = FWAppLanguageManager.shared.changeAppLanguage(language)
|
|
175
177
|
resolver(result)
|
|
176
|
-
|
|
177
|
-
FWRTLManager.sharedInstance().enableHorizontalFlip = FWAppLanguageManager.shared.shouldHorizontalFlip
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
@@ -9,6 +9,7 @@ import Foundation
|
|
|
9
9
|
|
|
10
10
|
struct ProductInfoViewConfiguration: Codable {
|
|
11
11
|
var addToCartButton: AddToCartButtonConfiguration?
|
|
12
|
+
var ctaButton: CTAButtonConfiguration?
|
|
12
13
|
var linkButton: LinkButtonConfiguration?
|
|
13
14
|
|
|
14
15
|
struct AddToCartButtonConfiguration: Codable {
|
|
@@ -18,6 +19,18 @@ struct ProductInfoViewConfiguration: Codable {
|
|
|
18
19
|
var iOSFontInfo: FontInfo?
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
struct CTAButtonConfiguration: Codable {
|
|
23
|
+
var text: CTAButtonText?
|
|
24
|
+
var backgroundColor: String?
|
|
25
|
+
var textColor: String?
|
|
26
|
+
var fontSize: Double?
|
|
27
|
+
var iOSFontInfo: FontInfo?
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
enum CTAButtonText: String, Codable {
|
|
31
|
+
case addToCart, shopNow
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
struct LinkButtonConfiguration: Codable {
|
|
22
35
|
var isHidden: Bool?
|
|
23
36
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ShoppingCTAResult.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/3/20.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
struct ShoppingCTAResult: Codable {
|
|
10
|
+
var res: ShoppingCTAResultRes?
|
|
11
|
+
var tips: String?
|
|
12
|
+
|
|
13
|
+
enum ShoppingCTAResultRes: String, Codable {
|
|
14
|
+
case success, fail
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -13,10 +13,11 @@ _RCT_EXTERN_REMAP_METHOD(init, initialize, NO)
|
|
|
13
13
|
RCT_EXTERN_METHOD(setCartIconVisible:(BOOL)visible)
|
|
14
14
|
RCT_EXTERN_METHOD(setCartItemCount:(int)itemCounts)
|
|
15
15
|
RCT_EXTERN_METHOD(updateVideoProducts:(NSArray *)products cbId:(nonnull NSNumber *)cbId)
|
|
16
|
-
RCT_EXTERN_METHOD(updateAddToCartStatus:(NSString *)res tips:(nullable NSString *)tips cbId:(nonnull NSNumber *)cbId)
|
|
17
16
|
RCT_EXTERN_METHOD(jumpToCartPage:(nonnull NSNumber *)cbId props:(NSDictionary *)props)
|
|
18
17
|
RCT_EXTERN_METHOD(setCustomClickCartIconEnabled:(BOOL)enabled resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
19
18
|
RCT_EXTERN_METHOD(setProductInfoViewConfiguration:(NSDictionary *)config)
|
|
20
19
|
RCT_EXTERN_METHOD(clearCallbackId:(nonnull NSNumber *)cbId eventName:(nonnull NSString *)name)
|
|
20
|
+
RCT_EXTERN_METHOD(setCustomClickLinkButtonEnabled:(BOOL)enabled resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
21
|
+
RCT_EXTERN_METHOD(updateShoppingCTAResult:(NSDictionary *)result cbId:(nonnull NSNumber *)cbId)
|
|
21
22
|
|
|
22
23
|
@end
|