react-native-firework-sdk 1.7.0 → 2.0.0-beta.1

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 (141) hide show
  1. package/android/build.gradle +25 -43
  2. package/android/src/main/AndroidManifest.xml +4 -4
  3. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +48 -194
  4. package/android/src/main/java/com/fireworksdk/bridge/constants/FWVideoPlayerConstant.kt +7 -0
  5. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdBadgeConfigModel.kt +2 -0
  6. package/android/src/main/java/com/fireworksdk/bridge/models/FWAdBadgeConfigModelDeserializer.kt +24 -0
  7. package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +1 -0
  8. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +17 -0
  9. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +35 -0
  10. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedConfigModel.kt +12 -13
  11. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedConfigModelDeserializer.kt +67 -0
  12. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedItemDetailsModel.kt +1 -1
  13. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +9 -10
  14. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +67 -0
  15. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlaybackDetails.kt +0 -3
  16. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +19 -11
  17. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +74 -0
  18. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoShoppingProduct.kt +17 -15
  19. package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoShoppingProductDeserializer.kt +120 -0
  20. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +4 -130
  21. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +48 -100
  22. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWNavigatorInterface.kt +2 -0
  23. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +2 -1
  24. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWLiveStreamModule.kt +2 -50
  25. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +17 -35
  26. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +152 -108
  27. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +87 -133
  28. package/android/src/main/java/com/fireworksdk/bridge/reactnative/pages/FWContainerActivity.kt +1 -14
  29. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/{FWDataUtils.kt → FWDataConvertUtils.kt} +1 -11
  30. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +14 -5
  31. package/android/src/main/java/com/fireworksdk/bridge/utils/FWCommonUtil.kt +23 -0
  32. package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +312 -0
  33. package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +14 -0
  34. package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +30 -14
  35. package/android/src/main/res/layout/fw_bridge_fragment_container.xml +2 -2
  36. package/android/src/main/res/values/colors.xml +2 -2
  37. package/android/src/main/res/values/styles.xml +0 -40
  38. package/ios/Components/StoryBlock.swift +1 -8
  39. package/ios/Components/StoryBlockManager.swift +4 -0
  40. package/ios/Components/VideoFeed.swift +9 -14
  41. package/ios/Components/VideoFeedConfiguration.swift +2 -0
  42. package/ios/Components/VideoFeedManager.m +2 -0
  43. package/ios/Components/VideoFeedManager.swift +4 -0
  44. package/ios/Components/VideoPlayerConfiguration.swift +1 -0
  45. package/ios/FireworkSdk.xcodeproj/project.pbxproj +12 -8
  46. package/ios/Models/Common/FontInfo.swift +57 -0
  47. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.m +2 -0
  48. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +295 -103
  49. package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +0 -2
  50. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +12 -12
  51. package/ios/Modules/LiveStream/LiveStreamModule.swift +5 -3
  52. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +7 -2
  53. package/ios/Modules/Shopping/ShoppingModule.m +1 -1
  54. package/ios/Modules/Shopping/ShoppingModule.swift +72 -63
  55. package/ios/Utils/FWSwizzleLoader.m +0 -1
  56. package/lib/commonjs/FWNavigator.js +14 -16
  57. package/lib/commonjs/FWNavigator.js.map +1 -1
  58. package/lib/commonjs/FireworkSDK.js +5 -39
  59. package/lib/commonjs/FireworkSDK.js.map +1 -1
  60. package/lib/commonjs/LiveStream.js +2 -2
  61. package/lib/commonjs/LiveStream.js.map +1 -1
  62. package/lib/commonjs/VideoShopping.js +59 -39
  63. package/lib/commonjs/VideoShopping.js.map +1 -1
  64. package/lib/commonjs/components/StoryBlock.js +3 -0
  65. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  66. package/lib/commonjs/components/VideoFeed.js +14 -5
  67. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  68. package/lib/commonjs/index.js.map +1 -1
  69. package/lib/commonjs/models/FWEventName.js +1 -1
  70. package/lib/commonjs/models/FWEventName.js.map +1 -1
  71. package/lib/commonjs/models/IOSFontInfo.js +2 -0
  72. package/lib/commonjs/modules/FWNavigatorModule.js.map +1 -1
  73. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  74. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  75. package/lib/module/FWNavigator.js +15 -16
  76. package/lib/module/FWNavigator.js.map +1 -1
  77. package/lib/module/FireworkSDK.js +5 -37
  78. package/lib/module/FireworkSDK.js.map +1 -1
  79. package/lib/module/LiveStream.js +2 -2
  80. package/lib/module/LiveStream.js.map +1 -1
  81. package/lib/module/VideoShopping.js +58 -38
  82. package/lib/module/VideoShopping.js.map +1 -1
  83. package/lib/module/components/StoryBlock.js +3 -0
  84. package/lib/module/components/StoryBlock.js.map +1 -1
  85. package/lib/module/components/VideoFeed.js +14 -5
  86. package/lib/module/components/VideoFeed.js.map +1 -1
  87. package/lib/module/index.js.map +1 -1
  88. package/lib/module/models/FWEventName.js +1 -1
  89. package/lib/module/models/FWEventName.js.map +1 -1
  90. package/lib/module/models/IOSFontInfo.js +2 -0
  91. package/lib/module/modules/FWNavigatorModule.js.map +1 -1
  92. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  93. package/lib/module/modules/ShoppingModule.js.map +1 -1
  94. package/lib/typescript/FWNavigator.d.ts +11 -14
  95. package/lib/typescript/FireworkSDK.d.ts +5 -16
  96. package/lib/typescript/LiveStream.d.ts +2 -2
  97. package/lib/typescript/VideoShopping.d.ts +24 -19
  98. package/lib/typescript/components/StoryBlock.d.ts +4 -1
  99. package/lib/typescript/components/VideoFeed.d.ts +7 -3
  100. package/lib/typescript/index.d.ts +6 -5
  101. package/lib/typescript/models/FWEventName.d.ts +2 -2
  102. package/lib/typescript/models/FWEvents.d.ts +5 -6
  103. package/lib/typescript/models/IOSFontInfo.d.ts +19 -0
  104. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +23 -0
  105. package/lib/typescript/models/VideoFeedConfiguration.d.ts +22 -4
  106. package/lib/typescript/models/VideoPlayerConfiguration.d.ts +18 -2
  107. package/lib/typescript/modules/FWNavigatorModule.d.ts +2 -3
  108. package/lib/typescript/modules/FireworkSDKModule.d.ts +0 -2
  109. package/lib/typescript/modules/ShoppingModule.d.ts +2 -3
  110. package/package.json +1 -1
  111. package/react-native-firework-sdk.podspec +1 -1
  112. package/src/FWNavigator.ts +52 -0
  113. package/src/FireworkSDK.ts +5 -31
  114. package/src/LiveStream.ts +2 -2
  115. package/src/VideoShopping.ts +74 -54
  116. package/src/components/StoryBlock.tsx +4 -1
  117. package/src/components/VideoFeed.tsx +15 -5
  118. package/src/{index.tsx → index.ts} +17 -9
  119. package/src/models/FWEventName.ts +1 -1
  120. package/src/models/FWEvents.ts +6 -7
  121. package/src/models/IOSFontInfo.ts +29 -0
  122. package/src/models/ProductInfoViewConfiguration.ts +25 -0
  123. package/src/models/VideoFeedConfiguration.ts +23 -4
  124. package/src/models/VideoPlayerConfiguration.ts +19 -2
  125. package/src/modules/FWNavigatorModule.ts +2 -1
  126. package/src/modules/FireworkSDKModule.ts +0 -2
  127. package/src/modules/ShoppingModule.ts +2 -9
  128. package/android/src/main/java/com/fireworksdk/bridge/utils/FWGsonUtil.kt +0 -38
  129. package/android/src/main/java/com/fireworksdk/bridge/utils/FWVideoPlayerUtils.kt +0 -122
  130. package/android/src/main/res/layout/fw_bridge_fragment_playlistfeed.xml +0 -18
  131. package/android/src/main/res/layout/fw_bridge_fragment_shoppingcart.xml +0 -8
  132. package/android/src/main/res/layout/fw_bridge_fragment_videofeed.xml +0 -17
  133. package/ios/Utils/FWPiPManager.swift +0 -24
  134. package/ios/Utils/UIButton+FWSwizzle.swift +0 -33
  135. package/lib/commonjs/models/NewNativeContainerProps.js +0 -2
  136. package/lib/module/models/NewNativeContainerProps.js +0 -2
  137. package/lib/typescript/models/NewNativeContainerProps.d.ts +0 -6
  138. package/src/FWNavigator.tsx +0 -58
  139. package/src/models/NewNativeContainerProps.ts +0 -4
  140. /package/lib/commonjs/models/{NewNativeContainerProps.js.map → IOSFontInfo.js.map} +0 -0
  141. /package/lib/module/models/{NewNativeContainerProps.js.map → IOSFontInfo.js.map} +0 -0
