react-native-pointr 8.16.1 → 9.1.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.
@@ -2,7 +2,6 @@ package com.pointr
2
2
 
3
3
  import android.Manifest
4
4
  import android.annotation.SuppressLint
5
- import android.content.Intent
6
5
  import android.os.Build
7
6
  import android.os.Parcel
8
7
  import android.os.Parcelable
@@ -15,20 +14,19 @@ import com.facebook.react.bridge.ReactMethod
15
14
  import com.facebook.react.bridge.WritableMap
16
15
  import com.facebook.react.modules.core.DeviceEventManagerModule
17
16
  import com.pointrlabs.core.management.Pointr
18
- import com.pointrlabs.core.management.PositionManager
17
+ import com.pointrlabs.core.management.PositioningManager
19
18
  import com.pointrlabs.core.management.interfaces.PointrListener
20
19
  import com.pointrlabs.core.management.models.Building
21
- import com.pointrlabs.core.management.models.Level
22
20
  import com.pointrlabs.core.management.models.PTRParams
23
- import com.pointrlabs.core.management.models.PointrEnvironment
24
21
  import com.pointrlabs.core.management.models.Site
25
- import com.pointrlabs.core.map.models.PTRError
26
- import com.pointrlabs.core.map.models.events_listeners.MapEventsListener
27
- import com.pointrlabs.core.map.views.PTRMapFragment
28
- import com.pointrlabs.core.map.views.helper_views.PTRDialog
29
22
  import com.pointrlabs.core.nativecore.wrappers.Plog
30
- import com.pointrlabs.core.positioning.model.CalculatedLocation
23
+ import com.pointrlabs.core.positioning.model.CalculatedPosition
31
24
  import com.pointrlabs.core.positioning.model.PositioningTypes
25
+ import com.pointrlabs.core.util.models.error.PTRError
26
+ import com.pointrlabs.ui.map.models.events_listeners.MapEventsListener
27
+ import com.pointrlabs.ui.map.viewmodels.PTRMapWidgetConfiguration
28
+ import com.pointrlabs.ui.map.views.PTRMapFragment
29
+ import com.pointrlabs.ui.map.views.helper_views.PTRDialog
32
30
  import org.json.JSONObject
33
31
  import kotlin.random.Random
34
32
  import kotlin.reflect.KMutableProperty1
@@ -37,21 +35,15 @@ import kotlin.reflect.KMutableProperty1
37
35
  class PointrModule(reactContext: ReactApplicationContext) :
