react-native-pointr 9.1.0 → 9.3.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 (78) hide show
  1. package/API_REFERENCE.md +887 -0
  2. package/CHANGELOG.md +35 -0
  3. package/EXTENDING.md +419 -0
  4. package/README.md +221 -117
  5. package/WAYFINDING_EVENTS.md +243 -0
  6. package/android/build.gradle +3 -16
  7. package/android/src/main/java/com/pointr/PTRCoreExtensions.kt +126 -0
  8. package/android/src/main/java/com/pointr/PTRMapWidgetCommandType.kt +3 -1
  9. package/android/src/main/java/com/pointr/PTRMapWidgetManager.kt +160 -11
  10. package/android/src/main/java/com/pointr/PointrModule.kt +106 -3
  11. package/example/pointr_rn_demo/.bundle/config +2 -0
  12. package/example/pointr_rn_demo/.eslintrc.js +4 -0
  13. package/example/pointr_rn_demo/.prettierrc.js +5 -0
  14. package/example/pointr_rn_demo/.watchmanconfig +1 -0
  15. package/example/pointr_rn_demo/App.tsx +323 -0
  16. package/example/pointr_rn_demo/Gemfile +16 -0
  17. package/example/pointr_rn_demo/Gemfile.lock +111 -0
  18. package/example/pointr_rn_demo/README.md +188 -0
  19. package/example/pointr_rn_demo/__tests__/App.test.tsx +13 -0
  20. package/example/pointr_rn_demo/android/app/build.gradle +119 -0
  21. package/example/pointr_rn_demo/android/app/debug.keystore +0 -0
  22. package/example/pointr_rn_demo/android/app/proguard-rules.pro +10 -0
  23. package/example/pointr_rn_demo/android/app/src/main/AndroidManifest.xml +27 -0
  24. package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainActivity.kt +22 -0
  25. package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainApplication.kt +27 -0
  26. package/example/pointr_rn_demo/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  27. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  28. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  29. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  30. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  31. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  32. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  33. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  34. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  35. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  36. package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  37. package/example/pointr_rn_demo/android/app/src/main/res/values/strings.xml +3 -0
  38. package/example/pointr_rn_demo/android/app/src/main/res/values/styles.xml +9 -0
  39. package/example/pointr_rn_demo/android/build.gradle +32 -0
  40. package/example/pointr_rn_demo/android/gradle.properties +44 -0
  41. package/example/pointr_rn_demo/android/settings.gradle +6 -0
  42. package/example/pointr_rn_demo/app.json +4 -0
  43. package/example/pointr_rn_demo/babel.config.js +3 -0
  44. package/example/pointr_rn_demo/index.js +16 -0
  45. package/example/pointr_rn_demo/ios/.xcode.env +11 -0
  46. package/example/pointr_rn_demo/ios/Podfile +40 -0
  47. package/example/pointr_rn_demo/ios/Podfile.lock +2767 -0
  48. package/example/pointr_rn_demo/ios/pointr_rn_demo/AppDelegate.swift +48 -0
  49. package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
  50. package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/Contents.json +6 -0
  51. package/example/pointr_rn_demo/ios/pointr_rn_demo/Info.plist +63 -0
  52. package/example/pointr_rn_demo/ios/pointr_rn_demo/LaunchScreen.storyboard +47 -0
  53. package/example/pointr_rn_demo/ios/pointr_rn_demo/PrivacyInfo.xcprivacy +37 -0
  54. package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/project.pbxproj +496 -0
  55. package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/xcshareddata/xcschemes/pointr_rn_demo.xcscheme +88 -0
  56. package/example/pointr_rn_demo/ios/pointr_rn_demo.xcworkspace/contents.xcworkspacedata +10 -0
  57. package/example/pointr_rn_demo/jest.config.js +3 -0
  58. package/example/pointr_rn_demo/metro.config.js +22 -0
  59. package/example/pointr_rn_demo/package-lock.json +11747 -0
  60. package/example/pointr_rn_demo/package.json +46 -0
  61. package/example/pointr_rn_demo/prepare-demo-distribution.sh +103 -0
  62. package/example/pointr_rn_demo/tsconfig.json +5 -0
  63. package/ios/PTRMapWidgetContainerView.swift +59 -7
  64. package/ios/PTRMapWidgetManager-Bridging.m +65 -1
  65. package/ios/PTRMapWidgetManager.swift +185 -144
  66. package/ios/PTRNativeLibrary-Bridging.m +4 -0
  67. package/ios/PTRNativeLibrary.swift +244 -18
  68. package/package.json +16 -2
  69. package/prepare-distribution.sh +84 -0
  70. package/react-native-pointr.podspec +1 -1
  71. package/src/PTRCommand.ts +34 -1
  72. package/src/PTRMapWidgetUtils.ts +105 -5
  73. package/src/PTRPoiManager.ts +20 -0
  74. package/src/index.tsx +40 -1
  75. package/src/types/PTRGeometry.ts +70 -0
  76. package/src/types/PTRPoi.ts +49 -0
  77. package/src/types/PTRPosition.ts +22 -0
  78. package/src/types/PTRWayfindingEvent.ts +18 -0
