react-native-firework-sdk 1.8.0 → 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 (138) 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 +33 -2
  4. package/ios/Components/StoryBlockManager.m +32 -0
  5. package/ios/Components/VideoFeed.swift +10 -29
  6. package/ios/Components/VideoFeedManager.m +11 -6
  7. package/ios/FireworkSdk.xcodeproj/project.pbxproj +378 -204
  8. package/ios/Models/NativeToRN/FireworkEventName.swift +3 -1
  9. package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
  10. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +27 -0
  11. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +23 -5
  12. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
  13. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +31 -0
  14. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +13 -0
  15. package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
  16. package/ios/Modules/Shopping/ShoppingModule.m +2 -1
  17. package/ios/Modules/Shopping/ShoppingModule.swift +103 -30
  18. package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
  19. package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
  20. package/ios/Utils/AppLanguage/Bundle+FWSwizzle.swift +58 -0
  21. package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +139 -0
  22. package/ios/Utils/AppLanguage/FWLanguageUtil.swift +43 -0
  23. package/ios/Utils/AppLanguage/NumberFormatter+FWSwizzle.swift +25 -0
  24. package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +91 -0
  25. package/ios/Utils/AppLanguage/UILabel+FWSwizzle.swift +98 -0
  26. package/ios/Utils/AppLanguage/UITextField+FWSwizzle.swift +97 -0
  27. package/ios/Utils/AppLanguage/UITextView+FWSwizzle.swift +97 -0
  28. package/ios/Utils/AppLanguage/UIView+FWSwizzle.swift +38 -0
  29. package/ios/Utils/AppLanguage/UIViewController+FWSwizzle.swift +32 -0
  30. package/ios/Utils/AppLanguage/UIWindow+FWSwizzle.swift +26 -0
  31. package/ios/Utils/AppLanguage/URLSession+FWSwizzle.swift +69 -0
  32. package/ios/Utils/{DispatchQueue+FWOnce.swift → Extensions/DispatchQueue+FWOnce.swift} +3 -3
  33. package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +6 -8
  34. package/ios/Utils/Extensions/UIView+FWUIHierarchy.swift +47 -0
  35. package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.h +25 -0
  36. package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.m +75 -0
  37. package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.h +21 -0
  38. package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.m +124 -0
  39. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.h +11 -0
  40. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.m +86 -0
  41. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.h +16 -0
  42. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.m +55 -0
  43. package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.h +18 -0
  44. package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.m +39 -0
  45. package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.h +54 -0
  46. package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.m +141 -0
  47. package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.h +16 -0
  48. package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.m +20 -0
  49. package/ios/Utils/FWRTL/Classes/Utils/FWRTLDefinitions.h +52 -0
  50. package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.h +19 -0
  51. package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.m +49 -0
  52. package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.h +21 -0
  53. package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.m +38 -0
  54. package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.h +18 -0
  55. package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.m +43 -0
  56. package/ios/Utils/FWSwizzleLoader.m +6 -1
  57. package/ios/Utils/FWSwizzleLoader.swift +13 -0
  58. package/ios/Utils/FWSwizzleUtil.swift +17 -9
  59. package/ios/react_native_firework_sdk.h +1 -0
  60. package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
  61. package/lib/commonjs/FWNavigator.js +2 -2
  62. package/lib/commonjs/FWNavigator.js.map +1 -1
  63. package/lib/commonjs/FireworkSDK.js +31 -6
  64. package/lib/commonjs/FireworkSDK.js.map +1 -1
  65. package/lib/commonjs/VideoShopping.js +71 -22
  66. package/lib/commonjs/VideoShopping.js.map +1 -1
  67. package/lib/commonjs/components/StoryBlock.js +156 -106
  68. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  69. package/lib/commonjs/components/VideoFeed.js +37 -11
  70. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  71. package/lib/commonjs/index.js +6 -0
  72. package/lib/commonjs/index.js.map +1 -1
  73. package/lib/commonjs/models/FWEventName.js +2 -0
  74. package/lib/commonjs/models/FWEventName.js.map +1 -1
  75. package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
  76. package/lib/commonjs/models/ShoppingCTAResult.js.map +1 -0
  77. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  78. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  79. package/lib/module/FWNavigator.js +5 -2
  80. package/lib/module/FWNavigator.js.map +1 -1
  81. package/lib/module/FireworkSDK.js +31 -6
  82. package/lib/module/FireworkSDK.js.map +1 -1
  83. package/lib/module/VideoShopping.js +70 -23
  84. package/lib/module/VideoShopping.js.map +1 -1
  85. package/lib/module/components/StoryBlock.js +146 -103
  86. package/lib/module/components/StoryBlock.js.map +1 -1
  87. package/lib/module/components/VideoFeed.js +41 -10
  88. package/lib/module/components/VideoFeed.js.map +1 -1
  89. package/lib/module/index.js +1 -1
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/models/FWEventName.js +2 -0
  92. package/lib/module/models/FWEventName.js.map +1 -1
  93. package/lib/module/models/ShoppingCTAResult.js +2 -0
  94. package/lib/module/models/ShoppingCTAResult.js.map +1 -0
  95. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  96. package/lib/module/modules/ShoppingModule.js.map +1 -1
  97. package/lib/typescript/FWNavigator.d.ts +6 -3
  98. package/lib/typescript/FireworkSDK.d.ts +20 -7
  99. package/lib/typescript/LiveStream.d.ts +2 -2
  100. package/lib/typescript/VideoShopping.d.ts +32 -11
  101. package/lib/typescript/components/StoryBlock.d.ts +21 -11
  102. package/lib/typescript/components/VideoFeed.d.ts +21 -5
  103. package/lib/typescript/index.d.ts +7 -4
  104. package/lib/typescript/models/AdBadgeConfiguration.d.ts +1 -1
  105. package/lib/typescript/models/AddToCartResult.d.ts +4 -0
  106. package/lib/typescript/models/FWEventName.d.ts +2 -0
  107. package/lib/typescript/models/FWEvents.d.ts +27 -0
  108. package/lib/typescript/models/IOSFontInfo.d.ts +2 -2
  109. package/lib/typescript/models/NewNativeContainerProps.d.ts +1 -1
  110. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +35 -0
  111. package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
  112. package/lib/typescript/models/StoryBlockSource.d.ts +1 -1
  113. package/lib/typescript/models/VideoFeedConfiguration.d.ts +4 -3
  114. package/lib/typescript/models/VideoFeedSource.d.ts +1 -1
  115. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +7 -5
  116. package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
  117. package/lib/typescript/modules/ShoppingModule.d.ts +2 -0
  118. package/package.json +10 -6
  119. package/react-native-firework-sdk.podspec +26 -24
  120. package/src/FWNavigator.ts +6 -3
  121. package/src/FireworkSDK.ts +27 -8
  122. package/src/VideoShopping.ts +110 -41
  123. package/src/components/StoryBlock.tsx +158 -84
  124. package/src/components/VideoFeed.tsx +38 -9
  125. package/src/index.ts +21 -0
  126. package/src/models/AddToCartResult.ts +4 -0
  127. package/src/models/FWEventName.ts +2 -0
  128. package/src/models/FWEvents.ts +28 -0
  129. package/src/models/ProductInfoViewConfiguration.ts +37 -0
  130. package/src/models/ShoppingCTAResult.ts +11 -0
  131. package/src/models/VideoFeedConfiguration.ts +3 -2
  132. package/src/models/VideoPlayerConfiguration.ts +3 -1
  133. package/src/modules/FireworkSDKModule.ts +1 -2
  134. package/src/modules/ShoppingModule.ts +6 -1
  135. package/ios/Utils/UIView+ParentViewController.swift +0 -21
  136. /package/ios/Utils/{String+Color.swift → Extensions/String+Color.swift} +0 -0
  137. /package/ios/Utils/{UIView+Constraints.swift → Extensions/UIView+Constraints.swift} +0 -0
  138. /package/ios/Utils/{UIViewController+AttachChild.swift → Extensions/UIViewController+AttachChild.swift} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-firework-sdk",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Firework React Native SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -18,13 +18,15 @@
