react-native-firework-sdk 2.7.2-beta.1 → 2.8.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 (72) hide show
  1. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  2. package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
  3. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
  4. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
  5. package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +1 -1
  6. package/ios/Components/StoryBlock.swift +86 -6
  7. package/ios/Components/StoryBlockConfiguration.swift +1 -0
  8. package/ios/Components/StoryBlockManager.m +4 -0
  9. package/ios/Components/VideoFeed.swift +90 -13
  10. package/ios/Components/VideoFeedManager.m +4 -0
  11. package/ios/Components/VideoPlayerConfiguration.swift +1 -0
  12. package/ios/Components/VideoPlayerLogoConfiguration.swift +18 -0
  13. package/ios/FireworkVideoUI/Podfile +1 -1
  14. package/ios/FireworkVideoUI/Podfile.lock +4 -4
  15. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +16 -14
  16. package/ios/Modules/FWNavigatorModule/FWRNPresentContainerViewController.swift +30 -0
  17. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+CTA.swift +23 -2
  18. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +2 -0
  19. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +3 -0
  20. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +41 -8
  21. package/ios/Modules/Shopping/ShoppingModule.m +2 -0
  22. package/ios/Modules/Shopping/ShoppingModule.swift +163 -2
  23. package/lib/commonjs/FireworkSDK.js +16 -0
  24. package/lib/commonjs/FireworkSDK.js.map +1 -1
  25. package/lib/commonjs/VideoShopping.js +21 -1
  26. package/lib/commonjs/VideoShopping.js.map +1 -1
  27. package/lib/commonjs/components/StoryBlock.js +71 -0
  28. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  29. package/lib/commonjs/components/VideoFeed.js +76 -1
  30. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/models/VideoPlayerLogoConfiguration.js +2 -0
  33. package/lib/commonjs/models/VideoPlayerLogoConfiguration.js.map +1 -0
  34. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  35. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  36. package/lib/module/FireworkSDK.js +15 -0
  37. package/lib/module/FireworkSDK.js.map +1 -1
  38. package/lib/module/VideoShopping.js +22 -1
  39. package/lib/module/VideoShopping.js.map +1 -1
  40. package/lib/module/components/StoryBlock.js +69 -0
  41. package/lib/module/components/StoryBlock.js.map +1 -1
  42. package/lib/module/components/VideoFeed.js +74 -1
  43. package/lib/module/components/VideoFeed.js.map +1 -1
  44. package/lib/module/index.js.map +1 -1
  45. package/lib/module/models/VideoPlayerLogoConfiguration.js +2 -0
  46. package/lib/module/models/VideoPlayerLogoConfiguration.js.map +1 -0
  47. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  48. package/lib/module/modules/ShoppingModule.js.map +1 -1
  49. package/lib/typescript/components/StoryBlock.d.ts +12 -1
  50. package/lib/typescript/components/VideoFeed.d.ts +12 -1
  51. package/lib/typescript/index.d.ts +3 -2
  52. package/lib/typescript/models/FWEvents.d.ts +21 -0
  53. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +110 -5
  54. package/lib/typescript/models/StoryBlockConfiguration.d.ts +7 -0
  55. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +7 -0
  56. package/lib/typescript/models/VideoPlayerLogoConfiguration.d.ts +15 -0
  57. package/lib/typescript/modules/FireworkSDKModule.d.ts +2 -0
  58. package/lib/typescript/modules/ShoppingModule.d.ts +2 -0
  59. package/package.json +1 -1
  60. package/react-native-firework-sdk.podspec +1 -1
  61. package/src/FireworkSDK.ts +16 -0
  62. package/src/VideoShopping.ts +18 -1
  63. package/src/components/StoryBlock.tsx +92 -3
  64. package/src/components/VideoFeed.tsx +93 -2
  65. package/src/index.ts +14 -0
  66. package/src/models/FWEvents.ts +24 -0
  67. package/src/models/ProductInfoViewConfiguration.ts +114 -5
  68. package/src/models/StoryBlockConfiguration.ts +7 -0
  69. package/src/models/VideoPlayerConfiguration.ts +7 -0
  70. package/src/models/VideoPlayerLogoConfiguration.ts +23 -0
  71. package/src/modules/FireworkSDKModule.ts +2 -0
  72. package/src/modules/ShoppingModule.ts +2 -0
