@situm/react-native 3.0.0-beta.0 → 3.0.0-beta.1

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 (51) hide show
  1. package/README.md +59 -505
  2. package/lib/commonjs/index.js +12 -0
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/sdk/types/index.d.js +349 -0
  5. package/lib/commonjs/sdk/types/index.d.js.map +1 -1
  6. package/lib/commonjs/utils/requestPermission.js +2 -2
  7. package/lib/commonjs/utils/requestPermission.js.map +1 -1
  8. package/lib/commonjs/wayfinding/components/MapView.js +97 -12
  9. package/lib/commonjs/wayfinding/components/MapView.js.map +1 -1
  10. package/lib/commonjs/wayfinding/hooks/index.js +40 -80
  11. package/lib/commonjs/wayfinding/hooks/index.js.map +1 -1
  12. package/lib/commonjs/wayfinding/store/index.js +8 -28
  13. package/lib/commonjs/wayfinding/store/index.js.map +1 -1
  14. package/lib/commonjs/wayfinding/utils/mapper.js +6 -4
  15. package/lib/commonjs/wayfinding/utils/mapper.js.map +1 -1
  16. package/lib/module/index.js +1 -0
  17. package/lib/module/index.js.map +1 -1
  18. package/lib/module/sdk/types/index.d.js +373 -1
  19. package/lib/module/sdk/types/index.d.js.map +1 -1
  20. package/lib/module/utils/requestPermission.js +2 -2
  21. package/lib/module/utils/requestPermission.js.map +1 -1
  22. package/lib/module/wayfinding/components/MapView.js +97 -11
  23. package/lib/module/wayfinding/components/MapView.js.map +1 -1
  24. package/lib/module/wayfinding/hooks/index.js +8 -49
  25. package/lib/module/wayfinding/hooks/index.js.map +1 -1
  26. package/lib/module/wayfinding/store/index.js +3 -24
  27. package/lib/module/wayfinding/store/index.js.map +1 -1
  28. package/lib/module/wayfinding/utils/mapper.js +6 -4
  29. package/lib/module/wayfinding/utils/mapper.js.map +1 -1
  30. package/lib/typescript/src/index.d.ts +1 -0
  31. package/lib/typescript/src/index.d.ts.map +1 -1
  32. package/lib/typescript/src/wayfinding/components/MapView.d.ts +5 -2
  33. package/lib/typescript/src/wayfinding/components/MapView.d.ts.map +1 -1
  34. package/lib/typescript/src/wayfinding/hooks/index.d.ts +3 -12
  35. package/lib/typescript/src/wayfinding/hooks/index.d.ts.map +1 -1
  36. package/lib/typescript/src/wayfinding/store/index.d.ts +3 -62
  37. package/lib/typescript/src/wayfinding/store/index.d.ts.map +1 -1
  38. package/lib/typescript/src/wayfinding/utils/mapper.d.ts +3 -2
  39. package/lib/typescript/src/wayfinding/utils/mapper.d.ts.map +1 -1
  40. package/package.json +12 -9
  41. package/src/index.ts +1 -0
  42. package/src/sdk/types/index.d.ts +80 -0
  43. package/src/utils/requestPermission.ts +2 -2
  44. package/src/wayfinding/components/MapView.tsx +329 -217
  45. package/src/wayfinding/hooks/index.ts +17 -78
  46. package/src/wayfinding/store/index.tsx +13 -80
  47. package/src/wayfinding/types/index.d.ts +10 -11
  48. package/src/wayfinding/utils/mapper.ts +16 -13
  49. package/android/.gradle/5.6.4/fileChanges/last-build.bin +0 -0
  50. package/android/.gradle/5.6.4/fileHashes/fileHashes.lock +0 -0
  51. package/android/.gradle/5.6.4/gc.properties +0 -0
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  /* eslint-disable @typescript-eslint/no-empty-function */
3
- import React, { useEffect, useRef, useState } from "react";
3
+ import React, { useEffect, useImperativeHandle, useRef, useState } from "react";
4
4
  import { Platform, StyleSheet } from "react-native";
5
5
  import WebView from "react-native-webview";
