@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.
Files changed (122) hide show
  1. package/README.md +214 -29
  2. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/AndroidAutoSession.kt +5 -0
  3. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplate.kt +9 -2
  4. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/NativeBackdrop.kt +40 -0
  5. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/VirtualRenderer.kt +52 -0
  6. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/GridTemplate.kt +47 -13
  7. package/android/src/main/java/com/margelo/nitro/swe/iternio/reactnativeautoplay/template/Parser.kt +21 -2
  8. package/ios/Types.swift +3 -0
  9. package/ios/extensions/UIImage+Toggle.swift +5 -2
  10. package/ios/hybrid/HybridAutoPlay.swift +28 -16
  11. package/ios/hybrid/HybridMapTemplate.swift +22 -5
  12. package/ios/scenes/AutoPlayInterfaceController.swift +261 -72
  13. package/ios/templates/AutoPlayMapPanelDelegate.swift +190 -0
  14. package/ios/templates/AutoPlayTemplate.swift +24 -2
  15. package/ios/templates/GridTemplate.swift +57 -57
  16. package/ios/templates/InformationTemplate.swift +84 -9
  17. package/ios/templates/ListTemplate.swift +66 -11
  18. package/ios/templates/MapTemplate.swift +83 -68
  19. package/ios/templates/MessageTemplate.swift +72 -6
  20. package/ios/templates/Parser.swift +564 -69
  21. package/ios/templates/SearchTemplate.swift +1 -1
  22. package/ios/templates/TemplateStore.swift +5 -15
  23. package/ios/utils/SymbolFont.swift +13 -28
  24. package/lib/Constants.d.ts +4 -0
  25. package/lib/Constants.js +6 -0
  26. package/lib/index.d.ts +1 -0
  27. package/lib/index.js +1 -0
  28. package/lib/specs/MapTemplate.nitro.d.ts +3 -1
  29. package/lib/templates/GridTemplate.d.ts +23 -3
  30. package/lib/templates/GridTemplate.js +8 -0
  31. package/lib/templates/InformationTemplate.d.ts +38 -12
  32. package/lib/templates/ListTemplate.d.ts +16 -47
  33. package/lib/templates/MapTemplate.d.ts +26 -2
  34. package/lib/templates/MapTemplate.js +16 -2
  35. package/lib/templates/MessageTemplate.d.ts +52 -11
  36. package/lib/templates/MessageTemplate.js +1 -1
  37. package/lib/utils/NitroOptionsPanel.d.ts +103 -0
  38. package/lib/utils/NitroOptionsPanel.js +63 -0
  39. package/lib/utils/NitroSection.d.ts +89 -2
  40. package/lib/utils/NitroSection.js +49 -2
  41. package/nitrogen/generated/android/ReactNativeAutoPlay+autolinking.cmake +1 -0
  42. package/nitrogen/generated/android/c++/JChargingConnector.hpp +79 -0
  43. package/nitrogen/generated/android/c++/JGridImageSize.hpp +64 -0
  44. package/nitrogen/generated/android/c++/JGridTemplateConfig.hpp +7 -1
  45. package/nitrogen/generated/android/c++/JHybridGridTemplateSpec.cpp +4 -0
  46. package/nitrogen/generated/android/c++/JHybridInformationTemplateSpec.cpp +12 -0
  47. package/nitrogen/generated/android/c++/JHybridListTemplateSpec.cpp +12 -0
  48. package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp +78 -3
  49. package/nitrogen/generated/android/c++/JHybridMapTemplateSpec.hpp +2 -1
  50. package/nitrogen/generated/android/c++/JHybridSearchTemplateSpec.cpp +12 -0
  51. package/nitrogen/generated/android/c++/JInformationTemplateConfig.hpp +6 -0
  52. package/nitrogen/generated/android/c++/JListImageType.hpp +67 -0
  53. package/nitrogen/generated/android/c++/JListTemplateConfig.hpp +6 -0
  54. package/nitrogen/generated/android/c++/JNitroChargerLocation.hpp +115 -0
  55. package/nitrogen/generated/android/c++/JNitroChargerOutlet.hpp +82 -0
  56. package/nitrogen/generated/android/c++/JNitroOptionsPanelChargerSection.hpp +112 -0
  57. package/nitrogen/generated/android/c++/JNitroOptionsPanelConfig.hpp +157 -0
  58. package/nitrogen/generated/android/c++/JNitroOptionsPanelGridSection.hpp +102 -0
  59. package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.cpp +30 -0
  60. package/nitrogen/generated/android/c++/JNitroOptionsPanelSection.hpp +129 -0
  61. package/nitrogen/generated/android/c++/JNitroRow.hpp +33 -3
  62. package/nitrogen/generated/android/c++/JNitroSection.hpp +6 -0
  63. package/nitrogen/generated/android/c++/JSearchTemplateConfig.hpp +6 -0
  64. package/nitrogen/generated/android/c++/JWaypointCoordinate.hpp +65 -0
  65. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ChargingConnector.kt +30 -0
  66. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridImageSize.kt +25 -0
  67. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/GridTemplateConfig.kt +9 -4
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/HybridMapTemplateSpec.kt +5 -1
  69. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/ListImageType.kt +26 -0
  70. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerLocation.kt +90 -0
  71. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroChargerOutlet.kt +70 -0
  72. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelChargerSection.kt +61 -0
  73. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelConfig.kt +61 -0
  74. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelGridSection.kt +56 -0
  75. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroOptionsPanelSection.kt +75 -0
  76. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/NitroRow.kt +36 -6
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/swe/iternio/reactnativeautoplay/WaypointCoordinate.kt +61 -0
  78. package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Bridge.hpp +174 -0
  79. package/nitrogen/generated/ios/ReactNativeAutoPlay-Swift-Cxx-Umbrella.hpp +27 -0
  80. package/nitrogen/generated/ios/c++/HybridGridTemplateSpecSwift.hpp +3 -0
  81. package/nitrogen/generated/ios/c++/HybridInformationTemplateSpecSwift.hpp +9 -0
  82. package/nitrogen/generated/ios/c++/HybridListTemplateSpecSwift.hpp +9 -0
  83. package/nitrogen/generated/ios/c++/HybridMapTemplateSpecSwift.hpp +47 -1
  84. package/nitrogen/generated/ios/c++/HybridSearchTemplateSpecSwift.hpp +9 -0
  85. package/nitrogen/generated/ios/swift/ChargingConnector.swift +68 -0
  86. package/nitrogen/generated/ios/swift/GridImageSize.swift +48 -0
  87. package/nitrogen/generated/ios/swift/GridTemplateConfig.swift +12 -1
  88. package/nitrogen/generated/ios/swift/HybridMapTemplateSpec.swift +2 -1
  89. package/nitrogen/generated/ios/swift/HybridMapTemplateSpec_cxx.swift +31 -4
  90. package/nitrogen/generated/ios/swift/ListImageType.swift +52 -0
  91. package/nitrogen/generated/ios/swift/NitroChargerLocation.swift +161 -0
  92. package/nitrogen/generated/ios/swift/NitroChargerOutlet.swift +65 -0
  93. package/nitrogen/generated/ios/swift/NitroOptionsPanelChargerSection.swift +64 -0
  94. package/nitrogen/generated/ios/swift/NitroOptionsPanelConfig.swift +94 -0
  95. package/nitrogen/generated/ios/swift/NitroOptionsPanelGridSection.swift +53 -0
  96. package/nitrogen/generated/ios/swift/NitroOptionsPanelSection.swift +32 -0
  97. package/nitrogen/generated/ios/swift/NitroRow.swift +81 -1
  98. package/nitrogen/generated/ios/swift/WaypointCoordinate.swift +52 -0
  99. package/nitrogen/generated/shared/c++/ChargingConnector.hpp +104 -0
  100. package/nitrogen/generated/shared/c++/GridImageSize.hpp +84 -0
  101. package/nitrogen/generated/shared/c++/GridTemplateConfig.hpp +8 -1
  102. package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.cpp +1 -0
  103. package/nitrogen/generated/shared/c++/HybridMapTemplateSpec.hpp +5 -1
  104. package/nitrogen/generated/shared/c++/ListImageType.hpp +88 -0
  105. package/nitrogen/generated/shared/c++/NitroChargerLocation.hpp +131 -0
  106. package/nitrogen/generated/shared/c++/NitroChargerOutlet.hpp +98 -0
  107. package/nitrogen/generated/shared/c++/NitroOptionsPanelChargerSection.hpp +98 -0
  108. package/nitrogen/generated/shared/c++/NitroOptionsPanelConfig.hpp +107 -0
  109. package/nitrogen/generated/shared/c++/NitroOptionsPanelGridSection.hpp +91 -0
  110. package/nitrogen/generated/shared/c++/NitroRow.hpp +39 -2
  111. package/nitrogen/generated/shared/c++/WaypointCoordinate.hpp +91 -0
  112. package/package.json +1 -1
  113. package/src/Constants.ts +9 -0
  114. package/src/index.ts +1 -0
  115. package/src/specs/MapTemplate.nitro.ts +3 -1
  116. package/src/templates/GridTemplate.ts +38 -3
  117. package/src/templates/InformationTemplate.ts +60 -29
  118. package/src/templates/ListTemplate.ts +27 -55
  119. package/src/templates/MapTemplate.ts +60 -2
  120. package/src/templates/MessageTemplate.ts +71 -24
  121. package/src/utils/NitroOptionsPanel.ts +218 -0
  122. package/src/utils/NitroSection.ts +160 -5