@@ -11,8 +11,6 @@
11
11
  8953CF5E2993E0D200F7413E /* UINavigationController+FWSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF5D2993E0D200F7413E /* UINavigationController+FWSwizzle.swift */; };
12
12
  8953CF602993E3B200F7413E /* FWSwizzleUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF5F2993E3B200F7413E /* FWSwizzleUtil.swift */; };
13
13
  8953CF622993E44E00F7413E /* DispatchQueue+FWOnce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF612993E44E00F7413E /* DispatchQueue+FWOnce.swift */; };
14
- 8953CF642993EF8200F7413E /* UIButton+FWSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF632993EF8200F7413E /* UIButton+FWSwizzle.swift */; };
15
- 8953CF662993F13800F7413E /* FWPiPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF652993F13800F7413E /* FWPiPManager.swift */; };
16
14
  8953CF6C2993FAAB00F7413E /* FWSwizzleLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8953CF6B2993FAAB00F7413E /* FWSwizzleLoader.m */; };
17
15
  896A8EB928E3DCCA007E51F8 /* AdConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896A8EB828E3DCCA007E51F8 /* AdConfiguration.swift */; };
18
16
  8975235E2817DEEE0070EBB6 /* VideoFeedManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897523592817DEEE0070EBB6 /* VideoFeedManager.swift */; };