18
18
  "!ios/build",
19
19
  "!**/__tests__",
20
20
  "!**/__fixtures__",
21
- "!**/__mocks__"
21
+ "!**/__mocks__",
22
+ "!docs/"
22
23
  ],
23
24
  "scripts": {
24
25
  "test": "jest",
25
26
  "typescript": "tsc --noEmit",
26
27
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
27
- "prepare": "bob build"
28
+ "prepare": "bob build",
29
+ "generate-doc": "rm -rf docs && npx typedoc"
28
30
  },
29
31
  "keywords": [
30
32
  "react-native",
@@ -32,7 +34,7 @@
32
34
  "android"
33
35
  ],
34
36
  "repository": "",
35
- "author": "",
37
+ "author": "Loop Now Technologies, Inc.",
36
38
  "license": "Apache-2.0",
37
39
  "bugs": {
38
40
  "url": "https://github.com/loopsocial/react-native-firework-sdk/issues"
@@ -57,7 +59,8 @@
57
59
  "react": "17.0.2",
58
60
  "react-native": "0.66.4",
59
61
  "react-native-builder-bob": "^0.18.0",
60
- "typescript": "^4.4.4"
62
+ "typedoc": "^0.23.27",
63
+ "typescript": "^4.9.5"
61
64
  },