@@ -1,12 +1,14 @@
1
- import type { AutoImage, BaseMapTemplateConfig, CustomActionButtonAndroid, HeaderActionsAndroid, TextButton } from '..';
1
+ import type { AutoImage, BaseMapTemplateConfig, CustomActionButtonAndroid, HeaderActions, TextButton } from '..';
2
2
  import type { AutoText } from '../types/Text';
3
3
  import { type NitroAction } from '../utils/NitroAction';
4
4
  import { type NitroImage } from '../utils/NitroImage';
5
+ import type { PanelActionsIos, PanelHeaderActions } from './MapTemplate';
5
6
  import type { NitroBaseMapTemplateConfig, TemplateConfig } from './Template';
6
7
  export interface NitroMessageTemplateConfig extends TemplateConfig {
7
8
  headerActions?: Array<NitroAction>;
8
9
  /**
9
10
  * @namespace Android title shown on header
11
+ * @namespace iOS title shown when mapConfig is set, otherwise it isn't supported
10
12
  */
11
13
  title?: AutoText;
12
14
  message: AutoText;
@@ -14,31 +16,69 @@ export interface NitroMessageTemplateConfig extends TemplateConfig {
14
16
  image?: NitroImage;
15
17
  mapConfig?: NitroBaseMapTemplateConfig;
16
18
  }
17
- export type MessageTemplateConfig = Omit<NitroMessageTemplateConfig, 'headerActions' | 'image' | 'mapConfig' | 'actions'> & {
19
+ type MessageActionsAndroid<T> = [CustomActionButtonAndroid<T>] | [CustomActionButtonAndroid<T>, CustomActionButtonAndroid<T>];
20
+ type MessageTemplateBaseConfig = Omit<NitroMessageTemplateConfig, 'headerActions' | 'image' | 'mapConfig' | 'actions'> & {
18
21
  /**
19
22
  * action buttons, usually at the top right on Android
20
- * @namespace Android
23
+ * @namespace iOS `ios` only takes effect once this renders as a CPMapPanel (`mapConfig` set,
24
+ * iOS 27+) and is applied to the root map template's nav bar — without `mapConfig` (or below
25
+ * iOS 27, where `mapConfig` is a no-op) this template is a full-screen `CPAlertTemplate`, which
26
+ * has no nav bar at all, so `ios` is silently unused there.
21
27
  */
22
- headerActions?: HeaderActionsAndroid<MessageTemplate>;
28
+ headerActions?: HeaderActions<MessageTemplate>;
23
29
  /**
24
30
  * image shown at the top of the message on Android
25
31
  * @namespace Android
26
32
  */
27
33
  image?: AutoImage;
34
+ };
35
+ /**
36
+ * `actions`/`mapConfig` are a discriminated union — `mapConfig` restricts `actions.ios` to at
37
+ * most one `TextButton` plus one icon-only `ImageButton` (a `CPMapPanel` can't show more), vs. up
38
+ * to three `TextButton`s otherwise. If your `mapConfig` value comes from a variable/prop rather
39
+ * than an inline literal, TS can't narrow which branch applies — assign it to a local `const` and
40
+ * branch with `if (mapConfig) { ... } else { ... }` into two separate constructor calls instead
41
+ * of passing it straight through to one.
42
+ */
43
+ export type MessageTemplateConfig = MessageTemplateBaseConfig & ({
44
+ mapConfig?: undefined;
28
45
  /**
29
- * If mapConfig is defined, it will use a MapWithContentTemplate with the current template. This results in a MessageTemplate with a map in background. No actions need to be specified, can be empty object.
30
- * @namespace Android
46
+ * @namespace Android up to 2 buttons of type TextButton, TextAndImageButton or ImageButton
47
+ * @namespace iOS - up to 3 buttons of type TextButton
31
48
  */
32
- mapConfig?: BaseMapTemplateConfig<MessageTemplate>;
49
+ actions?: {
50
+ android?: MessageActionsAndroid<MessageTemplate>;
51
+ ios?: [
52
+ TextButton<MessageTemplate>,
53
+ TextButton<MessageTemplate>,
54
+ TextButton<MessageTemplate>
55
+ ] | [TextButton<MessageTemplate>, TextButton<MessageTemplate>] | [TextButton<MessageTemplate>];
56
+ };
57
+ } | {
58
+ /**
59
+ * If mapConfig is defined, it will use a MapWithContentTemplate with the current
60
+ * template. This results in a MessageTemplate with a map in background. No actions
61
+ * need to be specified, can be empty object.
62
+ * @namespace Android - uses MapWithContentTemplate
63
+ * @namespace iOS - renders as a CPMapPanel on the current root map template (iOS 27+),
64
+ * trading the usual full-screen modal alert presentation for panel content;
65
+ * `headerActions` here is Android-only — on iOS this template's own `headerActions` are
66
+ * applied to the root map template's nav bar instead, since CarPlay has no separate
67
+ * header for the map behind a panel.
68
+ */
69
+ mapConfig: Omit<BaseMapTemplateConfig<MessageTemplate>, 'headerActions'> & {
70
+ headerActions?: PanelHeaderActions<MessageTemplate>;
71
+ };
33
72
  /**
34
73
  * @namespace Android up to 2 buttons of type TextButton, TextAndImageButton or ImageButton
35
- * @namespace iOS - up to 3 buttons of type TextButton
74
+ * @namespace iOS - the panel can only show one TextButton plus one optional icon-only
75
+ * ImageButton, see PanelActionsIos
36
76
  */
37
77
  actions?: {
38
- android?: [CustomActionButtonAndroid<MessageTemplate>] | [CustomActionButtonAndroid<MessageTemplate>, CustomActionButtonAndroid<MessageTemplate>];
39
- ios?: [TextButton<MessageTemplate>, TextButton<MessageTemplate>, TextButton<MessageTemplate>] | [TextButton<MessageTemplate>, TextButton<MessageTemplate>] | [TextButton<MessageTemplate>];
78
+ android?: MessageActionsAndroid<MessageTemplate>;
79
+ ios?: PanelActionsIos<MessageTemplate>;
40
80
  };
41
- };
81
+ });
42
82
  /**
43
83
  * This template is always pushed on top and will stay on top until it is popped.
44
84
  * Other templates being pushed will end up below this one on the stack.
@@ -53,3 +93,4 @@ export declare class MessageTemplate {
53
93
  */
54
94
  push(): Promise<void>;
55
95
  }
