react-native-unistyles 2.8.0-beta.4 → 2.8.0-rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. package/android/src/main/cxx/cpp-adapter.cpp +1 -1
  2. package/android/src/main/cxx/helpers.cpp +61 -0
  3. package/android/src/main/cxx/helpers.h +5 -0
  4. package/android/src/main/cxx/platform.cpp +51 -41
  5. package/android/src/main/cxx/platform.h +7 -4
  6. package/android/src/main/java/com/unistyles/Models.kt +13 -50
  7. package/android/src/main/java/com/unistyles/Platform.kt +175 -40
  8. package/android/src/main/java/com/unistyles/UnistylesModule.kt +17 -87
  9. package/cxx/UnistylesImpl.cpp +57 -2
  10. package/cxx/UnistylesModel.cpp +6 -2
  11. package/cxx/UnistylesModel.h +34 -8
  12. package/cxx/UnistylesRuntime.h +9 -1
  13. package/ios/platform/Platform_Shared.h +2 -0
  14. package/ios/platform/Platform_Shared.mm +84 -1
  15. package/ios/platform/Platform_iOS.h +2 -0
  16. package/ios/platform/Platform_iOS.mm +57 -14
  17. package/lib/commonjs/core/UnistylesModule.js +17 -2
  18. package/lib/commonjs/core/UnistylesModule.js.map +1 -1
  19. package/lib/commonjs/core/UnistylesRuntime.js +65 -4
  20. package/lib/commonjs/core/UnistylesRuntime.js.map +1 -1
  21. package/lib/commonjs/core/mocks/UnistylesMockedBridge.js +4 -0
  22. package/lib/commonjs/core/mocks/UnistylesMockedBridge.js.map +1 -1
  23. package/lib/commonjs/core/mocks/UnistylesMockedRuntime.js +12 -2
  24. package/lib/commonjs/core/mocks/UnistylesMockedRuntime.js.map +1 -1
  25. package/lib/commonjs/types/color.js +2 -0
  26. package/lib/commonjs/types/color.js.map +1 -0
  27. package/lib/commonjs/types/index.js +11 -0
  28. package/lib/commonjs/types/index.js.map +1 -1
  29. package/lib/commonjs/useStyles.js +1 -1
  30. package/lib/commonjs/useStyles.js.map +1 -1
  31. package/lib/commonjs/utils/index.js +7 -0
  32. package/lib/commonjs/utils/index.js.map +1 -1
  33. package/lib/commonjs/utils/parseColor.js +30 -0
  34. package/lib/commonjs/utils/parseColor.js.map +1 -0
  35. package/lib/module/core/UnistylesModule.js +17 -2
  36. package/lib/module/core/UnistylesModule.js.map +1 -1
  37. package/lib/module/core/UnistylesRuntime.js +66 -4
  38. package/lib/module/core/UnistylesRuntime.js.map +1 -1
  39. package/lib/module/core/index.js +2 -1
  40. package/lib/module/core/index.js.map +1 -1
  41. package/lib/module/core/mocks/UnistylesMockedBridge.js +4 -0
  42. package/lib/module/core/mocks/UnistylesMockedBridge.js.map +1 -1
  43. package/lib/module/core/mocks/UnistylesMockedRuntime.js +12 -2
  44. package/lib/module/core/mocks/UnistylesMockedRuntime.js.map +1 -1
  45. package/lib/module/types/color.js +2 -0
  46. package/lib/module/types/color.js.map +1 -0
  47. package/lib/module/types/index.js +1 -0
  48. package/lib/module/types/index.js.map +1 -1
  49. package/lib/module/useStyles.js +1 -1
  50. package/lib/module/useStyles.js.map +1 -1
  51. package/lib/module/utils/index.js +1 -0
  52. package/lib/module/utils/index.js.map +1 -1
  53. package/lib/module/utils/parseColor.js +23 -0
  54. package/lib/module/utils/parseColor.js.map +1 -0
  55. package/lib/typescript/src/core/UnistylesModule.d.ts +1 -0
  56. package/lib/typescript/src/core/UnistylesModule.d.ts.map +1 -1
  57. package/lib/typescript/src/core/UnistylesRuntime.d.ts +52 -5
  58. package/lib/typescript/src/core/UnistylesRuntime.d.ts.map +1 -1
  59. package/lib/typescript/src/core/index.d.ts +3 -1
  60. package/lib/typescript/src/core/index.d.ts.map +1 -1
  61. package/lib/typescript/src/core/mocks/UnistylesMockedBridge.d.ts +4 -0
  62. package/lib/typescript/src/core/mocks/UnistylesMockedBridge.d.ts.map +1 -1
  63. package/lib/typescript/src/core/mocks/UnistylesMockedRuntime.d.ts +7 -1
  64. package/lib/typescript/src/core/mocks/UnistylesMockedRuntime.d.ts.map +1 -1
  65. package/lib/typescript/src/index.d.ts +2 -2
  66. package/lib/typescript/src/index.d.ts.map +1 -1
  67. package/lib/typescript/src/types/breakpoints.d.ts +2 -2
  68. package/lib/typescript/src/types/breakpoints.d.ts.map +1 -1
  69. package/lib/typescript/src/types/color.d.ts +4 -0
  70. package/lib/typescript/src/types/color.d.ts.map +1 -0
  71. package/lib/typescript/src/types/index.d.ts +1 -0
  72. package/lib/typescript/src/types/index.d.ts.map +1 -1
  73. package/lib/typescript/src/types/stylesheet.d.ts +2 -2
  74. package/lib/typescript/src/types/stylesheet.d.ts.map +1 -1
  75. package/lib/typescript/src/types/unistyles.d.ts +8 -2
  76. package/lib/typescript/src/types/unistyles.d.ts.map +1 -1
  77. package/lib/typescript/src/utils/index.d.ts +1 -0
  78. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  79. package/lib/typescript/src/utils/parseColor.d.ts +3 -0
  80. package/lib/typescript/src/utils/parseColor.d.ts.map +1 -0
  81. package/package.json +1 -1
  82. package/src/core/UnistylesModule.ts +19 -3
  83. package/src/core/UnistylesRuntime.ts +67 -5
  84. package/src/core/index.ts +7 -1
  85. package/src/core/mocks/UnistylesMockedBridge.ts +4 -0
  86. package/src/core/mocks/UnistylesMockedRuntime.ts +15 -3
  87. package/src/index.ts +3 -2
  88. package/src/types/breakpoints.ts +2 -2
  89. package/src/types/color.ts +26 -0
  90. package/src/types/index.ts +1 -0
  91. package/src/types/stylesheet.ts +2 -2
  92. package/src/types/unistyles.ts +10 -4
  93. package/src/useStyles.ts +1 -1
  94. package/src/utils/index.ts +1 -0
  95. package/src/utils/parseColor.ts +27 -0
