@iternio/react-native-auto-play 0.2.4 → 0.2.5-alpha

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.
@@ -147,7 +147,7 @@ class HybridAutoPlay: HybridAutoPlaySpec {
147
147
  -> NitroModules.Promise<Void>
148
148
  {
149
149
  return Promise.async {
150
- return try await RootModule.withSceneAndInterfaceController {
150
+ try await RootModule.withSceneAndInterfaceController {
151
151
  scene,
152
152
  interfaceController in
153
153
 
@@ -196,7 +196,7 @@ class HybridAutoPlay: HybridAutoPlaySpec {
196
196
 
197
197
  func popTemplate(animate: Bool?) throws -> NitroModules.Promise<Void> {
198
198
  return Promise.async {
199
- return try await RootModule.withInterfaceController {
199
+ try await RootModule.withInterfaceController {
200
200
  interfaceController in
201
201
 
202
202
  if try await interfaceController.dismissTemplate(
@@ -240,7 +240,7 @@ class HybridAutoPlay: HybridAutoPlaySpec {
240
240
  Void
241
241
  > {
242
242
  return Promise.async {
243
- return try await RootModule.withInterfaceController {
243
+ try await RootModule.withInterfaceController {
244
244
  interfaceController in
245
245
 
246
246
  let _ = try await interfaceController.dismissTemplate(
@@ -53,11 +53,12 @@ class AutoPlayScene: UIResponder {
53
53
  }
54
54
 
55
55
  func disconnect() {
56
- SceneStore.removeScene(moduleName: moduleName)
57
- isConnected = false
58
- templateStore.disconnect()
59
56
  NitroSurface.stop(self.window?.rootViewController?.view)
60
57
  self.window = nil
58
+ isConnected = false
59
+
60
+ templateStore.disconnect()
61
+ SceneStore.removeScene(moduleName: moduleName)
61
62
  }
62
63
 
63
64
  func setState(state: VisibilityState) {
@@ -16,9 +16,7 @@ class RootModule {
16
16
  moduleName: SceneStore.rootModuleName
17
17
  )
18
18
  else {
19
- throw AutoPlayError.sceneNotFound(
20
- "operation failed, \(SceneStore.rootModuleName) scene not found"
21
- )
19
+ return
22
20
  }
23
21
 
24
22
  try action(scene)
@@ -71,15 +69,13 @@ class RootModule {
71
69
  static func withScene<T>(
72
70
  perform action:
73
71
  @escaping (AutoPlayScene) async throws -> T
74
- ) async throws -> T {
72
+ ) async throws -> T? {
75
73
  guard
76
74
  let scene = SceneStore.getScene(
77
75
  moduleName: SceneStore.rootModuleName
78
76
  )
79
77
  else {
80
- throw AutoPlayError.sceneNotFound(
81
- "operation failed, \(SceneStore.rootModuleName) scene not found"
82
- )
78
+ return nil
83
79
  }
84
80
 
85
81
  return try await action(scene)
@@ -90,7 +86,7 @@ class RootModule {
90
86
  perform action:
91
87
  @escaping (AutoPlayScene, AutoPlayInterfaceController) async throws
92
88
  -> T
93
- ) async throws -> T {
89
+ ) async throws -> T? {
94
90
  return try await withScene { scene in
95
91
  guard let interfaceController = scene.interfaceController else {
96
92
  throw AutoPlayError.interfaceControllerNotFound(
@@ -106,7 +102,7 @@ class RootModule {
106
102
  static func withInterfaceController<T>(
107
103
  perform action:
108
104
  @escaping (AutoPlayInterfaceController) async throws -> T
109
- ) async throws -> T {
105
+ ) async throws -> T? {
110
106
  try await withSceneAndInterfaceController { _, interfaceController in
111
107
  try await action(interfaceController)
112
108
  }
@@ -24,6 +24,7 @@ export class GridTemplate extends Template {
24
24
  HybridGridTemplate.createGridTemplate(nitroConfig);
25
25
  }
26
26
  updateGrid(buttons) {
27
+ this.assertConnected();
27
28
  return HybridGridTemplate.updateGridTemplateButtons(this.id, NitroGridUtil.convert(this.template, buttons));
28
29
  }
29
30
  }
@@ -33,6 +33,7 @@ export class InformationTemplate extends Template {
33
33
  HybridInformationTemplate.createInformationTemplate(nitroConfig);
34
34
  }
35
35
  updateItems(items) {
36
+ this.assertConnected();
36
37
  const section = this.getSection(items);
37
38
  return HybridInformationTemplate.updateInformationTemplateSections(this.id, NitroSectionUtil.convert(this.template, section)?.at(0) ?? { items: [], type: 'default' });
38
39
  }
@@ -24,6 +24,7 @@ export class ListTemplate extends Template {
24
24
  HybridListTemplate.createListTemplate(nitroConfig);
25
25
  }
26
26
  updateSections(sections) {
27
+ this.assertConnected();
27
28
  return HybridListTemplate.updateListTemplateSections(this.id, NitroSectionUtil.convert(this.template, sections));
28
29
  }
29
30
  }
@@ -36,10 +36,12 @@ export class MapTemplate extends Template {
36
36
  HybridMapTemplate.createMapTemplate(nitroConfig);
37
37
  }
38
38
  setMapButtons(mapButtons) {
39
+ this.assertConnected();
39
40
  const buttons = NitroMapButton.convert(this.template, mapButtons);
40
41
  return HybridMapTemplate.setTemplateMapButtons(this.id, buttons);
41
42
  }
42
43
  setHeaderActions(headerActions) {
44
+ this.assertConnected();
43
45
  const nitroActions = NitroActionUtil.convert(this.template, headerActions);
44
46
  return HybridAutoPlay.setTemplateHeaderActions(this.id, nitroActions);
45
47
  }
@@ -49,12 +51,15 @@ export class MapTemplate extends Template {
49
51
  * @returns a callback to dismiss or update the navigation alert
50
52
  */
51
53
  showAlert(alert) {
54
+ this.assertConnected();
52
55
  return HybridMapTemplate.showNavigationAlert(this.id, NitroAlertUtil.convert(alert));
53
56
  }
54
57
  updateAlert(alertId, title, subtitle) {
58
+ this.assertConnected();
55
59
  HybridMapTemplate.updateNavigationAlert(this.id, alertId, title, subtitle);
56
60
  }
57
61
  dismissAlert(alertId) {
62
+ this.assertConnected();
58
63
  HybridMapTemplate.dismissNavigationAlert(this.id, alertId);
59
64
  }
60
65
  /**
@@ -63,6 +68,7 @@ export class MapTemplate extends Template {
63
68
  * @returns a callback to update the shown trip
64
69
  */
65
70
  showTripSelector({ trips, selectedTripId, textConfig, onTripSelected, onTripStarted, onBackPressed, mapButtons, }) {
71
+ this.assertConnected();
66
72
  if (trips.length === 0 ||
67
73
  trips.some((t) => t.routeChoices.length === 0 || t.routeChoices.some((r) => r.steps.length < 2))) {
68
74
  throw new Error('Invalid trips passed, either no trips or some trips routeChoice or steps are empty');
@@ -76,9 +82,11 @@ export class MapTemplate extends Template {
76
82
  return HybridMapTemplate.showTripSelector(this.id, trips, selectedTripId, textConfig, onTripSelected, onTripStarted, onBackPressed, buttons ?? []);
77
83
  }
78
84
  hideTripSelector() {
85
+ this.assertConnected();
79
86
  HybridMapTemplate.hideTripSelector(this.id);
80
87
  }
81
88
  updateVisibleTravelEstimate(visibleTravelEstimate) {
89
+ this.assertConnected();
82
90
  HybridMapTemplate.updateVisibleTravelEstimate(this.id, visibleTravelEstimate);
83
91
  }
84
92
  /**
@@ -86,6 +94,7 @@ export class MapTemplate extends Template {
86
94
  * @param steps all future steps, do not put in origin or passed steps
87
95
  */
88
96
  updateTravelEstimates(steps) {
97
+ this.assertConnected();
89
98
  HybridMapTemplate.updateTravelEstimates(this.id, steps);
90
99
  }
91
100
  /**
@@ -94,6 +103,7 @@ export class MapTemplate extends Template {
94
103
  * @namespace iOS will update travelEstimates only when passing in maneuvers with the same id
95
104
  */
96
105
  updateManeuvers(maneuvers) {
106
+ this.assertConnected();
97
107
  if (Array.isArray(maneuvers)) {
98
108
  const nitroManeuvers = maneuvers.reduce((acc, maneuver) => {
99
109
  if (maneuver == null) {
@@ -117,9 +127,11 @@ export class MapTemplate extends Template {
117
127
  * or use this to start a navigation session without asking the user
118
128
  */
119
129
  startNavigation(trip) {
130
+ this.assertConnected();
120
131
  HybridMapTemplate.startNavigation(this.id, trip);
121
132
  }
122
133
  stopNavigation() {
134
+ this.assertConnected();
123
135
  HybridMapTemplate.stopNavigation(this.id);
124
136
  }
125
137
  }
@@ -47,7 +47,9 @@ export type MessageTemplateConfig = Omit<NitroMessageTemplateConfig, 'headerActi
47
47
  export declare class MessageTemplate {
48
48
  private template;
49
49
  id: string;
50
+ isConnected: boolean;
50
51
  constructor(config: MessageTemplateConfig);
52
+ assertConnected(): void;
51
53
  /**
52
54
  * push this template on the stack and show it to the user
53
55
  */
@@ -14,7 +14,13 @@ const HybridMessageTemplate = NitroModules.createHybridObject('MessageTemplate')
14
14
  export class MessageTemplate {
15
15
  template = this;
16
16
  id = uuid.v4();
17
+ isConnected = HybridAutoPlay.isConnected();
17
18
  constructor(config) {
19
+ this.assertConnected();
20
+ const removeDisconnectListener = HybridAutoPlay.addListener('didDisconnect', () => {
21
+ this.isConnected = false;
22
+ removeDisconnectListener();
23
+ });
18
24
  const { headerActions, image, mapConfig, actions, ...rest } = config;
19
25
  const platformActions = Platform.OS === 'android'
20
26
  ? NitroActionUtil.convert(this.template, actions?.android)
@@ -34,10 +40,16 @@ export class MessageTemplate {
34
40
  };
35
41
  HybridMessageTemplate.createMessageTemplate(nitroConfig);
36
42
  }
43
+ assertConnected() {
44
+ if (!this.isConnected) {
45
+ throw new Error(`Template '${this.id}' used after disconnect!`);
46
+ }
47
+ }
37
48
  /**
38
49
  * push this template on the stack and show it to the user
39
50
  */
40
51
  push() {
52
+ this.assertConnected();
41
53
  return HybridAutoPlay.pushTemplate(this.id);
42
54
  }
43
55
  }
@@ -20,6 +20,7 @@ export class SearchTemplate extends Template {
20
20
  HybridSearchTemplate.createSearchTemplate(nitroConfig);
21
21
  }
22
22
  updateSearchResults(results) {
23
+ this.assertConnected();
23
24
  return HybridSearchTemplate.updateSearchResults(this.id, NitroSectionUtil.convert(this.template, results)?.at(0) ?? {
24
25
  items: [],
25
26
  type: 'default',
@@ -35,6 +35,7 @@ export class SignInTemplate extends Template {
35
35
  * @returns A promise that resolves when the template is updated.
36
36
  */
37
37
  updateTemplate(updatedConfig) {
38
+ this.assertConnected();
38
39
  const { headerActions, actions, ...rest } = updatedConfig;
39
40
  const nitroConfig = {
40
41
  ...rest,
@@ -60,7 +60,9 @@ export interface NitroBaseMapTemplateConfig extends TemplateConfig {
60
60
  }
61
61
  export declare class Template<TemplateConfigType, ActionsType> {
62
62
  id: string;
63
+ isConnected: boolean;
63
64
  constructor(config: TemplateConfig & TemplateConfigType);
65
+ assertConnected(): void;
64
66
  /**
65
67
  * set as root template on the stack
66
68
  */
@@ -3,30 +3,45 @@ import { HybridAutoPlay } from '..';
3
3
  import { NitroActionUtil } from '../utils/NitroAction';
4
4
  export class Template {
5
5
  id;
6
+ isConnected = HybridAutoPlay.isConnected();
6
7
  constructor(config) {
8
+ this.assertConnected();
7
9
  // templates that render on a surface provide their own id, others use a auto generated one
8
10
  this.id =
9
11
  'id' in config && config.id != null && typeof config.id === 'string' ? config.id : uuid.v4();
12
+ const removeDisconnectListener = HybridAutoPlay.addListener('didDisconnect', () => {
13
+ this.isConnected = false;
14
+ removeDisconnectListener();
15
+ });
16
+ }
17
+ assertConnected() {
18
+ if (!this.isConnected) {
19
+ throw new Error(`Template '${this.id}' used after disconnect!`);
20
+ }
10
21
  }
11
22
  /**
12
23
  * set as root template on the stack
13
24
  */
14
25
  setRootTemplate() {
26
+ this.assertConnected();
15
27
  return HybridAutoPlay.setRootTemplate(this.id);
16
28
  }
17
29
  /**
18
30
  * push this template on the stack and show it to the user
19
31
  */
20
32
  push() {
33
+ this.assertConnected();
21
34
  return HybridAutoPlay.pushTemplate(this.id);
22
35
  }
23
36
  /**
24
37
  * remove all templates above this one from the stack
25
38
  */
26
39
  popTo() {
40
+ this.assertConnected();
27
41
  return HybridAutoPlay.popToTemplate(this.id);
28
42
  }
29
43
  setHeaderActions(headerActions) {
44
+ this.assertConnected();
30
45
  const nitroActions = NitroActionUtil.convert(this, headerActions);
31
46
  return HybridAutoPlay.setTemplateHeaderActions(this.id, nitroActions);
32
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iternio/react-native-auto-play",
3
- "version": "0.2.4",
3
+ "version": "0.2.5-alpha",
4
4
  "description": "Android Auto and Apple CarPlay for react-native",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -65,6 +65,8 @@ export class GridTemplate extends Template<GridTemplateConfig, HeaderActions<Gri
65
65
  }
66
66
 
67
67
  public updateGrid(buttons: Array<GridButton<GridTemplate>>) {
68
+ this.assertConnected();
69
+
68
70
  return HybridGridTemplate.updateGridTemplateButtons(
69
71
  this.id,
70
72
  NitroGridUtil.convert(this.template, buttons)
@@ -115,6 +115,8 @@ export class InformationTemplate extends Template<
115
115
  }
116
116
 
117
117
  public updateItems(items?: InformationItems) {
118
+ this.assertConnected();
119
+
118
120
  const section = this.getSection(items);
119
121
  return HybridInformationTemplate.updateInformationTemplateSections(
120
122
  this.id,
@@ -122,6 +122,8 @@ export class ListTemplate extends Template<ListTemplateConfig, HeaderActions<Lis
122
122
  }
123
123
 
124
124
  public updateSections(sections?: Section<ListTemplate>) {
125
+ this.assertConnected();
126
+
125
127
  return HybridListTemplate.updateListTemplateSections(
126
128
  this.id,
127
129
  NitroSectionUtil.convert(this.template, sections)
@@ -197,11 +197,15 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
197
197
  }
198
198
 
199
199
  public setMapButtons(mapButtons: MapTemplateConfig['mapButtons']) {
200
+ this.assertConnected();
201
+
200
202
  const buttons = NitroMapButton.convert(this.template, mapButtons);
201
203
  return HybridMapTemplate.setTemplateMapButtons(this.id, buttons);
202
204
  }
203
205
 
204
206
  public override setHeaderActions(headerActions: MapTemplateConfig['headerActions']) {
207
+ this.assertConnected();
208
+
205
209
  const nitroActions = NitroActionUtil.convert(this.template, headerActions);
206
210
  return HybridAutoPlay.setTemplateHeaderActions(this.id, nitroActions);
207
211
  }
@@ -212,14 +216,20 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
212
216
  * @returns a callback to dismiss or update the navigation alert
213
217
  */
214
218
  public showAlert(alert: NavigationAlert) {
219
+ this.assertConnected();
220
+
215
221
  return HybridMapTemplate.showNavigationAlert(this.id, NitroAlertUtil.convert(alert));
216
222
  }
217
223
 
218
224
  public updateAlert(alertId: number, title: AutoText, subtitle?: AutoText) {
225
+ this.assertConnected();
226
+
219
227
  HybridMapTemplate.updateNavigationAlert(this.id, alertId, title, subtitle);
220
228
  }
221
229
 
222
230
  public dismissAlert(alertId: number) {
231
+ this.assertConnected();
232
+
223
233
  HybridMapTemplate.dismissNavigationAlert(this.id, alertId);
224
234
  }
225
235
 
@@ -249,6 +259,8 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
249
259
  */
250
260
  mapButtons?: MapTemplateConfig['mapButtons'];
251
261
  }): TripSelectorCallback {
262
+ this.assertConnected();
263
+
252
264
  if (
253
265
  trips.length === 0 ||
254
266
  trips.some(
@@ -285,10 +297,14 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
285
297
  }
286
298
 
287
299
  public hideTripSelector() {
300
+ this.assertConnected();
301
+
288
302
  HybridMapTemplate.hideTripSelector(this.id);
289
303
  }
290
304
 
291
305
  public updateVisibleTravelEstimate(visibleTravelEstimate: VisibleTravelEstimate) {
306
+ this.assertConnected();
307
+
292
308
  HybridMapTemplate.updateVisibleTravelEstimate(this.id, visibleTravelEstimate);
293
309
  }
294
310
 
@@ -297,6 +313,8 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
297
313
  * @param steps all future steps, do not put in origin or passed steps
298
314
  */
299
315
  public updateTravelEstimates(steps: Array<TripPoint>) {
316
+ this.assertConnected();
317
+
300
318
  HybridMapTemplate.updateTravelEstimates(this.id, steps);
301
319
  }
302
320
 
@@ -306,6 +324,8 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
306
324
  * @namespace iOS will update travelEstimates only when passing in maneuvers with the same id
307
325
  */
308
326
  public updateManeuvers(maneuvers: AutoManeuver) {
327
+ this.assertConnected();
328
+
309
329
  if (Array.isArray(maneuvers)) {
310
330
  const nitroManeuvers = maneuvers.reduce((acc, maneuver) => {
311
331
  if (maneuver == null) {
@@ -334,10 +354,14 @@ export class MapTemplate extends Template<MapTemplateConfig, MapTemplateConfig['
334
354
  * or use this to start a navigation session without asking the user
335
355
  */
336
356
  public startNavigation(trip: TripConfig) {
357
+ this.assertConnected();
358
+
337
359
  HybridMapTemplate.startNavigation(this.id, trip);
338
360
  }
339
361
 
340
362
  public stopNavigation() {
363
+ this.assertConnected();
364
+
341
365
  HybridMapTemplate.stopNavigation(this.id);
342
366
  }
343
367
  }
@@ -74,8 +74,16 @@ export type MessageTemplateConfig = Omit<
74
74
  export class MessageTemplate {
75
75
  private template = this;
76
76
  public id = uuid.v4();
77
+ public isConnected = HybridAutoPlay.isConnected();
77
78
 
78
79
  constructor(config: MessageTemplateConfig) {
80
+ this.assertConnected();
81
+
82
+ const removeDisconnectListener = HybridAutoPlay.addListener('didDisconnect', () => {
83
+ this.isConnected = false;
84
+ removeDisconnectListener();
85
+ });
86
+
79
87
  const { headerActions, image, mapConfig, actions, ...rest } = config;
80
88
 
81
89
  const platformActions =
@@ -100,10 +108,18 @@ export class MessageTemplate {
100
108
  HybridMessageTemplate.createMessageTemplate(nitroConfig);
101
109
  }
102
110
 
111
+ public assertConnected() {
112
+ if (!this.isConnected) {
113
+ throw new Error(`Template '${this.id}' used after disconnect!`);
114
+ }
115
+ }
116
+
103
117
  /**
104
118
  * push this template on the stack and show it to the user
105
119
  */
106
120
  public push() {
121
+ this.assertConnected();
122
+
107
123
  return HybridAutoPlay.pushTemplate(this.id);
108
124
  }
109
125
  }
@@ -87,6 +87,8 @@ export class SearchTemplate extends Template<SearchTemplateConfig, HeaderActions
87
87
  }
88
88
 
89
89
  public updateSearchResults(results?: SingleSection<SearchTemplate>) {
90
+ this.assertConnected();
91
+
90
92
  return HybridSearchTemplate.updateSearchResults(
91
93
  this.id,
92
94
  NitroSectionUtil.convert(this.template, results)?.at(0) ?? {
@@ -97,6 +97,8 @@ export class SignInTemplate extends Template<
97
97
  * @returns A promise that resolves when the template is updated.
98
98
  */
99
99
  updateTemplate(updatedConfig: SignInTemplateUpdateConfig) {
100
+ this.assertConnected();
101
+
100
102
  const { headerActions, actions, ...rest } = updatedConfig;
101
103
  const nitroConfig: NitroSignInTemplateConfig & NitroTemplateConfig = {
102
104
  ...rest,
@@ -74,17 +74,33 @@ export interface NitroBaseMapTemplateConfig extends TemplateConfig {
74
74
 
75
75
  export class Template<TemplateConfigType, ActionsType> {
76
76
  public id!: string;
77
+ public isConnected = HybridAutoPlay.isConnected();
77
78
 
78
79
  constructor(config: TemplateConfig & TemplateConfigType) {
80
+ this.assertConnected();
81
+
79
82
  // templates that render on a surface provide their own id, others use a auto generated one
80
83
  this.id =
81
84
  'id' in config && config.id != null && typeof config.id === 'string' ? config.id : uuid.v4();
85
+
86
+ const removeDisconnectListener = HybridAutoPlay.addListener('didDisconnect', () => {
87
+ this.isConnected = false;
88
+ removeDisconnectListener();
89
+ });
90
+ }
91
+
92
+ public assertConnected() {
93
+ if (!this.isConnected) {
94
+ throw new Error(`Template '${this.id}' used after disconnect!`);
95
+ }
82
96
  }
83
97
 
84
98
  /**
85
99
  * set as root template on the stack
86
100
  */
87
101
  public setRootTemplate() {
102
+ this.assertConnected();
103
+
88
104
  return HybridAutoPlay.setRootTemplate(this.id);
89
105
  }
90
106
 
@@ -92,6 +108,8 @@ export class Template<TemplateConfigType, ActionsType> {
92
108
  * push this template on the stack and show it to the user
93
109
  */
94
110
  public push() {
111
+ this.assertConnected();
112
+
95
113
  return HybridAutoPlay.pushTemplate(this.id);
96
114
  }
97
115
 
@@ -99,10 +117,14 @@ export class Template<TemplateConfigType, ActionsType> {
99
117
  * remove all templates above this one from the stack
100
118
  */
101
119
  public popTo() {
120
+ this.assertConnected();
121
+
102
122
  return HybridAutoPlay.popToTemplate(this.id);
103
123
  }
104
124
 
105
125
  public setHeaderActions<T>(headerActions?: ActionsType) {
126
+ this.assertConnected();
127
+
106
128
  const nitroActions = NitroActionUtil.convert(
107
129
  this as unknown as T,
108
130
  headerActions as HeaderActions<T>