38
36
  ReactContextBaseJavaModule(reactContext) {
39
37
 
40
- private val positionManagerListener: PositionManager.Listener
38
+ private val positionManagerListener: PositioningManager.Listener
41
39
  private var listenerCount = 0
42
40
 
43
41
  init {
44
- positionManagerListener = object : PositionManager.Listener {
45
- override fun onPositionManagerCalculatedLocation(p0: CalculatedLocation?) {
46
- val calculatedLocation = p0 ?: return
47
- val params = applyParamsForCalculatedLocation(calculatedLocation)
42
+ positionManagerListener = object : PositioningManager.Listener {
43
+ override fun onPositioningManagerCalculatedPosition(position: CalculatedPosition) {
44
+ val params = applyParamsForCalculatedLocation(position)
48
45
  sendEventToJs(reactContext, OnPositionManagerCalculatedLocation, params)
49
46
  }
50
-
51
- override fun onPositionManagerDetectedPositionLevelChange(p0: Level) {}
52
- override fun onPositionManagerPositionIsFading() {}
53
- override fun onPositionManagerPositionIsLost() {}
54
- override fun onPositionManagerPositioningServiceStateChangedTo(p0: PositioningTypes.PositioningServiceState?) {}
55
47
  }
56
48
  setPointrListeners()
57
49
  }
@@ -116,18 +108,16 @@ class PointrModule(reactContext: ReactApplicationContext) :
116
108
 
117
109
  @ReactMethod
118
110
  fun initialize(
111
+ clientId: String,
119
112
  licenceKey: String,
120
113
  baseUrl: String,
121
- clientId: String,
122
- env: String,
123
114
  logLevel: Int
124
115
  ) {
125
116
  initialize(
126
117
  reactApplicationContext,
127
118
  clientId,
128
- baseUrl,
129
119
  licenceKey,
130
- env,
120
+ baseUrl,
131
121
  logLevel
132
122
  )
133
123
  }
@@ -167,134 +157,10 @@ class PointrModule(reactContext: ReactApplicationContext) :
167
157
  val pointr = Pointr.getPointr() ?: return callback.invoke(null)
168
158
  if (pointr.state != Pointr.State.RUNNING) return callback.invoke(null)
169
159
  val calculatedLocation =
170
- pointr.positionManager?.currentCalculatedLocation ?: return callback.invoke(null)
160
+ pointr.positioningManager?.currentCalculatedPosition ?: return callback.invoke(null)
171
161
  callback.invoke(applyParamsForCalculatedLocation(calculatedLocation))
172
162
  }
173
163
 
174
- @ReactMethod
175
- fun showSite(siteExternalId: String, animationType: Int, callback: Callback) {
176
- val activity = currentActivity ?: run {
177
- callback.invoke("Could not get current activity")
178
- return
179
- }
180
-
181
- val intent = Intent(activity, PointrMapWidgetActivity::class.java)
182
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
183
- intent.action = PointrMapWidgetActivity.SHOW_SITE
184
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
185
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
186
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
187
- PointrMapWidgetActivity.callback = callback
188
- activity.startActivity(intent)
189
- }
190
-
191
- @ReactMethod
192
- fun showBuilding(
193
- siteExternalId: String,
194
- buildingExternalId: String,
195
- animationType: Int,
196
- callback: Callback
197
- ) {
198
- val activityContext =
199
- currentActivity ?: return callback.invoke("Could not get current activity")
200
- val intent = Intent(activityContext, PointrMapWidgetActivity::class.java)
201
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
202
- intent.action = PointrMapWidgetActivity.SHOW_BUILDING
203
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
204
- intent.putExtra(PointrMapWidgetActivity.buildingExternalIdentifierKey, buildingExternalId)
205
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
206
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
207
- PointrMapWidgetActivity.callback = callback
208
- activityContext.startActivity(intent)
209
- }
210
-
211
- @ReactMethod
212
- fun showLevel(
213
- siteExternalId: String,
214
- buildingExternalId: String,
215
- levelIndex: Int,
216
- animationType: Int,
217
- callback: Callback
218
- ) {
219
- val activityContext =
220
- currentActivity ?: return callback.invoke("Could not get current activity")
221
- val intent = Intent(activityContext, PointrMapWidgetActivity::class.java)
222
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
223
- intent.action = PointrMapWidgetActivity.SHOW_LEVEL
224
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
225
- intent.putExtra(PointrMapWidgetActivity.buildingExternalIdentifierKey, buildingExternalId)
226
- intent.putExtra(PointrMapWidgetActivity.levelIndexKey, levelIndex)
227
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
228
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
229
- PointrMapWidgetActivity.callback = callback
230
- activityContext.startActivity(intent)
231
- }
232
-
233
- @ReactMethod
234
- fun showPoiDetails(
235
- siteExternalId: String,
236
- poiExternalId: String,
237
- animationType: Int,
238
- callback: Callback
239
- ) {
240
- val activityContext =
241
- currentActivity ?: return callback.invoke("Could not get current activity")
242
- val intent = Intent(activityContext, PointrMapWidgetActivity::class.java)
243
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
244
- intent.action = PointrMapWidgetActivity.SHOW_POI_DETAILS
245
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
246
- intent.putExtra(PointrMapWidgetActivity.poiExternalIdentifierKey, poiExternalId)
247
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
248
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
249
- PointrMapWidgetActivity.callback = callback
250
- activityContext.startActivity(intent)
251
- }
252
-
253
- @ReactMethod
254
- fun showPathFindingToPoi(
255
- siteExternalId: String,
256
- poiExternalId: String,
257
- animationType: Int,
258
- callback: Callback
259
- ) {
260
- val activityContext =
261
- currentActivity ?: return callback.invoke("Could not get current activity")
262
- val intent = Intent(activityContext, PointrMapWidgetActivity::class.java)
263
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
264
- intent.action = PointrMapWidgetActivity.SHOW_PATHFINDING_TO_POI
265
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
266
- intent.putExtra(PointrMapWidgetActivity.poiExternalIdentifierKey, poiExternalId)
267
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
268
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
269
- PointrMapWidgetActivity.callback = callback
270
- activityContext.startActivity(intent)
271
- }
272
-
273
- @ReactMethod
274
- fun showPathFindingBetweenPOIs(
275
- siteExternalId: String,
276
- sourcePoiExternalId: String,
277
- destinationPoiExternalId: String,
278
- animationType: Int,
279
- callback: Callback
280
- ) {
281
- val activityContext =
282
- currentActivity ?: return callback.invoke("Could not get current activity")
283
- val intent = Intent(activityContext, PointrMapWidgetActivity::class.java)
284
- intent.putExtra(mapEventsListenerKey, CustomMapEventsListener(reactApplicationContext))
285
- intent.action = PointrMapWidgetActivity.SHOW_PATHFINDING_BETWEEN_POIS
286
- intent.putExtra(PointrMapWidgetActivity.siteExternalIdentifierKey, siteExternalId)
287
- intent.putExtra(PointrMapWidgetActivity.sourcePoiExternalIdentifierKey, sourcePoiExternalId)
288
- intent.putExtra(
289
- PointrMapWidgetActivity.destinationPoiExternalIdentifierKey,
290
- destinationPoiExternalId
291
- )
292
- intent.putExtra(PointrMapWidgetActivity.animationTypeKey, animationType)
293
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
294
- PointrMapWidgetActivity.callback = callback
295
- activityContext.startActivity(intent)
296
- }
297
-
298
164
  @ReactMethod
299
165
  fun setPointrMapWidgetConfiguration(configurationString: String) {
300
166
  try {
@@ -307,7 +173,7 @@ class PointrModule(reactContext: ReactApplicationContext) :
307
173
 
308
174
  companion object {
309
175
  const val NAME = "PTRNativePointrLibrary"
310
-
176
+ val mapWidgetConfiguration = PTRMapWidgetConfiguration.defaultConfiguration()
311
177
  const val siteInternalIdentifierKey = "siteInternalIdentifier"
312
178
  const val siteExternalIdentifierKey = "siteExternalIdentifier"
313
179
  const val buildingInternalIdentifierKey = "buildingInternalIdentifier"
@@ -394,9 +260,9 @@ class PointrModule(reactContext: ReactApplicationContext) :
394
260
  // region [com.pointrlabs.core.map.models.events_listeners.CustomMapEventsListener]
395
261
  override fun mapDidReceiveTapOnBuilding(mapFragment: PTRMapFragment, building: Building) {
396
262
  val params: WritableMap = Arguments.createMap()
397
- params.putInt(INTERNAL_ID, building.internalIdentifier)
263
+ params.putString(INTERNAL_ID, building.identifier)
398
264
  params.putString(EXTERNAL_ID, building.externalIdentifier)
399
- params.putString(TITLE, building.title)
265
+ params.putString(TITLE, building.name)
400
266
  reactContext?.let {
401
267
  sendEventToJs(it, OnBuildingClicked, params)
402
268
  }
@@ -404,9 +270,9 @@ class PointrModule(reactContext: ReactApplicationContext) :
404
270
 
405
271
  override fun mapDidReceiveTapOnSite(mapFragment: PTRMapFragment, site: Site) {
406
272
  val params: WritableMap = Arguments.createMap()
407
- params.putInt(INTERNAL_ID, site.internalIdentifier)
273
+ params.putString(INTERNAL_ID, site.identifier)
408
274
  params.putString(EXTERNAL_ID, site.externalIdentifier)
409
- params.putString(TITLE, site.title)
275
+ params.putString(TITLE, site.name)
410
276
  reactContext?.let {
411
277
  sendEventToJs(it, OnSiteClicked, params)
412
278
  }
@@ -421,11 +287,11 @@ class PointrModule(reactContext: ReactApplicationContext) :
421
287
  ptrMapWidgetFragment.parentFragmentManager.beginTransaction()
422
288
  .remove(ptrMapWidgetFragment).commit()
423
289
  val ptrDialogModel = PTRDialog.PtrDialogModel(
424
- iconDrawableResId = com.pointrlabs.core.R.drawable.error_generic,
425
- bigTextString = activity.getString(com.pointrlabs.core.R.string.ptr_error_title_map_loading_generic_error),
426
- smallTextString = activity.getString(com.pointrlabs.core.R.string.no_internet),
290
+ iconDrawableResId = com.pointrlabs.ui.R.drawable.error_generic,
291
+ bigTextString = activity.getString(com.pointrlabs.ui.R.string.ptr_error_title_map_loading_generic_error),
292
+ smallTextString = activity.getString(com.pointrlabs.ui.R.string.no_internet),
427
293
  primaryButton = PTRDialog.PtrDialogButtonModel(
428
- activity.getString(com.pointrlabs.core.R.string.ok)
294
+ activity.getString(com.pointrlabs.ui.R.string.ok)
429
295
  ) { dialog, _ ->
430
296
  dialog.dismiss()
431
297
  // finish the activity after we are done with the dialog
@@ -442,18 +308,18 @@ class PointrModule(reactContext: ReactApplicationContext) :
442
308
  // endregion [com.pointrlabs.core.map.models.events_listeners.CustomMapEventsListener]
443
309
  }
444
310
 
445
- private fun applyParamsForCalculatedLocation(calculatedLocation: CalculatedLocation): WritableMap {
311
+ private fun applyParamsForCalculatedLocation(calculatedLocation: CalculatedPosition): WritableMap {
446
312
  val params: WritableMap = Arguments.createMap()
447
313
  val site = calculatedLocation.site
448
314
  val building = calculatedLocation.building
449
315
  val level = calculatedLocation.level
450
- val loc = calculatedLocation.location
316
+ val loc = calculatedLocation.position
451
317
  site?.let {
452
- params.putInt(siteInternalIdentifierKey, it.internalIdentifier)
318
+ params.putString(siteInternalIdentifierKey, it.identifier)
453
319
  params.putString(siteExternalIdentifierKey, it.externalIdentifier)
454
320
  }
455
321
  building?.let {
456
- params.putInt(buildingInternalIdentifierKey, it.internalIdentifier)
322
+ params.putString(buildingInternalIdentifierKey, it.identifier)
457
323
  params.putString(buildingExternalIdentifierKey, it.externalIdentifier)
458
324
  }
459
325
  level?.let {
@@ -466,7 +332,7 @@ class PointrModule(reactContext: ReactApplicationContext) :
466
332
  if (calculatedLocation.accuracy != PositioningTypes.INVALID_FLOAT) {
467
333
  params.putDouble(accuracyKey, calculatedLocation.accuracy)
468
334
  }
469
- if (calculatedLocation.headingAccuracyClass == CalculatedLocation.HeadingAccuracyClass.HIGH) {
335
+ if (calculatedLocation.headingAccuracyClass == CalculatedPosition.HeadingAccuracyClass.HIGH) {
470
336
  params.putDouble(headingKey, calculatedLocation.heading)
471
337
  }
472
338
  return params
@@ -475,18 +341,11 @@ class PointrModule(reactContext: ReactApplicationContext) :
475
341
  fun initialize(
476
342
  reactContext: ReactApplicationContext,
477
343
  clientId: String,
478
- baseUrl: String,
479
344
  licenceKey: String,
480
- env: String,
345
+ baseUrl: String,
481
346
  logLevel: Int
482
347
  ) {
483
348
  val ptrParams = PTRParams(clientId, licenceKey, baseUrl)
484
- try {
485
- val environment = PointrEnvironment.valueOf(env)
486
- ptrParams.environment = environment
487
- } catch (ex: IllegalArgumentException) {
488
- Log.e(name, "Could not set environment of PTRParams for env: $env")
489
- }
490
349
  try {
491
350
  val ptrLogLevel = Plog.LogLevel.entries[logLevel]
492
351
  ptrParams.logLevel = ptrLogLevel
@@ -513,31 +372,31 @@ class PointrModule(reactContext: ReactApplicationContext) :
513
372
  fun removePointrListeners() {
514
373
  val pointr = Pointr.getPointr() ?: return
515
374
  if (pointr.state != Pointr.State.RUNNING) return
516
- pointr.positionManager?.removeListener(positionManagerListener)
375
+ pointr.positioningManager?.removeListener(positionManagerListener)
517
376
  }
518
377
 
519
378
  private fun setPointrListeners() {
520
379
  val pointr = Pointr.getPointr() ?: return
521
380
  if (pointr.state != Pointr.State.RUNNING) return
522
- pointr.positionManager?.addListener(positionManagerListener)
381
+ pointr.positioningManager?.addListener(positionManagerListener)
523
382
  if (shouldRequestPermissionsAtStartup) {
524
383
  requestPermissions()
525
384
  } else {
526
- pointr.permissionManager?.shouldRequestLocationPermissionForWhileInUse = false
527
- pointr.permissionManager?.shouldRequestBluetoothPermission = false
528
- pointr.permissionManager?.shouldRequestLocationPermissionForAlways = false
385
+ pointr.permissionManager.shouldRequestLocationPermissionForWhileInUse = false
386
+ pointr.permissionManager.shouldRequestBluetoothPermission = false
387
+ pointr.permissionManager.shouldRequestLocationPermissionForAlways = false
529
388
  }
530
389
  }
531
390
 
532
391
  fun setPointrMapWidgetConfiguration(jsonObject: JSONObject) {
533
- PointrMapWidgetActivity.mapWidgetConfiguration::class.members.forEach { kCallable ->
392
+ mapWidgetConfiguration::class.members.forEach { kCallable ->
534
393
  if (kCallable !is KMutableProperty1<*, *>) return@forEach
535
394
  if (!jsonObject.has(kCallable.name)) return@forEach
536
395
  try {
537
396
  val value = if (kCallable.name == "isBuildingLevelSelectorEnabled")
538
397
  jsonObject.getBoolean("isLevelSelectorEnabled")
539
398
  else jsonObject.getBoolean(kCallable.name)
540
- kCallable.setter.call(PointrMapWidgetActivity.mapWidgetConfiguration, value)
399
+ kCallable.setter.call(mapWidgetConfiguration, value)
541
400
  } catch (_: Exception) {
542
401
  }
543
402
  }
@@ -0,0 +1,247 @@
1
+ import UIKit
2
+ import PointrKit
3
+
4
+ @objc class PTRMapWidgetContainerView: UIView, PTRSiteManagerDelegate, PTRDataManagerDelegate, PTRWayfindingManagerDelegate {
5
+
6
+ @objc var onMapWidgetDidEndLoading: RCTBubblingEventBlock?
7
+
8
+ private(set) var mapWidget: PTRMapWidgetViewController?
9
+ var semaphore: DispatchSemaphore?
10
+ var site: PTRSite?
11
+
12
+ private let kLayerStaticPath = "static-path"
13
+
14
+ @objc func ptrMapWidgetDidEndLoading(withParameters parameters: [String: Any]) {
15
+ onMapWidgetDidEndLoading?(parameters)
16
+ }
17
+
18
+ @objc func getMapWidget(_ action: PTRMapWidgetAction) -> PTRMapWidgetViewController {
19
+ if waitForPointrState() != .running {
20
+ print("Pointr is not running")
21
+ }
22
+
23
+ print("initializing map widget")
24
+ mapWidget = PTRMapWidgetViewController(action: action, configuration: PTRNativeLibrary.mapWidgetConfiguration)
25
+ return mapWidget!
26
+ }
27
+
28
+ @objc func present(_ mapWidget: PTRMapWidgetViewController) {
29
+ addSubview(mapWidget.view)
30
+ mapWidget.view.translatesAutoresizingMaskIntoConstraints = false
31
+ NSLayoutConstraint.activate([
32
+ mapWidget.view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
33
+ mapWidget.view.trailingAnchor.constraint(equalTo: self.trailingAnchor),
34
+ mapWidget.view.topAnchor.constraint(equalTo: self.topAnchor),
35
+ mapWidget.view.bottomAnchor.constraint(equalTo: self.bottomAnchor)
36
+ ])
37
+ }
38
+
39
+ @objc func showStaticPath(_ siteExternalIdentifier: String,
40
+ fromPoiExternalIdentifier: String,
41
+ toPoiExternalIdentifier: String) {
42
+ waitForPointrState()
43
+
44
+ var ptrCommand: [String: Any] = [
45
+ "command": "staticPath",
46
+ "siteExternalIdentifier": siteExternalIdentifier,
47
+ "fromPoiExternalIdentifier": fromPoiExternalIdentifier,
48
+ "toPoiExternalIdentifier": toPoiExternalIdentifier
49
+ ]
50
+
51
+ guard let site = getSite(siteExternalIdentifier) else {
52
+ ptrCommand["error"] = "Site not found"
53
+ ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
54
+ print("no site found")
55
+ return
56
+ }
57
+
58
+ guard let fromPoi = getPoi(site, poiExternalIdentifier: fromPoiExternalIdentifier) else {
59
+ ptrCommand["error"] = "Source poi not found"
60
+ ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
61
+ print("Source poi not found")
62
+ return
63
+ }
64
+
65
+ guard let toPoi = getPoi(site, poiExternalIdentifier: toPoiExternalIdentifier) else {
66
+ ptrCommand["error"] = "Target poi not found"
67
+ ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
68
+ print("Destination poi not found")
69
+ return
70
+ }
71
+
72
+ waitForPath(site)
73
+
74
+ guard let pathManager = Pointr.shared.wayfindingManager else {
75
+ ptrCommand["error"] = "Path manager not found"
76
+ ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
77
+ print("Path manager not found")
78
+ return
79
+ }
80
+
81
+ guard let route = pathManager.calculateRoute(fromPosition: fromPoi, toNearestPositionIn: [toPoi]) else {
82
+ ptrCommand["error"] = "Path not found"
83
+ ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
84
+ print("Path not found")
85
+ return
86
+ }
87
+
88
+ let workItem = DispatchWorkItem { [weak self] in
89
+ guard let self = self else { return }
90
+
91
+ let location: PTRMapWidgetLocation
92
+ if let level = fromPoi.position.level {
93
+ location = PTRMapWidgetLevelLocation(
94
+ siteIdentifier: site.identifier,
95
+ buildingIdentifier: level.building.identifier,
96
+ levelIndex: Int(level.index),
97
+ isExternalIdentifiers: false
98
+ )
99
+ } else {
100
+ location = PTRMapWidgetSiteLocation(
101
+ siteIdentifier: site.identifier,
102
+ isExternalIdentifiers: false
103
+ )
104
+ }
105
+ let action = PTRMapWidgetMapFocusAction(location: location)
106
+ let mapWidget = self.getMapWidget(action)
107
+ action.completion = { [weak self, weak mapWidget] error in
108
+ guard let self = self, let mapWidget = mapWidget else {
109
+ ptrCommand["error"] = "Lost reference to PTRMapWidgetContainerView and/or PTRMapWidgetViewController"
110
+ self?.ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
111
+ print("Error showing level: Lost reference to PTRMapWidgetContainerView and/or PTRMapWidgetViewController")
112
+ return
113
+ }
114
+ if let error = error {
115
+ ptrCommand["error"] = error.errorCode
116
+ self.ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
117
+ print("Error showing level: \(error.errorCode ?? "")")
118
+ return
119
+ }
120
+ self.setStaticPath(mapWidget.mapViewController, fromPoi: fromPoi, toPoi: toPoi, route: route)
121
+ ptrCommand["error"] = ""
122
+ self.ptrMapWidgetDidEndLoading(withParameters: ptrCommand)
123
+ print("ready")
124
+ }
125
+ self.present(mapWidget)
126
+ }
127
+ DispatchQueue.main.async(execute: workItem)
128
+ }
129
+
130
+ func setStaticPath(_ map: PTRMapViewController, fromPoi: PTRPoi, toPoi: PTRPoi, route: PTRRoute) {
131
+ let layer = PTRMapSymbolLayer(identifier: kLayerStaticPath)
132
+ map.addLayer(layer)
133
+ map.addFeatures([fromPoi, toPoi], toLayer: layer.identifier)
134
+ map.currentRoute = route
135
+ map.zoomToCoordinate(fromPoi.position.coordinate)
136
+ }
137
+
138
+ func waitForPath(_ site: PTRSite) {
139
+ print("waiting for path to be ready")
140
+ guard let pathManager = Pointr.shared.wayfindingManager else { return }
141
+
142
+ self.site = site
143
+ self.semaphore = DispatchSemaphore(value: 0)
144
+ pathManager.addListener(self)
145
+ if !pathManager.isReady(for: site) {
146
+ let timeout = DispatchTime.now() + .seconds(5)
147
+ if semaphore?.wait(timeout: timeout) == .timedOut {
148
+ print("Timeout waiting for pathmanager")
149
+ }
150
+ }
151
+ pathManager.removeListener(self)
152
+ }
153
+
154
+ func onWayfindingManagerReady(for site: PTRSite) {
155
+ guard site.internalIdentifier == self.site?.internalIdentifier else { return }
156
+ print("path became ready.")
157
+ semaphore?.signal()
158
+ }
159
+
160
+ func getPoi(_ site: PTRSite, poiExternalIdentifier: String) -> PTRPoi? {
161
+ guard let poiManager = Pointr.shared.poiManager else { return nil }
162
+
163
+ if !poiManager.hasContent(for: site) {
164
+ waitForPois(site)
165
+ }
166
+
167
+ if let poi = poiManager.pois(for: site, withExternalIdentifier: poiExternalIdentifier) {
168
+ return poi
169
+ }
170
+
171
+ return poiManager.pois(for: site, withIdentifier: poiExternalIdentifier)
172
+ }
173
+
174
+ func waitForPois(_ site: PTRSite) {
175
+ print("waiting for data to be ready")
176
+ guard let dataManager = Pointr.shared.dataManager else { return }
177
+
178
+ self.site = site
179
+ self.semaphore = DispatchSemaphore(value: 0)
180
+ dataManager.addListener(self)
181
+ dataManager.loadData(forSite: site.internalIdentifier)
182
+
183
+ if !dataManager.isContentReady(forSite: site.internalIdentifier) {
184
+ let timeout = DispatchTime.now() + .seconds(5)
185
+ if semaphore?.wait(timeout: timeout) == .timedOut {
186
+ print("Timeout waiting for datamanager")
187
+ }
188
+ }
189
+ dataManager.removeListener(self)
190
+ }
191
+
192
+ func onDataManagerCompleteAll(for site: PTRSite,
193
+ isSuccessful: Bool,
194
+ dataFromOnline isOnlineData: Bool,
195
+ errorMessages: [NSNumber : String]) {
196
+ guard isOnlineData else { return }
197
+ guard site.internalIdentifier == self.site?.internalIdentifier else { return }
198
+
199
+ print("data became ready.")
200
+ semaphore?.signal()
201
+ }
202
+
203
+ func getSite(_ siteExternalIdentifier: String) -> PTRSite? {
204
+ guard let siteManager = Pointr.shared.siteManager else { return nil }
205
+
206
+ if siteManager.sites().count == 0 {
207
+ waitForSites()
208
+ }
209
+
210
+ return siteManager.site(withExternalIdentifier: siteExternalIdentifier)
211
+ }
212
+
213
+ func waitForSites() {
214
+ print("waiting for sites")
215
+ self.semaphore = DispatchSemaphore(value: 0)
216
+ Pointr.shared.siteManager?.addListener(self)
217
+ let timeout = DispatchTime.now() + .seconds(5)
218
+ if semaphore?.wait(timeout: timeout) == .timedOut {
219
+ print("Timeout waiting for configuration")
220
+ }
221
+ Pointr.shared.siteManager?.removeListener(self)
222
+ }
223
+
224
+ func onSiteManagerDataChanged() {
225
+ print("sites became ready.")
226
+ semaphore?.signal()
227
+ }
228
+
229
+ @discardableResult
230
+ func waitForPointrState() -> PointrState {
231
+ print("waiting for pointr to run")
232
+ let state1 = Pointr.shared.state
233
+
234
+ if state1 == .running || state1.rawValue < PointrState.off.rawValue {
235
+ return Pointr.shared.state
236
+ }
237
+
238
+ let semaphore = DispatchSemaphore(value: 0)
239
+ Pointr.shared.start(with: PTRNativeLibrary.params) { state in
240
+ if state == .running || state.rawValue < PointrState.off.rawValue {
241
+ semaphore.signal()
242
+ }
243
+ }
244
+ semaphore.wait()
245
+ return Pointr.shared.state
246
+ }
247
+ }
@@ -0,0 +1,59 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTViewManager.h>
3
+ #import <React/RCTEventEmitter.h>
4
+ #import <React/RCTLog.h>
5
+ //
6
+ // PTRMapWidgetManager-Bridging.m
7
+ //
8
+ // This file provides Objective-C bridge methods for PTRMapWidgetManager
9
+ //
10
+
11
+ // The PTRMapWidgetManager is now implemented directly in Objective-C
12
+ // No bridging methods needed as RCT_EXPORT_METHOD is used directly
13
+
14
+ @interface RCT_EXTERN_MODULE(PTRMapWidgetManager, RCTViewManager)
15
+
16
+ RCT_EXPORT_VIEW_PROPERTY(onMapWidgetDidEndLoading, RCTBubblingEventBlock)
17
+
18
+ RCT_EXTERN_METHOD(site:(nonnull NSNumber *)reactTag
19
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier)
20
+ RCT_EXTERN_METHOD(building:(nonnull NSNumber *)reactTag
21
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
22
+ buildingExternalIdentifier:(NSString *)buildingExternalIdentifier)
23
+
24
+ RCT_EXTERN_METHOD(level:(nonnull NSNumber *)reactTag
25
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
26
+ buildingExternalIdentifier:(NSString *)buildingExternalIdentifier
27
+ levelIndex:(NSInteger)levelIndex)
28
+
29
+ RCT_EXTERN_METHOD(poi:(nonnull NSNumber *)reactTag
30
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
31
+ poiExternalIdentifier:(NSString *)poiExternalIdentifier)
32
+
33
+ RCT_EXTERN_METHOD(path:(nonnull NSNumber *)reactTag
34
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
35
+ toPoiExternalIdentifier:(NSString *)toPoiExternalIdentifier)
36
+
37
+ RCT_EXTERN_METHOD(staticPath:(nonnull NSNumber *)reactTag
38
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
39
+ fromPoiExternalIdentifier:(NSString *)fromPoiExternalIdentifier
40
+ toPoiExternalIdentifier:(NSString *)toPoiExternalIdentifier)
41
+
42
+ RCT_EXTERN_METHOD(markMyCarForLevel:(nonnull NSNumber *)reactTag
43
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
44
+ buildingExternalIdentifier:(NSString *)buildingExternalIdentifier
45
+ levelIndex:(NSInteger)levelIndex
46
+ shouldShowPopup:(BOOL)shouldShowPopup
47
+ animationType:(NSInteger)animationType)
48
+
49
+ RCT_EXTERN_METHOD(markMyCarForSite:(nonnull NSNumber *)reactTag
50
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
51
+ shouldShowPopup:(BOOL)shouldShowPopup
52
+ animationType:(NSInteger)animationType)
53
+
54
+ RCT_EXTERN_METHOD(myCarForSite:(nonnull NSNumber *)reactTag
55
+ siteExternalIdentifier:(NSString *)siteExternalIdentifier
56
+ animationType:(NSInteger)animationType)
57
+ @end
58
+
59
+ // No additional methods are needed here as the PTRMapWidgetManager is implemented in Objective-C