@iternio/react-native-auto-play 0.3.9 → 0.3.11
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/AndroidAutoSession.kt +1 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt +6 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/AndroidAutoTemplate.kt +2 -1
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/MapTemplate.kt +6 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/BitmapCache.kt +2 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/Debouncer.kt +2 -1
- package/ios/hybrid/HybridMapTemplate.swift +9 -5
- package/ios/templates/MapTemplate.swift +57 -0
- package/ios/templates/Parser.swift +18 -7
- package/lib/components/OnAppearedChildRenderer.d.ts +10 -0
- package/lib/components/OnAppearedChildRenderer.js +26 -0
- package/lib/specs/MapTemplate.nitro.d.ts +2 -0
- package/lib/templates/MapTemplate.d.ts +15 -2
- package/lib/templates/MapTemplate.js +25 -3
- package/lib/types/Maneuver.d.ts +18 -0
- package/lib/types/Maneuver.js +13 -0
- package/lib/utils/NitroManeuver.d.ts +2 -0
- package/lib/utils/NitroMapButton.js +1 -1
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp +8 -0
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.hpp +1 -0
- package/nitrogen/generated/android/c++/JManeuverState.hpp +64 -0
- package/nitrogen/generated/android/c++/JMapTemplateConfig.hpp +5 -1
- package/nitrogen/generated/android/c++/JNitroLoadingManeuver.hpp +15 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +4 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ManeuverState.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/MapTemplateConfig.kt +7 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroLoadingManeuver.kt +9 -3
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridMapTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec.swift +1 -0
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec_cxx.swift +11 -0
- package/nitrogen/generated/ios/swift/ManeuverState.swift +48 -0
- package/nitrogen/generated/ios/swift/MapTemplateConfig.swift +12 -1
- package/nitrogen/generated/ios/swift/NitroLoadingManeuver.swift +25 -2
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.hpp +4 -0
- package/nitrogen/generated/shared/c++/ManeuverState.hpp +64 -0
- package/nitrogen/generated/shared/c++/MapTemplateConfig.hpp +8 -1
- package/nitrogen/generated/shared/c++/NitroLoadingManeuver.hpp +15 -4
- package/package.json +1 -1
- package/src/components/OnAppearedChildRenderer.tsx +37 -0
- package/src/specs/MapTemplate.nitro.ts +2 -0
- package/src/templates/MapTemplate.ts +40 -4
- package/src/types/Maneuver.ts +19 -0
- package/src/utils/NitroManeuver.ts +2 -0
- package/src/utils/NitroMapButton.ts +1 -1
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt
CHANGED
|
@@ -13,7 +13,7 @@ class HybridMapTemplate : HybridMapTemplateSpec() {
|
|
|
13
13
|
|
|
14
14
|
override fun createMapTemplate(config: MapTemplateConfig) {
|
|
15
15
|
val context = AndroidAutoSession.getCarContext(config.id) ?: throw IllegalArgumentException(
|
|
16
|
-
"createMapTemplate failed, carContext found"
|
|
16
|
+
"createMapTemplate failed, carContext not found"
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
val template = MapTemplate(context, config, initNavigationManager = true)
|
|
@@ -50,7 +50,7 @@ class HybridMapTemplate : HybridMapTemplateSpec() {
|
|
|
50
50
|
) {
|
|
51
51
|
val carContext = AndroidAutoSession.getCarContext(AndroidAutoSession.ROOT_SESSION)
|
|
52
52
|
?: throw IllegalArgumentException(
|
|
53
|
-
"dismissNavigationAlert failed, carContext found"
|
|
53
|
+
"dismissNavigationAlert failed, carContext not found"
|
|
54
54
|
)
|
|
55
55
|
carContext.getCarService(AppManager::class.java).dismissAlert(navigationAlertId.toInt())
|
|
56
56
|
}
|
|
@@ -154,4 +154,8 @@ class HybridMapTemplate : HybridMapTemplateSpec() {
|
|
|
154
154
|
override fun stopNavigation(templateId: String) {
|
|
155
155
|
MapTemplate.stopNavigation()
|
|
156
156
|
}
|
|
157
|
+
|
|
158
|
+
override fun setManeuverState(templateId: String, state: ManeuverState) {
|
|
159
|
+
// Android Auto does not have an equivalent to CPManeuverState
|
|
160
|
+
}
|
|
157
161
|
}
|
|
@@ -5,6 +5,7 @@ import androidx.car.app.Screen
|
|
|
5
5
|
import androidx.car.app.model.Template
|
|
6
6
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.AndroidAutoScreen
|
|
7
7
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroAction
|
|
8
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
8
9
|
|
|
9
10
|
abstract class AndroidAutoTemplate<T>(val context: CarContext, var config: T) {
|
|
10
11
|
abstract fun parse(): Template
|
|
@@ -27,7 +28,7 @@ abstract class AndroidAutoTemplate<T>(val context: CarContext, var config: T) {
|
|
|
27
28
|
|
|
28
29
|
companion object {
|
|
29
30
|
const val TAG = "AndroidAutoTemplate"
|
|
30
|
-
val templates =
|
|
31
|
+
val templates = ConcurrentHashMap<String, AndroidAutoTemplate<*>>()
|
|
31
32
|
|
|
32
33
|
fun <T> setTemplate(id: String, template: AndroidAutoTemplate<T>) {
|
|
33
34
|
templates.put(id, template)
|
|
@@ -66,6 +66,10 @@ class MapTemplate(
|
|
|
66
66
|
navigationManager.setNavigationManagerCallback(navigationManagerCallback)
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
config.defaultGuidanceBackgroundColor?.let { nitroColor ->
|
|
71
|
+
MapTemplate.cardBackgroundColor = Parser.parseColor(nitroColor)
|
|
72
|
+
}
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
override fun parse(): Template {
|
|
@@ -329,7 +333,9 @@ class MapTemplate(
|
|
|
329
333
|
}
|
|
330
334
|
|
|
331
335
|
if (loadingInfo != null) {
|
|
336
|
+
cardBackgroundColor = Parser.parseColor(loadingInfo.cardBackgroundColor)
|
|
332
337
|
navigationInfo = RoutingInfo.Builder().setLoading(true).build()
|
|
338
|
+
AndroidAutoScreen.invalidateSurfaceScreens()
|
|
333
339
|
return
|
|
334
340
|
}
|
|
335
341
|
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/BitmapCache.kt
CHANGED
|
@@ -8,8 +8,8 @@ import com.margelo.nitro.swe.iternio.reactnativeautoplay.GlyphImage
|
|
|
8
8
|
import com.margelo.nitro.swe.iternio.reactnativeautoplay.NitroColor
|
|
9
9
|
|
|
10
10
|
object BitmapCache {
|
|
11
|
-
private val maxMemory = Runtime.getRuntime().maxMemory()
|
|
12
|
-
private val cacheSize = minOf(maxMemory / 8, 8388608) //limit cache to 8 megabyte
|
|
11
|
+
private val maxMemory = Runtime.getRuntime().maxMemory()
|
|
12
|
+
private val cacheSize = minOf(maxMemory / 8, 8388608).toInt() //limit cache to 8 megabyte
|
|
13
13
|
|
|
14
14
|
private val bitmapCache = object : LruCache<String, Bitmap>(cacheSize) {
|
|
15
15
|
override fun sizeOf(key: String, bitmap: Bitmap): Int {
|
package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/utils/Debouncer.kt
CHANGED
|
@@ -7,11 +7,12 @@ import kotlinx.coroutines.delay
|
|
|
7
7
|
import kotlinx.coroutines.launch
|
|
8
8
|
|
|
9
9
|
class Debouncer(private val delayMillis: Long = 300L) {
|
|
10
|
+
private val scope = CoroutineScope(Dispatchers.Main)
|
|
10
11
|
private var debounceJob: Job? = null
|
|
11
12
|
|
|
12
13
|
fun submit(action: () -> Unit) {
|
|
13
14
|
debounceJob?.cancel()
|
|
14
|
-
debounceJob =
|
|
15
|
+
debounceJob = scope.launch {
|
|
15
16
|
delay(delayMillis)
|
|
16
17
|
action()
|
|
17
18
|
}
|
|
@@ -138,12 +138,9 @@ class HybridMapTemplate: HybridMapTemplateSpec {
|
|
|
138
138
|
{
|
|
139
139
|
template.updateManeuvers(messageManeuver: messageManeuver)
|
|
140
140
|
}()
|
|
141
|
-
case .third(let
|
|
141
|
+
case .third(let loading):
|
|
142
142
|
{
|
|
143
|
-
template.
|
|
144
|
-
for: .loading,
|
|
145
|
-
description: nil
|
|
146
|
-
)
|
|
143
|
+
template.updateManeuversLoading(loading: loading)
|
|
147
144
|
}()
|
|
148
145
|
}
|
|
149
146
|
|
|
@@ -164,4 +161,11 @@ class HybridMapTemplate: HybridMapTemplateSpec {
|
|
|
164
161
|
template.stopNavigation()
|
|
165
162
|
}
|
|
166
163
|
}
|
|
164
|
+
|
|
165
|
+
func setManeuverState(templateId: String, state: ManeuverState) throws {
|
|
166
|
+
try RootModule.withAutoPlayTemplate(templateId: templateId) {
|
|
167
|
+
(template: MapTemplate) in
|
|
168
|
+
template.setManeuverState(state: state)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
167
171
|
}
|
|
@@ -50,6 +50,18 @@ class MapTemplate: AutoPlayHeaderProviding,
|
|
|
50
50
|
visibleTravelEstimate = config.visibleTravelEstimate
|
|
51
51
|
|
|
52
52
|
template = CPMapTemplate(id: config.id)
|
|
53
|
+
if let nitroColor = config.defaultGuidanceBackgroundColor,
|
|
54
|
+
let traitCollection = SceneStore.getRootTraitCollection()
|
|
55
|
+
{
|
|
56
|
+
let cardBackgroundColor = Parser.routingManeuverCardBackgroundUIColor(
|
|
57
|
+
color: nitroColor,
|
|
58
|
+
traitCollection: traitCollection
|
|
59
|
+
)
|
|
60
|
+
template.guidanceBackgroundColor = cardBackgroundColor
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
template.guidanceBackgroundColor = .black
|
|
64
|
+
}
|
|
53
65
|
|
|
54
66
|
if let initialProperties = SceneStore.getRootScene()?.initialProperties,
|
|
55
67
|
let windowDict = initialProperties["window"] as? [String: Any],
|
|
@@ -607,6 +619,35 @@ class MapTemplate: AutoPlayHeaderProviding,
|
|
|
607
619
|
updateVisibleTravelEstimate(visibleTravelEstimate: nil)
|
|
608
620
|
}
|
|
609
621
|
|
|
622
|
+
func updateManeuversLoading(loading: NitroLoadingManeuver) {
|
|
623
|
+
guard let navigationSession = navigationSession else { return }
|
|
624
|
+
|
|
625
|
+
let description = loading.text
|
|
626
|
+
|
|
627
|
+
guard let traitCollection = SceneStore.getRootTraitCollection() else {
|
|
628
|
+
navigationSession.pauseTrip(for: .loading, description: description)
|
|
629
|
+
return
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
let cardBackgroundColor = Parser.routingManeuverCardBackgroundUIColor(
|
|
633
|
+
color: loading.cardBackgroundColor,
|
|
634
|
+
traitCollection: traitCollection
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
template.guidanceBackgroundColor = cardBackgroundColor
|
|
638
|
+
|
|
639
|
+
if #available(iOS 18.0, *) {
|
|
640
|
+
navigationSession.pauseTrip(
|
|
641
|
+
for: .loading,
|
|
642
|
+
description: description,
|
|
643
|
+
turnCardColor: cardBackgroundColor
|
|
644
|
+
)
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
navigationSession.pauseTrip(for: .loading, description: description)
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
610
651
|
func updateManeuvers(messageManeuver: NitroMessageManeuver) {
|
|
611
652
|
guard let navigationSession = navigationSession else { return }
|
|
612
653
|
|
|
@@ -784,4 +825,20 @@ class MapTemplate: AutoPlayHeaderProviding,
|
|
|
784
825
|
navigationSession?.finishTrip()
|
|
785
826
|
navigationSession = nil
|
|
786
827
|
}
|
|
828
|
+
|
|
829
|
+
func setManeuverState(state: ManeuverState) {
|
|
830
|
+
guard #available(iOS 17.4, *) else { return }
|
|
831
|
+
guard let navigationSession = navigationSession else { return }
|
|
832
|
+
|
|
833
|
+
switch state {
|
|
834
|
+
case .continue:
|
|
835
|
+
navigationSession.maneuverState = .continue
|
|
836
|
+
case .initial:
|
|
837
|
+
navigationSession.maneuverState = .initial
|
|
838
|
+
case .prepare:
|
|
839
|
+
navigationSession.maneuverState = .prepare
|
|
840
|
+
case .execute:
|
|
841
|
+
navigationSession.maneuverState = .execute
|
|
842
|
+
}
|
|
843
|
+
}
|
|
787
844
|
}
|
|
@@ -503,6 +503,21 @@ class Parser {
|
|
|
503
503
|
)
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
/// Card background `UIColor` for routing maneuvers and loading pause — same light/dark component pick as `parseManeuver`.
|
|
507
|
+
static func routingManeuverCardBackgroundUIColor(
|
|
508
|
+
color: NitroColor,
|
|
509
|
+
traitCollection: UITraitCollection
|
|
510
|
+
) -> UIColor {
|
|
511
|
+
if #available(iOS 15.4, *) {
|
|
512
|
+
let component =
|
|
513
|
+
traitCollection.userInterfaceStyle == .dark
|
|
514
|
+
? color.darkColor
|
|
515
|
+
: color.lightColor
|
|
516
|
+
return doubleToColor(value: component)
|
|
517
|
+
}
|
|
518
|
+
return parseColor(color: color)
|
|
519
|
+
}
|
|
520
|
+
|
|
506
521
|
static func parseManeuver(
|
|
507
522
|
nitroManeuver: NitroRoutingManeuver,
|
|
508
523
|
traitCollection: UITraitCollection
|
|
@@ -528,13 +543,9 @@ class Parser {
|
|
|
528
543
|
)
|
|
529
544
|
|
|
530
545
|
if #available(iOS 15.4, *) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
: nitroManeuver.cardBackgroundColor.lightColor
|
|
535
|
-
|
|
536
|
-
maneuver.cardBackgroundColor = doubleToColor(
|
|
537
|
-
value: cardBackgroundColor
|
|
546
|
+
maneuver.cardBackgroundColor = routingManeuverCardBackgroundUIColor(
|
|
547
|
+
color: nitroManeuver.cardBackgroundColor,
|
|
548
|
+
traitCollection: traitCollection
|
|
538
549
|
)
|
|
539
550
|
}
|
|
540
551
|
|
|
@@ -0,0 +1,10 @@
|
|
|
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 {};
|
|
@@ -0,0 +1,26 @@
|
|
|
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,5 +1,6 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
2
|
import type { NitroMapTemplateConfig, TripSelectorCallback, VisibleTravelEstimate } from '../templates/MapTemplate';
|
|
3
|
+
import type { ManeuverState } from '../types/Maneuver';
|
|
3
4
|
import type { AutoText } from '../types/Text';
|
|
4
5
|
import type { TripConfig, TripPoint, TripPreviewTextConfiguration, TripsConfig } from '../types/Trip';
|
|
5
6
|
import type { NitroNavigationAlert } from '../utils/NitroAlert';
|
|
@@ -24,5 +25,6 @@ export interface MapTemplate extends HybridObject<{
|
|
|
24
25
|
updateManeuvers(templateId: string, maneuvers: NitroManeuver): void;
|
|
25
26
|
startNavigation(templateId: string, trip: TripConfig): void;
|
|
26
27
|
stopNavigation(templateId: string): void;
|
|
28
|
+
setManeuverState(templateId: string, state: ManeuverState): void;
|
|
27
29
|
}
|
|
28
30
|
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AutoText } from '..';
|
|
3
3
|
import type { ActionButtonAndroid, MapButton, MapPanButton } from '../types/Button';
|
|
4
|
-
import type { AutoManeuver } from '../types/Maneuver';
|
|
4
|
+
import type { AutoManeuver, ManeuverState } from '../types/Maneuver';
|
|
5
5
|
import type { ColorScheme, RootComponentInitialProps } from '../types/RootComponent';
|
|
6
6
|
import type { TripConfig, TripPoint, TripPreviewTextConfiguration, TripsConfig } from '../types/Trip';
|
|
7
7
|
import { type NitroAction } from '../utils/NitroAction';
|
|
8
8
|
import { type NavigationAlert } from '../utils/NitroAlert';
|
|
9
|
+
import { type NitroColor, type ThemedColor } from '../utils/NitroColor';
|
|
9
10
|
import { NitroMapButton } from '../utils/NitroMapButton';
|
|
10
11
|
import { type HeaderActionsIos, type NitroBaseMapTemplateConfig, Template, type TemplateConfig } from './Template';
|
|
11
12
|
export type Point = {
|
|
@@ -53,6 +54,7 @@ export interface NitroMapTemplateConfig extends TemplateConfig, NitroBaseMapTemp
|
|
|
53
54
|
onAutoDriveEnabled?: () => void;
|
|
54
55
|
mapButtons?: Array<NitroMapButton>;
|
|
55
56
|
headerActions?: Array<NitroAction>;
|
|
57
|
+
defaultGuidanceBackgroundColor?: NitroColor;
|
|
56
58
|
/**
|
|
57
59
|
* specify the percentage of screen height/width the pan button should scroll
|
|
58
60
|
* @namespace iOS
|
|
@@ -78,7 +80,7 @@ export type BaseMapTemplateConfig<T> = {
|
|
|
78
80
|
*/
|
|
79
81
|
headerActions?: MapHeaderActions<T>;
|
|
80
82
|
};
|
|
81
|
-
export type MapTemplateConfig = Omit<NitroMapTemplateConfig, 'mapButtons' | 'headerActions' | 'onStopNavigation' | 'onAutoDriveEnabled'> & BaseMapTemplateConfig<MapTemplate> & {
|
|
83
|
+
export type MapTemplateConfig = Omit<NitroMapTemplateConfig, 'mapButtons' | 'headerActions' | 'onStopNavigation' | 'onAutoDriveEnabled' | 'defaultGuidanceBackgroundColor'> & BaseMapTemplateConfig<MapTemplate> & {
|
|
82
84
|
/**
|
|
83
85
|
* react component that is rendered
|
|
84
86
|
*/
|
|
@@ -93,6 +95,10 @@ export type MapTemplateConfig = Omit<NitroMapTemplateConfig, 'mapButtons' | 'hea
|
|
|
93
95
|
* @namespace Android
|
|
94
96
|
*/
|
|
95
97
|
onAutoDriveEnabled?: (template: MapTemplate) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Initial navigation maneuver background color. Mainly useful, when in CarPlay the default loading maneuver does not have the right color.
|
|
100
|
+
*/
|
|
101
|
+
defaultGuidanceBackgroundColor?: ThemedColor | string;
|
|
96
102
|
};
|
|
97
103
|
export interface TripSelectorCallback {
|
|
98
104
|
setSelectedTrip: (id: string) => void;
|
|
@@ -148,4 +154,11 @@ export declare class MapTemplate extends Template<MapTemplateConfig, MapTemplate
|
|
|
148
154
|
*/
|
|
149
155
|
startNavigation(trip: TripConfig): void;
|
|
150
156
|
stopNavigation(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Sets the current maneuver state indicating progress within a maneuver.
|
|
159
|
+
* Transition through: continue → initial → prepare → execute → continue
|
|
160
|
+
* @namespace iOS sets CPManeuverState on the CPNavigationSession, used by instrument cluster and HUD
|
|
161
|
+
* @namespace Android no-op, Android Auto does not have an equivalent API
|
|
162
|
+
*/
|
|
163
|
+
setManeuverState(state: ManeuverState): void;
|
|
151
164
|
}
|
|
@@ -2,10 +2,12 @@ import React from 'react';
|
|
|
2
2
|
import { AppRegistry, Platform } from 'react-native';
|
|
3
3
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
4
|
import { MapTemplateProvider } from '../components/MapTemplateContext';
|
|
5
|
+
import OnAppearedChildRenderer from '../components/OnAppearedChildRenderer';
|
|
5
6
|
import { SafeAreaInsetsProvider } from '../components/SafeAreaInsetsContext';
|
|
6
7
|
import { HybridAutoPlay } from '../hybrid/HybridAutoPlay';
|
|
7
8
|
import { NitroActionUtil } from '../utils/NitroAction';
|
|
8
9
|
import { NitroAlertUtil } from '../utils/NitroAlert';
|
|
10
|
+
import { NitroColorUtil } from '../utils/NitroColor';
|
|
9
11
|
import { NitroManeuverUtil } from '../utils/NitroManeuver';
|
|
10
12
|
import { NitroMapButton } from '../utils/NitroMapButton';
|
|
11
13
|
import { Template, } from './Template';
|
|
@@ -15,14 +17,18 @@ export class MapTemplate extends Template {
|
|
|
15
17
|
template = this;
|
|
16
18
|
constructor(config) {
|
|
17
19
|
super(config);
|
|
18
|
-
const { component, mapButtons, headerActions, onStopNavigation, onAutoDriveEnabled, ...baseConfig } = config;
|
|
20
|
+
const { component, mapButtons, headerActions, onStopNavigation, onAutoDriveEnabled, defaultGuidanceBackgroundColor, ...baseConfig } = config;
|
|
19
21
|
AppRegistry.registerComponent(this.id, () => (props) => React.createElement(MapTemplateProvider, {
|
|
20
22
|
mapTemplate: this.template,
|
|
21
23
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
22
24
|
children: React.createElement(SafeAreaInsetsProvider, {
|
|
23
25
|
moduleName: this.id,
|
|
24
26
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
25
|
-
children: React.createElement(
|
|
27
|
+
children: React.createElement(OnAppearedChildRenderer, {
|
|
28
|
+
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
29
|
+
children: React.createElement(component, props),
|
|
30
|
+
moduleName: this.id,
|
|
31
|
+
}),
|
|
26
32
|
}),
|
|
27
33
|
}));
|
|
28
34
|
const nitroConfig = {
|
|
@@ -32,6 +38,9 @@ export class MapTemplate extends Template {
|
|
|
32
38
|
mapButtons: NitroMapButton.convert(this.template, mapButtons),
|
|
33
39
|
onStopNavigation: () => onStopNavigation(this.template),
|
|
34
40
|
onAutoDriveEnabled: onAutoDriveEnabled ? () => onAutoDriveEnabled(this.template) : undefined,
|
|
41
|
+
defaultGuidanceBackgroundColor: defaultGuidanceBackgroundColor != null
|
|
42
|
+
? NitroColorUtil.convert(defaultGuidanceBackgroundColor)
|
|
43
|
+
: undefined,
|
|
35
44
|
};
|
|
36
45
|
HybridMapTemplate.createMapTemplate(nitroConfig);
|
|
37
46
|
}
|
|
@@ -106,7 +115,11 @@ export class MapTemplate extends Template {
|
|
|
106
115
|
return;
|
|
107
116
|
}
|
|
108
117
|
if (maneuvers.type === 'loading') {
|
|
109
|
-
HybridMapTemplate.updateManeuvers(this.id, {
|
|
118
|
+
HybridMapTemplate.updateManeuvers(this.id, {
|
|
119
|
+
isLoading: true,
|
|
120
|
+
cardBackgroundColor: NitroColorUtil.convert(maneuvers.cardBackgroundColor),
|
|
121
|
+
text: maneuvers.text != null ? maneuvers.text : undefined,
|
|
122
|
+
});
|
|
110
123
|
return;
|
|
111
124
|
}
|
|
112
125
|
const messageManeuver = NitroManeuverUtil.convert(maneuvers);
|
|
@@ -122,4 +135,13 @@ export class MapTemplate extends Template {
|
|
|
122
135
|
stopNavigation() {
|
|
123
136
|
HybridMapTemplate.stopNavigation(this.id);
|
|
124
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Sets the current maneuver state indicating progress within a maneuver.
|
|
140
|
+
* Transition through: continue → initial → prepare → execute → continue
|
|
141
|
+
* @namespace iOS sets CPManeuverState on the CPNavigationSession, used by instrument cluster and HUD
|
|
142
|
+
* @namespace Android no-op, Android Auto does not have an equivalent API
|
|
143
|
+
*/
|
|
144
|
+
setManeuverState(state) {
|
|
145
|
+
HybridMapTemplate.setManeuverState(this.id, state);
|
|
146
|
+
}
|
|
125
147
|
}
|
package/lib/types/Maneuver.d.ts
CHANGED
|
@@ -56,6 +56,18 @@ export declare enum KeepType {
|
|
|
56
56
|
Right = 1,// Android TYPE_KEEP_RIGHT, iOS keepRight
|
|
57
57
|
FollowRoad = 2
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Describes the progress within a maneuver.
|
|
61
|
+
* Transition through: Continue → Initial → Prepare → Execute → Continue
|
|
62
|
+
* @namespace iOS sets CPManeuverState on the CPNavigationSession
|
|
63
|
+
* @namespace Android no-op, Android Auto does not have an equivalent API
|
|
64
|
+
*/
|
|
65
|
+
export declare enum ManeuverState {
|
|
66
|
+
Continue = 0,// iOS .continue
|
|
67
|
+
Initial = 1,// iOS .initial
|
|
68
|
+
Prepare = 2,// iOS .prepare
|
|
69
|
+
Execute = 3
|
|
70
|
+
}
|
|
59
71
|
export interface BaseManeuver {
|
|
60
72
|
/**
|
|
61
73
|
* @namespace iOS specify a unique identifier, sending over a Maneuver with a known id will only update the travelEstimates on the previously sent Maneuver
|
|
@@ -198,6 +210,12 @@ export type MessageManeuver = {
|
|
|
198
210
|
};
|
|
199
211
|
export type LoadingManeuver = {
|
|
200
212
|
type: 'loading';
|
|
213
|
+
cardBackgroundColor: ThemedColor | string;
|
|
214
|
+
/**
|
|
215
|
+
* @namespace iOS CarPlay — shows text on the loading maneuver card
|
|
216
|
+
* @namespace Android Auto — not supported
|
|
217
|
+
*/
|
|
218
|
+
text?: string;
|
|
201
219
|
};
|
|
202
220
|
export type AutoManeuver = (Array<RoutingManeuver> & {
|
|
203
221
|
length: 0 | 1 | 2;
|
package/lib/types/Maneuver.js
CHANGED
|
@@ -59,3 +59,16 @@ export var KeepType;
|
|
|
59
59
|
KeepType[KeepType["Right"] = 1] = "Right";
|
|
60
60
|
KeepType[KeepType["FollowRoad"] = 2] = "FollowRoad";
|
|
61
61
|
})(KeepType || (KeepType = {}));
|
|
62
|
+
/**
|
|
63
|
+
* Describes the progress within a maneuver.
|
|
64
|
+
* Transition through: Continue → Initial → Prepare → Execute → Continue
|
|
65
|
+
* @namespace iOS sets CPManeuverState on the CPNavigationSession
|
|
66
|
+
* @namespace Android no-op, Android Auto does not have an equivalent API
|
|
67
|
+
*/
|
|
68
|
+
export var ManeuverState;
|
|
69
|
+
(function (ManeuverState) {
|
|
70
|
+
ManeuverState[ManeuverState["Continue"] = 0] = "Continue";
|
|
71
|
+
ManeuverState[ManeuverState["Initial"] = 1] = "Initial";
|
|
72
|
+
ManeuverState[ManeuverState["Prepare"] = 2] = "Prepare";
|
|
73
|
+
ManeuverState[ManeuverState["Execute"] = 3] = "Execute";
|
|
74
|
+
})(ManeuverState || (ManeuverState = {}));
|
|
@@ -35,6 +35,8 @@ export interface NitroMessageManeuver {
|
|
|
35
35
|
}
|
|
36
36
|
interface NitroLoadingManeuver {
|
|
37
37
|
isLoading: true;
|
|
38
|
+
cardBackgroundColor: NitroColor;
|
|
39
|
+
text?: string;
|
|
38
40
|
}
|
|
39
41
|
export type NitroManeuver = Array<NitroRoutingManeuver> | NitroMessageManeuver | NitroLoadingManeuver;
|
|
40
42
|
declare function convert(autoManeuver: MessageManeuver): NitroMessageManeuver;
|
|
@@ -13,7 +13,7 @@ const convert = (template, mapButtons) => {
|
|
|
13
13
|
: 'backgroundColor' in button.image
|
|
14
14
|
? button.image.backgroundColor
|
|
15
15
|
: 'transparent';
|
|
16
|
-
const fontScale =
|
|
16
|
+
const fontScale = button.image.fontScale ?? (Platform.OS === 'android' ? 1.0 : 0.65);
|
|
17
17
|
return {
|
|
18
18
|
type,
|
|
19
19
|
onPress,
|
|
@@ -93,6 +93,8 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class Traffic
|
|
|
93
93
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class ManeuverType; }
|
|
94
94
|
// Forward declaration of `TripConfig` to properly resolve imports.
|
|
95
95
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct TripConfig; }
|
|
96
|
+
// Forward declaration of `ManeuverState` to properly resolve imports.
|
|
97
|
+
namespace margelo::nitro::swe::iternio::reactnativeautoplay { enum class ManeuverState; }
|
|
96
98
|
|
|
97
99
|
#include "TripSelectorCallback.hpp"
|
|
98
100
|
#include "JTripSelectorCallback.hpp"
|
|
@@ -203,6 +205,8 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay { struct TripConfig;
|
|
|
203
205
|
#include "JNitroLoadingManeuver.hpp"
|
|
204
206
|
#include "TripConfig.hpp"
|
|
205
207
|
#include "JTripConfig.hpp"
|
|
208
|
+
#include "ManeuverState.hpp"
|
|
209
|
+
#include "JManeuverState.hpp"
|
|
206
210
|
|
|
207
211
|
namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
208
212
|
|
|
@@ -333,5 +337,9 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
333
337
|
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* templateId */)>("stopNavigation");
|
|
334
338
|
method(_javaPart, jni::make_jstring(templateId));
|
|
335
339
|
}
|
|
340
|
+
void JHybridMapTemplateSpec::setManeuverState(const std::string& templateId, ManeuverState state) {
|
|
341
|
+
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* templateId */, jni::alias_ref<JManeuverState> /* state */)>("setManeuverState");
|
|
342
|
+
method(_javaPart, jni::make_jstring(templateId), JManeuverState::fromCpp(state));
|
|
343
|
+
}
|
|
336
344
|
|
|
337
345
|
} // namespace margelo::nitro::swe::iternio::reactnativeautoplay
|
|
@@ -66,6 +66,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
66
66
|
void updateManeuvers(const std::string& templateId, const std::variant<std::vector<NitroRoutingManeuver>, NitroMessageManeuver, NitroLoadingManeuver>& maneuvers) override;
|
|
67
67
|
void startNavigation(const std::string& templateId, const TripConfig& trip) override;
|
|
68
68
|
void stopNavigation(const std::string& templateId) override;
|
|
69
|
+
void setManeuverState(const std::string& templateId, ManeuverState state) override;
|
|
69
70
|
|
|
70
71
|
private:
|
|
71
72
|
jni::global_ref<JHybridMapTemplateSpec::JavaPart> _javaPart;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// JManeuverState.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <fbjni/fbjni.h>
|
|
11
|
+
#include "ManeuverState.hpp"
|
|
12
|
+
|
|
13
|
+
namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
14
|
+
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The C++ JNI bridge between the C++ enum "ManeuverState" and the the Kotlin enum "ManeuverState".
|
|
19
|
+
*/
|
|
20
|
+
struct JManeuverState final: public jni::JavaClass<JManeuverState> {
|
|
21
|
+
public:
|
|
22
|
+
static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/swe/iternio/reactnativeautoplay/ManeuverState;";
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
/**
|
|
26
|
+
* Convert this Java/Kotlin-based enum to the C++ enum ManeuverState.
|
|
27
|
+
*/
|
|
28
|
+
[[maybe_unused]]
|
|
29
|
+
[[nodiscard]]
|
|
30
|
+
ManeuverState toCpp() const {
|
|
31
|
+
static const auto clazz = javaClassStatic();
|
|
32
|
+
static const auto fieldOrdinal = clazz->getField<int>("value");
|
|
33
|
+
int ordinal = this->getFieldValue(fieldOrdinal);
|
|
34
|
+
return static_cast<ManeuverState>(ordinal);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public:
|
|
38
|
+
/**
|
|
39
|
+
* Create a Java/Kotlin-based enum with the given C++ enum's value.
|
|
40
|
+
*/
|
|
41
|
+
[[maybe_unused]]
|
|
42
|
+
static jni::alias_ref<JManeuverState> fromCpp(ManeuverState value) {
|
|
43
|
+
static const auto clazz = javaClassStatic();
|
|
44
|
+
switch (value) {
|
|
45
|
+
case ManeuverState::CONTINUE:
|
|
46
|
+
static const auto fieldCONTINUE = clazz->getStaticField<JManeuverState>("CONTINUE");
|
|
47
|
+
return clazz->getStaticFieldValue(fieldCONTINUE);
|
|
48
|
+
case ManeuverState::INITIAL:
|
|
49
|
+
static const auto fieldINITIAL = clazz->getStaticField<JManeuverState>("INITIAL");
|
|
50
|
+
return clazz->getStaticFieldValue(fieldINITIAL);
|
|
51
|
+
case ManeuverState::PREPARE:
|
|
52
|
+
static const auto fieldPREPARE = clazz->getStaticField<JManeuverState>("PREPARE");
|
|
53
|
+
return clazz->getStaticFieldValue(fieldPREPARE);
|
|
54
|
+
case ManeuverState::EXECUTE:
|
|
55
|
+
static const auto fieldEXECUTE = clazz->getStaticField<JManeuverState>("EXECUTE");
|
|
56
|
+
return clazz->getStaticFieldValue(fieldEXECUTE);
|
|
57
|
+
default:
|
|
58
|
+
std::string stringValue = std::to_string(static_cast<int>(value));
|
|
59
|
+
throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
} // namespace margelo::nitro::swe::iternio::reactnativeautoplay
|
|
@@ -103,6 +103,8 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
103
103
|
jni::local_ref<jni::JArrayClass<JNitroMapButton>> mapButtons = this->getFieldValue(fieldMapButtons);
|
|
104
104
|
static const auto fieldHeaderActions = clazz->getField<jni::JArrayClass<JNitroAction>>("headerActions");
|
|
105
105
|
jni::local_ref<jni::JArrayClass<JNitroAction>> headerActions = this->getFieldValue(fieldHeaderActions);
|
|
106
|
+
static const auto fieldDefaultGuidanceBackgroundColor = clazz->getField<JNitroColor>("defaultGuidanceBackgroundColor");
|
|
107
|
+
jni::local_ref<JNitroColor> defaultGuidanceBackgroundColor = this->getFieldValue(fieldDefaultGuidanceBackgroundColor);
|
|
106
108
|
static const auto fieldPanButtonScrollPercentage = clazz->getField<jni::JDouble>("panButtonScrollPercentage");
|
|
107
109
|
jni::local_ref<jni::JDouble> panButtonScrollPercentage = this->getFieldValue(fieldPanButtonScrollPercentage);
|
|
108
110
|
static const auto fieldOnDidChangePanningInterface = clazz->getField<JFunc_void_bool::javaobject>("onDidChangePanningInterface");
|
|
@@ -239,6 +241,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
239
241
|
}
|
|
240
242
|
return __vector;
|
|
241
243
|
}()) : std::nullopt,
|
|
244
|
+
defaultGuidanceBackgroundColor != nullptr ? std::make_optional(defaultGuidanceBackgroundColor->toCpp()) : std::nullopt,
|
|
242
245
|
panButtonScrollPercentage != nullptr ? std::make_optional(panButtonScrollPercentage->value()) : std::nullopt,
|
|
243
246
|
onDidChangePanningInterface != nullptr ? std::make_optional([&]() -> std::function<void(bool /* isPanningInterfaceVisible */)> {
|
|
244
247
|
if (onDidChangePanningInterface->isInstanceOf(JFunc_void_bool_cxx::javaClassStatic())) [[likely]] {
|
|
@@ -258,7 +261,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
258
261
|
*/
|
|
259
262
|
[[maybe_unused]]
|
|
260
263
|
static jni::local_ref<JMapTemplateConfig::javaobject> fromCpp(const MapTemplateConfig& value) {
|
|
261
|
-
using JSignature = JMapTemplateConfig(jni::alias_ref<jni::JString>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JVisibleTravelEstimate>, jni::alias_ref<JFunc_void_Point_std__optional_Point_::javaobject>, jni::alias_ref<JFunc_void_Point_double::javaobject>, jni::alias_ref<JFunc_void_Point::javaobject>, jni::alias_ref<JFunc_void_Point::javaobject>, jni::alias_ref<JFunc_void_ColorScheme::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JArrayClass<JNitroMapButton>>, jni::alias_ref<jni::JArrayClass<JNitroAction>>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JFunc_void_bool::javaobject>);
|
|
264
|
+
using JSignature = JMapTemplateConfig(jni::alias_ref<jni::JString>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void_std__optional_bool_::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JVisibleTravelEstimate>, jni::alias_ref<JFunc_void_Point_std__optional_Point_::javaobject>, jni::alias_ref<JFunc_void_Point_double::javaobject>, jni::alias_ref<JFunc_void_Point::javaobject>, jni::alias_ref<JFunc_void_Point::javaobject>, jni::alias_ref<JFunc_void_ColorScheme::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<JFunc_void::javaobject>, jni::alias_ref<jni::JArrayClass<JNitroMapButton>>, jni::alias_ref<jni::JArrayClass<JNitroAction>>, jni::alias_ref<JNitroColor>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JFunc_void_bool::javaobject>);
|
|
262
265
|
static const auto clazz = javaClassStatic();
|
|
263
266
|
static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
|
|
264
267
|
return create(
|
|
@@ -298,6 +301,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
|
|
|
298
301
|
}
|
|
299
302
|
return __array;
|
|
300
303
|
}() : nullptr,
|
|
304
|
+
value.defaultGuidanceBackgroundColor.has_value() ? JNitroColor::fromCpp(value.defaultGuidanceBackgroundColor.value()) : nullptr,
|
|
301
305
|
value.panButtonScrollPercentage.has_value() ? jni::JDouble::valueOf(value.panButtonScrollPercentage.value()) : nullptr,
|
|
302
306
|
value.onDidChangePanningInterface.has_value() ? JFunc_void_bool_cxx::fromCpp(value.onDidChangePanningInterface.value()) : nullptr
|
|
303
307
|
);
|