@iternio/react-native-auto-play 0.5.7 → 0.5.8
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/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlay.kt +0 -1
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt +29 -116
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VoiceInputManager.kt +17 -1
- package/ios/templates/MapTemplate.swift +14 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.js +1 -2
- package/lib/scenes/AutoPlayCluster.js +1 -6
- package/lib/templates/MapTemplate.js +1 -6
- package/lib/types/RootComponent.d.ts +0 -4
- package/nitro.json +0 -6
- package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +0 -2
- package/nitrogen/generated/android/ReactNativeAutoPlayOnLoad.cpp +0 -18
- package/package.json +1 -1
- package/src/index.ts +1 -2
- package/src/scenes/AutoPlayCluster.ts +1 -6
- package/src/templates/MapTemplate.ts +1 -6
- package/src/types/RootComponent.ts +0 -4
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidWindowInformation.kt +0 -49
- package/lib/HybridAutoPlay.d.ts +0 -2
- package/lib/HybridAutoPlay.js +0 -2
- package/lib/components/OnAppearedChildRenderer.d.ts +0 -10
- package/lib/components/OnAppearedChildRenderer.js +0 -26
- package/lib/components/WindowInformationWrapper.d.ts +0 -15
- package/lib/components/WindowInformationWrapper.js +0 -17
- package/lib/hooks/useIsAutoPlayFocused.d.ts +0 -7
- package/lib/hooks/useIsAutoPlayFocused.js +0 -20
- package/lib/hybrid/HybridAndroidWindowInformation.android.d.ts +0 -2
- package/lib/hybrid/HybridAndroidWindowInformation.android.js +0 -2
- package/lib/hybrid/HybridAndroidWindowInformation.d.ts +0 -2
- package/lib/hybrid/HybridAndroidWindowInformation.js +0 -1
- package/lib/hybrid.d.ts +0 -2
- package/lib/hybrid.js +0 -2
- package/lib/specs/AndroidWindowInformation.nitro.d.ts +0 -22
- package/lib/specs/AndroidWindowInformation.nitro.js +0 -1
- package/lib/specs/AutomotivePermissionRequestTemplate.d.ts +0 -11
- package/lib/specs/AutomotivePermissionRequestTemplate.js +0 -1
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.d.ts +0 -11
- package/lib/specs/AutomotivePermissionRequestTemplate.nitro.js +0 -1
- package/lib/templates/AutomotivePermissionRequestTemplate.d.ts +0 -23
- package/lib/templates/AutomotivePermissionRequestTemplate.js +0 -18
- package/lib/types/Glyphmap.d.ts +0 -4105
- package/lib/types/Glyphmap.js +0 -4105
- package/lib/utils/NitroOptionsPanel.d.ts +0 -67
- package/lib/utils/NitroOptionsPanel.js +0 -48
- package/nitrogen/generated/android/c++/JFunc_void_WindowInformation.hpp +0 -77
- package/nitrogen/generated/android/c++/JHybridAndroidWindowInformationSpec.cpp +0 -68
- package/nitrogen/generated/android/c++/JHybridAndroidWindowInformationSpec.hpp +0 -63
- package/nitrogen/generated/android/c++/JWindowInformation.hpp +0 -65
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/Func_void_WindowInformation.kt +0 -80
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidWindowInformationSpec.kt +0 -59
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/WindowInformation.kt +0 -61
- package/nitrogen/generated/shared/c++/HybridAndroidWindowInformationSpec.cpp +0 -21
- package/nitrogen/generated/shared/c++/HybridAndroidWindowInformationSpec.hpp +0 -65
- package/nitrogen/generated/shared/c++/WindowInformation.hpp +0 -91
- package/src/components/WindowInformationWrapper.tsx +0 -30
- package/src/hybrid/HybridAndroidWindowInformation.android.ts +0 -5
- package/src/hybrid/HybridAndroidWindowInformation.ts +0 -3
- package/src/specs/AndroidWindowInformation.nitro.ts +0 -24
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAutoPlay.kt
CHANGED
|
@@ -264,7 +264,6 @@ class HybridAutoPlay : HybridAutoPlaySpec() {
|
|
|
264
264
|
fun removeListeners(templateId: String) {
|
|
265
265
|
renderStateListeners.remove(templateId)
|
|
266
266
|
safeAreaInsetsListeners.remove(templateId)
|
|
267
|
-
HybridAndroidWindowInformation.removeListeners(templateId)
|
|
268
267
|
}
|
|
269
268
|
|
|
270
269
|
fun emit(event: EventName) {
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt
CHANGED
|
@@ -42,24 +42,20 @@ class VirtualRenderer(
|
|
|
42
42
|
) {
|
|
43
43
|
private var virtualDisplay: VirtualDisplay? = null
|
|
44
44
|
|
|
45
|
-
private var reactSurfaceImpl: ReactSurfaceImpl
|
|
45
|
+
private lateinit var reactSurfaceImpl: ReactSurfaceImpl
|
|
46
46
|
private var reactSurfaceView: ReactSurfaceView? = null
|
|
47
47
|
private var reactSurfaceId: Int? = null
|
|
48
48
|
|
|
49
49
|
private var height: Int = 0
|
|
50
50
|
private var width: Int = 0
|
|
51
|
-
private var dpi: Int = 0
|
|
52
51
|
|
|
53
52
|
private var splashWillDisappear = false
|
|
54
53
|
|
|
55
54
|
/**
|
|
56
|
-
* scale is the actual scale factor required to calculate proper insets and is passed in initialProperties to js side
|
|
57
|
-
* The density is derived from the surface container's dpi so it always matches the VirtualDisplay,
|
|
58
|
-
* and is recomputed on every onSurfaceAvailable since the host may recreate the surface with new metrics.
|
|
55
|
+
* scale is the actual scale factor required to calculate proper insets and is passed in initialProperties to js side
|
|
59
56
|
*/
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
private set
|
|
57
|
+
private val virtualScreenDensity = context.resources.displayMetrics.density
|
|
58
|
+
val scale = BuildConfig.SCALE_FACTOR * virtualScreenDensity
|
|
63
59
|
|
|
64
60
|
private fun isSurfaceReady(surfaceContainer: SurfaceContainer): Boolean {
|
|
65
61
|
return surfaceContainer.surface != null && surfaceContainer.dpi != 0 && surfaceContainer.height != 0 && surfaceContainer.width != 0
|
|
@@ -72,7 +68,7 @@ class VirtualRenderer(
|
|
|
72
68
|
val areaDebouncer = Debouncer(200)
|
|
73
69
|
|
|
74
70
|
// 12dp seems to be the default margin on AA for the ETA widget and the maneuver so use it as fallback
|
|
75
|
-
val defaultMargin
|
|
71
|
+
val defaultMargin = (12.0 * context.resources.displayMetrics.density).toInt()
|
|
76
72
|
var minMargin = Int.MAX_VALUE
|
|
77
73
|
var stableArea = Rect(0, 0, 0, 0)
|
|
78
74
|
var visibleArea = Rect(0, 0, 0, 0)
|
|
@@ -82,16 +78,25 @@ class VirtualRenderer(
|
|
|
82
78
|
return
|
|
83
79
|
}
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
val manager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
|
82
|
+
virtualDisplay?.release()
|
|
83
|
+
virtualDisplay = manager.createVirtualDisplay(
|
|
84
|
+
moduleName,
|
|
85
|
+
surfaceContainer.width,
|
|
86
|
+
surfaceContainer.height,
|
|
87
|
+
surfaceContainer.dpi,
|
|
88
|
+
surfaceContainer.surface,
|
|
89
|
+
DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
val display = virtualDisplay?.display ?: return
|
|
93
|
+
height = surfaceContainer.height
|
|
94
|
+
width = surfaceContainer.width
|
|
95
|
+
|
|
96
|
+
initRenderer(display)
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
override fun onSurfaceDestroyed(surfaceContainer: SurfaceContainer) {
|
|
89
|
-
// the host re-emits visible/stable areas for the next surface, so drop state derived
|
|
90
|
-
// from the old surface instead of combining it with the new dimensions
|
|
91
|
-
minMargin = Int.MAX_VALUE
|
|
92
|
-
stableArea = Rect(0, 0, 0, 0)
|
|
93
|
-
visibleArea = Rect(0, 0, 0, 0)
|
|
94
|
-
|
|
95
100
|
virtualDisplay?.release()
|
|
96
101
|
virtualDisplay = null
|
|
97
102
|
}
|
|
@@ -225,46 +230,6 @@ class VirtualRenderer(
|
|
|
225
230
|
})
|
|
226
231
|
}
|
|
227
232
|
|
|
228
|
-
@MainThread
|
|
229
|
-
private fun applySurface(surfaceContainer: SurfaceContainer) {
|
|
230
|
-
val surfaceWidth = surfaceContainer.width
|
|
231
|
-
val surfaceHeight = surfaceContainer.height
|
|
232
|
-
|
|
233
|
-
// The host signals surface size changes only via onSurfaceDestroyed -> onSurfaceAvailable
|
|
234
|
-
// with new dimensions, so all size-derived state (layout params, scale, Fabric measure
|
|
235
|
-
// specs) must be recomputed when the metrics differ from the current ones. The react
|
|
236
|
-
// surface itself is kept alive so JS state survives the resize; the JS side is informed
|
|
237
|
-
// via the windowInformation listener since the window initial prop stays stale.
|
|
238
|
-
val isResize = reactSurfaceView != null && (width != surfaceWidth
|
|
239
|
-
|| height != surfaceHeight || dpi != surfaceContainer.dpi)
|
|
240
|
-
|
|
241
|
-
val manager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
|
242
|
-
virtualDisplay?.release()
|
|
243
|
-
virtualDisplay = manager.createVirtualDisplay(
|
|
244
|
-
moduleName,
|
|
245
|
-
surfaceWidth,
|
|
246
|
-
surfaceHeight,
|
|
247
|
-
surfaceContainer.dpi,
|
|
248
|
-
surfaceContainer.surface,
|
|
249
|
-
DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION,
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
val display = virtualDisplay?.display ?: return
|
|
253
|
-
height = surfaceHeight
|
|
254
|
-
width = surfaceWidth
|
|
255
|
-
dpi = surfaceContainer.dpi
|
|
256
|
-
virtualScreenDensity = surfaceContainer.dpi / 160f
|
|
257
|
-
scale = BuildConfig.SCALE_FACTOR * virtualScreenDensity
|
|
258
|
-
|
|
259
|
-
initRenderer(display)
|
|
260
|
-
|
|
261
|
-
if (isResize) {
|
|
262
|
-
getWindowInformation(moduleName)?.let {
|
|
263
|
-
HybridAndroidWindowInformation.emitWindowInformation(moduleName, it)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
233
|
private fun getMapTemplateConfig(): MapTemplateConfig? {
|
|
269
234
|
val screenManager = AndroidAutoScreen.getScreen(moduleName)?.screenManager ?: return null
|
|
270
235
|
val marker = screenManager.top.marker ?: return null
|
|
@@ -325,48 +290,19 @@ class VirtualRenderer(
|
|
|
325
290
|
val appTheme = context.applicationContext.applicationInfo.theme
|
|
326
291
|
val themedContext = ContextThemeWrapper(context.applicationContext, appTheme)
|
|
327
292
|
|
|
328
|
-
|
|
329
|
-
themedContext, moduleName, initialProperties
|
|
330
|
-
).also {
|
|
331
|
-
reactSurfaceImpl = it
|
|
293
|
+
if (!this@VirtualRenderer::reactSurfaceImpl.isInitialized) {
|
|
294
|
+
reactSurfaceImpl = ReactSurfaceImpl(themedContext, moduleName, initialProperties)
|
|
332
295
|
}
|
|
333
296
|
|
|
334
297
|
var splashScreenView: View? = null
|
|
335
298
|
|
|
336
299
|
reactSurfaceView?.let {
|
|
337
300
|
(it.parent as ViewGroup).removeView(it)
|
|
338
|
-
|
|
339
|
-
// the surface may have been recreated with new dimensions, so reapply all
|
|
340
|
-
// size-derived values and push the new layout specs into the running Fabric surface
|
|
341
|
-
it.layoutParams = FrameLayout.LayoutParams(
|
|
342
|
-
(width / reactNativeScale).toInt(), (height / reactNativeScale).toInt()
|
|
343
|
-
)
|
|
344
|
-
it.scaleX = reactNativeScale
|
|
345
|
-
it.scaleY = reactNativeScale
|
|
346
|
-
|
|
347
|
-
reactSurfaceId?.let { surfaceId ->
|
|
348
|
-
fabricUiManager.updateRootLayoutSpecs(
|
|
349
|
-
surfaceId,
|
|
350
|
-
View.MeasureSpec.makeMeasureSpec(
|
|
351
|
-
(width / reactNativeScale).toInt(), View.MeasureSpec.EXACTLY
|
|
352
|
-
),
|
|
353
|
-
View.MeasureSpec.makeMeasureSpec(
|
|
354
|
-
(height / reactNativeScale).toInt(), View.MeasureSpec.EXACTLY
|
|
355
|
-
),
|
|
356
|
-
0,
|
|
357
|
-
0
|
|
358
|
-
)
|
|
359
|
-
}
|
|
360
301
|
} ?: run {
|
|
361
|
-
// skip the splash when the surface is rebuilt after a resize, content is already loaded
|
|
362
302
|
splashScreenView =
|
|
363
|
-
if (isCluster
|
|
364
|
-
getClusterSplashScreen(themedContext, height, width)
|
|
365
|
-
} else {
|
|
366
|
-
null
|
|
367
|
-
}
|
|
303
|
+
if (isCluster) getClusterSplashScreen(themedContext, height, width) else null
|
|
368
304
|
|
|
369
|
-
val surfaceView = ReactSurfaceView(themedContext,
|
|
305
|
+
val surfaceView = ReactSurfaceView(themedContext, reactSurfaceImpl).apply {
|
|
370
306
|
layoutParams = FrameLayout.LayoutParams(
|
|
371
307
|
(width / reactNativeScale).toInt(), (height / reactNativeScale).toInt()
|
|
372
308
|
)
|
|
@@ -466,7 +402,10 @@ class VirtualRenderer(
|
|
|
466
402
|
}
|
|
467
403
|
|
|
468
404
|
@MainThread
|
|
469
|
-
private fun
|
|
405
|
+
private fun stop() {
|
|
406
|
+
virtualDisplay?.release()
|
|
407
|
+
virtualDisplay = null
|
|
408
|
+
|
|
470
409
|
val uiManager = NitroModules.applicationContext?.let {
|
|
471
410
|
UIManagerHelper.getUIManager(
|
|
472
411
|
it, UIManagerType.FABRIC
|
|
@@ -481,19 +420,6 @@ class VirtualRenderer(
|
|
|
481
420
|
// Fabric already invalidated
|
|
482
421
|
} finally {
|
|
483
422
|
reactSurfaceId = null
|
|
484
|
-
reactSurfaceView = null
|
|
485
|
-
reactSurfaceImpl = null
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
@MainThread
|
|
490
|
-
private fun stop() {
|
|
491
|
-
virtualDisplay?.release()
|
|
492
|
-
virtualDisplay = null
|
|
493
|
-
|
|
494
|
-
try {
|
|
495
|
-
stopReactSurface()
|
|
496
|
-
} finally {
|
|
497
423
|
virtualRenderer.remove(moduleName)
|
|
498
424
|
}
|
|
499
425
|
}
|
|
@@ -507,19 +433,6 @@ class VirtualRenderer(
|
|
|
507
433
|
return virtualRenderer.contains(moduleId)
|
|
508
434
|
}
|
|
509
435
|
|
|
510
|
-
fun getWindowInformation(moduleId: String): WindowInformation? {
|
|
511
|
-
val renderer = virtualRenderer[moduleId] ?: return null
|
|
512
|
-
if (renderer.width == 0 || renderer.height == 0) {
|
|
513
|
-
return null
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return WindowInformation(
|
|
517
|
-
width = (renderer.width / renderer.scale).toInt().toDouble(),
|
|
518
|
-
height = (renderer.height / renderer.scale).toInt().toDouble(),
|
|
519
|
-
scale = renderer.scale.toDouble()
|
|
520
|
-
)
|
|
521
|
-
}
|
|
522
|
-
|
|
523
436
|
fun removeRenderer(moduleId: String) {
|
|
524
437
|
virtualRenderer[moduleId]?.stop()
|
|
525
438
|
virtualRenderer.remove(moduleId)
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VoiceInputManager.kt
CHANGED
|
@@ -23,6 +23,7 @@ import androidx.annotation.RequiresApi
|
|
|
23
23
|
import androidx.car.app.CarContext
|
|
24
24
|
import androidx.car.app.media.CarAudioRecord
|
|
25
25
|
import androidx.core.content.ContextCompat
|
|
26
|
+
import androidx.core.net.toUri
|
|
26
27
|
import com.facebook.react.bridge.UiThreadUtil
|
|
27
28
|
import com.margelo.nitro.NitroModules
|
|
28
29
|
import com.margelo.nitro.core.ArrayBuffer
|
|
@@ -495,7 +496,7 @@ class VoiceInputManager(
|
|
|
495
496
|
.setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
|
|
496
497
|
.build()
|
|
497
498
|
)
|
|
498
|
-
player.setDataSource(context,
|
|
499
|
+
player.setDataSource(context, resolveUri(context, uri))
|
|
499
500
|
player.setOnCompletionListener {
|
|
500
501
|
it.release()
|
|
501
502
|
if (cont.isActive) { cont.resume(Unit) }
|
|
@@ -516,6 +517,21 @@ class VoiceInputManager(
|
|
|
516
517
|
}
|
|
517
518
|
}
|
|
518
519
|
|
|
520
|
+
private fun resolveUri(context: Context, uri: String): Uri {
|
|
521
|
+
val parsed = uri.toUri()
|
|
522
|
+
return if (parsed.scheme != null) {
|
|
523
|
+
// Real URI already (dev/Metro http://, file://, content://, etc.)
|
|
524
|
+
parsed
|
|
525
|
+
} else {
|
|
526
|
+
// Release build: bare raw-resource name from RN's Android asset packager
|
|
527
|
+
val resId = context.resources.getIdentifier(uri, "raw", context.packageName)
|
|
528
|
+
if (resId == 0) {
|
|
529
|
+
throw IllegalArgumentException("Raw resource not found for: $uri")
|
|
530
|
+
}
|
|
531
|
+
"android.resource://${context.packageName}/$resId".toUri()
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
519
535
|
@RequiresApi(Build.VERSION_CODES.O)
|
|
520
536
|
private fun releaseResources() {
|
|
521
537
|
carAudioRecord?.stopRecording()
|
|
@@ -733,7 +733,7 @@ class MapTemplate: AutoPlayHeaderProviding,
|
|
|
733
733
|
Parser.parseTravelEstimates(
|
|
734
734
|
travelEstimates: nitroManeuver.travelEstimates
|
|
735
735
|
),
|
|
736
|
-
for:
|
|
736
|
+
for: sessionManeuvers[maneuverIndex]
|
|
737
737
|
)
|
|
738
738
|
|
|
739
739
|
if index != maneuverIndex {
|
|
@@ -805,6 +805,19 @@ class MapTemplate: AutoPlayHeaderProviding,
|
|
|
805
805
|
}
|
|
806
806
|
|
|
807
807
|
navigationSession.upcomingManeuvers = upcomingManeuvers
|
|
808
|
+
|
|
809
|
+
// CarPlay only applies an estimate update if the maneuver is already active,
|
|
810
|
+
// since we set new upcomingManeuvers we need to apply the latest travelEstimates on the active maneuver here
|
|
811
|
+
if let currentManeuver = navigationSession.upcomingManeuvers.first,
|
|
812
|
+
let currentNitroManeuver = maneuvers.first
|
|
813
|
+
{
|
|
814
|
+
navigationSession.updateEstimates(
|
|
815
|
+
Parser.parseTravelEstimates(
|
|
816
|
+
travelEstimates: currentNitroManeuver.travelEstimates
|
|
817
|
+
),
|
|
818
|
+
for: currentManeuver
|
|
819
|
+
)
|
|
820
|
+
}
|
|
808
821
|
}
|
|
809
822
|
}
|
|
810
823
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { HybridAndroidAutoTelemetry } from './hybrid/HybridAndroidAutoTelemetry';
|
|
2
|
-
import { HybridAndroidWindowInformation } from './hybrid/HybridAndroidWindowInformation';
|
|
3
2
|
import { HybridAutoPlay } from './hybrid/HybridAutoPlay';
|
|
4
3
|
import { HybridVoice } from './hybrid/HybridVoice';
|
|
5
4
|
import type { AndroidAutomotive } from './specs/AndroidAutomotive.nitro';
|
|
6
|
-
export { HybridAndroidAutoTelemetry,
|
|
5
|
+
export { HybridAndroidAutoTelemetry, HybridAutoPlay, HybridVoice };
|
|
7
6
|
export declare const HybridAndroidAutomotive: AndroidAutomotive | null;
|
|
8
7
|
/**
|
|
9
8
|
* These are the static module names for the app running on the mobile device, head unit screen and the CarPlay dashboard.
|
package/lib/index.js
CHANGED
|
@@ -2,11 +2,10 @@ import { Platform } from 'react-native';
|
|
|
2
2
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
3
3
|
import AutoPlayHeadlessJsTask from './AutoPlayHeadlessJsTask';
|
|
4
4
|
import { HybridAndroidAutoTelemetry } from './hybrid/HybridAndroidAutoTelemetry';
|
|
5
|
-
import { HybridAndroidWindowInformation } from './hybrid/HybridAndroidWindowInformation';
|
|
6
5
|
import { HybridAutoPlay } from './hybrid/HybridAutoPlay';
|
|
7
6
|
import { HybridVoice } from './hybrid/HybridVoice';
|
|
8
7
|
AutoPlayHeadlessJsTask.registerHeadlessTask(HybridAutoPlay);
|
|
9
|
-
export { HybridAndroidAutoTelemetry,
|
|
8
|
+
export { HybridAndroidAutoTelemetry, HybridAutoPlay, HybridVoice };
|
|
10
9
|
export const HybridAndroidAutomotive = Platform.OS === 'android'
|
|
11
10
|
? NitroModules.createHybridObject('AndroidAutomotive')
|
|
12
11
|
: null;
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { AppRegistry, Platform } from 'react-native';
|
|
3
3
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
4
|
import { SafeAreaInsetsProvider } from '../components/SafeAreaInsetsContext';
|
|
5
|
-
import { WindowInformationWrapper } from '../components/WindowInformationWrapper';
|
|
6
5
|
import { NitroImageUtil } from '../utils/NitroImage';
|
|
7
6
|
const HybridCluster = NitroModules.createHybridObject('Cluster');
|
|
8
7
|
class Cluster {
|
|
@@ -50,11 +49,7 @@ class Cluster {
|
|
|
50
49
|
AppRegistry.registerComponent(clusterId, () => (props) => React.createElement(SafeAreaInsetsProvider, {
|
|
51
50
|
moduleName: clusterId,
|
|
52
51
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
53
|
-
children: React.createElement(
|
|
54
|
-
moduleName: clusterId,
|
|
55
|
-
component,
|
|
56
|
-
componentProps: props,
|
|
57
|
-
}),
|
|
52
|
+
children: React.createElement(component, props),
|
|
58
53
|
}));
|
|
59
54
|
this.clusters[clusterId] = true;
|
|
60
55
|
await HybridCluster.initRootView(clusterId);
|
|
@@ -3,7 +3,6 @@ import { AppRegistry, Platform } from 'react-native';
|
|
|
3
3
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
4
|
import { MapTemplateProvider } from '../components/MapTemplateContext';
|
|
5
5
|
import { SafeAreaInsetsProvider } from '../components/SafeAreaInsetsContext';
|
|
6
|
-
import { WindowInformationWrapper } from '../components/WindowInformationWrapper';
|
|
7
6
|
import { HybridAutoPlay } from '../hybrid/HybridAutoPlay';
|
|
8
7
|
import { NitroActionUtil } from '../utils/NitroAction';
|
|
9
8
|
import { NitroAlertUtil } from '../utils/NitroAlert';
|
|
@@ -24,11 +23,7 @@ export class MapTemplate extends Template {
|
|
|
24
23
|
children: React.createElement(SafeAreaInsetsProvider, {
|
|
25
24
|
moduleName: this.id,
|
|
26
25
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
27
|
-
children: React.createElement(
|
|
28
|
-
moduleName: this.id,
|
|
29
|
-
component,
|
|
30
|
-
componentProps: props,
|
|
31
|
-
}),
|
|
26
|
+
children: React.createElement(component, props),
|
|
32
27
|
}),
|
|
33
28
|
}));
|
|
34
29
|
const nitroConfig = {
|
|
@@ -19,10 +19,6 @@ export type RootComponentInitialProps = {
|
|
|
19
19
|
* this is the initial color scheme, add onAppearanceDidChange on MapTemplate to get updates
|
|
20
20
|
*/
|
|
21
21
|
colorScheme: ColorScheme;
|
|
22
|
-
/**
|
|
23
|
-
* the dimensions of the render surface, kept up to date when the host resizes the surface
|
|
24
|
-
* (e.g. head units running Android Auto windowed)
|
|
25
|
-
*/
|
|
26
22
|
window: WindowInformation;
|
|
27
23
|
};
|
|
28
24
|
export type AutoPlayClusterInitialProps = RootComponentInitialProps & {
|
package/nitro.json
CHANGED
|
@@ -29,12 +29,6 @@
|
|
|
29
29
|
"language": "swift"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
"AndroidWindowInformation": {
|
|
33
|
-
"android": {
|
|
34
|
-
"implementationClassName": "HybridAndroidWindowInformation",
|
|
35
|
-
"language": "kotlin"
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
32
|
"AndroidAutoTelemetry": {
|
|
39
33
|
"android": {
|
|
40
34
|
"implementationClassName": "HybridAndroidAutoTelemetry",
|
|
@@ -35,7 +35,6 @@ target_sources(
|
|
|
35
35
|
# Shared Nitrogen C++ sources
|
|
36
36
|
../nitrogen/generated/shared/c++/HybridAndroidAutomotiveSpec.cpp
|
|
37
37
|
../nitrogen/generated/shared/c++/HybridAndroidAutoTelemetrySpec.cpp
|
|
38
|
-
../nitrogen/generated/shared/c++/HybridAndroidWindowInformationSpec.cpp
|
|
39
38
|
../nitrogen/generated/shared/c++/HybridAutoPlaySpec.cpp
|
|
40
39
|
../nitrogen/generated/shared/c++/HybridCarPlayDashboardSpec.cpp
|
|
41
40
|
../nitrogen/generated/shared/c++/HybridClusterSpec.cpp
|
|
@@ -50,7 +49,6 @@ target_sources(
|
|
|
50
49
|
# Android-specific Nitrogen C++ sources
|
|
51
50
|
../nitrogen/generated/android/c++/JHybridAndroidAutomotiveSpec.cpp
|
|
52
51
|
../nitrogen/generated/android/c++/JHybridAndroidAutoTelemetrySpec.cpp
|
|
53
|
-
../nitrogen/generated/android/c++/JHybridAndroidWindowInformationSpec.cpp
|
|
54
52
|
../nitrogen/generated/android/c++/JHybridAutoPlaySpec.cpp
|
|
55
53
|
../nitrogen/generated/android/c++/JVariant_GlyphImage_AssetImage_RemoteImage.cpp
|
|
56
54
|
../nitrogen/generated/android/c++/JHybridClusterSpec.cpp
|
|
@@ -21,8 +21,6 @@
|
|
|
21
21
|
#include "JFunc_void_AppFocusState.hpp"
|
|
22
22
|
#include "JHybridAndroidAutoTelemetrySpec.hpp"
|
|
23
23
|
#include "JFunc_void_std__optional_Telemetry_.hpp"
|
|
24
|
-
#include "JHybridAndroidWindowInformationSpec.hpp"
|
|
25
|
-
#include "JFunc_void_WindowInformation.hpp"
|
|
26
24
|
#include "JHybridAutoPlaySpec.hpp"
|
|
27
25
|
#include "JFunc_void_VisibilityState.hpp"
|
|
28
26
|
#include "JFunc_void_std__optional_Location__std__optional_std__string_.hpp"
|
|
@@ -76,14 +74,6 @@ struct JHybridAutoPlaySpecImpl: public jni::JavaClass<JHybridAutoPlaySpecImpl, J
|
|
|
76
74
|
return javaPart->getJHybridAutoPlaySpec();
|
|
77
75
|
}
|
|
78
76
|
};
|
|
79
|
-
struct JHybridAndroidWindowInformationSpecImpl: public jni::JavaClass<JHybridAndroidWindowInformationSpecImpl, JHybridAndroidWindowInformationSpec::JavaPart> {
|
|
80
|
-
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidWindowInformation;";
|
|
81
|
-
static std::shared_ptr<JHybridAndroidWindowInformationSpec> create() {
|
|
82
|
-
static const auto constructorFn = javaClassStatic()->getConstructor<JHybridAndroidWindowInformationSpecImpl::javaobject()>();
|
|
83
|
-
jni::local_ref<JHybridAndroidWindowInformationSpec::JavaPart> javaPart = javaClassStatic()->newObject(constructorFn);
|
|
84
|
-
return javaPart->getJHybridAndroidWindowInformationSpec();
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
77
|
struct JHybridAndroidAutoTelemetrySpecImpl: public jni::JavaClass<JHybridAndroidAutoTelemetrySpecImpl, JHybridAndroidAutoTelemetrySpec::JavaPart> {
|
|
88
78
|
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/swe/iternio/reactnativeautoplay/HybridAndroidAutoTelemetry;";
|
|
89
79
|
static std::shared_ptr<JHybridAndroidAutoTelemetrySpec> create() {
|
|
@@ -176,8 +166,6 @@ void registerAllNatives() {
|
|
|
176
166
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_AppFocusState_cxx::registerNatives();
|
|
177
167
|
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridAndroidAutoTelemetrySpec::CxxPart::registerNatives();
|
|
178
168
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_std__optional_Telemetry__cxx::registerNatives();
|
|
179
|
-
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridAndroidWindowInformationSpec::CxxPart::registerNatives();
|
|
180
|
-
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_WindowInformation_cxx::registerNatives();
|
|
181
169
|
margelo::nitro::swe::iternio::reactnativeautoplay::JHybridAutoPlaySpec::CxxPart::registerNatives();
|
|
182
170
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_VisibilityState_cxx::registerNatives();
|
|
183
171
|
margelo::nitro::swe::iternio::reactnativeautoplay::JFunc_void_std__optional_Location__std__optional_std__string__cxx::registerNatives();
|
|
@@ -219,12 +207,6 @@ void registerAllNatives() {
|
|
|
219
207
|
return JHybridAutoPlaySpecImpl::create();
|
|
220
208
|
}
|
|
221
209
|
);
|
|
222
|
-
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
223
|
-
"AndroidWindowInformation",
|
|
224
|
-
[]() -> std::shared_ptr<HybridObject> {
|
|
225
|
-
return JHybridAndroidWindowInformationSpecImpl::create();
|
|
226
|
-
}
|
|
227
|
-
);
|
|
228
210
|
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
229
211
|
"AndroidAutoTelemetry",
|
|
230
212
|
[]() -> std::shared_ptr<HybridObject> {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,14 +2,13 @@ import { Platform } from 'react-native';
|
|
|
2
2
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
3
3
|
import AutoPlayHeadlessJsTask from './AutoPlayHeadlessJsTask';
|
|
4
4
|
import { HybridAndroidAutoTelemetry } from './hybrid/HybridAndroidAutoTelemetry';
|
|
5
|
-
import { HybridAndroidWindowInformation } from './hybrid/HybridAndroidWindowInformation';
|
|
6
5
|
import { HybridAutoPlay } from './hybrid/HybridAutoPlay';
|
|
7
6
|
import { HybridVoice } from './hybrid/HybridVoice';
|
|
8
7
|
import type { AndroidAutomotive } from './specs/AndroidAutomotive.nitro';
|
|
9
8
|
|
|
10
9
|
AutoPlayHeadlessJsTask.registerHeadlessTask(HybridAutoPlay);
|
|
11
10
|
|
|
12
|
-
export { HybridAndroidAutoTelemetry,
|
|
11
|
+
export { HybridAndroidAutoTelemetry, HybridAutoPlay, HybridVoice };
|
|
13
12
|
|
|
14
13
|
export const HybridAndroidAutomotive =
|
|
15
14
|
Platform.OS === 'android'
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { AppRegistry, Platform } from 'react-native';
|
|
3
3
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
4
|
import { SafeAreaInsetsProvider } from '../components/SafeAreaInsetsContext';
|
|
5
|
-
import { WindowInformationWrapper } from '../components/WindowInformationWrapper';
|
|
6
5
|
import type { Cluster as NitroCluster, ZoomEvent } from '../specs/Cluster.nitro';
|
|
7
6
|
import type { ColorScheme, RootComponentInitialProps } from '../types/RootComponent';
|
|
8
7
|
import type { AutoAttributedString } from '../utils/NitroAttributedString';
|
|
@@ -63,11 +62,7 @@ class Cluster {
|
|
|
63
62
|
React.createElement(SafeAreaInsetsProvider, {
|
|
64
63
|
moduleName: clusterId,
|
|
65
64
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
66
|
-
children: React.createElement(
|
|
67
|
-
moduleName: clusterId,
|
|
68
|
-
component,
|
|
69
|
-
componentProps: props,
|
|
70
|
-
}),
|
|
65
|
+
children: React.createElement(component, props),
|
|
71
66
|
})
|
|
72
67
|
);
|
|
73
68
|
|
|
@@ -4,7 +4,6 @@ import { NitroModules } from 'react-native-nitro-modules';
|
|
|
4
4
|
import type { AutoText } from '..';
|
|
5
5
|
import { MapTemplateProvider } from '../components/MapTemplateContext';
|
|
6
6
|
import { SafeAreaInsetsProvider } from '../components/SafeAreaInsetsContext';
|
|
7
|
-
import { WindowInformationWrapper } from '../components/WindowInformationWrapper';
|
|
8
7
|
import { HybridAutoPlay } from '../hybrid/HybridAutoPlay';
|
|
9
8
|
import type { MapTemplate as NitroMapTemplate } from '../specs/MapTemplate.nitro';
|
|
10
9
|
import type { ActionButtonAndroid, MapButton, MapPanButton } from '../types/Button';
|
|
@@ -197,11 +196,7 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
|
|
|
197
196
|
children: React.createElement(SafeAreaInsetsProvider, {
|
|
198
197
|
moduleName: this.id,
|
|
199
198
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
200
|
-
children: React.createElement(
|
|
201
|
-
moduleName: this.id,
|
|
202
|
-
component,
|
|
203
|
-
componentProps: props,
|
|
204
|
-
}),
|
|
199
|
+
children: React.createElement(component, props),
|
|
205
200
|
}),
|
|
206
201
|
})
|
|
207
202
|
);
|
|
@@ -21,10 +21,6 @@ export type RootComponentInitialProps = {
|
|
|
21
21
|
* this is the initial color scheme, add onAppearanceDidChange on MapTemplate to get updates
|
|
22
22
|
*/
|
|
23
23
|
colorScheme: ColorScheme;
|
|
24
|
-
/**
|
|
25
|
-
* the dimensions of the render surface, kept up to date when the host resizes the surface
|
|
26
|
-
* (e.g. head units running Android Auto windowed)
|
|
27
|
-
*/
|
|
28
24
|
window: WindowInformation;
|
|
29
25
|
};
|
|
30
26
|
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
package com.margelo.nitro.swe.iternio.reactnativeautoplay
|
|
2
|
-
|
|
3
|
-
import java.util.concurrent.ConcurrentHashMap
|
|
4
|
-
import java.util.concurrent.CopyOnWriteArrayList
|
|
5
|
-
|
|
6
|
-
class HybridAndroidWindowInformation : HybridAndroidWindowInformationSpec() {
|
|
7
|
-
init {
|
|
8
|
-
windowInformationListeners.clear()
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
override fun addWindowInformationListener(
|
|
12
|
-
moduleName: String, callback: (WindowInformation) -> Unit
|
|
13
|
-
): () -> Unit {
|
|
14
|
-
val callbacks = windowInformationListeners.getOrPut(moduleName) {
|
|
15
|
-
CopyOnWriteArrayList()
|
|
16
|
-
}
|
|
17
|
-
callbacks.add(callback)
|
|
18
|
-
|
|
19
|
-
VirtualRenderer.getWindowInformation(moduleName)?.let {
|
|
20
|
-
callback(it)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
windowInformationListeners[moduleName]?.let {
|
|
25
|
-
it.remove(callback)
|
|
26
|
-
if (it.isEmpty()) {
|
|
27
|
-
windowInformationListeners.remove(moduleName)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
companion object {
|
|
34
|
-
const val TAG = "HybridAndroidWindowInformation"
|
|
35
|
-
|
|
36
|
-
private val windowInformationListeners =
|
|
37
|
-
ConcurrentHashMap<String, CopyOnWriteArrayList<(WindowInformation) -> Unit>>()
|
|
38
|
-
|
|
39
|
-
fun removeListeners(templateId: String) {
|
|
40
|
-
windowInformationListeners.remove(templateId)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
fun emitWindowInformation(moduleName: String, window: WindowInformation) {
|
|
44
|
-
windowInformationListeners[moduleName]?.forEach {
|
|
45
|
-
it(window)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
package/lib/HybridAutoPlay.d.ts
DELETED
package/lib/HybridAutoPlay.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
type Props = {
|
|
2
|
-
children: React.ReactNode;
|
|
3
|
-
moduleName: string;
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* renders the passed children when the specified scene/screen appeared
|
|
7
|
-
* this makes sure child hooks are executed only when the map template is ready
|
|
8
|
-
*/
|
|
9
|
-
export default function OnAppearedChildRenderer({ children, moduleName }: Props): import("react").ReactNode;
|
|
10
|
-
export {};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { HybridAutoPlay } from '../hybrid/HybridAutoPlay';
|
|
3
|
-
/**
|
|
4
|
-
* renders the passed children when the specified scene/screen appeared
|
|
5
|
-
* this makes sure child hooks are executed only when the map template is ready
|
|
6
|
-
*/
|
|
7
|
-
export default function OnAppearedChildRenderer({ children, moduleName }) {
|
|
8
|
-
const [didAppear, setDidAppear] = useState(false);
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
let remove = HybridAutoPlay.addListenerRenderState(moduleName, (renderState) => {
|
|
11
|
-
if (renderState === 'didAppear') {
|
|
12
|
-
remove?.();
|
|
13
|
-
remove = null;
|
|
14
|
-
setDidAppear(true);
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
return () => {
|
|
18
|
-
remove?.();
|
|
19
|
-
remove = null;
|
|
20
|
-
};
|
|
21
|
-
}, [moduleName]);
|
|
22
|
-
if (didAppear) {
|
|
23
|
-
return children;
|
|
24
|
-
}
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type React from 'react';
|
|
2
|
-
import type { RootComponentInitialProps } from '../types/RootComponent';
|
|
3
|
-
/**
|
|
4
|
-
* Renders a user-provided root component and keeps its `window` prop up to date when the host
|
|
5
|
-
* recreates the render surface with new dimensions (some head units run Android Auto windowed
|
|
6
|
-
* and resize it at runtime), so consumers can simply read `props.window` without registering a
|
|
7
|
-
* listener themselves.
|
|
8
|
-
* On iOS this only passes the initial props through — CarPlay windows keep their size for the
|
|
9
|
-
* lifetime of a scene, so there is nothing to subscribe to.
|
|
10
|
-
*/
|
|
11
|
-
export declare function WindowInformationWrapper({ moduleName, component, componentProps, }: {
|
|
12
|
-
moduleName: string;
|
|
13
|
-
component: React.ComponentType<RootComponentInitialProps>;
|
|
14
|
-
componentProps: RootComponentInitialProps;
|
|
15
|
-
}): React.ReactElement<RootComponentInitialProps, string | React.JSXElementConstructor<any>>;
|