6
6
  import {
@@ -8,16 +8,20 @@ import {
8
8
  WebViewMessageEvent,
9
9
  } from "react-native-webview/lib/WebViewTypes";
10
10
 
11
- //This icon should either be inside plugin or not be used rat all
12
- import useSitum from "../hooks";
13
11
  import {
12
+ NavigateToPoiType,
14
13
  NavigationStatus,
15
14
  NavigationUpdateType,
16
- setWebViewRef,
17
- } from "../store";
15
+ Poi,
16
+ } from "../../sdk/types/index.d";
17
+ //This icon should either be inside plugin or not be used rat all
18
+ import useSitum from "../hooks";
19
+ import { useCallbackRef } from "../hooks";
20
+ import { setWebViewRef } from "../store";
18
21
  import { useDispatch } from "../store/utils";
19
22
  import {
20
23
  MapViewError,
24
+ MapViewRef,
21
25
  OnFloorChangedResult,
22
26
  OnNavigationResult,
23
27
  OnPoiDeselectedResult,
@@ -49,6 +53,9 @@ export interface MapViewProps {
49
53
  user?: string;
50
54
  apikey?: string;
51
55
  configuration?: {
56
+ situmUser?: string;
57
+ situmApiKey?: string;
58
+ remoteIdentifier?: string;
52
59
  buildingIdentifier?: string;
53
60
  enablePoiClustering?: boolean;
54
61
  showPoiNames?: boolean;
@@ -79,234 +86,339 @@ const viewerStyles = StyleSheet.create({
79
86
  },
80
87
  });
81
88
 
82
- const MapView: React.FC<MapViewProps> = ({
83
- domain,
84
- // user,
85
- // apikey,
86
- configuration,
87
- onLoad = () => {},
88
- onLoadError = () => {},
89
- onFloorChanged = () => {},
90
- onPoiSelected = () => {},
91
- onPoiDeselected = () => {},
92
- onNavigationRequested = () => {},
93
- onNavigationStarted = () => {},
94
- onNavigationError = () => {},
95
- onNavigationFinished = () => {},
96
- style,
97
- //iOSMapViewIndex,
98
- }) => {
99
- const dispatch = useDispatch();
100
- const webViewRef = useRef();
101
- // Local states
102
- const [mapLoaded, setMapLoaded] = useState<boolean>(false);
89
+ const MapView = React.forwardRef<MapViewRef, MapViewProps>(
90
+ (
91
+ {
92
+ domain,
93
+ // user,
94
+ // apikey,
95
+ configuration,
96
+ onLoad = () => {},
97
+ onLoadError = () => {},
98
+ onFloorChanged = () => {},
99
+ onPoiSelected = () => {},
100
+ onPoiDeselected = () => {},
101
+ onNavigationRequested = () => {},
102
+ onNavigationStarted = () => {},
103
+ onNavigationError = () => {},
104
+ onNavigationFinished = () => {},
105
+ style,
106
+ //iOSMapViewIndex,
107
+ },
108
+ ref
109
+ ) => {
110
+ const dispatch = useDispatch();
111
+ const webViewRef = useRef(null);
112
+ // Local states
113
+ const [mapLoaded, setMapLoaded] = useState<boolean>(false);
103
114
 
104
- const {
105
- user: fullUser,
106
- location,
107
- directions,
108
- navigation,
109
- currentBuilding,
110
- initializeBuildingById,
111
- calculateRoute,
112
- startNavigation,
113
- stopNavigation,
114
- error,
115
- } = useSitum();
115
+ const {
116
+ user: fullUser,
117
+ pois,
118
+ location,
119
+ directions,
120
+ navigation,
121
+ currentBuilding,
122
+ initializeBuildingById,
123
+ calculateRoute,
124
+ startNavigation,
125
+ stopNavigation,
126
+ error,
127
+ } = useSitum();
116
128
 
117
- const sendFollowUser = () => {
118
- if (
119
- webViewRef.current &&
120
- mapLoaded &&
121
- location?.position?.buildingIdentifier ===
122
- configuration?.buildingIdentifier
123
- ) {
124
- sendMessageToViewer(webViewRef.current, Mapper.followUser(true));
125
- }
126
- };
129
+ const sendFollowUser = () => {
130
+ if (
131
+ webViewRef.current &&
132
+ mapLoaded &&
133
+ location?.position?.buildingIdentifier ===
134
+ configuration?.buildingIdentifier
135
+ ) {
136
+ sendMessageToViewer(webViewRef.current, Mapper.followUser(true));
137
+ }
138
+ };
127
139
 
128
- useEffect(() => {
129
- configuration.buildingIdentifier &&
130
- initializeBuildingById(configuration.buildingIdentifier);
131
- // eslint-disable-next-line react-hooks/exhaustive-deps
132
- }, [configuration.buildingIdentifier]);
140
+ /**
141
+ * API exported to the outside world from the MapViewer
142
+ *
143
+ * These handler allows third party developers to send actions to the MapView.
144
+ * please check the MapViewRef type definitions to know the public API.
145
+ *
146
+ * <MapView
147
+ * ref={(ref: MapViewRef) => ref.selectPoi(122)}
148
+ * configuration={{
149
+ * buildingIdentifier: SITUM_BUILDING_ID,
150
+ * }}
151
+ * onLoad={onLoad} />
152
+ */
153
+ const navigateToPoiRef = useCallbackRef(
154
+ ({ poi, poiId }: { poi?: Poi; poiId?: number }) => {
155
+ if (!webViewRef.current || (!poi && !poiId)) return;
156
+ const validPoi = pois?.find(
157
+ (p) =>
158
+ p?.identifier === poiId?.toString() ||
159
+ // @ts-ignore
160
+ p?.identifier === poi?.id?.toString()
161
+ );
162
+ if (!validPoi) {
163
+ console.error("Situm > hook > Invalid value as poi or poiId");
164
+ return;
165
+ }
166
+
167
+ sendMessageToViewer(
168
+ webViewRef.current,
169
+ Mapper.navigateToPoi({
170
+ // @ts-ignore
171
+ navigationTo: poi?.id || poiId,
172
+ } as NavigateToPoiType)
173
+ );
174
+ },
175
+ [pois]
176
+ );
177
+
178
+ const selectPoiRef = useCallbackRef(
179
+ (poiId: number) => {
180
+ if (!webViewRef.current) {
181
+ return;
182
+ }
183
+ const poi = pois?.find((p) => p?.identifier === poiId?.toString());
184
+ if (!poi) {
185
+ console.error("Situm > hook > Invalid value as poiId");
186
+ return;
187
+ }
188
+ if (navigation.status !== NavigationStatus.STOP) {
189
+ console.error(
190
+ "Situm > hook > Navigation on course, poi selection is unavailable"
191
+ );
192
+ return;
193
+ }
194
+ sendMessageToViewer(webViewRef.current, Mapper.selectPoi(poiId));
195
+ },
196
+ [pois, navigation.status]
197
+ );
133
198
 
134
- useEffect(() => {
135
- if (error) {
136
- console.error(
137
- "Error code:",
138
- error.code ? error.code : " no code provided"
139
- );
140
- console.error("Error detected:", error.message);
141
- }
142
- }, [error]);
199
+ useImperativeHandle(
200
+ ref,
201
+ () => {
202
+ return {
203
+ followUser() {
204
+ webViewRef.current &&
205
+ sendMessageToViewer(webViewRef.current, Mapper.followUser(true));
206
+ },
207
+ unFollowUser() {
208
+ webViewRef.current &&
209
+ sendMessageToViewer(webViewRef.current, Mapper.followUser(false));
210
+ },
211
+ selectPoi(poiId: number) {
212
+ selectPoiRef.current(poiId);
213
+ },
214
+ deselectPoi() {
215
+ webViewRef.current &&
216
+ sendMessageToViewer(webViewRef.current, Mapper.selectPoi(null));
217
+ },
218
+ navigateToPoi({ poi, poiId }: { poi?: Poi; poiId?: number }): void {
219
+ navigateToPoiRef.current({ poi, poiId });
220
+ },
221
+ cancelNavigation(): void {
222
+ if (!webViewRef.current) return;
223
+ stopNavigation();
224
+ sendMessageToViewer(webViewRef.current, Mapper.cancelNavigation());
225
+ },
226
+ };
227
+ },
228
+ [stopNavigation, navigateToPoiRef, selectPoiRef]
229
+ );
143
230
 
144
- // Updated SDK location
145
- useEffect(() => {
146
- if (!webViewRef.current || !location) return;
147
- //console.debug('location', location);
231
+ useEffect(() => {
232
+ configuration?.buildingIdentifier &&
233
+ initializeBuildingById(configuration.buildingIdentifier);
234
+ // eslint-disable-next-line react-hooks/exhaustive-deps
235
+ }, [configuration?.buildingIdentifier]);
148
236
 
149
- sendMessageToViewer(webViewRef.current, Mapper.location(location));
150
- }, [location]);
237
+ useEffect(() => {
238
+ if (error) {
239
+ console.error(
240
+ "Error code:",
241
+ error.code ? error.code : " no code provided"
242
+ );
243
+ console.error("Error detected:", error.message);
244
+ }
245
+ }, [error]);
151
246
 
152
- // Updated SDK navigation
153
- useEffect(() => {
154
- if (!webViewRef.current || !navigation) return;
247
+ // Updated SDK location
248
+ useEffect(() => {
249
+ if (!webViewRef.current || !location) return;
250
+ //console.debug('location', location);
155
251
 
156
- sendMessageToViewer(webViewRef.current, Mapper.navigation(navigation));
252
+ sendMessageToViewer(webViewRef.current, Mapper.location(location));
253
+ }, [location]);
157
254
 
158
- if (navigation.status === NavigationStatus.START) {
159
- onNavigationStarted({
160
- navigation: Mapper.routeToResult(navigation),
161
- } as OnNavigationResult);
162
- }
163
- if (navigation?.type === NavigationUpdateType.destinationReached) {
164
- onNavigationFinished({
165
- navigation: Mapper.navigationToResult(navigation),
166
- } as OnNavigationResult);
167
- }
168
- // eslint-disable-next-line react-hooks/exhaustive-deps
169
- }, [navigation]);
255
+ // Updated SDK navigation
256
+ useEffect(() => {
257
+ if (!webViewRef.current || !navigation) return;
170
258
 
171
- // Updated SDK route
172
- useEffect(() => {
173
- if (!webViewRef.current || !directions) return;
259
+ sendMessageToViewer(webViewRef.current, Mapper.navigation(navigation));
174
260
 
175
- sendMessageToViewer(webViewRef.current, Mapper.route(directions));
176
- }, [directions]);
261
+ if (navigation.status === NavigationStatus.START) {
262
+ onNavigationStarted({
263
+ navigation: Mapper.routeToResult(navigation),
264
+ } as OnNavigationResult);
265
+ }
266
+ if (navigation?.type === NavigationUpdateType.destinationReached) {
267
+ onNavigationFinished({
268
+ navigation: Mapper.navigationToResult(navigation),
269
+ } as OnNavigationResult);
270
+ }
271
+ // eslint-disable-next-line react-hooks/exhaustive-deps
272
+ }, [navigation]);
177
273
 
178
- useEffect(() => {
179
- if (webViewRef.current && mapLoaded) {
180
- sendMessageToViewer(
181
- webViewRef.current,
182
- Mapper.initialConfiguration(
183
- style,
184
- configuration.enablePoiClustering,
185
- configuration.showPoiNames,
186
- configuration.minZoom,
187
- configuration.maxZoom,
188
- configuration.initialZoom,
189
- configuration.useDashboardTheme
190
- )
191
- );
192
- }
193
- }, [
194
- webViewRef,
195
- mapLoaded,
196
- style,
197
- configuration.enablePoiClustering,
198
- configuration.showPoiNames,
199
- configuration.minZoom,
200
- configuration.maxZoom,
201
- configuration.initialZoom,
202
- configuration.useDashboardTheme,
203
- ]);
274
+ // Updated SDK route
275
+ useEffect(() => {
276
+ if (!webViewRef.current || !directions) return;
204
277
 
205
- const handleRequestFromViewer = (event: WebViewMessageEvent) => {
206
- const eventParsed = JSON.parse(event.nativeEvent.data);
207
- switch (eventParsed.type) {
208
- case "app.map_is_ready":
209
- onLoad({
210
- status: "SUCCESS",
211
- message: "Map is ready!",
212
- } as WayfindingResult);
213
- sendFollowUser();
214
- break;
215
- case "directions.requested":
216
- calculateRoute({
217
- originId: JSON.parse(event.nativeEvent.data).payload.originIdentifier,
218
- destinationId: JSON.parse(event.nativeEvent.data).payload
219
- .destinationIdentifier,
220
- directionsOptions: JSON.parse(event.nativeEvent.data).payload
221
- .directionsOptions,
222
- });
223
- break;
224
- case "navigation.requested":
225
- startNavigation({
226
- originId: JSON.parse(event.nativeEvent.data).payload.originIdentifier,
227
- destinationId: JSON.parse(event.nativeEvent.data).payload
228
- .destinationIdentifier,
229
- directionsOptions: JSON.parse(event.nativeEvent.data).payload
230
- .directionsOptions,
231
- callback: (status, _navigation?) =>
232
- status === "success" && navigation
233
- ? onNavigationRequested({
234
- navigation: Mapper.routeToResult(_navigation),
235
- } as OnNavigationResult)
236
- : status === "error" &&
237
- onNavigationError({} as OnNavigationResult),
238
- });
239
- break;
240
- case "navigation.stopped":
241
- stopNavigation();
242
- break;
243
- case "cartography.poi_selected":
244
- onPoiSelected(eventParsed?.payload);
245
- break;
246
- case "cartography.poi_deselected":
247
- onPoiDeselected(eventParsed?.payload);
248
- break;
249
- case "cartography.floor_changed":
250
- onFloorChanged(eventParsed?.payload);
251
- break;
252
- case "cartography.building_selected":
253
- if (
254
- !eventParsed.payload.identifier ||
255
- (currentBuilding &&
256
- eventParsed.payload.identifier.toString() ===
257
- currentBuilding.buildingIdentifier)
258
- ) {
259
- return;
260
- }
278
+ sendMessageToViewer(webViewRef.current, Mapper.route(directions));
279
+ }, [directions]);
261
280
 
262
- initializeBuildingById(eventParsed.payload.identifier.toString());
263
- break;
264
- default:
265
- break;
266
- }
267
- };
281
+ useEffect(() => {
282
+ if (webViewRef.current && mapLoaded) {
283
+ sendMessageToViewer(
284
+ webViewRef.current,
285
+ Mapper.initialConfiguration(
286
+ style,
287
+ configuration?.enablePoiClustering,
288
+ configuration?.showPoiNames,
289
+ configuration?.minZoom,
290
+ configuration?.maxZoom,
291
+ configuration?.initialZoom,
292
+ configuration?.useDashboardTheme
293
+ )
294
+ );
295
+ }
296
+ }, [
297
+ webViewRef,
298
+ mapLoaded,
299
+ style,
300
+ configuration?.enablePoiClustering,
301
+ configuration?.showPoiNames,
302
+ configuration?.minZoom,
303
+ configuration?.maxZoom,
304
+ configuration?.initialZoom,
305
+ configuration?.useDashboardTheme,
306
+ ]);
268
307
 
269
- return (
270
- <WebView
271
- ref={webViewRef}
272
- source={{
273
- uri: `${domain || SITUM_BASE_DOMAIN}/?email=${fullUser?.email}&apikey=${
274
- fullUser?.apiKey
275
- }&wl=true&global=true&mode=embed${
276
- configuration.buildingIdentifier
277
- ? `&buildingid=${configuration.buildingIdentifier}`
278
- : ""
279
- }&show=rts`,
280
- }}
281
- style={viewerStyles.webview}
282
- javaScriptEnabled={true}
283
- domStorageEnabled={true}
284
- startInLoadingState={true}
285
- onMessage={handleRequestFromViewer}
286
- // This is called on a lot of interactions with the map because of url change probably
287
- onLoadEnd={() => {
288
- if (!webViewRef.current) return;
289
- dispatch(setWebViewRef(webViewRef));
290
- setMapLoaded(true);
291
- }}
292
- onError={(evt: WebViewErrorEvent) => {
293
- const { nativeEvent } = evt;
294
- // TODO: on render error should probably still try to render an html
295
- if (nativeEvent.code === NETWORK_ERROR_CODE[Platform.OS]) {
296
- onLoadError({
297
- name: ErrorName.ERR_INTERNET_DISCONNECTED,
298
- description: nativeEvent.description,
308
+ const handleRequestFromViewer = (event: WebViewMessageEvent) => {
309
+ const eventParsed = JSON.parse(event.nativeEvent.data);
310
+ switch (eventParsed.type) {
311
+ case "app.map_is_ready":
312
+ onLoad({
313
+ status: "SUCCESS",
314
+ message: "Map is ready!",
315
+ } as WayfindingResult);
316
+ sendFollowUser();
317
+ break;
318
+ case "directions.requested":
319
+ calculateRoute({
320
+ originId: JSON.parse(event.nativeEvent.data).payload
321
+ .originIdentifier,
322
+ destinationId: JSON.parse(event.nativeEvent.data).payload
323
+ .destinationIdentifier,
324
+ directionsOptions: JSON.parse(event.nativeEvent.data).payload
325
+ .directionsOptions,
299
326
  });
300
- } else {
301
- // TODO: handle more errors
302
- onLoadError({
303
- name: ErrorName.ERR_INTERNAL_SERVER_ERROR,
304
- description: nativeEvent.description,
327
+ break;
328
+ case "navigation.requested":
329
+ startNavigation({
330
+ originId: JSON.parse(event.nativeEvent.data).payload
331
+ .originIdentifier,
332
+ destinationId: JSON.parse(event.nativeEvent.data).payload
333
+ .destinationIdentifier,
334
+ directionsOptions: JSON.parse(event.nativeEvent.data).payload
335
+ .directionsOptions,
336
+ callback: (status, _navigation?) =>
337
+ status === "success" && navigation
338
+ ? onNavigationRequested({
339
+ navigation: Mapper.routeToResult(_navigation),
340
+ } as OnNavigationResult)
341
+ : status === "error" &&
342
+ onNavigationError({} as OnNavigationResult),
305
343
  });
306
- }
307
- }}
308
- />
309
- );
310
- };
344
+ break;
345
+ case "navigation.stopped":
346
+ stopNavigation();
347
+ break;
348
+ case "cartography.poi_selected":
349
+ onPoiSelected(eventParsed?.payload);
350
+ break;
351
+ case "cartography.poi_deselected":
352
+ onPoiDeselected(eventParsed?.payload);
353
+ break;
354
+ case "cartography.floor_changed":
355
+ onFloorChanged(eventParsed?.payload);
356
+ break;
357
+ case "cartography.building_selected":
358
+ if (
359
+ !eventParsed.payload.identifier ||
360
+ (currentBuilding &&
361
+ eventParsed.payload.identifier.toString() ===
362
+ currentBuilding.buildingIdentifier)
363
+ ) {
364
+ return;
365
+ }
366
+
367
+ initializeBuildingById(eventParsed.payload.identifier.toString());
368
+ break;
369
+ default:
370
+ break;
371
+ }
372
+ };
373
+
374
+ return (
375
+ <WebView
376
+ ref={webViewRef}
377
+ source={{
378
+ uri: `${domain || SITUM_BASE_DOMAIN}/${
379
+ configuration?.remoteIdentifier
380
+ ? `id/${configuration.remoteIdentifier}`
381
+ : ""
382
+ }?email=${fullUser?.email}&apikey=${
383
+ fullUser?.apiKey
384
+ }&wl=true&global=true&mode=embed${
385
+ configuration?.buildingIdentifier
386
+ ? `&buildingid=${configuration.buildingIdentifier}`
387
+ : ""
388
+ }&show=rts`,
389
+ }}
390
+ style={viewerStyles.webview}
391
+ limitsNavigationsToAppBoundDomains={true}
392
+ javaScriptEnabled={true}
393
+ domStorageEnabled={true}
394
+ startInLoadingState={true}
395
+ cacheEnabled
396
+ onMessage={handleRequestFromViewer}
397
+ // This is called on a lot of interactions with the map because of url change probably
398
+ onLoadEnd={() => {
399
+ if (!webViewRef.current) return;
400
+ dispatch(setWebViewRef(webViewRef));
401
+ setMapLoaded(true);
402
+ }}
403
+ onError={(evt: WebViewErrorEvent) => {
404
+ const { nativeEvent } = evt;
405
+ // TODO: on render error should probably still try to render an html
406
+ if (nativeEvent.code === NETWORK_ERROR_CODE[Platform.OS]) {
407
+ onLoadError({
408
+ name: ErrorName.ERR_INTERNET_DISCONNECTED,
409
+ description: nativeEvent.description,
410
+ });
411
+ } else {
412
+ // TODO: handle more errors
413
+ onLoadError({
414
+ name: ErrorName.ERR_INTERNAL_SERVER_ERROR,
415
+ description: nativeEvent.description,
416
+ });
417
+ }
418
+ }}
419
+ />
420
+ );
421
+ }
422
+ );
311
423
 
312
424
  export default MapView;