@@ -45,6 +43,7 @@
45
43
  8975239E2817DEF80070EBB6 /* FireworkSDKModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 897523832817DEF80070EBB6 /* FireworkSDKModule.m */; };
46
44
  8975239F2817DEF80070EBB6 /* LiveStreamModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897523852817DEF80070EBB6 /* LiveStreamModule.swift */; };
47
45
  897523A02817DEF80070EBB6 /* LiveStreamModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 897523862817DEF80070EBB6 /* LiveStreamModule.m */; };
46
+ 89D6BBF929ACE2DC00C8AA2A /* FontInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89D6BBF829ACE2DC00C8AA2A /* FontInfo.swift */; };
48
47
  89DF27DD28A53A77003F3CCB /* StoryBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DF27DA28A53A77003F3CCB /* StoryBlock.swift */; };
49
48
  89DF27DE28A53A77003F3CCB /* StoryBlockManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DF27DB28A53A77003F3CCB /* StoryBlockManager.swift */; };
50
49
  89DF27DF28A53A77003F3CCB /* StoryBlockManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 89DF27DC28A53A77003F3CCB /* StoryBlockManager.m */; };
@@ -70,8 +69,6 @@
70
69
  8953CF5D2993E0D200F7413E /* UINavigationController+FWSwizzle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+FWSwizzle.swift"; sourceTree = "<group>"; };
71
70
  8953CF5F2993E3B200F7413E /* FWSwizzleUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FWSwizzleUtil.swift; sourceTree = "<group>"; };
72
71
  8953CF612993E44E00F7413E /* DispatchQueue+FWOnce.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+FWOnce.swift"; sourceTree = "<group>"; };
73
- 8953CF632993EF8200F7413E /* UIButton+FWSwizzle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+FWSwizzle.swift"; sourceTree = "<group>"; };
74
- 8953CF652993F13800F7413E /* FWPiPManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FWPiPManager.swift; sourceTree = "<group>"; };
75
72
  8953CF6A2993FAAB00F7413E /* FWSwizzleLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FWSwizzleLoader.h; sourceTree = "<group>"; };
76
73
  8953CF6B2993FAAB00F7413E /* FWSwizzleLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWSwizzleLoader.m; sourceTree = "<group>"; };
77
74
  896A8EB828E3DCCA007E51F8 /* AdConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdConfiguration.swift; sourceTree = "<group>"; };
@@ -106,6 +103,7 @@
106
103
  897523832817DEF80070EBB6 /* FireworkSDKModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FireworkSDKModule.m; sourceTree = "<group>"; };
107
104
  897523852817DEF80070EBB6 /* LiveStreamModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LiveStreamModule.swift; sourceTree = "<group>"; };
108
105
  897523862817DEF80070EBB6 /* LiveStreamModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveStreamModule.m; sourceTree = "<group>"; };
106
+ 89D6BBF829ACE2DC00C8AA2A /* FontInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontInfo.swift; sourceTree = "<group>"; };
109
107
  89DF27DA28A53A77003F3CCB /* StoryBlock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryBlock.swift; sourceTree = "<group>"; };
110
108
  89DF27DB28A53A77003F3CCB /* StoryBlockManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryBlockManager.swift; sourceTree = "<group>"; };
111
109
  89DF27DC28A53A77003F3CCB /* StoryBlockManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StoryBlockManager.m; sourceTree = "<group>"; };
@@ -170,8 +168,6 @@
170
168
  897523672817DEF80070EBB6 /* String+Color.swift */,
171
169
  897523682817DEF80070EBB6 /* UIView+ParentViewController.swift */,
172
170
  8953CF5D2993E0D200F7413E /* UINavigationController+FWSwizzle.swift */,
173
- 8953CF632993EF8200F7413E /* UIButton+FWSwizzle.swift */,
174
- 8953CF652993F13800F7413E /* FWPiPManager.swift */,
175
171
  8953CF6A2993FAAB00F7413E /* FWSwizzleLoader.h */,
176
172
  8953CF6B2993FAAB00F7413E /* FWSwizzleLoader.m */,
177
173
  );
@@ -181,6 +177,7 @@
181
177
  897523692817DEF80070EBB6 /* Models */ = {
182
178
  isa = PBXGroup;
183
179
  children = (
180
+ 89D6BBF729ACE28300C8AA2A /* Common */,
184
181
  8975236A2817DEF80070EBB6 /* RNToNative */,
185
182
  8975236E2817DEF80070EBB6 /* NativeToRN */,
186
183
  );
@@ -263,6 +260,14 @@
263
260
  path = LiveStream;
264
261
  sourceTree = "<group>";
265
262
  };
