react-native-firework-sdk 1.4.2 → 1.5.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 (69) hide show
  1. package/android/build.gradle +0 -1
  2. package/ios/Components/AdConfiguration.swift +20 -0
  3. package/ios/Components/StoryBlock.swift +7 -6
  4. package/ios/Components/StoryBlockManager.swift +2 -2
  5. package/ios/Components/VideoFeed.swift +128 -75
  6. package/ios/Components/VideoFeedConfiguration.swift +4 -3
  7. package/ios/Components/VideoFeedManager.m +5 -0
  8. package/ios/Components/VideoFeedManager.swift +9 -10
  9. package/ios/Components/VideoPlayerConfiguration.swift +1 -1
  10. package/ios/FireworkSdk.xcodeproj/project.pbxproj +11 -3
  11. package/ios/Models/NativeToRN/FireworkEventName.swift +25 -25
  12. package/ios/Models/NativeToRN/FireworkSDK+Json.swift +39 -21
  13. package/ios/Models/RNToNative/RCTConvert+FireworkSDKModule.swift +42 -16
  14. package/ios/Models/RNToNative/RCTConvert+Shopping.swift +13 -11
  15. package/ios/Models/RNToNative/RCTConvert+StoryBlock.swift +8 -6
  16. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +41 -22
  17. package/ios/Modules/FWNavigatorModule/FWNavigatorContainerViewController.swift +4 -3
  18. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +55 -19
  19. package/ios/Modules/FWNavigatorModule/FWNavigatorProtocol.swift +7 -3
  20. package/ios/Modules/FireworkSDKModule/AdBadgeConfiguration.swift +2 -1
  21. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+CTA.swift +15 -9
  22. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +79 -28
  23. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
  24. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +94 -45
  25. package/ios/Modules/FireworkSDKModule/TrackPurchaseParameters.swift +16 -0
  26. package/ios/Modules/LiveStream/LiveStreamModule.swift +32 -10
  27. package/ios/Modules/Shopping/FWCartViewController.swift +14 -12
  28. package/ios/Modules/Shopping/Product.swift +3 -3
  29. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +2 -2
  30. package/ios/Modules/Shopping/ShoppingModule.swift +147 -100
  31. package/ios/Utils/String+Color.swift +13 -5
  32. package/ios/Utils/UIView+Constraints.swift +34 -21
  33. package/ios/Utils/UIViewController+AttachChild.swift +13 -11
  34. package/lib/commonjs/FireworkSDK.js +9 -0
  35. package/lib/commonjs/FireworkSDK.js.map +1 -1
  36. package/lib/commonjs/components/VideoFeed.js +41 -3
  37. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  38. package/lib/commonjs/index.js.map +1 -1
  39. package/lib/commonjs/models/AdConfiguration.js +2 -0
  40. package/lib/commonjs/models/AdConfiguration.js.map +1 -0
  41. package/lib/commonjs/models/TrackPurchaseParameters.js +2 -0
  42. package/lib/commonjs/models/TrackPurchaseParameters.js.map +1 -0
  43. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  44. package/lib/module/FireworkSDK.js +9 -0
  45. package/lib/module/FireworkSDK.js.map +1 -1
  46. package/lib/module/components/VideoFeed.js +42 -5
  47. package/lib/module/components/VideoFeed.js.map +1 -1
  48. package/lib/module/index.js.map +1 -1
  49. package/lib/module/models/AdConfiguration.js +2 -0
  50. package/lib/module/models/AdConfiguration.js.map +1 -0
  51. package/lib/module/models/TrackPurchaseParameters.js +2 -0
  52. package/lib/module/models/TrackPurchaseParameters.js.map +1 -0
  53. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  54. package/lib/typescript/FireworkSDK.d.ts +6 -0
  55. package/lib/typescript/components/VideoFeed.d.ts +6 -0
  56. package/lib/typescript/index.d.ts +4 -1
  57. package/lib/typescript/models/AdConfiguration.d.ts +22 -0
  58. package/lib/typescript/models/TrackPurchaseParameters.d.ts +26 -0
  59. package/lib/typescript/models/VideoFeedConfiguration.d.ts +4 -0
  60. package/lib/typescript/modules/FireworkSDKModule.d.ts +2 -0
  61. package/package.json +1 -1
  62. package/react-native-firework-sdk.podspec +1 -1
  63. package/src/FireworkSDK.ts +9 -0
  64. package/src/components/VideoFeed.tsx +35 -1
  65. package/src/index.tsx +6 -0
  66. package/src/models/AdConfiguration.ts +23 -0
  67. package/src/models/TrackPurchaseParameters.ts +24 -0
  68. package/src/models/VideoFeedConfiguration.ts +4 -0
  69. package/src/modules/FireworkSDKModule.ts +2 -0