package/README.md CHANGED
@@ -12,6 +12,8 @@ Ensure you have the following set up before proceeding:
12
12
 
13
13
  ## 1. Install the Package
14
14
 
15
+ ### From npm Registry
16
+
15
17
  Run the following command to install the package using npm:
16
18
 
17
19
  ```
@@ -24,6 +26,32 @@ Or, if you use Yarn:
24
26
  yarn add react-native-pointr
25
27
  ```
26
28
 
29
+ ### From Local Storage
30
+
31
+ If you have the package in your local project (e.g., in a `modules` folder), you can install it by referencing the local path:
32
+
33
+ Using npm:
34
+
35
+ ```
36
+ npm install file:./modules/react-native-pointr
37
+ ```
38
+
39
+ Or with Yarn:
40
+
41
+ ```
42
+ yarn add file:./modules/react-native-pointr
43
+ ```
44
+
45
+ Alternatively, you can add it directly to your `package.json`:
46
+
47
+ ```json
48
+ "dependencies": {
49
+ "react-native-pointr": "file:./modules/react-native-pointr"
50
+ }
51
+ ```
52
+
53
+ Then run `npm install` or `yarn install` to install the dependencies.
54
+
27
55
  ## 2. Integration to Mobile Platforms
28
56
 
29
57
  === "iOS"
@@ -128,156 +156,217 @@ yarn add react-native-pointr
128
156
  Now you can start using the package in your React Native components. Here's a simple example of how to import on `App.tsx` file:
129
157
 
130
158
  ```typescript
131
- ...
132
- import React, { useEffect, useRef } from 'react';
159
+ import React, { useRef } from 'react';
133
160
  import {
134
161
  requireNativeComponent,
135
- UIManager,
136
162
  findNodeHandle,
137
163
  Button,
138
164
  SafeAreaView,
139
165
  View,
140
166
  ScrollView,
141
- Dimensions,
142
- StyleSheet,
167
+ NativeSyntheticEvent,
168
+ NativeEventEmitter,
143
169
  NativeModules
144
170
  } from 'react-native';
145
- import { PTRSiteCommand, PTRBuildingCommand, PTRLevelCommand, PTRPoiCommand, PTRPathCommand, PTRStaticPathCommand, PTRCommand, PTRCommandType } from 'react-native-pointr/src/PTRCommand';
171
+ import {
172
+ PTRSiteCommand,
173
+ PTRBuildingCommand,
174
+ PTRLevelCommand,
175
+ PTRPoiCommand,
176
+ PTRPathCommand,
177
+ PTRStaticPathCommand,
178
+ PTRMarkMyCarLevelCommand,
179
+ PTRMarkMyCarSiteCommand,
180
+ PTRShowMyCarSiteCommand,
181
+ PTRStartAndFocusCommand
182
+ } from 'react-native-pointr/src/PTRCommand';
146
183
  import { showMapWidget } from 'react-native-pointr/src/PTRMapWidgetUtils';
147
184
  ```
148
185
 
149
- Initialize and start Pointr instance before doing any operation.
186
+ Define the `PTRMapWidget` component interface and create the component using `requireNativeComponent`:
150
187
 
