react-native-firework-sdk 2.4.2 → 2.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.
- package/FireworkVideoUI.xcframework/Info.plist +5 -5
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +8 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +25 -5
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationSerializer.kt +17 -4
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +4 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelSerializer.kt +2 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWProductCardCtaButtonTextValue.kt +18 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWProductCardTheme.kt +18 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/enums/FWVideoFeedSource.kt +2 -1
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +7 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +7 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +2 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWColorUtil.kt +65 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +7 -8
- package/ios/Components/StoryBlock.swift +4 -1
- package/ios/Components/StoryBlockManager.m +1 -0
- package/ios/Components/VideoFeed.swift +39 -10
- package/ios/Components/VideoFeedManager.m +1 -0
- package/ios/Components/VideoPlayerConfiguration.swift +10 -0
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +4 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIView+AppLanguage.swift +6 -6
- package/ios/FireworkVideoUI/Podfile +1 -1
- package/ios/FireworkVideoUI/Podfile.lock +4 -4
- package/ios/Models/Common/ButtonInfo.swift +37 -0
- package/ios/Models/NativeToRN/FireworkEventName.swift +1 -0
- package/ios/Models/NativeToRN/FireworkSDK+Json.swift +11 -1
- package/ios/Models/RNToNative/RCTConvert+FireworkSDKModule.swift +18 -0
- package/ios/Models/RNToNative/RCTConvert+StoryBlock.swift +2 -1
- package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +2 -1
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +4 -4
- package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +16 -0
- package/ios/Modules/Shopping/ShoppingModule.m +1 -0
- package/ios/Modules/Shopping/ShoppingModule.swift +58 -17
- package/ios/Utils/Extensions/String+Color.swift +53 -27
- package/lib/commonjs/FWNavigator.js +0 -6
- package/lib/commonjs/FWNavigator.js.map +1 -1
- package/lib/commonjs/VideoShopping.js +32 -0
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +2 -0
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +2 -0
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/ButtonInfo.js +2 -0
- package/lib/commonjs/models/ButtonInfo.js.map +1 -0
- package/lib/commonjs/models/FWEventName.js +1 -0
- package/lib/commonjs/models/FWEventName.js.map +1 -1
- package/lib/commonjs/models/VideoPlayerButtonConfiguration.js +2 -0
- package/lib/commonjs/models/VideoPlayerButtonConfiguration.js.map +1 -0
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
- package/lib/module/FWNavigator.js +0 -2
- package/lib/module/FWNavigator.js.map +1 -1
- package/lib/module/VideoShopping.js +31 -0
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +2 -0
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +2 -0
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/ButtonInfo.js +2 -0
- package/lib/module/models/ButtonInfo.js.map +1 -0
- package/lib/module/models/FWEventName.js +1 -0
- package/lib/module/models/FWEventName.js.map +1 -1
- package/lib/module/models/VideoPlayerButtonConfiguration.js +2 -0
- package/lib/module/models/VideoPlayerButtonConfiguration.js.map +1 -0
- package/lib/module/modules/ShoppingModule.js.map +1 -1
- package/lib/typescript/VideoShopping.d.ts +13 -1
- package/lib/typescript/components/StoryBlock.d.ts +4 -0
- package/lib/typescript/components/VideoFeed.d.ts +4 -0
- package/lib/typescript/index.d.ts +3 -3
- package/lib/typescript/models/ButtonInfo.d.ts +18 -0
- package/lib/typescript/models/FWEventName.d.ts +2 -1
- package/lib/typescript/models/FWEvents.d.ts +18 -0
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +16 -0
- package/lib/typescript/models/StoryBlockSource.d.ts +1 -1
- package/lib/typescript/models/VideoFeedSource.d.ts +1 -1
- package/lib/typescript/models/VideoPlayerButtonConfiguration.d.ts +39 -0
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +6 -0
- package/lib/typescript/modules/ShoppingModule.d.ts +1 -0
- package/package.json +1 -1
- package/react-native-firework-sdk.podspec +1 -1
- package/src/FWNavigator.ts +0 -2
- package/src/VideoShopping.ts +40 -0
- package/src/components/StoryBlock.tsx +6 -0
- package/src/components/VideoFeed.tsx +6 -0
- package/src/index.ts +8 -0
- package/src/models/ButtonInfo.ts +18 -0
- package/src/models/FWEventName.ts +1 -0
- package/src/models/FWEvents.ts +19 -0
- package/src/models/ProductInfoViewConfiguration.ts +19 -0
- package/src/models/StoryBlockSource.ts +2 -1
- package/src/models/VideoFeedSource.ts +2 -1
- package/src/models/VideoPlayerButtonConfiguration.ts +40 -0
- package/src/models/VideoPlayerConfiguration.ts +6 -0
- package/src/modules/ShoppingModule.ts +1 -0
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
8988736C2A0A8E7E0089CD1C /* VideoPlayerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898873442A0A8E7E0089CD1C /* VideoPlayerConfiguration.swift */; };
|
|
72
72
|
8988736D2A0A8E7E0089CD1C /* VideoFeedManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 898873452A0A8E7E0089CD1C /* VideoFeedManager.m */; };
|
|
73
73
|
89C4D6A62A494EB800EFB74A /* StoryBlockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C4D6A52A494EB800EFB74A /* StoryBlockConfiguration.swift */; };
|
|
74
|
+
89C6791A2A736C80000C1A71 /* ButtonInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C679192A736C80000C1A71 /* ButtonInfo.swift */; };
|
|
74
75
|
89D6BBF929ACE2DC00C8AA2A /* (null) in Sources */ = {isa = PBXBuildFile; };
|
|
75
76
|
89DF27DD28A53A77003F3CCB /* (null) in Sources */ = {isa = PBXBuildFile; };
|
|
76
77
|
89DF27DE28A53A77003F3CCB /* (null) in Sources */ = {isa = PBXBuildFile; };
|
|
@@ -133,6 +134,7 @@
|
|
|
133
134
|
898873442A0A8E7E0089CD1C /* VideoPlayerConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerConfiguration.swift; sourceTree = "<group>"; };
|
|
134
135
|
898873452A0A8E7E0089CD1C /* VideoFeedManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoFeedManager.m; sourceTree = "<group>"; };
|
|
135
136
|
89C4D6A52A494EB800EFB74A /* StoryBlockConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryBlockConfiguration.swift; sourceTree = "<group>"; };
|
|
137
|
+
89C679192A736C80000C1A71 /* ButtonInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonInfo.swift; sourceTree = "<group>"; };
|
|
136
138
|
/* End PBXFileReference section */
|
|
137
139
|
|
|
138
140
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -248,6 +250,7 @@
|
|
|
248
250
|
isa = PBXGroup;
|
|
249
251
|
children = (
|
|
250
252
|
898873332A0A8E7E0089CD1C /* FontInfo.swift */,
|
|
253
|
+
89C679192A736C80000C1A71 /* ButtonInfo.swift */,
|
|
251
254
|
);
|
|
252
255
|
path = Common;
|
|
253
256
|
sourceTree = "<group>";
|
|
@@ -406,6 +409,7 @@
|
|
|
406
409
|
8988736B2A0A8E7E0089CD1C /* VideoFeed.swift in Sources */,
|
|
407
410
|
891F4AF62A67E12800A9E8DA /* FWRNContainerViewController.swift in Sources */,
|
|
408
411
|
898873522A0A8E7E0089CD1C /* ShoppingCTAResult.swift in Sources */,
|
|
412
|
+
89C6791A2A736C80000C1A71 /* ButtonInfo.swift in Sources */,
|
|
409
413
|
8975239D2817DEF80070EBB6 /* (null) in Sources */,
|
|
410
414
|
898873562A0A8E7E0089CD1C /* SDKInitOptions.swift in Sources */,
|
|
411
415
|
89DF27DE28A53A77003F3CCB /* (null) in Sources */,
|
|
@@ -30,7 +30,7 @@ extension UIView {
|
|
|
30
30
|
@objc func fw_init(frame: CGRect) -> UIView {
|
|
31
31
|
let view = self.fw_init(frame: frame)
|
|
32
32
|
updateViewTypeIfNeeded(view)
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
return view
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -38,21 +38,21 @@ extension UIView {
|
|
|
38
38
|
self.fw_viewAwakeFromNib()
|
|
39
39
|
updateViewTypeIfNeeded(self)
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
@objc func fw_semanticContentAttribute() -> UISemanticContentAttribute {
|
|
43
43
|
if self.isIOSSDKView, AppLanguageManager.shared.shouldHorizontalFlip {
|
|
44
44
|
return .forceLeftToRight
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
return fw_semanticContentAttribute()
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
private func updateViewTypeIfNeeded(_ view: UIView) {
|
|
51
51
|
if view is FireworkPlayerView, AppLanguageManager.shared.shouldHorizontalFlip {
|
|
52
52
|
view.viewType = .normal
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
DispatchQueue.main.async {
|
|
54
|
+
|
|
55
|
+
DispatchQueue.main.async {
|
|
56
56
|
if view.layer.sublayers?.first(where: { layer in
|
|
57
57
|
layer is AVPlayerLayer
|
|
58
58
|
}) != nil, AppLanguageManager.shared.shouldHorizontalFlip {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
PODS:
|
|
2
|
-
- FireworkVideo (1.
|
|
2
|
+
- FireworkVideo (1.12.0)
|
|
3
3
|
|
|
4
4
|
DEPENDENCIES:
|
|
5
|
-
- FireworkVideo (= 1.
|
|
5
|
+
- FireworkVideo (= 1.12.0)
|
|
6
6
|
|
|
7
7
|
SPEC REPOS:
|
|
8
8
|
trunk:
|
|
9
9
|
- FireworkVideo
|
|
10
10
|
|
|
11
11
|
SPEC CHECKSUMS:
|
|
12
|
-
FireworkVideo:
|
|
12
|
+
FireworkVideo: 8f7667ac08b5bb5a0bc09656f4cb6b782dcddccd
|
|
13
13
|
|
|
14
|
-
PODFILE CHECKSUM:
|
|
14
|
+
PODFILE CHECKSUM: 45fcc23fac9e8972f203deb221c0838163e06f6d
|
|
15
15
|
|
|
16
16
|
COCOAPODS: 1.12.1
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ButtonInfo.swift
|
|
3
|
+
// FireworkSdk
|
|
4
|
+
//
|
|
5
|
+
// Created by linjie jiang on 7/28/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import FireworkVideo
|
|
10
|
+
|
|
11
|
+
@objc
|
|
12
|
+
public class ButtonInfo: NSObject, Codable {
|
|
13
|
+
var imageName: String?
|
|
14
|
+
var systemImageName: String?
|
|
15
|
+
var tintColor: String?
|
|
16
|
+
|
|
17
|
+
public func getButtonDisplayConfiguration() -> ButtonDisplayConfiguration? {
|
|
18
|
+
if let imageName = imageName, let image = UIImage(named: imageName) {
|
|
19
|
+
var config = ButtonDisplayConfiguration()
|
|
20
|
+
config.displayMode = .image(image)
|
|
21
|
+
return config
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if #available(iOS 13.0, *) {
|
|
25
|
+
if let systemImageName = systemImageName, let image = UIImage(systemName: systemImageName) {
|
|
26
|
+
var config = ButtonDisplayConfiguration()
|
|
27
|
+
config.displayMode = .image(image)
|
|
28
|
+
if let tintColor = tintColor?.uicolor() {
|
|
29
|
+
config.tintColor = tintColor
|
|
30
|
+
}
|
|
31
|
+
return config
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return nil
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -43,6 +43,7 @@ enum ShoppingEventName: String, CaseIterable {
|
|
|
43
43
|
case clickCartIcon = "fw:shopping:click-cart-icon"
|
|
44
44
|
case logMessage = "fw:log-message"
|
|
45
45
|
case customLinkButtonClick = "fw:shopping:custom-link-button-click"
|
|
46
|
+
case customProductCardTap = "fw:shopping:custom-product-card-tap"
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
/// Live stream event
|
|
@@ -24,7 +24,7 @@ extension FireworkVideoSDKError {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
extension VideoPlaybackDetails {
|
|
27
|
-
var jsObject: [String: Any
|
|
27
|
+
var jsObject: [String: Any] {
|
|
28
28
|
[
|
|
29
29
|
"videoId": videoID,
|
|
30
30
|
"duration": duration,
|
|
@@ -149,3 +149,13 @@ extension StoryBlockError {
|
|
|
149
149
|
return error
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
extension SelectedProductVariant {
|
|
154
|
+
var jsObject: [String: Any] {
|
|
155
|
+
return [
|
|
156
|
+
"url": url?.absoluteString ?? "",
|
|
157
|
+
"productId": productID,
|
|
158
|
+
"unitId": unitID
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -34,6 +34,24 @@ extension RCTConvert {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
static func ctaButtonStyle(_ style: [String: AnyObject]?) -> ButtonContentConfiguration? {
|
|
38
|
+
guard let rStyle = style else {
|
|
39
|
+
return nil
|
|
40
|
+
}
|
|
41
|
+
var btnContentConfig = ButtonContentConfiguration()
|
|
42
|
+
if let backgroundColor = rStyle["backgroundColor"] as? String, let color = backgroundColor.uicolor() {
|
|
43
|
+
btnContentConfig.backgroundColor = color
|
|
44
|
+
}
|
|
45
|
+
if let textColor = rStyle["textColor"] as? String, let color = textColor.uicolor() {
|
|
46
|
+
btnContentConfig.textColor = color
|
|
47
|
+
}
|
|
48
|
+
if let fontSize = rStyle["fontSize"] as? Double {
|
|
49
|
+
btnContentConfig.font = UIFont.systemFont(ofSize: fontSize)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return btnContentConfig
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
static func adBadgeConfiguration(_ config: [String: Any]?) -> AdBadgeConfiguration? {
|
|
38
56
|
guard let rConfig = config else {
|
|
39
57
|
return nil
|
|
@@ -263,11 +263,11 @@ extension FireworkSDKModule {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
var fwAdBadgeConfiguration = FireworkVideo.AdBadgeConfiguration()
|
|
266
|
-
if let textColor = adBadgeConfiguration.textColor {
|
|
267
|
-
fwAdBadgeConfiguration.textColor =
|
|
266
|
+
if let textColor = adBadgeConfiguration.textColor, let color = textColor.uicolor() {
|
|
267
|
+
fwAdBadgeConfiguration.textColor = color
|
|
268
268
|
}
|
|
269
|
-
if let backgroundColor = adBadgeConfiguration.backgroundColor {
|
|
270
|
-
fwAdBadgeConfiguration.backgroundColor =
|
|
269
|
+
if let backgroundColor = adBadgeConfiguration.backgroundColor, let color = backgroundColor.uicolor() {
|
|
270
|
+
fwAdBadgeConfiguration.backgroundColor = color
|
|
271
271
|
}
|
|
272
272
|
switch adBadgeConfiguration.badgeTextType {
|
|
273
273
|
case .sponsored:
|
|
@@ -10,6 +10,7 @@ import Foundation
|
|
|
10
10
|
struct ProductInfoViewConfiguration: Codable {
|
|
11
11
|
var ctaButton: CTAButtonConfiguration?
|
|
12
12
|
var linkButton: LinkButtonConfiguration?
|
|
13
|
+
var productCard: ProductCardConfiguration?
|
|
13
14
|
|
|
14
15
|
struct CTAButtonConfiguration: Codable {
|
|
15
16
|
var text: CTAButtonText?
|
|
@@ -26,4 +27,19 @@ struct ProductInfoViewConfiguration: Codable {
|
|
|
26
27
|
struct LinkButtonConfiguration: Codable {
|
|
27
28
|
var isHidden: Bool?
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
struct ProductCardConfiguration: Codable {
|
|
32
|
+
var theme: ProductCardTheme?
|
|
33
|
+
var ctaButtonText: ProductCardCTAButtonText?
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
enum ProductCardTheme: String, Codable {
|
|
37
|
+
case light
|
|
38
|
+
case dark
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
enum ProductCardCTAButtonText: String, Codable {
|
|
42
|
+
case shopNow
|
|
43
|
+
case buyNow
|
|
44
|
+
}
|
|
29
45
|
}
|
|
@@ -17,5 +17,6 @@ RCT_EXTERN_METHOD(setProductInfoViewConfiguration:(NSDictionary *)config)
|
|
|
17
17
|
RCT_EXTERN_METHOD(clearCallbackId:(nonnull NSNumber *)cbId eventName:(nonnull NSString *)name)
|
|
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
|
+
RCT_EXTERN_METHOD(setCustomTapProductCardEnabled:(BOOL)enabled resolver: (RCTPromiseResolveBlock)resolver rejecter:(RCTPromiseRejectBlock)rejecter)
|
|
20
21
|
|
|
21
22
|
@end
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
// Created by Jeff Zheng on 2021/12/30.
|
|
6
6
|
//
|
|
7
7
|
|
|
8
|
-
// swiftlint:disable file_length
|
|
9
|
-
|
|
8
|
+
// swiftlint:disable file_length type_body_length
|
|
10
9
|
import FireworkVideo
|
|
11
10
|
import Foundation
|
|
12
11
|
|
|
@@ -21,6 +20,7 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate {
|
|
|
21
20
|
private var itemCounts = 0
|
|
22
21
|
private var productInfoViewConfiguration: ProductInfoViewConfiguration?
|
|
23
22
|
private var customClickLinkButtonEnabled = false
|
|
23
|
+
private var customTapProductCardEnabled = false
|
|
24
24
|
|
|
25
25
|
override func supportedEvents() -> [String]! {
|
|
26
26
|
ShoppingEventName.allCases.map { $0.rawValue }
|
|
@@ -168,6 +168,15 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate {
|
|
|
168
168
|
resolver([:])
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
@objc
|
|
172
|
+
func setCustomTapProductCardEnabled(
|
|
173
|
+
_ enabled: Bool, resolver: @escaping RCTPromiseResolveBlock,
|
|
174
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
175
|
+
) {
|
|
176
|
+
customTapProductCardEnabled = enabled
|
|
177
|
+
resolver([:])
|
|
178
|
+
}
|
|
179
|
+
|
|
171
180
|
@objc
|
|
172
181
|
func updateShoppingCTAResult(_ result: [String: Any]?, cbId: NSNumber) {
|
|
173
182
|
guard let ctaResult = RCTConvert.buildShoppingCTAResult(result) else {
|
|
@@ -264,14 +273,11 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate {
|
|
|
264
273
|
) {
|
|
265
274
|
let callbackId = ShoppingModule.generateCallbackId()
|
|
266
275
|
self.shoppingCTAHandlerMap[callbackId] = ctaCompletionHandler
|
|
276
|
+
var body = item.jsObject
|
|
277
|
+
body["callbackId"] = callbackId
|
|
267
278
|
sendEvent(
|
|
268
279
|
withName: ShoppingEventName.ctaButtonClick.rawValue,
|
|
269
|
-
body:
|
|
270
|
-
"url": item.url?.absoluteString ?? "",
|
|
271
|
-
"productId": item.productID,
|
|
272
|
-
"unitId": item.unitID,
|
|
273
|
-
"callbackId": callbackId
|
|
274
|
-
])
|
|
280
|
+
body: body)
|
|
275
281
|
}
|
|
276
282
|
|
|
277
283
|
func fireworkShopping(
|
|
@@ -282,11 +288,7 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate {
|
|
|
282
288
|
if customClickLinkButtonEnabled {
|
|
283
289
|
sendEvent(
|
|
284
290
|
withName: ShoppingEventName.customLinkButtonClick.rawValue,
|
|
285
|
-
body:
|
|
286
|
-
"url": itemURL,
|
|
287
|
-
"productId": item.productID,
|
|
288
|
-
"unitId": item.unitID
|
|
289
|
-
])
|
|
291
|
+
body: item.jsObject)
|
|
290
292
|
}
|
|
291
293
|
return customClickLinkButtonEnabled
|
|
292
294
|
}
|
|
@@ -298,9 +300,26 @@ class ShoppingModule: RCTEventEmitter, FireworkVideoShoppingDelegate {
|
|
|
298
300
|
sendEvent(
|
|
299
301
|
withName: ShoppingEventName.clickCartIcon.rawValue, body: [:])
|
|
300
302
|
}
|
|
303
|
+
|
|
304
|
+
func fireworkShopping(
|
|
305
|
+
_ fireworkShopping: FireworkVideoShopping,
|
|
306
|
+
didTapProductVariant item: SelectedProductVariant,
|
|
307
|
+
forVideo video: VideoDetails
|
|
308
|
+
) -> Bool {
|
|
309
|
+
if customTapProductCardEnabled {
|
|
310
|
+
var body = item.jsObject
|
|
311
|
+
body["video"] = video.jsObject
|
|
312
|
+
sendEvent(
|
|
313
|
+
withName: ShoppingEventName.customProductCardTap.rawValue,
|
|
314
|
+
body: body)
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
return customTapProductCardEnabled
|
|
318
|
+
}
|
|
301
319
|
}
|
|
302
320
|
|
|
303
321
|
extension ShoppingModule {
|
|
322
|
+
// swiftlint:disable:next cyclomatic_complexity
|
|
304
323
|
fileprivate static func hydrateProductViewConfig(
|
|
305
324
|
_ config: ProductInfoViewConfiguration,
|
|
306
325
|
_ productInfoViewConfigurator: ProductInfoViewConfigurable
|
|
@@ -317,13 +336,15 @@ extension ShoppingModule {
|
|
|
317
336
|
}
|
|
318
337
|
}
|
|
319
338
|
if let backgroundColor = ctaButtonConfiguration.backgroundColor,
|
|
320
|
-
backgroundColor.count > 0
|
|
321
|
-
|
|
339
|
+
backgroundColor.count > 0,
|
|
340
|
+
let color = backgroundColor.uicolor() {
|
|
341
|
+
productDetailsConfiguration.ctaButton.buttonConfiguration.backgroundColor = color
|
|
322
342
|
}
|
|
323
343
|
|
|
324
344
|
if let textColor = ctaButtonConfiguration.textColor,
|
|
325
|
-
textColor.count > 0
|
|
326
|
-
|
|
345
|
+
textColor.count > 0,
|
|
346
|
+
let color = textColor.uicolor() {
|
|
347
|
+
productDetailsConfiguration.ctaButton.buttonConfiguration.textColor = color
|
|
327
348
|
}
|
|
328
349
|
|
|
329
350
|
if let fontSize = ctaButtonConfiguration.fontSize {
|
|
@@ -338,6 +359,26 @@ extension ShoppingModule {
|
|
|
338
359
|
}
|
|
339
360
|
}
|
|
340
361
|
|
|
362
|
+
if let productCardConfiguration = config.productCard {
|
|
363
|
+
if let theme = productCardConfiguration.theme {
|
|
364
|
+
switch theme {
|
|
365
|
+
case .light:
|
|
366
|
+
productInfoViewConfigurator.productCardConfiguration.appearance = .light
|
|
367
|
+
case .dark:
|
|
368
|
+
productInfoViewConfigurator.productCardConfiguration.appearance = .dark
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if let text = productCardConfiguration.ctaButtonText {
|
|
373
|
+
switch text {
|
|
374
|
+
case .shopNow:
|
|
375
|
+
productInfoViewConfigurator.productCardConfiguration.ctaConfig.text = .shopNow
|
|
376
|
+
case .buyNow:
|
|
377
|
+
productInfoViewConfigurator.productCardConfiguration.ctaConfig.text = .buyNow
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
341
382
|
productInfoViewConfigurator.productDetailsConfiguration = productDetailsConfiguration
|
|
342
383
|
}
|
|
343
384
|
|
|
@@ -8,39 +8,65 @@
|
|
|
8
8
|
import UIKit
|
|
9
9
|
|
|
10
10
|
extension String {
|
|
11
|
+
func uicolor() -> UIColor? {
|
|
12
|
+
var hex = self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
if hex.hasPrefix("0x") || hex.hasPrefix("0X") {
|
|
14
|
+
guard matchHexColorWithLength(hex) else {
|
|
15
|
+
return nil
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if hex.hasPrefix("0X") {
|
|
19
19
|
hex = String(hex[hex.index(hex.startIndex, offsetBy: 2)...])
|
|
20
20
|
} else if hex.hasPrefix("#") {
|
|
21
21
|
hex = String(hex[hex.index(hex.startIndex, offsetBy: 1)...])
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
if hex.count
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
|
|
24
|
+
if hex.count == 3 {
|
|
25
|
+
hex = convertToDoubleChar(from: hex)
|
|
26
|
+
hex += "FF"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if hex.count == 4 {
|
|
30
|
+
hex = convertToDoubleChar(from: hex)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if hex.count == 6 {
|
|
34
|
+
hex += "FF"
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
var rgbaValue: UInt64 = 0
|
|
38
|
+
Scanner(string: hex).scanHexInt64(&rgbaValue)
|
|
39
|
+
|
|
40
|
+
let red = CGFloat((rgbaValue & 0xFF000000) >> 24) / 255.0
|
|
41
|
+
let green = CGFloat((rgbaValue & 0x00FF0000) >> 16) / 255.0
|
|
42
|
+
let blue = CGFloat((rgbaValue & 0x0000FF00) >> 8) / 255.0
|
|
43
|
+
let alpha = CGFloat(rgbaValue & 0x000000FF) / 255.0
|
|
44
|
+
|
|
45
|
+
return UIColor(red: red, green: green, blue: blue, alpha: alpha)
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private func convertToDoubleChar(from input: String) -> String {
|
|
50
|
+
var result = ""
|
|
51
|
+
|
|
52
|
+
for char in input {
|
|
53
|
+
let repeatedChar = String(repeating: char, count: 2)
|
|
54
|
+
result += repeatedChar
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return result
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private func matchHexColorWithLength(_ input: String) -> Bool {
|
|
61
|
+
do {
|
|
62
|
+
let pattern = "^(0X|#)?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$"
|
|
63
|
+
let regex = try NSRegularExpression(pattern: pattern)
|
|
64
|
+
let range = NSRange(location: 0, length: input.utf16.count)
|
|
65
|
+
let matches = regex.matches(in: input, range: range)
|
|
66
|
+
|
|
67
|
+
return matches.count > 0
|
|
68
|
+
} catch {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
45
71
|
}
|
|
46
72
|
}
|
|
@@ -9,10 +9,6 @@ var _FWEventName = require("./models/FWEventName");
|
|
|
9
9
|
|
|
10
10
|
var _FWNavigatorModule = _interopRequireWildcard(require("./modules/FWNavigatorModule"));
|
|
11
11
|
|
|
12
|
-
var _FWLoggerUtil = _interopRequireDefault(require("./utils/FWLoggerUtil"));
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
12
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
13
|
|
|
18
14
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -32,8 +28,6 @@ class FWNavigator {
|
|
|
32
28
|
}
|
|
33
29
|
|
|
34
30
|
constructor() {
|
|
35
|
-
_FWLoggerUtil.default.log('FWNavigator constructor');
|
|
36
|
-
|
|
37
31
|
_FWNavigatorModule.FWNavigatorModuleEventEmitter.addListener(_FWEventName.FWEventName.LogMessage, () => {});
|
|
38
32
|
}
|
|
39
33
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["FWNavigator.ts"],"names":["FWNavigator","getInstance","_instance","constructor","
|
|
1
|
+
{"version":3,"sources":["FWNavigator.ts"],"names":["FWNavigator","getInstance","_instance","constructor","FWNavigatorModuleEventEmitter","addListener","FWEventName","LogMessage","pushRNContainer","params","FWNavigatorModule","popRNContainer","popNativeContainer","startFloatingPlayer","stopFloatingPlayer"],"mappings":";;;;;;;AAAA;;AAEA;;;;;;;;AAIA;AACA;AACA;AACA,MAAMA,WAAN,CAAkB;AAGS,SAAXC,WAAW,GAAgB;AACvC,QAAI,CAACD,WAAW,CAACE,SAAjB,EAA4B;AAC1BF,MAAAA,WAAW,CAACE,SAAZ,GAAwB,IAAIF,WAAJ,EAAxB;AACD;;AACD,WAAOA,WAAW,CAACE,SAAnB;AACD;;AAEOC,EAAAA,WAAW,GAAG;AACpBC,qDAA8BC,WAA9B,CAA0CC,yBAAYC,UAAtD,EAAkE,MAAM,CAAE,CAA1E;AACD;AAED;AACF;AACA;AACA;AACA;AACA;AACA;;;AACSC,EAAAA,eAAe,CAACC,MAAD,EAAkD;AACtE,WAAOC,2BAAkBF,eAAlB,CAAkCC,MAAlC,CAAP;AACD;AAED;AACF;AACA;AACA;;;AACSE,EAAAA,cAAc,GAAqB;AACxC,WAAOD,2BAAkBC,cAAlB,EAAP;AACD;AAED;AACF;AACA;AACA;AACA;AACA;;;AACSC,EAAAA,kBAAkB,GAAqB;AAC5C,WAAOF,2BAAkBE,kBAAlB,EAAP;AACD;AAED;AACF;AACA;AACA;AACA;;;AACkC,QAAnBC,mBAAmB,GAAqB;AACnD,WAAOH,2BAAkBG,mBAAlB,EAAP;AACD;AAED;AACF;AACA;;;AACiC,QAAlBC,kBAAkB,GAAkB;AAC/C,UAAMJ,2BAAkBI,kBAAlB,EAAN;AACD;;AAzDe;;gBAAZd,W;;eA4DSA,W","sourcesContent":["import { FWEventName } from './models/FWEventName';\nimport type PushRNContainerParams from './models/PushRNContainerParams';\nimport FWNavigatorModule, {\n FWNavigatorModuleEventEmitter,\n} from './modules/FWNavigatorModule';\n\n/**\n * You can use this class for pushing RN page from the native page.\n */\nclass FWNavigator {\n private static _instance?: FWNavigator;\n\n public static getInstance(): FWNavigator {\n if (!FWNavigator._instance) {\n FWNavigator._instance = new FWNavigator();\n }\n return FWNavigator._instance!;\n }\n\n private constructor() {\n FWNavigatorModuleEventEmitter.addListener(FWEventName.LogMessage, () => {});\n }\n\n /**\n * Push a new RN container.\n * You could use this method to make a RN page on top of\n * SDK full-screen player.\n * @param params {PushRNContainerParams}\n * @returns {Promise<boolean>} The result of pushing a new Container.\n */\n public pushRNContainer(params: PushRNContainerParams): Promise<boolean> {\n return FWNavigatorModule.pushRNContainer(params);\n }\n\n /**\n * Pop the RN container you pushed before.\n * @returns {Promise<boolean>} The result of popping a new Container.\n */\n public popRNContainer(): Promise<boolean> {\n return FWNavigatorModule.popRNContainer();\n }\n\n /**\n * Pop the native container. You could use the method to close the fullscreen player.\n * But if the enablePictureInPicture of the associated video feed is true,\n * we can't close the fullscreen player.\n * @returns {Promise<boolean>} The result of popping the native container.\n */\n public popNativeContainer(): Promise<boolean> {\n return FWNavigatorModule.popNativeContainer();\n }\n\n /**\n * Change current fullscreen player to floating player.\n * @returns {Promise<boolean>} If the result is true, it means that the fullscreen\n * player is changed to floating player.\n */\n public async startFloatingPlayer(): Promise<boolean> {\n return FWNavigatorModule.startFloatingPlayer();\n }\n\n /**\n * Stop current floating player.\n */\n public async stopFloatingPlayer(): Promise<void> {\n await FWNavigatorModule.stopFloatingPlayer();\n }\n}\n\nexport default FWNavigator;\n"]}
|
|
@@ -62,6 +62,25 @@ class VideoShopping {
|
|
|
62
62
|
_ShoppingModule.default.setCustomClickLinkButtonEnabled(!!value);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* This callback is triggered when the user clicks product card.
|
|
67
|
+
* Only supported on iOS.
|
|
68
|
+
*
|
|
69
|
+
* The host app can customize the tap event processing logic of
|
|
70
|
+
* the product card by setting the callback.
|
|
71
|
+
*/
|
|
72
|
+
get onCustomTapProductCard() {
|
|
73
|
+
return this._onCustomTapProductCard;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
set onCustomTapProductCard(value) {
|
|
77
|
+
this._onCustomTapProductCard = value;
|
|
78
|
+
|
|
79
|
+
if (_reactNative.Platform.OS === 'ios') {
|
|
80
|
+
_ShoppingModule.default.setCustomTapProductCardEnabled(!!value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
65
84
|
/**
|
|
66
85
|
* Defaults to true.
|
|
67
86
|
* You can hide the cart icon by setting this property to false.
|
|
@@ -125,6 +144,8 @@ class VideoShopping {
|
|
|
125
144
|
|
|
126
145
|
_defineProperty(this, "_onCustomClickLinkButton", void 0);
|
|
127
146
|
|
|
147
|
+
_defineProperty(this, "_onCustomTapProductCard", void 0);
|
|
148
|
+
|
|
128
149
|
_defineProperty(this, "_cartIconVisible", true);
|
|
129
150
|
|
|
130
151
|
_defineProperty(this, "_productInfoViewConfiguration", void 0);
|
|
@@ -150,6 +171,11 @@ class VideoShopping {
|
|
|
150
171
|
|
|
151
172
|
this.handleCustomLinkButtonClickEvent(event);
|
|
152
173
|
});
|
|
174
|
+
this.eventEmitter.addListener(_FWEventName.FWEventName.CustomProductCardTap, event => {
|
|
175
|
+
_FWLoggerUtil.default.log(`Receive CustomProductCardTap event url: ${event === null || event === void 0 ? void 0 : event.url}`);
|
|
176
|
+
|
|
177
|
+
this.handleCustomProductCardTapEvent(event);
|
|
178
|
+
});
|
|
153
179
|
}
|
|
154
180
|
/**
|
|
155
181
|
*
|
|
@@ -238,6 +264,12 @@ class VideoShopping {
|
|
|
238
264
|
}
|
|
239
265
|
}
|
|
240
266
|
|
|
267
|
+
async handleCustomProductCardTapEvent(event) {
|
|
268
|
+
if (this.onCustomTapProductCard) {
|
|
269
|
+
this.onCustomTapProductCard(event);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
241
273
|
}
|
|
242
274
|
|
|
243
275
|
_defineProperty(VideoShopping, "_instance", void 0);
|