one 2.0.0-beta.101.1 → 2.0.0-beta.103.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.
Files changed (80) hide show
  1. package/android/src/main/java/com/margelo/nitro/one/HybridOneAdaptive.kt +392 -0
  2. package/dist/cjs/platform/adaptive/index.native.cjs +79 -53
  3. package/dist/cjs/platform/adaptive/index.native.js +79 -53
  4. package/dist/cjs/platform/adaptive/index.native.js.map +1 -1
  5. package/dist/cjs/platform/specs/OneAdaptive.nitro.cjs +16 -0
  6. package/dist/cjs/platform/specs/OneAdaptive.nitro.native.cjs +18 -0
  7. package/dist/cjs/platform/specs/OneAdaptive.nitro.native.js +20 -0
  8. package/dist/cjs/platform/specs/OneAdaptive.nitro.native.js.map +1 -0
  9. package/dist/cjs/vite/plugins/swiftPackagePlugin.cjs +4 -1
  10. package/dist/cjs/vite/plugins/swiftPackagePlugin.native.cjs +4 -1
  11. package/dist/cjs/vite/plugins/swiftPackagePlugin.native.js +4 -1
  12. package/dist/cjs/vite/plugins/swiftPackagePlugin.native.js.map +1 -1
  13. package/dist/esm/platform/adaptive/index.native.js +79 -53
  14. package/dist/esm/platform/adaptive/index.native.js.map +1 -1
  15. package/dist/esm/platform/specs/OneAdaptive.nitro.mjs +0 -0
  16. package/dist/esm/platform/specs/OneAdaptive.nitro.native.js +0 -0
  17. package/dist/esm/vite/plugins/swiftPackagePlugin.mjs +4 -1
  18. package/dist/esm/vite/plugins/swiftPackagePlugin.mjs.map +1 -1
  19. package/dist/esm/vite/plugins/swiftPackagePlugin.native.js +4 -1
  20. package/dist/esm/vite/plugins/swiftPackagePlugin.native.js.map +1 -1
  21. package/ios/Nitro/HybridOneAdaptive.swift +243 -0
  22. package/ios/OneNativeGlassView.swift +2 -6
  23. package/ios/OneNativeHostingController.swift +14 -0
  24. package/ios/OneNativeNavigationStackView.swift +1 -1
  25. package/ios/OneNativeSheetView.swift +1 -1
  26. package/ios/OneNativeTabsView.swift +1 -1
  27. package/nitrogen/generated/android/One+autolinking.cmake +2 -0
  28. package/nitrogen/generated/android/OneOnLoad.cpp +22 -2
  29. package/nitrogen/generated/android/c++/JFunc_void_SizeClass.hpp +79 -0
  30. package/nitrogen/generated/android/c++/JFunc_void_std__optional_HingeState_.hpp +80 -0
  31. package/nitrogen/generated/android/c++/JHingeState.hpp +62 -0
  32. package/nitrogen/generated/android/c++/JHingeStatus.hpp +64 -0
  33. package/nitrogen/generated/android/c++/JHybridOneAdaptiveSpec.cpp +138 -0
  34. package/nitrogen/generated/android/c++/JHybridOneAdaptiveSpec.hpp +68 -0
  35. package/nitrogen/generated/android/c++/JNetworkStateType.hpp +3 -3
  36. package/nitrogen/generated/android/c++/JSizeClass.hpp +62 -0
  37. package/nitrogen/generated/android/c++/JUserInterfaceSizeClass.hpp +61 -0
  38. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/Func_void_SizeClass.kt +78 -0
  39. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/Func_void_std__optional_HingeState_.kt +78 -0
  40. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/HingeState.kt +56 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/HingeStatus.kt +25 -0
  42. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/HybridOneAdaptiveSpec.kt +87 -0
  43. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/NetworkStateType.kt +2 -2
  44. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/SizeClass.kt +56 -0
  45. package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/UserInterfaceSizeClass.kt +24 -0
  46. package/nitrogen/generated/ios/One-Swift-Cxx-Bridge.cpp +49 -16
  47. package/nitrogen/generated/ios/One-Swift-Cxx-Bridge.hpp +201 -53
  48. package/nitrogen/generated/ios/One-Swift-Cxx-Umbrella.hpp +17 -0
  49. package/nitrogen/generated/ios/OneAutolinking.mm +8 -0
  50. package/nitrogen/generated/ios/OneAutolinking.swift +12 -0
  51. package/nitrogen/generated/ios/c++/HybridOneAdaptiveSpecSwift.cpp +11 -0
  52. package/nitrogen/generated/ios/c++/HybridOneAdaptiveSpecSwift.hpp +135 -0
  53. package/nitrogen/generated/ios/swift/Func_void_SizeClass.swift +46 -0
  54. package/nitrogen/generated/ios/swift/Func_void_std__optional_HingeState_.swift +46 -0
  55. package/nitrogen/generated/ios/swift/HingeState.swift +34 -0
  56. package/nitrogen/generated/ios/swift/HingeStatus.swift +48 -0
  57. package/nitrogen/generated/ios/swift/HybridOneAdaptiveSpec.swift +60 -0
  58. package/nitrogen/generated/ios/swift/HybridOneAdaptiveSpec_cxx.swift +246 -0
  59. package/nitrogen/generated/ios/swift/NetworkStateType.swift +4 -4
  60. package/nitrogen/generated/ios/swift/SizeClass.swift +34 -0
  61. package/nitrogen/generated/ios/swift/UserInterfaceSizeClass.swift +44 -0
  62. package/nitrogen/generated/shared/c++/HingeState.hpp +88 -0
  63. package/nitrogen/generated/shared/c++/HingeStatus.hpp +84 -0
  64. package/nitrogen/generated/shared/c++/HybridOneAdaptiveSpec.cpp +26 -0
  65. package/nitrogen/generated/shared/c++/HybridOneAdaptiveSpec.hpp +74 -0
  66. package/nitrogen/generated/shared/c++/NetworkStateType.hpp +5 -5
  67. package/nitrogen/generated/shared/c++/SizeClass.hpp +88 -0
  68. package/nitrogen/generated/shared/c++/UserInterfaceSizeClass.hpp +80 -0
  69. package/package.json +10 -10
  70. package/src/platform/adaptive/index.native.ts +99 -66
  71. package/src/platform/specs/OneAdaptive.nitro.ts +18 -0
  72. package/src/vite/plugins/swiftPackagePlugin.ts +9 -1
  73. package/types/platform/adaptive/index.native.d.ts +7 -3
  74. package/types/platform/adaptive/index.native.d.ts.map +1 -1
  75. package/types/platform/specs/OneAdaptive.nitro.d.ts +14 -0
  76. package/types/platform/specs/OneAdaptive.nitro.d.ts.map +1 -0
  77. package/types/vite/plugins/swiftPackagePlugin.d.ts.map +1 -1
  78. package/ios/OneNativeAdaptive.h +0 -5
  79. package/ios/OneNativeAdaptive.mm +0 -96
  80. package/ios/OneNativeAdaptiveBridge.swift +0 -134