62
65
  "peerDependencies": {
63
66
  "react": "*",
@@ -98,7 +101,8 @@
98
101
  },
99
102
  "eslintIgnore": [
100
103
  "node_modules/",
101
- "lib/"
104
+ "lib/",
105
+ "docs/"
102
106
  ],
103
107
  "prettier": {
104
108
  "quoteProps": "consistent",
@@ -1,31 +1,33 @@
1
- require "json"
1
+ require 'json'
2
2
 
3
- package = JSON.parse(File.read(File.join(__dir__, "package.json")))
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
4
 
5
5
  Pod::Spec.new do |s|
6
- s.name = "react-native-firework-sdk"
7
- s.version = package["version"]
8
- s.summary = package["description"]
9
- s.homepage = package["homepage"]
10
- s.license = "Apache License, Version 2.0"
11
- s.authors = package["author"]
6
+ s.name = 'react-native-firework-sdk'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.homepage = package['homepage']
10
+ s.license = 'Apache License, Version 2.0'
11
+ s.authors = package['author']
12
12
 
13
- s.platforms = { :ios => "12.0" }
14
- s.source = { :git => "https://github.com/loopsocial/bogano.git", :tag => "#{s.version}" }
13
+ s.platforms = { ios: '12.0' }
14
+ s.source = { git: 'https://github.com/loopsocial/bogano.git', tag: "#{s.version}" }
15
15
 
16
16
  s.swift_version = '5.0'
17
- # s.header_dir = "ios"
18
- # s.public_header_files = "ios/*.h"
19
- s.source_files = "ios/**/*.{h,m,mm,swift}"
20
-
21
- s.script_phase = { :name => 'Copy module header files', :script => 'echo "react-native-firework-sdk module_header_path path is"
22
- module_header_path=${PODS_TARGET_SRCROOT}"/ios/react_native_firework_sdk.h"
23
- echo $module_header_path
24
- cp $module_header_path "${PODS_ROOT}/Headers/Public/react_native_firework_sdk/"', :execution_position => :before_compile }
25
-
26
-
27
- s.dependency "React-Core"
28
-
29
- s.dependency "FireworkVideo", "1.7.0"
30
-
17
+ # s.header_dir = 'ios'
18
+ # s.public_header_files = 'ios/*.h'
19
+ s.source_files = 'ios/**/*.{h,m,mm,swift}'
20
+ s.exclude_files = 'ios/Support/**/*.{h,m,mm,swift}'
21
+ s.script_phase = { name: 'Copy module header files', script: '
22
+ module_header_path="${PODS_TARGET_SRCROOT}/ios/react_native_firework_sdk.h"
23
+ target_header_directory="${PODS_ROOT}/Headers/Public/react_native_firework_sdk/"
24
+ echo "module_header_path $module_header_path"
25
+ echo "target_header_directory $target_header_directory"
26
+ if [ -d $target_header_directory ]
27
+ then
28
+ cp -f $module_header_path $target_header_directory
29
+ fi
30
+ ', execution_position: :before_compile }
31
+ s.dependency 'React-Core'
32
+ s.dependency 'FireworkVideo', '1.8.0'
31
33
  end
@@ -5,7 +5,10 @@ import FWNavigatorModule, {
5
5
  } from './modules/FWNavigatorModule';
6
6
  import FWLoggerUtil from './utils/FWLoggerUtil';
7
7
 
8
- type FWNativeContainerProps = {
8
+ /**
9
+ * @deprecated The type will be deprecated since RN SDK V2.0.
10
+ */
11
+ export type FWNativeContainerProps = {
9
12
  [key: string]: any;
10
13
  };
11
14
 
@@ -33,7 +36,7 @@ class FWNavigator {
33
36
  * @param {FWNativeContainerProps} props We will pass the props to your app component.
34
37
  * @returns {Promise<boolean>} The result of pushing RN page from native page.
35
38
  *
36
- * @deprecated The property will be deprecated since RN SDK V2.
39
+ * @deprecated The method will be deprecated since RN SDK V2.0.
37
40
  */
38
41
  public pushNativeContainer(props: FWNativeContainerProps): Promise<boolean> {
39
42
  FWLoggerUtil.log(`Enter pushNewNativeContainer`);
@@ -54,7 +57,7 @@ class FWNavigator {
54
57
  * @returns {Promise<boolean>} If the result is true,
55
58
  * we could call popNativeContainer to pop top-most native container.
56
59
  *
57
- * @deprecated The property will be deprecated since RN SDK V2.
60
+ * @deprecated The method will be deprecated since RN SDK V2.0.
58
61
  */
59
62
  public canPopNativeContainer(): Promise<boolean> {
60
63
  return FWNavigatorModule.canPopNativeContainer();
@@ -56,10 +56,15 @@ class FireworkSDK {
56
56
 
57
57
  /**
58
58
  * The custom CTA link content page route name.
59
+ *
60
+ * @deprecated The get accessor will be deprecated since RN SDK V2.0.
59
61
  */
60
62
  public get customCTALinkContentPageRouteName(): string | undefined {
61
63
  return this._customCTALinkContentPageRouteName;
62
64
  }
65
+ /**
66
+ * @deprecated The set accessor will be deprecated since RN SDK V2.0.
67
+ */
63
68
  public set customCTALinkContentPageRouteName(value: string | undefined) {
64
69
  this._customCTALinkContentPageRouteName = value;
65
70
  FireworkSDKModule.setCustomCTALinkContentPageRouteName(value ?? '');
@@ -120,16 +125,26 @@ class FireworkSDK {
120
125
 
121
126
  /**
122
127
  * The app component name.
128
+ *
129
+ * @deprecated The get accessor will be deprecated since RN SDK V2.0.
123
130
  */
124
131
  public get appComponentName(): string | undefined {
125
132
  return this._appComponentName;
126
133
  }
134
+ /**
135
+ * @deprecated The set accessor will be deprecated since RN SDK V2.0.
136
+ */
127
137
  public set appComponentName(value: string | undefined) {
128
138
  this._appComponentName = value;
129
139
  FireworkSDKModule.setAppComponentName(value ?? '');
130
140
  }
131
141
  private _appComponentName: string | undefined;
132
142
 
143
+ public get appLanguage(): string | undefined | null {
144
+ return this._appLanguage;
145
+ }
146
+ private _appLanguage: string | undefined | null;
147
+
133
148
  /**
134
149
  * Defaults to false. You can enable debug logs by setting this property to true.
135
150
  */
@@ -253,17 +268,21 @@ class FireworkSDK {
253
268
  }
254
269
 
255
270
  /**
256
- * Change App level language. Only supported on Android.
257
- * @param {string} language Such as en, ar and en-US
271
+ * Change App level language.
272
+ * @param {string | undefined | null} language Such as en, ar and en-US
273
+ * If language is null or undefined or empty string, we will use system language.
258
274
  * @returns
259
275
  */
260
- public async changeAppLanguage(language: string): Promise<boolean> {
261
- if (Platform.OS === 'android') {
262
- const result = await FireworkSDKModule.changeAppLanguage(language);
263
- return result;
276
+ public async changeAppLanguage(language?: string | null): Promise<boolean> {
277
+ const result = await FireworkSDKModule.changeAppLanguage(language);
278
+ if (result) {
279
+ const valueHasChanged = this._appLanguage !== language;
280
+ this._appLanguage = language;
281
+ if (valueHasChanged) {
282
+ this.eventEmitter.emit(FWEventName.AppLanguageUpdated);
283
+ }
264
284
  }
265
-
266
- return false;
285
+ return result;
267
286
  }
268
287
  }
269
288
 
@@ -4,6 +4,7 @@ import type AddToCartResult from './models/AddToCartResult';
4
4
  import type {
5
5
  AddToCartEvent,
6
6
  CustomClickLinkButtonEvent,
7
+ ShoppingCTAEvent,
7
8
  UpdateProductDetailsEvent,
8
9
  WillDisplayProductEvent,
9
10
  } from './models/FWEvents';
@@ -15,11 +16,22 @@ import ShoppingModule, {
15
16
  } from './modules/ShoppingModule';
16
17
  import type { NewNativeContainerProps } from './models/NewNativeContainerProps';
17
18
  import FWLoggerUtil from './utils/FWLoggerUtil';
19
+ import type ShoppingCTAResult from './models/ShoppingCTAResult';
18
20
 
21
+ /**
22
+ * @deprecated The type will be deprecated since RN SDK V2.1.
23
+ */
19
24
  export type AddToCartCallback = (
20
25
  event: AddToCartEvent
21
26
  ) => Promise<AddToCartResult | undefined | null>;
22
27
 
28
+ export type ShoppingCTACallback = (
29
+ event: ShoppingCTAEvent
30
+ ) => Promise<ShoppingCTAResult>;
31
+
32
+ /**
33
+ * @deprecated The type will be deprecated since RN SDK V2.0.
34
+ */
23
35
  export type ClickCartIconCallback = () => Promise<
24
36
  NewNativeContainerProps | undefined | null
25
37
  >;
@@ -30,6 +42,9 @@ export type UpdateProductDetailsCallback = (
30
42
  event: UpdateProductDetailsEvent
31
43
  ) => Promise<Product[] | undefined | null>;
32
44
 
45
+ /**
46
+ * @deprecated The type will be deprecated since RN SDK V2.0.
47
+ */
33
48
  export type WillDisplayProductCallback = (
34
49
  event: WillDisplayProductEvent
35
50
  ) => Promise<ProductInfoViewConfiguration | undefined | null>;
@@ -38,8 +53,6 @@ export type CustomClickLinkButtonCallback = (
38
53
  event: CustomClickLinkButtonEvent
39
54
  ) => Promise<void>;
40
55
 
41
- type CallbackInfo = { callbackId?: number | string };
42
-
43
56
  /**
44
57
  * The entry class of video shopping.
45
58
  */
@@ -51,14 +64,23 @@ class VideoShopping {
51
64
  *
52
65
  * The host apps can return an AddToCartResult object to tell FireworkSDK the result of adding to cart.
53
66
  * If the host apps want to customize the processing logic of clicking "Add to cart" button, they could return null or undefined in the callback.
67
+ * @deprecated The callback will be deprecated since RN SDK V2.1.
54
68
  */
55
69
  public onAddToCart?: AddToCartCallback;
56
70
 
71
+ /**
72
+ * This callback is triggered when the user clicks the "Add to cart" or "Shop now" button.
73
+ * The host app can return a ShoppingCTAResult object to tell SDK how to handle the result.
74
+ */
75
+ public onShoppingCTA?: ShoppingCTACallback;
76
+
57
77
  /**
58
78
  * This callback is triggered when the user clicks the shopping cart icon.
59
79
  *
60
80
  * The host app can return NewNativeContainerProps object
61
81
  * and we will push a new native container with the props.
82
+ *
83
+ * @deprecated The property will be deprecated since RN SDK V2.0.
62
84
  */
63
85
  public onClickCartIcon?: ClickCartIconCallback;
64
86
 
@@ -91,7 +113,8 @@ class VideoShopping {
91
113
  /**
92
114
  * Please use productInfoViewConfiguration property. Only supported on iOS.
93
115
  *
94
- * @deprecated The property will be deprecated since RN SDK V2.
116
+ * @deprecated The property will be deprecated since RN SDK V2.0.
117
+ * Use {@link productInfoViewConfiguration} instead.
95
118
  */
96
119
  public onWillDisplayProduct?: WillDisplayProductCallback;
97
120
 
@@ -109,8 +132,9 @@ class VideoShopping {
109
132
  private _cartIconVisible: boolean = true;
110
133
 
111
134
  /**
112
- * The host app can use this property to configure "Add to cart" button style
113
- * and hide the link button next to "Add to cart" button. Only supported on iOS.
135
+ * The configuration of product info view.
136
+ * Please refer to {@link ProductInfoViewConfiguration} for more details.
137
+ * Only supported on iOS.
114
138
  */
115
139
  public get productInfoViewConfiguration():
116
140
  | ProductInfoViewConfiguration
@@ -147,9 +171,7 @@ class VideoShopping {
147
171
  value: CustomClickLinkButtonCallback | undefined
148
172
  ) {
149
173
  this._onCustomClickLinkButton = value;
150
- if (Platform.OS === 'android') {
151
- ShoppingModule.setCustomClickLinkButtonEnabled(!!value);
152
- }
174
+ ShoppingModule.setCustomClickLinkButtonEnabled(!!value);
153
175
  }
154
176
  private _onCustomClickLinkButton?: CustomClickLinkButtonCallback | undefined;
155
177
 
@@ -167,12 +189,26 @@ class VideoShopping {
167
189
  }
168
190
 
169
191
  private constructor() {
170
- this.eventEmitter.addListener(FWEventName.AddToCart, (event) => {
171
- FWLoggerUtil.log(
172
- `Receive AddToCart event productId: ${event?.productId} unitId: ${event?.unitId}`
192
+ if (Platform.OS === 'android') {
193
+ this.eventEmitter.addListener(FWEventName.AddToCart, (event) => {
194
+ FWLoggerUtil.log(
195
+ `Receive AddToCart event productId: ${event?.productId} unitId: ${event?.unitId}`
196
+ );
197
+ this.handleShoppingCTAEvent(event);
198
+ });
199
+ }
200
+
201
+ if (Platform.OS === 'ios') {
202
+ this.eventEmitter.addListener(
203
+ FWEventName.ShoppingCTAButtonClick,
204
+ (event) => {
205
+ FWLoggerUtil.log(
206
+ `Receive ShoppingCTA event productId: ${event?.productId} unitId: ${event?.unitId} url: ${event?.url}`
207
+ );
208
+ this.handleShoppingCTAEvent(event);
209
+ }
173
210
  );
174
- this.handleAddToCartEvent(event);
175
- });
211
+ }
176
212
 
177
213
  this.eventEmitter.addListener(FWEventName.ClickCartIcon, (event) => {
178
214
  FWLoggerUtil.log('Receive ClickCartIcon event');
@@ -194,17 +230,15 @@ class VideoShopping {
194
230
  });
195
231
  this.eventEmitter.addListener(FWEventName.LogMessage, () => {});
196
232
 
197
- if (Platform.OS === 'android') {
198
- this.eventEmitter.addListener(
199
- FWEventName.CustomLinkButtonClick,
200
- (event) => {
201
- FWLoggerUtil.log(
202
- `Receive CustomLinkButtonClick event url: ${event?.url}`
203
- );
204
- this.handleCustomLinkButtonClickEvent(event);
205
- }
206
- );
207
- }
233
+ this.eventEmitter.addListener(
234
+ FWEventName.CustomLinkButtonClick,
235
+ (event) => {
236
+ FWLoggerUtil.log(
237
+ `Receive CustomLinkButtonClick event url: ${event?.url}`
238
+ );
239
+ this.handleCustomLinkButtonClickEvent(event);
240
+ }
241
+ );
208
242
  }
209
243
 
210
244
  /**
@@ -219,36 +253,75 @@ class VideoShopping {
219
253
  ShoppingModule.setCartItemCount(count);
220
254
  }
221
255
 
222
- private async handleAddToCartEvent(event: AddToCartEvent & CallbackInfo) {
256
+ private async handleShoppingCTAEvent(event: any) {
223
257
  const callbackId = event.callbackId;
224
258
  delete event.callbackId;
225
- if (this.onAddToCart) {
259
+ let isShopNowCTA = false;
260
+ if (
261
+ Platform.OS === 'ios' &&
262
+ this.productInfoViewConfiguration?.ctaButton?.text === 'shopNow'
263
+ ) {
264
+ isShopNowCTA = true;
265
+ }
266
+
267
+ if (this.onShoppingCTA) {
268
+ const result = await this.onShoppingCTA(event as ShoppingCTAEvent);
269
+ if (callbackId) {
270
+ if (Platform.OS === 'ios') {
271
+ ShoppingModule.updateShoppingCTAResult(result, callbackId);
272
+ } else {
273
+ if (result.tips) {
274
+ ShoppingModule.updateAddToCartStatus(
275
+ result.res,
276
+ result.tips,
277
+ callbackId
278
+ );
279
+ }
280
+ }
281
+ }
282
+ } else if (this.onAddToCart && !isShopNowCTA) {
283
+ if (event.url) {
284
+ delete event.url;
285
+ }
226
286
  const result = await this.onAddToCart(event as AddToCartEvent);
227
287
  if (result) {
228
288
  if (callbackId) {
229
- ShoppingModule.updateAddToCartStatus(
230
- result.res,
231
- result.tips,
232
- callbackId
233
- );
289
+ if (Platform.OS === 'ios') {
290
+ ShoppingModule.updateShoppingCTAResult(
291
+ { res: result.res, tips: result.tips },
292
+ callbackId
293
+ );
294
+ } else {
295
+ ShoppingModule.updateAddToCartStatus(
296
+ result.res,
297
+ result.tips ?? '',
298
+ callbackId
299
+ );
300
+ }
234
301
  }
235
302
  } else {
236
303
  if (callbackId) {
237
304
  if (Platform.OS === 'ios') {
238
- ShoppingModule.clearCallbackId(callbackId, FWEventName.AddToCart);
305
+ ShoppingModule.clearCallbackId(
306
+ callbackId,
307
+ FWEventName.ShoppingCTAButtonClick
308
+ );
239
309
  }
240
310
  }
241
311
  }
242
312
  } else {
243
313
  if (callbackId) {
244
314
  if (Platform.OS === 'ios') {
245
- ShoppingModule.clearCallbackId(callbackId, FWEventName.AddToCart);
315
+ ShoppingModule.clearCallbackId(
316
+ callbackId,
317
+ FWEventName.ShoppingCTAButtonClick
318
+ );
246
319
  }
247
320
  }
248
321
  }
249
322
  }
250
323
 
251
- private async handleClickCartIconEvent(event: CallbackInfo) {
324
+ private async handleClickCartIconEvent(event: any) {
252
325
  if (this.onCustomClickCartIcon) {
253
326
  this.onCustomClickCartIcon();
254
327
  } else if (this.onClickCartIcon) {
@@ -261,9 +334,7 @@ class VideoShopping {
261
334
  }
262
335
  }
263
336
 
264
- private async handleUpdateProductDetailsEvent(
265
- event: UpdateProductDetailsEvent & CallbackInfo
266
- ) {
337
+ private async handleUpdateProductDetailsEvent(event: any) {
267
338
  const callbackId = event.callbackId;
268
339
  delete event.callbackId;
269
340
  if (this.onUpdateProductDetails) {
@@ -311,16 +382,14 @@ class VideoShopping {
311
382
  }
312
383
  }
313
384
 
314
- private async handleWillDisplayProductEvent(
315
- event: WillDisplayProductEvent & CallbackInfo
316
- ) {
385
+ private async handleWillDisplayProductEvent(event: any) {
317
386
  if (this.onWillDisplayProduct) {
318
387
  delete event.callbackId;
319
388
  const config = await this.onWillDisplayProduct(
320
389
  event as WillDisplayProductEvent
321
390
  );
322
391
  if (config) {
323
- ShoppingModule.setProductInfoViewConfiguration(config);
392
+ this.productInfoViewConfiguration = config;
324
393
  }
325
394
  }
326
395
  }