@@ -14,7 +14,7 @@
14
14
  </data>
15
15
  <key>Info.plist</key>
16
16
  <data>
17
- sp8HZ2jIRptrAIYXFhCi1ECJ82M=
17
+ +sxLWZZaXLRZ4LE21UnZGJgO790=
18
18
  </data>
19
19
  <key>Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.abi.json</key>
20
20
  <data>
@@ -19,7 +19,8 @@ public protocol StoryBlockViewDelegate: AnyObject {
19
19
  }
20
20
 
21
21
  @objc
22
- public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
22
+ // swiftlint:disable:next type_body_length
23
+ public class StoryBlock: UIView, StoryBlockViewControllerDelegate, PictureInPictureControllerDelegate {
23
24
  @objc public var sourceType: StoryBlockSourceType = .discover
24
25
  @objc public var channel: String = ""
25
26
  @objc public var playlist: String = ""
@@ -30,7 +31,20 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
30
31
  @objc public var adConfiguration: AdConfiguration?
31
32
  @objc public var storyBlockConfiguration: StoryBlockConfiguration? {
32
33
  didSet {
33
- updateStoryBlockVCConfiguration()
34
+ guard let storyBlockVC = storyBlockVC else {
35
+ return
36
+ }
37
+
38
+ if storyBlockConfiguration?.videoPlayerLogoConfiguration != oldValue?.videoPlayerLogoConfiguration {
39
+ storyBlockVC.isPictureInPictureEnabled = false
40
+ storyBlockVC.detachFromParent()
41
+ self.storyBlockVC = nil
42
+ DispatchQueue.main.async {
43
+ self.embed()
44
+ }
45
+ } else {
46
+ updateStoryBlockVCConfiguration()
47
+ }
34
48
  }
35
49
  }
36
50
 
@@ -38,6 +52,10 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
38
52
 
39
53
  @objc var onStoryBlockLoadFinished: RCTBubblingEventBlock?
40
54
 
55
+ @objc var onStoryBlockDidStartPictureInPicture: RCTBubblingEventBlock?
56
+
57
+ @objc var onStoryBlockDidStopPictureInPicture: RCTBubblingEventBlock?
58
+
41
59
  private var storyBlockVC: StoryBlockViewController?
42
60
 
43
61
  private var source: StoryBlockContentSource {
@@ -59,6 +77,7 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
59
77
  return .singleContent(videoOrLiveStreamID: contentId)
60
78
  }
61
79
  }
80
+ private var isInPip: Bool = false
62
81
 
63
82
  public override init(frame: CGRect) {
64
83
  super.init(frame: frame)
@@ -94,11 +113,13 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
94
113
  return
95
114
  }
96
115
 
97
- storyBlockVC.isPictureInPictureEnabled = storyBlockConfiguration?.enablePictureInPicture ?? true
98
-
99
- storyBlockVC.delegate = self
100
116
  self.storyBlockVC = storyBlockVC
101
117
  updateStoryBlockVCConfiguration()
118
+
119
+ storyBlockVC.isPictureInPictureEnabled = storyBlockConfiguration?.enablePictureInPicture ?? true
120
+ storyBlockVC.pictureInPictureDelegate = self
121
+ storyBlockVC.delegate = self
122
+
102
123
  parentVC.attachChild(storyBlockVC, to: self)
103
124
  }
104
125
 
@@ -108,7 +129,9 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
108
129
  guard let storyBlockVC = self.storyBlockVC else {
109
130
  return
110
131
  }
111
-
132
+ if !isInPip {
133
+ storyBlockVC.isPictureInPictureEnabled = false
134
+ }
112
135
  storyBlockVC.detachFromParent()
