react-native-unistyles 2.8.0-beta.1 → 2.8.0-beta.3
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/CMakeLists.txt +8 -1
- package/android/build.gradle +4 -1
- package/android/src/main/cxx/cpp-adapter.cpp +10 -100
- package/android/src/main/cxx/helpers.h +2 -0
- package/android/src/main/cxx/platform.cpp +126 -0
- package/android/src/main/cxx/platform.h +15 -0
- package/android/src/main/java/com/unistyles/Models.kt +14 -35
- package/android/src/main/java/com/unistyles/Platform.kt +91 -10
- package/android/src/main/java/com/unistyles/UnistylesModule.kt +84 -139
- package/cxx/Macros.h +11 -0
- package/cxx/UnistylesImpl.cpp +241 -0
- package/cxx/UnistylesModel.cpp +234 -0
- package/cxx/UnistylesModel.h +112 -0
- package/cxx/UnistylesRuntime.cpp +17 -388
- package/cxx/UnistylesRuntime.h +56 -95
- package/ios/UnistylesModule.h +8 -0
- package/ios/UnistylesModule.mm +12 -89
- package/ios/platform/Platform_Shared.h +5 -0
- package/ios/platform/Platform_Shared.mm +69 -0
- package/ios/platform/Platform_iOS.h +2 -9
- package/ios/platform/Platform_iOS.mm +47 -94
- package/ios/platform/Platform_macOS.h +1 -6
- package/ios/platform/Platform_macOS.mm +29 -29
- package/ios/platform/Platform_tvOS.h +2 -9
- package/ios/platform/Platform_tvOS.mm +30 -92
- package/ios/platform/Platform_visionOS.h +2 -8
- package/ios/platform/Platform_visionOS.mm +28 -83
- package/package.json +1 -1
- package/react-native-unistyles.podspec +3 -0
- package/android/src/main/java/com/unistyles/Config.kt +0 -116
- package/android/src/main/java/com/unistyles/Insets.kt +0 -141
- package/ios/UnistylesHelpers.h +0 -3
- package/ios/UnistylesHelpers.mm +0 -5
@@ -1,7 +1,6 @@
|
|
1
1
|
#if TARGET_OS_TV
|
2
2
|
|
3
3
|
#import "Platform_tvOS.h"
|
4
|
-
#import "UnistylesRuntime.h"
|
5
4
|
#import <React/RCTAppearance.h>
|
6
5
|
|
7
6
|
@implementation Platform
|
@@ -9,15 +8,6 @@
|
|
9
8
|
- (instancetype)init {
|
10
9
|
self = [super init];
|
11
10
|
if (self) {
|
12
|
-
UIScreen *screen = [UIScreen mainScreen];
|
13
|
-
UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
|
14
|
-
|
15
|
-
self.initialScreen = {(int)screen.bounds.size.width, (int)screen.bounds.size.height};
|
16
|
-
self.initialColorScheme = [self getColorScheme];
|
17
|
-
self.initialContentSizeCategory = [self getContentSizeCategory:contentSizeCategory];
|
18
|
-
self.initialStatusBar = [self getStatusBarDimensions];
|
19
|
-
self.initialInsets = [self getInsets];
|
20
|
-
|
21
11
|
[self setupListeners];
|
22
12
|
}
|
23
13
|
return self;
|
@@ -47,101 +37,49 @@
|
|
47
37
|
object:nil];
|
48
38
|
}
|
49
39
|
|
50
|
-
- (void)
|
51
|
-
|
40
|
+
- (void)makeShared:(void*)runtime {
|
41
|
+
self.unistylesRuntime = runtime;
|
42
|
+
|
43
|
+
auto unistylesRuntime = ((UnistylesRuntime*)self.unistylesRuntime);
|
44
|
+
|
45
|
+
unistylesRuntime->setScreenDimensionsCallback([self](){
|
46
|
+
return [self getScreenDimensions];
|
47
|
+
});
|
52
48
|
|
53
|
-
|
54
|
-
(
|
55
|
-
}
|
49
|
+
unistylesRuntime->setColorSchemeCallback([](){
|
50
|
+
return getColorScheme();
|
51
|
+
});
|
52
|
+
|
53
|
+
unistylesRuntime->setContentSizeCategoryCallback([](){
|
54
|
+
return getContentSizeCategory();
|
55
|
+
});
|
56
|
+
|
57
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
58
|
+
unistylesRuntime->screen = [self getScreenDimensions];
|
59
|
+
unistylesRuntime->contentSizeCategory = getContentSizeCategory();
|
60
|
+
unistylesRuntime->colorScheme = getColorScheme();
|
61
|
+
});
|
56
62
|
}
|
57
63
|
|
58
|
-
- (void)
|
59
|
-
UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
|
60
|
-
|
64
|
+
- (void)onAppearanceChange:(NSNotification *)notification {
|
61
65
|
if (self.unistylesRuntime != nullptr) {
|
62
|
-
((UnistylesRuntime*)self.unistylesRuntime)->
|
66
|
+
((UnistylesRuntime*)self.unistylesRuntime)->handleAppearanceChange(getColorScheme());
|
63
67
|
}
|
64
68
|
}
|
65
69
|
|
66
|
-
- (
|
67
|
-
|
68
|
-
|
69
|
-
switch (colorScheme) {
|
70
|
-
case UIUserInterfaceStyleLight:
|
71
|
-
return UnistylesLightScheme;
|
72
|
-
case UIUserInterfaceStyleDark:
|
73
|
-
return UnistylesDarkScheme;
|
74
|
-
case UIUserInterfaceStyleUnspecified:
|
75
|
-
default:
|
76
|
-
return UnistylesUnspecifiedScheme;
|
70
|
+
- (void)onContentSizeCategoryChange:(NSNotification *)notification {
|
71
|
+
if (self.unistylesRuntime != nullptr) {
|
72
|
+
((UnistylesRuntime*)self.unistylesRuntime)->handleContentSizeCategoryChange(getContentSizeCategory());
|
77
73
|
}
|
78
74
|
}
|
79
75
|
|
80
|
-
- (
|
81
|
-
|
82
|
-
}
|
83
|
-
|
84
|
-
- (Dimensions)getStatusBarDimensions {
|
85
|
-
return {0, 0};
|
86
|
-
}
|
87
|
-
|
88
|
-
- (Dimensions)getNavigationBarDimensions {
|
89
|
-
return {0, 0};
|
90
|
-
}
|
91
|
-
|
92
|
-
- (std::string)getContentSizeCategory:(UIContentSizeCategory)contentSizeCategory {
|
93
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) {
|
94
|
-
return std::string([@"xxxLarge" UTF8String]);
|
95
|
-
}
|
96
|
-
|
97
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) {
|
98
|
-
return std::string([@"xxLarge" UTF8String]);
|
99
|
-
}
|
100
|
-
|
101
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraLarge]) {
|
102
|
-
return std::string([@"xLarge" UTF8String]);
|
103
|
-
}
|
104
|
-
|
105
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryLarge]) {
|
106
|
-
return std::string([@"Large" UTF8String]);
|
107
|
-
}
|
108
|
-
|
109
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryMedium]) {
|
110
|
-
return std::string([@"Medium" UTF8String]);
|
111
|
-
}
|
112
|
-
|
113
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategorySmall]) {
|
114
|
-
return std::string([@"Small" UTF8String]);
|
115
|
-
}
|
116
|
-
|
117
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraSmall]) {
|
118
|
-
return std::string([@"xSmall" UTF8String]);
|
119
|
-
}
|
76
|
+
- (Dimensions)getScreenDimensions {
|
77
|
+
UIScreen *screen = [UIScreen mainScreen];
|
78
|
+
Dimensions screenDimension = {(int)screen.bounds.size.width, (int)screen.bounds.size.height};
|
120
79
|
|
121
|
-
|
122
|
-
return std::string([@"accessibilityMedium" UTF8String]);
|
123
|
-
}
|
124
|
-
|
125
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityLarge]) {
|
126
|
-
return std::string([@"accessibilityLarge" UTF8String]);
|
127
|
-
}
|
128
|
-
|
129
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraLarge]) {
|
130
|
-
return std::string([@"accessibilityExtraLarge" UTF8String]);
|
131
|
-
}
|
132
|
-
|
133
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraLarge]) {
|
134
|
-
return std::string([@"accessibilityExtraExtraLarge" UTF8String]);
|
135
|
-
}
|
136
|
-
|
137
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraExtraLarge]) {
|
138
|
-
return std::string([@"accessibilityExtraExtraExtraLarge" UTF8String]);
|
139
|
-
}
|
140
|
-
|
141
|
-
return std::string([@"unspecified" UTF8String]);
|
80
|
+
return screenDimension;
|
142
81
|
}
|
143
82
|
|
144
83
|
@end
|
145
84
|
|
146
|
-
|
147
85
|
#endif
|
@@ -1,23 +1,17 @@
|
|
1
1
|
#include <string>
|
2
2
|
#include <map>
|
3
|
-
#include <UnistylesRuntime.h>
|
4
3
|
#import <UIKit/UIKit.h>
|
4
|
+
#import "Platform_Shared.h"
|
5
5
|
|
6
6
|
@interface Platform : NSObject
|
7
7
|
|
8
|
-
@property (nonatomic, assign) Dimensions initialScreen;
|
9
|
-
@property (nonatomic, assign) std::string initialColorScheme;
|
10
|
-
@property (nonatomic, assign) std::string initialContentSizeCategory;
|
11
|
-
@property (nonatomic, assign) Insets initialInsets;
|
12
|
-
@property (nonatomic, assign) Dimensions initialStatusBar;
|
13
|
-
@property (nonatomic, assign) Dimensions initialNavigationBar;
|
14
8
|
@property (nonatomic, assign) void* unistylesRuntime;
|
15
9
|
|
16
10
|
- (instancetype)init;
|
17
11
|
|
18
12
|
- (void)setupListeners;
|
13
|
+
- (void)makeShared:(void*)runtime;
|
19
14
|
- (UIWindow *)getMainWindow;
|
20
|
-
- (std::string)getContentSizeCategory:(UIContentSizeCategory)contentSizeCategory;
|
21
15
|
- (void)onContentSizeCategoryChange:(NSNotification *)notification;
|
22
16
|
- (void)onWindowChange:(NSNotification *)notification;
|
23
17
|
|
@@ -9,15 +9,6 @@
|
|
9
9
|
- (instancetype)init {
|
10
10
|
self = [super init];
|
11
11
|
if (self) {
|
12
|
-
UIWindow* mainWindow = [self getMainWindow];
|
13
|
-
UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
|
14
|
-
|
15
|
-
self.initialScreen = {(int)mainWindow.bounds.size.width, (int)mainWindow.bounds.size.height};
|
16
|
-
self.initialColorScheme = UnistylesUnspecifiedScheme;
|
17
|
-
self.initialContentSizeCategory = [self getContentSizeCategory:contentSizeCategory];
|
18
|
-
self.initialStatusBar = [self getStatusBarDimensions];
|
19
|
-
self.initialInsets = [self getInsets];
|
20
|
-
|
21
12
|
[self setupListeners];
|
22
13
|
}
|
23
14
|
return self;
|
@@ -68,97 +59,51 @@
|
|
68
59
|
object:nil];
|
69
60
|
}
|
70
61
|
|
71
|
-
- (void)
|
72
|
-
|
62
|
+
- (void)makeShared:(void*)runtime {
|
63
|
+
self.unistylesRuntime = runtime;
|
64
|
+
|
65
|
+
auto unistylesRuntime = ((UnistylesRuntime*)self.unistylesRuntime);
|
66
|
+
|
67
|
+
unistylesRuntime->setScreenDimensionsCallback([self](){
|
68
|
+
return [self getScreenDimensions];
|
69
|
+
});
|
70
|
+
|
71
|
+
unistylesRuntime->setContentSizeCategoryCallback([](){
|
72
|
+
return getContentSizeCategory();
|
73
|
+
});
|
74
|
+
|
75
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
76
|
+
unistylesRuntime->screen = [self getScreenDimensions];
|
77
|
+
unistylesRuntime->contentSizeCategory = getContentSizeCategory();
|
78
|
+
});
|
79
|
+
}
|
73
80
|
|
74
|
-
|
75
|
-
|
76
|
-
Dimensions statusBar = [self getStatusBarDimensions];
|
77
|
-
Dimensions navigationBar = [self getNavigationBarDimensions];
|
81
|
+
- (void)onWindowChange:(NSNotification *)notification {
|
82
|
+
Dimensions screen = [self getScreenDimensions];
|
78
83
|
|
79
84
|
if (self.unistylesRuntime != nullptr) {
|
80
85
|
((UnistylesRuntime*)self.unistylesRuntime)->handleScreenSizeChange(
|
81
86
|
screen,
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
std::nullopt,
|
88
|
+
std::nullopt,
|
89
|
+
std::nullopt
|
85
90
|
);
|
86
91
|
}
|
87
92
|
}
|
88
93
|
|
89
94
|
- (void)onContentSizeCategoryChange:(NSNotification *)notification {
|
90
|
-
UIContentSizeCategory contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory];
|
91
|
-
|
92
95
|
if (self.unistylesRuntime != nullptr) {
|
93
|
-
((UnistylesRuntime*)self.unistylesRuntime)->handleContentSizeCategoryChange(
|
96
|
+
((UnistylesRuntime*)self.unistylesRuntime)->handleContentSizeCategoryChange(getContentSizeCategory());
|
94
97
|
}
|
95
98
|
}
|
96
99
|
|
97
|
-
- (
|
98
|
-
|
99
|
-
}
|
100
|
-
|
101
|
-
- (Dimensions)getStatusBarDimensions {
|
102
|
-
return {0, 0};
|
103
|
-
}
|
104
|
-
|
105
|
-
- (Dimensions)getNavigationBarDimensions {
|
106
|
-
return {0, 0};
|
107
|
-
}
|
108
|
-
|
109
|
-
- (std::string)getContentSizeCategory:(UIContentSizeCategory)contentSizeCategory {
|
110
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraExtraLarge]) {
|
111
|
-
return std::string([@"xxxLarge" UTF8String]);
|
112
|
-
}
|
113
|
-
|
114
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraExtraLarge]) {
|
115
|
-
return std::string([@"xxLarge" UTF8String]);
|
116
|
-
}
|
117
|
-
|
118
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraLarge]) {
|
119
|
-
return std::string([@"xLarge" UTF8String]);
|
120
|
-
}
|
121
|
-
|
122
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryLarge]) {
|
123
|
-
return std::string([@"Large" UTF8String]);
|
124
|
-
}
|
125
|
-
|
126
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryMedium]) {
|
127
|
-
return std::string([@"Medium" UTF8String]);
|
128
|
-
}
|
129
|
-
|
130
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategorySmall]) {
|
131
|
-
return std::string([@"Small" UTF8String]);
|
132
|
-
}
|
133
|
-
|
134
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryExtraSmall]) {
|
135
|
-
return std::string([@"xSmall" UTF8String]);
|
136
|
-
}
|
137
|
-
|
138
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityMedium]) {
|
139
|
-
return std::string([@"accessibilityMedium" UTF8String]);
|
140
|
-
}
|
141
|
-
|
142
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityLarge]) {
|
143
|
-
return std::string([@"accessibilityLarge" UTF8String]);
|
144
|
-
}
|
145
|
-
|
146
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraLarge]) {
|
147
|
-
return std::string([@"accessibilityExtraLarge" UTF8String]);
|
148
|
-
}
|
149
|
-
|
150
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraLarge]) {
|
151
|
-
return std::string([@"accessibilityExtraExtraLarge" UTF8String]);
|
152
|
-
}
|
153
|
-
|
154
|
-
if ([contentSizeCategory isEqualToString:UIContentSizeCategoryAccessibilityExtraExtraExtraLarge]) {
|
155
|
-
return std::string([@"accessibilityExtraExtraExtraLarge" UTF8String]);
|
156
|
-
}
|
100
|
+
- (Dimensions)getScreenDimensions {
|
101
|
+
UIWindow* mainWindow = [self getMainWindow];
|
102
|
+
Dimensions screenDimension = {(int)mainWindow.frame.size.width, (int)mainWindow.frame.size.height};
|
157
103
|
|
158
|
-
return
|
104
|
+
return screenDimension;
|
159
105
|
}
|
160
106
|
|
161
107
|
@end
|
162
108
|
|
163
|
-
|
164
109
|
#endif
|
package/package.json
CHANGED
@@ -1,116 +0,0 @@
|
|
1
|
-
package com.unistyles
|
2
|
-
|
3
|
-
import android.annotation.SuppressLint
|
4
|
-
import android.content.res.Configuration
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
6
|
-
|
7
|
-
class UnistylesConfig(private val reactApplicationContext: ReactApplicationContext) {
|
8
|
-
private val insets: UnistylesInsets = UnistylesInsets(reactApplicationContext)
|
9
|
-
private val density: Float = reactApplicationContext.resources.displayMetrics.density
|
10
|
-
private var lastConfig: Config = this.getAppConfig()
|
11
|
-
private var lastLayoutConfig: LayoutConfig = this.getAppLayoutConfig()
|
12
|
-
|
13
|
-
fun hasNewConfig(): Boolean {
|
14
|
-
val newConfig = this.getAppConfig()
|
15
|
-
val newContentSizeCategory = newConfig.contentSizeCategory != lastConfig.contentSizeCategory
|
16
|
-
val newColorScheme = newConfig.colorScheme != lastConfig.colorScheme
|
17
|
-
|
18
|
-
if (!newContentSizeCategory && !newColorScheme) {
|
19
|
-
return false
|
20
|
-
}
|
21
|
-
|
22
|
-
lastConfig = newConfig
|
23
|
-
lastConfig.hasNewContentSizeCategory = newContentSizeCategory
|
24
|
-
lastConfig.hasNewColorScheme = newColorScheme
|
25
|
-
|
26
|
-
return true
|
27
|
-
}
|
28
|
-
|
29
|
-
fun hasNewLayoutConfig(): Boolean {
|
30
|
-
val newConfig = this.getAppLayoutConfig()
|
31
|
-
|
32
|
-
if (newConfig.isEqual(lastLayoutConfig)) {
|
33
|
-
return false
|
34
|
-
}
|
35
|
-
|
36
|
-
lastLayoutConfig = newConfig
|
37
|
-
|
38
|
-
return true
|
39
|
-
}
|
40
|
-
|
41
|
-
fun getConfig(): Config {
|
42
|
-
return this.lastConfig
|
43
|
-
}
|
44
|
-
|
45
|
-
fun getLayoutConfig(): LayoutConfig {
|
46
|
-
return this.lastLayoutConfig
|
47
|
-
}
|
48
|
-
|
49
|
-
private fun getAppConfig(): Config {
|
50
|
-
val fontScale = reactApplicationContext.resources.configuration.fontScale
|
51
|
-
|
52
|
-
return Config(
|
53
|
-
this.getColorScheme(),
|
54
|
-
this.getContentSizeCategory(fontScale),
|
55
|
-
)
|
56
|
-
}
|
57
|
-
|
58
|
-
private fun getAppLayoutConfig(): LayoutConfig {
|
59
|
-
val displayMetrics = reactApplicationContext.resources.displayMetrics
|
60
|
-
val screenWidth = (displayMetrics.widthPixels / density).toInt()
|
61
|
-
val screenHeight = (displayMetrics.heightPixels / density).toInt()
|
62
|
-
|
63
|
-
return LayoutConfig(
|
64
|
-
Dimensions(screenWidth, screenHeight),
|
65
|
-
this.insets.get(),
|
66
|
-
Dimensions(screenWidth, getStatusBarHeight()),
|
67
|
-
Dimensions(screenWidth, getNavigationBarHeight())
|
68
|
-
)
|
69
|
-
}
|
70
|
-
|
71
|
-
private fun getContentSizeCategory(fontScale: Float): String {
|
72
|
-
val contentSizeCategory = when {
|
73
|
-
fontScale <= 0.85f -> "Small"
|
74
|
-
fontScale <= 1.0f -> "Default"
|
75
|
-
fontScale <= 1.15f -> "Large"
|
76
|
-
fontScale <= 1.3f -> "ExtraLarge"
|
77
|
-
fontScale <= 1.5f -> "Huge"
|
78
|
-
fontScale <= 1.8 -> "ExtraHuge"
|
79
|
-
else -> "ExtraExtraHuge"
|
80
|
-
}
|
81
|
-
|
82
|
-
return contentSizeCategory
|
83
|
-
}
|
84
|
-
|
85
|
-
private fun getColorScheme(): String {
|
86
|
-
val colorScheme = when (reactApplicationContext.resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) {
|
87
|
-
Configuration.UI_MODE_NIGHT_YES -> "dark"
|
88
|
-
Configuration.UI_MODE_NIGHT_NO -> "light"
|
89
|
-
else -> "unspecified"
|
90
|
-
}
|
91
|
-
|
92
|
-
return colorScheme
|
93
|
-
}
|
94
|
-
|
95
|
-
@SuppressLint("InternalInsetResource", "DiscouragedApi")
|
96
|
-
private fun getStatusBarHeight(): Int {
|
97
|
-
val heightResId = reactApplicationContext.resources.getIdentifier("status_bar_height", "dimen", "android")
|
98
|
-
|
99
|
-
if (heightResId > 0) {
|
100
|
-
return (reactApplicationContext.resources.getDimensionPixelSize(heightResId) / density).toInt()
|
101
|
-
}
|
102
|
-
|
103
|
-
return 0
|
104
|
-
}
|
105
|
-
|
106
|
-
@SuppressLint("InternalInsetResource", "DiscouragedApi")
|
107
|
-
private fun getNavigationBarHeight(): Int {
|
108
|
-
val heightResId = reactApplicationContext.resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
109
|
-
|
110
|
-
if (heightResId > 0) {
|
111
|
-
return (reactApplicationContext.resources.getDimensionPixelSize(heightResId) / density).toInt()
|
112
|
-
}
|
113
|
-
|
114
|
-
return 0
|
115
|
-
}
|
116
|
-
}
|
@@ -1,141 +0,0 @@
|
|
1
|
-
package com.unistyles
|
2
|
-
|
3
|
-
import android.content.Context
|
4
|
-
import android.graphics.Rect
|
5
|
-
import android.os.Build
|
6
|
-
import android.view.View
|
7
|
-
import android.view.Window
|
8
|
-
import android.view.WindowInsets
|
9
|
-
import android.view.WindowManager
|
10
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
11
|
-
import kotlin.math.roundToInt
|
12
|
-
|
13
|
-
class UnistylesInsets(private val reactApplicationContext: ReactApplicationContext) {
|
14
|
-
private val density: Float = reactApplicationContext.resources.displayMetrics.density
|
15
|
-
|
16
|
-
fun get(): Insets {
|
17
|
-
return this.getCurrentInsets()
|
18
|
-
}
|
19
|
-
|
20
|
-
private fun getCurrentInsets(): Insets {
|
21
|
-
val baseInsets = this.getBaseInsets()
|
22
|
-
val statusBarTranslucent = this.hasTranslucentStatusBar() ?: return baseInsets
|
23
|
-
val window = reactApplicationContext.currentActivity?.window ?: return baseInsets
|
24
|
-
val shouldModifyLandscapeInsets = this.forceLandscapeInsets(baseInsets, window)
|
25
|
-
|
26
|
-
val topInset = this.getTopInset(baseInsets, statusBarTranslucent, window)
|
27
|
-
val bottomInset = this.getBottomInset(baseInsets, window)
|
28
|
-
val leftInset = if (shouldModifyLandscapeInsets) 0 else baseInsets.left
|
29
|
-
val rightInset = if (shouldModifyLandscapeInsets) 0 else baseInsets.right
|
30
|
-
|
31
|
-
return Insets(topInset, bottomInset, leftInset, rightInset)
|
32
|
-
}
|
33
|
-
|
34
|
-
@Suppress("DEPRECATION")
|
35
|
-
private fun getBaseInsets(): Insets {
|
36
|
-
// this is the best API, but it's available from Android 11
|
37
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
38
|
-
val windowManager = reactApplicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
39
|
-
val systemBarsInsets = windowManager.currentWindowMetrics.windowInsets.getInsets(WindowInsets.Type.systemBars())
|
40
|
-
|
41
|
-
val top = (systemBarsInsets.top / density).roundToInt()
|
42
|
-
val bottom = (systemBarsInsets.bottom / density).roundToInt()
|
43
|
-
val left = (systemBarsInsets.left / density).roundToInt()
|
44
|
-
val right = (systemBarsInsets.right / density).roundToInt()
|
45
|
-
|
46
|
-
return Insets(top, bottom, left, right)
|
47
|
-
}
|
48
|
-
|
49
|
-
// available from Android 6.0
|
50
|
-
val window = reactApplicationContext.currentActivity?.window ?: return Insets(0, 0, 0, 0)
|
51
|
-
val systemInsets = window.decorView.rootWindowInsets ?: return Insets(0, 0, 0, 0)
|
52
|
-
|
53
|
-
val top = (systemInsets.systemWindowInsetTop / density).roundToInt()
|
54
|
-
val bottom = (systemInsets.systemWindowInsetBottom / density).roundToInt()
|
55
|
-
val left = (systemInsets.systemWindowInsetLeft / density).roundToInt()
|
56
|
-
val right = (systemInsets.systemWindowInsetRight / density).roundToInt()
|
57
|
-
|
58
|
-
return Insets(top, bottom, left, right)
|
59
|
-
}
|
60
|
-
|
61
|
-
// this function helps to detect statusBar translucent, as React Native is using weird API instead of windows flags
|
62
|
-
private fun hasTranslucentStatusBar(): Boolean? {
|
63
|
-
val window = reactApplicationContext.currentActivity?.window ?: return null
|
64
|
-
val contentView = window.decorView.findViewById<View>(android.R.id.content) ?: return null
|
65
|
-
val decorViewLocation = IntArray(2)
|
66
|
-
val contentViewLocation = IntArray(2)
|
67
|
-
|
68
|
-
// decor view is a top level view with navigationBar and statusBar
|
69
|
-
window.decorView.getLocationOnScreen(decorViewLocation)
|
70
|
-
// content view is view without navigationBar and statusBar
|
71
|
-
contentView.getLocationOnScreen(contentViewLocation)
|
72
|
-
|
73
|
-
val statusBarHeight = contentViewLocation[1] - decorViewLocation[1]
|
74
|
-
|
75
|
-
// if positions are the same, then the status bar is translucent
|
76
|
-
return statusBarHeight == 0
|
77
|
-
}
|
78
|
-
|
79
|
-
private fun getTopInset(baseInsets: Insets, statusBarTranslucent: Boolean, window: Window): Int {
|
80
|
-
if (!statusBarTranslucent) {
|
81
|
-
return 0
|
82
|
-
}
|
83
|
-
|
84
|
-
return baseInsets.top
|
85
|
-
}
|
86
|
-
|
87
|
-
@Suppress("DEPRECATION")
|
88
|
-
private fun getBottomInset(baseInsets: Insets, window: Window): Int {
|
89
|
-
val translucentNavigation = hasTranslucentNavigation(window)
|
90
|
-
val fullScreenMode = hasFullScreenMode(window)
|
91
|
-
|
92
|
-
// Android 11 has inconsistent FLAG_LAYOUT_NO_LIMITS, which alone does nothing
|
93
|
-
// https://stackoverflow.com/questions/64153785/android-11-window-setdecorfitssystemwindow-doesnt-show-screen-behind-status-a
|
94
|
-
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
|
95
|
-
if ((fullScreenMode && translucentNavigation) || translucentNavigation) {
|
96
|
-
return baseInsets.bottom
|
97
|
-
}
|
98
|
-
|
99
|
-
return 0
|
100
|
-
}
|
101
|
-
|
102
|
-
return if (translucentNavigation || fullScreenMode) baseInsets.bottom else 0
|
103
|
-
}
|
104
|
-
|
105
|
-
private fun forceLandscapeInsets(baseInsets: Insets, window: Window): Boolean {
|
106
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
107
|
-
return false
|
108
|
-
}
|
109
|
-
|
110
|
-
val displayMetrics = reactApplicationContext.resources.displayMetrics
|
111
|
-
val isLandscape = displayMetrics.widthPixels > displayMetrics.heightPixels
|
112
|
-
|
113
|
-
if (!isLandscape) {
|
114
|
-
return false
|
115
|
-
}
|
116
|
-
|
117
|
-
val contentView = window.decorView.findViewById<View>(android.R.id.content) ?: return false
|
118
|
-
val visibleRect = Rect()
|
119
|
-
val drawingRect = Rect()
|
120
|
-
|
121
|
-
window.decorView.getGlobalVisibleRect(visibleRect)
|
122
|
-
contentView.getDrawingRect(drawingRect)
|
123
|
-
|
124
|
-
// width is equal to navigationBarHeight + statusBarHeight (in landscape)
|
125
|
-
val width = ((visibleRect.width() - contentView.width) / density).roundToInt()
|
126
|
-
|
127
|
-
// we should correct landscape if insets are equal to width
|
128
|
-
return (baseInsets.left + baseInsets.right) == width
|
129
|
-
}
|
130
|
-
|
131
|
-
@Suppress("DEPRECATION")
|
132
|
-
private fun hasTranslucentNavigation(window: Window): Boolean {
|
133
|
-
return (window.attributes.flags and WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
|
134
|
-
}
|
135
|
-
|
136
|
-
private fun hasFullScreenMode(window: Window): Boolean {
|
137
|
-
val decorFitsSystemWindows = window.decorView.fitsSystemWindows
|
138
|
-
|
139
|
-
return (window.attributes.flags and WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) == WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS || !decorFitsSystemWindows
|
140
|
-
}
|
141
|
-
}
|
package/ios/UnistylesHelpers.h
DELETED