react-native-firework-sdk 2.0.0 → 2.1.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/android/build.gradle +5 -3
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFragment.kt +129 -0
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFrameLayout.kt +84 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +2 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +18 -5
- package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +33 -9
- package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResult.kt +17 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResultDeserializer.kt +33 -0
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +126 -45
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +6 -3
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +2 -2
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +9 -1
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +81 -50
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +9 -2
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +1 -1
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +4 -0
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +48 -16
- package/android/src/main/res/layout/fw_bridge_story_block.xml +24 -0
- package/ios/Components/StoryBlock.swift +33 -2
- package/ios/Components/StoryBlockManager.m +32 -0
- package/ios/Components/VideoFeed.swift +9 -29
- package/ios/Components/VideoFeedManager.m +11 -6
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +378 -104
- package/ios/Models/NativeToRN/FireworkEventName.swift +3 -1
- package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
- package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +27 -0
- package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +5 -1
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +30 -0
- package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +13 -0
- package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
- package/ios/Modules/Shopping/ShoppingModule.m +2 -1
- package/ios/Modules/Shopping/ShoppingModule.swift +106 -30
- package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
- package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
- package/ios/Utils/AppLanguage/Bundle+FWSwizzle.swift +58 -0
- package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +139 -0
- package/ios/Utils/AppLanguage/FWLanguageUtil.swift +43 -0
- package/ios/Utils/AppLanguage/NumberFormatter+FWSwizzle.swift +25 -0
- package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +91 -0
- package/ios/Utils/AppLanguage/UILabel+FWSwizzle.swift +98 -0
- package/ios/Utils/AppLanguage/UITextField+FWSwizzle.swift +97 -0
- package/ios/Utils/AppLanguage/UITextView+FWSwizzle.swift +97 -0
- package/ios/Utils/AppLanguage/UIView+FWSwizzle.swift +38 -0
- package/ios/Utils/AppLanguage/UIViewController+FWSwizzle.swift +32 -0
- package/ios/Utils/AppLanguage/UIWindow+FWSwizzle.swift +26 -0
- package/ios/Utils/AppLanguage/URLSession+FWSwizzle.swift +69 -0
- package/ios/Utils/{DispatchQueue+FWOnce.swift → Extensions/DispatchQueue+FWOnce.swift} +3 -3
- package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +6 -8
- package/ios/Utils/Extensions/UIView+FWUIHierarchy.swift +47 -0
- package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.h +25 -0
- package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.m +75 -0
- package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.h +21 -0
- package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.m +124 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.h +11 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.m +86 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.h +16 -0
- package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.m +55 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.h +18 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.m +39 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.h +54 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.m +141 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.h +16 -0
- package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.m +20 -0
- package/ios/Utils/FWRTL/Classes/Utils/FWRTLDefinitions.h +52 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.h +19 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.m +49 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.h +21 -0
- package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.m +38 -0
- package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.h +18 -0
- package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.m +43 -0
- package/ios/Utils/FWSwizzleLoader.m +6 -1
- package/ios/Utils/FWSwizzleLoader.swift +13 -0
- package/ios/Utils/FWSwizzleUtil.swift +17 -9
- package/ios/react_native_firework_sdk.h +1 -0
- package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
- package/lib/commonjs/FireworkSDK.js +21 -4
- package/lib/commonjs/FireworkSDK.js.map +1 -1
- package/lib/commonjs/VideoShopping.js +20 -37
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +190 -125
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +11 -1
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/FWEventName.js +2 -0
- package/lib/commonjs/models/FWEventName.js.map +1 -1
- package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
- package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
- package/lib/module/FireworkSDK.js +21 -4
- package/lib/module/FireworkSDK.js.map +1 -1
- package/lib/module/VideoShopping.js +20 -39
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +179 -131
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +10 -1
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/FWEventName.js +2 -0
- package/lib/module/models/FWEventName.js.map +1 -1
- package/lib/module/models/ShoppingCTAResult.js +2 -0
- package/lib/module/modules/FireworkSDKModule.js.map +1 -1
- package/lib/module/modules/ShoppingModule.js.map +1 -1
- package/lib/typescript/FireworkSDK.d.ts +7 -4
- package/lib/typescript/VideoShopping.d.ts +9 -11
- package/lib/typescript/components/StoryBlock.d.ts +19 -25
- package/lib/typescript/index.d.ts +6 -6
- package/lib/typescript/models/FWEventName.d.ts +2 -0
- package/lib/typescript/models/FWEvents.d.ts +14 -1
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +36 -1
- package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
- package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
- package/lib/typescript/modules/ShoppingModule.d.ts +2 -1
- package/package.json +2 -2
- package/react-native-firework-sdk.podspec +26 -24
- package/src/FireworkSDK.ts +18 -5
- package/src/VideoShopping.ts +40 -53
- package/src/components/StoryBlock.tsx +199 -96
- package/src/components/VideoFeed.tsx +11 -0
- package/src/index.ts +15 -7
- package/src/models/FWEventName.ts +2 -0
- package/src/models/FWEvents.ts +14 -1
- package/src/models/ProductInfoViewConfiguration.ts +38 -1
- package/src/models/ShoppingCTAResult.ts +11 -0
- package/src/modules/FireworkSDKModule.ts +1 -2
- package/src/modules/ShoppingModule.ts +5 -5
- package/android/src/main/java/com/fireworksdk/bridge/constants/FWCommandConstant.kt +0 -6
- package/ios/Utils/UIView+ParentViewController.swift +0 -21
- package/lib/commonjs/models/AddToCartResult.js +0 -2
- package/lib/module/models/AddToCartResult.js +0 -2
- package/lib/typescript/models/AddToCartResult.d.ts +0 -10
- package/src/models/AddToCartResult.ts +0 -10
- /package/ios/Utils/{String+Color.swift → Extensions/String+Color.swift} +0 -0
- /package/ios/Utils/{UIView+Constraints.swift → Extensions/UIView+Constraints.swift} +0 -0
- /package/ios/Utils/{UIViewController+AttachChild.swift → Extensions/UIViewController+AttachChild.swift} +0 -0
- /package/lib/commonjs/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
- /package/lib/module/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//
|
|
2
|
+
// FWLanguageUtil.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/9.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
public class FWLanguageUtil {
|
|
10
|
+
public static func getLanguageCode(_ language: String) -> String? {
|
|
11
|
+
guard language.count > 0 else {
|
|
12
|
+
return nil
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var languageCode = ""
|
|
16
|
+
#if compiler(>=5.7)
|
|
17
|
+
if #available(iOS 16, *) {
|
|
18
|
+
languageCode = Locale(identifier: language).language.languageCode?.identifier ?? ""
|
|
19
|
+
} else {
|
|
20
|
+
languageCode = Locale(identifier: language).languageCode ?? ""
|
|
21
|
+
}
|
|
22
|
+
#else
|
|
23
|
+
languageCode = Locale(identifier: language).languageCode ?? ""
|
|
24
|
+
#endif
|
|
25
|
+
return languageCode.lowercased()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public static func isValidLanguage(_ language: String?) -> Bool {
|
|
29
|
+
guard let language = language else {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
guard language.count > 0 else {
|
|
34
|
+
return false
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let languageWithUnderline = language.replacingOccurrences(of: "-", with: "_")
|
|
38
|
+
|
|
39
|
+
let availableIdentifiers = Locale.availableIdentifiers
|
|
40
|
+
|
|
41
|
+
return availableIdentifiers.contains(language) || availableIdentifiers.contains(languageWithUnderline)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
// NumberFormatter+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/20.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
public extension NumberFormatter {
|
|
10
|
+
static func swizzleMethodsForNumberFormatter() {
|
|
11
|
+
FWSwizzleUtil.swizzleSelector(
|
|
12
|
+
cls: self,
|
|
13
|
+
originalSelector: #selector(NumberFormatter.string(from:)),
|
|
14
|
+
customSelector: #selector(NumberFormatter.fw_string(from:)))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@objc func fw_string(from number: NSNumber) -> String? {
|
|
18
|
+
if let language = FWAppLanguageManager.shared.appLanguage,
|
|
19
|
+
self.numberStyle == .currency {
|
|
20
|
+
self.locale = Locale(identifier: language)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return fw_string(from: number)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIImageView+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/22.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
import FireworkVideo
|
|
9
|
+
|
|
10
|
+
private let FWImageNamesWithDirections: [String] = [
|
|
11
|
+
"shopping-cart",
|
|
12
|
+
"left-arrow",
|
|
13
|
+
"right-arrow",
|
|
14
|
+
"speaker-unmute",
|
|
15
|
+
"speaker-mute"
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
extension UIImageView {
|
|
19
|
+
static func swizzleMethodsForImageView() {
|
|
20
|
+
FWSwizzleUtil.swizzleSelector(
|
|
21
|
+
cls: self,
|
|
22
|
+
originalSelector: #selector(UIImageView.didMoveToWindow),
|
|
23
|
+
customSelector: #selector(UIImageView.fw_imageViewDidMoveToWindow))
|
|
24
|
+
FWSwizzleUtil.swizzleSelector(
|
|
25
|
+
cls: self,
|
|
26
|
+
originalSelector: #selector(setter: UIImageView.image),
|
|
27
|
+
customSelector: #selector(UIImageView.fw_setImage(_:))
|
|
28
|
+
)
|
|
29
|
+
FWSwizzleUtil.swizzleSelector(
|
|
30
|
+
cls: self,
|
|
31
|
+
originalSelector: #selector(UIImageView.awakeFromNib),
|
|
32
|
+
customSelector: #selector(UIImageView.fw_imageViewAwakeFromNib)
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@objc func fw_imageViewDidMoveToWindow() {
|
|
37
|
+
fw_imageViewDidMoveToWindow()
|
|
38
|
+
updateViewType(self.image)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@objc func fw_setImage(_ image: UIImage?) {
|
|
42
|
+
fw_setImage(image)
|
|
43
|
+
updateViewType(image)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@objc func fw_imageViewAwakeFromNib() {
|
|
47
|
+
self.fw_imageViewAwakeFromNib()
|
|
48
|
+
updateViewType(self.image)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private func updateViewType(_ image: UIImage?) {
|
|
52
|
+
self.fwrtl_viewType = shouldFlipImage(image) ? FWRTLViewTypeFlip : FWRTLViewTypeAuto
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private func shouldFlipImage(_ image: UIImage?) -> Bool {
|
|
56
|
+
guard let image = image else {
|
|
57
|
+
return false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip, self.isIOSSDKView {
|
|
61
|
+
let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
|
|
62
|
+
|
|
63
|
+
for imageName in FWImageNamesWithDirections {
|
|
64
|
+
let targetImage = UIImage(named: imageName, in: iOSSDKBundle, compatibleWith: nil)
|
|
65
|
+
if image.isEqual(targetImage) {
|
|
66
|
+
return true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if let cgImage = image.cgImage,
|
|
70
|
+
let targetCgImage = targetImage?.cgImage,
|
|
71
|
+
cgImage == targetCgImage {
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if let ciImage = image.ciImage,
|
|
76
|
+
let targetCiImage = targetImage?.ciImage,
|
|
77
|
+
ciImage == targetCiImage {
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
84
|
+
image.flipsForRightToLeftLayoutDirection == true,
|
|
85
|
+
self.isIOSSDKView {
|
|
86
|
+
return true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UILabel+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/22.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
|
|
9
|
+
extension UILabel {
|
|
10
|
+
private struct AssociatedKeys {
|
|
11
|
+
static var fwHasCalculatedTextAlignment = "fwHasCalculatedTextAlignmentKey"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private var fwHasCalculatedTextAlignment: Bool {
|
|
15
|
+
get {
|
|
16
|
+
let result = objc_getAssociatedObject(self, &AssociatedKeys.fwHasCalculatedTextAlignment) as? Bool
|
|
17
|
+
return result ?? false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set {
|
|
21
|
+
objc_setAssociatedObject(
|
|
22
|
+
self,
|
|
23
|
+
&AssociatedKeys.fwHasCalculatedTextAlignment,
|
|
24
|
+
newValue,
|
|
25
|
+
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func swizzleMethodsForLabel() {
|
|
31
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
32
|
+
originalSelector: #selector(setter: UILabel.textAlignment),
|
|
33
|
+
customSelector: #selector(UILabel.fw_setLabelTextAlignment(_:)))
|
|
34
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
35
|
+
originalSelector: #selector(UILabel.didMoveToWindow),
|
|
36
|
+
customSelector: #selector(UILabel.fw_labelDidMoveToWindow))
|
|
37
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
38
|
+
originalSelector: #selector(UILabel.removeFromSuperview),
|
|
39
|
+
customSelector: #selector(UILabel.fw_labelRemoveFromSuperview))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc func fw_setLabelTextAlignment(_ textAlignment: NSTextAlignment) {
|
|
43
|
+
self.fwrtl_addReloadBlock(forKey: "alignment") { [weak self] in
|
|
44
|
+
guard let self = self else {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.fw_setLabelTextAlignment(self.calculatedTextAlignment(textAlignment))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@objc func fw_labelDidMoveToWindow() {
|
|
53
|
+
fw_labelDidMoveToWindow()
|
|
54
|
+
if shouldCalculateTextAlignment(),
|
|
55
|
+
!self.fwHasCalculatedTextAlignment,
|
|
56
|
+
self.isIOSSDKView {
|
|
57
|
+
self.textAlignment = self.textAlignment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func fw_labelRemoveFromSuperview() {
|
|
62
|
+
fw_labelRemoveFromSuperview()
|
|
63
|
+
self.fwHasCalculatedTextAlignment = false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private func calculatedTextAlignment(_ textAlignment: NSTextAlignment) -> NSTextAlignment {
|
|
67
|
+
if shouldCalculateTextAlignment(),
|
|
68
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection {
|
|
69
|
+
self.fwHasCalculatedTextAlignment = true
|
|
70
|
+
if layoutDirection == .rtl {
|
|
71
|
+
if textAlignment == .center {
|
|
72
|
+
return textAlignment
|
|
73
|
+
} else if textAlignment == .right {
|
|
74
|
+
return .left
|
|
75
|
+
} else {
|
|
76
|
+
return .right
|
|
77
|
+
}
|
|
78
|
+
} else if layoutDirection == .ltr {
|
|
79
|
+
return .left
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return textAlignment
|
|
83
|
+
}
|
|
84
|
+
return textAlignment
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private func shouldCalculateTextAlignment() -> Bool {
|
|
88
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
89
|
+
self.isIOSSDKView,
|
|
90
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection,
|
|
91
|
+
layoutDirection != .unsupported,
|
|
92
|
+
fwrtl_shouldUseCalculatedTextAlignment() {
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return false
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UITextField+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/23.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
|
|
9
|
+
extension UITextField {
|
|
10
|
+
private struct AssociatedKeys {
|
|
11
|
+
static var fwHasCalculatedTextAlignment = "fwHasCalculatedTextAlignmentKey"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private var fwHasCalculatedTextAlignment: Bool {
|
|
15
|
+
get {
|
|
16
|
+
let result = objc_getAssociatedObject(self, &AssociatedKeys.fwHasCalculatedTextAlignment) as? Bool
|
|
17
|
+
return result ?? false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set {
|
|
21
|
+
objc_setAssociatedObject(
|
|
22
|
+
self,
|
|
23
|
+
&AssociatedKeys.fwHasCalculatedTextAlignment,
|
|
24
|
+
newValue,
|
|
25
|
+
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func swizzleMethodsForTextField() {
|
|
31
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
32
|
+
originalSelector: #selector(setter: UITextField.textAlignment),
|
|
33
|
+
customSelector: #selector(UITextField.fw_setTextFieldTextAlignment(_:)))
|
|
34
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
35
|
+
originalSelector: #selector(UITextField.didMoveToWindow),
|
|
36
|
+
customSelector: #selector(UITextField.fw_textFieldDidMoveToWindow))
|
|
37
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
38
|
+
originalSelector: #selector(UITextField.removeFromSuperview),
|
|
39
|
+
customSelector: #selector(UITextField.fw_textFieldRemoveFromSuperview))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc func fw_setTextFieldTextAlignment(_ textAlignment: NSTextAlignment) {
|
|
43
|
+
self.fwrtl_addReloadBlock(forKey: "alignment") { [weak self] in
|
|
44
|
+
guard let self = self else {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.fw_setTextFieldTextAlignment(self.calculatedTextAlignment(textAlignment))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@objc func fw_textFieldDidMoveToWindow() {
|
|
53
|
+
fw_textFieldDidMoveToWindow()
|
|
54
|
+
if shouldCalculateTextAlignment(),
|
|
55
|
+
!self.fwHasCalculatedTextAlignment,
|
|
56
|
+
self.isIOSSDKView {
|
|
57
|
+
self.textAlignment = self.textAlignment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func fw_textFieldRemoveFromSuperview() {
|
|
62
|
+
fw_textFieldRemoveFromSuperview()
|
|
63
|
+
self.fwHasCalculatedTextAlignment = false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private func calculatedTextAlignment(_ textAlignment: NSTextAlignment) -> NSTextAlignment {
|
|
67
|
+
if shouldCalculateTextAlignment(),
|
|
68
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection {
|
|
69
|
+
self.fwHasCalculatedTextAlignment = true
|
|
70
|
+
if layoutDirection == .rtl {
|
|
71
|
+
if textAlignment == .center {
|
|
72
|
+
return textAlignment
|
|
73
|
+
} else if textAlignment == .right {
|
|
74
|
+
return .left
|
|
75
|
+
} else {
|
|
76
|
+
return .right
|
|
77
|
+
}
|
|
78
|
+
} else if layoutDirection == .ltr {
|
|
79
|
+
return .left
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return textAlignment
|
|
83
|
+
}
|
|
84
|
+
return textAlignment
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private func shouldCalculateTextAlignment() -> Bool {
|
|
88
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
89
|
+
self.isIOSSDKView,
|
|
90
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection,
|
|
91
|
+
layoutDirection != .unsupported {
|
|
92
|
+
return true
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UITextView+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/23.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
|
|
9
|
+
extension UITextView {
|
|
10
|
+
private struct AssociatedKeys {
|
|
11
|
+
static var fwHasCalculatedTextAlignment = "fwHasCalculatedTextAlignmentKey"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private var fwHasCalculatedTextAlignment: Bool {
|
|
15
|
+
get {
|
|
16
|
+
let result = objc_getAssociatedObject(self, &AssociatedKeys.fwHasCalculatedTextAlignment) as? Bool
|
|
17
|
+
return result ?? false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set {
|
|
21
|
+
objc_setAssociatedObject(
|
|
22
|
+
self,
|
|
23
|
+
&AssociatedKeys.fwHasCalculatedTextAlignment,
|
|
24
|
+
newValue,
|
|
25
|
+
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func swizzleMethodsForTextView() {
|
|
31
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
32
|
+
originalSelector: #selector(setter: UITextView.textAlignment),
|
|
33
|
+
customSelector: #selector(UITextView.fw_setTextViewTextAlignment(_:)))
|
|
34
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
35
|
+
originalSelector: #selector(UITextView.didMoveToWindow),
|
|
36
|
+
customSelector: #selector(UITextView.fw_textViewDidMoveToWindow))
|
|
37
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
38
|
+
originalSelector: #selector(UITextView.removeFromSuperview),
|
|
39
|
+
customSelector: #selector(UITextView.fw_textViewRemoveFromSuperview))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc func fw_setTextViewTextAlignment(_ textAlignment: NSTextAlignment) {
|
|
43
|
+
self.fwrtl_addReloadBlock(forKey: "alignment") { [weak self] in
|
|
44
|
+
guard let self = self else {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
self.fw_setTextViewTextAlignment(self.calculatedTextAlignment(textAlignment))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@objc func fw_textViewDidMoveToWindow() {
|
|
53
|
+
fw_textViewDidMoveToWindow()
|
|
54
|
+
if shouldCalculateTextAlignment(),
|
|
55
|
+
!self.fwHasCalculatedTextAlignment,
|
|
56
|
+
self.isIOSSDKView {
|
|
57
|
+
self.textAlignment = self.textAlignment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func fw_textViewRemoveFromSuperview() {
|
|
62
|
+
fw_textViewRemoveFromSuperview()
|
|
63
|
+
self.fwHasCalculatedTextAlignment = false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private func calculatedTextAlignment(_ textAlignment: NSTextAlignment) -> NSTextAlignment {
|
|
67
|
+
if shouldCalculateTextAlignment(),
|
|
68
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection {
|
|
69
|
+
self.fwHasCalculatedTextAlignment = true
|
|
70
|
+
if layoutDirection == .rtl {
|
|
71
|
+
if textAlignment == .center {
|
|
72
|
+
return textAlignment
|
|
73
|
+
} else if textAlignment == .right {
|
|
74
|
+
return .left
|
|
75
|
+
} else {
|
|
76
|
+
return .right
|
|
77
|
+
}
|
|
78
|
+
} else if layoutDirection == .ltr {
|
|
79
|
+
return .left
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return textAlignment
|
|
83
|
+
}
|
|
84
|
+
return textAlignment
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private func shouldCalculateTextAlignment() -> Bool {
|
|
88
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
89
|
+
self.isIOSSDKView,
|
|
90
|
+
let layoutDirection = FWAppLanguageManager.shared.appLanguageLayoutDirection,
|
|
91
|
+
layoutDirection != .unsupported {
|
|
92
|
+
return true
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIView+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/3/11.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
import FireworkVideo
|
|
9
|
+
|
|
10
|
+
extension UIView {
|
|
11
|
+
static func swizzleMethodsForView() {
|
|
12
|
+
FWSwizzleUtil.swizzleSelector(
|
|
13
|
+
cls: self,
|
|
14
|
+
originalSelector: #selector(UIView.init(frame:)),
|
|
15
|
+
customSelector: #selector(UIView.fw_init(frame:))
|
|
16
|
+
)
|
|
17
|
+
FWSwizzleUtil.swizzleSelector(
|
|
18
|
+
cls: self,
|
|
19
|
+
originalSelector: #selector(UIView.awakeFromNib),
|
|
20
|
+
customSelector: #selector(UIView.fw_viewAwakeFromNib)
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc func fw_init(frame: CGRect) -> UIView {
|
|
25
|
+
let view = self.fw_init(frame: frame)
|
|
26
|
+
if view is FireworkPlayerView {
|
|
27
|
+
view.fwrtl_viewType = FWRTLViewTypeNormal
|
|
28
|
+
}
|
|
29
|
+
return view
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@objc func fw_viewAwakeFromNib() {
|
|
33
|
+
self.fw_viewAwakeFromNib()
|
|
34
|
+
if self is FireworkPlayerView, FWAppLanguageManager.shared.shouldHorizontalFlip {
|
|
35
|
+
self.fwrtl_viewType = FWRTLViewTypeNormal
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIViewController+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/21.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
import FireworkVideo
|
|
9
|
+
|
|
10
|
+
extension UIViewController {
|
|
11
|
+
static func swizzleMethodsForViewController() {
|
|
12
|
+
FWSwizzleUtil.swizzleSelector(
|
|
13
|
+
cls: self,
|
|
14
|
+
originalSelector: #selector(UIViewController.present(_:animated:completion:)),
|
|
15
|
+
customSelector: #selector(UIViewController.fw_present(_:animated:completion:))
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc func fw_present(
|
|
20
|
+
_ viewControllerToPresent: UIViewController,
|
|
21
|
+
animated flag: Bool,
|
|
22
|
+
completion: (() -> Void)? = nil
|
|
23
|
+
) {
|
|
24
|
+
let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
|
|
25
|
+
let viewControllerToPresentBundle = Bundle(for: type(of: viewControllerToPresent))
|
|
26
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
27
|
+
viewControllerToPresentBundle == iOSSDKBundle {
|
|
28
|
+
viewControllerToPresent.view.fwrtl_viewType = FWRTLViewTypeFlip
|
|
29
|
+
}
|
|
30
|
+
fw_present(viewControllerToPresent, animated: flag, completion: completion)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIWindow+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/24.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
import FireworkVideo
|
|
9
|
+
|
|
10
|
+
extension UIWindow {
|
|
11
|
+
static func swizzleMethodsForWindow() {
|
|
12
|
+
FWSwizzleUtil.swizzleSelector(cls: self,
|
|
13
|
+
originalSelector: #selector(setter: UIWindow.rootViewController),
|
|
14
|
+
customSelector: #selector(UIWindow.fw_setRootViewController(_:)))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@objc func fw_setRootViewController(_ rootViewController: UIViewController?) {
|
|
18
|
+
fw_setRootViewController(rootViewController)
|
|
19
|
+
let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
|
|
20
|
+
if FWAppLanguageManager.shared.shouldHorizontalFlip,
|
|
21
|
+
let viewController = rootViewController,
|
|
22
|
+
Bundle(for: type(of: viewController)) == iOSSDKBundle {
|
|
23
|
+
viewController.view.fwrtl_viewType = FWRTLViewTypeFlip
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
//
|
|
2
|
+
// URLSession+FWSwizzle.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/20.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
private var FWHostList: [String] = [
|
|
10
|
+
"api.firework.tv",
|
|
11
|
+
"p2.fwpixel.com"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
public extension URLSession {
|
|
15
|
+
static func swizzleMethodsForURLSession() {
|
|
16
|
+
// swiftlint:disable:next line_length
|
|
17
|
+
let orginalSelector1 = #selector(URLSession.dataTask(with:completionHandler:) as (URLSession) -> (URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask)
|
|
18
|
+
let customSelector1 = #selector(URLSession.fw_dataTask(with:completionHandler:))
|
|
19
|
+
FWSwizzleUtil.swizzleSelector(
|
|
20
|
+
cls: self,
|
|
21
|
+
originalSelector: orginalSelector1,
|
|
22
|
+
customSelector: customSelector1)
|
|
23
|
+
// swiftlint:disable:next line_length
|
|
24
|
+
let orginalSelector2 = #selector(URLSession.dataTask(with:) as (URLSession) -> (URLRequest) -> URLSessionDataTask)
|
|
25
|
+
let customSelector2 = #selector(URLSession.fw_dataTask(with:))
|
|
26
|
+
FWSwizzleUtil.swizzleSelector(
|
|
27
|
+
cls: self,
|
|
28
|
+
originalSelector: orginalSelector2,
|
|
29
|
+
customSelector: customSelector2)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@objc func fw_dataTask(
|
|
33
|
+
with request: URLRequest,
|
|
34
|
+
completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void
|
|
35
|
+
) -> URLSessionDataTask {
|
|
36
|
+
return fw_dataTask(with: swizzleRequest(request), completionHandler: completionHandler)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@objc func fw_dataTask(with request: URLRequest) -> URLSessionDataTask {
|
|
40
|
+
return fw_dataTask(with: swizzleRequest(request))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private func swizzleRequest(_ request: URLRequest) -> URLRequest {
|
|
44
|
+
var host = ""
|
|
45
|
+
#if compiler(>=5.7)
|
|
46
|
+
if #available(iOS 16, *) {
|
|
47
|
+
host = request.url?.host() ?? ""
|
|
48
|
+
} else {
|
|
49
|
+
host = request.url?.host ?? ""
|
|
50
|
+
}
|
|
51
|
+
#else
|
|
52
|
+
host = request.url?.host ?? ""
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
if let language = FWAppLanguageManager.shared.appLanguage,
|
|
56
|
+
let languageCode = FWAppLanguageManager.shared.appLanguageCode,
|
|
57
|
+
FWHostList.contains(host) {
|
|
58
|
+
var mutableRequest = request
|
|
59
|
+
if language != languageCode {
|
|
60
|
+
mutableRequest.setValue("\(language),\(languageCode);q=0.9", forHTTPHeaderField: "Accept-Language")
|
|
61
|
+
} else {
|
|
62
|
+
mutableRequest.setValue("\(language);q=0.9", forHTTPHeaderField: "Accept-Language")
|
|
63
|
+
}
|
|
64
|
+
return mutableRequest
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return request
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -10,15 +10,15 @@ extension DispatchQueue {
|
|
|
10
10
|
private static var _onceContainer = [String]()
|
|
11
11
|
|
|
12
12
|
/// Execute a block only once.
|
|
13
|
-
public class func
|
|
13
|
+
public class func once(
|
|
14
14
|
file: String = #file, function: String = #function, line: Int = #line, block: () -> Void
|
|
15
15
|
) {
|
|
16
16
|
let token = file + ":" + function + ":" + String(line)
|
|
17
|
-
|
|
17
|
+
once(token: token, block: block)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/// Execute a block only once.
|
|
21
|
-
public class func
|
|
21
|
+
public class func once(token: String, block: () -> Void) {
|
|
22
22
|
objc_sync_enter(self)
|
|
23
23
|
defer { objc_sync_exit(self) }
|
|
24
24
|
|
|
@@ -7,14 +7,12 @@
|
|
|
7
7
|
import UIKit
|
|
8
8
|
|
|
9
9
|
extension UINavigationController {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
17
|
-
}
|
|
10
|
+
static func swizzleMethodsForNavigationController() {
|
|
11
|
+
FWSwizzleUtil.swizzleSelector(
|
|
12
|
+
cls: self,
|
|
13
|
+
originalSelector: #selector(UINavigationController.pushViewController(_:animated:)),
|
|
14
|
+
customSelector: #selector(UINavigationController.fw_pushViewController(_:animated:))
|
|
15
|
+
)
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
@objc func fw_pushViewController(
|