113
136
  self.storyBlockVC = nil
114
137
  }
@@ -282,6 +305,63 @@ public class StoryBlock: UIView, StoryBlockViewControllerDelegate {
282
305
  resultConfig.adBadge = adBadge
283
306
  }
284
307
 
308
+ if let videoPlayerLogoConfiguration = config.videoPlayerLogoConfiguration {
309
+ switch videoPlayerLogoConfiguration.option {
310
+ case .disabled:
311
+ resultConfig.logoConfiguration.option = .disabled
312
+ resultConfig.fullScreenPlayerView.logoConfiguration.option = .disabled
313
+ case .creator:
314
+ if let encodedId = videoPlayerLogoConfiguration.encodedId {
315
+ resultConfig.logoConfiguration.option = .creator(encodedId)
316
+ resultConfig.fullScreenPlayerView.logoConfiguration.option = .creator(encodedId)
317
+ }
318
+ case .channelAggregator:
319
+ if let encodedId = videoPlayerLogoConfiguration.encodedId {
320
+ resultConfig.logoConfiguration.option = .channelAggregator(encodedId)
321
+ resultConfig.fullScreenPlayerView.logoConfiguration.option = .channelAggregator(encodedId)
322
+ }
323
+ }
324
+ }
325
+
285
326
  storyBlockVC.viewConfiguration = resultConfig
286
327
  }
328
+
329
+ // MARK: PictureInPictureDelegate
330
+
331
+ public func pictureInPictureControllerWillStartPictureInPicture(
332
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
333
+ ) {
334
+ }
335
+
336
+ public func pictureInPictureControllerDidStartPictureInPicture(
337
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
338
+ ) {
339
+ self.onStoryBlockDidStartPictureInPicture?(nil)
340
+ isInPip = true
341
+ }
342
+
343
+ public func pictureInPictureController(
344
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController,
345
+ failedToStartPictureInPictureWithError error: Error?
346
+ ) {
347
+ }
348
+
349
+ public func pictureInPictureControllerWillStopPictureInPicture(
350
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
351
+ ) {
352
+ }
353
+
354
+ public func pictureInPictureControllerDidStopPictureInPicture(
355
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
356
+ ) {
357
+ self.onStoryBlockDidStopPictureInPicture?(nil)
358
+ isInPip = false
359
+ }
360
+
361
+ public func pictureInPictureController(
362
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController,
363
+ restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
364
+ ) {
365
+ completionHandler(true)
366
+ }
287
367
  }
@@ -23,4 +23,5 @@ public class StoryBlockConfiguration: NSObject, Codable {
23
23
  var enablePictureInPicture: Bool?
24
24
  var buttonConfiguration: VideoPlayerButtonConfiguration?
25
25
  var showVideoDetailTitle: Bool?
26
+ var videoPlayerLogoConfiguration: VideoPlayerLogoConfiguration?
26
27
  }
