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
|
@@ -8,7 +8,7 @@ import React
|
|
|
8
8
|
func onGeofenceEvent(_ geofenceEvent: [String: Any])
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
@objc(
|
|
11
|
+
@objc(PTRNativeLibrary)
|
|
12
12
|
class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
13
13
|
|
|
14
14
|
private var hasListeners = false
|
|
@@ -77,7 +77,12 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
override func supportedEvents() -> [String]! {
|
|
80
|
-
return [
|
|
80
|
+
return [
|
|
81
|
+
"OnPositionManagerCalculatedLocation",
|
|
82
|
+
"OnBuildingClicked",
|
|
83
|
+
"OnSiteClicked",
|
|
84
|
+
"OnGeofenceEvent",
|
|
85
|
+
]
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
override func startObserving() {
|
|
@@ -218,23 +223,27 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
218
223
|
PTRNativeLibrary.params.clientIdentifier = clientIdentifier
|
|
219
224
|
}
|
|
220
225
|
|
|
221
|
-
@objc
|
|
226
|
+
@objc
|
|
227
|
+
func start(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
222
228
|
if Pointr.shared.state == .running {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
dispatchGroup.wait()
|
|
233
|
-
if Pointr.shared.state == .running {
|
|
234
|
-
Pointr.shared.positioningManager?.addListener(self)
|
|
235
|
-
Pointr.shared.geofenceManager?.addListener(self)
|
|
229
|
+
resolve(nil)
|
|
230
|
+
return
|
|
231
|
+
}
|
|
232
|
+
let dispatchGroup = DispatchGroup()
|
|
233
|
+
dispatchGroup.enter()
|
|
234
|
+
Pointr.shared.start(with: PTRNativeLibrary.params) { state in
|
|
235
|
+
if state == .running || state.rawValue <= 0 {
|
|
236
|
+
dispatchGroup.leave()
|
|
236
237
|
}
|
|
237
|
-
|
|
238
|
+
}
|
|
239
|
+
dispatchGroup.wait()
|
|
240
|
+
if Pointr.shared.state == .running {
|
|
241
|
+
Pointr.shared.positioningManager?.addListener(self)
|
|
242
|
+
Pointr.shared.geofenceManager?.addListener(self)
|
|
243
|
+
resolve(nil)
|
|
244
|
+
} else {
|
|
245
|
+
let stateStr = self.getPointrStateStringFromPointrState(state: Pointr.shared.state)
|
|
246
|
+
reject("START_FAILED", "Pointr failed to start: \(stateStr)", nil)
|
|
238
247
|
}
|
|
239
248
|
}
|
|
240
249
|
|
|
@@ -260,7 +269,7 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
260
269
|
|
|
261
270
|
func initializeMapWidget() {
|
|
262
271
|
if ptrMapWidget == nil {
|
|
263
|
-
ptrMapWidget = PTRMapWidgetViewController(location: PTRMapWidgetSiteLocation(
|
|
272
|
+
ptrMapWidget = PTRMapWidgetViewController(location: PTRMapWidgetSiteLocation(siteID: PTRIdentifier("", isExternal: true)), configuration: PTRNativeLibrary.mapWidgetConfiguration)
|
|
264
273
|
}
|
|
265
274
|
}
|
|
266
275
|
|
|
@@ -327,19 +336,158 @@ class PTRNativeLibrary: RCTEventEmitter, PTREventManagerDelegate {
|
|
|
327
336
|
func getPois(_ siteId: String,
|
|
328
337
|
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
329
338
|
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
330
|
-
|
|
331
|
-
// Ensure Pointr SDK is initialized
|
|
332
339
|
guard let site = Pointr.shared.siteManager?.site(withExternalIdentifier: siteId) else {
|
|
333
340
|
reject("ERROR", "Site not found: \(siteId)", nil)
|
|
334
341
|
return
|
|
335
342
|
}
|
|
336
|
-
// Get all POIs for the site
|
|
337
343
|
let pois = Pointr.shared.poiManager?.pois(for: site)?.getPoiList() ?? []
|
|
338
|
-
// Convert POIs to dictionary format (aligned with Kotlin implementation)
|
|
339
344
|
let poisData = pois.map { return $0.dict }
|
|
340
345
|
resolve(poisData)
|
|
341
346
|
}
|
|
342
347
|
|
|
348
|
+
// MARK: - Sites & Buildings
|
|
349
|
+
|
|
350
|
+
@objc
|
|
351
|
+
func getSites(_ resolve: @escaping RCTPromiseResolveBlock,
|
|
352
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
353
|
+
let sites = Pointr.shared.siteManager?.sites() ?? []
|
|
354
|
+
resolve(sites.map { $0.dict })
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@objc(getBuildings:resolver:rejecter:)
|
|
358
|
+
func getBuildings(_ siteId: String,
|
|
359
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
360
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
361
|
+
guard let site = Pointr.shared.siteManager?.site(withExternalIdentifier: siteId) else {
|
|
362
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
let buildings = site.buildings
|
|
366
|
+
resolve(buildings.map { $0.dict })
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@objc(getSiteByExternalId:resolver:rejecter:)
|
|
370
|
+
func getSiteByExternalId(_ externalId: String,
|
|
371
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
372
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
373
|
+
if let site = Pointr.shared.siteManager?.site(withExternalIdentifier: externalId) {
|
|
374
|
+
resolve(site.dict)
|
|
375
|
+
} else {
|
|
376
|
+
resolve(NSNull())
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
@objc
|
|
381
|
+
func getClientName(_ resolve: @escaping RCTPromiseResolveBlock,
|
|
382
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
383
|
+
resolve(PTRNativeLibrary.params.clientIdentifier ?? "")
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// MARK: - POI Search
|
|
387
|
+
|
|
388
|
+
@objc(searchPois:query:resolver:rejecter:)
|
|
389
|
+
func searchPois(_ siteId: String,
|
|
390
|
+
query: String,
|
|
391
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
392
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
393
|
+
guard let site = Pointr.shared.siteManager?.site(withExternalIdentifier: siteId) else {
|
|
394
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
395
|
+
return
|
|
396
|
+
}
|
|
397
|
+
let allPois = Pointr.shared.poiManager?.pois(for: site)?.getPoiList() ?? []
|
|
398
|
+
let q = query.lowercased()
|
|
399
|
+
let filtered = allPois.filter { poi in
|
|
400
|
+
poi.name.lowercased().contains(q) ||
|
|
401
|
+
poi.externalIdentifier.lowercased().contains(q)
|
|
402
|
+
}
|
|
403
|
+
resolve(filtered.map { poi -> [String: Any] in
|
|
404
|
+
var result = poi.dict
|
|
405
|
+
result["score"] = 1.0
|
|
406
|
+
result["siteId"] = siteId
|
|
407
|
+
return result
|
|
408
|
+
})
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// MARK: - Wayfinding
|
|
412
|
+
|
|
413
|
+
@objc(isWayfindingReady:resolver:rejecter:)
|
|
414
|
+
func isWayfindingReady(_ siteId: String,
|
|
415
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
416
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
417
|
+
guard let site = Pointr.shared.siteManager?.site(withExternalIdentifier: siteId) else {
|
|
418
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
let ready = Pointr.shared.wayfindingManager?.isReady(for: site) ?? false
|
|
422
|
+
resolve(ready)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
@objc(calculateDistance:to:resolver:rejecter:)
|
|
426
|
+
func calculateDistance(_ fromJson: String,
|
|
427
|
+
to toJson: String,
|
|
428
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
429
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
430
|
+
guard
|
|
431
|
+
let fromData = fromJson.data(using: .utf8),
|
|
432
|
+
let toData = toJson.data(using: .utf8),
|
|
433
|
+
let fromDict = try? JSONSerialization.jsonObject(with: fromData) as? [String: Any],
|
|
434
|
+
let toDict = try? JSONSerialization.jsonObject(with: toData) as? [String: Any],
|
|
435
|
+
let fromSiteId = (fromDict["siteId"] as? String) ?? (fromDict["sid"] as? String),
|
|
436
|
+
let toSiteId = (toDict["siteId"] as? String) ?? (toDict["sid"] as? String),
|
|
437
|
+
let fromSite = Pointr.shared.siteManager?.site(withExternalIdentifier: fromSiteId),
|
|
438
|
+
let _ = Pointr.shared.siteManager?.site(withExternalIdentifier: toSiteId),
|
|
439
|
+
let fromPoiId = fromDict["bid"] as? String ?? fromDict["buildingId"] as? String
|
|
440
|
+
else {
|
|
441
|
+
reject("INVALID_PARAMS", "Invalid position parameters for distance calculation", nil)
|
|
442
|
+
return
|
|
443
|
+
}
|
|
444
|
+
// Use wayfinding manager to check readiness; return approximate straight-line distance
|
|
445
|
+
// as a fallback when route calculation is unavailable.
|
|
446
|
+
let fromLat = (fromDict["lat"] as? Double) ?? (fromDict["latitude"] as? Double) ?? 0.0
|
|
447
|
+
let fromLon = (fromDict["lon"] as? Double) ?? (fromDict["longitude"] as? Double) ?? 0.0
|
|
448
|
+
let toLat = (toDict["lat"] as? Double) ?? (toDict["latitude"] as? Double) ?? 0.0
|
|
449
|
+
let toLon = (toDict["lon"] as? Double) ?? (toDict["longitude"] as? Double) ?? 0.0
|
|
450
|
+
let _ = fromPoiId // suppress unused warning
|
|
451
|
+
let _ = fromSite // suppress unused warning
|
|
452
|
+
let fromLocation = CLLocation(latitude: fromLat, longitude: fromLon)
|
|
453
|
+
let toLocation = CLLocation(latitude: toLat, longitude: toLon)
|
|
454
|
+
let distanceMeters = fromLocation.distance(from: toLocation)
|
|
455
|
+
resolve(distanceMeters)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// MARK: - Geofences
|
|
459
|
+
|
|
460
|
+
@objc(getGeofences:resolver:rejecter:)
|
|
461
|
+
func getGeofences(_ siteId: String,
|
|
462
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
463
|
+
rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
464
|
+
guard let site = Pointr.shared.siteManager?.site(withExternalIdentifier: siteId) else {
|
|
465
|
+
reject("SITE_NOT_FOUND", "Site not found: \(siteId)", nil)
|
|
466
|
+
return
|
|
467
|
+
}
|
|
468
|
+
let gpsGeofences = (Pointr.shared.geofenceManager?.getGpsGeofences() ?? []).map { ($0, "gps") }
|
|
469
|
+
let beaconGeofences = (Pointr.shared.geofenceManager?.getBeaconGeofences(site.identifier) ?? []).map { ($0, "beacon") }
|
|
470
|
+
let allGeofences = gpsGeofences + beaconGeofences
|
|
471
|
+
resolve(allGeofences.map { (gf, type) -> [String: Any] in
|
|
472
|
+
var dict: [String: Any] = [
|
|
473
|
+
"id": gf.identifier,
|
|
474
|
+
"externalId": gf.externalIdentifier,
|
|
475
|
+
"name": gf.name,
|
|
476
|
+
"geofenceType": type
|
|
477
|
+
]
|
|
478
|
+
var pos: [String: Any] = [
|
|
479
|
+
"lat": gf.position.coordinate.latitude,
|
|
480
|
+
"lon": gf.position.coordinate.longitude,
|
|
481
|
+
"isValid": true
|
|
482
|
+
]
|
|
483
|
+
if let lvl = gf.position.level { pos["lvl"] = lvl.index }
|
|
484
|
+
if let bid = gf.position.building?.identifier { pos["bid"] = bid }
|
|
485
|
+
if let sid = gf.position.site?.identifier { pos["sid"] = sid }
|
|
486
|
+
dict["position"] = pos
|
|
487
|
+
return dict
|
|
488
|
+
})
|
|
489
|
+
}
|
|
490
|
+
|
|
343
491
|
// MARK: - Event Manager Delegate
|
|
344
492
|
|
|
345
493
|
func onPositionManagerCalculatedLocation(location: [String : Any]) {
|
|
@@ -388,13 +536,13 @@ extension PTRNativeLibrary: PTRExitButtonEventsListener {
|
|
|
388
536
|
extension PTRNativeLibrary: PTRMapEventsListener {
|
|
389
537
|
public func map(_ map: PTRMapViewController, didReceiveTapOnFeature feature: PTRFeature) {
|
|
390
538
|
// Handle feature tap if needed
|
|
391
|
-
if
|
|
539
|
+
if feature is PTRBuilding {
|
|
392
540
|
eventManagerDelegate?.onBuildingClicked([
|
|
393
541
|
"internalIdentifier": feature.identifier,
|
|
394
542
|
"externalIdentifier": feature.externalIdentifier,
|
|
395
543
|
"title": feature.name
|
|
396
544
|
])
|
|
397
|
-
} else if
|
|
545
|
+
} else if feature is PTRSite {
|
|
398
546
|
eventManagerDelegate?.onSiteClicked([
|
|
399
547
|
"internalIdentifier": feature.identifier,
|
|
400
548
|
"externalIdentifier": feature.externalIdentifier,
|
|
@@ -443,13 +591,16 @@ extension PTRNativeLibrary: PTRPermissionManagerDelegate {
|
|
|
443
591
|
}
|
|
444
592
|
|
|
445
593
|
extension PTRFeature {
|
|
446
|
-
public var dict: [String: Any] {
|
|
594
|
+
@objc public var dict: [String: Any] {
|
|
447
595
|
var result: [String: Any] = [
|
|
448
596
|
"identifier": identifier,
|
|
449
597
|
"externalIdentifier": externalIdentifier,
|
|
450
|
-
"
|
|
598
|
+
"mainType": mainType,
|
|
451
599
|
"name": name
|
|
452
600
|
]
|
|
601
|
+
if let sub = subType {
|
|
602
|
+
result["subType"] = sub
|
|
603
|
+
}
|
|
453
604
|
if let geometry = geometry {
|
|
454
605
|
result["geometry"] = geometry.dict
|
|
455
606
|
}
|
|
@@ -459,6 +610,35 @@ extension PTRFeature {
|
|
|
459
610
|
}
|
|
460
611
|
}
|
|
461
612
|
|
|
613
|
+
extension PTRSite {
|
|
614
|
+
@objc override public var dict: [String: Any] {
|
|
615
|
+
return [
|
|
616
|
+
"identifier": internalIdentifier,
|
|
617
|
+
"externalIdentifier": externalIdentifier,
|
|
618
|
+
"name": name,
|
|
619
|
+
"buildings": buildings.map { $0.dict }
|
|
620
|
+
]
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
extension PTRBuilding {
|
|
625
|
+
@objc override public var dict: [String: Any] {
|
|
626
|
+
return [
|
|
627
|
+
"identifier": internalIdentifier,
|
|
628
|
+
"externalIdentifier": externalIdentifier,
|
|
629
|
+
"name": name,
|
|
630
|
+
"levels": levels.map { level -> [String: Any] in
|
|
631
|
+
[
|
|
632
|
+
"identifier": level.identifier,
|
|
633
|
+
"externalIdentifier": level.externalIdentifier,
|
|
634
|
+
"name": level.name,
|
|
635
|
+
"index": level.index
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
462
642
|
extension PTRPosition {
|
|
463
643
|
public var dict: [String: Any] {
|
|
464
644
|
var result: [String: Any] = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-pointr",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0",
|
|
4
4
|
"description": "Pointr React-Native Module",
|
|
5
5
|
"main": "src/index",
|
|
6
6
|
"files": [
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"version": "0.41.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"react
|
|
29
|
-
"react": ">=
|
|
28
|
+
"react": ">=18",
|
|
29
|
+
"react-native": ">=0.73"
|
|
30
30
|
},
|
|
31
31
|
"peerDependenciesMeta": {
|
|
32
32
|
"react": {
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": ">=20",
|
|
41
|
+
"@types/react": "^19.2.15",
|
|
42
|
+
"react": "^19.2.6",
|
|
41
43
|
"react-native": "0.82.1",
|
|
42
44
|
"typescript": "^5.8.3"
|
|
43
45
|
},
|
|
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
|
|
|
16
16
|
|
|
17
17
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
18
|
|
|
19
|
-
s.dependency 'PointrKit', '
|
|
19
|
+
s.dependency 'PointrKit', '10.0.0'
|
|
20
20
|
|
|
21
21
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
22
22
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* New Architecture (TurboModule) spec for PTRNativePointrLibrary.
|
|
3
|
+
*
|
|
4
|
+
* This file provides the codegen type-spec for React Native's New Architecture
|
|
5
|
+
* (Fabric / TurboModules). At runtime the module is resolved via
|
|
6
|
+
* TurboModuleRegistry with a fall-back to NativeModules for backward
|
|
7
|
+
* compatibility (interop mode).
|
|
8
|
+
*
|
|
9
|
+
* Do NOT import this file directly — use {@link PointrSdk} instead.
|
|
10
|
+
*
|
|
11
|
+
* @module NativePointrModule
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { TurboModule } from 'react-native';
|
|
15
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
16
|
+
|
|
17
|
+
export interface Spec extends TurboModule {
|
|
18
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────────────
|
|
19
|
+
initialize(
|
|
20
|
+
clientId: string,
|
|
21
|
+
licenseKey: string,
|
|
22
|
+
baseUrl: string,
|
|
23
|
+
logLevel: number
|
|
24
|
+
): void;
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
stop(): void;
|
|
27
|
+
|
|
28
|
+
// ─── Permissions ────────────────────────────────────────────────────────────
|
|
29
|
+
shouldRequestPermissionsAtStartup(should: boolean): void;
|
|
30
|
+
requestPermissions(): void;
|
|
31
|
+
|
|
32
|
+
// ─── Location ───────────────────────────────────────────────────────────────
|
|
33
|
+
getCurrentLocation(callback: (result: Object | null) => void): void;
|
|
34
|
+
|
|
35
|
+
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
36
|
+
setPointrMapWidgetConfiguration(configJson: string): void;
|
|
37
|
+
|
|
38
|
+
// ─── POIs ───────────────────────────────────────────────────────────────────
|
|
39
|
+
getPois(siteId: string): Promise<Object[]>;
|
|
40
|
+
searchPois(siteId: string, query: string): Promise<Object[]>;
|
|
41
|
+
|
|
42
|
+
// ─── Sites & Buildings ──────────────────────────────────────────────────────
|
|
43
|
+
getSites(): Promise<Object[]>;
|
|
44
|
+
getBuildings(siteId: string): Promise<Object[]>;
|
|
45
|
+
getSiteByExternalId(externalId: string): Promise<Object>;
|
|
46
|
+
getClientName(): Promise<string>;
|
|
47
|
+
|
|
48
|
+
// ─── Wayfinding ─────────────────────────────────────────────────────────────
|
|
49
|
+
isWayfindingReady(siteId: string): Promise<boolean>;
|
|
50
|
+
calculateDistance(fromJson: string, toJson: string): Promise<number>;
|
|
51
|
+
|
|
52
|
+
// ─── Geofences ──────────────────────────────────────────────────────────────
|
|
53
|
+
getGeofences(siteId: string): Promise<Object[]>;
|
|
54
|
+
|
|
55
|
+
// ─── Misc ───────────────────────────────────────────────────────────────────
|
|
56
|
+
isMyCarMarked(callback: (result: boolean) => void): void;
|
|
57
|
+
|
|
58
|
+
// ─── Event bridge (required by RCTEventEmitter) ─────────────────────────────
|
|
59
|
+
addListener(eventName: string): void;
|
|
60
|
+
removeListeners(count: number): void;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the native module via TurboModuleRegistry (New Architecture) with
|
|
65
|
+
* automatic interop fall-back to the legacy bridge (Old Architecture).
|
|
66
|
+
*
|
|
67
|
+
* Returns `null` if the native module is not linked — the consuming code
|
|
68
|
+
* should use the LINKING_ERROR proxy in {@link PointrSdk} in that case.
|
|
69
|
+
*/
|
|
70
|
+
export default TurboModuleRegistry.get<Spec>('PTRNativeLibrary');
|
package/src/PTRMapWidgetUtils.ts
CHANGED
|
@@ -1,185 +1,108 @@
|
|
|
1
1
|
import { UIManager } from 'react-native';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
* Handle PTRStartAndFocusCommand specifically
|
|
5
|
-
* @param reactTag view tag of the map widget
|
|
6
|
-
* @param startAndFocusCommand the start and focus command
|
|
7
|
-
*/
|
|
8
|
-
const handleStartAndFocusCommand = (reactTag: number, startAndFocusCommand: PTRStartAndFocusCommand) => {
|
|
9
|
-
const innerCommand = startAndFocusCommand.command;
|
|
10
|
-
// Build arguments based on the inner command type
|
|
11
|
-
let args: any[];
|
|
12
|
-
|
|
13
|
-
switch (innerCommand.type) {
|
|
14
|
-
case PTRCommandType.SITE: {
|
|
15
|
-
const siteCommand = innerCommand as PTRSiteCommand;
|
|
16
|
-
args = [
|
|
17
|
-
startAndFocusCommand.clientId,
|
|
18
|
-
startAndFocusCommand.licenseKey,
|
|
19
|
-
startAndFocusCommand.baseUrl,
|
|
20
|
-
startAndFocusCommand.logLevel,
|
|
21
|
-
innerCommand.type,
|
|
22
|
-
siteCommand.site,
|
|
23
|
-
"",
|
|
24
|
-
0
|
|
25
|
-
];
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
case PTRCommandType.BUILDING: {
|
|
29
|
-
const buildingCommand = innerCommand as PTRBuildingCommand;
|
|
30
|
-
args = [
|
|
31
|
-
startAndFocusCommand.clientId,
|
|
32
|
-
startAndFocusCommand.licenseKey,
|
|
33
|
-
startAndFocusCommand.baseUrl,
|
|
34
|
-
startAndFocusCommand.logLevel,
|
|
35
|
-
innerCommand.type,
|
|
36
|
-
buildingCommand.site,
|
|
37
|
-
buildingCommand.building,
|
|
38
|
-
0
|
|
39
|
-
];
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
case PTRCommandType.LEVEL: {
|
|
43
|
-
const levelCommand = innerCommand as PTRLevelCommand;
|
|
44
|
-
args = [
|
|
45
|
-
startAndFocusCommand.clientId,
|
|
46
|
-
startAndFocusCommand.licenseKey,
|
|
47
|
-
startAndFocusCommand.baseUrl,
|
|
48
|
-
startAndFocusCommand.logLevel,
|
|
49
|
-
innerCommand.type,
|
|
50
|
-
levelCommand.site,
|
|
51
|
-
levelCommand.building,
|
|
52
|
-
levelCommand.level
|
|
53
|
-
];
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
case PTRCommandType.POI: {
|
|
57
|
-
const poiCommand = innerCommand as PTRPoiCommand;
|
|
58
|
-
args = [
|
|
59
|
-
startAndFocusCommand.clientId,
|
|
60
|
-
startAndFocusCommand.licenseKey,
|
|
61
|
-
startAndFocusCommand.baseUrl,
|
|
62
|
-
startAndFocusCommand.logLevel,
|
|
63
|
-
innerCommand.type,
|
|
64
|
-
poiCommand.site,
|
|
65
|
-
poiCommand.poi,
|
|
66
|
-
0
|
|
67
|
-
];
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
default:
|
|
71
|
-
console.error('Unsupported command type in PTRStartAndFocusCommand:', innerCommand.type);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
UIManager.dispatchViewManagerCommand(
|
|
75
|
-
reactTag,
|
|
76
|
-
'startAndFocus',
|
|
77
|
-
args,
|
|
78
|
-
);
|
|
79
|
-
};
|
|
2
|
+
import { PTRActionType } from './constants';
|
|
3
|
+
import { PTRFocusMapAction, PTRHighlightPoiAction, PTRDisplayRouteAction, PTRStartWayfindingAction, PTRAction, PTRMarkMyCarAction, PTRShowMyCarAction, PTRFocusCoordinateAction, PTRHighlightCategoryAction } from './actions';
|
|
80
4
|
|
|
81
5
|
/**
|
|
82
|
-
* Show the map widget with the given
|
|
6
|
+
* Show the map widget with the given action
|
|
83
7
|
* @param reactTag view tag of the map widget
|
|
84
|
-
* @param ptrCommand
|
|
8
|
+
* @param ptrCommand action to show the map widget (PTRAction)
|
|
85
9
|
*/
|
|
86
|
-
export const showMapWidget = (reactTag: number, ptrCommand:
|
|
87
|
-
// Check if it's a PTRStartAndFocusCommand (which doesn't have a 'type' property)
|
|
88
|
-
if ('command' in ptrCommand) {
|
|
89
|
-
handleStartAndFocusCommand(reactTag, ptrCommand as PTRStartAndFocusCommand);
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
10
|
+
export const showMapWidget = (reactTag: number, ptrCommand: PTRAction) => {
|
|
92
11
|
|
|
93
|
-
// Handle regular
|
|
94
|
-
const
|
|
95
|
-
switch (
|
|
96
|
-
case
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
12
|
+
// Handle regular PTRAction
|
|
13
|
+
const action = ptrCommand as PTRAction;
|
|
14
|
+
switch (action.type) {
|
|
15
|
+
case PTRActionType.FOCUS_MAP: {
|
|
16
|
+
const focusAction = ptrCommand as PTRFocusMapAction;
|
|
17
|
+
if (focusAction.level !== undefined && focusAction.building) {
|
|
18
|
+
UIManager.dispatchViewManagerCommand(
|
|
19
|
+
reactTag,
|
|
20
|
+
'level',
|
|
21
|
+
[focusAction.site, focusAction.building, focusAction.level],
|
|
22
|
+
);
|
|
23
|
+
} else if (focusAction.building) {
|
|
24
|
+
UIManager.dispatchViewManagerCommand(
|
|
25
|
+
reactTag,
|
|
26
|
+
'building',
|
|
27
|
+
[focusAction.site, focusAction.building],
|
|
28
|
+
);
|
|
29
|
+
} else {
|
|
30
|
+
UIManager.dispatchViewManagerCommand(
|
|
31
|
+
reactTag,
|
|
32
|
+
'site',
|
|
33
|
+
[focusAction.site],
|
|
34
|
+
);
|
|
35
|
+
}
|
|
103
36
|
break;
|
|
104
37
|
}
|
|
105
|
-
case
|
|
106
|
-
const
|
|
107
|
-
UIManager.dispatchViewManagerCommand(
|
|
108
|
-
reactTag,
|
|
109
|
-
'building',
|
|
110
|
-
[buildingCommand.site, buildingCommand.building],
|
|
111
|
-
);
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
case PTRCommandType.LEVEL: {
|
|
115
|
-
const levelCommand = ptrCommand as PTRLevelCommand;
|
|
116
|
-
UIManager.dispatchViewManagerCommand(
|
|
117
|
-
reactTag,
|
|
118
|
-
'level',
|
|
119
|
-
[levelCommand.site, levelCommand.building, levelCommand.level],
|
|
120
|
-
);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
case PTRCommandType.POI: {
|
|
124
|
-
const poiCommand = ptrCommand as PTRPoiCommand;
|
|
38
|
+
case PTRActionType.HIGHLIGHT_POI: {
|
|
39
|
+
const highlightPoiAction = ptrCommand as PTRHighlightPoiAction;
|
|
125
40
|
UIManager.dispatchViewManagerCommand(
|
|
126
41
|
reactTag,
|
|
127
42
|
'poi',
|
|
128
|
-
[
|
|
43
|
+
[highlightPoiAction.site, highlightPoiAction.poi],
|
|
129
44
|
);
|
|
130
45
|
break;
|
|
131
46
|
}
|
|
132
|
-
case
|
|
133
|
-
const
|
|
47
|
+
case PTRActionType.DISPLAY_ROUTE: {
|
|
48
|
+
const displayRouteAction = ptrCommand as PTRDisplayRouteAction;
|
|
134
49
|
UIManager.dispatchViewManagerCommand(
|
|
135
50
|
reactTag,
|
|
136
|
-
'
|
|
137
|
-
[
|
|
51
|
+
'displayRoute',
|
|
52
|
+
[displayRouteAction.site, displayRouteAction.fromPoi, displayRouteAction.toPoi],
|
|
138
53
|
);
|
|
139
54
|
break;
|
|
140
55
|
}
|
|
141
|
-
case
|
|
142
|
-
const
|
|
56
|
+
case PTRActionType.START_WAYFINDING: {
|
|
57
|
+
const wayfindingAction = ptrCommand as PTRStartWayfindingAction;
|
|
143
58
|
UIManager.dispatchViewManagerCommand(
|
|
144
59
|
reactTag,
|
|
145
|
-
'
|
|
146
|
-
[
|
|
60
|
+
'startWayfinding',
|
|
61
|
+
[wayfindingAction.site, wayfindingAction.poi],
|
|
147
62
|
);
|
|
148
63
|
break;
|
|
149
64
|
}
|
|
150
|
-
case
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
65
|
+
case PTRActionType.MARK_MY_CAR: {
|
|
66
|
+
const markMyCarAction = ptrCommand as PTRMarkMyCarAction;
|
|
67
|
+
if (markMyCarAction.building !== undefined && markMyCarAction.level !== undefined) {
|
|
68
|
+
UIManager.dispatchViewManagerCommand(
|
|
69
|
+
reactTag,
|
|
70
|
+
'markMyCarForLevel',
|
|
71
|
+
[markMyCarAction.site, markMyCarAction.building, markMyCarAction.level, markMyCarAction.shouldShowPopup, markMyCarAction.animationType],
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
UIManager.dispatchViewManagerCommand(
|
|
75
|
+
reactTag,
|
|
76
|
+
'markMyCarForSite',
|
|
77
|
+
[markMyCarAction.site, markMyCarAction.shouldShowPopup, markMyCarAction.animationType],
|
|
78
|
+
);
|
|
79
|
+
}
|
|
157
80
|
break;
|
|
158
81
|
}
|
|
159
|
-
case
|
|
160
|
-
const
|
|
82
|
+
case PTRActionType.SHOW_MY_CAR: {
|
|
83
|
+
const showMyCarAction = ptrCommand as PTRShowMyCarAction;
|
|
161
84
|
UIManager.dispatchViewManagerCommand(
|
|
162
85
|
reactTag,
|
|
163
|
-
'
|
|
164
|
-
[
|
|
86
|
+
'myCarForSite',
|
|
87
|
+
[showMyCarAction.site, showMyCarAction.animationType],
|
|
165
88
|
);
|
|
166
89
|
break;
|
|
167
90
|
}
|
|
168
|
-
case
|
|
169
|
-
const
|
|
91
|
+
case PTRActionType.FOCUS_COORDINATE: {
|
|
92
|
+
const coordAction = ptrCommand as PTRFocusCoordinateAction;
|
|
170
93
|
UIManager.dispatchViewManagerCommand(
|
|
171
94
|
reactTag,
|
|
172
|
-
'
|
|
173
|
-
[
|
|
95
|
+
'coordinate',
|
|
96
|
+
[coordAction.site, coordAction.latitude, coordAction.longitude, coordAction.levelIndex ?? -1],
|
|
174
97
|
);
|
|
175
98
|
break;
|
|
176
99
|
}
|
|
177
|
-
case
|
|
178
|
-
const
|
|
100
|
+
case PTRActionType.HIGHLIGHT_CATEGORY: {
|
|
101
|
+
const filterAction = ptrCommand as PTRHighlightCategoryAction;
|
|
179
102
|
UIManager.dispatchViewManagerCommand(
|
|
180
103
|
reactTag,
|
|
181
|
-
'
|
|
182
|
-
[
|
|
104
|
+
'highlightCategory',
|
|
105
|
+
[filterAction.site, filterAction.categoryIds],
|
|
183
106
|
);
|
|
184
107
|
break;
|
|
185
108
|
}
|