96
+ export {};
@@ -22,7 +22,7 @@ export class MessageTemplate {
22
22
  const nitroConfig = {
23
23
  ...rest,
24
24
  id: this.id,
25
- headerActions: NitroActionUtil.convert(this.template, { android: headerActions }),
25
+ headerActions: NitroActionUtil.convert(this.template, headerActions),
26
26
  image: NitroImageUtil.convert(image),
27
27
  actions: platformActions,
28
28
  mapConfig: mapConfig
@@ -0,0 +1,103 @@
1
+ import type { ImageButton, TextButton } from '../types/Button';
2
+ import type { AutoImage } from '../types/Image';
3
+ import type { AutoText, Distance } from '../types/Text';
4
+ import type { DurationWithTimeZone } from '../types/Trip';
5
+ import { type NitroAction } from './NitroAction';
6
+ import { type GridButton, type NitroGridButton } from './NitroGrid';
7
+ import { type NitroImage } from './NitroImage';
8
+ import { type DefaultRow, type NitroSection, type RadioRow, type TextRow, type ToggleRow, type WaypointCoordinate, type WaypointRow } from './NitroSection';
9
+ export type OptionsPanelGridSection<T> = {
10
+ type: 'grid';
11
+ title?: string;
12
+ buttons: Array<GridButton<T>>;
13
+ };
14
+ export type ChargingConnector = 'ccs1' | 'ccs2' | 'j1772' | 'chaDeMo' | 'mennekes' | 'gbtDC' | 'gbtAC' | 'nacsDC' | 'nacsAC';
15
+ /**
16
+ * one outlet (`CPChargingStationConnection`) on a charging station.
17
+ */
18
+ export type ChargerOutlet<T> = {
19
+ connector: ChargingConnector;
20
+ voltage: number;
21
+ /** converted to megawatts on the native side above 1000 kW */
22
+ powerKw: number;
23
+ onPress?: (template: T) => void;
24
+ };
25
+ /**
26
+ * the charging station's own location, shown as an additional `CPMapTemplateWaypoint` item in
27
+ * the charger section, alongside its outlets.
28
+ */
29
+ export type ChargerLocation<T> = {
30
+ /**
31
+ * the item's own label — distinct from the section's `title`, which is already shown as the
32
+ * section header, so this defaults to blank rather than repeating it.
33
+ */
34
+ name?: string;
35
+ /** newline-separated address lines, most-preferred first */
36
+ address?: string;
37
+ coordinate: WaypointCoordinate;
38
+ travelEstimates: {
39
+ distance: Distance;
40
+ duration: DurationWithTimeZone;
41
+ /**
42
+ * by default travel estimates are not shown
43
+ * setting this to true add another row showing CPTravelEstimates
44
+ */
45
+ visible?: boolean;
46
+ };
47
+ image?: AutoImage;
48
+ onPress?: (template: T) => void;
49
+ };
50
+ /**
51
+ * charger section having n-ChargerOutlet
52
+ */
53
+ export type OptionsPanelChargerSection<T> = {
54
+ type: 'charger';
55
+ title?: string;
56
+ outlets: Array<ChargerOutlet<T>>;
57
+ location?: ChargerLocation<T>;
58
+ };
59
+ export type OptionsPanelListSection<T> = {
60
+ type: 'list';
61
+ title?: string;
62
+ items: Array<DefaultRow<T> | ToggleRow<T> | TextRow | WaypointRow<T>> | Array<RadioRow<T>>;
63
+ };
64
+ export type OptionsPanelSection<T> = OptionsPanelListSection<T> | OptionsPanelGridSection<T> | OptionsPanelChargerSection<T>;
65
+ export type OptionsPanelConfig<T> = {
66
+ title?: AutoText;
67
+ sections: Array<OptionsPanelSection<T>>;
68
+ actions?: [TextButton<T>] | [TextButton<T>, ImageButton<T>];
69
+ };
70
+ export type NitroOptionsPanelGridSection = {
71
+ title?: string;
72
+ buttons: Array<NitroGridButton>;
73
+ };
74
+ export type NitroChargerOutlet = {
75
+ connector: ChargingConnector;
76
+ voltage: number;
77
+ powerKw: number;
78
+ onPress?: () => void;
79
+ };
80
+ export type NitroChargerLocation = {
81
+ name?: string;
82
+ address?: string;
83
+ coordinate: WaypointCoordinate;
84
+ distance: Distance;
85
+ duration: DurationWithTimeZone;
86
+ visible?: boolean;
87
+ image?: NitroImage;
88
+ onPress?: () => void;
89
+ };
90
+ export type NitroOptionsPanelChargerSection = {
91
+ title?: string;
92
+ outlets: Array<NitroChargerOutlet>;
93
+ location?: NitroChargerLocation;
94
+ };
95
+ export type NitroOptionsPanelSection = NitroSection | NitroOptionsPanelGridSection | NitroOptionsPanelChargerSection;
96
+ export type NitroOptionsPanelConfig = {
97
+ title?: AutoText;
98
+ sections: Array<NitroOptionsPanelSection>;
99
+ actions?: Array<NitroAction>;
100
+ };
101
+ export declare const NitroOptionsPanelUtil: {
102
+ convert: <T>(template: T, config?: OptionsPanelConfig<T>) => NitroOptionsPanelConfig | undefined;
103
+ };
@@ -0,0 +1,63 @@
1
+ import { NitroActionUtil } from './NitroAction';
2
+ import { NitroGridUtil } from './NitroGrid';
3
+ import { NitroImageUtil } from './NitroImage';
4
+ import { NitroSectionUtil, } from './NitroSection';
5
+ const isRadioSection = (items) => {
6
+ return items.length > 0 && items.every((item) => item.type === 'radio');
7
+ };
8
+ const convertSection = (template, section) => {
9
+ if (section.type === 'grid') {
10
+ return {
11
+ title: section.title,
12
+ buttons: NitroGridUtil.convert(template, section.buttons),
13
+ };
14
+ }
15
+ if (section.type === 'charger') {
16
+ const { location } = section;
17
+ return {
18
+ title: section.title,
19
+ outlets: section.outlets.map((outlet) => ({
20
+ connector: outlet.connector,
21
+ voltage: outlet.voltage,
22
+ powerKw: outlet.powerKw,
23
+ onPress: outlet.onPress ? () => outlet.onPress?.(template) : undefined,
24
+ })),
25
+ location: location
26
+ ? {
27
+ name: location.name,
28
+ address: location.address,
29
+ coordinate: location.coordinate,
30
+ distance: location.travelEstimates.distance,
31
+ duration: location.travelEstimates.duration,
32
+ visible: location.travelEstimates.visible,
33
+ image: NitroImageUtil.convert(location.image),
34
+ onPress: location.onPress ? () => location.onPress?.(template) : undefined,
35
+ }
36
+ : undefined,
37
+ };
38
+ }
39
+ const { items, title = '' } = section;
40
+ const multiSection = isRadioSection(items)
41
+ ? { type: 'radio', title, items }
42
+ : {
43
+ type: 'default',
44
+ title,
45
+ items,
46
+ };
47
+ const [nitroSection] = NitroSectionUtil.convert(template, [multiSection]) ?? [];
48
+ if (nitroSection == null) {
49
+ throw new Error('converting sections failed');
50
+ }
51
+ return nitroSection;
52
+ };
53
+ const convert = (template, config) => {
54
+ if (config == null) {
55
+ return undefined;
56
+ }
57
+ return {
58
+ title: config.title,
59
+ sections: config.sections.map((section) => convertSection(template, section)),
60
+ actions: NitroActionUtil.convert(template, config.actions),
61
+ };
62
+ };
63
+ export const NitroOptionsPanelUtil = { convert };
@@ -1,6 +1,82 @@
1
- import type { Section } from '../templates/ListTemplate';
2
- import type { AutoText } from '../types/Text';
1
+ import type { ListImageType } from '../templates/ListTemplate';
2
+ import type { AutoImage } from '../types/Image';
3
+ import { type AutoText, type Distance } from '../types/Text';
4
+ import type { DurationWithTimeZone } from '../types/Trip';
3
5
  import { type NitroImage } from './NitroImage';
6
+ type BaseRow = {
7
+ title: AutoText;
8
+ enabled?: boolean;
9
+ image?: AutoImage;
10
+ /** @namespace Android */
11
+ imageType?: ListImageType;
12
+ };
13
+ export type DefaultRow<T> = BaseRow & {
14
+ type: 'default';
15
+ /**
16
+ * adds a chevron at the end of the row
17
+ */
18
+ browsable?: boolean;
19
+ onPress: (template: T) => void;
20
+ detailedText?: AutoText;
21
+ };
22
+ export type ToggleRow<T> = BaseRow & {
23
+ type: 'toggle';
24
+ checked: boolean;
25
+ onPress: (template: T, checked: boolean) => void;
26
+ };
27
+ export type RadioRow<T> = BaseRow & {
28
+ type: 'radio';
29
+ onPress: (template: T) => void;
30
+ selected?: boolean;
31
+ };
32
+ export type TextRow = BaseRow & {
33
+ type: 'text';
34
+ detailedText?: AutoText;
35
+ };
36
+ export type WaypointCoordinate = {
37
+ latitude: number;
38
+ longitude: number;
39
+ altitude?: number;
40
+ };
41
+ /**
42
+ * a point of interest, e.g. a charger's location. Renders as a `CPMapTemplateWaypoint` item
43
+ * (showing `title` as the name, `address` as the address, and the travel estimate for reaching
44
+ * it) when part of a `CPMapPanel` (iOS 27+); falls back to a plain row using `title`/`address`
45
+ * as the detail line everywhere else (including Android, which has no equivalent concept).
46
+ */
47
+ export type WaypointRow<T> = BaseRow & {
48
+ type: 'waypoint';
49
+ /**
50
+ * add one of {@link TextPlaceholders} to add travelEstimates
51
+ * prefer travelEstimates.visible over that on iOS 27+
52
+ */
53
+ address?: string;
54
+ coordinate: WaypointCoordinate;
55
+ travelEstimates: {
56
+ distance: Distance;
57
+ duration: DurationWithTimeZone;
58
+ /**
59
+ * by default travel estimates are not shown
60
+ * setting this to true adds another row showing CPTravelEstimates
61
+ * @namespace iOS 27+
62
+ */
63
+ visible?: boolean;
64
+ };
65
+ onPress?: (template: T) => void;
66
+ };
67
+ export type MultiSection<T> = {
68
+ type: 'default';
69
+ title: string;
70
+ items: Array<DefaultRow<T> | ToggleRow<T> | TextRow | WaypointRow<T>>;
71
+ } | {
72
+ type: 'radio';
73
+ title: string;
74
+ items: Array<RadioRow<T>>;
75
+ };
76
+ export type SingleSection<T> = {
77
+ [K in MultiSection<T> as K['type']]: Omit<K, 'title' | 'detailedText'>;
78
+ }[MultiSection<T>['type']];
79
+ export type Section<T> = Array<MultiSection<T>> | SingleSection<T>;
4
80
  type NitroSectionType = 'default' | 'radio';
5
81
  export type NitroRow = {
6
82
  title: AutoText;
@@ -8,9 +84,20 @@ export type NitroRow = {
8
84
  browsable?: boolean;
9
85
  enabled: boolean;
10
86
  image?: NitroImage;
87
+ imageType?: ListImageType;
11
88
  checked?: boolean;
12
89
  onPress?: (checked?: boolean) => void;
13
90
  selected?: boolean;
91
+ coordinate?: WaypointCoordinate;
92
+ distance?: Distance;
93
+ duration?: DurationWithTimeZone;
94
+ /**
95
+ * only meaningful in panel context (iOS 27+, `mapConfig` set) — adds a sibling `CPMapPanelItem`
96
+ * showing `distance`/`duration` as a native `CPTravelEstimates` row. Non-panel/Android rendering
97
+ * relies purely on `title`/`detailedText` opting in via `TextPlaceholders` instead.
98
+ */
99
+ travelEstimatesVisible?: boolean;
100
+ address?: string;
14
101
  };
15
102
  export type NitroSection = {
16
103
  title?: string;
@@ -1,3 +1,4 @@
1
+ import { TextPlaceholders } from '../types/Text';
1
2
  import { NitroImageUtil } from './NitroImage';
2
3
  const validateRadioItems = (type, items) => {
3
4
  if (__DEV__ &&
@@ -31,9 +32,49 @@ const convert = (template, sections) => {
31
32
  },
32
33
  ];
33
34
  };
35
+ /**
36
+ * `AutoText.distance`/`.duration` only take effect if `text` actually uses the matching
37
+ * `TextPlaceholders` marker — populate whichever of those the text references, leaving the rest
38
+ * of `text` untouched, so a title/address that doesn't opt in via a placeholder is unaffected.
39
+ */
40
+ const withTravelEstimates = (text, distance, durationSeconds) => {
41
+ const hasDistance = text.text.includes(TextPlaceholders.Distance);
42
+ const hasDuration = text.text.includes(TextPlaceholders.Duration);
43
+ if (!hasDistance && !hasDuration) {
44
+ return text;
45
+ }
46
+ return {
47
+ ...text,
48
+ distance: hasDistance ? distance : text.distance,
49
+ duration: hasDuration ? durationSeconds : text.duration,
50
+ };
51
+ };
34
52
  const convertRow = (template, item) => {
35
- const { title, type, enabled = true, image } = item;
36
- const detailedText = 'detailedText' in item ? item.detailedText : undefined;
53
+ const { type, enabled = true, image, imageType } = item;
54
+ // `WaypointRow` has no `detailedText` of its own — `address` doubles as the detail line
55
+ // whenever this falls back to a plain row (non-panel context, Android).
56
+ let title = item.title;
57
+ let detailedText = item.type === 'waypoint'
58
+ ? item.address != null
59
+ ? { text: item.address }
60
+ : undefined
61
+ : 'detailedText' in item
62
+ ? item.detailedText
63
+ : undefined;
64
+ // Opt-in only: a title/address using `{distance}`/`{duration}` gets those values filled in,
65
+ // via the same substitution `AutoText` already does everywhere else — no separate "estimate"
66
+ // UI element needed for a row embedded in a list alongside other rows. Deliberately NOT gated
67
+ // on `travelEstimates.visible` — that flag only controls the panel-only sibling
68
+ // `CPTravelEstimates` item (see `Parser.swift`'s `travelEstimatesVisible` check), which has no
69
+ // bearing on the non-panel/Android fallback text this feeds; a placeholder in the text is
70
+ // already its own explicit opt-in regardless of `visible`.
71
+ if (item.type === 'waypoint') {
72
+ const { distance, duration } = item.travelEstimates;
73
+ title = withTravelEstimates(title, distance, duration.seconds);
74
+ if (detailedText != null) {
75
+ detailedText = withTravelEstimates(detailedText, distance, duration.seconds);
76
+ }
77
+ }
37
78
  const selected = type === 'radio' ? (item.selected ?? false) : undefined;
38
79
  const onTogglePress = item.type === 'toggle' ? item.onPress : undefined;
39
80
  const onRowPress = item.type !== 'text' && item.type !== 'toggle' ? item.onPress : undefined;
@@ -53,10 +94,16 @@ const convertRow = (template, item) => {
53
94
  detailedText,
54
95
  enabled,
55
96
  image: NitroImageUtil.convert(image),
97
+ imageType,
56
98
  title,
57
99
  checked: type === 'toggle' ? item.checked : undefined,
58
100
  onPress,
59
101
  selected,
102
+ coordinate: item.type === 'waypoint' ? item.coordinate : undefined,
103
+ distance: item.type === 'waypoint' ? item.travelEstimates.distance : undefined,
104
+ duration: item.type === 'waypoint' ? item.travelEstimates.duration : undefined,
105
+ travelEstimatesVisible: item.type === 'waypoint' ? item.travelEstimates.visible : undefined,
106
+ address: item.type === 'waypoint' ? item.address : undefined,
60
107
  };
61
108
  };
62
109
  export const NitroSectionUtil = { convert };
@@ -61,6 +61,7 @@ target_sources(
61
61
  ../nitrogen/generated/android/c++/JHybridMapTemplateSpec.cpp
62
62
  ../nitrogen/generated/android/c++/JNitroManeuver.cpp
63
63
  ../nitrogen/generated/android/c++/JVariant_PreferredImageLane_ImageLane.cpp
64
+ ../nitrogen/generated/android/c++/JNitroOptionsPanelSection.cpp
64
65
  ../nitrogen/generated/android/c++/JHybridMessageTemplateSpec.cpp
65
66
  ../nitrogen/generated/android/c++/JHybridSearchTemplateSpec.cpp
66
67
  ../nitrogen/generated/android/c++/JHybridSignInTemplateSpec.cpp
@@ -0,0 +1,79 @@
1
+ ///
2
+ /// JChargingConnector.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 "ChargingConnector.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 "ChargingConnector" and the the Kotlin enum "ChargingConnector".
19
+ */
20
+ struct JChargingConnector final: public jni::JavaClass<JChargingConnector> {
21
+ public:
22
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/swe/iternio/reactnativeautoplay/ChargingConnector;";
23
+
24
+ public:
25
+ /**
26
+ * Convert this Java/Kotlin-based enum to the C++ enum ChargingConnector.
27
+ */
28
+ [[maybe_unused]]
29
+ [[nodiscard]]
30
+ ChargingConnector 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<ChargingConnector>(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<JChargingConnector> fromCpp(ChargingConnector value) {
43
+ static const auto clazz = javaClassStatic();
44
+ switch (value) {
45
+ case ChargingConnector::CCS1:
46
+ static const auto fieldCCS1 = clazz->getStaticField<JChargingConnector>("CCS1");
47
+ return clazz->getStaticFieldValue(fieldCCS1);
48
+ case ChargingConnector::CCS2:
49
+ static const auto fieldCCS2 = clazz->getStaticField<JChargingConnector>("CCS2");
50
+ return clazz->getStaticFieldValue(fieldCCS2);
51
+ case ChargingConnector::J1772:
52
+ static const auto fieldJ1772 = clazz->getStaticField<JChargingConnector>("J1772");
53
+ return clazz->getStaticFieldValue(fieldJ1772);
54
+ case ChargingConnector::CHADEMO:
55
+ static const auto fieldCHADEMO = clazz->getStaticField<JChargingConnector>("CHADEMO");
56
+ return clazz->getStaticFieldValue(fieldCHADEMO);
57
+ case ChargingConnector::MENNEKES:
58
+ static const auto fieldMENNEKES = clazz->getStaticField<JChargingConnector>("MENNEKES");
59
+ return clazz->getStaticFieldValue(fieldMENNEKES);
60
+ case ChargingConnector::GBTDC:
61
+ static const auto fieldGBTDC = clazz->getStaticField<JChargingConnector>("GBTDC");
62
+ return clazz->getStaticFieldValue(fieldGBTDC);
63
+ case ChargingConnector::GBTAC:
64
+ static const auto fieldGBTAC = clazz->getStaticField<JChargingConnector>("GBTAC");
65
+ return clazz->getStaticFieldValue(fieldGBTAC);
66
+ case ChargingConnector::NACSDC:
67
+ static const auto fieldNACSDC = clazz->getStaticField<JChargingConnector>("NACSDC");
68
+ return clazz->getStaticFieldValue(fieldNACSDC);
69
+ case ChargingConnector::NACSAC:
70
+ static const auto fieldNACSAC = clazz->getStaticField<JChargingConnector>("NACSAC");
71
+ return clazz->getStaticFieldValue(fieldNACSAC);
72
+ default:
73
+ std::string stringValue = std::to_string(static_cast<int>(value));
74
+ throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
75
+ }
76
+ }
77
+ };
78
+
79
+ } // namespace margelo::nitro::swe::iternio::reactnativeautoplay
@@ -0,0 +1,64 @@
1
+ ///
2
+ /// JGridImageSize.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 "GridImageSize.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 "GridImageSize" and the the Kotlin enum "GridImageSize".
19
+ */
20
+ struct JGridImageSize final: public jni::JavaClass<JGridImageSize> {
21
+ public:
22
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/swe/iternio/reactnativeautoplay/GridImageSize;";
23
+
24
+ public:
25
+ /**
26
+ * Convert this Java/Kotlin-based enum to the C++ enum GridImageSize.
27
+ */
28
+ [[maybe_unused]]
29
+ [[nodiscard]]
30
+ GridImageSize 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<GridImageSize>(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<JGridImageSize> fromCpp(GridImageSize value) {
43
+ static const auto clazz = javaClassStatic();
44
+ switch (value) {
45
+ case GridImageSize::UNSET:
46
+ static const auto fieldUNSET = clazz->getStaticField<JGridImageSize>("UNSET");
47
+ return clazz->getStaticFieldValue(fieldUNSET);
48
+ case GridImageSize::LARGE:
49
+ static const auto fieldLARGE = clazz->getStaticField<JGridImageSize>("LARGE");
50
+ return clazz->getStaticFieldValue(fieldLARGE);
51
+ case GridImageSize::MEDIUM:
52
+ static const auto fieldMEDIUM = clazz->getStaticField<JGridImageSize>("MEDIUM");
53
+ return clazz->getStaticFieldValue(fieldMEDIUM);
54
+ case GridImageSize::SMALL:
55
+ static const auto fieldSMALL = clazz->getStaticField<JGridImageSize>("SMALL");
56
+ return clazz->getStaticFieldValue(fieldSMALL);
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
@@ -15,6 +15,7 @@
15
15
  #include "Distance.hpp"
16
16
  #include "DistanceUnits.hpp"
17
17
  #include "GlyphImage.hpp"
18
+ #include "GridImageSize.hpp"
18
19
  #include "JAssetImage.hpp"
19
20
  #include "JAutoText.hpp"
20
21
  #include "JDistance.hpp"
@@ -23,6 +24,7 @@
23
24
  #include "JFunc_void_bool.hpp"
24
25
  #include "JFunc_void_std__optional_bool_.hpp"
25
26
  #include "JGlyphImage.hpp"
27
+ #include "JGridImageSize.hpp"
26
28
  #include "JNitroAction.hpp"
27
29
  #include "JNitroActionType.hpp"
28
30
  #include "JNitroAlignment.hpp"
@@ -91,6 +93,8 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
91
93
  jni::local_ref<JAutoText> title = this->getFieldValue(fieldTitle);
92
94
  static const auto fieldButtons = clazz->getField<jni::JArrayClass<JNitroGridButton>>("buttons");
93
95
  jni::local_ref<jni::JArrayClass<JNitroGridButton>> buttons = this->getFieldValue(fieldButtons);
96
+ static const auto fieldImageSize = clazz->getField<JGridImageSize>("imageSize");
97
+ jni::local_ref<JGridImageSize> imageSize = this->getFieldValue(fieldImageSize);
94
98
  static const auto fieldMapConfig = clazz->getField<JNitroBaseMapTemplateConfig>("mapConfig");
95
99
  jni::local_ref<JNitroBaseMapTemplateConfig> mapConfig = this->getFieldValue(fieldMapConfig);
96
100
  return GridTemplateConfig(
@@ -162,6 +166,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
162
166
  }
163
167
  return __vector;
164
168
  }(buttons),
169
+ imageSize != nullptr ? std::make_optional(imageSize->toCpp()) : std::nullopt,
165
170
  mapConfig != nullptr ? std::make_optional(mapConfig->toCpp()) : std::nullopt
166
171
  );
167
172
  }
@@ -172,7 +177,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
172
177
  */
173
178
  [[maybe_unused]]
174
179
  static jni::local_ref<JGridTemplateConfig::javaobject> fromCpp(const GridTemplateConfig& value) {
175
- using JSignature = JGridTemplateConfig(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<jni::JArrayClass<JNitroAction>>, jni::alias_ref<JAutoText>, jni::alias_ref<jni::JArrayClass<JNitroGridButton>>, jni::alias_ref<JNitroBaseMapTemplateConfig>);
180
+ using JSignature = JGridTemplateConfig(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<jni::JArrayClass<JNitroAction>>, jni::alias_ref<JAutoText>, jni::alias_ref<jni::JArrayClass<JNitroGridButton>>, jni::alias_ref<JGridImageSize>, jni::alias_ref<JNitroBaseMapTemplateConfig>);
176
181
  static const auto clazz = javaClassStatic();
177
182
  static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
178
183
  return create(
@@ -205,6 +210,7 @@ namespace margelo::nitro::swe::iternio::reactnativeautoplay {
205
210
  }
206
211
  return __array;
207
212
  }(value.buttons),
213
+ value.imageSize.has_value() ? JGridImageSize::fromCpp(value.imageSize.value()) : nullptr,
208
214
  value.mapConfig.has_value() ? JNitroBaseMapTemplateConfig::fromCpp(value.mapConfig.value()) : nullptr
209
215
  );
210
216
  }