263
+ 89D6BBF729ACE28300C8AA2A /* Common */ = {
264
+ isa = PBXGroup;
265
+ children = (
266
+ 89D6BBF829ACE2DC00C8AA2A /* FontInfo.swift */,
267
+ );
268
+ path = Common;
269
+ sourceTree = "<group>";
270
+ };
266
271
  /* End PBXGroup section */
267
272
 
268
273
  /* Begin PBXNativeTarget section */
@@ -330,15 +335,14 @@
330
335
  89DF27E128A53A89003F3CCB /* RCTConvert+StoryBlock.swift in Sources */,
331
336
  8953CF6C2993FAAB00F7413E /* FWSwizzleLoader.m in Sources */,
332
337
  8975235F2817DEEE0070EBB6 /* VideoFeedConfiguration.swift in Sources */,
338
+ 89D6BBF929ACE2DC00C8AA2A /* FontInfo.swift in Sources */,
333
339
  897523612817DEEE0070EBB6 /* VideoPlayerConfiguration.swift in Sources */,
334
340
  897523972817DEF80070EBB6 /* Product.swift in Sources */,
335
341
  89DF27DD28A53A77003F3CCB /* StoryBlock.swift in Sources */,
336
342
  89DF27DF28A53A77003F3CCB /* StoryBlockManager.m in Sources */,
337
- 8953CF642993EF8200F7413E /* UIButton+FWSwizzle.swift in Sources */,
338
343
  897523932817DEF80070EBB6 /* FWNavigatorModule.m in Sources */,
339
344
  897523922817DEF80070EBB6 /* FWNavigatorModule.swift in Sources */,
340
345
  897523872817DEF80070EBB6 /* UIViewController+AttachChild.swift in Sources */,
341
- 8953CF662993F13800F7413E /* FWPiPManager.swift in Sources */,
342
346
  897523902817DEF80070EBB6 /* FWNavigatorProtocol.swift in Sources */,
343
347
  897523882817DEF80070EBB6 /* UIView+Constraints.swift in Sources */,
344
348
  897523982817DEF80070EBB6 /* ShoppingModule.swift in Sources */,
