react-native-pointr 8.14.0 → 8.15.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/CHANGELOG.md +39 -0
- package/README.md +306 -3
- package/android/.settings/org.eclipse.buildship.core.prefs +2 -0
- package/android/build.gradle +2 -2
- package/android/src/main/AndroidManifest.xml +2 -1
- package/android/src/main/java/com/pointr/PTRMapWidgetCommandType.kt +20 -0
- package/android/src/main/java/com/pointr/PTRMapWidgetManager.kt +777 -0
- package/android/src/main/java/com/pointr/PointrMapWidgetActivity.kt +102 -20
- package/android/src/main/java/com/pointr/PointrModule.kt +101 -21
- package/android/src/main/java/com/pointr/PointrPackage.kt +1 -1
- package/ios/PTRMapWidgetContainerView.h +19 -0
- package/ios/PTRMapWidgetContainerView.m +281 -0
- package/ios/PTRMapWidgetManager.m +256 -0
- package/ios/PTRNativeLibrary.h +0 -8
- package/ios/PTRNativeLibrary.m +17 -8
- package/ios/PointrApp.swift +124 -69
- package/package.json +1 -1
- package/react-native-pointr.podspec +1 -1
- package/src/PTRCommand.ts +119 -0
- package/src/PTRMapWidgetUtils.ts +93 -0
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
package com.pointr
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.os.Handler
|
|
5
|
+
import android.os.Looper.getMainLooper
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import android.view.Choreographer
|
|
8
|
+
import android.view.View
|
|
9
|
+
import android.widget.FrameLayout
|
|
10
|
+
import androidx.fragment.app.FragmentActivity
|
|
11
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
12
|
+
import com.facebook.react.bridge.ReadableArray
|
|
13
|
+
import com.facebook.react.bridge.WritableMap
|
|
14
|
+
import com.facebook.react.bridge.WritableNativeMap
|
|
15
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
16
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
17
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
18
|
+
import com.pointrlabs.core.configuration.MutableConfiguration
|
|
19
|
+
import com.pointrlabs.core.management.DataManager
|
|
20
|
+
import com.pointrlabs.core.management.Pointr
|
|
21
|
+
import com.pointrlabs.core.management.interfaces.PointrListener
|
|
22
|
+
import com.pointrlabs.core.management.models.ErrorMessage
|
|
23
|
+
import com.pointrlabs.core.management.models.Site
|
|
24
|
+
import com.pointrlabs.core.map.handlers.MapWidgetEventsHandler
|
|
25
|
+
import com.pointrlabs.core.map.handlers.PathFindingEventsHandler
|
|
26
|
+
import com.pointrlabs.core.map.handlers.PathUpdatesEventHandler
|
|
27
|
+
import com.pointrlabs.core.map.models.PTRDeepLinkAction
|
|
28
|
+
import com.pointrlabs.core.map.models.PTRDeepLinkLocation
|
|
29
|
+
import com.pointrlabs.core.map.models.PTRDeepLinkPathfindingAction
|
|
30
|
+
import com.pointrlabs.core.map.models.PTRDeepLinkPoiLocation
|
|
31
|
+
import com.pointrlabs.core.map.models.PTRError
|
|
32
|
+
import com.pointrlabs.core.map.models.PTRMapSymbolLayer
|
|
33
|
+
import com.pointrlabs.core.map.models.events_listeners.MapEventsListener
|
|
34
|
+
import com.pointrlabs.core.map.models.events_listeners.MarkMyCarDetailsEvent
|
|
35
|
+
import com.pointrlabs.core.map.models.events_listeners.MarkMyCarDetailsEventsListener
|
|
36
|
+
import com.pointrlabs.core.map.models.events_listeners.PathFindingEventsListener
|
|
37
|
+
import com.pointrlabs.core.map.viewmodels.PTRMapWidgetConfiguration
|
|
38
|
+
import com.pointrlabs.core.map.views.PTRMapAnimationType
|
|
39
|
+
import com.pointrlabs.core.map.views.PTRMapFragment
|
|
40
|
+
import com.pointrlabs.core.map.views.PTRMapWidgetFragment
|
|
41
|
+
import com.pointrlabs.core.map.views.pathfinding.MarkMyCarBottomSheet
|
|
42
|
+
import com.pointrlabs.core.nativecore.wrappers.Plog
|
|
43
|
+
import com.pointrlabs.core.pathfinding.PathManager
|
|
44
|
+
import com.pointrlabs.core.pathfinding.session.PathSession
|
|
45
|
+
import com.pointrlabs.core.pathfinding.session.PathSessionState
|
|
46
|
+
import com.pointrlabs.core.positioning.model.PositioningTypes
|
|
47
|
+
import com.pointrlabs.core.site.SiteManager
|
|
48
|
+
import java.util.concurrent.Semaphore
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@SuppressLint("LogNotTimber")
|
|
52
|
+
class PTRMapWidgetManager(private val reactContext: ReactApplicationContext) :
|
|
53
|
+
ViewGroupManager<FrameLayout>(), MapEventsListener, MarkMyCarDetailsEventsListener {
|
|
54
|
+
|
|
55
|
+
override fun getName() = REACT_CLASS
|
|
56
|
+
|
|
57
|
+
private var markMyCarButtonSheet: MarkMyCarBottomSheet? = null
|
|
58
|
+
private lateinit var frameLayout: FrameLayout
|
|
59
|
+
|
|
60
|
+
// TODO: Uncomment 1
|
|
61
|
+
// private var _ptrMapWidgetFragment: PTRMapWidgetFragment? = null
|
|
62
|
+
private val ptrMapWidgetFragment: PTRMapWidgetFragment?
|
|
63
|
+
get() {
|
|
64
|
+
// TODO: Uncomment 1
|
|
65
|
+
// _ptrMapWidgetFragment?.let { return it }
|
|
66
|
+
Log.i("PTRMapWidgetManager", "Creating map widget fragment")
|
|
67
|
+
// TODO: Uncomment 1
|
|
68
|
+
//_ptrMapWidgetFragment = createMapWidgetFragment()
|
|
69
|
+
// TODO: Comment 1
|
|
70
|
+
val _ptrMapWidgetFragment = createMapWidgetFragment()
|
|
71
|
+
Choreographer.getInstance().postFrameCallback(frameCallback)
|
|
72
|
+
_ptrMapWidgetFragment?.addListener(this)
|
|
73
|
+
return _ptrMapWidgetFragment
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private fun createMapWidgetFragment(): PTRMapWidgetFragment {
|
|
77
|
+
waitForPointrToRun()
|
|
78
|
+
// TODO: wait for configuration to be ready
|
|
79
|
+
val configuration = PointrMapWidgetActivity.mapWidgetConfiguration
|
|
80
|
+
configuration.isExitButtonShown = false
|
|
81
|
+
@Suppress("DEPRECATION")
|
|
82
|
+
val widget = PTRMapWidgetFragment.newInstance(configuration).show(
|
|
83
|
+
(reactContext.currentActivity as FragmentActivity).supportFragmentManager,
|
|
84
|
+
frameLayout.id
|
|
85
|
+
)
|
|
86
|
+
return widget
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Return a FrameLayout which will later hold the Fragment
|
|
91
|
+
*/
|
|
92
|
+
override fun createViewInstance(reactContext: ThemedReactContext): FrameLayout {
|
|
93
|
+
frameLayout = FrameLayout(reactContext)
|
|
94
|
+
return frameLayout
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Handle "create" command (called from JS) and call createFragment method
|
|
99
|
+
*/
|
|
100
|
+
override fun receiveCommand(
|
|
101
|
+
root: FrameLayout, command: String, args: ReadableArray?
|
|
102
|
+
) {
|
|
103
|
+
super.receiveCommand(root, command, args)
|
|
104
|
+
val args1 = args ?: return
|
|
105
|
+
val ptrMapWidgetFragment = this.ptrMapWidgetFragment ?: run {
|
|
106
|
+
Log.e(
|
|
107
|
+
"PTRMapWidgetManager",
|
|
108
|
+
"PTRMapWidgetFragment is null"
|
|
109
|
+
)
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
// TODO: Uncomment 1
|
|
113
|
+
// clearPath(ptrMapWidgetFragment)
|
|
114
|
+
// dismissMarkMyCarDetails(ptrMapWidgetFragment)
|
|
115
|
+
executeCommand(ptrMapWidgetFragment, command, args1)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private fun dismissMarkMyCarDetails(ptrMapWidgetFragment: PTRMapWidgetFragment) {
|
|
119
|
+
val markMyCarButtonSheet = markMyCarButtonSheet ?: return
|
|
120
|
+
val handler = ptrMapWidgetFragment.markMyCarEventsHandler
|
|
121
|
+
?: return Plog.w("Mark my car events handler is null")
|
|
122
|
+
Plog.i("Dismissing mark my car details")
|
|
123
|
+
handler.onMarkMyCarDetailsEvent(markMyCarButtonSheet, MarkMyCarDetailsEvent.Cancel)
|
|
124
|
+
handler.onMarkMyCarDetailsEvent(markMyCarButtonSheet, MarkMyCarDetailsEvent.Close)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private fun clearPath(ptrMapWidgetFragment: PTRMapWidgetFragment) {
|
|
128
|
+
ptrMapWidgetFragment.mapFragment?.removeAllFeatures { isSuccess, message ->
|
|
129
|
+
if (!isSuccess) {
|
|
130
|
+
Log.e(
|
|
131
|
+
"PTRMapWidgetManager",
|
|
132
|
+
"Error removing features: $message"
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
ptrMapWidgetFragment.mapFragment?.removeLayer(LAYER_STATIC_PATH) { b, e ->
|
|
136
|
+
if (!b) {
|
|
137
|
+
Log.e(
|
|
138
|
+
"PTRMapWidgetManager",
|
|
139
|
+
"Error removing layer: $e"
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
ptrMapWidgetFragment.mapFragment?.currentPath = null
|
|
143
|
+
ptrMapWidgetFragment.mapFragment?.currentPathSession?.abort()
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private fun executeCommand(
|
|
149
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
150
|
+
command: String,
|
|
151
|
+
args1: ReadableArray
|
|
152
|
+
) {
|
|
153
|
+
when (command) {
|
|
154
|
+
PTRMapWidgetCommandType.SITE -> showSite(ptrMapWidgetFragment, args1.getString(0))
|
|
155
|
+
PTRMapWidgetCommandType.BUILDING -> showBuilding(
|
|
156
|
+
ptrMapWidgetFragment,
|
|
157
|
+
args1.getString(0),
|
|
158
|
+
args1.getString(1)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
PTRMapWidgetCommandType.LEVEL -> showLevel(
|
|
162
|
+
ptrMapWidgetFragment,
|
|
163
|
+
args1.getString(0),
|
|
164
|
+
args1.getString(1),
|
|
165
|
+
args1.getInt(2)
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
PTRMapWidgetCommandType.POI -> showPoi(
|
|
169
|
+
ptrMapWidgetFragment,
|
|
170
|
+
args1.getString(0),
|
|
171
|
+
args1.getString(1)
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
PTRMapWidgetCommandType.PATH -> showPath(
|
|
175
|
+
ptrMapWidgetFragment,
|
|
176
|
+
args1.getString(0),
|
|
177
|
+
args1.getString(1)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
PTRMapWidgetCommandType.STATIC_PATH -> showStaticPath(
|
|
181
|
+
ptrMapWidgetFragment,
|
|
182
|
+
args1.getString(0),
|
|
183
|
+
args1.getString(1),
|
|
184
|
+
args1.getString(2)
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
PTRMapWidgetCommandType.MARK_MY_CAR_SITE -> {
|
|
188
|
+
showMarkMyCarDetails(
|
|
189
|
+
ptrMapWidgetFragment,
|
|
190
|
+
args1.getString(0),
|
|
191
|
+
shouldShowPopup = args1.getBoolean(1),
|
|
192
|
+
animationType = args1.getInt(2)
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
PTRMapWidgetCommandType.MARK_MY_CAR_LEVEL -> {
|
|
197
|
+
showMarkMyCarDetails(
|
|
198
|
+
ptrMapWidgetFragment,
|
|
199
|
+
args1.getString(0),
|
|
200
|
+
args1.getString(1),
|
|
201
|
+
args1.getInt(2),
|
|
202
|
+
args1.getBoolean(3),
|
|
203
|
+
args1.getInt(4)
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
PTRMapWidgetCommandType.MY_CAR_SITE -> {
|
|
208
|
+
showMyCarDetails(ptrMapWidgetFragment, args1.getString(0), args1.getInt(1))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
else -> return
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private fun showMyCarDetails(
|
|
216
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
217
|
+
siteExternalIdentifier: String,
|
|
218
|
+
animationTypeOrdinal: Int
|
|
219
|
+
) {
|
|
220
|
+
val animationType = PTRMapAnimationType.entries[animationTypeOrdinal]
|
|
221
|
+
ptrMapWidgetFragment.showMyCarDetails(
|
|
222
|
+
siteExternalIdentifier,
|
|
223
|
+
shouldShowDialog = false,
|
|
224
|
+
animationType = animationType
|
|
225
|
+
) onComplete@{ error ->
|
|
226
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
227
|
+
PTRMapWidgetCommandType.MY_CAR_SITE,
|
|
228
|
+
siteExternalIdentifier,
|
|
229
|
+
animationType,
|
|
230
|
+
error ?: ""
|
|
231
|
+
)
|
|
232
|
+
error?.let {
|
|
233
|
+
Plog.e("Error showing mark my car details: $it")
|
|
234
|
+
return@onComplete
|
|
235
|
+
}
|
|
236
|
+
Plog.i("Mark my car details is shown")
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private fun showMarkMyCarDetails(
|
|
241
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
242
|
+
siteExternalIdentifier: String,
|
|
243
|
+
buildingExternalIdentifier: String? = null,
|
|
244
|
+
levelIndex: Int? = null,
|
|
245
|
+
shouldShowPopup: Boolean,
|
|
246
|
+
animationType: Int
|
|
247
|
+
) {
|
|
248
|
+
|
|
249
|
+
ptrMapWidgetFragment.showMarkMyCarDetails(
|
|
250
|
+
siteExternalIdentifier,
|
|
251
|
+
buildingExternalIdentifier,
|
|
252
|
+
levelIndex,
|
|
253
|
+
PTRMapAnimationType.entries[animationType],
|
|
254
|
+
shouldShowPopup
|
|
255
|
+
) onComplete@{ error ->
|
|
256
|
+
if (buildingExternalIdentifier == null || levelIndex == null || levelIndex == PositioningTypes.INVALID_INTEGER) {
|
|
257
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
258
|
+
PTRMapWidgetCommandType.MARK_MY_CAR_LEVEL,
|
|
259
|
+
siteExternalIdentifier,
|
|
260
|
+
buildingExternalIdentifier ?: "",
|
|
261
|
+
levelIndex ?: PositioningTypes.INVALID_INTEGER,
|
|
262
|
+
shouldShowPopup,
|
|
263
|
+
animationType,
|
|
264
|
+
error ?: ""
|
|
265
|
+
)
|
|
266
|
+
} else {
|
|
267
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
268
|
+
PTRMapWidgetCommandType.MARK_MY_CAR_SITE,
|
|
269
|
+
siteExternalIdentifier,
|
|
270
|
+
shouldShowPopup,
|
|
271
|
+
animationType,
|
|
272
|
+
error ?: ""
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
error?.let {
|
|
276
|
+
Plog.e("Error showing mark my car details: $it")
|
|
277
|
+
return@onComplete
|
|
278
|
+
}
|
|
279
|
+
Plog.i("Mark my car details is shown")
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private fun mapWidgetDidEndLoading(
|
|
284
|
+
@PTRMapWidgetCommandType command: String,
|
|
285
|
+
vararg args: Any
|
|
286
|
+
) {
|
|
287
|
+
val event: WritableMap = WritableNativeMap()
|
|
288
|
+
event.putString("command", command)
|
|
289
|
+
when (command) {
|
|
290
|
+
PTRMapWidgetCommandType.SITE -> {
|
|
291
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
292
|
+
event.putString("error", args[1] as String)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
PTRMapWidgetCommandType.BUILDING -> {
|
|
296
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
297
|
+
event.putString("buildingExternalIdentifier", args[1] as String)
|
|
298
|
+
event.putString("error", args[2] as String)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
PTRMapWidgetCommandType.LEVEL -> {
|
|
302
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
303
|
+
event.putString("buildingExternalIdentifier", args[1] as String)
|
|
304
|
+
event.putInt("levelIndex", args[2] as Int)
|
|
305
|
+
event.putString("error", args[3] as String)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
PTRMapWidgetCommandType.POI -> {
|
|
309
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
310
|
+
event.putString("poiExternalIdentifier", args[1] as String)
|
|
311
|
+
event.putString("error", args[2] as String)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
PTRMapWidgetCommandType.PATH -> {
|
|
315
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
316
|
+
event.putString("poiExternalIdentifier", args[1] as String)
|
|
317
|
+
event.putString("error", args[2] as String)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
PTRMapWidgetCommandType.STATIC_PATH -> {
|
|
321
|
+
event.putString("siteExternalIdentifier", args[0] as String)
|
|
322
|
+
event.putString("fromPoiExternalIdentifier", args[1] as String)
|
|
323
|
+
event.putString("toPoiExternalIdentifier", args[2] as String)
|
|
324
|
+
event.putString("error", args[3] as String)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
else -> {
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(
|
|
332
|
+
frameLayout.id,
|
|
333
|
+
"onMapWidgetDidEndLoading",
|
|
334
|
+
event
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
override fun getExportedCustomBubblingEventTypeConstants(): Map<String, Any> {
|
|
339
|
+
return mapOf(
|
|
340
|
+
"onMapWidgetDidEndLoading" to mapOf(
|
|
341
|
+
"phasedRegistrationNames" to mapOf(
|
|
342
|
+
"bubbled" to "onMapWidgetDidEndLoading"
|
|
343
|
+
)
|
|
344
|
+
)
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
private fun showStaticPath(
|
|
350
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
351
|
+
site: String,
|
|
352
|
+
fromPoi: String,
|
|
353
|
+
toPoi: String
|
|
354
|
+
) {
|
|
355
|
+
val siteObject = getSite(site) ?: run {
|
|
356
|
+
mapWidgetDidEndLoading(
|
|
357
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
358
|
+
site,
|
|
359
|
+
fromPoi,
|
|
360
|
+
toPoi,
|
|
361
|
+
"Site not found"
|
|
362
|
+
)
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
if (!waitForSiteData(siteObject)) {
|
|
366
|
+
mapWidgetDidEndLoading(
|
|
367
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
368
|
+
site,
|
|
369
|
+
fromPoi,
|
|
370
|
+
toPoi,
|
|
371
|
+
"Site data not found"
|
|
372
|
+
)
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
val source = Pointr.getPointr()?.poiManager?.getPoiByExternalIdentifier(siteObject, fromPoi)
|
|
376
|
+
?: run {
|
|
377
|
+
mapWidgetDidEndLoading(
|
|
378
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
379
|
+
site,
|
|
380
|
+
fromPoi,
|
|
381
|
+
toPoi,
|
|
382
|
+
"Source POI not found"
|
|
383
|
+
)
|
|
384
|
+
return
|
|
385
|
+
}
|
|
386
|
+
val target =
|
|
387
|
+
Pointr.getPointr()?.poiManager?.getPoiByExternalIdentifier(siteObject, toPoi) ?: run {
|
|
388
|
+
mapWidgetDidEndLoading(
|
|
389
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
390
|
+
site,
|
|
391
|
+
fromPoi,
|
|
392
|
+
toPoi,
|
|
393
|
+
"Target POI not found"
|
|
394
|
+
)
|
|
395
|
+
return
|
|
396
|
+
}
|
|
397
|
+
if (!waitForPathManager(siteObject)) {
|
|
398
|
+
mapWidgetDidEndLoading(
|
|
399
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
400
|
+
site,
|
|
401
|
+
fromPoi,
|
|
402
|
+
toPoi,
|
|
403
|
+
"Path manager not ready"
|
|
404
|
+
)
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
val pathManager = Pointr.getPointr()?.pathManager ?: run {
|
|
408
|
+
mapWidgetDidEndLoading(
|
|
409
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
410
|
+
site,
|
|
411
|
+
fromPoi,
|
|
412
|
+
toPoi,
|
|
413
|
+
"Path manager not found"
|
|
414
|
+
)
|
|
415
|
+
return
|
|
416
|
+
}
|
|
417
|
+
val path = pathManager.calculatePath(source, listOf(target)) ?: run {
|
|
418
|
+
mapWidgetDidEndLoading(
|
|
419
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
420
|
+
site,
|
|
421
|
+
fromPoi,
|
|
422
|
+
toPoi,
|
|
423
|
+
"Path not found"
|
|
424
|
+
)
|
|
425
|
+
return
|
|
426
|
+
}
|
|
427
|
+
val onCompleted = { error: String? ->
|
|
428
|
+
error?.let {
|
|
429
|
+
mapWidgetDidEndLoading(
|
|
430
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
431
|
+
site,
|
|
432
|
+
fromPoi,
|
|
433
|
+
toPoi,
|
|
434
|
+
"Error loading the map: $it"
|
|
435
|
+
)
|
|
436
|
+
Plog.e("Error showing level: $it")
|
|
437
|
+
return@let
|
|
438
|
+
}
|
|
439
|
+
ptrMapWidgetFragment.focusOnCoordinate(
|
|
440
|
+
source.location.site?.internalIdentifier ?: PositioningTypes.INVALID_INTEGER,
|
|
441
|
+
source.location.building?.internalIdentifier ?: PositioningTypes.INVALID_INTEGER,
|
|
442
|
+
source.location.level?.index ?: PositioningTypes.INVALID_INTEGER,
|
|
443
|
+
source.location.lat,
|
|
444
|
+
source.location.lon
|
|
445
|
+
) {
|
|
446
|
+
val layer = PTRMapSymbolLayer(LAYER_STATIC_PATH)
|
|
447
|
+
val mapFragment = ptrMapWidgetFragment.mapFragment ?: return@focusOnCoordinate
|
|
448
|
+
mapFragment.addLayer(layer) { b1, e1 ->
|
|
449
|
+
if (!b1) {
|
|
450
|
+
mapWidgetDidEndLoading(
|
|
451
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
452
|
+
site,
|
|
453
|
+
fromPoi,
|
|
454
|
+
toPoi,
|
|
455
|
+
"Error adding layer: $e1"
|
|
456
|
+
)
|
|
457
|
+
Plog.e("Error adding layer: $e1")
|
|
458
|
+
return@addLayer
|
|
459
|
+
}
|
|
460
|
+
mapFragment.addFeatures(
|
|
461
|
+
listOf(source, target), layer.identifier
|
|
462
|
+
) { b2, e2 ->
|
|
463
|
+
if (!b2) {
|
|
464
|
+
mapWidgetDidEndLoading(
|
|
465
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
466
|
+
site,
|
|
467
|
+
fromPoi,
|
|
468
|
+
toPoi,
|
|
469
|
+
"Error adding features: $e2"
|
|
470
|
+
)
|
|
471
|
+
Plog.e("Error adding features: $e2")
|
|
472
|
+
return@addFeatures
|
|
473
|
+
}
|
|
474
|
+
mapFragment.currentPath = path
|
|
475
|
+
mapWidgetDidEndLoading(
|
|
476
|
+
PTRMapWidgetCommandType.STATIC_PATH,
|
|
477
|
+
site,
|
|
478
|
+
fromPoi,
|
|
479
|
+
toPoi,
|
|
480
|
+
""
|
|
481
|
+
)
|
|
482
|
+
Plog.i("Path shown")
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
source.level?.let {
|
|
488
|
+
ptrMapWidgetFragment.showLevel(it, onComplete = onCompleted)
|
|
489
|
+
} ?: ptrMapWidgetFragment.showSite(
|
|
490
|
+
source.location.site?.internalIdentifier ?: 0, onComplete = onCompleted
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
private fun showPath(ptrMapWidgetFragment: PTRMapWidgetFragment, site: String, toPoi: String) {
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
val siteObject = getSite(site) ?: run {
|
|
499
|
+
mapWidgetDidEndLoading(
|
|
500
|
+
PTRMapWidgetCommandType.PATH,
|
|
501
|
+
site,
|
|
502
|
+
toPoi,
|
|
503
|
+
"Site not found"
|
|
504
|
+
)
|
|
505
|
+
return
|
|
506
|
+
}
|
|
507
|
+
if (!waitForSiteData(siteObject)) {
|
|
508
|
+
mapWidgetDidEndLoading(
|
|
509
|
+
PTRMapWidgetCommandType.PATH,
|
|
510
|
+
site,
|
|
511
|
+
toPoi,
|
|
512
|
+
"Site data not found"
|
|
513
|
+
)
|
|
514
|
+
return
|
|
515
|
+
}
|
|
516
|
+
val target =
|
|
517
|
+
Pointr.getPointr()?.poiManager?.getPoiByExternalIdentifier(siteObject, toPoi) ?: run {
|
|
518
|
+
mapWidgetDidEndLoading(
|
|
519
|
+
PTRMapWidgetCommandType.PATH,
|
|
520
|
+
site,
|
|
521
|
+
toPoi,
|
|
522
|
+
"Target POI not found"
|
|
523
|
+
)
|
|
524
|
+
return
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
val action = PTRDeepLinkPathfindingAction(
|
|
528
|
+
PTRDeepLinkPoiLocation(
|
|
529
|
+
siteObject.internalIdentifier,
|
|
530
|
+
target.id
|
|
531
|
+
)
|
|
532
|
+
)
|
|
533
|
+
ptrMapWidgetFragment.performDeepLinkAction(action) { error ->
|
|
534
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
535
|
+
PTRMapWidgetCommandType.PATH,
|
|
536
|
+
site,
|
|
537
|
+
toPoi,
|
|
538
|
+
error ?: ""
|
|
539
|
+
)
|
|
540
|
+
error?.let {
|
|
541
|
+
Plog.e("Error showing path: $it")
|
|
542
|
+
return@performDeepLinkAction
|
|
543
|
+
}
|
|
544
|
+
Plog.i("Path shown")
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
private fun showPoi(ptrMapWidgetFragment: PTRMapWidgetFragment, site: String, poi: String) {
|
|
549
|
+
ptrMapWidgetFragment.showPoiDetails(site, poi) { error ->
|
|
550
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
551
|
+
PTRMapWidgetCommandType.POI,
|
|
552
|
+
site,
|
|
553
|
+
poi,
|
|
554
|
+
error ?: ""
|
|
555
|
+
)
|
|
556
|
+
error?.let {
|
|
557
|
+
Plog.e("Error showing poi: $it")
|
|
558
|
+
return@showPoiDetails
|
|
559
|
+
}
|
|
560
|
+
Plog.i("Poi shown")
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
private fun showLevel(
|
|
565
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
566
|
+
site: String,
|
|
567
|
+
building: String,
|
|
568
|
+
level: Int
|
|
569
|
+
) {
|
|
570
|
+
ptrMapWidgetFragment.showLevel(site, building, level) showLevelInternal@{ error ->
|
|
571
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
572
|
+
PTRMapWidgetCommandType.LEVEL,
|
|
573
|
+
site,
|
|
574
|
+
building,
|
|
575
|
+
level,
|
|
576
|
+
error ?: ""
|
|
577
|
+
)
|
|
578
|
+
error?.let {
|
|
579
|
+
Plog.e("Error showing level: $it")
|
|
580
|
+
return@showLevelInternal
|
|
581
|
+
}
|
|
582
|
+
Plog.i("Level shown")
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
private fun showBuilding(
|
|
587
|
+
ptrMapWidgetFragment: PTRMapWidgetFragment,
|
|
588
|
+
site: String,
|
|
589
|
+
building: String
|
|
590
|
+
) {
|
|
591
|
+
ptrMapWidgetFragment.showBuilding(site, building) showBuildingInternal@{ error ->
|
|
592
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
593
|
+
PTRMapWidgetCommandType.BUILDING,
|
|
594
|
+
site,
|
|
595
|
+
building,
|
|
596
|
+
error ?: ""
|
|
597
|
+
)
|
|
598
|
+
error?.let {
|
|
599
|
+
Plog.e("Error showing building: $it")
|
|
600
|
+
return@showBuildingInternal
|
|
601
|
+
}
|
|
602
|
+
Plog.i("Building shown")
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
private fun showSite(ptrMapWidgetFragment: PTRMapWidgetFragment, site: String) {
|
|
607
|
+
ptrMapWidgetFragment.showSite(site) showSiteInternal@{ error ->
|
|
608
|
+
this@PTRMapWidgetManager.mapWidgetDidEndLoading(
|
|
609
|
+
PTRMapWidgetCommandType.SITE,
|
|
610
|
+
site,
|
|
611
|
+
error ?: ""
|
|
612
|
+
)
|
|
613
|
+
error?.let {
|
|
614
|
+
Plog.e("Error showing site: $it")
|
|
615
|
+
return@showSiteInternal
|
|
616
|
+
}
|
|
617
|
+
Plog.i("Site shown")
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// region Show path
|
|
622
|
+
|
|
623
|
+
private fun waitForPathManager(theSite: Site): Boolean {
|
|
624
|
+
val pathManager = Pointr.getPointr()?.pathManager ?: return false
|
|
625
|
+
val semaphore = Semaphore(0)
|
|
626
|
+
val listener = object : PathManager.Listener {
|
|
627
|
+
override fun onPathManagerReadyForSite(site: Site) {
|
|
628
|
+
if (site != theSite) return
|
|
629
|
+
semaphore.release()
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
pathManager.addListener(listener)
|
|
633
|
+
if (!pathManager.isReadyForSite(theSite)) {
|
|
634
|
+
semaphore.tryAcquire(15, java.util.concurrent.TimeUnit.SECONDS)
|
|
635
|
+
}
|
|
636
|
+
pathManager.removeListener(listener)
|
|
637
|
+
return pathManager.isReadyForSite(theSite)
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
private fun waitForSiteData(theSite: Site): Boolean {
|
|
641
|
+
val dataManager = Pointr.getPointr()?.dataManager ?: return false
|
|
642
|
+
val semaphore = Semaphore(0)
|
|
643
|
+
val listener = object : DataManager.Listener {
|
|
644
|
+
override fun onDataManagerCompleteAllForSite(
|
|
645
|
+
site: Site,
|
|
646
|
+
isSuccessful: Boolean,
|
|
647
|
+
isOnlineData: Boolean,
|
|
648
|
+
errors: List<ErrorMessage?>?
|
|
649
|
+
) {
|
|
650
|
+
if (site != theSite) return
|
|
651
|
+
if (!isOnlineData) return
|
|
652
|
+
semaphore.release()
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
dataManager.addListener(listener)
|
|
656
|
+
if (Pointr.getPointr()?.poiManager?.hasContentForSite(theSite) != true) {
|
|
657
|
+
dataManager.loadDataForSite(theSite)
|
|
658
|
+
semaphore.tryAcquire(15, java.util.concurrent.TimeUnit.SECONDS)
|
|
659
|
+
}
|
|
660
|
+
dataManager.removeListener(listener)
|
|
661
|
+
return Pointr.getPointr()?.poiManager?.hasContentForSite(theSite) == true
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
private fun getSite(site: String): Site? {
|
|
665
|
+
val siteManager = Pointr.getPointr()?.siteManager ?: return null
|
|
666
|
+
val semaphore = Semaphore(0)
|
|
667
|
+
val listener = object : SiteManager.Listener {
|
|
668
|
+
override fun onSiteManagerDataChanged() {
|
|
669
|
+
semaphore.release()
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
siteManager.addListener(listener)
|
|
673
|
+
if (siteManager.getSites().isEmpty()) {
|
|
674
|
+
semaphore.tryAcquire(10, java.util.concurrent.TimeUnit.SECONDS)
|
|
675
|
+
}
|
|
676
|
+
siteManager.removeListener(listener)
|
|
677
|
+
return siteManager.getSite(site)
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// endregion
|
|
681
|
+
|
|
682
|
+
private fun waitForPointrToRun(): Boolean {
|
|
683
|
+
Log.e(
|
|
684
|
+
"PTRMapWidgetManager",
|
|
685
|
+
"Waiting for Pointr to run"
|
|
686
|
+
)
|
|
687
|
+
val semaphore = Semaphore(0)
|
|
688
|
+
val listener = object : PointrListener {
|
|
689
|
+
override fun onStateUpdated(p0: Pointr.State?) {
|
|
690
|
+
Log.e(
|
|
691
|
+
"PTRMapWidgetManager",
|
|
692
|
+
"Pointr state updated to: $p0"
|
|
693
|
+
)
|
|
694
|
+
val state = p0 ?: return
|
|
695
|
+
if (state.`val` < Pointr.State.OFF.`val` || state == Pointr.State.RUNNING) {
|
|
696
|
+
semaphore.release()
|
|
697
|
+
return
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
Log.e(
|
|
702
|
+
"PTRMapWidgetManager",
|
|
703
|
+
"Adding listener to Pointr"
|
|
704
|
+
)
|
|
705
|
+
Pointr.getPointr()?.addListener(listener)
|
|
706
|
+
Log.e(
|
|
707
|
+
"PTRMapWidgetManager",
|
|
708
|
+
"Pointr state: ${Pointr.getPointr()?.state}"
|
|
709
|
+
)
|
|
710
|
+
if (Pointr.getPointr()?.state == Pointr.State.RUNNING) {
|
|
711
|
+
Log.e(
|
|
712
|
+
"PTRMapWidgetManager",
|
|
713
|
+
"Already running Pointr"
|
|
714
|
+
)
|
|
715
|
+
Pointr.getPointr()?.removeListener(listener)
|
|
716
|
+
return true
|
|
717
|
+
}
|
|
718
|
+
Log.e(
|
|
719
|
+
"PTRMapWidgetManager",
|
|
720
|
+
"Starting Pointr"
|
|
721
|
+
)
|
|
722
|
+
Pointr.getPointr()?.start()
|
|
723
|
+
Log.e(
|
|
724
|
+
"PTRMapWidgetManager",
|
|
725
|
+
"Pointr started"
|
|
726
|
+
)
|
|
727
|
+
semaphore.tryAcquire(10, java.util.concurrent.TimeUnit.SECONDS)
|
|
728
|
+
Log.e(
|
|
729
|
+
"PTRMapWidgetManager",
|
|
730
|
+
"Final Pointr state: ${Pointr.getPointr()?.state}"
|
|
731
|
+
)
|
|
732
|
+
Pointr.getPointr()?.removeListener(listener)
|
|
733
|
+
return Pointr.getPointr()?.state == Pointr.State.RUNNING
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
override fun mapDidEndLoading(mapFragment: PTRMapFragment) {
|
|
737
|
+
super.mapDidEndLoading(mapFragment)
|
|
738
|
+
Log.i("PTRMapWidgetManager", "Map loaded")
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
override fun mapDidFailToLoad(mapFragment: PTRMapFragment, ptrError: PTRError) {
|
|
742
|
+
super.mapDidFailToLoad(mapFragment, ptrError)
|
|
743
|
+
Log.e("PTRMapWidgetManager", "Map failed to load: $ptrError")
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
override fun onMarkMyCarDetailsEvent(
|
|
747
|
+
markMyCarSheet: MarkMyCarBottomSheet,
|
|
748
|
+
markMyCarDetailsEvent: MarkMyCarDetailsEvent
|
|
749
|
+
) {
|
|
750
|
+
super.onMarkMyCarDetailsEvent(markMyCarSheet, markMyCarDetailsEvent)
|
|
751
|
+
this.markMyCarButtonSheet = markMyCarSheet
|
|
752
|
+
Plog.i("Mark my car details event: $markMyCarDetailsEvent")
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
private val frameCallback = object : Choreographer.FrameCallback {
|
|
756
|
+
override fun doFrame(frameTimeNanos: Long) {
|
|
757
|
+
frameLayout.measure(
|
|
758
|
+
View.MeasureSpec.makeMeasureSpec(frameLayout.width, View.MeasureSpec.EXACTLY),
|
|
759
|
+
View.MeasureSpec.makeMeasureSpec(frameLayout.height, View.MeasureSpec.EXACTLY)
|
|
760
|
+
)
|
|
761
|
+
frameLayout.layout(
|
|
762
|
+
frameLayout.left,
|
|
763
|
+
frameLayout.top,
|
|
764
|
+
frameLayout.right,
|
|
765
|
+
frameLayout.bottom
|
|
766
|
+
)
|
|
767
|
+
frameLayout.viewTreeObserver.dispatchOnGlobalLayout()
|
|
768
|
+
Choreographer.getInstance().postFrameCallback(this)
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
companion object {
|
|
773
|
+
const val REACT_CLASS = "PTRMapWidget"
|
|
774
|
+
const val LAYER_STATIC_PATH = "sym-static-path"
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
}
|