@@ -0,0 +1,392 @@
1
+ package com.margelo.nitro.one
2
+
3
+ import android.app.Activity
4
+ import android.content.ComponentCallbacks
5
+ import android.content.Context
6
+ import android.content.res.Configuration
7
+ import android.hardware.Sensor
8
+ import android.hardware.SensorEvent
9
+ import android.hardware.SensorEventListener
10
+ import android.hardware.SensorManager
11
+ import android.os.Handler
12
+ import android.os.Looper
13
+ import androidx.core.content.ContextCompat
14
+ import androidx.core.util.Consumer
15
+ import androidx.window.WindowSdkExtensions
16
+ import androidx.window.java.layout.WindowInfoTrackerCallbackAdapter
17
+ import androidx.window.layout.FoldingFeature
18
+ import androidx.window.layout.WindowInfoTracker
19
+ import androidx.window.layout.WindowLayoutInfo
20
+ import androidx.window.layout.WindowMetricsCalculator
21
+ import com.margelo.nitro.NitroModules
22
+ import com.margelo.nitro.core.Promise
23
+
24
+ // window size class and hinge state, the android half of OneAdaptive. size
25
+ // classes come from the current activity window's WindowMetrics against the
26
+ // Jetpack WindowSizeClass breakpoints (width compact below 600dp, height
27
+ // compact below 480dp, else regular) and re-emit on configuration and
28
+ // window-layout changes. hinge status comes from the WindowInfoTracker
29
+ // FoldingFeature (FLAT fullyOpen, HALF_OPENED partiallyOpen) with the angle
30
+ // from the hinge-angle sensor in radians; a hinge sensor with no
31
+ // FoldingFeature in the current window reads closed, and a device with no
32
+ // hinge sensor reads null. the first listener starts the monitors and the
33
+ // last removal stops them, including the sensor.
34
+ class HybridOneAdaptive : HybridOneAdaptiveSpec() {
35
+ private val sizeClassListeners = mutableMapOf<Int, (SizeClass) -> Unit>()
36
+ private val hingeListeners = mutableMapOf<Int, (HingeState?) -> Unit>()
37
+ private var nextListenerId = 0
38
+
39
+ private var configCallbacks: ComponentCallbacks? = null
40
+ private var layoutTracker: WindowInfoTrackerCallbackAdapter? = null
41
+ private val layoutConsumer = Consumer<WindowLayoutInfo> { info ->
42
+ synchronized(this) {
43
+ foldingFeatures = info.displayFeatures.filterIsInstance<FoldingFeature>()
44
+ }
45
+ emitSizeClassIfChanged()
46
+ emitHinge()
47
+ }
48
+ private var foldingFeatures: List<FoldingFeature> = emptyList()
49
+
50
+ private var sensorListener: SensorEventListener? = null
51
+ private var lastAngleDeg: Float? = null
52
+ private var hingeSensorChecked = false
53
+ private var hingeSensor: Sensor? = null
54
+
55
+ private var lastSizeClass: SizeClass? = null
56
+ private var lastHinge: HingeState? = null
57
+ private var lastHingeSet = false
58
+
59
+ private fun activity(): Activity? =
60
+ NitroModules.applicationContext?.currentActivity
61
+
62
+ private fun appContext(): Context? = NitroModules.applicationContext
63
+
64
+ private fun computeSizeClass(): SizeClass {
65
+ val current = activity()
66
+ ?: return SizeClass(UserInterfaceSizeClass.UNSPECIFIED, UserInterfaceSizeClass.UNSPECIFIED)
67
+ return try {
68
+ val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(current)
69
+ val density = current.resources.displayMetrics.density
70
+ if (density <= 0) {
71
+ return SizeClass(UserInterfaceSizeClass.UNSPECIFIED, UserInterfaceSizeClass.UNSPECIFIED)
72
+ }
73
+ val widthDp = metrics.bounds.width() / density
74
+ val heightDp = metrics.bounds.height() / density
75
+ SizeClass(
76
+ if (widthDp < 600) UserInterfaceSizeClass.COMPACT else UserInterfaceSizeClass.REGULAR,
77
+ if (heightDp < 480) UserInterfaceSizeClass.COMPACT else UserInterfaceSizeClass.REGULAR
78
+ )
79
+ } catch (e: Exception) {
80
+ throw OneNativeError("E_ADAPTIVE_SIZE_CLASS", "Adaptive.getSizeClass: ${e.message}")
81
+ }
82
+ }
83
+
84
+ private fun hasHingeSensor(): Boolean {
85
+ synchronized(this) {
86
+ if (hingeSensorChecked) return hingeSensor != null
87
+ hingeSensorChecked = true
88
+ hingeSensor =
89
+ try {
90
+ val manager = appContext()?.getSystemService(Context.SENSOR_SERVICE) as? SensorManager
91
+ manager?.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
92
+ } catch (e: Exception) {
93
+ null
94
+ }
95
+ return hingeSensor != null
96
+ }
97
+ }
98
+
99
+ private fun currentFoldingFeatures(): List<FoldingFeature> {
100
+ synchronized(this) {
101
+ if (foldingFeatures.isNotEmpty()) return foldingFeatures
102
+ }
103
+ // one-shot read before any layout callback has landed.
104
+ return try {
105
+ val context = appContext()
106
+ val current = activity()
107
+ if (context == null || current == null) emptyList()
108
+ else if (WindowSdkExtensions.getInstance().extensionVersion < 9) emptyList()
109
+ else {
110
+ WindowInfoTracker.getOrCreate(context)
111
+ .getCurrentWindowLayoutInfo(current)
112
+ .displayFeatures.filterIsInstance<FoldingFeature>()
113
+ }
114
+ } catch (e: Exception) {
115
+ emptyList()
116
+ }
117
+ }
118
+
119
+ private fun computeHinge(): HingeState? {
120
+ if (!hasHingeSensor()) return null
121
+ val angleRad =
122
+ synchronized(this) { lastAngleDeg }?.let { (it * Math.PI / 180.0) }
123
+ val features = currentFoldingFeatures()
124
+ val feature = features.firstOrNull()
125
+ return when (feature?.state) {
126
+ FoldingFeature.State.FLAT ->
127
+ HingeState(HingeStatus.FULLYOPEN, angleRad ?: Math.PI)
128
+ FoldingFeature.State.HALF_OPENED ->
129
+ HingeState(HingeStatus.PARTIALLYOPEN, angleRad ?: (Math.PI / 2.0))
130
+ else -> HingeState(HingeStatus.CLOSED, angleRad ?: 0.0)
131
+ }
132
+ }
133
+
134
+ override fun getSizeClass(): Promise<SizeClass> =
135
+ Promise.async {
136
+ try {
137
+ computeSizeClass()
138
+ } catch (e: OneNativeError) {
139
+ throw e
140
+ } catch (e: Exception) {
141
+ throw OneNativeError("E_ADAPTIVE_SIZE_CLASS", "Adaptive.getSizeClass: ${e.message}")
142
+ }
143
+ }
144
+
145
+ // synchronous seed for the JS import-time read: the same measurement as
146
+ // getSizeClass/getHinge, unspecified when no activity is attached yet.
147
+ override fun getInitialSizeClass(): SizeClass = computeSizeClass()
148
+
149
+ override fun getInitialHinge(): HingeState? = computeHinge()
150
+
151
+ override fun getHinge(): Promise<HingeState?> =
152
+ Promise.async {
153
+ try {
154
+ computeHinge()
155
+ } catch (e: OneNativeError) {
156
+ throw e
157
+ } catch (e: Exception) {
158
+ throw OneNativeError("E_ADAPTIVE_HINGE", "Adaptive.getHinge: ${e.message}")
159
+ }
160
+ }
161
+
162
+ override fun addSizeClassListener(listener: (sizeClass: SizeClass) -> Unit): () -> Unit {
163
+ val id: Int
164
+ val shouldStart: Boolean
165
+ synchronized(this) {
166
+ id = nextListenerId++
167
+ sizeClassListeners[id] = listener
168
+ shouldStart = sizeClassListeners.size + hingeListeners.size == 1
169
+ }
170
+ if (shouldStart) startMonitors()
171
+ // deliver the current value to the newcomer without racing the monitor.
172
+ try {
173
+ val current = computeSizeClass()
174
+ synchronized(this) {
175
+ if (lastSizeClass == null) lastSizeClass = current
176
+ }
177
+ listener(current)
178
+ } catch (e: Exception) {
179
+ // monitoring continues; the next change still emits.
180
+ }
181
+ return { removeSizeClassListener(id) }
182
+ }
183
+
184
+ override fun addHingeListener(listener: (hinge: HingeState?) -> Unit): () -> Unit {
185
+ val id: Int
186
+ val shouldStart: Boolean
187
+ synchronized(this) {
188
+ id = nextListenerId++
189
+ hingeListeners[id] = listener
190
+ shouldStart = sizeClassListeners.size + hingeListeners.size == 1
191
+ }
192
+ if (shouldStart) startMonitors() else startSensorIfNeeded()
193
+ try {
194
+ val current = computeHinge()
195
+ synchronized(this) {
196
+ if (!lastHingeSet) {
197
+ lastHinge = current
198
+ lastHingeSet = true
199
+ }
200
+ }
201
+ listener(current)
202
+ } catch (e: Exception) {
203
+ }
204
+ return { removeHingeListener(id) }
205
+ }
206
+
207
+ private fun removeSizeClassListener(id: Int) {
208
+ val shouldStop: Boolean
209
+ synchronized(this) {
210
+ sizeClassListeners.remove(id)
211
+ shouldStop = sizeClassListeners.isEmpty() && hingeListeners.isEmpty()
212
+ }
213
+ if (shouldStop) stopMonitors()
214
+ }
215
+
216
+ private fun removeHingeListener(id: Int) {
217
+ val shouldStop: Boolean
218
+ val stopSensor: Boolean
219
+ synchronized(this) {
220
+ hingeListeners.remove(id)
221
+ shouldStop = sizeClassListeners.isEmpty() && hingeListeners.isEmpty()
222
+ stopSensor = hingeListeners.isEmpty()
223
+ }
224
+ if (stopSensor) stopSensor()
225
+ if (shouldStop) stopMonitors()
226
+ }
227
+
228
+ private fun startMonitors() {
229
+ val context = appContext() ?: return
230
+ synchronized(this) {
231
+ if (configCallbacks == null) {
232
+ val callbacks =
233
+ object : ComponentCallbacks {
234
+ override fun onConfigurationChanged(newConfig: Configuration) {
235
+ emitSizeClassIfChanged()
236
+ emitHinge()
237
+ }
238
+
239
+ override fun onLowMemory() = Unit
240
+ }
241
+ configCallbacks = callbacks
242
+ context.registerComponentCallbacks(callbacks)
243
+ }
244
+ }
245
+ startLayoutTracking()
246
+ startSensorIfNeeded()
247
+ }
248
+
249
+ private fun startLayoutTracking() {
250
+ synchronized(this) {
251
+ if (layoutTracker != null) return
252
+ }
253
+ try {
254
+ val context = appContext() ?: return
255
+ val current = activity() ?: return
256
+ val tracker = WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(context))
257
+ tracker.addWindowLayoutInfoListener(
258
+ current, ContextCompat.getMainExecutor(context), layoutConsumer
259
+ )
260
+ synchronized(this) {
261
+ layoutTracker = tracker
262
+ }
263
+ } catch (e: Exception) {
264
+ // window tracking is best-effort; configuration changes still emit.
265
+ }
266
+ }
267
+
268
+ private fun startSensorIfNeeded() {
269
+ val hasListeners: Boolean
270
+ synchronized(this) {
271
+ hasListeners = hingeListeners.isNotEmpty()
272
+ if (!hasListeners || sensorListener != null) return
273
+ }
274
+ if (!hasHingeSensor()) return
275
+ try {
276
+ val manager = appContext()?.getSystemService(Context.SENSOR_SERVICE) as? SensorManager
277
+ val sensor = synchronized(this) { hingeSensor } ?: return
278
+ val listener =
279
+ object : SensorEventListener {
280
+ override fun onSensorChanged(event: SensorEvent) {
281
+ val degrees = event.values.firstOrNull() ?: return
282
+ synchronized(this@HybridOneAdaptive) {
283
+ lastAngleDeg = degrees
284
+ }
285
+ emitHinge()
286
+ }
287
+
288
+ override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) = Unit
289
+ }
290
+ manager?.registerListener(
291
+ listener, sensor, SensorManager.SENSOR_DELAY_NORMAL,
292
+ Handler(Looper.getMainLooper())
293
+ )
294
+ synchronized(this) {
295
+ // a second caller may have registered while we were working.
296
+ if (sensorListener == null) sensorListener = listener
297
+ else manager?.unregisterListener(listener)
298
+ }
299
+ } catch (e: Exception) {
300
+ // hinge angle stays at its default; status still reports.
301
+ }
302
+ }
303
+
304
+ private fun stopSensor() {
305
+ val listener: SensorEventListener?
306
+ synchronized(this) {
307
+ listener = sensorListener
308
+ sensorListener = null
309
+ }
310
+ if (listener != null) {
311
+ try {
312
+ val manager = appContext()?.getSystemService(Context.SENSOR_SERVICE) as? SensorManager
313
+ manager?.unregisterListener(listener)
314
+ } catch (e: Exception) {
315
+ }
316
+ }
317
+ }
318
+
319
+ private fun stopMonitors() {
320
+ val callbacks: ComponentCallbacks?
321
+ val tracker: WindowInfoTrackerCallbackAdapter?
322
+ synchronized(this) {
323
+ callbacks = configCallbacks
324
+ configCallbacks = null
325
+ tracker = layoutTracker
326
+ layoutTracker = null
327
+ }
328
+ if (callbacks != null) {
329
+ try {
330
+ appContext()?.unregisterComponentCallbacks(callbacks)
331
+ } catch (e: Exception) {
332
+ }
333
+ }
334
+ if (tracker != null) {
335
+ try {
336
+ tracker.removeWindowLayoutInfoListener(layoutConsumer)
337
+ } catch (e: Exception) {
338
+ }
339
+ }
340
+ stopSensor()
341
+ }
342
+
343
+ private fun emitSizeClassIfChanged() {
344
+ val next: SizeClass
345
+ try {
346
+ next = computeSizeClass()
347
+ } catch (e: Exception) {
348
+ return
349
+ }
350
+ // a rotation can detach the activity before the new window exists;
351
+ // reattach layout tracking once it is back.
352
+ if (next.horizontal != UserInterfaceSizeClass.UNSPECIFIED) startLayoutTracking()
353
+ val changed: Boolean
354
+ synchronized(this) {
355
+ changed = lastSizeClass == null || lastSizeClass != next
356
+ if (changed) lastSizeClass = next
357
+ }
358
+ if (!changed) return
359
+ val current = synchronized(this) { sizeClassListeners.values.toList() }
360
+ current.forEach {
361
+ try {
362
+ it(next)
363
+ } catch (e: Exception) {
364
+ }
365
+ }
366
+ }
367
+
368
+ private fun emitHinge() {
369
+ val next: HingeState?
370
+ try {
371
+ next = computeHinge()
372
+ } catch (e: Exception) {
373
+ return
374
+ }
375
+ val changed: Boolean
376
+ synchronized(this) {
377
+ changed = !lastHingeSet || lastHinge != next
378
+ if (changed) {
379
+ lastHinge = next
380
+ lastHingeSet = true
381
+ }
382
+ }
383
+ if (!changed) return
384
+ val current = synchronized(this) { hingeListeners.values.toList() }
385
+ current.forEach {
386
+ try {
387
+ it(next)
388
+ } catch (e: Exception) {
389
+ }
390
+ }
391
+ }
392
+ }
@@ -37,86 +37,112 @@ __export(index_native_exports, {
37
37
  });
