@iternio/react-native-auto-play 0.5.14-beta.1 → 0.6.0
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/README.md +214 -29
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoSession.kt +5 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt +9 -2
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/NativeBackdrop.kt +40 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt +52 -0
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/GridTemplate.kt +47 -13
- package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +21 -2
- package/ios/Types.swift +3 -0
- package/ios/extensions/UIImage+Toggle.swift +5 -2
- package/ios/hybrid/HybridAutoPlay.swift +28 -16
- package/ios/hybrid/HybridMapTemplate.swift +22 -5
- package/ios/scenes/AutoPlayInterfaceController.swift +261 -72
- package/ios/templates/AutoPlayMapPanelDelegate.swift +190 -0
- package/ios/templates/AutoPlayTemplate.swift +24 -2
- package/ios/templates/GridTemplate.swift +57 -57
- package/ios/templates/InformationTemplate.swift +84 -9
- package/ios/templates/ListTemplate.swift +66 -11
- package/ios/templates/MapTemplate.swift +83 -68
- package/ios/templates/MessageTemplate.swift +72 -6
- package/ios/templates/Parser.swift +564 -69
- package/ios/templates/SearchTemplate.swift +1 -1
- package/ios/templates/TemplateStore.swift +5 -15
- package/ios/utils/SymbolFont.swift +13 -28
- package/lib/Constants.d.ts +4 -0
- package/lib/Constants.js +6 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/specs/MapTemplate.nitro.d.ts +3 -1
- package/lib/templates/GridTemplate.d.ts +23 -3
- package/lib/templates/GridTemplate.js +8 -0
- package/lib/templates/InformationTemplate.d.ts +38 -12
- package/lib/templates/ListTemplate.d.ts +16 -47
- package/lib/templates/MapTemplate.d.ts +26 -2
- package/lib/templates/MapTemplate.js +16 -2
- package/lib/templates/MessageTemplate.d.ts +52 -11
- package/lib/templates/MessageTemplate.js +1 -1
- package/lib/utils/NitroOptionsPanel.d.ts +103 -0
- package/lib/utils/NitroOptionsPanel.js +63 -0
- package/lib/utils/NitroSection.d.ts +89 -2
- package/lib/utils/NitroSection.js +49 -2
- package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +1 -0
- package/nitrogen/generated/android/c++/JChargingConnector.hpp +79 -0
- package/nitrogen/generated/android/c++/JGridImageSize.hpp +64 -0
- package/nitrogen/generated/android/c++/JGridTemplateConfig.hpp +7 -1
- package/nitrogen/generated/android/c++/JHybridGridTemplateSpec.cpp +4 -0
- package/nitrogen/generated/android/c++/JHybridInformationTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JHybridListTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp +78 -3
- package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.hpp +2 -1
- package/nitrogen/generated/android/c++/JHybridSearchTemplateSpec.cpp +12 -0
- package/nitrogen/generated/android/c++/JInformationTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JListImageType.hpp +67 -0
- package/nitrogen/generated/android/c++/JListTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JNitroChargerLocation.hpp +115 -0
- package/nitrogen/generated/android/c++/JNitroChargerOutlet.hpp +82 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelChargerSection.hpp +112 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelConfig.hpp +157 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelGridSection.hpp +102 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.cpp +30 -0
- package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.hpp +129 -0
- package/nitrogen/generated/android/c++/JNitroRow.hpp +33 -3
- package/nitrogen/generated/android/c++/JNitroSection.hpp +6 -0
- package/nitrogen/generated/android/c++/JSearchTemplateConfig.hpp +6 -0
- package/nitrogen/generated/android/c++/JWaypointCoordinate.hpp +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ChargingConnector.kt +30 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridImageSize.kt +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridTemplateConfig.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +5 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ListImageType.kt +26 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerLocation.kt +90 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerOutlet.kt +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelChargerSection.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelConfig.kt +61 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelGridSection.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelSection.kt +75 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroRow.kt +36 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/WaypointCoordinate.kt +61 -0
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.hpp +174 -0
- package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +27 -0
- package/nitrogen/generated/ios/c++/HybridGridTemplateSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridInformationTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridListTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/c++/HybridMapTemplateSpecSwift.hpp +47 -1
- package/nitrogen/generated/ios/c++/HybridSearchTemplateSpecSwift.hpp +9 -0
- package/nitrogen/generated/ios/swift/ChargingConnector.swift +68 -0
- package/nitrogen/generated/ios/swift/GridImageSize.swift +48 -0
- package/nitrogen/generated/ios/swift/GridTemplateConfig.swift +12 -1
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec.swift +2 -1
- package/nitrogen/generated/ios/swift/HybridMapTemplateSpec_cxx.swift +31 -4
- package/nitrogen/generated/ios/swift/ListImageType.swift +52 -0
- package/nitrogen/generated/ios/swift/NitroChargerLocation.swift +161 -0
- package/nitrogen/generated/ios/swift/NitroChargerOutlet.swift +65 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelChargerSection.swift +64 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelConfig.swift +94 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelGridSection.swift +53 -0
- package/nitrogen/generated/ios/swift/NitroOptionsPanelSection.swift +32 -0
- package/nitrogen/generated/ios/swift/NitroRow.swift +81 -1
- package/nitrogen/generated/ios/swift/WaypointCoordinate.swift +52 -0
- package/nitrogen/generated/shared/c++/ChargingConnector.hpp +104 -0
- package/nitrogen/generated/shared/c++/GridImageSize.hpp +84 -0
- package/nitrogen/generated/shared/c++/GridTemplateConfig.hpp +8 -1
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.hpp +5 -1
- package/nitrogen/generated/shared/c++/ListImageType.hpp +88 -0
- package/nitrogen/generated/shared/c++/NitroChargerLocation.hpp +131 -0
- package/nitrogen/generated/shared/c++/NitroChargerOutlet.hpp +98 -0
- package/nitrogen/generated/shared/c++/NitroOptionsPanelChargerSection.hpp +98 -0
- package/nitrogen/generated/shared/c++/NitroOptionsPanelConfig.hpp +107 -0
- package/nitrogen/generated/shared/c++/NitroOptionsPanelGridSection.hpp +91 -0
- package/nitrogen/generated/shared/c++/NitroRow.hpp +39 -2
- package/nitrogen/generated/shared/c++/WaypointCoordinate.hpp +91 -0
- package/package.json +1 -1
- package/src/Constants.ts +9 -0
- package/src/index.ts +1 -0
- package/src/specs/MapTemplate.nitro.ts +3 -1
- package/src/templates/GridTemplate.ts +38 -3
- package/src/templates/InformationTemplate.ts +60 -29
- package/src/templates/ListTemplate.ts +27 -55
- package/src/templates/MapTemplate.ts +60 -2
- package/src/templates/MessageTemplate.ts +71 -24
- package/src/utils/NitroOptionsPanel.ts +218 -0
- package/src/utils/NitroSection.ts +160 -5
|
@@ -9,8 +9,7 @@ import CarPlay
|
|
|
9
9
|
class TemplateStore {
|
|
10
10
|
/// Guards `store`. Templates are added from the JS thread (the
|
|
11
11
|
/// `createXTemplate` hybrid methods are synchronous and never hop actors)
|
|
12
|
-
/// while the CarPlay delegate callbacks remove/purge them on the main
|
|
13
|
-
/// thread, and Swift dictionaries are not thread-safe.
|
|
12
|
+
/// while the CarPlay delegate callbacks remove/purge them on the main thread
|
|
14
13
|
private let lock = NSLock()
|
|
15
14
|
private var store: [String: AutoPlayTemplate] = [:]
|
|
16
15
|
|
|
@@ -21,7 +20,7 @@ class TemplateStore {
|
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
func getCPTemplate(templateId key: String) -> CPTemplate? {
|
|
24
|
-
return withLock { store[key] }?.getTemplate()
|
|
23
|
+
return try? withLock { store[key] }?.getTemplate()
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
func getTemplate(templateId: String) throws -> AutoPlayTemplate {
|
|
@@ -36,9 +35,6 @@ class TemplateStore {
|
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
func removeTemplate(templateId: String) {
|
|
39
|
-
// Remove first, then notify outside the lock: `onPopped` runs a JS
|
|
40
|
-
// callback which can re-enter the store (see
|
|
41
|
-
// VoiceInputTemplate.onDidDisappear).
|
|
42
38
|
let removed = withLock { store.removeValue(forKey: templateId) }
|
|
43
39
|
|
|
44
40
|
removed?.onPopped()
|
|
@@ -53,11 +49,10 @@ class TemplateStore {
|
|
|
53
49
|
}
|
|
54
50
|
|
|
55
51
|
func purge() {
|
|
56
|
-
|
|
57
|
-
// intercept, so they need an `onPopped()` just like an explicit pop.
|
|
52
|
+
/// These templates were popped by a native CarPlay button we cannot intercept, so they need an `onPopped()`
|
|
58
53
|
let removed = withLock {
|
|
59
54
|
let searchTemplates = store.filter {
|
|
60
|
-
$0.value.getTemplate() is CPSearchTemplate
|
|
55
|
+
(try? $0.value.getTemplate() is CPSearchTemplate) ?? false
|
|
61
56
|
}
|
|
62
57
|
searchTemplates.keys.forEach { store.removeValue(forKey: $0) }
|
|
63
58
|
|
|
@@ -75,12 +70,7 @@ class TemplateStore {
|
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
func disconnect() {
|
|
78
|
-
|
|
79
|
-
// individually. Without an `onPopped()` here anything the app tied to a
|
|
80
|
-
// template's lifetime (event listeners, timers, cached render state)
|
|
81
|
-
// leaks for the rest of the app lifetime, and the host app keeps
|
|
82
|
-
// running after a disconnect. Android does the same on
|
|
83
|
-
// `Lifecycle.Event.ON_DESTROY` (AndroidAutoScreen.kt).
|
|
73
|
+
/// notify every visible template about it being gone
|
|
84
74
|
let removed = withLock {
|
|
85
75
|
let templates = Array(store.values)
|
|
86
76
|
store = [:]
|
|
@@ -65,7 +65,8 @@ class SymbolFont {
|
|
|
65
65
|
foregroundColor: UIColor,
|
|
66
66
|
backgroundColor: UIColor,
|
|
67
67
|
size: CGFloat,
|
|
68
|
-
fontScale: CGFloat
|
|
68
|
+
fontScale: CGFloat,
|
|
69
|
+
displayScale: CGFloat
|
|
69
70
|
) -> UIImage? {
|
|
70
71
|
guard let font = uiFont(for: glyphImage, size: size, fontScale: fontScale) else {
|
|
71
72
|
return nil
|
|
@@ -89,7 +90,7 @@ class SymbolFont {
|
|
|
89
90
|
)
|
|
90
91
|
|
|
91
92
|
// Start drawing
|
|
92
|
-
UIGraphicsBeginImageContextWithOptions(canvasSize, false,
|
|
93
|
+
UIGraphicsBeginImageContextWithOptions(canvasSize, false, displayScale)
|
|
93
94
|
guard let context = UIGraphicsGetCurrentContext() else {
|
|
94
95
|
return nil
|
|
95
96
|
}
|
|
@@ -128,7 +129,8 @@ class SymbolFont {
|
|
|
128
129
|
value: backgroundColor.lightColor
|
|
129
130
|
),
|
|
130
131
|
size: size,
|
|
131
|
-
fontScale: fontScale
|
|
132
|
+
fontScale: fontScale,
|
|
133
|
+
displayScale: traitCollection.displayScale
|
|
132
134
|
),
|
|
133
135
|
let darkImage = imageFromGlyph(
|
|
134
136
|
glyphImage: glyphImage,
|
|
@@ -139,7 +141,8 @@ class SymbolFont {
|
|
|
139
141
|
value: backgroundColor.darkColor
|
|
140
142
|
),
|
|
141
143
|
size: size,
|
|
142
|
-
fontScale: fontScale
|
|
144
|
+
fontScale: fontScale,
|
|
145
|
+
displayScale: traitCollection.displayScale
|
|
143
146
|
)
|
|
144
147
|
else {
|
|
145
148
|
return nil
|
|
@@ -148,15 +151,19 @@ class SymbolFont {
|
|
|
148
151
|
// Create a UIImageAsset that contains both light and dark variants
|
|
149
152
|
let imageAsset = UIImageAsset()
|
|
150
153
|
|
|
154
|
+
let displayScaleTrait = UITraitCollection(displayScale: traitCollection.displayScale)
|
|
155
|
+
|
|
151
156
|
// Register the light image for light trait collection
|
|
152
157
|
let lightTraits = UITraitCollection(traitsFrom: [
|
|
153
|
-
UITraitCollection(userInterfaceStyle: .light)
|
|
158
|
+
UITraitCollection(userInterfaceStyle: .light),
|
|
159
|
+
displayScaleTrait,
|
|
154
160
|
])
|
|
155
161
|
imageAsset.register(lightImage, with: lightTraits)
|
|
156
162
|
|
|
157
163
|
// Register the dark image for dark trait collection
|
|
158
164
|
let darkTraits = UITraitCollection(traitsFrom: [
|
|
159
|
-
UITraitCollection(userInterfaceStyle: .dark)
|
|
165
|
+
UITraitCollection(userInterfaceStyle: .dark),
|
|
166
|
+
displayScaleTrait,
|
|
160
167
|
])
|
|
161
168
|
imageAsset.register(darkImage, with: darkTraits)
|
|
162
169
|
|
|
@@ -167,34 +174,12 @@ class SymbolFont {
|
|
|
167
174
|
static func imageFromNitroImage(
|
|
168
175
|
image: GlyphImage?,
|
|
169
176
|
size: CGFloat = 32,
|
|
170
|
-
noImageAsset: Bool = false,
|
|
171
177
|
traitCollection: UITraitCollection
|
|
172
178
|
) -> UIImage? {
|
|
173
179
|
guard let image else { return nil }
|
|
174
180
|
|
|
175
181
|
let fontScale = image.fontScale ?? 1.0
|
|
176
182
|
|
|
177
|
-
if noImageAsset {
|
|
178
|
-
let foregroundColor = Parser.doubleToColor(
|
|
179
|
-
value: traitCollection.userInterfaceStyle == .light
|
|
180
|
-
? image.color.lightColor : image.color.darkColor
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
let backgroundColor = Parser.doubleToColor(
|
|
184
|
-
value: traitCollection.userInterfaceStyle == .light
|
|
185
|
-
? image.backgroundColor.lightColor
|
|
186
|
-
: image.backgroundColor.darkColor
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
return SymbolFont.imageFromGlyph(
|
|
190
|
-
glyphImage: image,
|
|
191
|
-
foregroundColor: foregroundColor,
|
|
192
|
-
backgroundColor: backgroundColor,
|
|
193
|
-
size: size,
|
|
194
|
-
fontScale: fontScale
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
|
-
|
|
198
183
|
return SymbolFont.imageFromGlyph(
|
|
199
184
|
glyphImage: image,
|
|
200
185
|
size: size,
|
package/lib/Constants.js
ADDED
package/lib/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare enum AutoPlayModules {
|
|
|
14
14
|
AutoPlayRoot = "AutoPlayRoot",
|
|
15
15
|
CarPlayDashboard = "CarPlayDashboard"
|
|
16
16
|
}
|
|
17
|
+
export * from './Constants';
|
|
17
18
|
export * from './components/SafeAreaView';
|
|
18
19
|
export * from './hooks/useAndroidAutoTelemetry';
|
|
19
20
|
export * from './hooks/useFocusedEffect';
|
package/lib/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export var AutoPlayModules;
|
|
|
20
20
|
AutoPlayModules["AutoPlayRoot"] = "AutoPlayRoot";
|
|
21
21
|
AutoPlayModules["CarPlayDashboard"] = "CarPlayDashboard";
|
|
22
22
|
})(AutoPlayModules || (AutoPlayModules = {}));
|
|
23
|
+
export * from './Constants';
|
|
23
24
|
export * from './components/SafeAreaView';
|
|
24
25
|
export * from './hooks/useAndroidAutoTelemetry';
|
|
25
26
|
export * from './hooks/useFocusedEffect';
|
|
@@ -6,6 +6,7 @@ import type { TripConfig, TripPoint, TripPreviewTextConfiguration, TripsConfig }
|
|
|
6
6
|
import type { NitroNavigationAlert } from '../utils/NitroAlert';
|
|
7
7
|
import type { NitroManeuver } from '../utils/NitroManeuver';
|
|
8
8
|
import type { NitroMapButton } from '../utils/NitroMapButton';
|
|
9
|
+
import type { NitroOptionsPanelConfig } from '../utils/NitroOptionsPanel';
|
|
9
10
|
import type { NitroTemplateConfig } from './AutoPlay.nitro';
|
|
10
11
|
interface MapTemplateConfig extends NitroTemplateConfig, NitroMapTemplateConfig {
|
|
11
12
|
}
|
|
@@ -23,8 +24,9 @@ export interface MapTemplate extends HybridObject<{
|
|
|
23
24
|
updateVisibleTravelEstimate(templateId: string, visibleTravelEstimate: VisibleTravelEstimate): void;
|
|
24
25
|
updateTravelEstimates(templateId: string, steps: Array<TripPoint>): void;
|
|
25
26
|
updateManeuvers(templateId: string, maneuvers: NitroManeuver): void;
|
|
26
|
-
startNavigation(templateId: string, trip: TripConfig): void
|
|
27
|
+
startNavigation(templateId: string, trip: TripConfig): Promise<void>;
|
|
27
28
|
stopNavigation(templateId: string): void;
|
|
28
29
|
setManeuverState(templateId: string, state: ManeuverState): void;
|
|
30
|
+
updateOptionsPanel(templateId: string, config?: NitroOptionsPanelConfig): Promise<void>;
|
|
29
31
|
}
|
|
30
32
|
export {};
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { AutoText } from '../types/Text';
|
|
2
2
|
import { type NitroAction } from '../utils/NitroAction';
|
|
3
3
|
import { type GridButton, type NitroGridButton } from '../utils/NitroGrid';
|
|
4
|
-
import type { BaseMapTemplateConfig } from './MapTemplate';
|
|
4
|
+
import type { BaseMapTemplateConfig, PanelHeaderActions } from './MapTemplate';
|
|
5
5
|
import { type HeaderActions, type NitroBaseMapTemplateConfig, Template, type TemplateConfig } from './Template';
|
|
6
|
+
/**
|
|
7
|
+
* Controls the size of Android grid items. A selected size requires Android Car API 8.
|
|
8
|
+
* @namespace Android
|
|
9
|
+
*/
|
|
10
|
+
export type GridImageSize = 'unset' | 'large' | 'medium' | 'small';
|
|
6
11
|
export interface NitroGridTemplateConfig extends TemplateConfig {
|
|
7
12
|
headerActions?: Array<NitroAction>;
|
|
8
13
|
title: AutoText;
|
|
9
14
|
buttons: Array<NitroGridButton>;
|
|
15
|
+
imageSize?: GridImageSize;
|
|
10
16
|
mapConfig?: NitroBaseMapTemplateConfig;
|
|
11
17
|
}
|
|
12
18
|
export type GridTemplateConfig = Omit<NitroGridTemplateConfig, 'headerActions' | 'buttons' | 'mapConfig'> & {
|
|
@@ -16,10 +22,24 @@ export type GridTemplateConfig = Omit<NitroGridTemplateConfig, 'headerActions' |
|
|
|
16
22
|
headerActions?: HeaderActions<GridTemplate>;
|
|
17
23
|
buttons: Array<GridButton<GridTemplate>>;
|
|
18
24
|
/**
|
|
19
|
-
*
|
|
25
|
+
* Controls the size of all images in the Android grid. Defaults to `unset`, which preserves
|
|
26
|
+
* the platform's standard grid layout. `large`, `medium`, and `small` require Android Car API
|
|
27
|
+
* 8. Ignored (with a `__DEV__` warning) when `mapConfig` is also set — `MapWithContentTemplate`
|
|
28
|
+
* does not support the sized grid content type.
|
|
20
29
|
* @namespace Android
|
|
21
30
|
*/
|
|
22
|
-
|
|
31
|
+
imageSize?: GridImageSize;
|
|
32
|
+
/**
|
|
33
|
+
* If mapConfig is defined, it will use a MapWithContentTemplate with the current template. This results in a GridTemplate with a map in background. No actions need to be specified, can be empty object.
|
|
34
|
+
* @namespace Android - uses MapWithContentTemplate
|
|
35
|
+
* @namespace iOS - renders as a CPMapPanel on the current root map template (iOS 27+);
|
|
36
|
+
* `headerActions` here is Android-only — on iOS this template's own `headerActions` are
|
|
37
|
+
* applied to the root map template's nav bar instead, since CarPlay has no separate header
|
|
38
|
+
* for the map behind a panel.
|
|
39
|
+
*/
|
|
40
|
+
mapConfig?: Omit<BaseMapTemplateConfig<GridTemplate>, 'headerActions'> & {
|
|
41
|
+
headerActions?: PanelHeaderActions<GridTemplate>;
|
|
42
|
+
};
|
|
23
43
|
};
|
|
24
44
|
export declare class GridTemplate extends Template<GridTemplateConfig, HeaderActions<GridTemplate>> {
|
|
25
45
|
private template;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
1
2
|
import { NitroModules } from 'react-native-nitro-modules';
|
|
2
3
|
import { NitroActionUtil } from '../utils/NitroAction';
|
|
3
4
|
import { NitroGridUtil } from '../utils/NitroGrid';
|
|
@@ -9,6 +10,13 @@ export class GridTemplate extends Template {
|
|
|
9
10
|
constructor(config) {
|
|
10
11
|
super(config);
|
|
11
12
|
const { headerActions, buttons, mapConfig, ...rest } = config;
|
|
13
|
+
if (__DEV__ &&
|
|
14
|
+
Platform.OS === 'android' &&
|
|
15
|
+
mapConfig != null &&
|
|
16
|
+
rest.imageSize != null &&
|
|
17
|
+
rest.imageSize !== 'unset') {
|
|
18
|
+
console.warn('GridTemplate: imageSize is ignored on Android when mapConfig is set — MapWithContentTemplate does not support the sized grid content type');
|
|
19
|
+
}
|
|
12
20
|
const nitroConfig = {
|
|
13
21
|
...rest,
|
|
14
22
|
id: this.id,
|
|
@@ -3,8 +3,9 @@ import type { AutoText } from '../types/Text';
|
|
|
3
3
|
import { type NitroAction } from '../utils/NitroAction';
|
|
4
4
|
import { type NitroSection } from '../utils/NitroSection';
|
|
5
5
|
import type { TextRow } from './ListTemplate';
|
|
6
|
-
import type { BaseMapTemplateConfig } from './MapTemplate';
|
|
6
|
+
import type { BaseMapTemplateConfig, PanelActionsIos, PanelHeaderActions } from './MapTemplate';
|
|
7
7
|
import { type HeaderActions, type NitroBaseMapTemplateConfig, Template, type TemplateConfig } from './Template';
|
|
8
|
+
type InformationActionsAndroid<T> = [CustomActionButtonAndroid<T>] | [CustomActionButtonAndroid<T>, CustomActionButtonAndroid<T>];
|
|
8
9
|
export interface NitroInformationTemplateConfig extends TemplateConfig {
|
|
9
10
|
headerActions?: Array<NitroAction>;
|
|
10
11
|
title: AutoText;
|
|
@@ -13,7 +14,7 @@ export interface NitroInformationTemplateConfig extends TemplateConfig {
|
|
|
13
14
|
mapConfig?: NitroBaseMapTemplateConfig;
|
|
14
15
|
}
|
|
15
16
|
export type InformationItems = [TextRow] | [TextRow, TextRow] | [TextRow, TextRow, TextRow] | [TextRow, TextRow, TextRow, TextRow];
|
|
16
|
-
|
|
17
|
+
type InformationTemplateBaseConfig = Omit<NitroInformationTemplateConfig, 'headerActions' | 'section' | 'mapConfig' | 'actions'> & {
|
|
17
18
|
/**
|
|
18
19
|
* action buttons, usually at the the top right on Android and a top bar on iOS
|
|
19
20
|
*/
|
|
@@ -23,30 +24,55 @@ export type InformationTemplateConfig = Omit<NitroInformationTemplateConfig, 'he
|
|
|
23
24
|
* @namespace iOS this is an InformationTemplate, ⚠️ the row image is NOT supported
|
|
24
25
|
*/
|
|
25
26
|
items?: InformationItems;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* `actions`/`mapConfig` are a discriminated union — `mapConfig` restricts `actions.ios` to at
|
|
30
|
+
* most one `TextButton` plus one icon-only `ImageButton` (a `CPMapPanel` can't show more), vs. up
|
|
31
|
+
* to three `TextButton`s otherwise. If your `mapConfig` value comes from a variable/prop rather
|
|
32
|
+
* than an inline literal, TS can't narrow which branch applies — assign it to a local `const` and
|
|
33
|
+
* branch with `if (mapConfig) { ... } else { ... }` into two separate constructor calls instead
|
|
34
|
+
* of passing it straight through to one.
|
|
35
|
+
*/
|
|
36
|
+
export type InformationTemplateConfig = InformationTemplateBaseConfig & ({
|
|
37
|
+
mapConfig?: undefined;
|
|
31
38
|
/**
|
|
32
39
|
* @namespace Android up to 2 buttons of type TextButton, TextAndImageButton or ImageButton
|
|
33
40
|
* @namespace iOS - up to 3 buttons of type TextButton
|
|
34
41
|
*/
|
|
35
42
|
actions?: {
|
|
36
|
-
android?:
|
|
37
|
-
CustomActionButtonAndroid<InformationTemplate>,
|
|
38
|
-
CustomActionButtonAndroid<InformationTemplate>
|
|
39
|
-
];
|
|
43
|
+
android?: InformationActionsAndroid<InformationTemplate>;
|
|
40
44
|
ios?: [
|
|
41
45
|
TextButton<InformationTemplate>,
|
|
42
46
|
TextButton<InformationTemplate>,
|
|
43
47
|
TextButton<InformationTemplate>
|
|
44
48
|
] | [TextButton<InformationTemplate>, TextButton<InformationTemplate>] | [TextButton<InformationTemplate>];
|
|
45
49
|
};
|
|
46
|
-
}
|
|
50
|
+
} | {
|
|
51
|
+
/**
|
|
52
|
+
* If mapConfig is defined, it will use a MapWithContentTemplate with the current template. This results in a PaneTemplate with a map in background. No actions need to be specified, can be empty object.
|
|
53
|
+
* @namespace Android - uses MapWithContentTemplate
|
|
54
|
+
* @namespace iOS - renders as a CPMapPanel on the current root map template (iOS 27+);
|
|
55
|
+
* `headerActions` here is Android-only — on iOS this template's own `headerActions` are
|
|
56
|
+
* applied to the root map template's nav bar instead, since CarPlay has no separate
|
|
57
|
+
* header for the map behind a panel.
|
|
58
|
+
*/
|
|
59
|
+
mapConfig: Omit<BaseMapTemplateConfig<InformationTemplate>, 'headerActions'> & {
|
|
60
|
+
headerActions?: PanelHeaderActions<InformationTemplate>;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* @namespace Android up to 2 buttons of type TextButton, TextAndImageButton or ImageButton
|
|
64
|
+
* @namespace iOS - the panel can only show one TextButton plus one optional icon-only
|
|
65
|
+
* ImageButton, see PanelActionsIos
|
|
66
|
+
*/
|
|
67
|
+
actions?: {
|
|
68
|
+
android?: InformationActionsAndroid<InformationTemplate>;
|
|
69
|
+
ios?: PanelActionsIos<InformationTemplate>;
|
|
70
|
+
};
|
|
71
|
+
});
|
|
47
72
|
export declare class InformationTemplate extends Template<InformationTemplateConfig, HeaderActions<InformationTemplate>> {
|
|
48
73
|
private template;
|
|
49
74
|
constructor(config: InformationTemplateConfig);
|
|
50
75
|
updateItems(items?: InformationItems): Promise<void>;
|
|
51
76
|
private getSection;
|
|
52
77
|
}
|
|
78
|
+
export {};
|
|
@@ -1,50 +1,14 @@
|
|
|
1
|
-
import type { AutoImage } from '../types/Image';
|
|
2
1
|
import type { AutoText } from '../types/Text';
|
|
3
2
|
import { type NitroAction } from '../utils/NitroAction';
|
|
4
|
-
import { type NitroSection } from '../utils/NitroSection';
|
|
5
|
-
import type { BaseMapTemplateConfig } from './MapTemplate';
|
|
3
|
+
import { type NitroSection, type Section } from '../utils/NitroSection';
|
|
4
|
+
import type { BaseMapTemplateConfig, PanelHeaderActions } from './MapTemplate';
|
|
6
5
|
import { type HeaderActions, type NitroBaseMapTemplateConfig, Template, type TemplateConfig } from './Template';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export type DefaultRow
|
|
13
|
-
type: 'default';
|
|
14
|
-
/**
|
|
15
|
-
* adds a chevron at the end of the row
|
|
16
|
-
*/
|
|
17
|
-
browsable?: boolean;
|
|
18
|
-
onPress: (template: T) => void;
|
|
19
|
-
detailedText?: AutoText;
|
|
20
|
-
};
|
|
21
|
-
export type ToggleRow<T> = BaseRow & {
|
|
22
|
-
type: 'toggle';
|
|
23
|
-
checked: boolean;
|
|
24
|
-
onPress: (template: T, checked: boolean) => void;
|
|
25
|
-
};
|
|
26
|
-
export type RadioRow<T> = BaseRow & {
|
|
27
|
-
type: 'radio';
|
|
28
|
-
onPress: (template: T) => void;
|
|
29
|
-
selected?: boolean;
|
|
30
|
-
};
|
|
31
|
-
export type TextRow = BaseRow & {
|
|
32
|
-
type: 'text';
|
|
33
|
-
detailedText?: AutoText;
|
|
34
|
-
};
|
|
35
|
-
export type MultiSection<T> = {
|
|
36
|
-
type: 'default';
|
|
37
|
-
title: string;
|
|
38
|
-
items: Array<DefaultRow<T> | ToggleRow<T> | TextRow>;
|
|
39
|
-
} | {
|
|
40
|
-
type: 'radio';
|
|
41
|
-
title: string;
|
|
42
|
-
items: Array<RadioRow<T>>;
|
|
43
|
-
};
|
|
44
|
-
export type SingleSection<T> = {
|
|
45
|
-
[K in MultiSection<T> as K['type']]: Omit<K, 'title' | 'detailedText'>;
|
|
46
|
-
}[MultiSection<T>['type']];
|
|
47
|
-
export type Section<T> = Array<MultiSection<T>> | SingleSection<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Controls the Android image size for a list item.
|
|
8
|
+
* @namespace Android
|
|
9
|
+
*/
|
|
10
|
+
export type ListImageType = 'large' | 'medium' | 'small' | 'extra_small' | 'icon';
|
|
11
|
+
export type { DefaultRow, MultiSection, RadioRow, Section, SingleSection, TextRow, ToggleRow, WaypointCoordinate, WaypointRow, } from '../utils/NitroSection';
|
|
48
12
|
export interface NitroListTemplateConfig extends TemplateConfig {
|
|
49
13
|
headerActions?: Array<NitroAction>;
|
|
50
14
|
title: AutoText;
|
|
@@ -65,13 +29,18 @@ export type ListTemplateConfig = Omit<NitroListTemplateConfig, 'headerActions' |
|
|
|
65
29
|
sections?: Section<ListTemplate>;
|
|
66
30
|
/**
|
|
67
31
|
* If mapConfig is defined, it will use a MapWithContentTemplate with the current template. This results in a ListTemplate with a map in background. No actions need to be specified, can be empty object.
|
|
68
|
-
* @namespace Android
|
|
32
|
+
* @namespace Android - uses MapWithContentTemplate
|
|
33
|
+
* @namespace iOS - renders as a CPMapPanel on the current root map template (iOS 27+);
|
|
34
|
+
* `headerActions` here is Android-only — on iOS this template's own `headerActions` are
|
|
35
|
+
* applied to the root map template's nav bar instead, since CarPlay has no separate header
|
|
36
|
+
* for the map behind a panel.
|
|
69
37
|
*/
|
|
70
|
-
mapConfig?: BaseMapTemplateConfig<ListTemplate
|
|
38
|
+
mapConfig?: Omit<BaseMapTemplateConfig<ListTemplate>, 'headerActions'> & {
|
|
39
|
+
headerActions?: PanelHeaderActions<ListTemplate>;
|
|
40
|
+
};
|
|
71
41
|
};
|
|
72
42
|
export declare class ListTemplate extends Template<ListTemplateConfig, HeaderActions<ListTemplate>> {
|
|
73
43
|
private template;
|
|
74
44
|
constructor(config: ListTemplateConfig);
|
|
75
45
|
updateSections(sections?: Section<ListTemplate>): Promise<void>;
|
|
76
46
|
}
|
|
77
|
-
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { AutoText } from '..';
|
|
3
|
-
import type { ActionButtonAndroid, MapButton, MapPanButton } from '../types/Button';
|
|
3
|
+
import type { ActionButtonAndroid, ImageButton, MapButton, MapPanButton, TextButton } from '../types/Button';
|
|
4
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';
|
|
@@ -8,7 +8,9 @@ import { type NitroAction } from '../utils/NitroAction';
|
|
|
8
8
|
import { type NavigationAlert } from '../utils/NitroAlert';
|
|
9
9
|
import { type NitroColor, type ThemedColor } from '../utils/NitroColor';
|
|
10
10
|
import { NitroMapButton } from '../utils/NitroMapButton';
|
|
11
|
+
import { type OptionsPanelConfig } from '../utils/NitroOptionsPanel';
|
|
11
12
|
import { type HeaderActionsIos, type NitroBaseMapTemplateConfig, Template, type TemplateConfig } from './Template';
|
|
13
|
+
export type { ChargerLocation, ChargerOutlet, ChargingConnector, OptionsPanelChargerSection, OptionsPanelConfig, OptionsPanelGridSection, OptionsPanelListSection, OptionsPanelSection, } from '../utils/NitroOptionsPanel';
|
|
12
14
|
export type Point = {
|
|
13
15
|
x: number;
|
|
14
16
|
y: number;
|
|
@@ -68,6 +70,17 @@ export type MapHeaderActions<T> = {
|
|
|
68
70
|
android?: HeaderActionsAndroidMap<T>;
|
|
69
71
|
ios?: HeaderActionsIos<T>;
|
|
70
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* @namespace iOS - not supported; CarPlay has no separate header for the map behind a panel, so
|
|
75
|
+
* the panel template's own `headerActions` are applied to the root map template's nav bar instead.
|
|
76
|
+
*/
|
|
77
|
+
export type PanelHeaderActions<T> = Omit<MapHeaderActions<T>, 'ios'>;
|
|
78
|
+
/**
|
|
79
|
+
* @namespace iOS - a CPMapPanel can only show one CPTextButton (with a title) and one
|
|
80
|
+
* optional icon-only button (any title is dropped natively), so a second action must be an
|
|
81
|
+
* ImageButton rather than a TextButton, and a third action isn't supported at all.
|
|
82
|
+
*/
|
|
83
|
+
export type PanelActionsIos<T> = [TextButton<T>] | [TextButton<T>, ImageButton<T>];
|
|
71
84
|
export type BaseMapTemplateConfig<T> = {
|
|
72
85
|
/**
|
|
73
86
|
* buttons that represent actions on the map template, usually on the bottom right corner
|
|
@@ -85,6 +98,12 @@ export type MapTemplateConfig = Omit<NitroMapTemplateConfig, 'mapButtons' | 'hea
|
|
|
85
98
|
* react component that is rendered
|
|
86
99
|
*/
|
|
87
100
|
component: React.ComponentType<RootComponentInitialProps>;
|
|
101
|
+
/**
|
|
102
|
+
* the panel shown when tapping the ellipsis button next to the travel estimates during active navigation (iOS 27+).
|
|
103
|
+
* No-op on Android
|
|
104
|
+
* @namespace iOS
|
|
105
|
+
*/
|
|
106
|
+
optionsPanel?: OptionsPanelConfig<MapTemplate>;
|
|
88
107
|
/**
|
|
89
108
|
* Notification that navigation was stopped. May occur when another source such as the car head unit starts navigating.
|
|
90
109
|
* The navigation session on Android Auto/CarPlay is stopped already when this callback is triggered, make sure to stop other things like TTS too.
|
|
@@ -110,6 +129,11 @@ export declare class MapTemplate extends Template<MapTemplateConfig, MapTemplate
|
|
|
110
129
|
id: string;
|
|
111
130
|
private template;
|
|
112
131
|
constructor(config: MapTemplateConfig);
|
|
132
|
+
/**
|
|
133
|
+
* @namespace iOS updates the panel shown when tapping the ellipsis button
|
|
134
|
+
* next to the travel estimates during navigation (iOS 27+).
|
|
135
|
+
*/
|
|
136
|
+
updateOptionsPanel(optionsPanel?: OptionsPanelConfig<MapTemplate>): Promise<void> | undefined;
|
|
113
137
|
setMapButtons(mapButtons: MapTemplateConfig['mapButtons']): Promise<void>;
|
|
114
138
|
setHeaderActions(headerActions: MapTemplateConfig['headerActions']): Promise<void>;
|
|
115
139
|
/**
|
|
@@ -155,7 +179,7 @@ export declare class MapTemplate extends Template<MapTemplateConfig, MapTemplate
|
|
|
155
179
|
* either use showTripSelector to show a set of trips and let the user start the navigation session
|
|
156
180
|
* or use this to start a navigation session without asking the user
|
|
157
181
|
*/
|
|
158
|
-
startNavigation(trip: TripConfig): void
|
|
182
|
+
startNavigation(trip: TripConfig): Promise<void>;
|
|
159
183
|
stopNavigation(): void;
|
|
160
184
|
/**
|
|
161
185
|
* Sets the current maneuver state indicating progress within a maneuver.
|
|
@@ -10,6 +10,7 @@ import { NitroAlertUtil } from '../utils/NitroAlert';
|
|
|
10
10
|
import { NitroColorUtil } from '../utils/NitroColor';
|
|
11
11
|
import { NitroManeuverUtil } from '../utils/NitroManeuver';
|
|
12
12
|
import { NitroMapButton } from '../utils/NitroMapButton';
|
|
13
|
+
import { NitroOptionsPanelUtil } from '../utils/NitroOptionsPanel';
|
|
13
14
|
import { Template, } from './Template';
|
|
14
15
|
const HybridMapTemplate = NitroModules.createHybridObject('MapTemplate');
|
|
15
16
|
export class MapTemplate extends Template {
|
|
@@ -17,7 +18,7 @@ export class MapTemplate extends Template {
|
|
|
17
18
|
template = this;
|
|
18
19
|
constructor(config) {
|
|
19
20
|
super(config);
|
|
20
|
-
const { component, mapButtons, headerActions, onStopNavigation, onAutoDriveEnabled, defaultGuidanceBackgroundColor, ...baseConfig } = config;
|
|
21
|
+
const { component, mapButtons, headerActions, onStopNavigation, onAutoDriveEnabled, defaultGuidanceBackgroundColor, optionsPanel, ...baseConfig } = config;
|
|
21
22
|
AppRegistry.registerComponent(this.id, () => (props) => React.createElement(MapTemplateProvider, {
|
|
22
23
|
mapTemplate: this.template,
|
|
23
24
|
// biome-ignore lint/correctness/noChildrenProp: there is no other way in a ts file
|
|
@@ -43,6 +44,19 @@ export class MapTemplate extends Template {
|
|
|
43
44
|
: undefined,
|
|
44
45
|
};
|
|
45
46
|
HybridMapTemplate.createMapTemplate(nitroConfig);
|
|
47
|
+
// routed through updateOptionsPanel, not embedded in nitroConfig above — nitrogen can't generate
|
|
48
|
+
// a spec for a variant type nested that deep inside NitroMapTemplateConfig.
|
|
49
|
+
this.updateOptionsPanel(optionsPanel);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @namespace iOS updates the panel shown when tapping the ellipsis button
|
|
53
|
+
* next to the travel estimates during navigation (iOS 27+).
|
|
54
|
+
*/
|
|
55
|
+
updateOptionsPanel(optionsPanel) {
|
|
56
|
+
if (Platform.OS !== 'ios') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
return HybridMapTemplate.updateOptionsPanel(this.id, NitroOptionsPanelUtil.convert(this.template, optionsPanel));
|
|
46
60
|
}
|
|
47
61
|
setMapButtons(mapButtons) {
|
|
48
62
|
const buttons = NitroMapButton.convert(this.template, mapButtons);
|
|
@@ -130,7 +144,7 @@ export class MapTemplate extends Template {
|
|
|
130
144
|
* or use this to start a navigation session without asking the user
|
|
131
145
|
*/
|
|
132
146
|
startNavigation(trip) {
|
|
133
|
-
HybridMapTemplate.startNavigation(this.id, trip);
|
|
147
|
+
return HybridMapTemplate.startNavigation(this.id, trip);
|
|
134
148
|
}
|
|
135
149
|
stopNavigation() {
|
|
136
150
|
HybridMapTemplate.stopNavigation(this.id);
|