@@ -45,7 +45,7 @@ extern "C"
45
45
  JNIEXPORT void JNICALL
46
46
  Java_com_unistyles_UnistylesModule_nativeOnOrientationChange(JNIEnv *env, jobject thiz, jobject screen, jobject insets, jobject statusBar, jobject navigationBar) {
47
47
  if (unistylesRuntime != nullptr) {
48
- Dimensions screenDimensions = jobjectToDimensions(env, screen);
48
+ Screen screenDimensions = jobjectToScreen(env, screen);
49
49
  Dimensions statusBarDimensions = jobjectToDimensions(env, statusBar);
50
50
  Insets screenInsets = jobjectToInsets(env, insets);
51
51
  Dimensions navigationBarDimensions = jobjectToDimensions(env, navigationBar);
@@ -14,6 +14,23 @@ Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj) {
14
14
  return Dimensions{width, height};
15
15
  }
16
16
 
17
+ Screen jobjectToScreen(JNIEnv *env, jobject screenObj) {
18
+ jclass screenClass = env->FindClass("com/unistyles/Screen");
19
+ jfieldID widthFieldID = env->GetFieldID(screenClass, "width", "I");
20
+ jfieldID heightFieldID = env->GetFieldID(screenClass, "height", "I");
21
+ jfieldID pixelRatioFieldID = env->GetFieldID(screenClass, "pixelRatio", "F");
22
+ jfieldID scaleFieldID = env->GetFieldID(screenClass, "fontScale", "F");
23
+
24
+ int width = env->GetIntField(screenObj, widthFieldID);
25
+ int height = env->GetIntField(screenObj, heightFieldID);
26
+ float pixelRatio = env->GetFloatField(screenObj, pixelRatioFieldID);
27
+ float fontScale = env->GetFloatField(screenObj, scaleFieldID);
28
+
29
+ env->DeleteLocalRef(screenClass);
30
+
31
+ return Screen{width, height, pixelRatio, fontScale};
32
+ }
33
+
17
34
  Insets jobjectToInsets(JNIEnv *env, jobject insetsObj) {
18
35
  jclass insetsClass = env->FindClass("com/unistyles/Insets");
19
36
  jfieldID leftFieldID = env->GetFieldID(insetsClass, "left", "I");
@@ -31,6 +48,50 @@ Insets jobjectToInsets(JNIEnv *env, jobject insetsObj) {
31
48
  return Insets{top, bottom, left, right};
32
49
  }
33
50
 
51
+ void JNI_callPlatformWithColor(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, std::string param, float alpha) {
52
+ jclass cls = env->GetObjectClass(unistylesModule);
53
+ jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
54
+ jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
55
+ jclass platformClass = env->GetObjectClass(platformInstance);
56
+ jstring strParam = env->NewStringUTF(param.c_str());
57
+ jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
58
+
59
+ env->CallVoidMethod(platformInstance, methodId, strParam, static_cast<jfloat>(alpha));
60
+
61
+ env->DeleteLocalRef(cls);
62
+ env->DeleteLocalRef(platformInstance);
63
+ env->DeleteLocalRef(platformClass);
64
+ env->DeleteLocalRef(strParam);
65
+ }
66
+
67
+ void JNI_callPlatformWithBool(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, bool param) {
68
+ jclass cls = env->GetObjectClass(unistylesModule);
69
+ jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
70
+ jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
71
+ jclass platformClass = env->GetObjectClass(platformInstance);
72
+ jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
73
+
74
+ env->CallVoidMethod(platformInstance, methodId, param);
75
+ env->DeleteLocalRef(cls);
76
+ env->DeleteLocalRef(platformInstance);
77
+ env->DeleteLocalRef(platformClass);
78
+ }
79
+
80
+ jobject JNI_callPlatform(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig) {
81
+ jclass cls = env->GetObjectClass(unistylesModule);
82
+ jfieldID platformFieldId = env->GetFieldID(cls, "platform", "Lcom/unistyles/Platform;");
83
+ jobject platformInstance = env->GetObjectField(unistylesModule, platformFieldId);
84
+ jclass platformClass = env->GetObjectClass(platformInstance);
85
+ jmethodID methodId = env->GetMethodID(platformClass, name.c_str(), sig.c_str());
86
+ jobject result = env->CallObjectMethod(platformInstance, methodId);
87
+
88
+ env->DeleteLocalRef(cls);
89
+ env->DeleteLocalRef(platformInstance);
90
+ env->DeleteLocalRef(platformClass);
91
+
92
+ return result;
93
+ }
94
+
34
95
  void throwKotlinException(
35
96
  JNIEnv *env,
36
97
  const char *message
@@ -6,6 +6,11 @@
6
6
  #include <UnistylesRuntime.h>
7
7
 
8
8
  Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj);
9
+ Screen jobjectToScreen(JNIEnv *env, jobject screenObj);
9
10
  Insets jobjectToInsets(JNIEnv *env, jobject insetsObj);
10
11
 
12
+ void JNI_callPlatformWithColor(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, std::string param, float alpha);
13
+ jobject JNI_callPlatform(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig);
14
+ void JNI_callPlatformWithBool(JNIEnv *env, jobject unistylesModule, std::string name, std::string sig, bool param);
15
+
11
16
  void throwKotlinException(JNIEnv *env, const char *message);
@@ -25,102 +25,112 @@ void makeShared(JNIEnv *env, jobject unistylesModule, std::shared_ptr<UnistylesR
25
25
  return getContentSizeCategory(env, unistylesModule);
26
26
  });
27
27
 
28
- unistylesRuntime->setNavigationBarColorCallback([=](const std::string &color) {
29
- setNavigationBarColor(env, unistylesModule, color);
28
+ unistylesRuntime->setNavigationBarColorCallback([=](const std::string &color, float alpha) {
29
+ setNavigationBarColor(env, unistylesModule, color, alpha);
30
30
  });
31
31
 
32
- unistylesRuntime->setStatusBarColorCallback([=](const std::string &color) {
33
- setStatusBarColor(env, unistylesModule, color);
32
+ unistylesRuntime->setStatusBarColorCallback([=](const std::string &color, float alpha) {
33
+ setStatusBarColor(env, unistylesModule, color, alpha);
34
34
  });
35
35
 
36
- unistylesRuntime->screen = getScreenDimensions(env, unistylesModule);
36
+ unistylesRuntime->setNavigationBarHiddenCallback([=](bool hidden) {
37
+ setNavigationBarHidden(env, unistylesModule, hidden);
38
+ });
39
+
40
+ unistylesRuntime->setStatusBarHiddenCallback([=](bool hidden) {
41
+ setStatusBarHidden(env, unistylesModule, hidden);
42
+ });
43
+
44
+ unistylesRuntime->setImmersiveModeCallback([=](bool enabled) {
45
+ setImmersiveMode(env, unistylesModule, enabled);
46
+ });
47
+
48
+ unistylesRuntime->setRootViewBackgroundColorCallback([=](const std::string &color, float alpha) {
49
+ setRootViewBackgroundColor(env, unistylesModule, color, alpha);
50
+ });
51
+
52
+ Screen screen = getScreenDimensions(env, unistylesModule);
53
+
54
+ unistylesRuntime->screen = Dimensions{screen.width, screen.height};
37
55
  unistylesRuntime->contentSizeCategory = getContentSizeCategory(env, unistylesModule);
38
56
  unistylesRuntime->colorScheme = getColorScheme(env, unistylesModule);
39
57
  unistylesRuntime->statusBar = getStatusBarDimensions(env, unistylesModule);
40
58
  unistylesRuntime->insets = getInsets(env, unistylesModule);
41
59
  unistylesRuntime->navigationBar = getNavigationBarDimensions(env, unistylesModule);
60
+ unistylesRuntime->fontScale = screen.fontScale;
61
+ unistylesRuntime->pixelRatio = screen.pixelRatio;
42
62
  }
43
63
 
44
- Dimensions getScreenDimensions(JNIEnv *env, jobject unistylesModule) {
45
- jclass cls = env->GetObjectClass(unistylesModule);
46
- jmethodID methodId = env->GetMethodID(cls, "getScreenDimensions", "()Lcom/unistyles/Dimensions;");
47
- jobject dimensionsObj = env->CallObjectMethod(unistylesModule, methodId);
48
- Dimensions screenDimensions = jobjectToDimensions(env, dimensionsObj);
64
+ Screen getScreenDimensions(JNIEnv *env, jobject unistylesModule) {
65
+ jobject result = JNI_callPlatform(env, unistylesModule, "getScreenDimensions", "()Lcom/unistyles/Screen;");
66
+ Screen screenDimensions = jobjectToScreen(env, result);
49
67
 
50
68
  return screenDimensions;
51
69
  }
52
70
 
53
71
  std::string getColorScheme(JNIEnv *env, jobject unistylesModule) {
54
- jclass cls = env->GetObjectClass(unistylesModule);
55
- jmethodID methodId = env->GetMethodID(cls, "getColorScheme", "()Ljava/lang/String;");
56
- jstring colorScheme = (jstring) env->CallObjectMethod(unistylesModule, methodId);
72
+ jstring colorScheme = (jstring) JNI_callPlatform(env, unistylesModule, "getColorScheme", "()Ljava/lang/String;");
57
73
  const char *colorSchemeChars = env->GetStringUTFChars(colorScheme, nullptr);
58
74
  std::string colorSchemeStr = std::string(colorSchemeChars);
59
75
 
60
76
  env->ReleaseStringUTFChars(colorScheme, colorSchemeChars);
61
77
  env->DeleteLocalRef(colorScheme);
62
- env->DeleteLocalRef(cls);
63
78
 
64
79
  return colorSchemeStr;
65
80
  }
66
81
 
67
82
  Dimensions getStatusBarDimensions(JNIEnv *env, jobject unistylesModule) {
68
- jclass cls = env->GetObjectClass(unistylesModule);
69
- jmethodID methodId = env->GetMethodID(cls, "getStatusBarDimensions", "()Lcom/unistyles/Dimensions;");
70
- jobject dimensionsObj = env->CallObjectMethod(unistylesModule, methodId);
83
+ jobject dimensionsObj = JNI_callPlatform(env, unistylesModule, "getStatusBarDimensions", "()Lcom/unistyles/Dimensions;");
71
84
  Dimensions statusBarDimensions = jobjectToDimensions(env, dimensionsObj);
72
85
 
73
86
  return statusBarDimensions;
74
87
  }
75
88
 
76
89
  Dimensions getNavigationBarDimensions(JNIEnv *env, jobject unistylesModule) {
77
- jclass cls = env->GetObjectClass(unistylesModule);
78
- jmethodID methodId = env->GetMethodID(cls, "getNavigationBarDimensions", "()Lcom/unistyles/Dimensions;");
79
- jobject dimensionsObj = env->CallObjectMethod(unistylesModule, methodId);
90
+ jobject dimensionsObj = JNI_callPlatform(env, unistylesModule, "getNavigationBarDimensions", "()Lcom/unistyles/Dimensions;");
80
91
  Dimensions navigationBarDimensions = jobjectToDimensions(env, dimensionsObj);
81
92
 
82
93
  return navigationBarDimensions;
83
94
  }
84
95
 
85
96
  Insets getInsets(JNIEnv *env, jobject unistylesModule) {
86
- jclass cls = env->GetObjectClass(unistylesModule);
87
- jmethodID methodId = env->GetMethodID(cls, "getInsets", "()Lcom/unistyles/Insets;");
88
- jobject insetsObj = env->CallObjectMethod(unistylesModule, methodId);
97
+ jobject insetsObj = JNI_callPlatform(env, unistylesModule, "getInsets", "()Lcom/unistyles/Insets;");
89
98
  Insets insets = jobjectToInsets(env, insetsObj);
90
99
 
91
100
  return insets;
92
101
  }
93
102
 
94
103
  std::string getContentSizeCategory(JNIEnv *env, jobject unistylesModule) {
95
- jclass cls = env->GetObjectClass(unistylesModule);
96
- jmethodID methodId = env->GetMethodID(cls, "getContentSizeCategory", "()Ljava/lang/String;");
97
- jstring contentSizeCategory = (jstring) env->CallObjectMethod(unistylesModule, methodId);
104
+ jstring contentSizeCategory = (jstring) JNI_callPlatform(env, unistylesModule, "getContentSizeCategory", "()Ljava/lang/String;");
98
105
  const char *contentSizeCategoryChars = env->GetStringUTFChars(contentSizeCategory, nullptr);
99
106
  std::string contentSizeCategoryStr = std::string(contentSizeCategoryChars);
100
107
 
101
108
  env->ReleaseStringUTFChars(contentSizeCategory, contentSizeCategoryChars);
102
109
  env->DeleteLocalRef(contentSizeCategory);
103
- env->DeleteLocalRef(cls);
104
110
 
105
111
  return contentSizeCategoryStr;
106
112
  }
107
113
 
108
- void setStatusBarColor(JNIEnv *env, jobject unistylesModule, std::string color) {
109
- jstring colorStr = env->NewStringUTF(color.c_str());
110
- jclass cls = env->GetObjectClass(unistylesModule);
111
- jmethodID methodId = env->GetMethodID(cls, "onSetStatusBarColor", "(Ljava/lang/String;)V");
114
+ void setStatusBarColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha) {
115
+ JNI_callPlatformWithColor(env, unistylesModule, "onSetStatusBarColor", "(Ljava/lang/String;F)V", color, alpha);
116
+ }
117
+
118
+ void setNavigationBarColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha) {
119
+ JNI_callPlatformWithColor(env, unistylesModule, "onSetNavigationBarColor", "(Ljava/lang/String;F)V", color, alpha);
120
+ }
112
121
 
113
- env->CallVoidMethod(unistylesModule, methodId, colorStr);
114
- env->DeleteLocalRef(colorStr);
115
- env->DeleteLocalRef(cls);
122
+ void setNavigationBarHidden(JNIEnv *env, jobject unistylesModule, bool hidden) {
123
+ JNI_callPlatformWithBool(env, unistylesModule, "onSetNavigationBarHidden", "(Z)V", hidden);
116
124
  }
117
125
 
118
- void setNavigationBarColor(JNIEnv *env, jobject unistylesModule, std::string color) {
119
- jstring colorStr = env->NewStringUTF(color.c_str());
120
- jclass cls = env->GetObjectClass(unistylesModule);
121
- jmethodID methodId = env->GetMethodID(cls, "onSetNavigationBarColor", "(Ljava/lang/String;)V");
126
+ void setStatusBarHidden(JNIEnv *env, jobject unistylesModule, bool hidden) {
127
+ JNI_callPlatformWithBool(env, unistylesModule, "onSetStatusBarHidden", "(Z)V", hidden);
128
+ }
129
+
130
+ void setImmersiveMode(JNIEnv *env, jobject unistylesModule, bool enabled) {
131
+ JNI_callPlatformWithBool(env, unistylesModule, "onSetImmersiveMode", "(Z)V", enabled);
132
+ }
122
133
 
123
- env->CallVoidMethod(unistylesModule, methodId, colorStr);
124
- env->DeleteLocalRef(colorStr);
125
- env->DeleteLocalRef(cls);
134
+ void setRootViewBackgroundColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha) {
135
+ JNI_callPlatformWithColor(env, unistylesModule, "onSetRootViewBackgroundColor", "(Ljava/lang/String;F)V", color, alpha);
126
136
  }
@@ -4,12 +4,15 @@
4
4
  #include "helpers.h"
5
5
 
6
6
  void makeShared(JNIEnv *env, jobject unistylesModule, std::shared_ptr<UnistylesRuntime> unistylesRuntime);
7
- Dimensions getScreenDimensions(JNIEnv *env, jobject unistylesModule);
7
+ Screen getScreenDimensions(JNIEnv *env, jobject unistylesModule);
8
8
  std::string getColorScheme(JNIEnv *env, jobject unistylesModule);
9
9
  Dimensions getStatusBarDimensions(JNIEnv *env, jobject unistylesModule);
10
10
  Dimensions getNavigationBarDimensions(JNIEnv *env, jobject unistylesModule);
11
+ void setNavigationBarHidden(JNIEnv *env, jobject unistylesModule, bool hidden);
12
+ void setStatusBarHidden(JNIEnv *env, jobject unistylesModule, bool hidden);
13
+ void setImmersiveMode(JNIEnv *env, jobject unistylesModule, bool hidden);
14
+ void setRootViewBackgroundColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha);
11
15
  Insets getInsets(JNIEnv *env, jobject unistylesModule);
12
16
  std::string getContentSizeCategory(JNIEnv *env, jobject unistylesModule);
13
-
14
- void setNavigationBarColor(JNIEnv *env, jobject unistylesModule, std::string color);
15
- void setStatusBarColor(JNIEnv *env, jobject unistylesModule, std::string color);
17
+ void setNavigationBarColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha);
18
+ void setStatusBarColor(JNIEnv *env, jobject unistylesModule, std::string color, float alpha);
@@ -1,64 +1,27 @@
1
1
  package com.unistyles
2
2
 
3
- class Dimensions(var width: Int, var height: Int) {
4
- fun isEqual(dimensions: Dimensions): Boolean {
5
- if (this.width != dimensions.width) {
6
- return false
7
- }
8
-
9
- return this.height == dimensions.height
10
- }
11
-
3
+ class Dimensions(
4
+ var width: Int,
5
+ var height: Int
6
+ ) {
12
7
  override fun toString(): String {
13
8
  return "${width}x${height}"
14
9
  }
15
10
  }
16
11
 
17
- class Insets(var top: Int, var bottom: Int, var left: Int, var right: Int) {
18
- fun isEqual(insets: Insets): Boolean {
19
- if (this.top != insets.top) {
20
- return false
21
- }
22
-
23
- if (this.bottom != insets.bottom) {
24
- return false
25
- }
26
-
27
- if (this.left != insets.left) {
28
- return false
29
- }
30
-
31
- return this.right == insets.right
32
- }
33
-
12
+ class Screen(
13
+ var width: Int,
14
+ var height: Int,
15
+ var pixelRatio: Float,
16
+ var fontScale: Float
17
+ ) {
34
18
  override fun toString(): String {
35
- return "T:${top}B:${bottom}L:${left}R:${right}"
19
+ return "${width}x${height} ${pixelRatio} ${fontScale}"
36
20
  }
37
21
  }
38
22
 
39
- class InsetsCompat(
40
- val statusBar: Insets,
41
- val navigationBar: Insets,
42
- val cutout: Insets
43
- ) {
23
+ class Insets(var top: Int, var bottom: Int, var left: Int, var right: Int) {
44
24
  override fun toString(): String {
45
- return buildString {
46
- append(" statusBar=")
47
- append(statusBar)
48
- append(" navigationBar=")
49
- append(navigationBar)
50
- append(" cutout=")
51
- append(cutout)
52
- }
53
- }
54
-
55
- companion object {
56
- fun getDefaults(): InsetsCompat {
57
- return InsetsCompat(
58
- Insets(0, 0, 0, 0),
59
- Insets(0, 0, 0, 0),
60
- Insets(0, 0, 0, 0)
61
- )
62
- }
25
+ return "T:${top}B:${bottom}L:${left}R:${right}"
63
26
  }
64
27
  }
@@ -1,26 +1,34 @@
1
1
  package com.unistyles
2
2
 
3
3
  import android.content.res.Configuration
4
+ import android.graphics.Color
4
5
  import android.graphics.Rect
5
- import android.util.DisplayMetrics
6
+ import android.os.Build
7
+ import android.util.Log
6
8
  import android.view.View
9
+ import android.view.Window
10
+ import android.view.WindowManager
11
+ import androidx.core.graphics.ColorUtils
12
+ import androidx.core.view.ViewCompat
7
13
  import androidx.core.view.WindowInsetsCompat
14
+ import androidx.core.view.WindowInsetsControllerCompat
8
15
  import com.facebook.react.bridge.ReactApplicationContext
9
- import kotlin.math.max
16
+ import kotlin.math.roundToInt
10
17
 
11
18
  class Platform(private val reactApplicationContext: ReactApplicationContext) {
12
- private val displayMetrics: DisplayMetrics = reactApplicationContext.resources.displayMetrics
13
- private var insetsCompat: InsetsCompat = InsetsCompat.getDefaults()
19
+ private var insets: Insets = Insets(0, 0, 0, 0)
20
+ private var defaultNavigationBarColor: Int = -1
21
+ private var defaultStatusBarColor: Int = -1
14
22
 
15
- var defaultNavigationBarColor: Int? = null
16
- var defaultStatusBarColor: Int? = null
23
+ var orientation: Int = reactApplicationContext.resources.configuration.orientation
17
24
 
18
- fun getScreenDimensions(): Dimensions {
19
- val density = reactApplicationContext.resources.displayMetrics.density
20
- val screenWidth = (displayMetrics.widthPixels / density).toInt()
21
- val screenHeight = (displayMetrics.heightPixels / density).toInt()
25
+ fun getScreenDimensions(): Screen {
26
+ val displayMetrics = reactApplicationContext.resources.displayMetrics
27
+ val fontScale = reactApplicationContext.resources.configuration.fontScale
28
+ val screenWidth = (displayMetrics.widthPixels / displayMetrics.density).roundToInt()
29
+ val screenHeight = (displayMetrics.heightPixels / displayMetrics.density).roundToInt()
22
30
 
23
- return Dimensions(screenWidth, screenHeight)
31
+ return Screen(screenWidth, screenHeight, displayMetrics.density, fontScale)
24
32
  }
25
33
 
26
34
  fun getColorScheme(): String {
@@ -36,15 +44,15 @@ class Platform(private val reactApplicationContext: ReactApplicationContext) {
36
44
  }
37
45
 
38
46
  fun getStatusBarDimensions(): Dimensions {
39
- val density = reactApplicationContext.resources.displayMetrics.density
40
- val screenWidth = (displayMetrics.widthPixels / density).toInt()
47
+ val displayMetrics = reactApplicationContext.resources.displayMetrics
48
+ val screenWidth = (displayMetrics.widthPixels / displayMetrics.density).roundToInt()
41
49
 
42
50
  return Dimensions(screenWidth, getStatusBarHeight())
43
51
  }
44
52
 
45
53
  fun getNavigationBarDimensions(): Dimensions {
46
- val density = reactApplicationContext.resources.displayMetrics.density
47
- val screenWidth = (displayMetrics.widthPixels / density).toInt()
54
+ val displayMetrics = reactApplicationContext.resources.displayMetrics
55
+ val screenWidth = (displayMetrics.widthPixels / displayMetrics.density).roundToInt()
48
56
 
49
57
  return Dimensions(screenWidth, getNavigationBarHeight())
50
58
  }
@@ -65,50 +73,177 @@ class Platform(private val reactApplicationContext: ReactApplicationContext) {
65
73
  return contentSizeCategory
66
74
  }
67
75
 
68
- fun setInsetsCompat(insetsCompat: WindowInsetsCompat, decorView: View) {
69
- val statusBar = insetsCompat.getInsets(WindowInsetsCompat.Type.statusBars())
70
- val navigationBar = insetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars())
71
- val cutout = insetsCompat.getInsets(WindowInsetsCompat.Type.displayCutout())
76
+ fun setInsetsCompat(insetsCompat: WindowInsetsCompat, window: Window) {
77
+ // below Android 11, we need to use window flags to detect status bar visibility
78
+ val isStatusBarVisible = when(Build.VERSION.SDK_INT) {
79
+ in 30..Int.MAX_VALUE -> {
80
+ insetsCompat.isVisible(WindowInsetsCompat.Type.statusBars())
81
+ }
82
+ else -> {
83
+ @Suppress("DEPRECATION")
84
+ window.attributes.flags and WindowManager.LayoutParams.FLAG_FULLSCREEN != WindowManager.LayoutParams.FLAG_FULLSCREEN
85
+ }
86
+ }
87
+ // React Native is forcing insets to make status bar translucent
88
+ // so we need to calculate top inset manually, as WindowInsetCompat will always return 0
89
+ val statusBarTopInset = when(isStatusBarVisible) {
90
+ true -> {
91
+ val visibleRect = Rect()
72
92
 
73
- // get the visible frame of the window to detect translucent status bar
74
- // react native (and expo) are setting top inset to 0
75
- // so there is no other way to detect if status bar is hidden or translucent
76
- val visibleFrame = Rect()
77
- decorView.getWindowVisibleDisplayFrame(visibleFrame)
93
+ window.decorView.getWindowVisibleDisplayFrame(visibleRect)
78
94
 
79
- val visibleTopFrame = max(visibleFrame.top, statusBar.top)
95
+ visibleRect.top
96
+ }
97
+ false -> 0
98
+ }
80
99
 
81
- this.insetsCompat = InsetsCompat(
82
- Insets(visibleTopFrame, statusBar.bottom, statusBar.left, statusBar.right),
83
- Insets(navigationBar.top, navigationBar.bottom, navigationBar.left, navigationBar.right),
84
- Insets(cutout.top, cutout.bottom, cutout.left, cutout.right)
85
- )
100
+ val insets = insetsCompat.getInsets(WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout())
101
+
102
+ this.insets = Insets(statusBarTopInset, insets.bottom, insets.left, insets.right)
86
103
  }
87
104
 
88
105
  fun getInsets(): Insets {
89
106
  val density = reactApplicationContext.resources.displayMetrics.density
90
- val top = max(this.insetsCompat.cutout.top, this.insetsCompat.statusBar.top)
91
- val bottom = this.insetsCompat.navigationBar.bottom
92
- val left = this.insetsCompat.statusBar.left
93
- val right = this.insetsCompat.statusBar.right
94
107
 
95
108
  return Insets(
96
- (top / density).toInt(),
97
- (bottom / density).toInt(),
98
- (left / density).toInt(),
99
- (right / density).toInt()
109
+ (this.insets.top / density).roundToInt(),
110
+ (this.insets.bottom / density).roundToInt(),
111
+ (this.insets.left / density).roundToInt(),
112
+ (this.insets.right / density).roundToInt()
100
113
  )
101
114
  }
102
115
 
103
116
  private fun getStatusBarHeight(): Int {
104
117
  val density = reactApplicationContext.resources.displayMetrics.density
105
118
 
106
- return (this.insetsCompat.statusBar.top / density).toInt()
119
+ return (this.insets.top / density).roundToInt()
107
120
  }
108
121
 
109
122
  private fun getNavigationBarHeight(): Int {
110
123
  val density = reactApplicationContext.resources.displayMetrics.density
111
124
 
112
- return (this.insetsCompat.navigationBar.bottom / density).toInt()
125
+ return (this.insets.bottom / density).roundToInt()
126
+ }
127
+
128
+ fun onSetNavigationBarColor(color: String, alpha: Float) {
129
+ this.reactApplicationContext.currentActivity?.let { activity ->
130
+ if (this.defaultNavigationBarColor == -1) {
131
+ this.defaultNavigationBarColor = activity.window.navigationBarColor
132
+ }
133
+
134
+ try {
135
+ activity.runOnUiThread {
136
+ activity.window.navigationBarColor = parseColor(color, alpha, this.defaultNavigationBarColor)
137
+ }
138
+ } catch (_: Exception) {
139
+ Log.d("Unistyles", "Failed to set navigation bar color: $color")
140
+ }
141
+ }
142
+ }
143
+
144
+ fun onSetNavigationBarHidden(isHidden: Boolean) {
145
+ this.reactApplicationContext.currentActivity?.let { activity ->
146
+ WindowInsetsControllerCompat(activity.window, activity.window.decorView).apply {
147
+ activity.window?.decorView?.let { decorView ->
148
+ @Suppress("DEPRECATION")
149
+ activity.runOnUiThread {
150
+ if (isHidden) {
151
+ // below Android 11, we need to use window flags to hide the navigation bar
152
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
153
+ decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
154
+ or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
155
+ } else {
156
+ hide(WindowInsetsCompat.Type.navigationBars())
157
+ systemBarsBehavior =
158
+ WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
159
+ }
160
+
161
+ // dispatch new insets to invoke the insets listener
162
+ val newInsets = WindowInsetsCompat.Builder()
163
+ .setInsets(WindowInsetsCompat.Type.navigationBars(), androidx.core.graphics.Insets.of(0, 0, 0, 0))
164
+ .build()
165
+
166
+ ViewCompat.dispatchApplyWindowInsets(activity.findViewById(android.R.id.content), newInsets)
167
+ } else {
168
+ show(WindowInsetsCompat.Type.navigationBars())
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ fun onSetStatusBarHidden(isHidden: Boolean) {
177
+ this.reactApplicationContext.currentActivity?.let { activity ->
178
+ WindowInsetsControllerCompat(activity.window, activity.window.decorView).apply {
179
+ activity.window?.let { window ->
180
+ @Suppress("DEPRECATION")
181
+ activity.runOnUiThread {
182
+ if (isHidden) {
183
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
184
+ window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
185
+ window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
186
+ } else {
187
+ hide(WindowInsetsCompat.Type.statusBars())
188
+ }
189
+ } else {
190
+ show(WindowInsetsCompat.Type.statusBars())
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ fun onSetStatusBarColor(color: String, alpha: Float) {
199
+ this.reactApplicationContext.currentActivity?.let { activity ->
200
+ if (this.defaultStatusBarColor == -1) {
201
+ this.defaultStatusBarColor = activity.window.statusBarColor
202
+ }
203
+
204
+ try {
205
+ activity.runOnUiThread {
206
+ activity.window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
207
+ activity.window.statusBarColor = parseColor(color, alpha, this.defaultStatusBarColor)
208
+ }
209
+ } catch (_: Exception) {
210
+ Log.d("Unistyles", "Failed to set status bar color: $color")
211
+ }
212
+ }
213
+ }
214
+
215
+ fun onSetImmersiveMode(isEnabled: Boolean) {
216
+ this.onSetStatusBarHidden(isEnabled)
217
+ this.onSetNavigationBarHidden(isEnabled)
218
+ }
219
+
220
+ fun onSetRootViewBackgroundColor(color: String, alpha: Float) {
221
+ this.reactApplicationContext.currentActivity?.let { activity ->
222
+ activity.window?.decorView?.let { decorView ->
223
+ try {
224
+ activity.runOnUiThread {
225
+ decorView.rootView.setBackgroundColor(parseColor(color, alpha, Color.WHITE))
226
+ }
227
+ } catch (_: Exception) {
228
+ Log.d("Unistyles", "Failed to set root view background color: $color")
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ private fun parseColor(color: String, alpha: Float, defaultColor: Int): Int {
235
+ if (color == "") {
236
+ return defaultColor
237
+ }
238
+
239
+ if (color == "transparent") {
240
+ return Color.TRANSPARENT
241
+ }
242
+
243
+ if (alpha == 1.toFloat()) {
244
+ return Color.parseColor(color)
245
+ }
246
+
247
+ return ColorUtils.setAlphaComponent(Color.parseColor(color), (255 * alpha).toInt())
113
248
  }
114
249
  }