38
38
  module.exports = __toCommonJS(index_native_exports);
39
39
  var import_react = require("react");
40
- var import_react_native = require("react-native");
40
+ var import_react_native_nitro_modules = require("react-native-nitro-modules");
41
41
  var ReservedRegions = __toESM(require("./ReservedRegions.native.js"), 1);
42
- var NativeAdaptive = import_react_native.NativeModules.OneNativeAdaptive;
42
+ var hybrid;
43
+ function native() {
44
+ if (hybrid === void 0) {
45
+ hybrid = import_react_native_nitro_modules.NitroModules.createHybridObject("OneAdaptive");
46
+ }
47
+ return hybrid;
48
+ }
43
49
  var DEFAULT_SIZE_CLASS = {
44
50
  horizontal: "unspecified",
45
51
  vertical: "unspecified"
46
52
  };
47
- function getInitialConstants() {
48
- var _ref, _ref1;
49
- if (import_react_native.Platform.OS !== "ios" || !NativeAdaptive) {
50
- return {
51
- initialSizeClass: DEFAULT_SIZE_CLASS,
52
- initialHinge: null
53
- };
54
- }
55
- var constants = typeof NativeAdaptive.getConstants === "function" ? NativeAdaptive.getConstants() : NativeAdaptive;
56
- return {
57
- initialSizeClass: (_ref = constants === null || constants === void 0 ? void 0 : constants.initialSizeClass) !== null && _ref !== void 0 ? _ref : DEFAULT_SIZE_CLASS,
58
- initialHinge: (_ref1 = constants === null || constants === void 0 ? void 0 : constants.initialHinge) !== null && _ref1 !== void 0 ? _ref1 : null
59
- };
53
+ var currentSizeClass = DEFAULT_SIZE_CLASS;
54
+ var currentHinge = null;
55
+ function seedFromNative() {
56
+ var _created_getInitialHinge;
57
+ var created = native();
58
+ currentSizeClass = created.getInitialSizeClass();
59
+ currentHinge = (_created_getInitialHinge = created.getInitialHinge()) !== null && _created_getInitialHinge !== void 0 ? _created_getInitialHinge : null;
60
60
  }
61
- var emitter = import_react_native.Platform.OS === "ios" && NativeAdaptive ? new import_react_native.NativeEventEmitter(NativeAdaptive) : null;
62
- var currentSizeClass = getInitialConstants().initialSizeClass;
63
- var currentHinge = getInitialConstants().initialHinge;
61
+ seedFromNative();
64
62
  var sizeClassListeners = /* @__PURE__ */ new Set();
65
63
  var hingeListeners = /* @__PURE__ */ new Set();
66
- if (emitter) {
67
- emitter.addListener("oneNativeSizeClassDidChange", function(event) {
68
- currentSizeClass = event;
69
- sizeClassListeners.forEach(function(listener) {
70
- return listener();
71
- });
64
+ var sizeClassRemove;
65
+ var hingeRemove;
66
+ function sizesEqual(a, b) {
67
+ return a.horizontal === b.horizontal && a.vertical === b.vertical;
68
+ }
69
+ function hingesEqual(a, b) {
70
+ return a === b || a != null && b != null && a.status === b.status && a.angle === b.angle;
71
+ }
72
+ function setSizeClass(next) {
73
+ if (sizesEqual(currentSizeClass, next)) return;
74
+ currentSizeClass = next;
75
+ sizeClassListeners.forEach(function(listener) {
76
+ return listener();
72
77
  });
73
- emitter.addListener("oneNativeHingeDidChange", function(event) {
74
- currentHinge = event;
75
- hingeListeners.forEach(function(listener) {
76
- return listener();
77
- });
78
+ }
79
+ function setHinge(next) {
80
+ if (hingesEqual(currentHinge, next)) return;
81
+ currentHinge = next;
82
+ hingeListeners.forEach(function(listener) {
83
+ return listener();
78
84
  });
79
85
  }
86
+ function subscribeSizeClass(onStoreChange) {
87
+ sizeClassListeners.add(onStoreChange);
88
+ if (sizeClassRemove === void 0) {
89
+ var created = native();
90
+ sizeClassRemove = created.addSizeClassListener(setSizeClass);
91
+ created.getSizeClass().then(setSizeClass);
92
+ }
93
+ return function() {
94
+ sizeClassListeners.delete(onStoreChange);
95
+ if (sizeClassListeners.size === 0) {
96
+ sizeClassRemove === null || sizeClassRemove === void 0 ? void 0 : sizeClassRemove();
97
+ sizeClassRemove = void 0;
98
+ }
99
+ };
100
+ }
101
+ function subscribeHinge(onStoreChange) {
102
+ hingeListeners.add(onStoreChange);
103
+ if (hingeRemove === void 0) {
104
+ var created = native();
105
+ hingeRemove = created.addHingeListener(function(hinge) {
106
+ return setHinge(hinge !== null && hinge !== void 0 ? hinge : null);
107
+ });
108
+ created.getHinge().then(function(hinge) {
109
+ return setHinge(hinge !== null && hinge !== void 0 ? hinge : null);
110
+ });
111
+ }
112
+ return function() {
113
+ hingeListeners.delete(onStoreChange);
114
+ if (hingeListeners.size === 0) {
115
+ hingeRemove === null || hingeRemove === void 0 ? void 0 : hingeRemove();
116
+ hingeRemove = void 0;
117
+ }
118
+ };
119
+ }
80
120
  function useSizeClass() {
81
- return (0, import_react.useSyncExternalStore)(function(onStoreChange) {
82
- sizeClassListeners.add(onStoreChange);
83
- return function() {
84
- sizeClassListeners.delete(onStoreChange);
85
- };
86
- }, function() {
121
+ return (0, import_react.useSyncExternalStore)(subscribeSizeClass, function() {
87
122
  return currentSizeClass;
88
123
  }, function() {
89
124
  return DEFAULT_SIZE_CLASS;
90
125
  });
91
126
  }
92
- async function getSizeClass() {
93
- if (import_react_native.Platform.OS !== "ios" || !(NativeAdaptive === null || NativeAdaptive === void 0 ? void 0 : NativeAdaptive.getSizeClass)) {
94
- return DEFAULT_SIZE_CLASS;
95
- }
96
- return await NativeAdaptive.getSizeClass();
127
+ function getSizeClass() {
128
+ return native().getSizeClass();
97
129
  }
98
130
  function useHinge() {
99
- return (0, import_react.useSyncExternalStore)(function(onStoreChange) {
100
- hingeListeners.add(onStoreChange);
101
- return function() {
102
- hingeListeners.delete(onStoreChange);
103
- };
104
- }, function() {
131
+ return (0, import_react.useSyncExternalStore)(subscribeHinge, function() {
105
132
  return currentHinge;
106
133
  }, function() {
107
134
  return null;
108
135
  });
109
136
  }
110
137
  async function getHinge() {
111
- if (import_react_native.Platform.OS !== "ios" || !(NativeAdaptive === null || NativeAdaptive === void 0 ? void 0 : NativeAdaptive.getHinge)) {
112
- return null;
113
- }
114
- return await NativeAdaptive.getHinge();
138
+ var _ref;
139
+ return (_ref = await native().getHinge()) !== null && _ref !== void 0 ? _ref : null;
115
140
  }
116
141
  function onHingeChange(callback) {
117
- if (!emitter) return function() {};
118
- var sub = emitter.addListener("oneNativeHingeDidChange", callback);
142
+ var remove = native().addHingeListener(function(hinge) {
143
+ return callback(hinge !== null && hinge !== void 0 ? hinge : null);
144
+ });
119
145
  return function() {
120
- return sub.remove();
146
+ return remove();
121
147
  };
122
148
  }