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.
Files changed (138) hide show
  1. package/android/build.gradle +5 -3
  2. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFragment.kt +129 -0
  3. package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/StoryBlockFrameLayout.kt +84 -0
  4. package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +2 -1
  5. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfiguration.kt +18 -5
  6. package/android/src/main/java/com/fireworksdk/bridge/models/FWProductInfoViewConfigurationDeserializer.kt +33 -9
  7. package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResult.kt +17 -0
  8. package/android/src/main/java/com/fireworksdk/bridge/models/FWShoppingCtaResultDeserializer.kt +33 -0
  9. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +126 -45
  10. package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +6 -3
  11. package/android/src/main/java/com/fireworksdk/bridge/reactnative/models/FWVideoShoppingInterface.kt +2 -2
  12. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWNavigatorModule.kt +9 -1
  13. package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FWVideoShoppingModule.kt +81 -50
  14. package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +9 -2
  15. package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +1 -1
  16. package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +4 -0
  17. package/android/src/main/java/com/fireworksdk/bridge/utils/FWLanguageUtil.kt +48 -16
  18. package/android/src/main/res/layout/fw_bridge_story_block.xml +24 -0
  19. package/ios/Components/StoryBlock.swift +33 -2
  20. package/ios/Components/StoryBlockManager.m +32 -0
  21. package/ios/Components/VideoFeed.swift +9 -29
  22. package/ios/Components/VideoFeedManager.m +11 -6
  23. package/ios/FireworkSdk.xcodeproj/project.pbxproj +378 -104
  24. package/ios/Models/NativeToRN/FireworkEventName.swift +3 -1
  25. package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
  26. package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +27 -0
  27. package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +5 -1
  28. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
  29. package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +30 -0
  30. package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +13 -0
  31. package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
  32. package/ios/Modules/Shopping/ShoppingModule.m +2 -1
  33. package/ios/Modules/Shopping/ShoppingModule.swift +106 -30
  34. package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +24 -0
  35. package/ios/Support/MultiHostStreaming/src/MultiHostStreamingSDK.swift +17 -0
  36. package/ios/Utils/AppLanguage/Bundle+FWSwizzle.swift +58 -0
  37. package/ios/Utils/AppLanguage/FWAppLanguageManager.swift +139 -0
  38. package/ios/Utils/AppLanguage/FWLanguageUtil.swift +43 -0
  39. package/ios/Utils/AppLanguage/NumberFormatter+FWSwizzle.swift +25 -0
  40. package/ios/Utils/AppLanguage/UIImageView+FWSwizzle.swift +91 -0
  41. package/ios/Utils/AppLanguage/UILabel+FWSwizzle.swift +98 -0
  42. package/ios/Utils/AppLanguage/UITextField+FWSwizzle.swift +97 -0
  43. package/ios/Utils/AppLanguage/UITextView+FWSwizzle.swift +97 -0
  44. package/ios/Utils/AppLanguage/UIView+FWSwizzle.swift +38 -0
  45. package/ios/Utils/AppLanguage/UIViewController+FWSwizzle.swift +32 -0
  46. package/ios/Utils/AppLanguage/UIWindow+FWSwizzle.swift +26 -0
  47. package/ios/Utils/AppLanguage/URLSession+FWSwizzle.swift +69 -0
  48. package/ios/Utils/{DispatchQueue+FWOnce.swift → Extensions/DispatchQueue+FWOnce.swift} +3 -3
  49. package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +6 -8
  50. package/ios/Utils/Extensions/UIView+FWUIHierarchy.swift +47 -0
  51. package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.h +25 -0
  52. package/ios/Utils/FWRTL/Classes/Manager/FWRTLManager.m +75 -0
  53. package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.h +21 -0
  54. package/ios/Utils/FWRTL/Classes/UICategories/CALayer+FWRTL.m +124 -0
  55. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.h +11 -0
  56. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLRemoteViewControllerAdaptor.m +86 -0
  57. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.h +16 -0
  58. package/ios/Utils/FWRTL/Classes/UICategories/FWRTLWhiteListManager.m +55 -0
  59. package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.h +18 -0
  60. package/ios/Utils/FWRTL/Classes/UICategories/UILabel+FWRTL.m +39 -0
  61. package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.h +54 -0
  62. package/ios/Utils/FWRTL/Classes/UICategories/UIView+FWRTL.m +141 -0
  63. package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.h +16 -0
  64. package/ios/Utils/FWRTL/Classes/UICategories/UIWindow+FWRTL.m +20 -0
  65. package/ios/Utils/FWRTL/Classes/Utils/FWRTLDefinitions.h +52 -0
  66. package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.h +19 -0
  67. package/ios/Utils/FWRTL/Classes/Utils/NSObject+FWRTLReloadBlock.m +49 -0
  68. package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.h +21 -0
  69. package/ios/Utils/FWRTL/Classes/Utils/NSString+FWRTL.m +38 -0
  70. package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.h +18 -0
  71. package/ios/Utils/FWRTL/Classes/Utils/UIImage+FWRTL.m +43 -0
  72. package/ios/Utils/FWSwizzleLoader.m +6 -1
  73. package/ios/Utils/FWSwizzleLoader.swift +13 -0
  74. package/ios/Utils/FWSwizzleUtil.swift +17 -9
  75. package/ios/react_native_firework_sdk.h +1 -0
  76. package/ios/scripts/react_native_firework_sdk_pods.rb +31 -0
  77. package/lib/commonjs/FireworkSDK.js +21 -4
  78. package/lib/commonjs/FireworkSDK.js.map +1 -1
  79. package/lib/commonjs/VideoShopping.js +20 -37
  80. package/lib/commonjs/VideoShopping.js.map +1 -1
  81. package/lib/commonjs/components/StoryBlock.js +190 -125
  82. package/lib/commonjs/components/StoryBlock.js.map +1 -1
  83. package/lib/commonjs/components/VideoFeed.js +11 -1
  84. package/lib/commonjs/components/VideoFeed.js.map +1 -1
  85. package/lib/commonjs/index.js.map +1 -1
  86. package/lib/commonjs/models/FWEventName.js +2 -0
  87. package/lib/commonjs/models/FWEventName.js.map +1 -1
  88. package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
  89. package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
  90. package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
  91. package/lib/module/FireworkSDK.js +21 -4
  92. package/lib/module/FireworkSDK.js.map +1 -1
  93. package/lib/module/VideoShopping.js +20 -39
  94. package/lib/module/VideoShopping.js.map +1 -1
  95. package/lib/module/components/StoryBlock.js +179 -131
  96. package/lib/module/components/StoryBlock.js.map +1 -1
  97. package/lib/module/components/VideoFeed.js +10 -1
  98. package/lib/module/components/VideoFeed.js.map +1 -1
  99. package/lib/module/index.js.map +1 -1
  100. package/lib/module/models/FWEventName.js +2 -0
  101. package/lib/module/models/FWEventName.js.map +1 -1
  102. package/lib/module/models/ShoppingCTAResult.js +2 -0
  103. package/lib/module/modules/FireworkSDKModule.js.map +1 -1
  104. package/lib/module/modules/ShoppingModule.js.map +1 -1
  105. package/lib/typescript/FireworkSDK.d.ts +7 -4
  106. package/lib/typescript/VideoShopping.d.ts +9 -11
  107. package/lib/typescript/components/StoryBlock.d.ts +19 -25
  108. package/lib/typescript/index.d.ts +6 -6
  109. package/lib/typescript/models/FWEventName.d.ts +2 -0
  110. package/lib/typescript/models/FWEvents.d.ts +14 -1
  111. package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +36 -1
  112. package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
  113. package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
  114. package/lib/typescript/modules/ShoppingModule.d.ts +2 -1
  115. package/package.json +2 -2
  116. package/react-native-firework-sdk.podspec +26 -24
  117. package/src/FireworkSDK.ts +18 -5
  118. package/src/VideoShopping.ts +40 -53
  119. package/src/components/StoryBlock.tsx +199 -96
  120. package/src/components/VideoFeed.tsx +11 -0
  121. package/src/index.ts +15 -7
  122. package/src/models/FWEventName.ts +2 -0
  123. package/src/models/FWEvents.ts +14 -1
  124. package/src/models/ProductInfoViewConfiguration.ts +38 -1
  125. package/src/models/ShoppingCTAResult.ts +11 -0
  126. package/src/modules/FireworkSDKModule.ts +1 -2
  127. package/src/modules/ShoppingModule.ts +5 -5
  128. package/android/src/main/java/com/fireworksdk/bridge/constants/FWCommandConstant.kt +0 -6
  129. package/ios/Utils/UIView+ParentViewController.swift +0 -21
  130. package/lib/commonjs/models/AddToCartResult.js +0 -2
  131. package/lib/module/models/AddToCartResult.js +0 -2
  132. package/lib/typescript/models/AddToCartResult.d.ts +0 -10
  133. package/src/models/AddToCartResult.ts +0 -10
  134. /package/ios/Utils/{String+Color.swift → Extensions/String+Color.swift} +0 -0
  135. /package/ios/Utils/{UIView+Constraints.swift → Extensions/UIView+Constraints.swift} +0 -0
  136. /package/ios/Utils/{UIViewController+AttachChild.swift → Extensions/UIViewController+AttachChild.swift} +0 -0
  137. /package/lib/commonjs/models/{AddToCartResult.js.map → ShoppingCTAResult.js.map} +0 -0
  138. /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 fw_once(
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
- fw_once(token: token, block: block)
17
+ once(token: token, block: block)
18
18
  }
19
19
 
20
20
  /// Execute a block only once.
21
- public class func fw_once(token: String, block: () -> Void) {
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
- @objc public static func fw_swizzleMethods() {
11
- DispatchQueue.fw_once {
12
- FWSwizzleUtil.swizzleSelector(
13
- cls: self,
14
- orginalSelector: #selector(pushViewController(_:animated:)),
15
- customSelector: #selector(fw_pushViewController(_:animated:))
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(