react-native-pointr 9.9.0 → 10.0.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 +284 -315
- package/CHANGELOG.md +36 -0
- package/EXTENDING.md +11 -16
- package/README.md +14 -14
- package/WAYFINDING_EVENTS.md +5 -3
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/pointr/PTRCoreExtensions.kt +33 -2
- package/android/src/main/java/com/pointr/PTRMapWidgetActionType.kt +17 -0
- package/android/src/main/java/com/pointr/PTRMapWidgetManager.kt +162 -406
- package/android/src/main/java/com/pointr/{PointrModule.kt → PTRNativeLibrary.kt} +150 -32
- package/android/src/main/java/com/pointr/{PointrPackage.kt → PTRPackage.kt} +2 -2
- package/ios/PTRMapWidgetContainerView.swift +174 -187
- package/ios/PTRMapWidgetManager-Bridging.m +12 -64
- package/ios/PTRMapWidgetManager.swift +164 -136
- package/ios/PTRNativeLibrary-Bridging.m +38 -2
- package/ios/PTRNativeLibrary.swift +206 -26
- package/package.json +5 -3
- package/react-native-pointr.podspec +1 -1
- package/src/NativePointrModule.ts +70 -0
- package/src/PTRMapWidgetUtils.ts +67 -144
- package/src/actions/index.ts +171 -0
- package/src/api/MapWidgetApi.ts +8 -8
- package/src/api/PointrSdk.ts +50 -91
- package/src/components/index.tsx +27 -26
- package/src/constants/index.ts +32 -13
- package/src/hooks/index.ts +1 -0
- package/src/hooks/usePointrGeofences.ts +37 -0
- package/src/hooks/usePointrSdk.ts +12 -5
- package/src/index.tsx +37 -70
- package/src/managers/PTRPoiManager.ts +2 -2
- package/src/types/PTRPoi.ts +5 -2
- package/src/types/PTRPosition.ts +15 -5
- package/src/types/PTRSite.ts +46 -0
- package/src/types/PTRWayfindingEvent.ts +11 -7
- package/src/types/config.ts +1 -0
- package/src/types/events.ts +1 -0
- package/src/types/index.ts +4 -0
- package/android/src/main/java/com/pointr/PTRMapWidgetCommandType.kt +0 -20
- package/src/PTRCommand.ts +0 -153
- package/src/api/index.ts +0 -9
- package/src/commands/index.ts +0 -275
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action pattern implementation for Pointr SDK
|
|
3
|
+
* Actions are immutable objects that represent operations to perform on the map
|
|
4
|
+
* @module commands
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { PTRActionType } from '../constants';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Base class for all Pointr SDK actions
|
|
11
|
+
*/
|
|
12
|
+
export abstract class PTRAction {
|
|
13
|
+
readonly type: PTRActionType;
|
|
14
|
+
|
|
15
|
+
constructor(type: PTRActionType) {
|
|
16
|
+
this.type = type;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Action to focus the map on a site, building, or level.
|
|
22
|
+
* All parameters are optional — provide only those needed for the desired zoom level.
|
|
23
|
+
*/
|
|
24
|
+
export class PTRFocusMapAction extends PTRAction {
|
|
25
|
+
readonly site: string;
|
|
26
|
+
readonly building?: string;
|
|
27
|
+
readonly level?: number;
|
|
28
|
+
|
|
29
|
+
constructor(site: string, building?: string, level?: number) {
|
|
30
|
+
super(PTRActionType.FOCUS_MAP);
|
|
31
|
+
this.site = site;
|
|
32
|
+
this.building = building;
|
|
33
|
+
this.level = level;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Action to highlight a Point of Interest on the map
|
|
39
|
+
*/
|
|
40
|
+
export class PTRHighlightPoiAction extends PTRAction {
|
|
41
|
+
readonly site: string;
|
|
42
|
+
readonly poi: string;
|
|
43
|
+
|
|
44
|
+
constructor(site: string, poi: string) {
|
|
45
|
+
super(PTRActionType.HIGHLIGHT_POI);
|
|
46
|
+
this.site = site;
|
|
47
|
+
this.poi = poi;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Action to display a static route between two POIs (no live location required).
|
|
53
|
+
* Both source and destination POIs must be specified.
|
|
54
|
+
*/
|
|
55
|
+
export class PTRDisplayRouteAction extends PTRAction {
|
|
56
|
+
readonly site: string;
|
|
57
|
+
readonly fromPoi: string;
|
|
58
|
+
readonly toPoi: string;
|
|
59
|
+
|
|
60
|
+
constructor(site: string, fromPoi: string, toPoi: string) {
|
|
61
|
+
super(PTRActionType.DISPLAY_ROUTE);
|
|
62
|
+
this.site = site;
|
|
63
|
+
this.fromPoi = fromPoi;
|
|
64
|
+
this.toPoi = toPoi;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Action to start wayfinding from the user's current position to a destination POI.
|
|
70
|
+
*/
|
|
71
|
+
export class PTRStartWayfindingAction extends PTRAction {
|
|
72
|
+
readonly site: string;
|
|
73
|
+
readonly poi: string;
|
|
74
|
+
|
|
75
|
+
constructor(site: string, poi: string) {
|
|
76
|
+
super(PTRActionType.START_WAYFINDING);
|
|
77
|
+
this.site = site;
|
|
78
|
+
this.poi = poi;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Action to mark the car location.
|
|
84
|
+
* When building and level are provided, marks at a specific level.
|
|
85
|
+
* Otherwise marks at the site level.
|
|
86
|
+
*/
|
|
87
|
+
export class PTRMarkMyCarAction extends PTRAction {
|
|
88
|
+
readonly site: string;
|
|
89
|
+
readonly building?: string;
|
|
90
|
+
readonly level?: number;
|
|
91
|
+
readonly shouldShowPopup: boolean;
|
|
92
|
+
readonly animationType: number;
|
|
93
|
+
|
|
94
|
+
constructor(
|
|
95
|
+
site: string,
|
|
96
|
+
building?: string,
|
|
97
|
+
level?: number,
|
|
98
|
+
shouldShowPopup: boolean = true,
|
|
99
|
+
animationType: number = 1
|
|
100
|
+
) {
|
|
101
|
+
super(PTRActionType.MARK_MY_CAR);
|
|
102
|
+
this.site = site;
|
|
103
|
+
this.building = building;
|
|
104
|
+
this.level = level;
|
|
105
|
+
this.shouldShowPopup = shouldShowPopup;
|
|
106
|
+
this.animationType = animationType;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Action to show the previously saved car location at a site
|
|
112
|
+
*/
|
|
113
|
+
export class PTRShowMyCarAction extends PTRAction {
|
|
114
|
+
readonly site: string;
|
|
115
|
+
readonly shouldShowPopup: boolean;
|
|
116
|
+
readonly animationType: number;
|
|
117
|
+
|
|
118
|
+
constructor(
|
|
119
|
+
site: string,
|
|
120
|
+
shouldShowPopup: boolean = true,
|
|
121
|
+
animationType: number = 1
|
|
122
|
+
) {
|
|
123
|
+
super(PTRActionType.SHOW_MY_CAR);
|
|
124
|
+
this.site = site;
|
|
125
|
+
this.shouldShowPopup = shouldShowPopup;
|
|
126
|
+
this.animationType = animationType;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Action to focus the map on a specific geographic coordinate.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* new PTRFocusCoordinateAction(SITE_ID, 47.4979, 19.0402, 2)
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export class PTRFocusCoordinateAction extends PTRAction {
|
|
139
|
+
readonly site: string;
|
|
140
|
+
readonly latitude: number;
|
|
141
|
+
readonly longitude: number;
|
|
142
|
+
readonly levelIndex?: number;
|
|
143
|
+
|
|
144
|
+
constructor(site: string, latitude: number, longitude: number, levelIndex?: number) {
|
|
145
|
+
super(PTRActionType.FOCUS_COORDINATE);
|
|
146
|
+
this.site = site;
|
|
147
|
+
this.latitude = latitude;
|
|
148
|
+
this.longitude = longitude;
|
|
149
|
+
this.levelIndex = levelIndex;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Action to filter map POIs by one or more category identifiers.
|
|
155
|
+
* Pass an empty array to clear the active filter.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* new PTRHighlightCategoryAction(SITE_ID, ['cafes', 'restaurants'])
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
export class PTRHighlightCategoryAction extends PTRAction {
|
|
163
|
+
readonly site: string;
|
|
164
|
+
readonly categoryIds: string[];
|
|
165
|
+
|
|
166
|
+
constructor(site: string, categoryIds: string[]) {
|
|
167
|
+
super(PTRActionType.HIGHLIGHT_CATEGORY);
|
|
168
|
+
this.site = site;
|
|
169
|
+
this.categoryIds = categoryIds;
|
|
170
|
+
}
|
|
171
|
+
}
|
package/src/api/MapWidgetApi.ts
CHANGED
|
@@ -5,19 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { findNodeHandle } from 'react-native';
|
|
8
|
-
import type {
|
|
8
|
+
import type { PTRAction } from '../actions';
|
|
9
9
|
import { PTRErrorMessages } from '../constants';
|
|
10
10
|
import { showMapWidget } from '../PTRMapWidgetUtils';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Execute
|
|
13
|
+
* Execute an action on the map widget
|
|
14
14
|
* @param mapRef - Reference to the map widget component
|
|
15
|
-
* @param
|
|
16
|
-
* @throws Error if mapRef is null or
|
|
15
|
+
* @param action - Action to execute
|
|
16
|
+
* @throws Error if mapRef is null or action is invalid
|
|
17
17
|
*/
|
|
18
|
-
export function
|
|
18
|
+
export function executeMapAction(
|
|
19
19
|
mapRef: React.RefObject<any> | any,
|
|
20
|
-
|
|
20
|
+
action: PTRAction
|
|
21
21
|
): void {
|
|
22
22
|
if (!mapRef) {
|
|
23
23
|
throw new Error(PTRErrorMessages.NO_MAP_REF);
|
|
@@ -30,12 +30,12 @@ export function executeMapCommand(
|
|
|
30
30
|
throw new Error(PTRErrorMessages.NO_MAP_REF);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
if (!
|
|
33
|
+
if (!action || !action.type) {
|
|
34
34
|
throw new Error(PTRErrorMessages.INVALID_COMMAND);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
try {
|
|
38
|
-
showMapWidget(reactTag,
|
|
38
|
+
showMapWidget(reactTag, action);
|
|
39
39
|
} catch (error) {
|
|
40
40
|
console.error('Error executing map command:', error);
|
|
41
41
|
throw error;
|
package/src/api/PointrSdk.ts
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
|
|
8
|
-
import type { PTRConfiguration, PTRMapWidgetConfiguration
|
|
8
|
+
import type { PTRConfiguration, PTRMapWidgetConfiguration } from '../types/config';
|
|
9
9
|
import type { PTRPosition } from '../types/PTRPosition';
|
|
10
|
+
import type { PTRGeofence } from '../types/events';
|
|
10
11
|
import { PTRState, PTRLogLevel, PTRErrorMessages, PTREvents } from '../constants';
|
|
11
12
|
|
|
12
13
|
const LINKING_ERROR =
|
|
@@ -15,8 +16,8 @@ const LINKING_ERROR =
|
|
|
15
16
|
'- You rebuilt the app after installing the package\n' +
|
|
16
17
|
'- You are not using Expo Go\n';
|
|
17
18
|
|
|
18
|
-
const
|
|
19
|
-
? NativeModules.
|
|
19
|
+
const PTRNativeLibrary = NativeModules.PTRNativeLibrary
|
|
20
|
+
? NativeModules.PTRNativeLibrary
|
|
20
21
|
: new Proxy(
|
|
21
22
|
{},
|
|
22
23
|
{
|
|
@@ -36,12 +37,10 @@ export class PointrSdk {
|
|
|
36
37
|
private eventEmitter: NativeEventEmitter;
|
|
37
38
|
|
|
38
39
|
private constructor() {
|
|
39
|
-
this.eventEmitter = new NativeEventEmitter(
|
|
40
|
+
this.eventEmitter = new NativeEventEmitter(PTRNativeLibrary);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
/**
|
|
43
|
-
* Get the singleton instance of PointrSdk
|
|
44
|
-
*/
|
|
43
|
+
/** Get the singleton instance of PointrSdk */
|
|
45
44
|
public static getInstance(): PointrSdk {
|
|
46
45
|
if (!PointrSdk.instance) {
|
|
47
46
|
PointrSdk.instance = new PointrSdk();
|
|
@@ -58,7 +57,6 @@ export class PointrSdk {
|
|
|
58
57
|
if (this.state !== PTRState.NOT_INITIALIZED) {
|
|
59
58
|
throw new Error(PTRErrorMessages.ALREADY_INITIALIZED);
|
|
60
59
|
}
|
|
61
|
-
|
|
62
60
|
if (!config.clientId || !config.licenseKey || !config.baseUrl) {
|
|
63
61
|
throw new Error(PTRErrorMessages.INVALID_CONFIG);
|
|
64
62
|
}
|
|
@@ -67,9 +65,8 @@ export class PointrSdk {
|
|
|
67
65
|
this.config = config;
|
|
68
66
|
|
|
69
67
|
const logLevel = config.logLevel ?? PTRLogLevel.ERROR;
|
|
70
|
-
|
|
71
68
|
try {
|
|
72
|
-
|
|
69
|
+
PTRNativeLibrary.initialize(
|
|
73
70
|
config.clientId,
|
|
74
71
|
config.licenseKey,
|
|
75
72
|
config.baseUrl,
|
|
@@ -83,132 +80,88 @@ export class PointrSdk {
|
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
/**
|
|
86
|
-
* Start the Pointr SDK
|
|
87
|
-
*
|
|
83
|
+
* Start the Pointr SDK.
|
|
84
|
+
* Resolves when the SDK reaches the RUNNING state.
|
|
88
85
|
* @throws Error if not initialized
|
|
89
86
|
*/
|
|
90
|
-
public start(
|
|
87
|
+
public start(): Promise<void> {
|
|
91
88
|
if (this.state === PTRState.NOT_INITIALIZED) {
|
|
92
|
-
|
|
89
|
+
return Promise.reject(new Error(PTRErrorMessages.NOT_INITIALIZED));
|
|
93
90
|
}
|
|
94
|
-
|
|
95
91
|
this.state = PTRState.STARTING;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
PTRNativePointrLibrary.start((state: string) => {
|
|
92
|
+
return PTRNativeLibrary.start()
|
|
93
|
+
.then(() => {
|
|
99
94
|
this.state = PTRState.RUNNING;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
})
|
|
96
|
+
.catch((error: Error) => {
|
|
97
|
+
this.state = PTRState.ERROR;
|
|
98
|
+
throw error;
|
|
103
99
|
});
|
|
104
|
-
} catch (error) {
|
|
105
|
-
this.state = PTRState.ERROR;
|
|
106
|
-
throw error;
|
|
107
|
-
}
|
|
108
100
|
}
|
|
109
101
|
|
|
110
|
-
/**
|
|
111
|
-
* Stop the Pointr SDK
|
|
112
|
-
*/
|
|
102
|
+
/** Stop the Pointr SDK */
|
|
113
103
|
public stop(): void {
|
|
114
104
|
if (this.state === PTRState.RUNNING) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.state = PTRState.STOPPED;
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.error('Error stopping Pointr SDK:', error);
|
|
120
|
-
throw error;
|
|
121
|
-
}
|
|
105
|
+
PTRNativeLibrary.stop();
|
|
106
|
+
this.state = PTRState.STOPPED;
|
|
122
107
|
}
|
|
123
108
|
}
|
|
124
109
|
|
|
125
|
-
/**
|
|
126
|
-
* Get the current SDK state
|
|
127
|
-
*/
|
|
110
|
+
/** Get the current SDK state */
|
|
128
111
|
public getState(): PTRState {
|
|
129
112
|
return this.state;
|
|
130
113
|
}
|
|
131
114
|
|
|
132
|
-
/**
|
|
133
|
-
* Check if SDK is initialized
|
|
134
|
-
*/
|
|
115
|
+
/** Check if SDK is initialized */
|
|
135
116
|
public isInitialized(): boolean {
|
|
136
117
|
return this.state !== PTRState.NOT_INITIALIZED;
|
|
137
118
|
}
|
|
138
119
|
|
|
139
|
-
/**
|
|
140
|
-
* Check if SDK is started and running
|
|
141
|
-
*/
|
|
120
|
+
/** Check if SDK is started and running */
|
|
142
121
|
public isStarted(): boolean {
|
|
143
122
|
return this.state === PTRState.RUNNING;
|
|
144
123
|
}
|
|
145
124
|
|
|
146
|
-
/**
|
|
147
|
-
* Get the current configuration
|
|
148
|
-
*/
|
|
125
|
+
/** Get the current configuration */
|
|
149
126
|
public getConfig(): PTRConfiguration | null {
|
|
150
127
|
return this.config;
|
|
151
128
|
}
|
|
152
129
|
|
|
153
|
-
/**
|
|
154
|
-
* Get the event emitter for subscribing to Pointr events
|
|
155
|
-
*/
|
|
130
|
+
/** Get the event emitter for subscribing to Pointr events */
|
|
156
131
|
public getEventEmitter(): NativeEventEmitter {
|
|
157
132
|
return this.eventEmitter;
|
|
158
133
|
}
|
|
159
134
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* @returns Subscription that can be removed
|
|
164
|
-
*/
|
|
135
|
+
// ─── Event subscriptions ───────────────────────────────────────────────────
|
|
136
|
+
|
|
137
|
+
/** Subscribe to position updates */
|
|
165
138
|
public onPositionUpdate(callback: (position: any) => void) {
|
|
166
|
-
return this.eventEmitter.addListener(
|
|
167
|
-
PTREvents.ON_POSITION_CALCULATED,
|
|
168
|
-
callback
|
|
169
|
-
);
|
|
139
|
+
return this.eventEmitter.addListener(PTREvents.ON_POSITION_CALCULATED, callback);
|
|
170
140
|
}
|
|
171
141
|
|
|
172
|
-
/**
|
|
173
|
-
* Subscribe to building click events
|
|
174
|
-
* @param callback - Function to call when building is clicked
|
|
175
|
-
* @returns Subscription that can be removed
|
|
176
|
-
*/
|
|
142
|
+
/** Subscribe to building click events */
|
|
177
143
|
public onBuildingClick(callback: (event: any) => void) {
|
|
178
|
-
return this.eventEmitter.addListener(
|
|
179
|
-
PTREvents.ON_BUILDING_CLICKED,
|
|
180
|
-
callback
|
|
181
|
-
);
|
|
144
|
+
return this.eventEmitter.addListener(PTREvents.ON_BUILDING_CLICKED, callback);
|
|
182
145
|
}
|
|
183
146
|
|
|
184
|
-
/**
|
|
185
|
-
* Subscribe to site click events
|
|
186
|
-
* @param callback - Function to call when site is clicked
|
|
187
|
-
* @returns Subscription that can be removed
|
|
188
|
-
*/
|
|
147
|
+
/** Subscribe to site click events */
|
|
189
148
|
public onSiteClick(callback: (event: any) => void) {
|
|
190
149
|
return this.eventEmitter.addListener(PTREvents.ON_SITE_CLICKED, callback);
|
|
191
150
|
}
|
|
192
151
|
|
|
193
|
-
/**
|
|
194
|
-
* Subscribe to geofence events
|
|
195
|
-
* @param callback - Function to call when geofence event occurs
|
|
196
|
-
* @returns Subscription that can be removed
|
|
197
|
-
*/
|
|
152
|
+
/** Subscribe to geofence events */
|
|
198
153
|
public onGeofenceEvent(callback: (event: any) => void) {
|
|
199
|
-
return this.eventEmitter.addListener(
|
|
200
|
-
PTREvents.ON_GEOFENCE_EVENT,
|
|
201
|
-
callback
|
|
202
|
-
);
|
|
154
|
+
return this.eventEmitter.addListener(PTREvents.ON_GEOFENCE_EVENT, callback);
|
|
203
155
|
}
|
|
204
156
|
|
|
157
|
+
// ─── Map widget ────────────────────────────────────────────────────────────
|
|
158
|
+
|
|
205
159
|
/**
|
|
206
|
-
* Set the map widget configuration
|
|
160
|
+
* Set the map widget configuration.
|
|
207
161
|
* Must be called before the map widget renders to take effect.
|
|
208
|
-
* @param config - Map widget configuration options
|
|
209
162
|
*/
|
|
210
163
|
public setMapWidgetConfiguration(config: PTRMapWidgetConfiguration): void {
|
|
211
|
-
|
|
164
|
+
PTRNativeLibrary.setPointrMapWidgetConfiguration(JSON.stringify(config));
|
|
212
165
|
}
|
|
213
166
|
|
|
214
167
|
/**
|
|
@@ -217,7 +170,7 @@ export class PointrSdk {
|
|
|
217
170
|
*/
|
|
218
171
|
public getCurrentLocation(): Promise<PTRPosition | null> {
|
|
219
172
|
return new Promise((resolve) => {
|
|
220
|
-
|
|
173
|
+
PTRNativeLibrary.getCurrentLocation((result: any) => {
|
|
221
174
|
if (!result || typeof result === 'string') {
|
|
222
175
|
resolve(null);
|
|
223
176
|
} else {
|
|
@@ -227,15 +180,21 @@ export class PointrSdk {
|
|
|
227
180
|
});
|
|
228
181
|
}
|
|
229
182
|
|
|
183
|
+
// ─── Geofences ─────────────────────────────────────────────────────────────
|
|
184
|
+
|
|
230
185
|
/**
|
|
231
|
-
* Get
|
|
186
|
+
* Get all configured geofences for a site.
|
|
187
|
+
* @param siteId - External site identifier
|
|
232
188
|
*/
|
|
189
|
+
public getGeofences(siteId: string): Promise<PTRGeofence[]> {
|
|
190
|
+
return PTRNativeLibrary.getGeofences(siteId);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Get native module reference (for advanced use cases) */
|
|
233
194
|
public getNativeModule() {
|
|
234
|
-
return
|
|
195
|
+
return PTRNativeLibrary;
|
|
235
196
|
}
|
|
236
197
|
}
|
|
237
198
|
|
|
238
|
-
/**
|
|
239
|
-
* Export singleton instance for easy access
|
|
240
|
-
*/
|
|
199
|
+
/** Singleton instance for easy access */
|
|
241
200
|
export const pointrSdk = PointrSdk.getInstance();
|
package/src/components/index.tsx
CHANGED
|
@@ -10,9 +10,11 @@ import {
|
|
|
10
10
|
ViewStyle,
|
|
11
11
|
} from 'react-native';
|
|
12
12
|
import type { PTRWayfindingEvent } from '../types/PTRWayfindingEvent';
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
PTRMapCommandResponse,
|
|
15
|
+
} from '../types/events';
|
|
14
16
|
import type { PTRConfiguration, PTRMapWidgetConfiguration } from '../types/config';
|
|
15
|
-
import type {
|
|
17
|
+
import type { PTRAction } from '../actions';
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Native PTRMapWidget component
|
|
@@ -27,18 +29,15 @@ export interface PTRMapWidgetProps {
|
|
|
27
29
|
/** Component style */
|
|
28
30
|
style?: ViewStyle;
|
|
29
31
|
/**
|
|
30
|
-
* Declarative
|
|
32
|
+
* Declarative action that the map widget executes automatically on mount.
|
|
31
33
|
* When provided the SDK is started if not already running, removing the need
|
|
32
|
-
* for an imperative `
|
|
34
|
+
* for an imperative `executeMapAction` call after the widget loads.
|
|
33
35
|
*
|
|
34
|
-
* Supports all
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* <PTRMapWidget command={new PTRSiteCommand('my-site')} style={{ flex: 1 }} />
|
|
36
|
+
* Supports all PTRAction subtypes: PTRFocusMapAction, PTRHighlightPoiAction,
|
|
37
|
+
* PTRFocusCoordinateAction, PTRHighlightCategoryAction, PTRDisplayRouteAction,
|
|
38
|
+
* PTRStartWayfindingAction.
|
|
40
39
|
*/
|
|
41
|
-
|
|
40
|
+
action?: PTRAction;
|
|
42
41
|
/**
|
|
43
42
|
* Optional SDK credentials. When provided the widget initialises the Pointr
|
|
44
43
|
* SDK with these credentials rather than relying on a prior `pointrSdk.initialize()` call.
|
|
@@ -47,21 +46,23 @@ export interface PTRMapWidgetProps {
|
|
|
47
46
|
/**
|
|
48
47
|
* Map widget UI configuration applied before the widget renders.
|
|
49
48
|
* Equivalent to calling `pointrSdk.setMapWidgetConfiguration(...)` imperatively.
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* <PTRMapWidget
|
|
53
|
-
* mapWidgetConfig={{ isLevelSelectorEnabled: true, isJoystickEnabled: true }}
|
|
54
|
-
* />
|
|
55
49
|
*/
|
|
56
50
|
mapWidgetConfig?: PTRMapWidgetConfiguration;
|
|
57
|
-
|
|
51
|
+
|
|
52
|
+
// ─── Map lifecycle events ────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
/** Fired when the map finishes loading */
|
|
58
55
|
onMapWidgetDidEndLoading?: (
|
|
59
56
|
event: NativeSyntheticEvent<PTRMapCommandResponse>
|
|
60
57
|
) => void;
|
|
61
|
-
|
|
58
|
+
|
|
59
|
+
// ─── Navigation events ───────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
/** Fired when wayfinding starts, ends, or is cancelled */
|
|
62
62
|
onWayfindingEvent?: (
|
|
63
63
|
event: NativeSyntheticEvent<PTRWayfindingEvent>
|
|
64
64
|
) => void;
|
|
65
|
+
|
|
65
66
|
/** Additional native props */
|
|
66
67
|
[key: string]: any;
|
|
67
68
|
}
|
|
@@ -79,13 +80,13 @@ interface NativePTRMapWidgetProps extends PTRMapWidgetProps {}
|
|
|
79
80
|
*
|
|
80
81
|
* @example
|
|
81
82
|
* ```tsx
|
|
82
|
-
* import { PTRMapWidget,
|
|
83
|
+
* import { PTRMapWidget, PTRFocusMapAction, executeMapAction } from 'react-native-pointr';
|
|
83
84
|
*
|
|
84
85
|
* function MyMap() {
|
|
85
86
|
* const mapRef = useRef(null);
|
|
86
87
|
*
|
|
87
88
|
* const showSite = () => {
|
|
88
|
-
*
|
|
89
|
+
* executeMapAction(mapRef, new PTRFocusMapAction('my-site'));
|
|
89
90
|
* };
|
|
90
91
|
*
|
|
91
92
|
* return (
|
|
@@ -100,20 +101,20 @@ interface NativePTRMapWidgetProps extends PTRMapWidgetProps {}
|
|
|
100
101
|
* ```
|
|
101
102
|
*/
|
|
102
103
|
/**
|
|
103
|
-
* Serialize a
|
|
104
|
+
* Serialize a PTRAction to the JSON string expected by the native action prop.
|
|
104
105
|
*/
|
|
105
|
-
function serializeCommand(
|
|
106
|
-
const base = { type:
|
|
106
|
+
function serializeCommand(action: PTRAction): string {
|
|
107
|
+
const base = { type: action.type, ...(action as any) };
|
|
107
108
|
// Remove the 'type' key duplication from spread then re-add cleanly
|
|
108
109
|
return JSON.stringify(base);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
export const PTRMapWidget = forwardRef<any, PTRMapWidgetProps>(
|
|
112
113
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
|
-
({
|
|
114
|
+
({ action, sdkConfig, mapWidgetConfig, ...rest }: PTRMapWidgetProps, ref: any) => {
|
|
114
115
|
const nativeProps: Record<string, any> = { ...rest };
|
|
115
|
-
if (
|
|
116
|
-
nativeProps.
|
|
116
|
+
if (action) {
|
|
117
|
+
nativeProps.action = serializeCommand(action);
|
|
117
118
|
}
|
|
118
119
|
if (sdkConfig) {
|
|
119
120
|
nativeProps.sdkConfig = JSON.stringify(sdkConfig);
|
package/src/constants/index.ts
CHANGED
|
@@ -74,20 +74,39 @@ export const PTREvents = {
|
|
|
74
74
|
} as const;
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* Action types supported by the Pointr SDK
|
|
78
78
|
*/
|
|
79
|
-
export enum
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
79
|
+
export enum PTRActionType {
|
|
80
|
+
FOCUS_MAP = 'focusMap',
|
|
81
|
+
HIGHLIGHT_POI = 'highlightPoi',
|
|
82
|
+
DISPLAY_ROUTE = 'displayRoute',
|
|
83
|
+
START_WAYFINDING = 'startWayfinding',
|
|
84
|
+
MARK_MY_CAR = 'markMyCar',
|
|
85
|
+
SHOW_MY_CAR = 'showMyCar',
|
|
86
|
+
FOCUS_COORDINATE = 'focusCoordinate',
|
|
87
|
+
HIGHLIGHT_CATEGORY = 'highlightCategory',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Wayfinding mode controlling accessible vs standard routing
|
|
92
|
+
*/
|
|
93
|
+
export enum PTRWayfindingMode {
|
|
94
|
+
/** Standard routing */
|
|
95
|
+
NORMAL = 'normal',
|
|
96
|
+
/** Accessible routing (avoids stairs, prefers ramps/lifts) */
|
|
97
|
+
ACCESSIBLE = 'accessible',
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Wayfinding event type — lifecycle of a navigation session
|
|
102
|
+
*/
|
|
103
|
+
export enum PTRWayfindingEventType {
|
|
104
|
+
/** Wayfinding was cancelled by the user */
|
|
105
|
+
CANCELLED = -1,
|
|
106
|
+
/** Wayfinding session started */
|
|
107
|
+
STARTED = 0,
|
|
108
|
+
/** Wayfinding session ended (destination reached) */
|
|
109
|
+
ENDED = 1,
|
|
91
110
|
}
|
|
92
111
|
|
|
93
112
|
/**
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useEffect, useState, useCallback } from 'react';
|
|
2
|
+
import { pointrSdk } from '../api/PointrSdk';
|
|
3
|
+
import type { PTRGeofence } from '../types/events';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook that loads configured geofences for a site.
|
|
7
|
+
*
|
|
8
|
+
* @param siteId - External site identifier
|
|
9
|
+
* @returns `{ geofences, loading, error, refresh }`
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* const { geofences, loading } = usePointrGeofences(SITE_ID);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function usePointrGeofences(siteId: string | undefined) {
|
|
17
|
+
const [geofences, setGeofences] = useState<PTRGeofence[]>([]);
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const [error, setError] = useState<Error | null>(null);
|
|
20
|
+
|
|
21
|
+
const refresh = useCallback(() => {
|
|
22
|
+
if (!siteId) return;
|
|
23
|
+
setLoading(true);
|
|
24
|
+
setError(null);
|
|
25
|
+
pointrSdk
|
|
26
|
+
.getGeofences(siteId)
|
|
27
|
+
.then(setGeofences)
|
|
28
|
+
.catch((err: Error) => setError(err))
|
|
29
|
+
.finally(() => setLoading(false));
|
|
30
|
+
}, [siteId]);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
refresh();
|
|
34
|
+
}, [refresh]);
|
|
35
|
+
|
|
36
|
+
return { geofences, loading, error, refresh };
|
|
37
|
+
}
|