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.
Files changed (92) hide show
  1. package/android/build.gradle +1 -1
  2. package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +47 -14
  3. package/ios/Components/StoryBlock.swift +28 -1
  4. package/ios/Components/StoryBlockManager.m +32 -0
  5. package/ios/Components/VideoFeed.swift +1 -24
  6. package/ios/Components/VideoFeedManager.m +11 -6
  7. package/ios/FireworkSdk-Bridging-Header.h +0 -6
  8. package/ios/FireworkSdk.xcodeproj/project.pbxproj +4 -0
  9. package/ios/Models/NativeToRN/FireworkEventName.swift +2 -1
  10. package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
  11. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +27 -0
  12. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +4 -4
  13. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -1
  14. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +4 -4
  15. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +13 -0
  16. package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
  17. package/ios/Modules/Shopping/ShoppingModule.m +2 -1
  18. package/ios/Modules/Shopping/ShoppingModule.swift +103 -30
  19. package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
  20. package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
  21. package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +23 -2
  22. package/ios/Utils/AppLanguage/FWLanguageUtil.swift +5 -1
  23. package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +3 -3
  24. package/ios/Utils/FWSwizzleLoader.m +5 -0
  25. package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
  26. package/lib/commonjs/FWNavigator.js +2 -2
  27. package/lib/commonjs/FWNavigator.js.map +1 -1
  28. package/lib/commonjs/FireworkSDK.js +14 -1
  29. package/lib/commonjs/FireworkSDK.js.map +1 -1
  30. package/lib/commonjs/VideoShopping.js +71 -22
  31. package/lib/commonjs/VideoShopping.js.map +1 -1
  32. package/lib/commonjs/components/StoryBlock.js +156 -106
  33. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  34. package/lib/commonjs/components/VideoFeed.js +29 -15
  35. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  36. package/lib/commonjs/index.js.map +1 -1
  37. package/lib/commonjs/models/FWEventName.js +1 -0
  38. package/lib/commonjs/models/FWEventName.js.map +1 -1
  39. package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
  40. package/lib/commonjs/models/ShoppingCTAResult.js.map +1 -0
  41. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  42. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  43. package/lib/module/FWNavigator.js +5 -2
  44. package/lib/module/FWNavigator.js.map +1 -1
  45. package/lib/module/FireworkSDK.js +14 -1
  46. package/lib/module/FireworkSDK.js.map +1 -1
  47. package/lib/module/VideoShopping.js +70 -23
  48. package/lib/module/VideoShopping.js.map +1 -1
  49. package/lib/module/components/StoryBlock.js +146 -103
  50. package/lib/module/components/StoryBlock.js.map +1 -1
  51. package/lib/module/components/VideoFeed.js +36 -12
  52. package/lib/module/components/VideoFeed.js.map +1 -1
  53. package/lib/module/index.js.map +1 -1
  54. package/lib/module/models/FWEventName.js +1 -0
  55. package/lib/module/models/FWEventName.js.map +1 -1
  56. package/lib/module/models/ShoppingCTAResult.js +2 -0
  57. package/lib/module/models/ShoppingCTAResult.js.map +1 -0
  58. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  59. package/lib/module/modules/ShoppingModule.js.map +1 -1
  60. package/lib/typescript/FWNavigator.d.ts +5 -2
  61. package/lib/typescript/FireworkSDK.d.ts +14 -3
  62. package/lib/typescript/VideoShopping.d.ts +26 -5
  63. package/lib/typescript/components/StoryBlock.d.ts +21 -11
  64. package/lib/typescript/components/VideoFeed.d.ts +20 -4
  65. package/lib/typescript/index.d.ts +6 -5
  66. package/lib/typescript/models/AddToCartResult.d.ts +4 -0
  67. package/lib/typescript/models/FWEventName.d.ts +1 -0
  68. package/lib/typescript/models/FWEvents.d.ts +27 -0
  69. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +35 -0
  70. package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
  71. package/lib/typescript/models/VideoFeedConfiguration.d.ts +2 -1
  72. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +2 -0
  73. package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
  74. package/lib/typescript/modules/ShoppingModule.d.ts +2 -0
  75. package/package.json +5 -4
  76. package/react-native-firework-sdk.podspec +14 -9
  77. package/src/FWNavigator.ts +5 -2
  78. package/src/FireworkSDK.ts +15 -4
  79. package/src/VideoShopping.ts +107 -32
  80. package/src/components/StoryBlock.tsx +158 -84
  81. package/src/components/VideoFeed.tsx +28 -11
  82. package/src/index.ts +15 -1
  83. package/src/models/AddToCartResult.ts +4 -0
  84. package/src/models/FWEventName.ts +1 -0
  85. package/src/models/FWEvents.ts +28 -0
  86. package/src/models/ProductInfoViewConfiguration.ts +37 -0
  87. package/src/models/ShoppingCTAResult.ts +11 -0
  88. package/src/models/VideoFeedConfiguration.ts +2 -1
  89. package/src/models/VideoPlayerConfiguration.ts +2 -0
  90. package/src/modules/FireworkSDKModule.ts +1 -2
  91. package/src/modules/ShoppingModule.ts +6 -1
  92. package/ios/scripts/firework_sdk_pods.rb +0 -3
@@ -167,7 +167,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
167
167
 
168
168
  dependencies {
169
169
 
170
- def firework_sdk_version = 'v5.14.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 fun init(context: Context) {
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
- if (l.isNullOrBlank() || !isValidLocale(l)) {
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 (isSame(context, l)) {
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
- if (context is Activity) {
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
- init(context)
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
- return updateResourcesLocale(context, Locale.getDefault())
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 isSame(context: Context, l: String?) : Boolean {
84
- if (locale.isNullOrBlank()) {
85
- init(context)
113
+ private fun restartActivity(context: Context) {
114
+ if (context is Activity) {
115
+ context.recreate()
86
116
  }
87
- return locale.equals(l)
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
- let storyBlockVC = StoryBlockViewController(source: source)
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 = 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
- VideoFeed *view = (VideoFeed *)(viewRegistry[reactTag]);
55
- if (!view || ![view isKindOfClass:[VideoFeed class]]) {
56
- RCTLogError(@"Cannot find NativeView with tag #%@", reactTag);
57
- return;
58
- }
59
- [view refresh];
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 addToCart = "fw:shopping:add-to-cart"
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, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
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