react-native-firework-sdk 2.0.0 → 2.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FireworkVideoUI.xcframework/Info.plist +40 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Headers/FireworkVideoUI-Swift.h +280 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Headers/FireworkVideoUI.h +18 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Info.plist +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.abi.json +1327 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.private.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64/FireworkVideoUI.framework/Modules/module.modulemap +11 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/FireworkVideoUI +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Headers/FireworkVideoUI-Swift.h +556 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Headers/FireworkVideoUI.h +18 -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/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.abi.json +1327 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/arm64-apple-ios-simulator.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.abi.json +1327 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/FireworkVideoUI.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +41 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/Modules/module.modulemap +11 -0
- package/FireworkVideoUI.xcframework/ios-arm64_x86_64-simulator/FireworkVideoUI.framework/_CodeSignature/CodeResources +245 -0
- package/README.md +1 -1
- package/android/build.gradle +5 -4
- package/android/src/main/java/com/fireworksdk/bridge/components/videofeed/FWVideoFeed.kt +6 -0
- 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 +90 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWAdBadgeConfigModelDeserializer.kt +3 -3
- package/android/src/main/java/com/fireworksdk/bridge/models/FWEventName.kt +5 -1
- package/android/src/main/java/com/fireworksdk/bridge/models/FWFontInfoModelDeserializer.kt +1 -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 +36 -8
- package/android/src/main/java/com/fireworksdk/bridge/models/FWSDKInitOptionsModelDeserializer.kt +3 -3
- 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/models/FWVideoFeedConfigModelDeserializer.kt +14 -12
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModel.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedPropsModelDeserializer.kt +11 -7
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoFeedSource.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlaybackDetails.kt +8 -8
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModel.kt +1 -0
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoPlayerConfigModelDeserializer.kt +19 -12
- package/android/src/main/java/com/fireworksdk/bridge/models/FWVideoShoppingProductDeserializer.kt +11 -11
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWStoryBlockManager.kt +131 -45
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/manager/FWVideoFeedManager.kt +11 -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/FWLiveStreamModule.kt +45 -4
- 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 +83 -50
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/module/FireworkSDKModule.kt +112 -36
- package/android/src/main/java/com/fireworksdk/bridge/reactnative/utils/FWEventUtils.kt +16 -6
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWConfigUtil.kt +26 -32
- package/android/src/main/java/com/fireworksdk/bridge/utils/FWGlobalDataUtil.kt +10 -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 +32 -2
- package/ios/Components/StoryBlockManager.m +33 -0
- package/ios/Components/StoryBlockManager.swift +4 -0
- package/ios/Components/VideoFeed.swift +16 -32
- package/ios/Components/VideoFeedManager.m +12 -6
- package/ios/Components/VideoFeedManager.swift +4 -0
- package/ios/Components/VideoPlayerConfiguration.swift +1 -0
- package/ios/FireworkSdk.xcodeproj/project.pbxproj +276 -212
- package/ios/FireworkVideoUI/FireworkVideoUI/FireworkVideoUI.docc/FireworkVideoUI.md +13 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/FireworkVideoUI.h +18 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/AppLanguageManager.swift +147 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/Bundle+AppLanguage.swift +58 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/NumberFormatter+AppLanguage.swift +25 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/Foundation/URLSession+AppLanguage.swift +69 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIImageView+AppLanguage.swift +91 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UILabel+AppLanguage.swift +98 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UITextField+AppLanguage.swift +97 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UITextView+AppLanguage.swift +97 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIView+AppLanguage.swift +38 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIViewController+AppLanguage.swift +46 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/Extensions/UIKit/UIWindow+AppLanguage.swift +26 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/AppLanguage/LanguageUtil.swift +43 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/Foundation/NSObject+LayoutFlip.swift +42 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/CALayer+LayoutFlip.swift +160 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/UILabel+LayoutFlip.swift +35 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/Extensions/UIKit/UIView+LayoutFlip.swift +199 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/LayoutFlip/LayoutFlipManager.swift +59 -0
- package/ios/{Utils/DispatchQueue+FWOnce.swift → FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/Foundation/DispatchQueue+Once.swift} +5 -5
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/Foundation/String+Base64.swift +18 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Extensions/UIKit/UIView+UIHierarchy.swift +46 -0
- package/ios/FireworkVideoUI/FireworkVideoUI/Sources/Utils/Swizzle.swift +37 -0
- package/ios/FireworkVideoUI/FireworkVideoUI.xcodeproj/project.pbxproj +766 -0
- package/ios/FireworkVideoUI/FireworkVideoUI.xcworkspace/contents.xcworkspacedata +10 -0
- package/ios/FireworkVideoUI/FireworkVideoUI.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/FireworkVideoUI/FireworkVideoUITests/FireworkVideoUITests.swift +37 -0
- package/ios/FireworkVideoUI/Podfile +15 -0
- package/ios/FireworkVideoUI/Podfile.lock +16 -0
- package/ios/Models/NativeToRN/FireworkEventName.swift +7 -1
- package/ios/Models/NativeToRN/FireworkSDK+Json.swift +5 -1
- package/ios/Models/RNToNative/RCTConvert+Shopping.swift +21 -0
- package/ios/Models/RNToNative/RCTConvert+StoryBlock.swift +2 -1
- package/ios/Models/RNToNative/RCTConvert+VideoFeed.swift +29 -1
- package/ios/Modules/FWNavigatorModule/FWNavigatorModule.swift +13 -101
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule+EventTracking.swift +34 -16
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.m +1 -0
- package/ios/Modules/FireworkSDKModule/FireworkSDKModule.swift +48 -2
- package/ios/Modules/FireworkSDKModule/SDKInitOptions.swift +0 -1
- package/ios/Modules/LiveStream/LiveStreamModule.swift +1 -0
- package/ios/Modules/Shopping/ProductInfoViewConfiguration.swift +7 -2
- package/ios/Modules/Shopping/ShoppingCTAResult.swift +16 -0
- package/ios/Modules/Shopping/ShoppingModule.m +2 -1
- package/ios/Modules/Shopping/ShoppingModule.swift +92 -34
- package/ios/Support/MultiHostStreaming/FWMultiHostStreaming.podspec +22 -0
- package/ios/Support/MultiHostStreaming/Sources/MultiHostStreamingSDK.swift +17 -0
- package/ios/Utils/{UINavigationController+FWSwizzle.swift → Extensions/Swizzle/UINavigationController+FWSwizzle.swift} +9 -8
- package/ios/Utils/FWSwizzleLoader.m +6 -1
- package/ios/Utils/FWSwizzleLoader.swift +13 -0
- package/ios/react_native_firework_sdk.h +1 -0
- package/ios/scripts/react_native_firework_sdk_pods.rb +27 -0
- package/lib/commonjs/FireworkSDK.js +55 -15
- package/lib/commonjs/FireworkSDK.js.map +1 -1
- package/lib/commonjs/LiveStream.js +2 -2
- package/lib/commonjs/LiveStream.js.map +1 -1
- package/lib/commonjs/VideoShopping.js +21 -38
- package/lib/commonjs/VideoShopping.js.map +1 -1
- package/lib/commonjs/components/StoryBlock.js +193 -128
- package/lib/commonjs/components/StoryBlock.js.map +1 -1
- package/lib/commonjs/components/VideoFeed.js +17 -5
- package/lib/commonjs/components/VideoFeed.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/models/FWEventName.js +3 -0
- package/lib/commonjs/models/FWEventName.js.map +1 -1
- package/lib/commonjs/models/ShoppingCTAResult.js +2 -0
- package/lib/commonjs/models/VideoPlaybackEventName.js +3 -0
- package/lib/commonjs/models/VideoPlaybackEventName.js.map +1 -1
- package/lib/commonjs/modules/FireworkSDKModule.js.map +1 -1
- package/lib/commonjs/modules/ShoppingModule.js.map +1 -1
- package/lib/module/FireworkSDK.js +54 -15
- package/lib/module/FireworkSDK.js.map +1 -1
- package/lib/module/LiveStream.js +2 -2
- package/lib/module/LiveStream.js.map +1 -1
- package/lib/module/VideoShopping.js +21 -40
- package/lib/module/VideoShopping.js.map +1 -1
- package/lib/module/components/StoryBlock.js +183 -133
- package/lib/module/components/StoryBlock.js.map +1 -1
- package/lib/module/components/VideoFeed.js +16 -5
- package/lib/module/components/VideoFeed.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/models/FWEventName.js +3 -0
- package/lib/module/models/FWEventName.js.map +1 -1
- package/lib/module/models/ShoppingCTAResult.js +2 -0
- package/lib/module/models/VideoPlaybackEventName.js +3 -0
- package/lib/module/models/VideoPlaybackEventName.js.map +1 -1
- package/lib/module/modules/FireworkSDKModule.js.map +1 -1
- package/lib/module/modules/ShoppingModule.js.map +1 -1
- package/lib/typescript/FireworkSDK.d.ts +15 -8
- package/lib/typescript/LiveStream.d.ts +2 -2
- package/lib/typescript/VideoShopping.d.ts +10 -12
- package/lib/typescript/components/StoryBlock.d.ts +25 -24
- package/lib/typescript/components/VideoFeed.d.ts +7 -0
- package/lib/typescript/index.d.ts +6 -6
- package/lib/typescript/models/FWEventName.d.ts +3 -0
- package/lib/typescript/models/FWEvents.d.ts +14 -1
- package/lib/typescript/models/ProductInfoViewConfiguration.d.ts +12 -8
- package/lib/typescript/models/SDKInitOptions.d.ts +6 -1
- package/lib/typescript/models/ShoppingCTAResult.d.ts +11 -0
- package/lib/typescript/models/StoryBlockSource.d.ts +1 -1
- package/lib/typescript/models/VideoFeedSource.d.ts +1 -1
- package/lib/typescript/models/VideoPlaybackDetails.d.ts +16 -0
- package/lib/typescript/models/VideoPlaybackEventName.d.ts +13 -1
- package/lib/typescript/models/VideoPlayerConfiguration.d.ts +4 -0
- package/lib/typescript/modules/FireworkSDKModule.d.ts +1 -2
- package/lib/typescript/modules/ShoppingModule.d.ts +2 -1
- package/package.json +8 -3
- package/react-native-firework-sdk.podspec +31 -24
- package/src/FireworkSDK.ts +54 -15
- package/src/LiveStream.ts +2 -2
- package/src/VideoShopping.ts +41 -54
- package/src/components/StoryBlock.tsx +210 -98
- package/src/components/VideoFeed.tsx +23 -4
- package/src/index.ts +15 -9
- package/src/models/FWEventName.ts +3 -0
- package/src/models/FWEvents.ts +14 -1
- package/src/models/ProductInfoViewConfiguration.ts +13 -8
- package/src/models/SDKInitOptions.ts +6 -1
- package/src/models/ShoppingCTAResult.ts +11 -0
- package/src/models/StoryBlockSource.ts +2 -1
- package/src/models/VideoFeedSource.ts +2 -1
- package/src/models/VideoPlaybackDetails.ts +16 -0
- package/src/models/VideoPlaybackEventName.ts +13 -1
- package/src/models/VideoPlayerConfiguration.ts +4 -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/FWSwizzleUtil.swift +0 -29
- 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,13 @@
|
|
|
1
|
+
# ``FireworkVideoUI``
|
|
2
|
+
|
|
3
|
+
<!--@START_MENU_TOKEN@-->Summary<!--@END_MENU_TOKEN@-->
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->
|
|
8
|
+
|
|
9
|
+
## Topics
|
|
10
|
+
|
|
11
|
+
### <!--@START_MENU_TOKEN@-->Group<!--@END_MENU_TOKEN@-->
|
|
12
|
+
|
|
13
|
+
- <!--@START_MENU_TOKEN@-->``Symbol``<!--@END_MENU_TOKEN@-->
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//
|
|
2
|
+
// FireworkVideoUI.h
|
|
3
|
+
// FireworkVideoUI
|
|
4
|
+
//
|
|
5
|
+
// Created by linjie jiang on 4/25/23.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
|
|
10
|
+
//! Project version number for FireworkVideoUI.
|
|
11
|
+
FOUNDATION_EXPORT double FireworkVideoUIVersionNumber;
|
|
12
|
+
|
|
13
|
+
//! Project version string for FireworkVideoUI.
|
|
14
|
+
FOUNDATION_EXPORT const unsigned char FireworkVideoUIVersionString[];
|
|
15
|
+
|
|
16
|
+
// In this header, you should import all the public headers of your framework using statements like #import <FireworkVideoUI/PublicHeader.h>
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AppLanguageManager.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/7.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import UIKit
|
|
8
|
+
|
|
9
|
+
private let appLanguageStorageKey = "firework_sdk_app_language_storage_key"
|
|
10
|
+
|
|
11
|
+
enum AppLanguageLayoutDirection: Int {
|
|
12
|
+
case ltr, rtl, unsupported
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/// The manager of supporting app language
|
|
16
|
+
public class AppLanguageManager {
|
|
17
|
+
public struct NotificationName {
|
|
18
|
+
/// The notification name for language change
|
|
19
|
+
public static let AppLanguageChanged = Notification.Name(
|
|
20
|
+
rawValue: "firework.notification.name.appLanguageChanged"
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static let shared = AppLanguageManager()
|
|
25
|
+
|
|
26
|
+
var systemLanguage: String?
|
|
27
|
+
private var systemLanguageCode: String? {
|
|
28
|
+
guard let language = systemLanguage else {
|
|
29
|
+
return nil
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return LanguageUtil.getLanguageCode(language)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Get current app language.
|
|
36
|
+
public private(set) var appLanguage: String? {
|
|
37
|
+
didSet {
|
|
38
|
+
if appLanguage != nil {
|
|
39
|
+
AppLanguageManager.swizzelMethods()
|
|
40
|
+
LayoutFlipManager.shared.enableHorizontalFlip = shouldHorizontalFlip
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if appLanguage != oldValue {
|
|
44
|
+
NotificationCenter.default.post(name: NotificationName.AppLanguageChanged, object: nil)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var appLanguageCode: String? {
|
|
50
|
+
guard let language = appLanguage else {
|
|
51
|
+
return nil
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return LanguageUtil.getLanguageCode(language)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var appLanguageLayoutDirection: AppLanguageLayoutDirection? {
|
|
58
|
+
guard let languageCode = appLanguageCode else {
|
|
59
|
+
return nil
|
|
60
|
+
}
|
|
61
|
+
let direction = Locale.characterDirection(forLanguage: languageCode)
|
|
62
|
+
switch direction {
|
|
63
|
+
case .leftToRight:
|
|
64
|
+
return .ltr
|
|
65
|
+
case .rightToLeft:
|
|
66
|
+
return .rtl
|
|
67
|
+
default:
|
|
68
|
+
return .unsupported
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var shouldHorizontalFlip: Bool {
|
|
73
|
+
guard let appLanguageCode = appLanguageCode else {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
guard let systemLanguageCode = systemLanguageCode else {
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let appLanguageDirection = Locale.characterDirection(forLanguage: appLanguageCode)
|
|
82
|
+
let systemLanguageDirection = Locale.characterDirection(forLanguage: systemLanguageCode)
|
|
83
|
+
|
|
84
|
+
if appLanguageDirection == .leftToRight, systemLanguageDirection == .rightToLeft {
|
|
85
|
+
return true
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if appLanguageDirection == .rightToLeft, systemLanguageDirection == .leftToRight {
|
|
89
|
+
return true
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static func swizzelMethods() {
|
|
96
|
+
DispatchQueue.once {
|
|
97
|
+
UIViewController.swizzleViewControllerMethodsForAppLanguage()
|
|
98
|
+
Bundle.swizzleBundleMethodsForAppLanguage()
|
|
99
|
+
URLSession.swizzleURLSessionMethodsForAppLanguage()
|
|
100
|
+
NumberFormatter.swizzleNumberFormatterMethodsForAppLanguage()
|
|
101
|
+
UIImageView.swizzleImageViewMethodsForAppLanguage()
|
|
102
|
+
UILabel.swizzleLabelMethodsForAppLanguage()
|
|
103
|
+
UITextField.swizzleTextFieldMethodsForAppLanguage()
|
|
104
|
+
UITextView.swizzleTextViewMethodsForAppLanguage()
|
|
105
|
+
UIWindow.swizzleWindowMethodsForAppLanguage()
|
|
106
|
+
UIView.swizzleViewMethodsForAppLanguage()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
LayoutFlipManager.swizzelMethods()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private init() {
|
|
113
|
+
initializeManager()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private func initializeManager() {
|
|
117
|
+
self.systemLanguage = Locale.preferredLanguages.first
|
|
118
|
+
let cachedAppLanguage = UserDefaults.standard.object(forKey: appLanguageStorageKey) as? String
|
|
119
|
+
if LanguageUtil.isValidLanguage(cachedAppLanguage) {
|
|
120
|
+
self.appLanguage = cachedAppLanguage
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/// Change app language
|
|
125
|
+
///
|
|
126
|
+
/// - Parameters:
|
|
127
|
+
/// - language: app language. We will use system langauge when language is nil.
|
|
128
|
+
/// - Returns: The result of changing app language.
|
|
129
|
+
@discardableResult
|
|
130
|
+
public func changeAppLanguage(_ language: String?) -> Bool {
|
|
131
|
+
guard let language = language, language.count > 0 else {
|
|
132
|
+
appLanguage = nil
|
|
133
|
+
UserDefaults.standard.removeObject(forKey: appLanguageStorageKey)
|
|
134
|
+
UserDefaults.standard.synchronize()
|
|
135
|
+
return true
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if LanguageUtil.isValidLanguage(language) {
|
|
139
|
+
appLanguage = language
|
|
140
|
+
UserDefaults.standard.set(language, forKey: appLanguageStorageKey)
|
|
141
|
+
UserDefaults.standard.synchronize()
|
|
142
|
+
return true
|
|
143
|
+
} else {
|
|
144
|
+
return false
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Bundle+AppLanguage.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/7.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
import FireworkVideo
|
|
9
|
+
|
|
10
|
+
extension Bundle {
|
|
11
|
+
static func swizzleBundleMethodsForAppLanguage() {
|
|
12
|
+
Swizzle.swizzleSelector(
|
|
13
|
+
cls: self,
|
|
14
|
+
originalSelector: #selector(Bundle.localizedString(forKey:value:table:)),
|
|
15
|
+
customSelector: #selector(Bundle.fw_localizedString(forKey:value:table:)))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@objc func fw_localizedString(
|
|
19
|
+
forKey key: String,
|
|
20
|
+
value: String?,
|
|
21
|
+
table tableName: String?
|
|
22
|
+
) -> String {
|
|
23
|
+
if let language = AppLanguageManager.shared.appLanguage,
|
|
24
|
+
let languageCode = AppLanguageManager.shared.appLanguageCode,
|
|
25
|
+
Bundle(for: FireworkVideoSDK.self) == self {
|
|
26
|
+
let iOSSDKBundle = Bundle(for: FireworkVideoSDK.self)
|
|
27
|
+
|
|
28
|
+
var languageBundlePath: String?
|
|
29
|
+
let defaultLanguageBundlePath = iOSSDKBundle.path(forResource: "Base", ofType: "lproj")
|
|
30
|
+
if languageCode == "en" {
|
|
31
|
+
languageBundlePath = defaultLanguageBundlePath
|
|
32
|
+
} else if let path = iOSSDKBundle.path(forResource: language, ofType: "lproj") {
|
|
33
|
+
languageBundlePath = path
|
|
34
|
+
} else if let path = iOSSDKBundle.path(forResource: languageCode, ofType: "lproj") {
|
|
35
|
+
languageBundlePath = path
|
|
36
|
+
} else {
|
|
37
|
+
let targeLanguageList = iOSSDKBundle.localizations.filter { item in
|
|
38
|
+
return item != "Base" && item != "en"
|
|
39
|
+
}
|
|
40
|
+
if let targeLanguage = targeLanguageList.first(where: { item in
|
|
41
|
+
let targeLanguageCode = LanguageUtil.getLanguageCode(item)
|
|
42
|
+
return languageCode == targeLanguageCode
|
|
43
|
+
}) {
|
|
44
|
+
languageBundlePath = iOSSDKBundle.path(forResource: targeLanguage, ofType: "lproj")
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if let resultLanguageBundlePath = languageBundlePath ?? defaultLanguageBundlePath,
|
|
49
|
+
let resultLanguageBundle = Bundle(path: resultLanguageBundlePath) {
|
|
50
|
+
return resultLanguageBundle.fw_localizedString(forKey: key, value: value, table: tableName)
|
|
51
|
+
} else {
|
|
52
|
+
return self.fw_localizedString(forKey: key, value: value, table: tableName)
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
return self.fw_localizedString(forKey: key, value: value, table: tableName)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
// NumberFormatter+AppLanguage.swift
|
|
3
|
+
//
|
|
4
|
+
// Created by linjie jiang on 2023/2/20.
|
|
5
|
+
//
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
extension NumberFormatter {
|
|
10
|
+
static func swizzleNumberFormatterMethodsForAppLanguage() {
|
|
11
|
+
Swizzle.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 = AppLanguageManager.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,69 @@
|
|
|
1
|
+
//
|
|
2
|
+
// URLSession+AppLanguage.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
|
+
extension URLSession {
|
|
15
|
+
static func swizzleURLSessionMethodsForAppLanguage() {
|
|
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
|
+
Swizzle.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
|
+
Swizzle.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 = AppLanguageManager.shared.appLanguage,
|
|
56
|
+
let languageCode = AppLanguageManager.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
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UIImageView+AppLanguage.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 swizzleImageViewMethodsForAppLanguage() {
|
|
20
|
+
Swizzle.swizzleSelector(
|
|
21
|
+
cls: self,
|
|
22
|
+
originalSelector: #selector(UIImageView.didMoveToWindow),
|
|
23
|
+
customSelector: #selector(UIImageView.fw_imageViewDidMoveToWindow))
|
|
24
|
+
Swizzle.swizzleSelector(
|
|
25
|
+
cls: self,
|
|
26
|
+
originalSelector: #selector(setter: UIImageView.image),
|
|
27
|
+
customSelector: #selector(UIImageView.fw_setImage(_:))
|
|
28
|
+
)
|
|
29
|
+
Swizzle.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.viewType = shouldFlipImage(image) ? .flip : .auto
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private func shouldFlipImage(_ image: UIImage?) -> Bool {
|
|
56
|
+
guard let image = image else {
|
|
57
|
+
return false
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if AppLanguageManager.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 AppLanguageManager.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+AppLanguage.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 hasCalculatedTextAlignment = "hasCalculatedTextAlignmentKey"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private var hasCalculatedTextAlignment: Bool {
|
|
15
|
+
get {
|
|
16
|
+
let result = objc_getAssociatedObject(self, &AssociatedKeys.hasCalculatedTextAlignment) as? Bool
|
|
17
|
+
return result ?? false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set {
|
|
21
|
+
objc_setAssociatedObject(
|
|
22
|
+
self,
|
|
23
|
+
&AssociatedKeys.hasCalculatedTextAlignment,
|
|
24
|
+
newValue,
|
|
25
|
+
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func swizzleLabelMethodsForAppLanguage() {
|
|
31
|
+
Swizzle.swizzleSelector(cls: self,
|
|
32
|
+
originalSelector: #selector(setter: UILabel.textAlignment),
|
|
33
|
+
customSelector: #selector(UILabel.fw_setLabelTextAlignment(_:)))
|
|
34
|
+
Swizzle.swizzleSelector(cls: self,
|
|
35
|
+
originalSelector: #selector(UILabel.didMoveToWindow),
|
|
36
|
+
customSelector: #selector(UILabel.fw_labelDidMoveToWindow))
|
|
37
|
+
Swizzle.swizzleSelector(cls: self,
|
|
38
|
+
originalSelector: #selector(UILabel.removeFromSuperview),
|
|
39
|
+
customSelector: #selector(UILabel.fw_labelRemoveFromSuperview))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc func fw_setLabelTextAlignment(_ textAlignment: NSTextAlignment) {
|
|
43
|
+
addReloadClosure(key: "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.hasCalculatedTextAlignment,
|
|
56
|
+
self.isIOSSDKView {
|
|
57
|
+
self.textAlignment = self.textAlignment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func fw_labelRemoveFromSuperview() {
|
|
62
|
+
fw_labelRemoveFromSuperview()
|
|
63
|
+
self.hasCalculatedTextAlignment = false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private func calculatedTextAlignment(_ textAlignment: NSTextAlignment) -> NSTextAlignment {
|
|
67
|
+
if shouldCalculateTextAlignment(),
|
|
68
|
+
let layoutDirection = AppLanguageManager.shared.appLanguageLayoutDirection {
|
|
69
|
+
self.hasCalculatedTextAlignment = 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 AppLanguageManager.shared.shouldHorizontalFlip,
|
|
89
|
+
self.isIOSSDKView,
|
|
90
|
+
let layoutDirection = AppLanguageManager.shared.appLanguageLayoutDirection,
|
|
91
|
+
layoutDirection != .unsupported,
|
|
92
|
+
shouldUseCalculatedTextAlignment() {
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return false
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// UITextField+AppLanguage.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 hasCalculatedTextAlignment = "hasCalculatedTextAlignmentKey"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private var hasCalculatedTextAlignment: Bool {
|
|
15
|
+
get {
|
|
16
|
+
let result = objc_getAssociatedObject(self, &AssociatedKeys.hasCalculatedTextAlignment) as? Bool
|
|
17
|
+
return result ?? false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set {
|
|
21
|
+
objc_setAssociatedObject(
|
|
22
|
+
self,
|
|
23
|
+
&AssociatedKeys.hasCalculatedTextAlignment,
|
|
24
|
+
newValue,
|
|
25
|
+
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static func swizzleTextFieldMethodsForAppLanguage() {
|
|
31
|
+
Swizzle.swizzleSelector(cls: self,
|
|
32
|
+
originalSelector: #selector(setter: UITextField.textAlignment),
|
|
33
|
+
customSelector: #selector(UITextField.fw_setTextFieldTextAlignment(_:)))
|
|
34
|
+
Swizzle.swizzleSelector(cls: self,
|
|
35
|
+
originalSelector: #selector(UITextField.didMoveToWindow),
|
|
36
|
+
customSelector: #selector(UITextField.fw_textFieldDidMoveToWindow))
|
|
37
|
+
Swizzle.swizzleSelector(cls: self,
|
|
38
|
+
originalSelector: #selector(UITextField.removeFromSuperview),
|
|
39
|
+
customSelector: #selector(UITextField.fw_textFieldRemoveFromSuperview))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc func fw_setTextFieldTextAlignment(_ textAlignment: NSTextAlignment) {
|
|
43
|
+
addReloadClosure(key: "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.hasCalculatedTextAlignment,
|
|
56
|
+
self.isIOSSDKView {
|
|
57
|
+
self.textAlignment = self.textAlignment
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func fw_textFieldRemoveFromSuperview() {
|
|
62
|
+
fw_textFieldRemoveFromSuperview()
|
|
63
|
+
self.hasCalculatedTextAlignment = false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private func calculatedTextAlignment(_ textAlignment: NSTextAlignment) -> NSTextAlignment {
|
|
67
|
+
if shouldCalculateTextAlignment(),
|
|
68
|
+
let layoutDirection = AppLanguageManager.shared.appLanguageLayoutDirection {
|
|
69
|
+
self.hasCalculatedTextAlignment = 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 AppLanguageManager.shared.shouldHorizontalFlip,
|
|
89
|
+
self.isIOSSDKView,
|
|
90
|
+
let layoutDirection = AppLanguageManager.shared.appLanguageLayoutDirection,
|
|
91
|
+
layoutDirection != .unsupported {
|
|
92
|
+
return true
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
}
|