151
188
  ```typescript
189
+ interface PTRMapWidgetProps {
190
+ style?: any;
191
+ onMapWidgetDidEndLoading?: (event: NativeSyntheticEvent<any>) => void;
192
+ }
152
193
 
153
- // initialize Pointr instance with the provided credentials
154
- NativeModules.PTRNativePointrLibrary.initialize("<LICENSE_KEY>", "<API_URL>", "<CLIEND_ID>", "<ENVIRONMENT>", <LOG_LEVEL>);
155
- NativeModules.PTRNativePointrLibrary.start((state: string) => {
156
- console.log(`Pointr state: ${state}`);
157
- });
194
+ const PTRMapWidget = requireNativeComponent<PTRMapWidgetProps>('PTRMapWidget');
158
195
  ```
159
196
 
160
- Define the `PTRMapWidget` component using `requireNativeComponent`:
197
+ Initialize and start Pointr instance before doing any operation:
161
198
 
162
199
  ```typescript
163
- interface PTRMapWidgetProps {
164
- onMapDidEndLoading?: (event: NativeSyntheticEvent<object>) => void;
165
- }
200
+ // Initialize Pointr instance with the provided credentials
201
+ NativeModules.PTRNativePointrLibrary.initialize(
202
+ "<CLIENT_ID>",
203
+ "<LICENSE_KEY>",
204
+ "<BASE_URL>",
205
+ <LOG_LEVEL> // 0=off, 1=error, 2=warn, 3=info, 4=debug
206
+ );
207
+
208
+ // Start the Pointr SDK
209
+ NativeModules.PTRNativePointrLibrary.start((state: string) => {
210
+ console.log(`Pointr state: ${state}`);
211
+ });
166
212
 
167
- export const PTRMapWidget = requireNativeComponent<PTRMapWidgetProps>('PTRMapWidget');
213
+ // Create event emitter for Pointr events (optional)
214
+ const PTREventEmitter = NativeModules.PTRNativePointrLibrary;
215
+ const nativeEventEmitter = new NativeEventEmitter(PTREventEmitter);
168
216
  ```
169
217
 
170
218
  Implement the map widget in your React Native component:
171
219
 