@@ -5,17 +5,17 @@
5
5
  // Created by Jeff Zheng on 2021/12/30.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import FireworkVideo
9
+ import Foundation
10
10
 
11
- weak var gCartViewController: FWCartViewController?;
11
+ weak var gCartViewController: FWCartViewController?
12
12
 
13
13
  @objc(ShoppingModule)
14
14
  class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewControllerProviding {
15
-
15
+
16
16
  private var productInfoViewConfigurator: (Int, ProductInfoViewConfigurable)?
17
- private var addToCartHandlerMap: Dictionary<Int, AddToCartHandler> = [:]
18
- private var productHydratingMap: Dictionary<Int, ProductHydrating> = [:]
17
+ private var addToCartHandlerMap: [Int: AddToCartHandler] = [:]
18
+ private var productHydratingMap: [Int: ProductHydrating] = [:]
19
19
 
20
20
  private var cartViewController: FWCartViewController?
21
21
  private var cartIconVisible = true
@@ -25,20 +25,20 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
25
25
  override func supportedEvents() -> [String]! {
26
26
  ShoppingEventName.allCases.map { $0.rawValue }
27
27
  }
28
-
28
+
29
29
  override class func requiresMainQueueSetup() -> Bool {
30
30
  return true
31
31
  }
32
-
32
+
33
33
  private static func generateCallbackId() -> Int {
34
34
  struct CBIdIncreasingFactor {
35
35
  static var callbackId = 0
36
36
  }
37
-
38
- CBIdIncreasingFactor.callbackId += 1;
37
+
38
+ CBIdIncreasingFactor.callbackId += 1
39
39
  return CBIdIncreasingFactor.callbackId
40
40
  }
41
-
41
+
42
42
  @objc
43
43
  func initialize() {
44
44
  DispatchQueue.main.async {
@@ -46,37 +46,41 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
46
46
  FireworkVideoSDK.shopping.cartViewControllerProvider = self
47
47
  }
48
48
  }
49
-
49
+
50
50
  @objc
51
51
  func setCartIconVisible(_ visible: Bool) {
52
52
  cartIconVisible = visible
53
53
  }
54
-
54
+
55
55
  @objc
56
56
  func setCartItemCount(_ itemCounts: Int) {
57
57
  self.itemCounts = itemCounts
58
-
58
+
59
59
  guard let rProductInfoViewConfigurator = productInfoViewConfigurator else {
60
60
  return
61
61
  }
62
62
  DispatchQueue.main.async {
63
- var shoppingCartIconConfiguration = rProductInfoViewConfigurator.1.shoppingCartIconConfiguration
63
+ var shoppingCartIconConfiguration = rProductInfoViewConfigurator.1
64
+ .shoppingCartIconConfiguration
64
65
  shoppingCartIconConfiguration.indicator.isHidden = itemCounts == 0
65
- rProductInfoViewConfigurator.1.shoppingCartIconConfiguration = shoppingCartIconConfiguration
66
+ rProductInfoViewConfigurator.1.shoppingCartIconConfiguration =
67
+ shoppingCartIconConfiguration
66
68
  }
67
69
  }
68
-
70
+
69
71
  @objc
70
72
  func updateVideoProducts(_ products: [AnyObject]?, cbId: NSNumber) {
71
73
  #if DEBUG
72
- let formatter = DateFormatter()
73
- formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
74
- let message1 = "[iOS] Call updateVideoProducts 1 \(formatter.string(from: Date()))"
75
- print("[react-native-firework-sdk] [swift] \(message1)")
76
-
77
- sendEvent(withName: FWEventName.LogMessage.rawValue, body: [
78
- "message": message1
79
- ])
74
+ let formatter = DateFormatter()
75
+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
76
+ let message1 = "[iOS] Call updateVideoProducts 1 \(formatter.string(from: Date()))"
77
+ print("[react-native-firework-sdk] [swift] \(message1)")
78
+
79
+ sendEvent(
80
+ withName: FWEventName.logMessage.rawValue,
81
+ body: [
82
+ "message": message1
83
+ ])
80
84
  #endif
81
85
 
82
86
  guard let productHydrating = productHydratingMap[Int(truncating: cbId)] else {
@@ -86,12 +90,14 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
86
90
  productHydratingMap.removeValue(forKey: Int(truncating: cbId))
87
91
 
88
92
  #if DEBUG
89
- let message2 = "[iOS] Call updateVideoProducts 2 \(formatter.string(from: Date()))"
90
- print("[react-native-firework-sdk] [swift] \(message2)")
93
+ let message2 = "[iOS] Call updateVideoProducts 2 \(formatter.string(from: Date()))"
94
+ print("[react-native-firework-sdk] [swift] \(message2)")
91
95
 
92
- sendEvent(withName: FWEventName.LogMessage.rawValue, body: [
93
- "message": message2
94
- ])
96
+ sendEvent(
97
+ withName: FWEventName.logMessage.rawValue,
98
+ body: [
99
+ "message": message2
100
+ ])
95
101
  #endif
96
102
 
97
103
  guard let rProducts = RCTConvert.buildProducts(products) else {
@@ -99,42 +105,50 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
99
105
  }
100
106
 
101
107
  #if DEBUG
102
- let productIds = rProducts.map({ product in
103
- return product.productId
104
- }).joined(separator: ",")
105
- let message3 = "[iOS] Call updateVideoProducts 3 productIds: \(productIds) \(formatter.string(from: Date()))"
106
- print("[react-native-firework-sdk] [swift] \(message3)")
107
-
108
- sendEvent(withName: FWEventName.LogMessage.rawValue, body: [
109
- "message": message3
110
- ])
108
+ let productIds = rProducts.map({ product in
109
+ return product.productId
110
+ }).joined(separator: ",")
111
+ let message3 =
112
+ "[iOS] Call updateVideoProducts 3 productIds: \(productIds) \(formatter.string(from: Date()))"
113
+ print("[react-native-firework-sdk] [swift] \(message3)")
114
+
115
+ sendEvent(
116
+ withName: FWEventName.logMessage.rawValue,
117
+ body: [
118
+ "message": message3
119
+ ])
111
120
  #endif
112
-
121
+
113
122
  DispatchQueue.main.async {
114
123
  for product in rProducts {
115
- productHydrating.hydrateProduct(product.productId, { build in
116
- return ShoppingModule.hydrateProduct(product, build)
117
- })
124
+ productHydrating.hydrateProduct(
125
+ product.productId, { build in
126
+ return ShoppingModule.hydrateProduct(product, build)
127
+ })
118
128
  }
119
129
  }
120
130
  }
121
-
131
+
122
132
  @objc
123
133
  func updateProductViewConfig(_ config: [String: Any]?, cbId: NSNumber) {
124
134
  let config = RCTConvert.buildProductInfoViewConfiguration(config)
125
- guard let rConfig = config, let rProductInfoViewConfigurator = productInfoViewConfigurator, rProductInfoViewConfigurator.0 == Int(truncating: cbId) else {
135
+ guard let rConfig = config, let rProductInfoViewConfigurator = productInfoViewConfigurator,
136
+ rProductInfoViewConfigurator.0 == Int(truncating: cbId)
137
+ else {
126
138
  return
127
139
  }
128
-
140
+
129
141
  DispatchQueue.main.async {
130
- //The configuration of CartIcon'visible determined by global cartIconVisible
131
- rProductInfoViewConfigurator.1.shoppingCartIconConfiguration.isHidden = !self.cartIconVisible
132
- //The configuration of CartIcon'indicator'visible determined by global itemCounts
133
- rProductInfoViewConfigurator.1.shoppingCartIconConfiguration.indicator.isHidden = self.itemCounts == 0
142
+ // The configuration of CartIcon'visible determined by global cartIconVisible
143
+ rProductInfoViewConfigurator.1.shoppingCartIconConfiguration.isHidden = !self
144
+ .cartIconVisible
145
+ // The configuration of CartIcon'indicator'visible determined by global itemCounts
146
+ rProductInfoViewConfigurator.1.shoppingCartIconConfiguration.indicator.isHidden =
147
+ self.itemCounts == 0
134
148
  ShoppingModule.hydrateProductViewConfig(rConfig, rProductInfoViewConfigurator.1)
135
149
  }
136
150
  }
137
-
151
+
138
152
  @objc
139
153
  func updateAddToCartStatus(_ res: String, tips: String?, cbId: NSNumber) {
140
154
  guard let handler = addToCartHandlerMap[Int(truncating: cbId)] else {
@@ -151,86 +165,113 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
151
165
  }
152
166
  }
153
167
  }
154
-
168
+
155
169
  @objc
156
170
  func jumpToCartPage(_ cbId: NSNumber, props: NSDictionary) {
157
171
  DispatchQueue.main.async {
158
172
  let properties: [String: Any] = (props as? [String: Any]) ?? [:]
159
- let noti = Notification(name: Notification.Name(rawValue: "showCustomCartView"), object: nil, userInfo: [
160
- "cbId": Int(truncating: cbId),
161
- "properties": properties
162
- ])
173
+ let noti = Notification(
174
+ name: Notification.Name(rawValue: "showCustomCartView"), object: nil,
175
+ userInfo: [
176
+ "cbId": Int(truncating: cbId),
177
+ "properties": properties
178
+ ])
163
179
  NotificationCenter.default.post(noti)
164
180
  }
165
181
  }
166
182
 
167
183
  @objc
168
- func setCustomClickCartIconEnabled(_ enabled: Bool, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) {
184
+ func setCustomClickCartIconEnabled(
185
+ _ enabled: Bool, resolver: @escaping RCTPromiseResolveBlock,
186
+ rejecter: @escaping RCTPromiseRejectBlock
187
+ ) {
169
188
  customClickCartIconEnabled = enabled
170
189
  resolver([:])
171
190
  }
172
191
 
173
192
  @objc
174
193
  func clearCallbackId(_ cbId: NSNumber, eventName: String) {
175
- if eventName == ShoppingEventName.UpdateProductDetails.rawValue {
194
+ if eventName == ShoppingEventName.updateProductDetails.rawValue {
176
195
  productHydratingMap.removeValue(forKey: Int(truncating: cbId))
177
- } else if eventName == ShoppingEventName.AddToCart.rawValue {
196
+ } else if eventName == ShoppingEventName.addToCart.rawValue {
178
197
  addToCartHandlerMap.removeValue(forKey: Int(truncating: cbId))
179
198
  }
180
199
  }
181
-
200
+
182
201
  // MARK: - FireworkVideoShoppingDelegate
183
- func fireworkShopping(_ fireworkShopping: FireworkVideoShopping, willDisplayProductInfo productInfoViewConfigurator: ProductInfoViewConfigurable, forVideo video: VideoDetails) {
202
+ func fireworkShopping(
203
+ _ fireworkShopping: FireworkVideoShopping,
204
+ willDisplayProductInfo productInfoViewConfigurator: ProductInfoViewConfigurable,
205
+ forVideo video: VideoDetails
206
+ ) {
184
207
  let callbackId = ShoppingModule.generateCallbackId()
185
208
  self.productInfoViewConfigurator = (callbackId, productInfoViewConfigurator)
186
209
  productInfoViewConfigurator.shoppingCartIconConfiguration.isHidden = !self.cartIconVisible
187
210
 
188
211
  #if DEBUG
189
- let formatter = DateFormatter()
190
- formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
212
+ let formatter = DateFormatter()
213
+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
191
214
 
192
- let message = "[iOS] Send WillDisplayProduct event videoId: \(video.videoID) \(formatter.string(from: Date()))"
193
- print("[react-native-firework-sdk] [swift] \(message)")
215
+ let message =
216
+ "[iOS] Send WillDisplayProduct event videoId: \(video.videoID) \(formatter.string(from: Date()))"
217
+ print("[react-native-firework-sdk] [swift] \(message)")
194
218
 
195
- sendEvent(
196
- withName: FWEventName.LogMessage.rawValue,
197
- body: ["message": message])
219
+ sendEvent(
220
+ withName: FWEventName.logMessage.rawValue,
221
+ body: ["message": message])
198
222
  #endif
199
223
 
200
- sendEvent(withName: ShoppingEventName.WillDisplayProduct.rawValue, body: ["videoId": video.videoID, "callbackId": callbackId])
224
+ sendEvent(
225
+ withName: ShoppingEventName.willDisplayProduct.rawValue,
226
+ body: ["videoId": video.videoID, "callbackId": callbackId])
201
227
  }
202
-
203
- func fireworkShopping(_ fireworkShopping: FireworkVideoShopping, updateDetailsForProducts products: [ProductID], forVideo video: VideoDetails, _ productHydrator: ProductHydrating) {
228
+
229
+ func fireworkShopping(
230
+ _ fireworkShopping: FireworkVideoShopping, updateDetailsForProducts products: [ProductID],
231
+ forVideo video: VideoDetails, _ productHydrator: ProductHydrating
232
+ ) {
204
233
  let callbackId = ShoppingModule.generateCallbackId()
205
234
  self.productHydratingMap[callbackId] = productHydrator
206
235
 
207
236
  #if DEBUG
208
- let formatter = DateFormatter()
209
- formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
237
+ let formatter = DateFormatter()
238
+ formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
210
239
 
211
- let message = "[iOS] Send UpdateProductDetails event productIds: \(products) and videoId: \(video.videoID) \(formatter.string(from: Date()))"
212
- print("[react-native-firework-sdk] [swift] \(message)")
240
+ let message = """
241
+ "[iOS] Send UpdateProductDetails event productIds: \(products) and \
242
+ videoId: \(video.videoID) \(formatter.string(from: Date()))
243
+ """
244
+ print("[react-native-firework-sdk] [swift] \(message)")
213
245
 
214
- sendEvent(
215
- withName: FWEventName.LogMessage.rawValue,
216
- body: ["message": message])
246
+ sendEvent(
247
+ withName: FWEventName.logMessage.rawValue,
248
+ body: ["message": message])
217
249
  #endif
218
-
219
- sendEvent(withName: ShoppingEventName.UpdateProductDetails.rawValue, body: ["productIds": products, "callbackId": callbackId])
250
+
251
+ sendEvent(
252
+ withName: ShoppingEventName.updateProductDetails.rawValue,
253
+ body: ["productIds": products, "callbackId": callbackId])
220
254
  }
221
-
222
- func fireworkShopping(_ fireworkShopping: FireworkVideoShopping, addProductVariantToCart item: SelectedProductVariant, fromVideo video: VideoDetails, _ addToCartCompletionHandler: @escaping AddToCartHandler) {
255
+
256
+ func fireworkShopping(
257
+ _ fireworkShopping: FireworkVideoShopping,
258
+ addProductVariantToCart item: SelectedProductVariant, fromVideo video: VideoDetails,
259
+ _ addToCartCompletionHandler: @escaping AddToCartHandler
260
+ ) {
223
261
  let callbackId = ShoppingModule.generateCallbackId()
224
262
  self.addToCartHandlerMap[callbackId] = addToCartCompletionHandler
225
263
 
226
- sendEvent(withName: ShoppingEventName.AddToCart.rawValue, body: ["productId": item.productID, "unitId": item.unitID, "callbackId": callbackId])
264
+ sendEvent(
265
+ withName: ShoppingEventName.addToCart.rawValue,
266
+ body: ["productId": item.productID, "unitId": item.unitID, "callbackId": callbackId])
227
267
  }
228
-
268
+
229
269
  // MARK: - CartViewControllerProviding
230
270
  func cartViewController(for video: VideoDetails) -> FireworkVideo.CartViewController {
231
271
  let callbackId = ShoppingModule.generateCallbackId()
232
- sendEvent(withName: ShoppingEventName.ClickCartIcon.rawValue, body: ["callbackId": callbackId])
233
-
272
+ sendEvent(
273
+ withName: ShoppingEventName.clickCartIcon.rawValue, body: ["callbackId": callbackId])
274
+
234
275
  let cartVC = FWCartViewController(
235
276
  callbackId: callbackId,
236
277
  enableShowCustomCartView: !customClickCartIconEnabled)
@@ -243,31 +284,35 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate, CartViewCo
243
284
  }
244
285
  }
245
286
 
246
- private extension ShoppingModule {
247
-
248
- static func hydrateProductViewConfig(_ config: ProductInfoViewConfiguration, _ productInfoViewConfigurator: ProductInfoViewConfigurable) {
287
+ extension ShoppingModule {
288
+
289
+ fileprivate static func hydrateProductViewConfig(
290
+ _ config: ProductInfoViewConfiguration,
291
+ _ productInfoViewConfigurator: ProductInfoViewConfigurable
292
+ ) {
249
293
  if let buttonConfiguration = config.addToCartButton {
250
294
  var config = productInfoViewConfigurator.productDetailsConfiguration
251
295
  if let backgroundColor = buttonConfiguration.backgroundColor,
252
- backgroundColor.count > 0 {
296
+ backgroundColor.count > 0 {
253
297
  config.addToCartButton.backgroundColor = backgroundColor.uicolor()
254
298
  }
255
299
  if let textColor = buttonConfiguration.textColor,
256
- textColor.count > 0 {
300
+ textColor.count > 0 {
257
301
  config.addToCartButton.textColor = textColor.uicolor()
258
302
  }
259
- if let fontSize = buttonConfiguration.fontSize {
303
+ if let fontSize = buttonConfiguration.fontSize {
260
304
  config.addToCartButton.font = UIFont.systemFont(ofSize: fontSize)
261
305
  }
262
306
  productInfoViewConfigurator.productDetailsConfiguration = config
263
307
  }
264
308
  }
265
-
309
+
266
310
  }
267
311
 
268
- private extension ShoppingModule {
269
-
270
- static func hydrateProduct(_ product: Product, _ pbuild: ProductBuilder) -> ProductBuilder {
312
+ extension ShoppingModule {
313
+
314
+ fileprivate static func hydrateProduct(_ product: Product, _ pbuild: ProductBuilder)
315
+ -> ProductBuilder {
271
316
  if let name = product.name {
272
317
  pbuild.name(name)
273
318
  }
@@ -283,8 +328,10 @@ private extension ShoppingModule {
283
328
  }
284
329
  return pbuild
285
330
  }
286
-
287
- static func buildVariant(_ variant: Product.ProductUnit, _ pvBuild: ProductVariantBuilder) -> ProductVariantBuilder {
331
+
332
+ fileprivate static func buildVariant(
333
+ _ variant: Product.ProductUnit, _ pvBuild: ProductVariantBuilder
334
+ ) -> ProductVariantBuilder {
288
335
  if let name = variant.name {
289
336
  pvBuild.name(name)
290
337
  }
@@ -305,8 +352,8 @@ private extension ShoppingModule {
305
352
  }
306
353
  return pvBuild
307
354
  }
308
-
309
- static func buildVariantOption(_ options: [Product.VariantOption]?) -> [String: String]? {
355
+
356
+ fileprivate static func buildVariantOption(_ options: [Product.VariantOption]?) -> [String: String]? {
310
357
  guard let options = options else {
311
358
  return nil
312
359
  }
@@ -319,5 +366,5 @@ private extension ShoppingModule {
319
366
  }
320
367
  return result
321
368
  }
322
-
369
+
323
370
  }
@@ -8,9 +8,11 @@
8
8
  import UIKit
9
9
 
10
10
  extension String {
11
-
11
+
12
12
  func uicolor(alpha: CGFloat = 1.0) -> UIColor {
13
- var red: UInt64 = 0, green: UInt64 = 0, blue: UInt64 = 0
13
+ var red: UInt64 = 0
14
+ var green: UInt64 = 0
15
+ var blue: UInt64 = 0
14
16
  var hex = self
15
17
  //
16
18
  if hex.hasPrefix("0x") || hex.hasPrefix("0X") {
@@ -20,7 +22,7 @@ extension String {
20
22
  }
21
23
  //
22
24
  if hex.count < 6 {
23
- for _ in 0..<6-hex.count {
25
+ for _ in 0..<6 - hex.count {
24
26
  hex += "0"
25
27
  }
26
28
  }
@@ -29,10 +31,16 @@ extension String {
29
31
  // red
30
32
  Scanner(string: String(hex[..<hex.index(hex.startIndex, offsetBy: 2)])).scanHexInt64(&red)
31
33
  // green
32
- Scanner(string: String(hex[hex.index(hex.startIndex, offsetBy: 2)..<hex.index(hex.startIndex, offsetBy: 4)])).scanHexInt64(&green)
34
+ Scanner(
35
+ string: String(
36
+ hex[hex.index(hex.startIndex, offsetBy: 2)..<hex.index(hex.startIndex, offsetBy: 4)]
37
+ )
38
+ ).scanHexInt64(&green)
33
39
  // blue
34
40
  Scanner(string: String(hex[hex.index(startIndex, offsetBy: 4)...])).scanHexInt64(&blue)
35
41
 
36
- return UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: alpha)
42
+ return UIColor(
43
+ red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0,
44
+ alpha: alpha)
37
45
  }
38
46
  }
@@ -9,7 +9,7 @@ import Foundation
9
9
 
10
10
  public struct LayoutDirection: OptionSet {
11
11
  public let rawValue: Int
12
-
12
+
13
13
  public init(rawValue: Int) {
14
14
  self.rawValue = rawValue
15
15
  }
@@ -25,67 +25,80 @@ public struct LayoutDirection: OptionSet {
25
25
  public static let all: LayoutDirection = [.horizontal, .vertical]
26
26
  }
27
27
 
28
- public extension UILayoutPriority {
29
- static var almostRequired: UILayoutPriority {
28
+ extension UILayoutPriority {
29
+ public static var almostRequired: UILayoutPriority {
30
30
  return .required - 1
31
31
  }
32
32
  }
33
33
 
34
- public extension NSLayoutConstraint {
35
- func withPriority(_ new: UILayoutPriority) -> NSLayoutConstraint {
34
+ extension NSLayoutConstraint {
35
+ public func withPriority(_ new: UILayoutPriority) -> NSLayoutConstraint {
36
36
  priority = new
37
37
  return self
38
38
  }
39
39
  }
40
40
 
41
- public extension UIView {
42
- func setContentHuggingPriorities(_ new: UILayoutPriority) {
41
+ extension UIView {
42
+ public func setContentHuggingPriorities(_ new: UILayoutPriority) {
43
43
  setContentHuggingPriority(new, for: .horizontal)
44
44
  setContentHuggingPriority(new, for: .vertical)
45
45
  }
46
46
 
47
- func setContentCompressionResistancePriorities(_ new: UILayoutPriority) {
47
+ public func setContentCompressionResistancePriorities(_ new: UILayoutPriority) {
48
48
  setContentCompressionResistancePriority(new, for: .horizontal)
49
49
  setContentCompressionResistancePriority(new, for: .vertical)
50
50
  }
51
51
 
52
- func constraints(equalTo other: UIView, directions: LayoutDirection = .all,
53
- priority: UILayoutPriority = .required) -> [NSLayoutConstraint] {
52
+ public func constraints(
53
+ equalTo other: UIView, directions: LayoutDirection = .all,
54
+ priority: UILayoutPriority = .required
55
+ ) -> [NSLayoutConstraint] {
54
56
  var constraints: [NSLayoutConstraint] = []
55
57
  if directions.contains(.top) {
56
- constraints.append(topAnchor.constraint(equalTo: other.topAnchor).withPriority(priority))
58
+ constraints.append(
59
+ topAnchor.constraint(equalTo: other.topAnchor).withPriority(priority))
57
60
  }
58
61
  if directions.contains(.leading) {
59
- constraints.append(leadingAnchor.constraint(equalTo: other.leadingAnchor).withPriority(priority))
62
+ constraints.append(
63
+ leadingAnchor.constraint(equalTo: other.leadingAnchor).withPriority(priority))
60
64
  }
61
65
  if directions.contains(.bottom) {
62
- constraints.append(bottomAnchor.constraint(equalTo: other.bottomAnchor).withPriority(priority))
66
+ constraints.append(
67
+ bottomAnchor.constraint(equalTo: other.bottomAnchor).withPriority(priority))
63
68
  }
64
69
  if directions.contains(.trailing) {
65
- constraints.append(trailingAnchor.constraint(equalTo: other.trailingAnchor).withPriority(priority))
70
+ constraints.append(
71
+ trailingAnchor.constraint(equalTo: other.trailingAnchor).withPriority(priority))
66
72
  }
67
73
  return constraints
68
74
  }
69
75
 
70
- func constraints(equalTo layoutGuide: UILayoutGuide, directions: LayoutDirection = .all,
71
- priority: UILayoutPriority = .required) -> [NSLayoutConstraint] {
76
+ public func constraints(
77
+ equalTo layoutGuide: UILayoutGuide, directions: LayoutDirection = .all,
78
+ priority: UILayoutPriority = .required
79
+ ) -> [NSLayoutConstraint] {
72
80
  var constraints: [NSLayoutConstraint] = []
73
81
  if directions.contains(.top) {
74
- constraints.append(topAnchor.constraint(equalTo: layoutGuide.topAnchor).withPriority(priority))
82
+ constraints.append(
83
+ topAnchor.constraint(equalTo: layoutGuide.topAnchor).withPriority(priority))
75
84
  }
76
85
  if directions.contains(.leading) {
77
- constraints.append(leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).withPriority(priority))
86
+ constraints.append(
87
+ leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).withPriority(priority))
78
88
  }
79
89
  if directions.contains(.bottom) {
80
- constraints.append(bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).withPriority(priority))
90
+ constraints.append(
91
+ bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).withPriority(priority))
81
92
  }
82
93
  if directions.contains(.trailing) {
83
- constraints.append(trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).withPriority(priority))
94
+ constraints.append(
95
+ trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).withPriority(
96
+ priority))
84
97
  }
85
98
  return constraints
86
99
  }
87
100
 
88
- var isRightToLeft: Bool {
101
+ public var isRightToLeft: Bool {
89
102
  return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
90
103
  }
91
104
  }
@@ -8,29 +8,31 @@
8
8
  import Foundation
9
9
 
10
10
  /// util method for managing child viewcontroller
11
- public extension UIViewController {
11
+ extension UIViewController {
12
12
  /// add viewController view to the receiver's viewController.view,
13
13
  /// and set the constraints align view.safeAreaLayoutGuide
14
14
  /// - Parameter viewController: ViewController to be added
15
- func attachChild(_ viewController: UIViewController) {
15
+ public func attachChild(_ viewController: UIViewController) {
16
16
  let constraints = viewController.view.constraints(equalTo: view.safeAreaLayoutGuide)
17
- attachChild(viewController,
18
- to: view,
19
- using: constraints)
17
+ attachChild(
18
+ viewController,
19
+ to: view,
20
+ using: constraints)
20
21
  }
21
22
 
22
23
  /// add viewController view to the receiver's viewController.view, and set the constraints on the four sides
23
24
  /// - Parameters:
24
25
  /// - viewController: UIViewController to be added
25
26
  /// - container: the container view to add child view
26
- func attachChild(
27
+ public func attachChild(
27
28
  _ viewController: UIViewController,
28
29
  to containerView: UIView
29
30
  ) {
30
31
  let constraints = viewController.view.constraints(equalTo: containerView)
31
- attachChild(viewController,
32
- to: containerView,
33
- using: constraints)
32
+ attachChild(
33
+ viewController,
34
+ to: containerView,
35
+ using: constraints)
34
36
  }
35
37
 
36
38
  /// add viewController view to the receiver's viewController.view, and set the constraints on the four sides
@@ -38,7 +40,7 @@ public extension UIViewController {
38
40
  /// - viewController: UIViewController to be added
39
41
  /// - container: the container view to add child view
40
42
  /// - constraints: constraints between container and viewController.view
41
- func attachChild(
43
+ public func attachChild(
42
44
  _ viewController: UIViewController,
43
45
  to container: UIView,
44
46
  using constraints: [NSLayoutConstraint]
@@ -54,7 +56,7 @@ public extension UIViewController {
54
56
  }
55
57
 
56
58
  /// remove from parent controller
57
- func detachFromParent() {
59
+ public func detachFromParent() {
58
60
  guard self.parent != nil else {
59
61
  return
60
62
  }
@@ -264,6 +264,15 @@ class FireworkSDK {
264
264
  openVideoPlayer(url, config) {
265
265
  _FireworkSDKModule.default.openVideoPlayer(url, config !== null && config !== void 0 ? config : {});
266
266
  }
267
+ /**
268
+ * Records the user purchase.
269
+ * @param {TrackPurchaseParameters} parameters
270
+ */
271
+
272
+
273
+ trackPurchase(parameters) {
274
+ _FireworkSDKModule.default.trackPurchase(parameters);
275
+ }
267
276
 
268
277
  }
269
278