@@ -43,6 +43,10 @@ RCT_CUSTOM_VIEW_PROPERTY(storyBlockConfiguration, StoryBlockConfiguration, Story
43
43
 
44
44
  RCT_EXPORT_VIEW_PROPERTY(onStoryBlockLoadFinished, RCTBubblingEventBlock)
45
45
 
46
+ RCT_EXPORT_VIEW_PROPERTY(onStoryBlockDidStartPictureInPicture, RCTBubblingEventBlock)
47
+
48
+ RCT_EXPORT_VIEW_PROPERTY(onStoryBlockDidStopPictureInPicture, RCTBubblingEventBlock)
49
+
46
50
  RCT_EXPORT_METHOD(play:(nonnull NSNumber *)reactTag) {
47
51
  [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
48
52
  StoryBlock *view = (StoryBlock *)(viewRegistry[reactTag]);
@@ -33,7 +33,7 @@ public protocol VideoFeedDelegate: AnyObject {
33
33
  }
34
34
 
35
35
  @objc
36
- public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
36
+ public class VideoFeed: UIView, VideoFeedViewControllerDelegate, PictureInPictureControllerDelegate {
37
37
  @objc public var sourceType: VideFeedSourceType = .discover
38
38
  @objc public var channel: String = ""
39
39
  @objc public var playlist: String = ""
@@ -48,7 +48,8 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
48
48
  guard let feedVC = feedVC else {
49
49
  return
50
50
  }
51
- feedVC.viewConfiguration = convertToVideoFeedContentConfiguration()
51
+ let newVideoFeedContentConfiguration = convertToVideoFeedContentConfiguration()
52
+ feedVC.viewConfiguration = newVideoFeedContentConfiguration
52
53
  feedVC.layout = videoFeedLayout
53
54
  }
54
55
  }
@@ -57,7 +58,18 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
57
58
  guard let feedVC = feedVC else {
58
59
  return
59
60
  }
60
- feedVC.viewConfiguration = convertToVideoFeedContentConfiguration()
61
+
62
+ if playerViewConfig?.videoPlayerLogoConfiguration != oldValue?.videoPlayerLogoConfiguration {
63
+ feedVC.isPictureInPictureEnabled = false
64
+ feedVC.detachFromParent()
65
+ self.feedVC = nil
66
+ DispatchQueue.main.async {
67
+ self.embed()
68
+ }
69
+ } else {
70
+ let newVideoFeedContentConfiguration = convertToVideoFeedContentConfiguration()
71
+ feedVC.viewConfiguration = newVideoFeedContentConfiguration
72
+ }
61
73
  }
62
74
  }
63
75
  @objc public var adConfiguration: AdConfiguration?
@@ -65,6 +77,10 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
65
77
  @objc var onVideoFeedLoadFinished: RCTBubblingEventBlock?
66
78
  // @objc var onVideoFeedClick: RCTBubblingEventBlock?
67
79
 
80
+ @objc var onVideoFeedDidStartPictureInPicture: RCTBubblingEventBlock?
81
+
82
+ @objc var onVideoFeedDidStopPictureInPicture: RCTBubblingEventBlock?
83
+
68
84
  public weak var delegate: VideoFeedDelegate?
69
85
 
70
86
  private var feedVC: VideoFeedViewController?
@@ -141,6 +157,8 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
141
157
  return resultLayout ?? VideoFeedHorizontalLayout()
142
158
  }
143
159
 
160
+ private var isInPip: Bool = false
161
+
144
162
  public override func layoutSubviews() {
145
163
  super.layoutSubviews()
146
164
 
@@ -173,16 +191,6 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
173
191
  return
174
192
  }
175
193
 
176
- if let subView = feedVC.view.subviews.first {
177
- let constraints = feedVC.view.constraints
178
- for constraint in constraints {
179
- if (constraint.firstItem as? NSObject) == subView || (constraint.secondItem as? NSObject) == subView {
180
- constraint.isActive = false
181
- }
182
- }
183
- NSLayoutConstraint.activate(subView.constraints(equalTo: feedVC.view))
184
- }
185
-
186
194
  var viewConfiguration = convertToVideoFeedContentConfiguration()
187
195
  if viewConfiguration.itemView.autoplay.isEnabled {
188
196
  viewConfiguration.itemView.autoplay.isEnabled = false
@@ -198,7 +206,19 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
198
206
  feedVC.isPictureInPictureEnabled = playerViewConfig?.enablePictureInPicture ?? true
199
207
 
200
208
  feedVC.delegate = self
209
+ feedVC.pictureInPictureDelegate = self
201
210
  self.feedVC = feedVC
211
+
212
+ if self.mode != .row, let subView = feedVC.view.subviews.first {
213
+ let constraints = feedVC.view.constraints
214
+ for constraint in constraints {
215
+ if (constraint.firstItem as? NSObject) == subView || (constraint.secondItem as? NSObject) == subView {
216
+ constraint.isActive = false
217
+ }
218
+ }
219
+ NSLayoutConstraint.activate(subView.constraints(equalTo: feedVC.view))
220
+ }
221
+
202
222
  parentVC.attachChild(feedVC, to: self)
203
223
  }
