react-native-pointr 9.5.0 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API_REFERENCE.md +1035 -557
- package/CHANGELOG.md +12 -0
- package/README.md +75 -216
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/pointr/PTRMapWidgetManager.kt +156 -0
- package/ios/PTRMapWidgetContainerView.swift +179 -1
- package/ios/PTRMapWidgetManager-Bridging.m +6 -0
- package/ios/PTRNativeLibrary.swift +14 -0
- package/package.json +30 -6
- package/react-native-pointr.podspec +1 -1
- package/src/PTRMapWidgetUtils.ts +2 -8
- package/src/api/MapWidgetApi.ts +45 -0
- package/src/api/PointrSdk.ts +241 -0
- package/src/api/index.ts +9 -0
- package/src/commands/index.ts +275 -0
- package/src/components/index.tsx +130 -0
- package/src/constants/index.ts +104 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/usePointrEvents.ts +40 -0
- package/src/hooks/usePointrPois.ts +41 -0
- package/src/hooks/usePointrPosition.ts +31 -0
- package/src/hooks/usePointrSdk.ts +41 -0
- package/src/index.tsx +87 -7
- package/src/{PTRPoiManager.ts → managers/PTRPoiManager.ts} +1 -1
- package/src/types/config.ts +57 -0
- package/src/types/events.ts +106 -0
- package/src/types/index.ts +35 -0
- package/.vscode/settings.json +0 -21
- package/example/pointr_rn_demo/.bundle/config +0 -2
- package/example/pointr_rn_demo/.eslintrc.js +0 -4
- package/example/pointr_rn_demo/.prettierrc.js +0 -5
- package/example/pointr_rn_demo/.watchmanconfig +0 -1
- package/example/pointr_rn_demo/App.tsx +0 -323
- package/example/pointr_rn_demo/Gemfile +0 -16
- package/example/pointr_rn_demo/Gemfile.lock +0 -111
- package/example/pointr_rn_demo/README.md +0 -188
- package/example/pointr_rn_demo/__tests__/App.test.tsx +0 -13
- package/example/pointr_rn_demo/android/app/build.gradle +0 -119
- package/example/pointr_rn_demo/android/app/debug.keystore +0 -0
- package/example/pointr_rn_demo/android/app/proguard-rules.pro +0 -10
- package/example/pointr_rn_demo/android/app/src/main/AndroidManifest.xml +0 -27
- package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainActivity.kt +0 -22
- package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainApplication.kt +0 -27
- package/example/pointr_rn_demo/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -37
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/values/strings.xml +0 -3
- package/example/pointr_rn_demo/android/app/src/main/res/values/styles.xml +0 -9
- package/example/pointr_rn_demo/android/build.gradle +0 -34
- package/example/pointr_rn_demo/android/gradle.properties +0 -44
- package/example/pointr_rn_demo/android/settings.gradle +0 -6
- package/example/pointr_rn_demo/app.json +0 -4
- package/example/pointr_rn_demo/babel.config.js +0 -3
- package/example/pointr_rn_demo/index.js +0 -16
- package/example/pointr_rn_demo/ios/.xcode.env +0 -11
- package/example/pointr_rn_demo/ios/Podfile +0 -40
- package/example/pointr_rn_demo/ios/pointr_rn_demo/AppDelegate.swift +0 -48
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/Contents.json +0 -6
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Info.plist +0 -63
- package/example/pointr_rn_demo/ios/pointr_rn_demo/LaunchScreen.storyboard +0 -47
- package/example/pointr_rn_demo/ios/pointr_rn_demo/PrivacyInfo.xcprivacy +0 -37
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/project.pbxproj +0 -488
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/xcshareddata/xcschemes/pointr_rn_demo.xcscheme +0 -88
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcworkspace/contents.xcworkspacedata +0 -10
- package/example/pointr_rn_demo/jest.config.js +0 -3
- package/example/pointr_rn_demo/metro.config.js +0 -22
- package/example/pointr_rn_demo/package.json +0 -47
- package/example/pointr_rn_demo/prepare-demo-distribution.sh +0 -103
- package/example/pointr_rn_demo/tsconfig.json +0 -5
- package/prepare-distribution.sh +0 -151
package/API_REFERENCE.md
CHANGED
|
@@ -3,287 +3,535 @@
|
|
|
3
3
|
> **Platform Compatibility:** This API reference is identical for both Android and iOS platforms. All methods, parameters, and behaviors are consistent across platforms.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
|
-
- [
|
|
7
|
-
- [
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
6
|
+
- [Quick Start](#quick-start)
|
|
7
|
+
- [PointrSdk Class](#pointrsdk-class)
|
|
8
|
+
- [executeMapCommand](#executemapcommand)
|
|
9
|
+
- [React Hooks](#react-hooks)
|
|
10
|
+
- [PTRMapWidget Component](#ptrmapwidget-component)
|
|
11
|
+
- [Constants & Enums](#constants--enums)
|
|
12
|
+
- [Command Classes](#command-classes)
|
|
13
|
+
- [Types](#types)
|
|
10
14
|
- [Event Listeners](#event-listeners)
|
|
15
|
+
- [Complete Example](#complete-example)
|
|
16
|
+
- [Legacy API](#legacy-api)
|
|
17
|
+
- [Error Handling](#error-handling)
|
|
11
18
|
|
|
12
19
|
---
|
|
13
20
|
|
|
14
|
-
##
|
|
21
|
+
## Quick Start
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
The library now exposes two API layers:
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
| Layer | When to use |
|
|
26
|
+
|-------|-------------|
|
|
27
|
+
| **New API** (`PointrSdk`, `usePointrSdk`, `PTRMapWidget` declarative props) | All new integration work |
|
|
28
|
+
| **Legacy API** (`NativeModules.PTRNativePointrLibrary`, `showMapWidget`) | Existing code — still fully supported |
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
**Minimal declarative setup (new API):**
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
```tsx
|
|
33
|
+
import { PTRMapWidget, PTRSiteCommand } from 'react-native-pointr';
|
|
34
|
+
import type { PTRConfiguration } from 'react-native-pointr';
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
const SDK_CONFIG: PTRConfiguration = {
|
|
37
|
+
clientId: '<CLIENT_ID>',
|
|
38
|
+
licenseKey: '<LICENSE_KEY>',
|
|
39
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default function MapScreen() {
|
|
43
|
+
return (
|
|
44
|
+
<PTRMapWidget
|
|
45
|
+
style={{ flex: 1 }}
|
|
46
|
+
sdkConfig={SDK_CONFIG}
|
|
47
|
+
command={new PTRSiteCommand('<SITE_EXTERNAL_ID>')}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## PointrSdk Class
|
|
56
|
+
|
|
57
|
+
`PointrSdk` is a singleton class that wraps the native module and provides a clean, typed interface for SDK lifecycle management.
|
|
58
|
+
|
|
59
|
+
### Importing
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { PointrSdk, pointrSdk } from 'react-native-pointr';
|
|
63
|
+
|
|
64
|
+
// Use the pre-created singleton (recommended)
|
|
65
|
+
pointrSdk.initialize({ ... });
|
|
66
|
+
|
|
67
|
+
// Or obtain the singleton instance explicitly
|
|
68
|
+
const sdk = PointrSdk.getInstance();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Methods
|
|
72
|
+
|
|
73
|
+
#### `initialize(config)`
|
|
74
|
+
|
|
75
|
+
Initializes the SDK. Must be called before `start()`.
|
|
25
76
|
|
|
26
77
|
**Parameters:**
|
|
27
|
-
- `
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- `logLevel` (number): Log level (0-4)
|
|
31
|
-
- `0`: Verbose
|
|
32
|
-
- `1`: Debug
|
|
33
|
-
- `2`: Info
|
|
34
|
-
- `3`: Warning
|
|
35
|
-
- `4`: Error
|
|
78
|
+
- `config` (`PTRConfiguration`): SDK credentials and options
|
|
79
|
+
|
|
80
|
+
**Throws:** `Error` if already initialized or if required fields are missing.
|
|
36
81
|
|
|
37
|
-
**Example:**
|
|
38
82
|
```typescript
|
|
39
|
-
import {
|
|
83
|
+
import { pointrSdk, PTRLogLevel } from 'react-native-pointr';
|
|
40
84
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
);
|
|
85
|
+
pointrSdk.initialize({
|
|
86
|
+
clientId: '<CLIENT_ID>',
|
|
87
|
+
licenseKey: '<LICENSE_KEY>',
|
|
88
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
89
|
+
logLevel: PTRLogLevel.WARNING, // optional, defaults to ERROR
|
|
90
|
+
});
|
|
47
91
|
```
|
|
48
92
|
|
|
49
93
|
---
|
|
50
94
|
|
|
51
|
-
|
|
95
|
+
#### `start(callback?)`
|
|
52
96
|
|
|
53
|
-
Starts the
|
|
97
|
+
Starts the SDK. SDK must be initialized first.
|
|
54
98
|
|
|
55
99
|
**Parameters:**
|
|
56
|
-
- `callback` (
|
|
100
|
+
- `callback` (`PTRStateCallback`, optional): Receives the native state string when the SDK is running.
|
|
101
|
+
|
|
102
|
+
**Throws:** `Error` if not initialized.
|
|
57
103
|
|
|
58
|
-
**Example:**
|
|
59
104
|
```typescript
|
|
60
|
-
|
|
61
|
-
console.log(
|
|
105
|
+
pointrSdk.start((state) => {
|
|
106
|
+
console.log('Native state:', state); // e.g. "running"
|
|
62
107
|
});
|
|
63
108
|
```
|
|
64
109
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
#### `stop()`
|
|
113
|
+
|
|
114
|
+
Stops the SDK when it is in the `RUNNING` state.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
pointrSdk.stop();
|
|
118
|
+
```
|
|
72
119
|
|
|
73
120
|
---
|
|
74
121
|
|
|
75
|
-
|
|
122
|
+
#### `getState()`
|
|
76
123
|
|
|
77
|
-
|
|
124
|
+
Returns the current `PTRState` enum value.
|
|
78
125
|
|
|
79
|
-
**Example:**
|
|
80
126
|
```typescript
|
|
81
|
-
|
|
127
|
+
const state: PTRState = pointrSdk.getState();
|
|
82
128
|
```
|
|
83
129
|
|
|
84
130
|
---
|
|
85
131
|
|
|
86
|
-
|
|
132
|
+
#### `isInitialized()`
|
|
87
133
|
|
|
88
|
-
|
|
134
|
+
Returns `true` if the SDK has been initialized (any state other than `NOT_INITIALIZED`).
|
|
89
135
|
|
|
90
|
-
**Example:**
|
|
91
136
|
```typescript
|
|
92
|
-
|
|
137
|
+
if (pointrSdk.isInitialized()) { ... }
|
|
93
138
|
```
|
|
94
139
|
|
|
95
140
|
---
|
|
96
141
|
|
|
97
|
-
|
|
142
|
+
#### `isStarted()`
|
|
98
143
|
|
|
99
|
-
|
|
144
|
+
Returns `true` only if the SDK is in the `RUNNING` state.
|
|
100
145
|
|
|
101
|
-
|
|
102
|
-
|
|
146
|
+
```typescript
|
|
147
|
+
if (pointrSdk.isStarted()) { ... }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
#### `getConfig()`
|
|
153
|
+
|
|
154
|
+
Returns the `PTRConfiguration` passed to `initialize()`, or `null` if not yet initialized.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const config = pointrSdk.getConfig();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
#### `getCurrentLocation()`
|
|
163
|
+
|
|
164
|
+
Returns a `Promise<any | null>` with the last known calculated position, or `null` if unavailable.
|
|
165
|
+
|
|
166
|
+
The resolved object contains the raw native payload with these fields:
|
|
167
|
+
|
|
168
|
+
| Field | Type | Description |
|
|
169
|
+
|-------|------|-------------|
|
|
170
|
+
| `latitude` | number | Latitude |
|
|
171
|
+
| `longitude` | number | Longitude |
|
|
172
|
+
| `levelIndex` | number | Level index |
|
|
173
|
+
| `siteInternalIdentifier` | string | Site internal ID |
|
|
174
|
+
| `siteExternalIdentifier` | string | Site external ID |
|
|
175
|
+
| `buildingInternalIdentifier` | string | Building internal ID |
|
|
176
|
+
| `buildingExternalIdentifier` | string | Building external ID |
|
|
177
|
+
| `accuracy` | number | Accuracy in meters (optional) |
|
|
178
|
+
| `heading` | number | Heading in degrees (optional, only when accuracy is high) |
|
|
103
179
|
|
|
104
|
-
**Example:**
|
|
105
180
|
```typescript
|
|
106
|
-
|
|
181
|
+
const loc = await pointrSdk.getCurrentLocation();
|
|
182
|
+
if (loc) {
|
|
183
|
+
console.log(loc.latitude, loc.longitude, loc.levelIndex);
|
|
184
|
+
}
|
|
107
185
|
```
|
|
108
186
|
|
|
109
187
|
---
|
|
110
188
|
|
|
111
|
-
|
|
189
|
+
#### `setMapWidgetConfiguration(config)`
|
|
112
190
|
|
|
113
|
-
|
|
191
|
+
Applies map widget UI settings. Must be called before the `PTRMapWidget` renders to take effect.
|
|
114
192
|
|
|
115
193
|
**Parameters:**
|
|
116
|
-
- `
|
|
194
|
+
- `config` (`PTRMapWidgetConfiguration`): UI feature toggles
|
|
117
195
|
|
|
118
|
-
**Example:**
|
|
119
196
|
```typescript
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
console.log('Level:', location.levelIndex);
|
|
125
|
-
console.log('Coordinates:', location.latitude, location.longitude);
|
|
126
|
-
}
|
|
197
|
+
pointrSdk.setMapWidgetConfiguration({
|
|
198
|
+
isLevelSelectorEnabled: true,
|
|
199
|
+
isJoystickEnabled: true,
|
|
200
|
+
isExitButtonEnabled: false,
|
|
127
201
|
});
|
|
128
202
|
```
|
|
129
203
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
#### `onPositionUpdate(callback)`
|
|
207
|
+
|
|
208
|
+
Subscribes to `OnPositionManagerCalculatedLocation` events. Returns a subscription object with a `.remove()` method.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const sub = pointrSdk.onPositionUpdate((pos) => {
|
|
212
|
+
console.log(pos);
|
|
213
|
+
});
|
|
214
|
+
// later:
|
|
215
|
+
sub.remove();
|
|
216
|
+
```
|
|
140
217
|
|
|
141
218
|
---
|
|
142
219
|
|
|
143
|
-
|
|
220
|
+
#### `onBuildingClick(callback)`
|
|
144
221
|
|
|
145
|
-
|
|
222
|
+
Subscribes to `OnBuildingClicked` events.
|
|
146
223
|
|
|
147
|
-
|
|
148
|
-
|
|
224
|
+
```typescript
|
|
225
|
+
const sub = pointrSdk.onBuildingClick((event) => {
|
|
226
|
+
console.log(event.internalIdentifier, event.title);
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
#### `onSiteClick(callback)`
|
|
233
|
+
|
|
234
|
+
Subscribes to `OnSiteClicked` events.
|
|
149
235
|
|
|
150
|
-
**Example:**
|
|
151
236
|
```typescript
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
237
|
+
const sub = pointrSdk.onSiteClick((event) => {
|
|
238
|
+
console.log(event.internalIdentifier, event.title);
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
#### `onGeofenceEvent(callback)`
|
|
245
|
+
|
|
246
|
+
Subscribes to `OnGeofenceEvent` events.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
const sub = pointrSdk.onGeofenceEvent((event) => {
|
|
250
|
+
console.log(event.eventType, event.geofence?.name);
|
|
158
251
|
});
|
|
159
252
|
```
|
|
160
253
|
|
|
161
254
|
---
|
|
162
255
|
|
|
163
|
-
|
|
256
|
+
#### `getEventEmitter()`
|
|
257
|
+
|
|
258
|
+
Returns the underlying `NativeEventEmitter` for advanced subscription use cases.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const emitter = pointrSdk.getEventEmitter();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
#### `getNativeModule()`
|
|
267
|
+
|
|
268
|
+
Returns the raw `NativeModules.PTRNativePointrLibrary` reference for advanced use cases.
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const native = pointrSdk.getNativeModule();
|
|
272
|
+
native.requestPermissions();
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## executeMapCommand
|
|
164
278
|
|
|
165
|
-
|
|
279
|
+
A convenience function that resolves `findNodeHandle` internally and dispatches a command to the native map widget.
|
|
280
|
+
|
|
281
|
+
**Import:**
|
|
282
|
+
```typescript
|
|
283
|
+
import { executeMapCommand } from 'react-native-pointr';
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Signature:**
|
|
287
|
+
```typescript
|
|
288
|
+
function executeMapCommand(
|
|
289
|
+
mapRef: React.RefObject<any> | any,
|
|
290
|
+
command: PTRCommand
|
|
291
|
+
): void
|
|
292
|
+
```
|
|
166
293
|
|
|
167
294
|
**Parameters:**
|
|
168
|
-
- `
|
|
295
|
+
- `mapRef`: A React ref (or any object with a `.current` property) pointing to the rendered `PTRMapWidget`.
|
|
296
|
+
- `command`: Any `PTRCommand` subclass instance.
|
|
297
|
+
|
|
298
|
+
**Throws:** `Error` if `mapRef` is null, the native view tag cannot be resolved, or the command is invalid.
|
|
169
299
|
|
|
170
300
|
**Example:**
|
|
171
301
|
```typescript
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
isLevelSelectorEnabled: true,
|
|
178
|
-
isMyCarButtonEnabled: true
|
|
179
|
-
})
|
|
180
|
-
);
|
|
181
|
-
```
|
|
302
|
+
import { useRef } from 'react';
|
|
303
|
+
import { PTRMapWidget, PTRPoiCommand, executeMapCommand } from 'react-native-pointr';
|
|
304
|
+
|
|
305
|
+
function MyMap() {
|
|
306
|
+
const mapRef = useRef(null);
|
|
182
307
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
308
|
+
const navigateToLobby = () => {
|
|
309
|
+
executeMapCommand(mapRef, new PTRPoiCommand('<SITE_ID>', 'Lobby'));
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
return <PTRMapWidget ref={mapRef} style={{ flex: 1 }} />;
|
|
313
|
+
}
|
|
314
|
+
```
|
|
190
315
|
|
|
191
316
|
---
|
|
192
317
|
|
|
193
|
-
|
|
318
|
+
## React Hooks
|
|
194
319
|
|
|
195
|
-
|
|
320
|
+
All hooks are exported from `react-native-pointr`.
|
|
321
|
+
|
|
322
|
+
### `usePointrSdk(config?)`
|
|
323
|
+
|
|
324
|
+
Manages SDK initialization and startup. When `config` is provided the hook initializes and starts the SDK automatically on mount.
|
|
196
325
|
|
|
197
326
|
**Parameters:**
|
|
198
|
-
- `
|
|
327
|
+
- `config` (`PTRConfiguration`, optional): When supplied, triggers `initialize` + `start` automatically.
|
|
199
328
|
|
|
200
|
-
**Returns:**
|
|
329
|
+
**Returns:**
|
|
330
|
+
```typescript
|
|
331
|
+
{
|
|
332
|
+
sdk: PointrSdk; // The singleton SDK instance
|
|
333
|
+
state: PTRState; // Current SDK state
|
|
334
|
+
isInitialized: boolean;
|
|
335
|
+
isStarted: boolean;
|
|
336
|
+
error: Error | null;
|
|
337
|
+
}
|
|
338
|
+
```
|
|
201
339
|
|
|
202
340
|
**Example:**
|
|
203
341
|
```typescript
|
|
204
|
-
import {
|
|
342
|
+
import { usePointrSdk } from 'react-native-pointr';
|
|
205
343
|
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
console.log(`${poi.name} (${poi.typeCode})`);
|
|
212
|
-
console.log(` Location: ${poi.position.lat}, ${poi.position.lon}`);
|
|
213
|
-
console.log(` Level: ${poi.position.lvl}`);
|
|
344
|
+
function App() {
|
|
345
|
+
const { sdk, isStarted, state, error } = usePointrSdk({
|
|
346
|
+
clientId: '<CLIENT_ID>',
|
|
347
|
+
licenseKey: '<LICENSE_KEY>',
|
|
348
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
214
349
|
});
|
|
215
|
-
|
|
216
|
-
|
|
350
|
+
|
|
351
|
+
// sdk is available immediately; isStarted turns true once the SDK is running
|
|
217
352
|
}
|
|
218
353
|
```
|
|
219
354
|
|
|
220
|
-
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### `usePointrPosition(enabled?)`
|
|
358
|
+
|
|
359
|
+
Listens to live position updates from the SDK.
|
|
360
|
+
|
|
361
|
+
**Parameters:**
|
|
362
|
+
- `enabled` (boolean, default: `true`): Set to `false` to pause the subscription without unmounting.
|
|
363
|
+
|
|
364
|
+
**Returns:** The raw native position event or `null`. The payload fields match those described under [`getCurrentLocation()`](#getcurrentlocation).
|
|
365
|
+
|
|
221
366
|
```typescript
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
attributes: PTRPoiAttributes; // Metadata
|
|
367
|
+
import { usePointrPosition } from 'react-native-pointr';
|
|
368
|
+
|
|
369
|
+
function PositionView() {
|
|
370
|
+
const position = usePointrPosition();
|
|
371
|
+
if (position) {
|
|
372
|
+
console.log(position.latitude, position.longitude, position.levelIndex);
|
|
373
|
+
}
|
|
230
374
|
}
|
|
375
|
+
```
|
|
231
376
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
### `usePointrPois(siteId?)`
|
|
380
|
+
|
|
381
|
+
Fetches and manages the POI list for a given site.
|
|
382
|
+
|
|
383
|
+
**Parameters:**
|
|
384
|
+
- `siteId` (string, optional): External site identifier. POIs are fetched when this value changes.
|
|
385
|
+
|
|
386
|
+
**Returns:**
|
|
387
|
+
```typescript
|
|
388
|
+
{
|
|
389
|
+
pois: PTRPoi[];
|
|
390
|
+
loading: boolean;
|
|
391
|
+
error: Error | null;
|
|
392
|
+
refetch: () => void;
|
|
239
393
|
}
|
|
394
|
+
```
|
|
240
395
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
[key: string]: any; // Other attributes
|
|
396
|
+
```typescript
|
|
397
|
+
import { usePointrPois } from 'react-native-pointr';
|
|
398
|
+
|
|
399
|
+
function PoiList() {
|
|
400
|
+
const { pois, loading, error } = usePointrPois('<SITE_ID>');
|
|
247
401
|
}
|
|
248
402
|
```
|
|
249
403
|
|
|
250
404
|
---
|
|
251
405
|
|
|
252
|
-
|
|
406
|
+
### `usePointrGeofence(callback)`
|
|
253
407
|
|
|
254
|
-
|
|
408
|
+
Subscribes to geofence events for the lifetime of the component.
|
|
255
409
|
|
|
256
|
-
|
|
410
|
+
**Parameters:**
|
|
411
|
+
- `callback` (`(event: PTRGeofenceEvent) => void`): Called on every geofence enter/exit event.
|
|
257
412
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
- `onMapWidgetDidEndLoading` (function): Callback when map finishes loading with a command
|
|
261
|
-
- `ref` (ref): Reference to the component for sending commands
|
|
413
|
+
```typescript
|
|
414
|
+
import { usePointrGeofence } from 'react-native-pointr';
|
|
262
415
|
|
|
263
|
-
|
|
416
|
+
usePointrGeofence((event) => {
|
|
417
|
+
console.log(event.eventType, event.geofence?.name);
|
|
418
|
+
});
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
### `usePointrBuildingClick(callback)`
|
|
424
|
+
|
|
425
|
+
Subscribes to building-tap events on the map.
|
|
426
|
+
|
|
427
|
+
**Parameters:**
|
|
428
|
+
- `callback` (`(event: PTRBuildingClickEvent) => void`)
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
import { usePointrBuildingClick } from 'react-native-pointr';
|
|
432
|
+
|
|
433
|
+
usePointrBuildingClick((event) => {
|
|
434
|
+
console.log('Building tapped:', event.internalIdentifier, event.title);
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### `usePointrSiteClick(callback)`
|
|
441
|
+
|
|
442
|
+
Subscribes to site-tap events on the map.
|
|
443
|
+
|
|
444
|
+
**Parameters:**
|
|
445
|
+
- `callback` (`(event: PTRSiteClickEvent) => void`)
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
import { usePointrSiteClick } from 'react-native-pointr';
|
|
449
|
+
|
|
450
|
+
usePointrSiteClick((event) => {
|
|
451
|
+
console.log('Site tapped:', event.internalIdentifier, event.title);
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## PTRMapWidget Component
|
|
458
|
+
|
|
459
|
+
`PTRMapWidget` is a typed React component (with `forwardRef`) that wraps the native map view.
|
|
460
|
+
|
|
461
|
+
**Import:**
|
|
264
462
|
```typescript
|
|
265
|
-
import {
|
|
463
|
+
import { PTRMapWidget } from 'react-native-pointr';
|
|
464
|
+
import type { PTRMapWidgetProps } from 'react-native-pointr';
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Props
|
|
468
|
+
|
|
469
|
+
| Prop | Type | Description |
|
|
470
|
+
|------|------|-------------|
|
|
471
|
+
| `style` | `ViewStyle` | Component styling |
|
|
472
|
+
| `command` | `PTRCommand` | Declarative command executed automatically on mount |
|
|
473
|
+
| `sdkConfig` | `PTRConfiguration` | When provided, initializes the SDK without a prior `pointrSdk.initialize()` call |
|
|
474
|
+
| `mapWidgetConfig` | `PTRMapWidgetConfiguration` | UI configuration applied before the widget renders |
|
|
475
|
+
| `onMapWidgetDidEndLoading` | `(event: NativeSyntheticEvent<PTRMapCommandResponse>) => void` | Fired when the map finishes loading a command |
|
|
476
|
+
| `onWayfindingEvent` | `(event: NativeSyntheticEvent<PTRWayfindingEvent>) => void` | Fired during wayfinding (start / end / cancel) |
|
|
477
|
+
|
|
478
|
+
### Declarative usage (recommended)
|
|
479
|
+
|
|
480
|
+
Pass `command`, `sdkConfig`, and `mapWidgetConfig` as props so the widget handles initialization automatically:
|
|
481
|
+
|
|
482
|
+
```tsx
|
|
483
|
+
import { PTRMapWidget, PTRSiteCommand } from 'react-native-pointr';
|
|
484
|
+
import type { PTRConfiguration, PTRMapWidgetConfiguration } from 'react-native-pointr';
|
|
485
|
+
|
|
486
|
+
const SDK_CONFIG: PTRConfiguration = {
|
|
487
|
+
clientId: '<CLIENT_ID>',
|
|
488
|
+
licenseKey: '<LICENSE_KEY>',
|
|
489
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
const MAP_CONFIG: PTRMapWidgetConfiguration = {
|
|
493
|
+
isLevelSelectorEnabled: true,
|
|
494
|
+
isJoystickEnabled: true,
|
|
495
|
+
isExitButtonEnabled: false,
|
|
496
|
+
};
|
|
266
497
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
498
|
+
function MapScreen() {
|
|
499
|
+
return (
|
|
500
|
+
<PTRMapWidget
|
|
501
|
+
style={{ flex: 1 }}
|
|
502
|
+
sdkConfig={SDK_CONFIG}
|
|
503
|
+
mapWidgetConfig={MAP_CONFIG}
|
|
504
|
+
command={new PTRSiteCommand('<SITE_ID>')}
|
|
505
|
+
onMapWidgetDidEndLoading={(e) => console.log('Loaded', e.nativeEvent)}
|
|
506
|
+
onWayfindingEvent={(e) => console.log('Navigation', e.nativeEvent)}
|
|
507
|
+
/>
|
|
508
|
+
);
|
|
270
509
|
}
|
|
510
|
+
```
|
|
271
511
|
|
|
272
|
-
|
|
512
|
+
### Imperative usage
|
|
273
513
|
|
|
274
|
-
|
|
275
|
-
const ref = useRef(null);
|
|
514
|
+
Use `ref` + `executeMapCommand` to dispatch commands after mount:
|
|
276
515
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
516
|
+
```tsx
|
|
517
|
+
import { useRef } from 'react';
|
|
518
|
+
import { PTRMapWidget, PTRPoiCommand, executeMapCommand } from 'react-native-pointr';
|
|
519
|
+
|
|
520
|
+
function MapScreen() {
|
|
521
|
+
const mapRef = useRef(null);
|
|
522
|
+
|
|
523
|
+
const goToLobby = () => {
|
|
524
|
+
executeMapCommand(mapRef, new PTRPoiCommand('<SITE_ID>', 'Lobby'));
|
|
280
525
|
};
|
|
281
526
|
|
|
282
527
|
return (
|
|
283
|
-
<PTRMapWidget
|
|
284
|
-
ref={
|
|
528
|
+
<PTRMapWidget
|
|
529
|
+
ref={mapRef}
|
|
285
530
|
style={{ flex: 1 }}
|
|
286
|
-
onMapWidgetDidEndLoading={
|
|
531
|
+
onMapWidgetDidEndLoading={(e) => {
|
|
532
|
+
const { command, error } = e.nativeEvent;
|
|
533
|
+
if (error) console.error(command, error);
|
|
534
|
+
}}
|
|
287
535
|
/>
|
|
288
536
|
);
|
|
289
537
|
}
|
|
@@ -291,464 +539,588 @@ function MyComponent() {
|
|
|
291
539
|
|
|
292
540
|
---
|
|
293
541
|
|
|
294
|
-
##
|
|
542
|
+
## Constants & Enums
|
|
295
543
|
|
|
296
|
-
|
|
544
|
+
All constants and enums are exported from `react-native-pointr`.
|
|
297
545
|
|
|
298
|
-
|
|
546
|
+
### `PTRLogLevel`
|
|
299
547
|
|
|
300
548
|
```typescript
|
|
301
|
-
enum
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
MARK_MY_CAR_LEVEL = "markMyCarForLevel",
|
|
309
|
-
MARK_MY_CAR_SITE = "markMyCarForSite",
|
|
310
|
-
SHOW_MY_CAR_SITE = "showMyCarForSite",
|
|
311
|
-
START_AND_FOCUS = "startAndFocus"
|
|
549
|
+
enum PTRLogLevel {
|
|
550
|
+
VERBOSE = 0,
|
|
551
|
+
DEBUG = 1,
|
|
552
|
+
INFO = 2,
|
|
553
|
+
WARNING = 3,
|
|
554
|
+
ERROR = 4, // default
|
|
555
|
+
NONE = 5,
|
|
312
556
|
}
|
|
313
557
|
```
|
|
314
558
|
|
|
315
559
|
---
|
|
316
560
|
|
|
317
|
-
###
|
|
561
|
+
### `PTRState`
|
|
318
562
|
|
|
319
|
-
|
|
563
|
+
Tracks the lifecycle state of the SDK as managed by `PointrSdk`.
|
|
320
564
|
|
|
321
|
-
|
|
565
|
+
```typescript
|
|
566
|
+
enum PTRState {
|
|
567
|
+
NOT_INITIALIZED = 'NOT_INITIALIZED',
|
|
568
|
+
INITIALIZING = 'INITIALIZING',
|
|
569
|
+
INITIALIZED = 'INITIALIZED',
|
|
570
|
+
STARTING = 'STARTING',
|
|
571
|
+
RUNNING = 'RUNNING',
|
|
572
|
+
STOPPED = 'STOPPED',
|
|
573
|
+
ERROR = 'ERROR',
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
### `PTRCommandType`
|
|
322
580
|
|
|
323
|
-
**Constructor:**
|
|
324
581
|
```typescript
|
|
325
|
-
|
|
582
|
+
enum PTRCommandType {
|
|
583
|
+
SITE = 'site',
|
|
584
|
+
BUILDING = 'building',
|
|
585
|
+
LEVEL = 'level',
|
|
586
|
+
POI = 'poi',
|
|
587
|
+
PATH = 'path',
|
|
588
|
+
STATIC_PATH = 'staticPath',
|
|
589
|
+
STATIC_WAYFINDING = 'staticWayfinding',
|
|
590
|
+
MARK_MY_CAR_LEVEL = 'markMyCarForLevel',
|
|
591
|
+
MARK_MY_CAR_SITE = 'markMyCarForSite',
|
|
592
|
+
SHOW_MY_CAR_SITE = 'showMyCarForSite',
|
|
593
|
+
START_AND_FOCUS = 'startAndFocus',
|
|
594
|
+
}
|
|
326
595
|
```
|
|
327
596
|
|
|
328
|
-
|
|
329
|
-
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
### `PTRAnimationType`
|
|
600
|
+
|
|
601
|
+
Animation type constants for map transitions.
|
|
330
602
|
|
|
331
|
-
**Example:**
|
|
332
603
|
```typescript
|
|
333
|
-
|
|
334
|
-
|
|
604
|
+
enum PTRAnimationType {
|
|
605
|
+
NONE = 'none',
|
|
606
|
+
FADE = 'fade',
|
|
607
|
+
SLIDE = 'slide',
|
|
608
|
+
ZOOM = 'zoom',
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
> **Note:** The "My Car" command constructors (`PTRMarkMyCarLevelCommand`, `PTRMarkMyCarSiteCommand`, `PTRShowMyCarSiteCommand`) accept `animationType` as a plain `number` parameter, not as `PTRAnimationType`. The numeric values `0`, `1`, `2` correspond to none, standard, and fly-over animation respectively.
|
|
613
|
+
|
|
614
|
+
---
|
|
335
615
|
|
|
336
|
-
|
|
337
|
-
|
|
616
|
+
### `PTRGeofenceEventType`
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
enum PTRGeofenceEventType {
|
|
620
|
+
ENTER = 'enter',
|
|
621
|
+
EXIT = 'exit',
|
|
622
|
+
}
|
|
338
623
|
```
|
|
339
624
|
|
|
625
|
+
> **Note:** `DWELL` is not emitted by the native SDK on either platform.
|
|
626
|
+
|
|
340
627
|
---
|
|
341
628
|
|
|
342
|
-
|
|
629
|
+
### `PTREvents`
|
|
343
630
|
|
|
344
|
-
|
|
631
|
+
Event name constants used internally and available for direct `NativeEventEmitter` subscriptions.
|
|
345
632
|
|
|
346
|
-
**Constructor:**
|
|
347
633
|
```typescript
|
|
348
|
-
|
|
634
|
+
const PTREvents = {
|
|
635
|
+
ON_POSITION_CALCULATED: 'OnPositionManagerCalculatedLocation',
|
|
636
|
+
ON_BUILDING_CLICKED: 'OnBuildingClicked',
|
|
637
|
+
ON_SITE_CLICKED: 'OnSiteClicked',
|
|
638
|
+
ON_GEOFENCE_EVENT: 'OnGeofenceEvent',
|
|
639
|
+
ON_WAYFINDING_EVENT: 'onWayfindingEvent',
|
|
640
|
+
ON_MAP_WIDGET_DID_END_LOADING:'onMapWidgetDidEndLoading',
|
|
641
|
+
}
|
|
349
642
|
```
|
|
350
643
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
### `PTRErrorMessages`
|
|
647
|
+
|
|
648
|
+
Pre-defined error message strings thrown by `PointrSdk` and `executeMapCommand`.
|
|
354
649
|
|
|
355
|
-
**Example:**
|
|
356
650
|
```typescript
|
|
357
|
-
const
|
|
358
|
-
|
|
651
|
+
const PTRErrorMessages = {
|
|
652
|
+
NOT_INITIALIZED: 'Pointr SDK is not initialized. Call initialize() first.',
|
|
653
|
+
NOT_STARTED: 'Pointr SDK is not started. Call start() first.',
|
|
654
|
+
ALREADY_INITIALIZED:'Pointr SDK is already initialized.',
|
|
655
|
+
INVALID_CONFIG: 'Invalid configuration provided.',
|
|
656
|
+
INVALID_COMMAND: 'Invalid map command provided.',
|
|
657
|
+
NO_MAP_REF: 'Map widget reference is required.',
|
|
658
|
+
NATIVE_ERROR: 'Native module error occurred.',
|
|
659
|
+
}
|
|
359
660
|
```
|
|
360
661
|
|
|
361
662
|
---
|
|
362
663
|
|
|
363
|
-
|
|
664
|
+
## Command Classes
|
|
364
665
|
|
|
365
|
-
|
|
666
|
+
All command classes are exported from `react-native-pointr`.
|
|
667
|
+
|
|
668
|
+
### `PTRSiteCommand`
|
|
669
|
+
|
|
670
|
+
Shows a specific site on the map.
|
|
366
671
|
|
|
367
|
-
**Constructor:**
|
|
368
672
|
```typescript
|
|
369
|
-
new
|
|
673
|
+
new PTRSiteCommand(site: string)
|
|
370
674
|
```
|
|
371
675
|
|
|
372
|
-
**Parameters:**
|
|
373
|
-
- `site` (string): Site external identifier
|
|
374
|
-
- `building` (string): Building external identifier
|
|
375
|
-
- `level` (number): Level index
|
|
376
|
-
|
|
377
|
-
**Example:**
|
|
378
676
|
```typescript
|
|
379
|
-
|
|
380
|
-
showMapWidget(reactTag, command);
|
|
677
|
+
new PTRSiteCommand('<SITE_EXTERNAL_ID>')
|
|
381
678
|
```
|
|
382
679
|
|
|
383
680
|
---
|
|
384
681
|
|
|
385
|
-
|
|
682
|
+
### `PTRBuildingCommand`
|
|
386
683
|
|
|
387
|
-
Shows
|
|
684
|
+
Shows a specific building within a site.
|
|
388
685
|
|
|
389
|
-
**Constructor:**
|
|
390
686
|
```typescript
|
|
391
|
-
new
|
|
687
|
+
new PTRBuildingCommand(site: string, building: string)
|
|
392
688
|
```
|
|
393
689
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
### `PTRLevelCommand`
|
|
693
|
+
|
|
694
|
+
Shows a specific level within a building.
|
|
397
695
|
|
|
398
|
-
**Example:**
|
|
399
696
|
```typescript
|
|
400
|
-
|
|
401
|
-
showMapWidget(reactTag, command);
|
|
697
|
+
new PTRLevelCommand(site: string, building: string, level: number)
|
|
402
698
|
```
|
|
403
699
|
|
|
404
700
|
---
|
|
405
701
|
|
|
406
|
-
|
|
702
|
+
### `PTRPoiCommand`
|
|
407
703
|
|
|
408
|
-
|
|
704
|
+
Focuses the map on a specific POI.
|
|
409
705
|
|
|
410
|
-
**Constructor:**
|
|
411
706
|
```typescript
|
|
412
|
-
new
|
|
707
|
+
new PTRPoiCommand(site: string, poi: string)
|
|
413
708
|
```
|
|
414
709
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
710
|
+
- `poi`: POI external identifier or name.
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
### `PTRPathCommand`
|
|
715
|
+
|
|
716
|
+
Shows a navigation path from the user's current location to a POI.
|
|
418
717
|
|
|
419
|
-
**Example:**
|
|
420
718
|
```typescript
|
|
421
|
-
|
|
422
|
-
showMapWidget(reactTag, command);
|
|
719
|
+
new PTRPathCommand(site: string, poi: string)
|
|
423
720
|
```
|
|
424
721
|
|
|
425
722
|
---
|
|
426
723
|
|
|
427
|
-
|
|
724
|
+
### `PTRStaticPathCommand`
|
|
428
725
|
|
|
429
726
|
Shows a static path between two POIs.
|
|
430
727
|
|
|
431
|
-
**Constructor:**
|
|
432
728
|
```typescript
|
|
433
729
|
new PTRStaticPathCommand(site: string, fromPoi: string, toPoi: string)
|
|
434
730
|
```
|
|
435
731
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
### `PTRStaticWayfindingCommand`
|
|
735
|
+
|
|
736
|
+
Initiates static wayfinding between two POIs.
|
|
440
737
|
|
|
441
|
-
**Example:**
|
|
442
738
|
```typescript
|
|
443
|
-
|
|
444
|
-
showMapWidget(reactTag, command);
|
|
739
|
+
new PTRStaticWayfindingCommand(site: string, sourcePoi: string, destinationPoi: string)
|
|
445
740
|
```
|
|
446
741
|
|
|
447
742
|
---
|
|
448
743
|
|
|
449
|
-
|
|
744
|
+
### `PTRMarkMyCarLevelCommand`
|
|
450
745
|
|
|
451
|
-
Marks "My Car" location
|
|
746
|
+
Marks the "My Car" location at a specific level.
|
|
452
747
|
|
|
453
|
-
**Constructor:**
|
|
454
748
|
```typescript
|
|
455
749
|
new PTRMarkMyCarLevelCommand(
|
|
456
750
|
site: string,
|
|
457
751
|
building: string,
|
|
458
752
|
level: number,
|
|
459
|
-
shouldShowPopup?: boolean,
|
|
460
|
-
animationType?: number
|
|
753
|
+
shouldShowPopup?: boolean, // default: true
|
|
754
|
+
animationType?: number // default: 1
|
|
461
755
|
)
|
|
462
756
|
```
|
|
463
757
|
|
|
464
|
-
**Parameters:**
|
|
465
|
-
- `site` (string): Site external identifier
|
|
466
|
-
- `building` (string): Building external identifier
|
|
467
|
-
- `level` (number): Level index
|
|
468
|
-
- `shouldShowPopup` (boolean): Show popup after marking (default: true)
|
|
469
|
-
- `animationType` (number): Animation type (default: 1)
|
|
470
|
-
- `0`: None
|
|
471
|
-
- `1`: Standard
|
|
472
|
-
- `2`: Fly over
|
|
473
|
-
|
|
474
|
-
**Example:**
|
|
475
|
-
```typescript
|
|
476
|
-
const command = new PTRMarkMyCarLevelCommand("site-id", "building-id", 1, true, 1);
|
|
477
|
-
showMapWidget(reactTag, command);
|
|
478
|
-
```
|
|
479
|
-
|
|
480
758
|
---
|
|
481
759
|
|
|
482
|
-
|
|
760
|
+
### `PTRMarkMyCarSiteCommand`
|
|
483
761
|
|
|
484
|
-
Marks "My Car" location at the current position within a site.
|
|
762
|
+
Marks the "My Car" location at the current position within a site.
|
|
485
763
|
|
|
486
|
-
**Constructor:**
|
|
487
764
|
```typescript
|
|
488
765
|
new PTRMarkMyCarSiteCommand(
|
|
489
766
|
site: string,
|
|
490
|
-
shouldShowPopup?: boolean,
|
|
491
|
-
animationType?: number
|
|
767
|
+
shouldShowPopup?: boolean, // default: true
|
|
768
|
+
animationType?: number // default: 1
|
|
492
769
|
)
|
|
493
770
|
```
|
|
494
771
|
|
|
495
|
-
**Parameters:**
|
|
496
|
-
- `site` (string): Site external identifier
|
|
497
|
-
- `shouldShowPopup` (boolean): Show popup after marking (default: true)
|
|
498
|
-
- `animationType` (number): Animation type (default: 1)
|
|
499
|
-
|
|
500
|
-
**Example:**
|
|
501
|
-
```typescript
|
|
502
|
-
const command = new PTRMarkMyCarSiteCommand("site-id", true, 1);
|
|
503
|
-
showMapWidget(reactTag, command);
|
|
504
|
-
```
|
|
505
|
-
|
|
506
772
|
---
|
|
507
773
|
|
|
508
|
-
|
|
774
|
+
### `PTRShowMyCarSiteCommand`
|
|
509
775
|
|
|
510
|
-
Shows the saved "My Car" location.
|
|
776
|
+
Shows the previously saved "My Car" location.
|
|
511
777
|
|
|
512
|
-
**Constructor:**
|
|
513
778
|
```typescript
|
|
514
779
|
new PTRShowMyCarSiteCommand(
|
|
515
780
|
site: string,
|
|
516
|
-
shouldShowPopup?: boolean,
|
|
517
|
-
animationType?: number
|
|
781
|
+
shouldShowPopup?: boolean, // default: true
|
|
782
|
+
animationType?: number // default: 1
|
|
518
783
|
)
|
|
519
784
|
```
|
|
520
785
|
|
|
521
|
-
**Parameters:**
|
|
522
|
-
- `site` (string): Site external identifier
|
|
523
|
-
- `shouldShowPopup` (boolean): Show popup (default: true)
|
|
524
|
-
- `animationType` (number): Animation type (default: 1)
|
|
525
|
-
|
|
526
|
-
**Example:**
|
|
527
|
-
```typescript
|
|
528
|
-
const command = new PTRShowMyCarSiteCommand("site-id", true, 1);
|
|
529
|
-
showMapWidget(reactTag, command);
|
|
530
|
-
```
|
|
531
|
-
|
|
532
786
|
---
|
|
533
787
|
|
|
534
|
-
|
|
788
|
+
### `PTRStartAndFocusCommand`
|
|
535
789
|
|
|
536
|
-
|
|
790
|
+
Combines SDK initialization with a focus command in a single native dispatch. Use for deep-link or notification-driven entry points where the SDK may not yet be running.
|
|
791
|
+
|
|
792
|
+
> **Note:** This command is dispatched via `showMapWidget` / the legacy `UIManager` path and is not a `PTRCommand` subclass. Prefer the declarative `sdkConfig` + `command` props on `PTRMapWidget` for new code.
|
|
537
793
|
|
|
538
|
-
**Constructor:**
|
|
539
794
|
```typescript
|
|
540
795
|
new PTRStartAndFocusCommand(
|
|
541
796
|
clientId: string,
|
|
542
797
|
licenseKey: string,
|
|
543
798
|
baseUrl: string,
|
|
544
|
-
logLevel: number,
|
|
799
|
+
logLevel: number, // default: 4 (ERROR)
|
|
545
800
|
command: PTRSiteCommand | PTRBuildingCommand | PTRLevelCommand | PTRPoiCommand
|
|
546
801
|
)
|
|
547
802
|
```
|
|
548
803
|
|
|
549
|
-
**Parameters:**
|
|
550
|
-
- `clientId` (string): Client identifier
|
|
551
|
-
- `licenseKey` (string): License key
|
|
552
|
-
- `baseUrl` (string): Base URL
|
|
553
|
-
- `logLevel` (number): Log level (0-4)
|
|
554
|
-
- `command` (PTRCommand): Focus command to execute after initialization
|
|
555
|
-
|
|
556
|
-
**Example:**
|
|
557
804
|
```typescript
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
805
|
+
import { PTRStartAndFocusCommand, PTRSiteCommand, showMapWidget } from 'react-native-pointr';
|
|
806
|
+
import { findNodeHandle } from 'react-native';
|
|
807
|
+
|
|
808
|
+
const cmd = new PTRStartAndFocusCommand(
|
|
809
|
+
'<CLIENT_ID>',
|
|
810
|
+
'<LICENSE_KEY>',
|
|
811
|
+
'https://<your-instance>.pointr.cloud',
|
|
812
|
+
4,
|
|
813
|
+
new PTRSiteCommand('<SITE_ID>')
|
|
565
814
|
);
|
|
566
|
-
showMapWidget(
|
|
815
|
+
showMapWidget(findNodeHandle(mapRef.current), cmd);
|
|
567
816
|
```
|
|
568
817
|
|
|
569
818
|
---
|
|
570
819
|
|
|
571
|
-
|
|
820
|
+
### Type guards
|
|
572
821
|
|
|
573
|
-
|
|
822
|
+
```typescript
|
|
823
|
+
import {
|
|
824
|
+
isPTRSiteCommand,
|
|
825
|
+
isPTRBuildingCommand,
|
|
826
|
+
isPTRLevelCommand,
|
|
827
|
+
isPTRPoiCommand,
|
|
828
|
+
isPTRPathCommand,
|
|
829
|
+
isPTRStaticPathCommand,
|
|
830
|
+
} from 'react-native-pointr';
|
|
831
|
+
```
|
|
574
832
|
|
|
575
|
-
|
|
833
|
+
---
|
|
576
834
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
835
|
+
## Types
|
|
836
|
+
|
|
837
|
+
All types are exported from `react-native-pointr`.
|
|
838
|
+
|
|
839
|
+
### `PTRConfiguration`
|
|
580
840
|
|
|
581
|
-
**Example:**
|
|
582
841
|
```typescript
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
if (reactTag) {
|
|
590
|
-
const command = new PTRSiteCommand("site-id");
|
|
591
|
-
showMapWidget(reactTag, command);
|
|
592
|
-
}
|
|
593
|
-
};
|
|
842
|
+
interface PTRConfiguration {
|
|
843
|
+
readonly clientId: string;
|
|
844
|
+
readonly licenseKey: string;
|
|
845
|
+
readonly baseUrl: string;
|
|
846
|
+
readonly logLevel?: PTRLogLevel; // default: PTRLogLevel.ERROR
|
|
847
|
+
}
|
|
594
848
|
```
|
|
595
849
|
|
|
596
850
|
---
|
|
597
851
|
|
|
598
|
-
|
|
852
|
+
### `PTRMapWidgetConfiguration`
|
|
853
|
+
|
|
854
|
+
Parameter names must match the boolean properties of `PTRMapWidgetConfiguration` declared in the native SDK. See [iOS SDK reference](https://pointr.blob.core.windows.net/api-ref/ios/9.6/Classes/PTRMapWidgetConfiguration.html) and [Android SDK reference](https://pointr.blob.core.windows.net/api-ref/android/9.6/-pointr%20-android%20-s-d-k%209.6.0/com.pointrlabs.ui.map.viewmodels/-p-t-r-map-widget-configuration/index.html) for the full list.
|
|
599
855
|
|
|
600
|
-
|
|
856
|
+
```typescript
|
|
857
|
+
interface PTRMapWidgetConfiguration {
|
|
858
|
+
readonly isLevelSelectorEnabled?: boolean;
|
|
859
|
+
readonly isLoadingViewEnabled?: boolean;
|
|
860
|
+
readonly isMapTrackingModeButtonEnabled?: boolean;
|
|
861
|
+
readonly isExitButtonEnabled?: boolean;
|
|
862
|
+
readonly isSplashScreenEnabled?: boolean;
|
|
863
|
+
readonly isOnboardingEnabled?: boolean;
|
|
864
|
+
readonly isJoystickEnabled?: boolean;
|
|
865
|
+
readonly isToastMessagesEnabled?: boolean;
|
|
866
|
+
readonly isInfoButtonEnabled?: boolean;
|
|
867
|
+
readonly isLocationIndicatorEnabled?: boolean;
|
|
868
|
+
readonly shouldFocusOnFirstUserPosition?: boolean;
|
|
869
|
+
readonly isQuickAccessEnabled?: boolean;
|
|
870
|
+
readonly isAppBannerEnabled?: boolean;
|
|
871
|
+
}
|
|
872
|
+
```
|
|
601
873
|
|
|
602
|
-
|
|
874
|
+
---
|
|
603
875
|
|
|
604
|
-
|
|
605
|
-
- `OnPositionManagerCalculatedLocation`: Fired when a new position is calculated
|
|
606
|
-
- `OnBuildingClicked`: Fired when a building is tapped on the map
|
|
607
|
-
- `OnSiteClicked`: Fired when a site is tapped on the map
|
|
608
|
-
- `OnGeofenceEvent`: Fired when a geofence enter/exit event occurs
|
|
876
|
+
### `PTRPosition`
|
|
609
877
|
|
|
610
|
-
**Example:**
|
|
611
878
|
```typescript
|
|
612
|
-
|
|
879
|
+
interface PTRPosition {
|
|
880
|
+
lat: number; // Latitude
|
|
881
|
+
lon: number; // Longitude
|
|
882
|
+
isValid: boolean;
|
|
883
|
+
sid: string; // Site identifier
|
|
884
|
+
bid: string; // Building identifier
|
|
885
|
+
lvl: number; // Level index
|
|
886
|
+
}
|
|
887
|
+
```
|
|
613
888
|
|
|
614
|
-
|
|
615
|
-
const eventEmitter = new NativeEventEmitter(PTREventEmitter);
|
|
889
|
+
---
|
|
616
890
|
|
|
617
|
-
|
|
618
|
-
const subscription = eventEmitter.addListener(
|
|
619
|
-
'OnPositionManagerCalculatedLocation',
|
|
620
|
-
(location) => {
|
|
621
|
-
console.log('New position:', location);
|
|
622
|
-
}
|
|
623
|
-
);
|
|
891
|
+
### `PTRPositionEvent`
|
|
624
892
|
|
|
625
|
-
|
|
626
|
-
const buildingSubscription = eventEmitter.addListener(
|
|
627
|
-
'OnBuildingClicked',
|
|
628
|
-
(building) => {
|
|
629
|
-
console.log('Building clicked:', building);
|
|
630
|
-
}
|
|
631
|
-
);
|
|
893
|
+
The TypeScript return type of `usePointrPosition` and the argument type of `pointrSdk.onPositionUpdate` callbacks. The actual runtime payload is the raw native event object with the fields listed under [`getCurrentLocation()`](#getcurrentlocation) rather than a wrapped `PTRPosition`.
|
|
632
894
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
### `PTRPoi`
|
|
898
|
+
|
|
899
|
+
```typescript
|
|
900
|
+
interface PTRPoi {
|
|
901
|
+
identifier: string;
|
|
902
|
+
externalIdentifier: string;
|
|
903
|
+
name: string;
|
|
904
|
+
typeCode: string;
|
|
905
|
+
position: PTRPosition;
|
|
906
|
+
geometry: PTRGeometry;
|
|
907
|
+
attributes: PTRPoiAttributes;
|
|
908
|
+
}
|
|
640
909
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
910
|
+
interface PTRPoiAttributes {
|
|
911
|
+
logo?: string;
|
|
912
|
+
images?: string[];
|
|
913
|
+
description?: string;
|
|
914
|
+
extra?: Record<string, any>;
|
|
915
|
+
[key: string]: any;
|
|
916
|
+
}
|
|
645
917
|
```
|
|
646
918
|
|
|
647
919
|
---
|
|
648
920
|
|
|
649
|
-
###
|
|
921
|
+
### `PTRGeometry`
|
|
650
922
|
|
|
651
|
-
|
|
923
|
+
Union of all supported geometry shapes.
|
|
652
924
|
|
|
653
|
-
**Event Structure:**
|
|
654
925
|
```typescript
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
926
|
+
type PTRGeometry =
|
|
927
|
+
| PTRGeoPoint
|
|
928
|
+
| PTRGeoPolygon
|
|
929
|
+
| PTRGeoMultiPoint
|
|
930
|
+
| PTRGeoLineString
|
|
931
|
+
| PTRGeoMultiLineString
|
|
932
|
+
| PTRGeoMultiPolygon
|
|
933
|
+
| PTRGeoCircle;
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
| Type | Key fields |
|
|
937
|
+
|------|-----------|
|
|
938
|
+
| `PTRGeoPoint` | `type: 'Point'`, `lat`, `lon` |
|
|
939
|
+
| `PTRGeoPolygon` | `type: 'Polygon'`, `outer: PTRGeoPoint[]`, `inners: PTRGeoPoint[][]` |
|
|
940
|
+
| `PTRGeoMultiPoint` | `type: 'MultiPoint'`, `points: PTRGeoPoint[]` |
|
|
941
|
+
| `PTRGeoLineString` | `type: 'LineString'`, `points: PTRGeoPoint[]` |
|
|
942
|
+
| `PTRGeoMultiLineString` | `type: 'MultiLineString'`, `lines: PTRGeoPoint[][]` |
|
|
943
|
+
| `PTRGeoMultiPolygon` | `type: 'MultiPolygon'`, `polygons: PTRGeoPolygon[]` |
|
|
944
|
+
| `PTRGeoCircle` | `type: 'Circle'`, `center: PTRGeoPoint`, `radius: number` |
|
|
945
|
+
|
|
946
|
+
---
|
|
947
|
+
|
|
948
|
+
### `PTRWayfindingEvent`
|
|
949
|
+
|
|
950
|
+
Fired via `onWayfindingEvent` prop on `PTRMapWidget`.
|
|
951
|
+
|
|
952
|
+
```typescript
|
|
953
|
+
interface PTRWayfindingEvent {
|
|
954
|
+
type: -1 | 0 | 1; // -1 Cancelled, 0 Started, 1 Ended
|
|
955
|
+
poi: PTRPoi; // Destination POI
|
|
674
956
|
}
|
|
675
957
|
```
|
|
676
958
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
959
|
+
| `type` value | Meaning |
|
|
960
|
+
|-----|---------|
|
|
961
|
+
| `-1` | Wayfinding cancelled by user |
|
|
962
|
+
| `0` | Wayfinding started |
|
|
963
|
+
| `1` | Wayfinding ended (completed or dismissed) |
|
|
964
|
+
|
|
965
|
+
---
|
|
966
|
+
|
|
967
|
+
### `PTRMapCommandResponse`
|
|
968
|
+
|
|
969
|
+
Payload of the `onMapWidgetDidEndLoading` event.
|
|
681
970
|
|
|
682
|
-
**Example:**
|
|
683
971
|
```typescript
|
|
684
|
-
|
|
685
|
-
|
|
972
|
+
interface PTRMapCommandResponse {
|
|
973
|
+
readonly command: string;
|
|
974
|
+
readonly siteExternalIdentifier?: string;
|
|
975
|
+
readonly error?: string;
|
|
976
|
+
}
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
### `PTRGeofenceEvent`
|
|
686
982
|
|
|
687
|
-
function GeofenceMonitor() {
|
|
688
|
-
useEffect(() => {
|
|
689
|
-
const eventEmitter = new NativeEventEmitter(
|
|
690
|
-
NativeModules.PTRNativePointrLibrary
|
|
691
|
-
);
|
|
692
|
-
|
|
693
|
-
const geofenceSubscription = eventEmitter.addListener(
|
|
694
|
-
'OnGeofenceEvent',
|
|
695
|
-
(geofenceEvent) => {
|
|
696
|
-
console.log(`Geofence ${geofenceEvent.eventType}: ${geofenceEvent.geofence.name}`);
|
|
697
|
-
console.log(`Type: ${geofenceEvent.geofence.geofenceType}`);
|
|
698
|
-
console.log(`Location: ${geofenceEvent.geofence.position.latitude}, ${geofenceEvent.geofence.position.longitude}`);
|
|
699
|
-
|
|
700
|
-
if (geofenceEvent.geofenceNotification) {
|
|
701
|
-
console.log(`Notification: ${geofenceEvent.geofenceNotification.message}`);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
if (geofenceEvent.timestamp) {
|
|
705
|
-
console.log(`Timestamp: ${new Date(geofenceEvent.timestamp).toISOString()}`);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
);
|
|
709
|
-
|
|
710
|
-
return () => {
|
|
711
|
-
geofenceSubscription.remove();
|
|
712
|
-
};
|
|
713
|
-
}, []);
|
|
714
|
-
|
|
715
|
-
return null;
|
|
716
|
-
}
|
|
717
|
-
```
|
|
718
|
-
|
|
719
|
-
---
|
|
720
|
-
|
|
721
|
-
### Map Widget Load Events
|
|
722
|
-
|
|
723
|
-
The `onMapWidgetDidEndLoading` prop receives events when commands complete.
|
|
724
|
-
|
|
725
|
-
**Event Object:**
|
|
726
983
|
```typescript
|
|
727
|
-
{
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
984
|
+
interface PTRGeofenceEvent {
|
|
985
|
+
readonly eventType: 'enter' | 'exit';
|
|
986
|
+
readonly geofence: PTRGeofence;
|
|
987
|
+
readonly geofenceNotification?: PTRGeofenceNotification;
|
|
988
|
+
readonly timestamp?: number; // iOS only — milliseconds since epoch at root level
|
|
989
|
+
readonly geofenceType?: string; // Android only — 'beacon' | 'gps' at root level
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
interface PTRGeofence {
|
|
993
|
+
readonly id: string;
|
|
994
|
+
readonly externalId: string;
|
|
995
|
+
readonly name: string;
|
|
996
|
+
readonly geofenceType?: string; // iOS only — 'beacon' | 'gps' inside geofence object
|
|
997
|
+
readonly position: {
|
|
998
|
+
readonly latitude: number;
|
|
999
|
+
readonly longitude: number;
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
interface PTRGeofenceNotification {
|
|
1004
|
+
readonly id: string;
|
|
1005
|
+
readonly message: string;
|
|
1006
|
+
readonly timestamp: number; // milliseconds
|
|
734
1007
|
}
|
|
735
1008
|
```
|
|
736
1009
|
|
|
737
|
-
**
|
|
1010
|
+
**Platform differences:**
|
|
1011
|
+
- iOS: `timestamp` (milliseconds since epoch) is present at the event root level; `geofenceType` is inside the `geofence` object.
|
|
1012
|
+
- Android: No `timestamp` at the root level; `geofenceType` is at the event root level (not inside `geofence`).
|
|
1013
|
+
|
|
1014
|
+
---
|
|
1015
|
+
|
|
1016
|
+
### `PTRBuildingClickEvent` / `PTRSiteClickEvent`
|
|
1017
|
+
|
|
1018
|
+
Both events share the same payload shape emitted by the native SDK:
|
|
1019
|
+
|
|
738
1020
|
```typescript
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
} else {
|
|
745
|
-
console.log(`Command ${command} completed for site:`, siteExternalIdentifier);
|
|
746
|
-
}
|
|
747
|
-
};
|
|
1021
|
+
interface PTRBuildingClickEvent {
|
|
1022
|
+
readonly internalIdentifier: string;
|
|
1023
|
+
readonly externalIdentifier: string;
|
|
1024
|
+
readonly title: string;
|
|
1025
|
+
}
|
|
748
1026
|
|
|
1027
|
+
interface PTRSiteClickEvent {
|
|
1028
|
+
readonly internalIdentifier: string;
|
|
1029
|
+
readonly externalIdentifier: string;
|
|
1030
|
+
readonly title: string;
|
|
1031
|
+
}
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
---
|
|
1035
|
+
|
|
1036
|
+
## Event Listeners
|
|
1037
|
+
|
|
1038
|
+
There are three ways to subscribe to SDK events, in order of preference:
|
|
1039
|
+
|
|
1040
|
+
### 1. React Hooks (recommended)
|
|
1041
|
+
|
|
1042
|
+
```typescript
|
|
1043
|
+
import {
|
|
1044
|
+
usePointrPosition,
|
|
1045
|
+
usePointrGeofence,
|
|
1046
|
+
usePointrBuildingClick,
|
|
1047
|
+
usePointrSiteClick,
|
|
1048
|
+
} from 'react-native-pointr';
|
|
1049
|
+
|
|
1050
|
+
// Position
|
|
1051
|
+
const position = usePointrPosition();
|
|
1052
|
+
|
|
1053
|
+
// Geofence
|
|
1054
|
+
usePointrGeofence((event) => {
|
|
1055
|
+
console.log(event.eventType, event.geofence?.name);
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
// Building click
|
|
1059
|
+
usePointrBuildingClick((event) => {
|
|
1060
|
+
console.log('Building:', event.internalIdentifier, event.title);
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
// Site click
|
|
1064
|
+
usePointrSiteClick((event) => {
|
|
1065
|
+
console.log('Site:', event.internalIdentifier, event.title);
|
|
1066
|
+
});
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
---
|
|
1070
|
+
|
|
1071
|
+
### 2. `PointrSdk` subscription methods
|
|
1072
|
+
|
|
1073
|
+
```typescript
|
|
1074
|
+
import { pointrSdk } from 'react-native-pointr';
|
|
1075
|
+
|
|
1076
|
+
useEffect(() => {
|
|
1077
|
+
const sub = pointrSdk.onPositionUpdate((pos) => {
|
|
1078
|
+
console.log(pos);
|
|
1079
|
+
});
|
|
1080
|
+
return () => sub.remove();
|
|
1081
|
+
}, []);
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
Available methods: `onPositionUpdate`, `onBuildingClick`, `onSiteClick`, `onGeofenceEvent`.
|
|
1085
|
+
|
|
1086
|
+
---
|
|
1087
|
+
|
|
1088
|
+
### 3. Direct `NativeEventEmitter` (advanced)
|
|
1089
|
+
|
|
1090
|
+
```typescript
|
|
1091
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
1092
|
+
import { PTREvents } from 'react-native-pointr';
|
|
1093
|
+
|
|
1094
|
+
const emitter = new NativeEventEmitter(NativeModules.PTRNativePointrLibrary);
|
|
1095
|
+
|
|
1096
|
+
const sub = emitter.addListener(PTREvents.ON_POSITION_CALCULATED, (pos) => {
|
|
1097
|
+
console.log(pos);
|
|
1098
|
+
});
|
|
1099
|
+
// cleanup:
|
|
1100
|
+
sub.remove();
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
---
|
|
1104
|
+
|
|
1105
|
+
### Map widget events
|
|
1106
|
+
|
|
1107
|
+
The `PTRMapWidget` component exposes two event callbacks as props:
|
|
1108
|
+
|
|
1109
|
+
- **`onMapWidgetDidEndLoading`** — fires when the map finishes loading a command.
|
|
1110
|
+
- **`onWayfindingEvent`** — fires during wayfinding (started / ended / cancelled).
|
|
1111
|
+
|
|
1112
|
+
```tsx
|
|
749
1113
|
<PTRMapWidget
|
|
750
|
-
|
|
751
|
-
onMapWidgetDidEndLoading={
|
|
1114
|
+
style={{ flex: 1 }}
|
|
1115
|
+
onMapWidgetDidEndLoading={(e) => {
|
|
1116
|
+
const { command, siteExternalIdentifier, error } = e.nativeEvent;
|
|
1117
|
+
if (error) console.error(`Command ${command} failed:`, error);
|
|
1118
|
+
}}
|
|
1119
|
+
onWayfindingEvent={(e) => {
|
|
1120
|
+
const { type, poi } = e.nativeEvent;
|
|
1121
|
+
// type: -1 cancelled, 0 started, 1 ended
|
|
1122
|
+
console.log('Wayfinding', type, poi.name);
|
|
1123
|
+
}}
|
|
752
1124
|
/>
|
|
753
1125
|
```
|
|
754
1126
|
|
|
@@ -756,129 +1128,235 @@ const handleMapWidgetDidEndLoading = (event) => {
|
|
|
756
1128
|
|
|
757
1129
|
## Complete Example
|
|
758
1130
|
|
|
759
|
-
|
|
760
|
-
|
|
1131
|
+
### Declarative (recommended for simple integrations)
|
|
1132
|
+
|
|
1133
|
+
Pass `sdkConfig`, `mapWidgetConfig`, and `command` directly as props. No hook or imperative call is needed.
|
|
1134
|
+
|
|
1135
|
+
```tsx
|
|
1136
|
+
import React from 'react';
|
|
1137
|
+
import { StyleSheet } from 'react-native';
|
|
1138
|
+
import { PTRMapWidget, PTRSiteCommand } from 'react-native-pointr';
|
|
1139
|
+
import type { PTRConfiguration, PTRMapWidgetConfiguration } from 'react-native-pointr';
|
|
1140
|
+
|
|
1141
|
+
const SDK_CONFIG: PTRConfiguration = {
|
|
1142
|
+
clientId: '<CLIENT_ID>',
|
|
1143
|
+
licenseKey: '<LICENSE_KEY>',
|
|
1144
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
const MAP_CONFIG: PTRMapWidgetConfiguration = {
|
|
1148
|
+
isLevelSelectorEnabled: true,
|
|
1149
|
+
isJoystickEnabled: true,
|
|
1150
|
+
isExitButtonEnabled: false,
|
|
1151
|
+
isQuickAccessEnabled: true,
|
|
1152
|
+
};
|
|
1153
|
+
|
|
1154
|
+
export default function MapScreen() {
|
|
1155
|
+
return (
|
|
1156
|
+
<PTRMapWidget
|
|
1157
|
+
style={styles.map}
|
|
1158
|
+
sdkConfig={SDK_CONFIG}
|
|
1159
|
+
mapWidgetConfig={MAP_CONFIG}
|
|
1160
|
+
command={new PTRSiteCommand('<SITE_EXTERNAL_ID>')}
|
|
1161
|
+
onMapWidgetDidEndLoading={(e) => {
|
|
1162
|
+
const { command, error } = e.nativeEvent;
|
|
1163
|
+
if (error) console.error(`${command} failed:`, error);
|
|
1164
|
+
else console.log(`${command} loaded`);
|
|
1165
|
+
}}
|
|
1166
|
+
onWayfindingEvent={(e) => {
|
|
1167
|
+
const { type, poi } = e.nativeEvent;
|
|
1168
|
+
console.log('Wayfinding event', type, 'to', poi.name);
|
|
1169
|
+
}}
|
|
1170
|
+
/>
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
const styles = StyleSheet.create({
|
|
1175
|
+
map: { flex: 1 },
|
|
1176
|
+
});
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
### App-level SDK management (hooks)
|
|
1180
|
+
|
|
1181
|
+
Use `usePointrSdk` when you need SDK state, position updates, or other events outside of the map widget.
|
|
1182
|
+
|
|
1183
|
+
```tsx
|
|
1184
|
+
import React, { useState } from 'react';
|
|
1185
|
+
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
|
|
761
1186
|
import {
|
|
762
|
-
|
|
763
|
-
findNodeHandle,
|
|
764
|
-
NativeModules,
|
|
765
|
-
NativeEventEmitter,
|
|
766
|
-
View
|
|
767
|
-
} from 'react-native';
|
|
768
|
-
import {
|
|
1187
|
+
PTRMapWidget,
|
|
769
1188
|
PTRSiteCommand,
|
|
770
|
-
|
|
771
|
-
getPois,
|
|
772
|
-
type PTRPoi
|
|
1189
|
+
usePointrSdk,
|
|
773
1190
|
} from 'react-native-pointr';
|
|
1191
|
+
import type { PTRConfiguration } from 'react-native-pointr';
|
|
774
1192
|
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1193
|
+
const SDK_CONFIG: PTRConfiguration = {
|
|
1194
|
+
clientId: '<CLIENT_ID>',
|
|
1195
|
+
licenseKey: '<LICENSE_KEY>',
|
|
1196
|
+
baseUrl: 'https://<your-instance>.pointr.cloud',
|
|
1197
|
+
};
|
|
779
1198
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
"client-id",
|
|
784
|
-
"license-key",
|
|
785
|
-
"https://your-instance.pointr.cloud",
|
|
786
|
-
3
|
|
787
|
-
);
|
|
788
|
-
|
|
789
|
-
// Start SDK
|
|
790
|
-
NativeModules.PTRNativePointrLibrary.start((state) => {
|
|
791
|
-
console.log('Pointr state:', state);
|
|
792
|
-
|
|
793
|
-
if (state === 'running') {
|
|
794
|
-
// Show site when SDK is running
|
|
795
|
-
const reactTag = findNodeHandle(mapRef.current);
|
|
796
|
-
if (reactTag) {
|
|
797
|
-
const command = new PTRSiteCommand("site-id");
|
|
798
|
-
showMapWidget(reactTag, command);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
// Fetch POIs for the site
|
|
802
|
-
fetchPOIs();
|
|
803
|
-
}
|
|
804
|
-
});
|
|
805
|
-
|
|
806
|
-
// Listen to position updates
|
|
807
|
-
const eventEmitter = new NativeEventEmitter(
|
|
808
|
-
NativeModules.PTRNativePointrLibrary
|
|
809
|
-
);
|
|
810
|
-
const subscription = eventEmitter.addListener(
|
|
811
|
-
'OnPositionManagerCalculatedLocation',
|
|
812
|
-
(location) => {
|
|
813
|
-
console.log('Position update:', location);
|
|
814
|
-
}
|
|
815
|
-
);
|
|
816
|
-
|
|
817
|
-
// Listen to geofence events
|
|
818
|
-
const geofenceSubscription = eventEmitter.addListener(
|
|
819
|
-
'OnGeofenceEvent',
|
|
820
|
-
(event) => {
|
|
821
|
-
console.log(`Geofence ${event.eventType}: ${event.geofence.name}`);
|
|
822
|
-
}
|
|
823
|
-
);
|
|
824
|
-
|
|
825
|
-
return () => {
|
|
826
|
-
subscription.remove();
|
|
827
|
-
geofenceSubscription.remove();
|
|
828
|
-
NativeModules.PTRNativePointrLibrary.stop();
|
|
829
|
-
};
|
|
830
|
-
}, []);
|
|
831
|
-
|
|
832
|
-
const fetchPOIs = async () => {
|
|
833
|
-
try {
|
|
834
|
-
const pois: PTRPoi[] = await getPois('site-id');
|
|
835
|
-
console.log(`Found ${pois.length} POIs`);
|
|
836
|
-
pois.forEach(poi => {
|
|
837
|
-
console.log(`${poi.name} at level ${poi.position.lvl}`);
|
|
838
|
-
});
|
|
839
|
-
} catch (error) {
|
|
840
|
-
console.error('Failed to fetch POIs:', error);
|
|
841
|
-
}
|
|
842
|
-
};
|
|
1199
|
+
export default function App() {
|
|
1200
|
+
const [showMap, setShowMap] = useState(false);
|
|
1201
|
+
const { sdk, isStarted, state } = usePointrSdk(SDK_CONFIG);
|
|
843
1202
|
|
|
844
|
-
const
|
|
845
|
-
const
|
|
846
|
-
console.log(
|
|
1203
|
+
const checkPosition = async () => {
|
|
1204
|
+
const loc = await sdk.getCurrentLocation();
|
|
1205
|
+
if (loc) console.log(loc.latitude, loc.longitude, loc.levelIndex);
|
|
847
1206
|
};
|
|
848
1207
|
|
|
849
1208
|
return (
|
|
850
|
-
<View style={
|
|
851
|
-
<
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
1209
|
+
<View style={styles.container}>
|
|
1210
|
+
<Text>SDK State: {state}</Text>
|
|
1211
|
+
<TouchableOpacity onPress={checkPosition} disabled={!isStarted}>
|
|
1212
|
+
<Text>Get Position</Text>
|
|
1213
|
+
</TouchableOpacity>
|
|
1214
|
+
<TouchableOpacity onPress={() => setShowMap(true)}>
|
|
1215
|
+
<Text>Open Map</Text>
|
|
1216
|
+
</TouchableOpacity>
|
|
1217
|
+
|
|
1218
|
+
{showMap && (
|
|
1219
|
+
<PTRMapWidget
|
|
1220
|
+
style={StyleSheet.absoluteFill}
|
|
1221
|
+
command={new PTRSiteCommand('<SITE_EXTERNAL_ID>')}
|
|
1222
|
+
/>
|
|
1223
|
+
)}
|
|
856
1224
|
</View>
|
|
857
1225
|
);
|
|
858
1226
|
}
|
|
859
1227
|
|
|
860
|
-
|
|
1228
|
+
const styles = StyleSheet.create({
|
|
1229
|
+
container: { flex: 1 },
|
|
1230
|
+
});
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
---
|
|
1234
|
+
|
|
1235
|
+
## Legacy API
|
|
1236
|
+
|
|
1237
|
+
The original imperative API is still fully functional. Existing integrations do not need to migrate.
|
|
1238
|
+
|
|
1239
|
+
### `NativeModules.PTRNativePointrLibrary`
|
|
1240
|
+
|
|
1241
|
+
All native module methods remain available via `NativeModules`:
|
|
1242
|
+
|
|
1243
|
+
```typescript
|
|
1244
|
+
import { NativeModules } from 'react-native';
|
|
1245
|
+
|
|
1246
|
+
const { PTRNativePointrLibrary } = NativeModules;
|
|
1247
|
+
|
|
1248
|
+
// Initialize
|
|
1249
|
+
PTRNativePointrLibrary.initialize('<CLIENT_ID>', '<LICENSE_KEY>', '<BASE_URL>', 3);
|
|
1250
|
+
|
|
1251
|
+
// Start
|
|
1252
|
+
PTRNativePointrLibrary.start((state: string) => {
|
|
1253
|
+
console.log('State:', state);
|
|
1254
|
+
});
|
|
1255
|
+
|
|
1256
|
+
// Stop
|
|
1257
|
+
PTRNativePointrLibrary.stop();
|
|
1258
|
+
|
|
1259
|
+
// Permissions
|
|
1260
|
+
PTRNativePointrLibrary.requestPermissions();
|
|
1261
|
+
PTRNativePointrLibrary.shouldRequestPermissionsAtStartup(true);
|
|
1262
|
+
|
|
1263
|
+
// Position
|
|
1264
|
+
PTRNativePointrLibrary.getCurrentLocation((location: any) => {
|
|
1265
|
+
if (location) console.log(location);
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1268
|
+
// Map widget configuration
|
|
1269
|
+
PTRNativePointrLibrary.setPointrMapWidgetConfiguration(
|
|
1270
|
+
JSON.stringify({ isExitButtonEnabled: false })
|
|
1271
|
+
);
|
|
1272
|
+
|
|
1273
|
+
// POIs
|
|
1274
|
+
const pois = await PTRNativePointrLibrary.getPois('<SITE_ID>');
|
|
1275
|
+
|
|
1276
|
+
// My car
|
|
1277
|
+
PTRNativePointrLibrary.isMyCarMarked((error: any) => {
|
|
1278
|
+
if (!error) console.log('Car is marked');
|
|
1279
|
+
});
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
**Native start state strings:**
|
|
1283
|
+
|
|
1284
|
+
| Value | Meaning |
|
|
1285
|
+
|-------|---------|
|
|
1286
|
+
| `"running"` | SDK running successfully |
|
|
1287
|
+
| `"failed registration"` | Registration failed |
|
|
1288
|
+
| `"failed validation"` | Validation failed |
|
|
1289
|
+
| `"failed invalid deep link url"` | Invalid deep link URL |
|
|
1290
|
+
| `"failed no internet"` | No internet connection |
|
|
1291
|
+
| `"off"` | SDK is off |
|
|
1292
|
+
|
|
1293
|
+
---
|
|
1294
|
+
|
|
1295
|
+
### `showMapWidget(reactTag, command)`
|
|
1296
|
+
|
|
1297
|
+
Dispatches a command directly by numeric native view tag.
|
|
1298
|
+
|
|
1299
|
+
```typescript
|
|
1300
|
+
import { showMapWidget } from 'react-native-pointr';
|
|
1301
|
+
import { findNodeHandle } from 'react-native';
|
|
1302
|
+
|
|
1303
|
+
const reactTag = findNodeHandle(mapRef.current);
|
|
1304
|
+
if (reactTag) {
|
|
1305
|
+
showMapWidget(reactTag, new PTRSiteCommand('<SITE_ID>'));
|
|
1306
|
+
}
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
---
|
|
1310
|
+
|
|
1311
|
+
### `getPois(siteId)`
|
|
1312
|
+
|
|
1313
|
+
```typescript
|
|
1314
|
+
import { getPois } from 'react-native-pointr';
|
|
1315
|
+
|
|
1316
|
+
const pois = await getPois('<SITE_EXTERNAL_ID>');
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
---
|
|
1320
|
+
|
|
1321
|
+
### Legacy command imports
|
|
1322
|
+
|
|
1323
|
+
```typescript
|
|
1324
|
+
import {
|
|
1325
|
+
LegacyPTRCommand,
|
|
1326
|
+
LegacyPTRSiteCommand,
|
|
1327
|
+
LegacyPTRBuildingCommand,
|
|
1328
|
+
LegacyPTRLevelCommand,
|
|
1329
|
+
LegacyPTRPoiCommand,
|
|
1330
|
+
LegacyPTRPathCommand,
|
|
1331
|
+
LegacyPTRStaticPathCommand,
|
|
1332
|
+
LegacyPTRStaticWayfindingCommand,
|
|
1333
|
+
LegacyPTRMarkMyCarLevelCommand,
|
|
1334
|
+
LegacyPTRMarkMyCarSiteCommand,
|
|
1335
|
+
LegacyPTRShowMyCarSiteCommand,
|
|
1336
|
+
LegacyPTRStartAndFocusCommand,
|
|
1337
|
+
} from 'react-native-pointr';
|
|
861
1338
|
```
|
|
862
1339
|
|
|
863
1340
|
---
|
|
864
1341
|
|
|
865
1342
|
## Error Handling
|
|
866
1343
|
|
|
867
|
-
### Common
|
|
1344
|
+
### Common errors
|
|
868
1345
|
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
1346
|
+
| Error | Cause | Fix |
|
|
1347
|
+
|-------|-------|-----|
|
|
1348
|
+
| `"Pointr SDK is not initialized. Call initialize() first."` | `start()` or other methods called before `initialize()` | Call `pointrSdk.initialize(config)` first |
|
|
1349
|
+
| `"Pointr SDK is not started. Call start() first."` | SDK method called before `start()` completes | Wait for `isStarted` / `PTRState.RUNNING` |
|
|
1350
|
+
| `"Pointr SDK is already initialized."` | `initialize()` called twice on the same singleton | Guard with `pointrSdk.isInitialized()` |
|
|
1351
|
+
| `"Map widget reference is required."` | `executeMapCommand` called with a null or unmounted ref | Ensure the ref is attached and the component is mounted |
|
|
1352
|
+
| `"Invalid map command provided."` | `executeMapCommand` called with a command missing a `type` | Use a proper `PTRCommand` subclass |
|
|
873
1353
|
|
|
874
|
-
### Best
|
|
1354
|
+
### Best practices
|
|
875
1355
|
|
|
876
|
-
1.
|
|
877
|
-
2.
|
|
878
|
-
3.
|
|
879
|
-
4.
|
|
880
|
-
5. Initialize SDK before rendering the map widget
|
|
881
|
-
6. Request permissions before starting SDK if needed
|
|
1356
|
+
1. Use `usePointrSdk(config)` or the declarative `sdkConfig` prop — they handle lifecycle errors internally.
|
|
1357
|
+
2. Always remove event subscriptions in cleanup functions (`useEffect` return / `componentWillUnmount`).
|
|
1358
|
+
3. Check `isStarted` before calling `getCurrentLocation()` or dispatching map commands imperatively.
|
|
1359
|
+
4. Initialize SDK once at the application root — `PointrSdk` is a singleton and re-initialization throws.
|
|
882
1360
|
|
|
883
1361
|
---
|
|
884
1362
|
|