172
220
  ```typescript
173
221
  function App(): React.JSX.Element {
174
-
175
- const ref = useRef(null);
222
+ const ref = useRef<any>(null);
176
223
 
177
- const handleMapWidgetDidEndLoading = (event: NativeSyntheticEvent<object>) => {
178
- const ptrCommand = event.nativeEvent;
179
- if (ptrCommand.command == "site") {
180
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.error);
181
- } else if (ptrCommand.command == "building") {
182
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.buildingExternalIdentifier, ptrCommand.error);
183
- } else if (ptrCommand.command == "level") {
184
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.buildingExternalIdentifier, ptrCommand.levelIndex, ptrCommand.error);
185
- } else if (ptrCommand.command == "poi") {
186
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.poiExternalIdentifier, ptrCommand.error);
187
- } else if (ptrCommand.command == "path") {
188
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.poiExternalIdentifier, ptrCommand.error);
189
- } else if (ptrCommand.command == "staticPath") {
190
- console.log("Map did end loading with parameters:", ptrCommand.command, ptrCommand.siteExternalIdentifier, ptrCommand.fromPoiExternalIdentifier, ptrCommand.toPoiExternalIdentifier, ptrCommand.error);
224
+ const handleMapWidgetDidEndLoading = (event: NativeSyntheticEvent<any>) => {
225
+ const ptrCommandResponse = event.nativeEvent;
226
+ if (ptrCommandResponse.command === "site") {
227
+ console.log("Map did end loading:", ptrCommandResponse.command, ptrCommandResponse.siteExternalIdentifier, ptrCommandResponse.error);
191
228
  } else {
192
- console.log("Map did end loading with unknown parameters:", ptrCommand);
229
+ console.log("Map did end loading with unknown parameters:", ptrCommandResponse);
230
+ }
231
+ };
232
+
233
+ const showSite = () => {
234
+ const reactTag = findNodeHandle(ref.current);
235
+ if (reactTag) {
236
+ let command = new PTRSiteCommand("your-site-id");
237
+ showMapWidget(reactTag, command);
238
+ } else {
239
+ console.error("Failed to find node handle for ref");
240
+ }
241
+ };
242
+
243
+ const showBuilding = () => {
244
+ const reactTag = findNodeHandle(ref.current);
245
+ if (reactTag) {
246
+ let command = new PTRBuildingCommand("your-site-id", "your-building-id");
247
+ showMapWidget(reactTag, command);
248
+ } else {
249
+ console.error("Failed to find node handle for ref");
250
+ }
251
+ };
252
+
253
+ const showLevel = () => {
254
+ const reactTag = findNodeHandle(ref.current);
255
+ if (reactTag) {
256
+ let command = new PTRLevelCommand("your-site-id", "your-building-id", 2);
257
+ showMapWidget(reactTag, command);
258
+ } else {
259
+ console.error("Failed to find node handle for ref");
260
+ }
261
+ };
262
+
263
+ const showPoi = () => {
264
+ const reactTag = findNodeHandle(ref.current);
265
+ if (reactTag) {
266
+ let command = new PTRPoiCommand("your-site-id", "your-poi-id");
267
+ showMapWidget(reactTag, command);
268
+ } else {
269
+ console.error("Failed to find node handle for ref");
270
+ }
271
+ };
272
+
273
+ const showPath = () => {
274
+ const reactTag = findNodeHandle(ref.current);
275
+ if (reactTag) {
276
+ let command = new PTRPathCommand("your-site-id", "your-poi-id");
277
+ showMapWidget(reactTag, command);
278
+ } else {
279
+ console.error("Failed to find node handle for ref");
280
+ }
281
+ };
282
+
283
+ const showStaticPath = () => {
284
+ const reactTag = findNodeHandle(ref.current);
285
+ if (reactTag) {
286
+ let command = new PTRStaticPathCommand("your-site-id", "from-poi-id", "to-poi-id");
287
+ showMapWidget(reactTag, command);
288
+ } else {
289
+ console.error("Failed to find node handle for ref");
290
+ }
291
+ };
292
+
293
+ const markMyCarLevel = () => {
294
+ const reactTag = findNodeHandle(ref.current);
295
+ if (reactTag) {
296
+ let command = new PTRMarkMyCarLevelCommand("your-site-id", "your-building-id", 1, true);
297
+ showMapWidget(reactTag, command);
298
+ } else {
299
+ console.error("Failed to find node handle for ref");
300
+ }
301
+ };
302
+
303
+ const markMyCarSite = () => {
304
+ const reactTag = findNodeHandle(ref.current);
305
+ if (reactTag) {
306
+ let command = new PTRMarkMyCarSiteCommand("your-site-id", true);
307
+ showMapWidget(reactTag, command);
308
+ } else {
309
+ console.error("Failed to find node handle for ref");
310
+ }
311
+ };
312
+
313
+ const showMyCarSite = () => {
314
+ const reactTag = findNodeHandle(ref.current);
315
+ if (reactTag) {
316
+ let command = new PTRShowMyCarSiteCommand("your-site-id", true);
317
+ showMapWidget(reactTag, command);
318
+ } else {
319
+ console.error("Failed to find node handle for ref");
320
+ }
321
+ };
322
+
323
+ const startAndFocusSite = () => {
324
+ const reactTag = findNodeHandle(ref.current);
325
+ if (reactTag) {
326
+ const siteCommand = new PTRSiteCommand("your-site-id");
327
+ const command = new PTRStartAndFocusCommand(
328
+ "your-client-id",
329
+ "your-license-key",
330
+ "your-base-url",
331
+ 0,
332
+ siteCommand
333
+ );
334
+ showMapWidget(reactTag, command);
335
+ } else {
336
+ console.error("Failed to find node handle for ref");
193
337
  }
194
338
  };
195
339
 
196
340
  return (
197
- <SafeAreaView style={{ flex: 1 }}>
198
- <ScrollView contentInsetAdjustmentBehavior="automatic" style={{ flex: 1 }}>
199
- <Button
200
- title="Show Site"
201
- onPress={() => {
202
- const reactTag = findNodeHandle(ref.current);
203
- console.log(`React tag: "${reactTag}" to show site`);
204
- if (reactTag !== null) {
205
- let command = new PTRSiteCommand("officebuilding");
206
- showMapWidget(reactTag, command);
207
- } else {
208
- console.error("Failed to find node handle for ref");
209
- }
210
- }}
211
- />
212
- <Button
213
- title="Show Building"
214
- onPress={() => {
215
- const reactTag = findNodeHandle(ref.current);
216
- console.log(`React tag: "${reactTag}" to show building`);
217
- if (reactTag !== null) {
218
- let command = new PTRBuildingCommand("officebuilding", "office2");
219
- showMapWidget(reactTag, command);
220
- } else {
221
- console.error("Failed to find node handle for ref");
222
- }
223
- }}
224
- />
225
- <Button
226
- title="Show level"
227
- onPress={() => {
228
- const reactTag = findNodeHandle(ref.current);
229
- console.log(`React tag: "${reactTag}" to show level`);
230
- if (reactTag !== null) {
231
- let command = new PTRLevelCommand("officebuilding", "office2", 2);
232
- showMapWidget(reactTag, command);
233
- } else {
234
- console.error("Failed to find node handle for ref");
235
- }
236
- }}
237
- />
238
- <Button
239
- title="Show Poi"
240
- onPress={() => {
241
- const reactTag = findNodeHandle(ref.current);
242
- console.log(`React tag: "${reactTag}" to show poi`);
243
- if (reactTag !== null) {
244
- let command = new PTRPoiCommand("officebuilding", "Accessories");
245
- showMapWidget(reactTag, command);
246
- } else {
247
- console.error("Failed to find node handle for ref");
248
- }
249
- }}
250
- />
251
- <Button
252
- title="Show path"
253
- onPress={() => {
254
- const reactTag = findNodeHandle(ref.current);
255
- console.log(`React tag: "${reactTag}" to show poi`);
256
- if (reactTag !== null) {
257
- let command = new PTRPathCommand("officebuilding", "Accessories");
258
- showMapWidget(reactTag, command);
259
- } else {
260
- console.error("Failed to find node handle for ref");
261
- }
262
- }}
263
- />
264
- <Button
265
- title="Show Static Path"
266
- onPress={() => {
267
- const reactTag = findNodeHandle(ref.current);
268
- console.log(`React tag: "${reactTag}" to show site`);
269
- if (reactTag !== null) {
270
- let command = new PTRStaticPathCommand("officebuilding", "Accessories", "Lobby");
271
- showMapWidget(reactTag, command);
272
- } else {
273
- console.error("Failed to find node handle for ref");
274
- }
275
- }}
276
- />
277
- </ScrollView>
278
- <View style={{ flex: 5 }}>
279
- <PTRMapWidget ref={ref} style={{ flex: 1 }} onMapWidgetDidEndLoading={handleMapWidgetDidEndLoading} />
341
+ <SafeAreaView style={{ flex: 1 }}>
342
+ <View style={{ flex: 1 }}>
343
+ <ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16 }}>
344
+ <Button title="Show Site" onPress={showSite} />
345
+ <View style={{ height: 12 }} />
346
+ <Button title="Show Building" onPress={showBuilding} />
347
+ <View style={{ height: 12 }} />
348
+ <Button title="Show Level" onPress={showLevel} />
349
+ <View style={{ height: 12 }} />
350
+ <Button title="Show POI" onPress={showPoi} />
351
+ <View style={{ height: 12 }} />
352
+ <Button title="Show Path" onPress={showPath} />
353
+ <View style={{ height: 12 }} />
354
+ <Button title="Show Static Path" onPress={showStaticPath} />
355
+ <View style={{ height: 12 }} />
356
+ <Button title="Mark My Car Level" onPress={markMyCarLevel} />
357
+ <View style={{ height: 12 }} />
358
+ <Button title="Mark My Car Site" onPress={markMyCarSite} />
359
+ <View style={{ height: 12 }} />
360
+ <Button title="Show My Car Site" onPress={showMyCarSite} />
361
+ <View style={{ height: 12 }} />
362
+ <Button title="Start & Focus Site" onPress={startAndFocusSite} />
363
+ </ScrollView>
280
364
  </View>
365
+ <PTRMapWidget
366
+ ref={ref}
367
+ style={{ flex: 4 }}
368
+ onMapWidgetDidEndLoading={handleMapWidgetDidEndLoading}
369
+ />
281
370
  </SafeAreaView>
282
371
  );
283
372
  }
@@ -285,6 +374,21 @@ function App(): React.JSX.Element {
285
374
  export default App;
286
375
  ```