204
224
 
@@ -209,6 +229,10 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
209
229
  return
210
230
  }
211
231
 
232
+ if !isInPip {
233
+ feedVC.isPictureInPictureEnabled = false
234
+ }
235
+
212
236
  feedVC.detachFromParent()
213
237
  self.feedVC = nil
214
238
  }
@@ -237,6 +261,45 @@ public class VideoFeed: UIView, VideoFeedViewControllerDelegate {
237
261
  }
238
262
  delegate.videoFeed(self, didFailToLoadFeed: error)
239
263
  }
264
+
265
+ // MARK: PictureInPictureDelegate
266
+
267
+ public func pictureInPictureControllerWillStartPictureInPicture(
268
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
269
+ ) {
270
+ }
271
+
272
+ public func pictureInPictureControllerDidStartPictureInPicture(
273
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
274
+ ) {
275
+ self.onVideoFeedDidStartPictureInPicture?(nil)
276
+ isInPip = true
277
+ }
278
+
279
+ public func pictureInPictureController(
280
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController,
281
+ failedToStartPictureInPictureWithError error: Error?
282
+ ) {
283
+ }
284
+
285
+ public func pictureInPictureControllerWillStopPictureInPicture(
286
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
287
+ ) {
288
+ }
289
+
290
+ public func pictureInPictureControllerDidStopPictureInPicture(
291
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController
292
+ ) {
293
+ self.onVideoFeedDidStopPictureInPicture?(nil)
294
+ isInPip = false
295
+ }
296
+
297
+ public func pictureInPictureController(
298
+ _ pictureInPictureController: FireworkVideo.PictureInPictureController,
299
+ restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
300
+ ) {
301
+ completionHandler(true)
302
+ }
240
303
  }
241
304
 
242
305
  extension VideoFeed {
@@ -432,6 +495,20 @@ extension VideoFeed {
432
495
  vpcConfig.videoDetail.titleConfiguration.isHidden = !showVideoDetailTitle
433
496
  }
434
497
 
498
+ if let videoPlayerLogoConfiguration = config.videoPlayerLogoConfiguration {
499
+ switch videoPlayerLogoConfiguration.option {
500
+ case .disabled:
501
+ vpcConfig.logoConfiguration.option = .disabled
502
+ case .creator:
503
+ if let encodedId = videoPlayerLogoConfiguration.encodedId {
504
+ vpcConfig.logoConfiguration.option = .creator(encodedId)
505
+ }
506
+ case .channelAggregator:
507
+ if let encodedId = videoPlayerLogoConfiguration.encodedId {
508
+ vpcConfig.logoConfiguration.option = .channelAggregator(encodedId)
509
+ }
510
+ }
511
+ }
435
512
  return vpcConfig
436
513
  }
437
514
 