@@ -0,0 +1,57 @@
1
+ //
2
+ // FontInfo.swift
3
+ //
4
+ // Created by linjie jiang on 2023/2/27.
5
+ //
6
+
7
+ import UIKit
8
+
9
+ @objc
10
+ public class FontInfo: NSObject, Codable {
11
+ var fontName: String?
12
+ var systemFontStyle: SystemFontStyle?
13
+ var systemFontWeight: SystemFontWeight?
14
+
15
+ public enum SystemFontStyle: String, Codable {
16
+ case normal, italic
17
+ }
18
+
19
+ public enum SystemFontWeight: String, Codable {
20
+ case ultraLight, thin, light, regular, medium, semibold, bold, heavy, black
21
+
22
+ func getFontWeight() -> UIFont.Weight {
23
+ switch self {
24
+ case .ultraLight:
25
+ return .ultraLight
26
+ case .thin:
27
+ return .thin
28
+ case .light:
29
+ return .light
30
+ case .regular:
31
+ return .regular
32
+ case .medium:
33
+ return .medium
34
+ case .semibold:
35
+ return .semibold
36
+ case .bold:
37
+ return .bold
38
+ case .heavy:
39
+ return .heavy
40
+ case .black:
41
+ return .black
42
+ }
43
+ }
44
+ }
45
+
46
+ public func getFont(_ fontSize: Double) -> UIFont {
47
+ if let fontName = fontName, let font = UIFont(name: fontName, size: fontSize) {
48
+ return font
49
+ } else if let fontStyle = systemFontStyle, fontStyle == .italic {
50
+ return UIFont.italicSystemFont(ofSize: fontSize)
51
+ } else if let systemFontWeight = systemFontWeight?.getFontWeight() {
52
+ return UIFont.systemFont(ofSize: fontSize, weight: systemFontWeight)
53
+ } else {
54
+ return UIFont.systemFont(ofSize: fontSize)
55
+ }
56
+ }
57
+ }
@@ -14,5 +14,7 @@
14
14
  RCT_EXTERN_METHOD(pushNativeContainer:(NSDictionary *)props resolver:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
15
15
  RCT_EXTERN_METHOD(popNativeContainer:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
16
16
  RCT_EXTERN_METHOD(canPopNativeContainer:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
17
+ RCT_EXTERN_METHOD(startFloatingPlayer:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
18
+ RCT_EXTERN_METHOD(stopFloatingPlayer:(RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
17
19
 
18
20
  @end
@@ -7,6 +7,22 @@
7
7
 
8
8
  import FireworkVideo
9
9
 
10
+ private struct PlayerInfo {
11
+ enum PlayerMode: Int {
12
+ case fullscreen, floating
13
+ }
14
+ var playerVC: PlayerViewController
15
+ var mode: PlayerMode
16
+ }
17
+
18
+ private struct PlayerExitButtonInfo {
19
+ enum ExitButtonType: Int {
20
+ case close, floating
21
+ }
22
+ var button: UIButton
23
+ var type: ExitButtonType
24
+ }
25
+
10
26
  @objc(FWNavigatorModule)
11
27
  class FWNavigatorModule: RCTEventEmitter, FWNavigator {
12
28
  override func supportedEvents() -> [String]! {
@@ -17,6 +33,10 @@ class FWNavigatorModule: RCTEventEmitter, FWNavigator {
17
33
  return true
18
34
  }
19
35
 
36
+ override var methodQueue: DispatchQueue {
37
+ return DispatchQueue.main
38
+ }
39
+
20
40
  // swiftlint:disable function_body_length
21
41
 
22
42
  @objc(pushNativeContainer:resolver:rejecter:)
@@ -34,92 +54,72 @@ class FWNavigatorModule: RCTEventEmitter, FWNavigator {
34
54
  ])
35
55
  #endif
36
56
 
37
- DispatchQueue.main.async {
38
- guard let props = props as? [String: Any] else {
39
- resolver(false)
40
- return
41
- }
57
+ guard let props = props as? [String: Any] else {
58
+ resolver(false)
59
+ return
60
+ }
42
61
 
43
- guard let appComponentName = gAppComponentName, appComponentName.count > 0 else {
44
- resolver(false)
45
- return
46
- }
62
+ guard let appComponentName = gAppComponentName, appComponentName.count > 0 else {
63
+ resolver(false)
64
+ return
65
+ }
47
66
 
48
- guard let presentedVC = RCTPresentedViewController() else {
49
- resolver(false)
50
- return
51
- }
67
+ guard let presentedVC = RCTPresentedViewController() else {
68
+ resolver(false)
69
+ return
70
+ }
52
71
 
53
- #if DEBUG
54
- self.sendEvent(
55
- withName: FWEventName.logMessage.rawValue,
56
- body: [
57
- "message":
58
- "[iOS] Before creating containerViewController \(formatter.string(from: Date()))"
59
- ])
60
- #endif
72
+ #if DEBUG
73
+ self.sendEvent(
74
+ withName: FWEventName.logMessage.rawValue,
75
+ body: [
76
+ "message":
77
+ "[iOS] Before creating containerViewController \(formatter.string(from: Date()))"
78
+ ])
79
+ #endif
61
80
 
62
- let containerViewController = FWNavigatorContainerViewController()
81
+ let containerViewController = FWNavigatorContainerViewController()
63
82
 
64
- #if DEBUG
65
- self.sendEvent(
66
- withName: FWEventName.logMessage.rawValue,
67
- body: [
68
- "message":
69
- "[iOS] After creating containerViewController \(formatter.string(from: Date()))"
70
- ])
71
- #endif
83
+ #if DEBUG
84
+ self.sendEvent(
85
+ withName: FWEventName.logMessage.rawValue,
86
+ body: [
87
+ "message":
88
+ "[iOS] After creating containerViewController \(formatter.string(from: Date()))"
89
+ ])
90
+ #endif
72
91
 
73
- containerViewController.moduleName = appComponentName
74
- containerViewController.properties = props
75
- containerViewController.modalPresentationStyle = .fullScreen
76
- if presentedVC.modalPresentationStyle == .custom,
77
- let presentingVC = presentedVC.presentingViewController,
78
- presentingVC is FireworkVideo.PlayerViewController
79
- {
80
- containerViewController.modalPresentationStyle = .overFullScreen
81
- }
92
+ containerViewController.moduleName = appComponentName
93
+ containerViewController.properties = props
94
+ containerViewController.modalPresentationStyle = .fullScreen
95
+ if presentedVC.modalPresentationStyle == .custom,
96
+ let presentingVC = presentedVC.presentingViewController,
97
+ presentingVC is FireworkVideo.PlayerViewController
98
+ {
99
+ containerViewController.modalPresentationStyle = .overFullScreen
100
+ }
101
+
102
+ #if DEBUG
103
+ self.sendEvent(
104
+ withName: FWEventName.logMessage.rawValue,
105
+ body: [
106
+ "message":
107
+ "[iOS] Present containerViewController \(formatter.string(from: Date()))"
108
+ ])
109
+ #endif
82
110
 
111
+ presentedVC.present(containerViewController, animated: true) {
83
112
  #if DEBUG
84
113
  self.sendEvent(
85
114
  withName: FWEventName.logMessage.rawValue,
86
115
  body: [
87
116
  "message":
88
- "[iOS] Present containerViewController \(formatter.string(from: Date()))"
117
+ "[iOS] Finish presenting containerViewController \(formatter.string(from: Date()))"
89
118
  ])
90
119
  #endif
91
120
 
92
- presentedVC.present(containerViewController, animated: true) {
93
- #if DEBUG
94
- self.sendEvent(
95
- withName: FWEventName.logMessage.rawValue,
96
- body: [
97
- "message":
98
- "[iOS] Finish presenting containerViewController \(formatter.string(from: Date()))"
99
- ])
100
- #endif
101
-
102
- resolver(true)
103
- }
104
- }
105
- }
106
-
107
- func getCloseButton(view: UIView) -> UIButton? {
108
- if let button = view as? UIButton, let targetImage = button.image(for: .normal) {
109
- let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
110
- if targetImage.isEqual(UIImage(named: "closeX", in: iOSSDKBundle, compatibleWith: nil))
111
- || targetImage.isEqual(UIImage(named: "down-arrow-light", in: iOSSDKBundle, compatibleWith: nil)) {
112
- return button
113
- }
114
- }
115
-
116
- for subview in view.subviews {
117
- if let result = getCloseButton(view: subview) {
118
- return result
119
- }
121
+ resolver(true)
120
122
  }
121
-
122
- return nil
123
123
  }
124
124
 
125
125
  // swiftlint:enable function_body_length
@@ -128,45 +128,54 @@ class FWNavigatorModule: RCTEventEmitter, FWNavigator {
128
128
  func popNativeContainer(
129
129
  _ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
130
130
  ) {
131
- DispatchQueue.main.async {
132
- if let navigatorContainerVC = RCTPresentedViewController()
133
- as? FWNavigatorContainerViewController,
134
- navigatorContainerVC.presentingViewController != nil {
135
- navigatorContainerVC.dismiss(animated: true) {
136
- resolver(true)
137
- }
138
- } else if let cartViewController = gCartViewController {
139
- cartViewController.navigationController?.popViewController(animated: true)
140
- gCartViewController = nil
131
+ if let navigatorContainerVC = RCTPresentedViewController()
132
+ as? FWNavigatorContainerViewController,
133
+ navigatorContainerVC.presentingViewController != nil {
134
+ navigatorContainerVC.dismiss(animated: true) {
141
135
  resolver(true)
142
- } else if let presentedVC = RCTPresentedViewController(),
143
- let presentingVC = presentedVC.presentingViewController,
144
- presentingVC.presentingViewController == RCTKeyWindow()?.rootViewController {
145
- presentedVC.dismiss(animated: false) {
146
- DispatchQueue.main.asyncAfter(wallDeadline: .now() + 0.1) {
147
- if let closeButton = self.getCloseButton(view: presentingVC.view) {
148
- closeButton.sendActions(for: .touchUpInside)
136
+ }
137
+ } else if let cartViewController = gCartViewController {
138
+ cartViewController.navigationController?.popViewController(animated: true)
139
+ gCartViewController = nil
140
+ resolver(true)
141
+ } else if let presentedVC = RCTPresentedViewController(),
142
+ FWNavigatorModule.isIOSSDKViewController(presentedVC),
143
+ let presentingVC = presentedVC.presentingViewController,
144
+ presentingVC.presentingViewController == RCTKeyWindow()?.rootViewController,
145
+ FWNavigatorModule.isIOSSDKViewController(presentingVC) {
146
+ presentedVC.dismiss(animated: false) {
147
+ DispatchQueue.main.asyncAfter(wallDeadline: .now() + 0.1) {
148
+ if let buttonInfo = FWNavigatorModule.getPlayerExitButtonInfo(view: presentingVC.view) {
149
+ if buttonInfo.type == .close {
150
+ buttonInfo.button.sendActions(for: .touchUpInside)
149
151
  resolver(true)
150
152
  } else {
151
- presentingVC.dismiss(animated: true) {
152
- resolver(true)
153
- }
153
+ resolver(false)
154
+ }
155
+ } else {
156
+ presentingVC.dismiss(animated: true) {
157
+ resolver(true)
154
158
  }
155
159
  }
156
160
  }
157
- } else if let rootVC = RCTKeyWindow()?.rootViewController,
158
- let presentedVC = rootVC.presentedViewController {
159
- if let closeButton = self.getCloseButton(view: presentedVC.view) {
160
- closeButton.sendActions(for: .touchUpInside)
161
+ }
162
+ } else if let rootVC = RCTKeyWindow()?.rootViewController,
163
+ let presentedVC = rootVC.presentedViewController,
164
+ FWNavigatorModule.isIOSSDKViewController(presentedVC) {
165
+ if let buttonInfo = FWNavigatorModule.getPlayerExitButtonInfo(view: presentedVC.view) {
166
+ if buttonInfo.type == .close {
167
+ buttonInfo.button.sendActions(for: .touchUpInside)
161
168
  resolver(true)
162
169
  } else {
163
- presentedVC.dismiss(animated: true) {
164
- resolver(true)
165
- }
170
+ resolver(false)
166
171
  }
167
172
  } else {
168
- resolver(false)
173
+ presentedVC.dismiss(animated: true) {
174
+ resolver(true)
175
+ }
169
176
  }
177
+ } else {
178
+ resolver(false)
170
179
  }
171
180
  }
172
181
 
@@ -174,15 +183,198 @@ class FWNavigatorModule: RCTEventEmitter, FWNavigator {
174
183
  func canPopNativeContainer(
175
184
  _ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
176
185
  ) {
177
- DispatchQueue.main.async {
178
- if let presentedVC = RCTPresentedViewController(),
179
- presentedVC.presentingViewController != nil {
180
- resolver(true)
181
- } else if gCartViewController != nil {
186
+ if let navigatorContainerVC = RCTPresentedViewController()
187
+ as? FWNavigatorContainerViewController,
188
+ navigatorContainerVC.presentingViewController != nil {
189
+ resolver(true)
190
+ } else if let _ = gCartViewController {
191
+ resolver(true)
192
+ } else if let presentedVC = RCTPresentedViewController(),
193
+ FWNavigatorModule.isIOSSDKViewController(presentedVC),
194
+ let presentingVC = presentedVC.presentingViewController,
195
+ presentingVC.presentingViewController == RCTKeyWindow()?.rootViewController,
196
+ FWNavigatorModule.isIOSSDKViewController(presentingVC) {
197
+ if let buttonInfo = FWNavigatorModule.getPlayerExitButtonInfo(view: presentingVC.view) {
198
+ if buttonInfo.type == .close {
199
+ resolver(true)
200
+ } else {
201
+ resolver(false)
202
+ }
203
+ } else {
182
204
  resolver(true)
205
+ }
206
+ } else if let rootVC = RCTKeyWindow()?.rootViewController,
207
+ let presentedVC = rootVC.presentedViewController,
208
+ FWNavigatorModule.isIOSSDKViewController(presentedVC) {
209
+ if let buttonInfo = FWNavigatorModule.getPlayerExitButtonInfo(view: presentedVC.view) {
210
+ if buttonInfo.type == .close {
211
+ resolver(true)
212
+ } else {
213
+ resolver(false)
214
+ }
183
215
  } else {
216
+ resolver(true)
217
+ }
218
+ } else {
219
+ resolver(false)
220
+ }
221
+ }
222
+
223
+ @objc(startFloatingPlayer:rejecter:)
224
+ func startFloatingPlayer(
225
+ _ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
226
+ ) {
227
+ guard let playerInfo = FWNavigatorModule.getPlayerInfo() else {
228
+ resolver(false)
229
+ return
230
+ }
231
+
232
+ if playerInfo.mode == .fullscreen {
233
+ do {
234
+ try playerInfo.playerVC.startPictureInPicture()
235
+ resolver(true)
236
+ } catch {
184
237
  resolver(false)
185
238
  }
239
+ } else {
240
+ // current player is already in floating mode.
241
+ resolver(false)
242
+ }
243
+ }
244
+
245
+ @objc(stopFloatingPlayer:rejecter:)
246
+ func stopFloatingPlayer(
247
+ _ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
248
+ ) {
249
+ let result = FWNavigatorModule.stopFloatingPlayer()
250
+ resolver(result)
251
+ }
252
+ }
253
+
254
+ extension FWNavigatorModule {
255
+ private static func getPlayerExitButtonInfo(view: UIView) -> PlayerExitButtonInfo? {
256
+ if let button = view as? UIButton, let targetImage = button.image(for: .normal) {
257
+ let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
258
+ if targetImage.isEqual(UIImage(named: "closeX", in: iOSSDKBundle, compatibleWith: nil)) {
259
+ return PlayerExitButtonInfo(button: button, type: .close)
260
+ }
261
+
262
+ if targetImage.isEqual(UIImage(named: "down-arrow-light", in: iOSSDKBundle, compatibleWith: nil)) {
263
+ return PlayerExitButtonInfo(button: button, type: .floating)
264
+ }
265
+ }
266
+
267
+ for subview in view.subviews {
268
+ if let result = getPlayerExitButtonInfo(view: subview) {
269
+ return result
270
+ }
271
+ }
272
+
273
+ return nil
274
+ }
275
+
276
+ private static func getWindowList() -> [UIWindow] {
277
+ var windowList: [UIWindow] = []
278
+ if #available(iOS 13.0, *) {
279
+ for scene in UIApplication.shared.connectedScenes {
280
+ if let currentSene = scene as? UIWindowScene {
281
+ for window in currentSene.windows {
282
+ windowList.append(window)
283
+ }
284
+ }
285
+ }
286
+ } else {
287
+ for window in UIApplication.shared.windows {
288
+ windowList.append(window)
289
+ }
290
+ }
291
+
292
+ return windowList
293
+ }
294
+
295
+ private static func getFurthestAncestorController(_ controller: UIViewController) -> UIViewController {
296
+ guard let parentVC = controller.parent else {
297
+ return controller
298
+ }
299
+
300
+ return getFurthestAncestorController(parentVC)
301
+ }
302
+
303
+ private static func getPlayerViewController(_ viewController: UIViewController) -> PlayerViewController? {
304
+ if let playerVC = viewController as? PlayerViewController {
305
+ return playerVC
306
+ }
307
+
308
+ for childVC in viewController.children {
309
+ if let playerVC = getPlayerViewController(childVC) {
310
+ return playerVC
311
+ }
312
+ }
313
+
314
+ return nil
315
+ }
316
+
317
+ private static func getPlayerInfo() -> PlayerInfo? {
318
+ let windowList: [UIWindow] = getWindowList()
319
+
320
+ if let floatingPlayerWindow = windowList.first(where: { window in
321
+ NSStringFromClass(type(of: window)) == "FireworkVideo.FloatingPlayerController"
322
+ }) {
323
+ if let rootVC = floatingPlayerWindow.rootViewController,
324
+ let playerVC = getPlayerViewController(rootVC) {
325
+ return PlayerInfo(playerVC: playerVC, mode: .floating)
326
+ }
327
+ return nil
328
+ }
329
+
330
+ if let keyWindow = windowList.first(where: { window in
331
+ return window.isKeyWindow
332
+ }) {
333
+ if let rootVC = keyWindow.rootViewController,
334
+ let presentedVC = rootVC.presentedViewController {
335
+ let furthestAncestorController = getFurthestAncestorController(presentedVC)
336
+
337
+ if let playerVC = getPlayerViewController(furthestAncestorController) {
338
+ return PlayerInfo(playerVC: playerVC, mode: .fullscreen)
339
+ }
340
+ }
341
+
342
+ return nil
343
+ }
344
+
345
+ return nil
346
+ }
347
+
348
+ private static func isIOSSDKViewController(_ controller: UIViewController?) -> Bool {
349
+ guard let controller = controller else {
350
+ return false
351
+ }
352
+
353
+ let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
354
+ if Bundle(for: type(of: controller)) == iOSSDKBundle {
355
+ return true
356
+ }
357
+
358
+ return isIOSSDKViewController(controller.parent)
359
+ }
360
+ }
361
+
362
+ extension FWNavigatorModule {
363
+ static func stopFloatingPlayer() -> Bool {
364
+ guard let playerInfo = self.getPlayerInfo() else {
365
+ return false
366
+ }
367
+
368
+ if playerInfo.mode == .floating {
369
+ do {
370
+ try playerInfo.playerVC.stopPictureInPicture()
371
+ return true
372
+ } catch {
373
+ return false
374
+ }
375
+ } else {
376
+ // current player is in fullscreen player
377
+ return false
186
378
  }
187
379
  }
188
380
  }
@@ -127,7 +127,5 @@ extension FireworkSDKModule: FireworkVideoFeedDelegate {
127
127
 
128
128
  sendEvent(
129
129
  withName: FWEventName.videoFeedClick.rawValue, body: ["info": eventDetails.jsObject])
130
-
131
- FWPiPManager.shared.removeAllPiPControllers()
132
130
  }
133
131
  }
@@ -30,6 +30,10 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
30
30
  return true
31
31
  }
32
32
 
33
+ override var methodQueue: DispatchQueue {
34
+ return DispatchQueue.main
35
+ }
36
+
33
37
  @objc(initializeSDK:)
34
38
  func initializeSDK(_ userId: String? = nil) {
35
39
  #if DEBUG
@@ -42,12 +46,10 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
42
46
  sendEvent(withName: FWEventName.logMessage.rawValue, body: ["message": message])
43
47
  #endif
44
48
 
45
- DispatchQueue.main.async {
46
- FireworkVideoSDK.initializeSDK(delegate: self, userID: userId)
47
- FireworkVideoSDK.ctaDelegate = self
48
- FireworkVideoSDK.eventTracking.videoPlaybackDelegate = self
49
- FireworkVideoSDK.eventTracking.feedDelegate = self
50
- }
49
+ FireworkVideoSDK.initializeSDK(delegate: self, userID: userId)
50
+ FireworkVideoSDK.ctaDelegate = self
51
+ FireworkVideoSDK.eventTracking.videoPlaybackDelegate = self
52
+ FireworkVideoSDK.eventTracking.feedDelegate = self
51
53
  }
52
54
 
53
55
  @objc(openVideoPlayer:config:)
@@ -67,14 +69,12 @@ class FireworkSDKModule: RCTEventEmitter, FireworkVideoSDKDelegate {
67
69
  feedContentConfig.adBadge = adBadge
68
70
  }
69
71
 
70
- DispatchQueue.main.async {
71
- guard let presentedVC = RCTPresentedViewController() else {
72
- return
73
- }
72
+ guard let presentedVC = RCTPresentedViewController() else {
73
+ return
74
+ }
74
75
 
75
- VideoFeedViewController.openVideoPlayer(with: urlString, feedContentConfig, presentedVC) { _ in
76
+ VideoFeedViewController.openVideoPlayer(with: urlString, feedContentConfig, presentedVC) { _ in
76
77
 
77
- }
78
78
  }
79
79
  }
80
80