287
376
 
377
+ ### Available Commands
378
+
379
+ The package provides several command types for interacting with the map:
380
+
381
+ - **PTRSiteCommand**: Display a specific site
382
+ - **PTRBuildingCommand**: Display a specific building within a site
383
+ - **PTRLevelCommand**: Display a specific level of a building
384
+ - **PTRPoiCommand**: Display and focus on a specific point of interest (POI)
385
+ - **PTRPathCommand**: Display a navigation path from the current location to a POI
386
+ - **PTRStaticPathCommand**: Display a navigation path between two POIs
387
+ - **PTRMarkMyCarLevelCommand**: Mark car location at a specific level
388
+ - **PTRMarkMyCarSiteCommand**: Mark car location at site level
389
+ - **PTRShowMyCarSiteCommand**: Show marked car location on the site
390
+ - **PTRStartAndFocusCommand**: Initialize SDK and focus on a location in one command
391
+
288
392
  For more information about the available functionality, check the [API documentation](https://docs.pointr.tech/docs/8.x/Developer%20Portal/API%20Reference/api%20ref-mobile/).
289
393
 
290
394
  ## 5. Run the App
@@ -0,0 +1,243 @@
1
+ # Wayfinding Events
2
+
3
+ This document describes how to use the `onWayfindingEvent` callback to track wayfinding navigation events in the Pointr Map Widget.
4
+
5
+ ## Overview
6
+
7
+ The `onWayfindingEvent` callback is triggered during wayfinding operations, providing information about the navigation state and destination. This allows you to track when users start, cancel, or complete navigation to a Point of Interest (POI).
8
+
9
+ ## Event Structure
10
+
11
+ The `PTRWayfindingEvent` type is exported from the `react-native-pointr` package and contains the following data:
12
+
13
+ ```typescript
14
+ import { type PTRWayfindingEvent } from 'react-native-pointr';
15
+
16
+ // PTRWayfindingEvent structure:
17
+ {
18
+ type: number; // Event type indicator (-1, 0, or 1)
19
+ poi: PTRPoi; // Destination POI information
20
+ }
21
+ ```
22
+
23
+ For the complete type definition, see [PTRWayfindingEvent.ts](./src/types/PTRWayfindingEvent.ts).
24
+
25
+ ### Event Types
26
+
27
+ | Type | Value | Description |
28
+ |------|-------|-------------|
29
+ | Cancelled | `-1` | User cancelled the wayfinding navigation |
30
+ | Started | `0` | Wayfinding navigation has started |
31
+ | Ended | `1` | User completed or closed the wayfinding navigation |
32
+
33
+ ### POI Object
34
+
35
+ The `poi` field is a `PTRPoi` object that contains complete information about the destination:
36
+
37
+ ```typescript
38
+ import { type PTRPoi } from 'react-native-pointr';
39
+
40
+ // PTRPoi structure:
41
+ {
42
+ identifier: string; // Internal unique identifier
43
+ externalIdentifier: string; // External API reference ID
44
+ name: string; // Display name
45
+ typeCode: string; // POI type (e.g., "lobby", "room")
46
+ position: PTRPosition; // Geographic position
47
+ geometry: PTRGeometry; // Shape data
48
+ attributes: PTRPoiAttributes; // Additional metadata
49
+ }
50
+ ```
51
+
52
+ For the complete type definition, see [PTRPoi.ts](./src/types/PTRPoi.ts).
53
+
54
+ ## Usage
55
+
56
+ ### 1. Import Required Types
57
+
58
+ First, import the necessary types from the package:
59
+
60
+ ```typescript
61
+ import { type PTRPoi, type PTRWayfindingEvent } from 'react-native-pointr';
62
+ ```
63
+
64
+ ### 2. Create Event Handler
65
+
66
+ Implement the handler function to process wayfinding events:
67
+
68
+ ```typescript
69
+ const handleWayfindingEvent = (event: NativeSyntheticEvent<PTRWayfindingEvent>) => {
70
+ const wayfindingEvent = event.nativeEvent;
71
+
72
+ // Determine event type
73
+ let eventTypeName: string;
74
+ switch (wayfindingEvent.type) {
75
+ case -1:
76
+ eventTypeName = 'Cancelled';
77
+ // Handle cancellation (e.g., update UI, analytics)
78
+ break;
79
+ case 0:
80
+ eventTypeName = 'Started';
81
+ // Handle start (e.g., show navigation UI)
82
+ break;
83
+ case 1:
84
+ eventTypeName = 'Ended';
85
+ // Handle completion (e.g., hide navigation UI, show success)
86
+ break;
87
+ default:
88
+ eventTypeName = 'Unknown';
89
+ }
90
+
91
+ // Access destination POI information
92
+ console.log(`Navigation ${eventTypeName} to: ${wayfindingEvent.poi.name}`);
93
+ console.log(`POI Type: ${wayfindingEvent.poi.typeCode}`);
94
+ console.log(`Location: Level ${wayfindingEvent.poi.position.lvl}`);
95
+ };
96
+ ```
97
+
98
+ ### 3. Attach to Map Widget
99
+
100
+ Attach the handler to the PTRMapWidget component:
101
+
102
+ ```typescript
103
+ <PTRMapWidget
104
+ ref={mapWidgetRef}
105
+ style={{ flex: 1 }}
106
+ onWayfindingEvent={handleWayfindingEvent}
107
+ />
108
+ ```
109
+
110
+ ## Complete Example
111
+
112
+ ```typescript
113
+ import React, { useRef } from 'react';
114
+ import {
115
+ requireNativeComponent,
116
+ NativeSyntheticEvent,
117
+ View,
118
+ } from 'react-native';
119
+ import { type PTRPoi, type PTRWayfindingEvent } from 'react-native-pointr';
120
+
121
+ interface PTRMapWidgetProps {
122
+ style?: any;
123
+ onWayfindingEvent?: (event: NativeSyntheticEvent<PTRWayfindingEvent>) => void;
124
+ }
125
+
126
+ const PTRMapWidget = requireNativeComponent<PTRMapWidgetProps>('PTRMapWidget');
127
+
128
+ function MapScreen() {
129
+ const mapWidgetRef = useRef<any>(null);
130
+
131
+ const handleWayfindingEvent = (event: NativeSyntheticEvent<PTRWayfindingEvent>) => {
132
+ const { type, poi } = event.nativeEvent;
133
+
134
+ switch (type) {
135
+ case -1:
136
+ console.log(`User cancelled navigation to ${poi.name}`);
137
+ // Update your app state - navigation was cancelled
138
+ break;
139
+ case 0:
140
+ console.log(`Started navigation to ${poi.name} at level ${poi.position.lvl}`);
141
+ // Update your app state - show navigation in progress
142
+ break;
143
+ case 1:
144
+ console.log(`Completed navigation to ${poi.name}`);
145
+ // Update your app state - navigation finished
146
+ break;
147
+ }
148
+ };
149
+
150
+ return (
151
+ <View style={{ flex: 1 }}>
152
+ <PTRMapWidget
153
+ ref={mapWidgetRef}
154
+ style={{ flex: 1 }}
155
+ onWayfindingEvent={handleWayfindingEvent}
156
+ />
157
+ </View>
158
+ );
159
+ }
160
+
161
+ export default MapScreen;
162
+ ```
163
+
164
+ ## Use Cases
165
+
166
+ ### Analytics Tracking
167
+
168
+ Track navigation patterns and popular destinations:
169
+
170
+ ```typescript
171
+ const handleWayfindingEvent = (event: NativeSyntheticEvent<PTRWayfindingEvent>) => {
172
+ const { type, poi } = event.nativeEvent;
173
+
174
+ // Log to analytics service
175
+ analytics.track('Wayfinding Event', {
176
+ eventType: type === -1 ? 'cancelled' : type === 0 ? 'started' : 'ended',
177
+ destinationName: poi.name,
178
+ destinationType: poi.typeCode,
179
+ destinationId: poi.externalIdentifier,
180
+ });
181
+ };
182
+ ```
183
+
184
+ ### UI State Management
185
+
186
+ Update your UI based on navigation state:
187
+
188
+ ```typescript
189
+ const [isNavigating, setIsNavigating] = useState(false);
190
+ const [currentDestination, setCurrentDestination] = useState<string | null>(null);
191
+
192
+ const handleWayfindingEvent = (event: NativeSyntheticEvent<PTRWayfindingEvent>) => {
193
+ const { type, poi } = event.nativeEvent;
194
+
195
+ switch (type) {
196
+ case 0: // Started
197
+ setIsNavigating(true);
198
+ setCurrentDestination(poi.name);
199
+ break;
200
+ case -1: // Cancelled
201
+ case 1: // Ended
202
+ setIsNavigating(false);
203
+ setCurrentDestination(null);
204
+ break;
205
+ }
206
+ };
207
+ ```
208
+
209
+ ### Custom Notifications
210
+
211
+ Show custom notifications based on events:
212
+
213
+ ```typescript
214
+ import { Alert } from 'react-native';
215
+
216
+ const handleWayfindingEvent = (event: NativeSyntheticEvent<PTRWayfindingEvent>) => {
217
+ const { type, poi } = event.nativeEvent;
218
+
219
+ if (type === 1) { // Ended
220
+ Alert.alert(
221
+ 'Navigation Complete',
222
+ `You have arrived at ${poi.name}`,
223
+ [{ text: 'OK' }]
224
+ );
225
+ }
226
+ };
227
+ ```
228
+
229
+ ## Notes
230
+
231
+ - The event is fired automatically by the native map widget during wayfinding operations
232
+ - The POI object contains complete destination information including position, geometry, and custom attributes
233
+ - Event types are consistent across both iOS and Android platforms
234
+ - The event fires regardless of how wayfinding was initiated (tap, programmatic command, etc.)
235
+
236
+ ## Related Documentation
237
+
238
+ - [PTRWayfindingEvent Type Definition](./src/types/PTRWayfindingEvent.ts)
239
+ - [PTRPoi Type Definition](./src/types/PTRPoi.ts)
240
+ - [PTRPosition Type Definition](./src/types/PTRPosition.ts)
241
+ - [PTRGeometry Type Definition](./src/types/PTRGeometry.ts)
242
+ - [PTR Commands](./src/PTRCommand.ts)
243
+ - [API Reference](./API_REFERENCE.md)
@@ -1,6 +1,6 @@
1
1
  buildscript {
2
2
  // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
- def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : "1.9.24"
3
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : "2.2.21"
4
4
 
5
5
  repositories {
6
6
  google()
@@ -8,23 +8,10 @@ buildscript {
8
8
  }
9
9
 
10
10
  dependencies {
11
- classpath "com.android.tools.build:gradle:8.10.1"
12
11
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13
12
  }
14
13
  }
15
14
 
16
- allprojects {
17
- repositories {
18
- maven {
19
- url "https://android.pointr.dev/artifactory/gradle-release-local"
20
- credentials {
21
- username 'consumer'
22
- password 'AKCp5dKiUPiSx94yLYgSsu6WzM4MaMAohkrpPyDydQgnNsUajTmhBXLzqLVkwJPNFNZzzv5Rt'
23
- }
24
- }
25
- }
26
- }
27
-
28
15
  def reactNativeArchitectures() {
29
16
  def value = rootProject.getProperties().get("reactNativeArchitectures")
30
17
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
@@ -98,7 +85,7 @@ repositories {
98
85
  google()
99
86
  }
100
87
 
101
- def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : "1.9.24"
88
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : "2.2.21"
102
89
 
103
90
  dependencies {
104
91
  // For < 0.71, this will be from the local maven repo
@@ -106,7 +93,7 @@ dependencies {
106
93
  //noinspection GradleDynamicVersion
107
94
  implementation "com.facebook.react:react-native:+"
108
95
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
109
- implementation("com.pointrlabs:pointr:9.1.0")
96
+ implementation("com.pointrlabs:pointr:9.3.0")
110
97
  implementation ("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")
111
98
  implementation 'com.google.android.material:material:1.12.0'
112
99
  implementation 'androidx.constraintlayout:constraintlayout:2.2.1'