@@ -55,6 +55,10 @@ RCT_CUSTOM_VIEW_PROPERTY(adConfiguration, AdConfiguration, VideoFeed) {
55
55
  RCT_EXPORT_VIEW_PROPERTY(onVideoFeedLoadFinished, RCTBubblingEventBlock)
56
56
  //RCT_EXPORT_VIEW_PROPERTY(onVideoFeedClick, RCTBubblingEventBlock)
57
57
 
58
+ RCT_EXPORT_VIEW_PROPERTY(onVideoFeedDidStartPictureInPicture, RCTBubblingEventBlock)
59
+
60
+ RCT_EXPORT_VIEW_PROPERTY(onVideoFeedDidStopPictureInPicture, RCTBubblingEventBlock)
61
+
58
62
  RCT_EXPORT_METHOD(refresh:(nonnull NSNumber *)reactTag) {
59
63
  [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
60
64
  VideoFeed *view = (VideoFeed *)(viewRegistry[reactTag]);
@@ -72,4 +72,5 @@ public class VideoPlayerConfiguration: NSObject, Codable {
72
72
  var enablePictureInPicture: Bool?
73
73
  var buttonConfiguration: VideoPlayerButtonConfiguration?
74
74
  var showVideoDetailTitle: Bool?
75
+ var videoPlayerLogoConfiguration: VideoPlayerLogoConfiguration?
75
76
  }
@@ -0,0 +1,18 @@
1
+ //
2
+ // VideoPlayerLogoConfiguration.swift
3
+ // react-native-firework-sdk
4
+ //
5
+ // Created by Haitao Shangguan on 2023/9/19.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ public struct VideoPlayerLogoConfiguration: Codable, Equatable {
11
+ enum LogoOption: String, Codable {
12
+ case disabled
13
+ case creator
14
+ case channelAggregator
15
+ }
16
+ var option: LogoOption = .disabled
17
+ var encodedId: String?
18
+ }
@@ -6,7 +6,7 @@ target 'FireworkVideoUI' do
6
6
  use_frameworks!
7
7
 
8
8
  # Pods for FireworkVideoUI
9
- pod 'FireworkVideo', '1.14.0'
9
+ pod 'FireworkVideo', '1.15.0'
10
10
 
11
11
  target 'FireworkVideoUITests' do
12
12
  # Pods for testing
@@ -1,16 +1,16 @@
1
1
  PODS:
2
- - FireworkVideo (1.14.0)
2
+ - FireworkVideo (1.15.0)
3
3
 
4
4
  DEPENDENCIES:
5
- - FireworkVideo (= 1.14.0)
5
+ - FireworkVideo (= 1.15.0)
6
6
 
7
7
  SPEC REPOS:
8
8
  trunk:
9
9
  - FireworkVideo
10
10
 
11
11
  SPEC CHECKSUMS:
12
- FireworkVideo: c8af446a350e2486e86c0a789ecfd4a57ce6facc
12
+ FireworkVideo: fae657a5093efadbf7f4aa723466aee8dcf47824
13
13
 
14
- PODFILE CHECKSUM: 880bd5c72a5a81b620b803189a6ec208e8481116
14
+ PODFILE CHECKSUM: b8d50fd1ccf28eaa3033fe13c43ca09199e1e245
15
15
 
16
16
  COCOAPODS: 1.12.1
@@ -8,7 +8,7 @@
8
8
  import UIKit
9
9
  import FireworkVideo
10
10
 
11
- private class RCTRootViewPlaceholder: UIView {
11
+ class RCTRootViewPlaceholder: UIView {
12
12
  weak var reactViewController: UIViewController?
13
13
  }
14
14
 
@@ -17,7 +17,7 @@ private struct RCTRootViewResult {
17
17
  weak var view: RCTRootView?
18
18
  }
19
19
 
20
- private struct RCTRootViewPlaceholderResult {
20
+ struct RCTRootViewPlaceholderResult {
21
21
  weak var viewController: UIViewController?
22
22
  weak var view: RCTRootViewPlaceholder?
23
23
  }
@@ -223,6 +223,7 @@ class FWNavigatorModule: RCTEventEmitter {
223
223
  }
224
224
 
225
225
  let childViewControllers = rootView.reactViewController()?.children
226
+ containerVC.rootView = nil
226
227
  containerVC.dismiss(animated: true) {
227
228
  childViewControllers?.forEach { (childViewController) in
228
229
  let detachedController = childViewController
@@ -318,7 +319,19 @@ extension FWNavigatorModule {
318
319
  return nil
319
320
  }
320
321
 
321
- private static func findRCTRootViewPlaceholderResult(
322
+ }
323
+
324
+ extension FWNavigatorModule {
325
+ static func stopFloatingPlayer() -> Bool {
326
+ do {
327
+ try PictureInPictureController.stop()
328
+ return true
329
+ } catch {
330
+ return false
331
+ }
332
+ }
333
+
334
+ static func findRCTRootViewPlaceholderResult(
322
335
  _ viewController: UIViewController
323
336
  ) -> RCTRootViewPlaceholderResult? {
324
337
  if let rootViewPlaceholder = viewController.view as? RCTRootViewPlaceholder {
@@ -334,14 +347,3 @@ extension FWNavigatorModule {
334
347
  return nil
335
348
  }
336
349
  }
337
-
338
- extension FWNavigatorModule {
339
- static func stopFloatingPlayer() -> Bool {
340
- do {
341
- try PictureInPictureController.stop()
342
- return true
343
- } catch {
344
- return false
345
- }
346
- }
347
- }
@@ -15,6 +15,36 @@ class FWRNPresentContainerViewController: UIViewController {
15
15
  loadContent()
16
16
  }
17
17
 
18
+ override func viewDidDisappear(_ animated: Bool) {
19
+ super.viewDidDisappear(animated)
20
+ if let rootView = rootView {
21
+ guard let rootVC = RCTKeyWindow()?.rootViewController,
22
+ let rootViewPlaceholderResult = FWNavigatorModule.findRCTRootViewPlaceholderResult(rootVC),
23
+ let rootViewPlaceholderVC = rootViewPlaceholderResult.viewController,
24
+ let rootViewPlaceholder = rootViewPlaceholderResult.view else {
25
+ return
26
+ }
27
+
28
+ let childViewControllers = rootView.reactViewController()?.children
29
+ childViewControllers?.forEach { (childViewController) in
30
+ let detachedController = childViewController
31
+ detachedController.willMove(toParent: nil)
32
+ detachedController.removeFromParent()
33
+ rootViewPlaceholderVC.addChild(detachedController)
34
+ detachedController.didMove(toParent: rootViewPlaceholderVC)
35
+ }
36
+ rootView.removeFromSuperview()
37
+ rootViewPlaceholderVC.view = rootView
38
+
39
+ if let reactViewController = rootViewPlaceholder.reactViewController {
40
+ // Restore previous reactViewController
41
+ rootView.setReactViewController(reactViewController)
42
+ }
43
+
44
+ self.rootView = nil
45
+ }
46
+ }
47
+
18
48
  private func loadContent() {
19
49
  guard let rootView = rootView else {
20
50
  return
@@ -20,9 +20,30 @@ extension FireworkSDKModule: FireworkVideoCTADelegate {
20
20
  "[iOS] Receive CustomCTAClick event \(formatter.string(from: Date()))"
21
21
  ])
22
22
  #endif
23
-
24
- sendEvent(withName: FWEventName.customCTAClick.rawValue, body: ["url": url.absoluteString])
23
+ let callbackId = UUID().uuidString
24
+ playerMap.setObject(viewController, forKey: callbackId as NSString)
25
+ sendEvent(withName: FWEventName.customCTAClick.rawValue,
26
+ body: [
27
+ "url": url.absoluteString,
28
+ "callbackId": callbackId
29
+ ])
25
30
 
26
31
  return customCTAClickEnabled
27
32
  }
33
+
34
+ @objc(pausePlayer:)
35
+ func pausePlayer(_ callbackId: String) {
36
+ if let playerViewController = playerMap.object(forKey: callbackId as NSString),
37
+ let playerViewController = playerViewController as? PlayerViewController {
38
+ playerViewController.pause()
39
+ }
40
+ }
41
+
42
+ @objc(resumePlayer:)
43
+ func resumePlayer(_ callbackId: String) {
44
+ if let playerViewController = playerMap.object(forKey: callbackId as NSString),
45
+ let playerViewController = playerViewController as? PlayerViewController {
46
+ playerViewController.resume()
47
+ }
48
+ }
28
49
  }
@@ -19,5 +19,7 @@ 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(trackPurchase:(NSDictionary *)parameters)
21
21
  RCT_EXTERN_METHOD(changeAppLanguage:(NSString * __nullable)language resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
22
+ RCT_EXTERN_METHOD(pausePlayer:(NSString *)callbackId)
23
+ RCT_EXTERN_METHOD(resumePlayer:(NSString *)callbackId)
22
24
 
23
25
  @end
@@ -23,6 +23,9 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
23
23
  /// Decide whether to send video playback event to RN.
24
24
  var enableVideoPlayBackEvent: Bool = false
25
25
 
26
+ // player view controller
27
+ var playerMap: NSMapTable<NSString, UIViewController> = NSMapTable.strongToWeakObjects()
28
+
26
29
  override init() {
27
30
  super.init()
28
31
  _ = AppLanguageManager.shared
@@ -28,14 +28,6 @@ struct ProductInfoViewConfiguration: Codable {
28
28
  var isHidden: Bool?
29
29
  }
30
30
 
31
- struct ProductCardConfiguration: Codable {
32
- var theme: ProductCardTheme?
33
- var ctaButtonText: ProductCardCTAButtonText?
34
- var cornerRadius: CGFloat?
35
- var priceConfiguration: ProductCardPriceConfiguration?
36
- var isCtaButtonHidden: Bool?
37
- }
38
-
39
31
  enum ProductCardTheme: String, Codable {
40
32
  case light
41
33
  case dark
@@ -46,7 +38,48 @@ struct ProductInfoViewConfiguration: Codable {
46
38
  case buyNow
47
39
  }
48
40
 
41
+ enum ProductCardPriceLabelAxis: String, Codable {
42
+ case horizontal
43
+ case vertical
44
+ }
45
+
46
+ struct ProductCardLabelConfiguration: Codable {
47
+ var textColor: String?
48
+ var fontSize: Double?
49
+ var numberOfLines: Int?
50
+ var iOSFontInfo: FontInfo?
51
+ }
52
+
49
53
  struct ProductCardPriceConfiguration: Codable {
54
+ @available(*, deprecated, message: "This property has no effect.")
50
55
  var isHidden: Bool?
56
+ var axis: ProductCardPriceLabelAxis?
57
+ var priceLabel: ProductCardLabelConfiguration?
58
+ var originalPriceLabel: ProductCardLabelConfiguration?
59
+ var isPriceFirst: Bool?
60
+ }
61
+
62
+ struct ProductCardIconConfiguration: Codable {
63
+ var cornerRadius: CGFloat?
64
+ }
65
+
66
+ struct ProductCardCTAButtonStyle: Codable {
67
+ var textColor: String?
68
+ var fontSize: Double?
69
+ var iOSFontInfo: FontInfo?
70
+ }
71
+
72
+ struct ProductCardConfiguration: Codable {
73
+ var theme: ProductCardTheme?
74
+ var cornerRadius: CGFloat?
75
+ var ctaButtonText: ProductCardCTAButtonText?
76
+ var isCtaButtonHidden: Bool?
77
+ var ctaButtonStyle: ProductCardCTAButtonStyle?
78
+ var priceConfiguration: ProductCardPriceConfiguration?
79
+ var width: CGFloat?
80
+ var height: CGFloat?
81
+ var backgroundColor: String?
82
+ var iconConfiguration: ProductCardIconConfiguration?
83
+ var nameLabel: ProductCardLabelConfiguration?
51
84
  }
52
85
  }
@@ -18,5 +18,7 @@ RCT_EXTERN_METHOD(clearCallbackId:(nonnull NSNumber *)cbId eventName:(nonnull NS
18
18
  RCT_EXTERN_METHOD(setCustomClickLinkButtonEnabled:(BOOL)enabled resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
19
19
  RCT_EXTERN_METHOD(updateShoppingCTAResult:(NSDictionary *)result cbId:(nonnull NSNumber *)cbId)
20
20
  RCT_EXTERN_METHOD(setCustomTapProductCardEnabled:(BOOL)enabled resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
21
+ RCT_EXTERN_METHOD(pausePlayer:(NSNumber *)callbackId)
22
+ RCT_EXTERN_METHOD(resumePlayer:(NSNumber *)callbackId)
21
23
 
22
24
  @end