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
@@ -4,44 +4,45 @@ import android.content.BroadcastReceiver
|
|
4
4
|
import android.content.Context
|
5
5
|
import android.content.Intent
|
6
6
|
import android.content.IntentFilter
|
7
|
+
import android.content.res.Configuration
|
7
8
|
import android.graphics.Color
|
8
9
|
import android.os.Handler
|
9
10
|
import android.os.Looper
|
10
11
|
import android.util.Log
|
11
|
-
import android.view.
|
12
|
-
import
|
12
|
+
import android.view.View
|
13
|
+
import androidx.core.view.ViewCompat
|
14
|
+
import androidx.core.view.WindowCompat
|
13
15
|
import com.facebook.react.bridge.LifecycleEventListener
|
14
16
|
import com.facebook.react.bridge.ReactApplicationContext
|
15
17
|
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
16
18
|
import com.facebook.react.bridge.ReactMethod
|
17
|
-
import com.facebook.react.
|
19
|
+
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
|
18
20
|
|
19
21
|
class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
|
20
|
-
private val drawHandler = Handler(Looper.getMainLooper())
|
21
|
-
private val debounceDuration = 250L
|
22
|
-
private var runnable: Runnable? = null
|
23
|
-
|
24
22
|
private var isCxxReady: Boolean = false
|
25
23
|
private lateinit var platform: Platform
|
26
|
-
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
|
27
|
-
if (this.isCxxReady) {
|
28
|
-
runnable?.let { drawHandler.removeCallbacks(it) }
|
29
|
-
|
30
|
-
runnable = Runnable {
|
31
|
-
this@UnistylesModule.onLayoutConfigChange()
|
32
|
-
}.also {
|
33
|
-
drawHandler.postDelayed(it, debounceDuration)
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
37
24
|
|
38
25
|
private val configurationChangeReceiver = object : BroadcastReceiver() {
|
39
26
|
override fun onReceive(context: Context, intent: Intent) {
|
40
|
-
if (
|
27
|
+
if (!this@UnistylesModule.isCxxReady) {
|
28
|
+
return
|
29
|
+
}
|
30
|
+
|
31
|
+
if (intent.action == Intent.ACTION_CONFIGURATION_CHANGED) {
|
41
32
|
Handler(Looper.getMainLooper()).postDelayed({
|
42
33
|
this@UnistylesModule.onConfigChange()
|
43
34
|
}, 10)
|
44
35
|
}
|
36
|
+
|
37
|
+
val newConfig = context.resources.configuration
|
38
|
+
|
39
|
+
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
40
|
+
this@UnistylesModule.onLayoutConfigChange()
|
41
|
+
}
|
42
|
+
|
43
|
+
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
44
|
+
this@UnistylesModule.onLayoutConfigChange()
|
45
|
+
}
|
45
46
|
}
|
46
47
|
}
|
47
48
|
|
@@ -56,21 +57,8 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
56
57
|
reactApplicationContext.addLifecycleEventListener(this)
|
57
58
|
}
|
58
59
|
|
59
|
-
|
60
|
-
val activity = currentActivity ?: return
|
61
|
-
activity.window.decorView.rootView.viewTreeObserver.addOnGlobalLayoutListener(layoutListener)
|
62
|
-
}
|
63
|
-
|
64
|
-
private fun stopLayoutListener() {
|
65
|
-
val activity = currentActivity ?: return
|
66
|
-
activity.window.decorView.rootView.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
|
67
|
-
}
|
68
|
-
|
69
|
-
@Deprecated("Deprecated in Java")
|
70
|
-
override fun onCatalystInstanceDestroy() {
|
71
|
-
this.stopLayoutListener()
|
60
|
+
override fun invalidate() {
|
72
61
|
reactApplicationContext.unregisterReceiver(configurationChangeReceiver)
|
73
|
-
runnable?.let { drawHandler.removeCallbacks(it) }
|
74
62
|
reactApplicationContext.removeLifecycleEventListener(this)
|
75
63
|
|
76
64
|
if (this.isCxxReady) {
|
@@ -81,36 +69,27 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
81
69
|
//endregion
|
82
70
|
//region Event handlers
|
83
71
|
private fun onConfigChange() {
|
84
|
-
|
85
|
-
|
86
|
-
}
|
87
|
-
|
88
|
-
val config = platform.getConfig()
|
72
|
+
val colorScheme = this.platform.getColorScheme()
|
73
|
+
val contentSizeCategory = this.platform.getContentSizeCategory()
|
89
74
|
|
90
75
|
reactApplicationContext.runOnJSQueueThread {
|
91
|
-
|
92
|
-
|
93
|
-
}
|
94
|
-
|
95
|
-
if (config.hasNewContentSizeCategory) {
|
96
|
-
this.nativeOnContentSizeCategoryChange(config.contentSizeCategory)
|
97
|
-
}
|
76
|
+
this.nativeOnAppearanceChange(colorScheme)
|
77
|
+
this.nativeOnContentSizeCategoryChange(contentSizeCategory)
|
98
78
|
}
|
99
79
|
}
|
100
80
|
|
101
81
|
private fun onLayoutConfigChange() {
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
val config = platform.getLayoutConfig()
|
82
|
+
val screen = this.getScreenDimensions()
|
83
|
+
val insets = this.getInsets()
|
84
|
+
val statusBar = this.getStatusBarDimensions()
|
85
|
+
val navigationBar = this.getNavigationBarDimensions()
|
107
86
|
|
108
87
|
reactApplicationContext.runOnJSQueueThread {
|
109
88
|
this.nativeOnOrientationChange(
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
89
|
+
screen,
|
90
|
+
insets,
|
91
|
+
statusBar,
|
92
|
+
navigationBar
|
114
93
|
)
|
115
94
|
}
|
116
95
|
}
|
@@ -123,25 +102,17 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
123
102
|
System.loadLibrary("unistyles")
|
124
103
|
|
125
104
|
this.platform = Platform(reactApplicationContext)
|
105
|
+
this.enableEdgeToEdge()
|
126
106
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
this.nativeInstall(
|
132
|
-
it.get(),
|
133
|
-
layoutConfig.screen,
|
134
|
-
config.colorScheme,
|
135
|
-
config.contentSizeCategory,
|
136
|
-
layoutConfig.insets,
|
137
|
-
layoutConfig.statusBar,
|
138
|
-
layoutConfig.navigationBar
|
139
|
-
)
|
140
|
-
this.isCxxReady = true
|
107
|
+
this.reactApplicationContext.javaScriptContextHolder?.let { contextHolder ->
|
108
|
+
this.reactApplicationContext.catalystInstance.jsCallInvokerHolder?.let { callInvokerHolder: CallInvokerHolder ->
|
109
|
+
this.nativeInstall(contextHolder.get(), callInvokerHolder)
|
110
|
+
this.isCxxReady = true
|
141
111
|
|
142
|
-
|
112
|
+
Log.i(NAME, "Installed Unistyles \uD83E\uDD84!")
|
143
113
|
|
144
|
-
|
114
|
+
return true
|
115
|
+
}
|
145
116
|
}
|
146
117
|
|
147
118
|
false
|
@@ -152,88 +123,36 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
152
123
|
}
|
153
124
|
}
|
154
125
|
|
155
|
-
private external fun nativeInstall(
|
156
|
-
jsi: Long,
|
157
|
-
screen: Dimensions,
|
158
|
-
colorScheme: String,
|
159
|
-
contentSizeCategory: String,
|
160
|
-
insets: Insets,
|
161
|
-
statusBar: Dimensions,
|
162
|
-
navigationBar: Dimensions
|
163
|
-
)
|
126
|
+
private external fun nativeInstall(jsi: Long, callInvoker: CallInvokerHolder)
|
164
127
|
private external fun nativeDestroy()
|
165
128
|
private external fun nativeOnOrientationChange(screen: Dimensions, insets: Insets, statusBar: Dimensions, navigationBar: Dimensions)
|
166
129
|
private external fun nativeOnAppearanceChange(colorScheme: String)
|
167
130
|
private external fun nativeOnContentSizeCategoryChange(contentSizeCategory: String)
|
168
131
|
|
169
132
|
//endregion
|
170
|
-
//region Event emitter
|
171
|
-
private fun onLayoutChange(breakpoint: String, orientation: String, screen: Dimensions, statusBar: Dimensions, insets: Insets, navigationBar: Dimensions) {
|
172
|
-
val body = Arguments.createMap().apply {
|
173
|
-
putString("type", "layout")
|
174
|
-
putMap("payload", Arguments.createMap().apply {
|
175
|
-
putString("breakpoint", breakpoint)
|
176
|
-
putString("orientation", orientation)
|
177
|
-
putMap("screen", Arguments.createMap().apply {
|
178
|
-
putInt("width", screen.width)
|
179
|
-
putInt("height", screen.height)
|
180
|
-
})
|
181
|
-
putMap("statusBar", Arguments.createMap().apply {
|
182
|
-
putInt("width", statusBar.width)
|
183
|
-
putInt("height", statusBar.height)
|
184
|
-
})
|
185
|
-
putMap("insets", Arguments.createMap().apply {
|
186
|
-
putInt("top", insets.top)
|
187
|
-
putInt("bottom", insets.bottom)
|
188
|
-
putInt("left", insets.left)
|
189
|
-
putInt("right", insets.right)
|
190
|
-
})
|
191
|
-
putMap("navigationBar", Arguments.createMap().apply {
|
192
|
-
putInt("width", navigationBar.width)
|
193
|
-
putInt("height", navigationBar.height)
|
194
|
-
})
|
195
|
-
})
|
196
|
-
}
|
197
133
|
|
198
|
-
|
199
|
-
|
200
|
-
.emit("__unistylesOnChange", body)
|
134
|
+
private fun getScreenDimensions(): Dimensions {
|
135
|
+
return platform.getScreenDimensions()
|
201
136
|
}
|
202
137
|
|
203
|
-
private fun
|
204
|
-
|
205
|
-
putString("type", "theme")
|
206
|
-
putMap("payload", Arguments.createMap().apply {
|
207
|
-
putString("themeName", themeName)
|
208
|
-
})
|
209
|
-
}
|
210
|
-
|
211
|
-
reactApplicationContext
|
212
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
213
|
-
.emit("__unistylesOnChange", body)
|
138
|
+
private fun getColorScheme(): String {
|
139
|
+
return platform.getColorScheme()
|
214
140
|
}
|
215
141
|
|
216
|
-
private fun
|
217
|
-
|
218
|
-
|
219
|
-
}
|
142
|
+
private fun getStatusBarDimensions(): Dimensions {
|
143
|
+
return platform.getStatusBarDimensions()
|
144
|
+
}
|
220
145
|
|
221
|
-
|
222
|
-
|
223
|
-
.emit("__unistylesOnChange", body)
|
146
|
+
private fun getNavigationBarDimensions(): Dimensions {
|
147
|
+
return platform.getNavigationBarDimensions()
|
224
148
|
}
|
225
149
|
|
226
|
-
private fun
|
227
|
-
|
228
|
-
|
229
|
-
putMap("payload", Arguments.createMap().apply {
|
230
|
-
putString("contentSizeCategory", contentSizeCategory)
|
231
|
-
})
|
232
|
-
}
|
150
|
+
private fun getContentSizeCategory(): String {
|
151
|
+
return platform.getContentSizeCategory()
|
152
|
+
}
|
233
153
|
|
234
|
-
|
235
|
-
|
236
|
-
.emit("__unistylesOnChange", body)
|
154
|
+
private fun getInsets(): Insets {
|
155
|
+
return platform.getInsets()
|
237
156
|
}
|
238
157
|
|
239
158
|
private fun onSetNavigationBarColor(color: String) {
|
@@ -268,6 +187,14 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
268
187
|
}
|
269
188
|
}
|
270
189
|
|
190
|
+
private fun enableEdgeToEdge() {
|
191
|
+
this.reactApplicationContext.currentActivity?.let { activity ->
|
192
|
+
activity.runOnUiThread {
|
193
|
+
WindowCompat.setDecorFitsSystemWindows(activity.window, false)
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
271
198
|
@ReactMethod
|
272
199
|
fun addListener(eventName: String?) = Unit
|
273
200
|
|
@@ -278,11 +205,29 @@ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
|
|
278
205
|
this.onConfigChange()
|
279
206
|
}
|
280
207
|
|
281
|
-
this.
|
208
|
+
this.reactApplicationContext.currentActivity?.let { activity ->
|
209
|
+
activity.findViewById<View>(android.R.id.content)?.let { mainView ->
|
210
|
+
activity.window?.decorView?.let { decorView ->
|
211
|
+
ViewCompat.setOnApplyWindowInsetsListener(mainView) { _, insets ->
|
212
|
+
this.platform.setInsetsCompat(insets, decorView)
|
213
|
+
|
214
|
+
if (this.isCxxReady) {
|
215
|
+
this.onLayoutConfigChange()
|
216
|
+
}
|
217
|
+
|
218
|
+
insets
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
282
223
|
}
|
283
224
|
|
284
225
|
override fun onHostPause() {
|
285
|
-
this.
|
226
|
+
this.reactApplicationContext.currentActivity?.let { activity ->
|
227
|
+
activity.window?.decorView?.let { view ->
|
228
|
+
ViewCompat.setOnApplyWindowInsetsListener(view, null)
|
229
|
+
}
|
230
|
+
}
|
286
231
|
}
|
287
232
|
|
288
233
|
override fun onHostDestroy() {}
|
package/cxx/Macros.h
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#define HOST_FN(name, args, fn_body) \
|
4
|
+
jsi::Function::createFromHostFunction(rt, \
|
5
|
+
jsi::PropNameID::forAscii(rt, name), \
|
6
|
+
args, \
|
7
|
+
[this, &fnName](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *arguments, size_t count) -> jsi::Value \
|
8
|
+
fn_body \
|
9
|
+
); \
|
10
|
+
|
11
|
+
#define BIND_FN(fn) std::bind(&UnistylesRuntime::fn, this, std::placeholders::_1, std::placeholders::_2)
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#include "UnistylesRuntime.h"
|
2
|
+
#include <jsi/jsi.h>
|
3
|
+
|
4
|
+
using namespace facebook;
|
5
|
+
|
6
|
+
jsi::Value UnistylesRuntime::getScreenWidth(jsi::Runtime& rt, std::string fnName) {
|
7
|
+
return jsi::Value(this->screen.width);
|
8
|
+
}
|
9
|
+
|
10
|
+
jsi::Value UnistylesRuntime::getScreenHeight(jsi::Runtime& rt, std::string fnName) {
|
11
|
+
return jsi::Value(this->screen.height);
|
12
|
+
}
|
13
|
+
|
14
|
+
jsi::Value UnistylesRuntime::getContentSizeCategory(jsi::Runtime & rt, std::string fnName) {
|
15
|
+
return jsi::Value(jsi::String::createFromUtf8(rt, this->contentSizeCategory));
|
16
|
+
}
|
17
|
+
|
18
|
+
jsi::Value UnistylesRuntime::hasEnabledAdaptiveThemes(jsi::Runtime& rt, std::string fnName) {
|
19
|
+
return jsi::Value(this->hasAdaptiveThemes);
|
20
|
+
}
|
21
|
+
|
22
|
+
jsi::Value UnistylesRuntime::getThemeName(jsi::Runtime& rt, std::string fnName) {
|
23
|
+
return !this->themeName.empty()
|
24
|
+
? jsi::Value(jsi::String::createFromUtf8(rt, this->themeName))
|
25
|
+
: this->getThemeOrFail(rt);
|
26
|
+
}
|
27
|
+
|
28
|
+
jsi::Value UnistylesRuntime::getCurrentBreakpoint(jsi::Runtime& rt, std::string fnName) {
|
29
|
+
return !this->breakpoint.empty()
|
30
|
+
? jsi::Value(jsi::String::createFromUtf8(rt, this->breakpoint))
|
31
|
+
: jsi::Value::undefined();
|
32
|
+
}
|
33
|
+
|
34
|
+
jsi::Value UnistylesRuntime::getColorScheme(jsi::Runtime& rt, std::string fnName) {
|
35
|
+
return jsi::Value(jsi::String::createFromUtf8(rt, this->colorScheme));
|
36
|
+
}
|
37
|
+
|
38
|
+
jsi::Value UnistylesRuntime::getSortedBreakpointPairs(jsi::Runtime& rt, std::string fnName) {
|
39
|
+
std::unique_ptr<jsi::Array> sortedBreakpointEntriesArray = std::make_unique<jsi::Array>(rt, this->sortedBreakpointPairs.size());
|
40
|
+
|
41
|
+
for (size_t i = 0; i < this->sortedBreakpointPairs.size(); ++i) {
|
42
|
+
std::unique_ptr<jsi::Array> pairArray = std::make_unique<jsi::Array>(rt, 2);
|
43
|
+
jsi::String nameValue = jsi::String::createFromUtf8(rt, this->sortedBreakpointPairs[i].first);
|
44
|
+
|
45
|
+
pairArray->setValueAtIndex(rt, 0, nameValue);
|
46
|
+
pairArray->setValueAtIndex(rt, 1, jsi::Value(this->sortedBreakpointPairs[i].second));
|
47
|
+
sortedBreakpointEntriesArray->setValueAtIndex(rt, i, *pairArray);
|
48
|
+
}
|
49
|
+
|
50
|
+
return jsi::Value(rt, *sortedBreakpointEntriesArray);
|
51
|
+
}
|
52
|
+
|
53
|
+
jsi::Value UnistylesRuntime::setBreakpoints(jsi::Runtime& rt, std::string fnName) {
|
54
|
+
return HOST_FN(fnName, 1, {
|
55
|
+
jsi::Object breakpointsObj = arguments[0].asObject(rt);
|
56
|
+
auto sortedBreakpoints = this->toSortedBreakpointPairs(rt, breakpointsObj);
|
57
|
+
|
58
|
+
if (sortedBreakpoints.size() == 0) {
|
59
|
+
throw jsi::JSError(rt, UnistylesErrorBreakpointsCannotBeEmpty);
|
60
|
+
}
|
61
|
+
|
62
|
+
if (sortedBreakpoints.at(0).second != 0) {
|
63
|
+
throw jsi::JSError(rt, UnistylesErrorBreakpointsMustStartFromZero);
|
64
|
+
}
|
65
|
+
|
66
|
+
this->sortedBreakpointPairs = sortedBreakpoints;
|
67
|
+
|
68
|
+
std::string breakpoint = this->getBreakpointFromScreenWidth(this->screen.width, sortedBreakpoints);
|
69
|
+
|
70
|
+
this->breakpoint = breakpoint;
|
71
|
+
|
72
|
+
return jsi::Value::undefined();
|
73
|
+
});
|
74
|
+
}
|
75
|
+
|
76
|
+
jsi::Value UnistylesRuntime::setActiveTheme(jsi::Runtime& rt, std::string fnName) {
|
77
|
+
return HOST_FN(fnName, 1, {
|
78
|
+
std::string themeName = arguments[0].asString(rt).utf8(rt);
|
79
|
+
|
80
|
+
if (this->themeName != themeName) {
|
81
|
+
this->themeName = themeName;
|
82
|
+
this->onThemeChange(themeName);
|
83
|
+
}
|
84
|
+
|
85
|
+
return jsi::Value::undefined();
|
86
|
+
});
|
87
|
+
}
|
88
|
+
|
89
|
+
jsi::Value UnistylesRuntime::updateTheme(jsi::Runtime& rt, std::string fnName) {
|
90
|
+
return HOST_FN(fnName, 1, {
|
91
|
+
std::string themeName = arguments[0].asString(rt).utf8(rt);
|
92
|
+
|
93
|
+
if (this->themeName == themeName) {
|
94
|
+
this->onThemeChange(themeName);
|
95
|
+
}
|
96
|
+
|
97
|
+
return jsi::Value::undefined();
|
98
|
+
});
|
99
|
+
}
|
100
|
+
|
101
|
+
jsi::Value UnistylesRuntime::useAdaptiveThemes(jsi::Runtime& rt, std::string fnName) {
|
102
|
+
return HOST_FN(fnName, 1, {
|
103
|
+
bool enableAdaptiveThemes = arguments[0].asBool();
|
104
|
+
|
105
|
+
if (enableAdaptiveThemes && this->colorScheme == UnistylesUnspecifiedScheme) {
|
106
|
+
throw jsi::JSError(rt, UnistylesErrorAdaptiveThemesNotSupported);
|
107
|
+
}
|
108
|
+
|
109
|
+
this->hasAdaptiveThemes = enableAdaptiveThemes;
|
110
|
+
|
111
|
+
if (!enableAdaptiveThemes || !this->supportsAutomaticColorScheme) {
|
112
|
+
return jsi::Value::undefined();
|
113
|
+
}
|
114
|
+
|
115
|
+
if (this->themeName != this->colorScheme) {
|
116
|
+
this->themeName = this->colorScheme;
|
117
|
+
this->onThemeChange(this->themeName);
|
118
|
+
}
|
119
|
+
|
120
|
+
return jsi::Value::undefined();
|
121
|
+
});
|
122
|
+
}
|
123
|
+
|
124
|
+
jsi::Value UnistylesRuntime::addPlugin(jsi::Runtime& rt, std::string fnName) {
|
125
|
+
return HOST_FN(fnName, 1, {
|
126
|
+
std::string pluginName = arguments[0].asString(rt).utf8(rt);
|
127
|
+
bool notify = arguments[1].asBool();
|
128
|
+
|
129
|
+
this->pluginNames.push_back(pluginName);
|
130
|
+
|
131
|
+
// registry enabled plugins won't notify listeners
|
132
|
+
if (notify) {
|
133
|
+
this->onPluginChange();
|
134
|
+
}
|
135
|
+
|
136
|
+
return jsi::Value::undefined();
|
137
|
+
});
|
138
|
+
}
|
139
|
+
|
140
|
+
jsi::Value UnistylesRuntime::removePlugin(jsi::Runtime& rt, std::string fnName) {
|
141
|
+
return HOST_FN(fnName, 1, {
|
142
|
+
std::string pluginName = arguments[0].asString(rt).utf8(rt);
|
143
|
+
|
144
|
+
auto it = std::find(this->pluginNames.begin(), this->pluginNames.end(), pluginName);
|
145
|
+
|
146
|
+
if (it != this->pluginNames.end()) {
|
147
|
+
this->pluginNames.erase(it);
|
148
|
+
this->onPluginChange();
|
149
|
+
}
|
150
|
+
|
151
|
+
return jsi::Value::undefined();
|
152
|
+
});
|
153
|
+
}
|
154
|
+
|
155
|
+
jsi::Value UnistylesRuntime::getEnabledPlugins(jsi::Runtime& rt, std::string fnName) {
|
156
|
+
auto jsiArray = facebook::jsi::Array(rt, this->pluginNames.size());
|
157
|
+
|
158
|
+
for (size_t i = 0; i < this->pluginNames.size(); i++) {
|
159
|
+
jsiArray.setValueAtIndex(rt, i, facebook::jsi::String::createFromUtf8(rt, this->pluginNames[i]));
|
160
|
+
}
|
161
|
+
|
162
|
+
return jsiArray;
|
163
|
+
}
|
164
|
+
|
165
|
+
jsi::Value UnistylesRuntime::getInsets(jsi::Runtime& rt, std::string fnName) {
|
166
|
+
auto insets = jsi::Object(rt);
|
167
|
+
|
168
|
+
insets.setProperty(rt, "top", this->insets.top);
|
169
|
+
insets.setProperty(rt, "bottom", this->insets.bottom);
|
170
|
+
insets.setProperty(rt, "left", this->insets.left);
|
171
|
+
insets.setProperty(rt, "right", this->insets.right);
|
172
|
+
|
173
|
+
return insets;
|
174
|
+
}
|
175
|
+
|
176
|
+
jsi::Value UnistylesRuntime::getStatusBar(jsi::Runtime& rt, std::string fnName) {
|
177
|
+
auto statusBar = jsi::Object(rt);
|
178
|
+
auto setStatusBarColorFunction = HOST_FN("setColor", 1, {
|
179
|
+
std::string color = arguments[0].asString(rt).utf8(rt);
|
180
|
+
|
181
|
+
if (this->setStatusBarColor.has_value()) {
|
182
|
+
this->setStatusBarColor.value()(color);
|
183
|
+
}
|
184
|
+
|
185
|
+
return jsi::Value::undefined();
|
186
|
+
});
|
187
|
+
|
188
|
+
statusBar.setProperty(rt, "width", this->statusBar.width);
|
189
|
+
statusBar.setProperty(rt, "height", this->statusBar.height);
|
190
|
+
statusBar.setProperty(rt, "setColor", setStatusBarColorFunction);
|
191
|
+
|
192
|
+
return statusBar;
|
193
|
+
}
|
194
|
+
|
195
|
+
jsi::Value UnistylesRuntime::getNavigationBar(jsi::Runtime& rt, std::string fnName) {
|
196
|
+
auto navigationBarValue = jsi::Object(rt);
|
197
|
+
auto setNavigationBarColorFunction = HOST_FN("setColor", 1, {
|
198
|
+
std::string color = arguments[0].asString(rt).utf8(rt);
|
199
|
+
|
200
|
+
if (this->setNavigationBarColor.has_value()) {
|
201
|
+
this->setNavigationBarColor.value()(color);
|
202
|
+
}
|
203
|
+
|
204
|
+
return jsi::Value::undefined();
|
205
|
+
});
|
206
|
+
|
207
|
+
navigationBarValue.setProperty(rt, "width", this->navigationBar.width);
|
208
|
+
navigationBarValue.setProperty(rt, "height", this->navigationBar.height);
|
209
|
+
navigationBarValue.setProperty(rt, "setColor", setNavigationBarColorFunction);
|
210
|
+
|
211
|
+
return navigationBarValue;
|
212
|
+
}
|
213
|
+
|
214
|
+
std::optional<jsi::Value> UnistylesRuntime::setThemes(jsi::Runtime& rt, const jsi::Value& value) {
|
215
|
+
jsi::Array themes = value.asObject(rt).asArray(rt);
|
216
|
+
std::vector<std::string> themesVector;
|
217
|
+
size_t length = themes.size(rt);
|
218
|
+
|
219
|
+
for (size_t i = 0; i < length; ++i) {
|
220
|
+
jsi::Value element = themes.getValueAtIndex(rt, i);
|
221
|
+
|
222
|
+
if (element.isString()) {
|
223
|
+
std::string theme = element.asString(rt).utf8(rt);
|
224
|
+
themesVector.push_back(theme);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
if (themesVector.size() == 0) {
|
229
|
+
throw jsi::JSError(rt, UnistylesErrorThemesCannotBeEmpty);
|
230
|
+
}
|
231
|
+
|
232
|
+
this->themes = themesVector;
|
233
|
+
this->themeName = "";
|
234
|
+
|
235
|
+
bool hasLightTheme = std::find(themesVector.begin(), themesVector.end(), "light") != themesVector.end();
|
236
|
+
bool hasDarkTheme = std::find(themesVector.begin(), themesVector.end(), "dark") != themesVector.end();
|
237
|
+
|
238
|
+
this->supportsAutomaticColorScheme = hasLightTheme && hasDarkTheme;
|
239
|
+
|
240
|
+
return std::nullopt;
|
241
|
+
}
|