@rnmapbox/maps 10.1.0-rc.2 → 10.1.0-rc.4

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.
Files changed (61) hide show
  1. package/android/src/main/java/com/rnmapbox/rnmbx/RNMBXPackage.kt +11 -0
  2. package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerView.kt +11 -3
  3. package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewContent.kt +16 -8
  4. package/android/src/main/java/com/rnmapbox/rnmbx/components/annotation/RNMBXMarkerViewManager.kt +5 -0
  5. package/android/src/main/java/com/rnmapbox/rnmbx/modules/RNMBXOfflineModuleLegacy.kt +444 -0
  6. package/android/src/main/mapbox-v11-compat/v10/com/rnmapbox/rnmbx/v11compat/Annotation.kt +4 -0
  7. package/android/src/main/mapbox-v11-compat/v11/com/rnmapbox/rnmbx/v11compat/Annotation.kt +0 -1
  8. package/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXMarkerViewManagerDelegate.java +3 -0
  9. package/android/src/main/old-arch/com/facebook/react/viewmanagers/RNMBXMarkerViewManagerInterface.java +1 -0
  10. package/ios/RNMBX/RNMBXMarkerView.swift +10 -1
  11. package/ios/RNMBX/RNMBXMarkerViewComponentView.mm +4 -0
  12. package/ios/RNMBX/RNMBXMarkerViewManager.m +1 -0
  13. package/ios/RNMBX/RNMBXOfflineModule.m +1 -1
  14. package/ios/RNMBX/RNMBXOfflineModuleLegacy.m +33 -0
  15. package/ios/RNMBX/RNMBXOfflineModuleLegacy.swift +431 -0
  16. package/lib/commonjs/Mapbox.js +8 -0
  17. package/lib/commonjs/Mapbox.js.map +1 -1
  18. package/lib/commonjs/components/MarkerView.js +2 -0
  19. package/lib/commonjs/components/MarkerView.js.map +1 -1
  20. package/lib/commonjs/modules/offline/OfflinePackLegacy.js +40 -0
  21. package/lib/commonjs/modules/offline/OfflinePackLegacy.js.map +1 -0
  22. package/lib/commonjs/modules/offline/offlineManager.js +4 -4
  23. package/lib/commonjs/modules/offline/offlineManager.js.map +1 -1
  24. package/lib/commonjs/modules/offline/offlineManagerLegacy.js +166 -0
  25. package/lib/commonjs/modules/offline/offlineManagerLegacy.js.map +1 -0
  26. package/lib/commonjs/specs/RNMBXMarkerViewNativeComponent.js.map +1 -1
  27. package/lib/module/Mapbox.js +1 -0
  28. package/lib/module/Mapbox.js.map +1 -1
  29. package/lib/module/components/MarkerView.js +2 -0
  30. package/lib/module/components/MarkerView.js.map +1 -1
  31. package/lib/module/modules/offline/OfflinePackLegacy.js +34 -0
  32. package/lib/module/modules/offline/OfflinePackLegacy.js.map +1 -0
  33. package/lib/module/modules/offline/offlineManager.js +4 -4
  34. package/lib/module/modules/offline/offlineManager.js.map +1 -1
  35. package/lib/module/modules/offline/offlineManagerLegacy.js +154 -0
  36. package/lib/module/modules/offline/offlineManagerLegacy.js.map +1 -0
  37. package/lib/module/specs/RNMBXMarkerViewNativeComponent.js.map +1 -1
  38. package/lib/typescript/src/Mapbox.d.ts +1 -0
  39. package/lib/typescript/src/Mapbox.d.ts.map +1 -1
  40. package/lib/typescript/src/components/Images.d.ts +1 -1
  41. package/lib/typescript/src/components/MapView.d.ts +1 -1
  42. package/lib/typescript/src/components/MarkerView.d.ts +5 -0
  43. package/lib/typescript/src/components/MarkerView.d.ts.map +1 -1
  44. package/lib/typescript/src/modules/offline/OfflinePackLegacy.d.ts +24 -0
  45. package/lib/typescript/src/modules/offline/OfflinePackLegacy.d.ts.map +1 -0
  46. package/lib/typescript/src/modules/offline/offlineManager.d.ts +1 -1
  47. package/lib/typescript/src/modules/offline/offlineManager.d.ts.map +1 -1
  48. package/lib/typescript/src/modules/offline/offlineManagerLegacy.d.ts +93 -0
  49. package/lib/typescript/src/modules/offline/offlineManagerLegacy.d.ts.map +1 -0
  50. package/lib/typescript/src/specs/RNMBXMarkerViewNativeComponent.d.ts +1 -0
  51. package/lib/typescript/src/specs/RNMBXMarkerViewNativeComponent.d.ts.map +1 -1
  52. package/package.json +3 -2
  53. package/setup-jest.js +15 -0
  54. package/src/Mapbox.ts +1 -0
  55. package/src/components/Images.tsx +1 -1
  56. package/src/components/MapView.tsx +1 -1
  57. package/src/components/MarkerView.tsx +8 -0
  58. package/src/modules/offline/OfflinePackLegacy.ts +55 -0
  59. package/src/modules/offline/offlineManager.ts +4 -4
  60. package/src/modules/offline/offlineManagerLegacy.ts +181 -0
  61. package/src/specs/RNMBXMarkerViewNativeComponent.ts +1 -0
@@ -48,6 +48,7 @@ import com.rnmapbox.rnmbx.modules.RNMBXLocationModule
48
48
  import com.rnmapbox.rnmbx.modules.RNMBXLogging
49
49
  import com.rnmapbox.rnmbx.modules.RNMBXModule
50
50
  import com.rnmapbox.rnmbx.modules.RNMBXOfflineModule
51
+ import com.rnmapbox.rnmbx.modules.RNMBXOfflineModuleLegacy
51
52
  import com.rnmapbox.rnmbx.modules.RNMBXSnapshotModule
52
53
  import com.rnmapbox.rnmbx.shape_animators.RNMBXMovePointShapeAnimatorModule
53
54
  import com.rnmapbox.rnmbx.shape_animators.ShapeAnimatorManager
@@ -89,6 +90,7 @@ class RNMBXPackage : TurboReactPackage() {
89
90
  RNMBXModule.REACT_CLASS -> return RNMBXModule(reactApplicationContext)
90
91
  RNMBXLocationModule.REACT_CLASS -> return RNMBXLocationModule(reactApplicationContext)
91
92
  RNMBXOfflineModule.REACT_CLASS -> return RNMBXOfflineModule(reactApplicationContext)
93
+ RNMBXOfflineModuleLegacy.REACT_CLASS -> return RNMBXOfflineModuleLegacy(reactApplicationContext)
92
94
  RNMBXSnapshotModule.REACT_CLASS -> return RNMBXSnapshotModule(reactApplicationContext)
93
95
  RNMBXLogging.REACT_CLASS -> return RNMBXLogging(reactApplicationContext)
94
96
  NativeMapViewModule.NAME -> return NativeMapViewModule(reactApplicationContext, getViewTagResolver(reactApplicationContext, s))
@@ -187,6 +189,15 @@ class RNMBXPackage : TurboReactPackage() {
187
189
  false, // isCxxModule
188
190
  false // isTurboModule
189
191
  )
192
+ moduleInfos[RNMBXOfflineModuleLegacy.REACT_CLASS] = ReactModuleInfo(
193
+ RNMBXOfflineModuleLegacy.REACT_CLASS,
194
+ RNMBXOfflineModuleLegacy.REACT_CLASS,
195
+ false, // canOverrideExistingModule
196
+ false, // needsEagerInit
197
+ true, // hasConstants
198
+ false, // isCxxModule
199
+ false // isTurboModule
200
+ )
190
201
  moduleInfos[RNMBXSnapshotModule.REACT_CLASS] = ReactModuleInfo(
191
202
  RNMBXSnapshotModule.REACT_CLASS,
192
203
  RNMBXSnapshotModule.REACT_CLASS,
@@ -31,6 +31,7 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa
31
31
  private var mCoordinate: Point? = null
32
32
  private var mAnchor: Vec2 = Vec2(0.5, 0.5)
33
33
  private var mAllowOverlap = false
34
+ private var mAllowOverlapWithPuck = false
34
35
  private var mIsSelected = false
35
36
 
36
37
  fun setCoordinate(point: Point?) {
@@ -48,6 +49,11 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa
48
49
  update()
49
50
  }
50
51
 
52
+ fun setAllowOverlapWithPuck(allowOverlapWithPuck: Boolean) {
53
+ mAllowOverlapWithPuck = allowOverlapWithPuck
54
+ update()
55
+ }
56
+
51
57
  fun setIsSelected(isSelected: Boolean) {
52
58
  mIsSelected = isSelected
53
59
  update()
@@ -116,13 +122,14 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa
116
122
 
117
123
  val options = getOptions()
118
124
 
119
-
125
+ val content = view as? RNMBXMarkerViewContent;
126
+ content?.inAdd = true;
127
+ didAddToMap = true
120
128
  val annotation = mMapView?.viewAnnotationManager?.addViewAnnotation(
121
129
  view,
122
130
  options
123
131
  )
124
- didAddToMap = true
125
-
132
+ content?.inAdd = false;
126
133
  }
127
134
 
128
135
  fun update() {
@@ -176,6 +183,7 @@ class RNMBXMarkerView(context: Context?, private val mManager: RNMBXMarkerViewMa
176
183
  width(width.toDouble())
177
184
  height(height.toDouble())
178
185
  allowOverlap(mAllowOverlap)
186
+ allowOverlapWithPuck(mAllowOverlapWithPuck)
179
187
  offsets(offset.dx, offset.dy)
180
188
  selected(mIsSelected)
181
189
 
@@ -1,21 +1,29 @@
1
1
  package com.rnmapbox.rnmbx.components.annotation
2
2
 
3
3
  import android.content.Context
4
+ import android.view.View.MeasureSpec
4
5
  import com.facebook.react.uimanager.MeasureSpecAssertions
5
6
  import com.facebook.react.views.view.ReactViewGroup
6
7
 
7
8
  class RNMBXMarkerViewContent(context: Context): ReactViewGroup(context) {
9
+
10
+ var inAdd: Boolean = false
8
11
  // see https://github.com/rnmapbox/maps/pull/3235
9
12
  override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
10
- try {
13
+ if (inAdd) {
14
+ val w = if (widthMeasureSpec == 0) {
15
+ MeasureSpec.makeMeasureSpec(measuredWidth, MeasureSpec.EXACTLY)
16
+ } else {
17
+ widthMeasureSpec
18
+ };
19
+ val h = if (heightMeasureSpec == 0) {
20
+ MeasureSpec.makeMeasureSpec(measuredHeight, MeasureSpec.EXACTLY)
21
+ } else {
22
+ heightMeasureSpec
23
+ }
24
+ super.onMeasure(w, h)
25
+ } else {
11
26
  super.onMeasure(widthMeasureSpec, heightMeasureSpec)
12
- } catch(e: IllegalStateException) {
13
- val w = MeasureSpec.getSize(widthMeasureSpec)
14
- val h = MeasureSpec.getSize(heightMeasureSpec)
15
- setMeasuredDimension(
16
- if (w == 0) measuredWidth else w,
17
- if (h == 0) measuredHeight else h
18
- )
19
27
  }
20
28
  }
21
29
 
@@ -49,6 +49,11 @@ class RNMBXMarkerViewManager(reactApplicationContext: ReactApplicationContext) :
49
49
  markerView.setAllowOverlap(allowOverlap.asBoolean())
50
50
  }
51
51
 
52
+ @ReactProp(name = "allowOverlapWithPuck")
53
+ override fun setAllowOverlapWithPuck(markerView: RNMBXMarkerView, allowOverlapWithPuck: Dynamic) {
54
+ markerView.setAllowOverlapWithPuck(allowOverlapWithPuck.asBoolean())
55
+ }
56
+
52
57
  @ReactProp(name = "isSelected")
53
58
  override fun setIsSelected(markerView: RNMBXMarkerView, isSelected: Dynamic) {
54
59
  markerView.setIsSelected(isSelected.asBoolean())
@@ -0,0 +1,444 @@
1
+ package com.rnmapbox.rnmbx.modules
2
+
3
+ import android.os.Build
4
+ import android.util.Log
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.Promise
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
9
+ import com.facebook.react.bridge.ReactMethod
10
+ import com.facebook.react.bridge.ReadableMap
11
+ import com.facebook.react.bridge.UiThreadUtil
12
+ import com.facebook.react.bridge.WritableMap
13
+ import com.facebook.react.module.annotations.ReactModule
14
+ import com.mapbox.bindgen.Expected
15
+ import com.mapbox.geojson.FeatureCollection
16
+ import com.mapbox.geojson.Point
17
+ import com.mapbox.maps.CoordinateBounds
18
+ import com.mapbox.maps.GlyphsRasterizationMode
19
+ import com.mapbox.maps.OfflineRegion
20
+ import com.mapbox.maps.OfflineRegionCallback
21
+ import com.mapbox.maps.OfflineRegionCreateCallback
22
+ import com.mapbox.maps.OfflineRegionDownloadState
23
+ import com.mapbox.maps.OfflineRegionManager
24
+ import com.mapbox.maps.OfflineRegionStatus
25
+ import com.mapbox.maps.OfflineRegionTilePyramidDefinition
26
+ import com.rnmapbox.rnmbx.utils.ConvertUtils
27
+ import com.rnmapbox.rnmbx.utils.extensions.toGeometryCollection
28
+ import com.rnmapbox.rnmbx.utils.writableArrayOf
29
+ import com.rnmapbox.rnmbx.v11compat.offlinemanager.getOfflineRegionManager
30
+ import org.json.JSONException
31
+ import org.json.JSONObject
32
+ import java.io.File
33
+ import java.io.UnsupportedEncodingException
34
+ import java.nio.file.Files
35
+ import java.nio.file.Paths
36
+ import java.nio.file.StandardCopyOption
37
+ import kotlin.math.ceil
38
+
39
+
40
+ @ReactModule(name = RNMBXOfflineModuleLegacy.REACT_CLASS)
41
+ class RNMBXOfflineModuleLegacy(private val mReactContext: ReactApplicationContext) :
42
+ ReactContextBaseJavaModule(
43
+ mReactContext
44
+ ) {
45
+ companion object {
46
+ const val REACT_CLASS = "RNMBXOfflineModuleLegacy"
47
+ const val LOG_TAG = "OfflineModuleLegacy"
48
+ const val DEFAULT_STYLE_URL = "mapbox://styles/mapbox/streets-v11"
49
+ const val DEFAULT_MIN_ZOOM_LEVEL = 10.0
50
+ const val DEFAULT_MAX_ZOOM_LEVEL = 20.0
51
+ const val COMPLETE_REGION_DOWNLOAD_STATE = 2
52
+ }
53
+
54
+ override fun getName(): String {
55
+ return REACT_CLASS
56
+ }
57
+
58
+ val offlineRegionManager: OfflineRegionManager by lazy {
59
+ getOfflineRegionManager {
60
+ RNMBXModule.getAccessToken(mReactContext)
61
+ }
62
+ }
63
+
64
+ private fun makeDefinition(
65
+ bounds: CoordinateBounds,
66
+ options: ReadableMap
67
+ ): OfflineRegionTilePyramidDefinition {
68
+ return OfflineRegionTilePyramidDefinition.Builder()
69
+ .styleURL(ConvertUtils.getString("styleURL", options, DEFAULT_STYLE_URL))
70
+ .bounds(bounds)
71
+ .minZoom(ConvertUtils.getDouble("minZoom", options, DEFAULT_MIN_ZOOM_LEVEL))
72
+ .maxZoom(ConvertUtils.getDouble("maxZoom", options, DEFAULT_MAX_ZOOM_LEVEL))
73
+ .pixelRatio(mReactContext.getResources().getDisplayMetrics().density)
74
+ .glyphsRasterizationMode(GlyphsRasterizationMode.IDEOGRAPHS_RASTERIZED_LOCALLY)
75
+ .build()
76
+ }
77
+
78
+ private fun convertPointPairToBounds(boundsFC: FeatureCollection): CoordinateBounds? {
79
+ val geometryCollection = boundsFC.toGeometryCollection()
80
+ val geometries = geometryCollection.geometries()
81
+ if (geometries.size != 2) {
82
+ return null
83
+ }
84
+ val pt0 = geometries.get(0) as Point?
85
+ val pt1 = geometries.get(1) as Point?
86
+ if (pt0 == null || pt1 == null) {
87
+ return null
88
+ }
89
+ return CoordinateBounds(pt0, pt1)
90
+ }
91
+
92
+ private fun createPackCallback(promise: Promise, metadata: ByteArray): OfflineRegionCreateCallback {
93
+ return OfflineRegionCreateCallback { expected ->
94
+ if (expected.isValue) {
95
+ expected.value?.let {
96
+ it.setOfflineRegionDownloadState(OfflineRegionDownloadState.ACTIVE)
97
+ it.setMetadata(metadata) { expectedMetadata ->
98
+ if (expectedMetadata.isError) {
99
+ promise.reject("createPack error:", "Failed to setMetadata")
100
+ } else {
101
+ Log.d(LOG_TAG, "createPack done:")
102
+ promise.resolve(fromOfflineRegion(it))
103
+ }
104
+ }
105
+ }
106
+ } else {
107
+ Log.d(LOG_TAG, "createPack error:")
108
+ promise.reject("createPack error:", "Failed to create OfflineRegion")
109
+ }
110
+ }
111
+ }
112
+
113
+
114
+ private fun fromOfflineRegion(region: OfflineRegion): WritableMap? {
115
+ val bb = region.tilePyramidDefinition?.bounds
116
+ val map = Arguments.createMap()
117
+
118
+ if (bb === null) return map
119
+
120
+ val jsonBounds = writableArrayOf(
121
+ writableArrayOf(bb.east(), bb.north()),
122
+ writableArrayOf(bb.west(), bb.south())
123
+ )
124
+
125
+ map.putArray("bounds", jsonBounds)
126
+ map.putString("metadata", String(region.metadata))
127
+
128
+ return map
129
+ }
130
+
131
+ private fun getMetadataBytes(metadata: String?): ByteArray? {
132
+ var metadataBytes: ByteArray? = null
133
+ if (metadata == null || metadata.isEmpty()) {
134
+ return metadataBytes
135
+ }
136
+ try {
137
+ metadataBytes = metadata.toByteArray(charset("utf-8"))
138
+ } catch (e: UnsupportedEncodingException) {
139
+ Log.w(LOG_TAG, e.localizedMessage)
140
+ }
141
+ return metadataBytes
142
+ }
143
+
144
+ private fun getRegionByName(
145
+ name: String?,
146
+ offlineRegions: List<OfflineRegion>
147
+ ): OfflineRegion? {
148
+ if (name.isNullOrEmpty()) {
149
+ return null
150
+ }
151
+ for (region in offlineRegions) {
152
+ try {
153
+ val byteMetadata = region.metadata
154
+
155
+ if (byteMetadata != null) {
156
+ val metadata = JSONObject(String(byteMetadata))
157
+ if (name == metadata.getString("name")) {
158
+ return region
159
+ }
160
+ }
161
+ } catch (e: JSONException) {
162
+ Log.w(LOG_TAG, e.localizedMessage)
163
+ }
164
+ }
165
+ return null
166
+ }
167
+
168
+ private fun makeRegionStatus(regionName: String, status: OfflineRegionStatus): WritableMap? {
169
+ val map = Arguments.createMap()
170
+ val progressPercentage = if (status.requiredResourceCount > 0) status.completedResourceCount.toDouble() / status.requiredResourceCount.toDouble() else 0.0
171
+ val percentage = ceil(progressPercentage * 100.0).coerceAtMost(100.0)
172
+ val isCompleted = percentage == 100.0
173
+ val downloadState = if (isCompleted) COMPLETE_REGION_DOWNLOAD_STATE else status.downloadState.ordinal
174
+
175
+ map.putString("name", regionName)
176
+ map.putInt("state", downloadState)
177
+ map.putDouble("percentage", percentage)
178
+ map.putInt("completedResourceCount", status.completedResourceCount.toInt())
179
+ map.putInt("completedResourceSize", status.completedResourceSize.toInt())
180
+ map.putInt("completedTileSize", status.completedTileSize.toInt())
181
+ map.putInt("completedTileCount", status.completedTileCount.toInt())
182
+ map.putInt("requiredResourceCount", status.requiredResourceCount.toInt())
183
+ return map
184
+ }
185
+
186
+ @ReactMethod
187
+ @Throws(JSONException::class)
188
+ fun createPack(options: ReadableMap, promise: Promise) {
189
+ try {
190
+ val metadataBytes: ByteArray? =
191
+ getMetadataBytes(ConvertUtils.getString("metadata", options, ""))
192
+
193
+ val boundsStr = options.getString("bounds")!!
194
+ val boundsFC = FeatureCollection.fromJson(boundsStr)
195
+ val bounds = convertPointPairToBounds(boundsFC)
196
+
197
+ if (metadataBytes == null || bounds == null) {
198
+ promise.reject("createPack error:", "No metadata or bounds set")
199
+ return
200
+ };
201
+
202
+ val definition: OfflineRegionTilePyramidDefinition = makeDefinition(bounds, options)
203
+
204
+ UiThreadUtil.runOnUiThread {
205
+ offlineRegionManager.createOfflineRegion(definition, createPackCallback(promise, metadataBytes))
206
+ }
207
+
208
+ } catch (e: Throwable) {
209
+ promise.reject("createPack error:", e)
210
+ }
211
+ }
212
+
213
+ @ReactMethod
214
+ fun getPacks(promise: Promise) {
215
+ UiThreadUtil.runOnUiThread {
216
+ offlineRegionManager.getOfflineRegions(object: OfflineRegionCallback {
217
+ override fun run(expected: Expected<String, MutableList<OfflineRegion>>) {
218
+ if (expected.isValue) {
219
+ expected.value?.let {
220
+ val payload = Arguments.createArray()
221
+
222
+ for (region in it) {
223
+ payload.pushMap(fromOfflineRegion(region!!))
224
+ }
225
+
226
+ Log.d(LOG_TAG, "getPacks done:" + it.size.toString())
227
+ promise.resolve(payload)
228
+ }
229
+ } else {
230
+ promise.reject("getPacks error:", expected.error)
231
+ Log.d(LOG_TAG, "getPacks error:${expected.error}")
232
+ }
233
+ }
234
+ })
235
+ }
236
+ }
237
+
238
+ @ReactMethod
239
+ fun deletePack(name: String?, promise: Promise) {
240
+ UiThreadUtil.runOnUiThread {
241
+ offlineRegionManager.getOfflineRegions { regionsExpected ->
242
+ if (regionsExpected.isValue) {
243
+ regionsExpected.value?.let { regions ->
244
+ var region = getRegionByName(name, regions);
245
+
246
+ if (region == null) {
247
+ promise.resolve(null);
248
+ Log.w(LOG_TAG, "deleteRegion - Unknown offline region");
249
+ return@getOfflineRegions
250
+ }
251
+
252
+ region.setOfflineRegionDownloadState(OfflineRegionDownloadState.INACTIVE)
253
+
254
+ region.purge { purgeExpected ->
255
+ if (purgeExpected.isError) {
256
+ promise.reject("deleteRegion error:", purgeExpected.error);
257
+ } else {
258
+ promise.resolve(null);
259
+ }
260
+ }
261
+ }
262
+ } else {
263
+ promise.reject("deleteRegion error:", regionsExpected.error);
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ @ReactMethod
270
+ fun invalidatePack(name: String?, promise: Promise) {
271
+ UiThreadUtil.runOnUiThread {
272
+ offlineRegionManager.getOfflineRegions { expected ->
273
+ if (expected.isValue) {
274
+ expected.value?.let { regions ->
275
+ var region = getRegionByName(name, regions);
276
+
277
+ if (region == null) {
278
+ promise.resolve(null);
279
+ Log.w(LOG_TAG, "invalidateRegion - Unknown offline region");
280
+ return@getOfflineRegions
281
+ }
282
+
283
+ region.invalidate { expected ->
284
+ if (expected.isError) {
285
+ promise.reject("invalidateRegion error:", expected.error);
286
+ } else {
287
+ promise.resolve(null);
288
+ }
289
+ }
290
+ }
291
+ } else {
292
+ promise.reject("invalidateRegion error:", expected.error);
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ @ReactMethod
299
+ fun getPackStatus(name: String?, promise: Promise) {
300
+ UiThreadUtil.runOnUiThread {
301
+ offlineRegionManager.getOfflineRegions { expected ->
302
+ if (expected.isValue) {
303
+ expected.value?.let { regions ->
304
+ var region = getRegionByName(name, regions);
305
+
306
+ if (region == null) {
307
+ promise.resolve(null);
308
+ Log.w(LOG_TAG, "getPackStatus - Unknown offline region");
309
+ return@getOfflineRegions
310
+ }
311
+
312
+ region.getStatus {
313
+ if (it.isValue) {
314
+ it.value?.let { status ->
315
+ promise.resolve(makeRegionStatus(name!!, status));
316
+ }
317
+ } else {
318
+ promise.reject("getPackStatus error:", expected.error);
319
+ }
320
+ }
321
+ }
322
+ } else {
323
+ promise.reject("getPackStatus error:", expected.error);
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ @ReactMethod
330
+ fun pausePackDownload(name: String?, promise: Promise) {
331
+ UiThreadUtil.runOnUiThread {
332
+ offlineRegionManager.getOfflineRegions { expected ->
333
+ if (expected.isValue) {
334
+ expected.value?.let { regions ->
335
+ var region = getRegionByName(name, regions);
336
+
337
+ if (region == null) {
338
+ promise.resolve(null);
339
+ Log.w(LOG_TAG, "pausePackDownload - Unknown offline region");
340
+ return@getOfflineRegions
341
+ }
342
+
343
+ region.setOfflineRegionDownloadState(OfflineRegionDownloadState.INACTIVE)
344
+ promise.resolve(null)
345
+ }
346
+ } else {
347
+ promise.reject("pausePackDownload error:", expected.error);
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ @ReactMethod
354
+ fun resumePackDownload(name: String?, promise: Promise) {
355
+ UiThreadUtil.runOnUiThread {
356
+ offlineRegionManager.getOfflineRegions { expected ->
357
+ if (expected.isValue) {
358
+ expected.value?.let { regions ->
359
+ var region = getRegionByName(name, regions);
360
+
361
+ if (region == null) {
362
+ promise.resolve(null);
363
+ Log.w(LOG_TAG, "resumeRegionDownload - Unknown offline region");
364
+ return@getOfflineRegions
365
+ }
366
+
367
+ region.setOfflineRegionDownloadState(OfflineRegionDownloadState.ACTIVE)
368
+ promise.resolve(null);
369
+ }
370
+ } else {
371
+ promise.reject("resumeRegionDownload error:", expected.error);
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ @ReactMethod
378
+ fun resetDatabase(promise: Promise) {
379
+ UiThreadUtil.runOnUiThread {
380
+ var purgedCount = 0
381
+ offlineRegionManager.getOfflineRegions { expected ->
382
+ if (expected.isValue) {
383
+ expected.value?.let { regions ->
384
+ if (regions.size == 0) promise.resolve(null)
385
+
386
+ for (region in regions) {
387
+ region.setOfflineRegionDownloadState(OfflineRegionDownloadState.INACTIVE)
388
+
389
+ region.purge { expected ->
390
+ if (expected.isError) {
391
+ promise.reject("resetDatabase error:", expected.error);
392
+ } else {
393
+ purgedCount++
394
+ if (purgedCount == regions.size) {
395
+ Log.d(LOG_TAG, "resetDatabase done: ${regions.size} packs were purged")
396
+ promise.resolve(null)
397
+ }
398
+ }
399
+ }
400
+ }
401
+ }
402
+ } else {
403
+ promise.reject("resetDatabase error:", expected.error);
404
+ }
405
+ }
406
+ }
407
+ }
408
+
409
+ @ReactMethod
410
+ fun migrateOfflineCache(promise: Promise) {
411
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
412
+ // Old and new cache file paths
413
+ val targetDirectoryPathName = mReactContext.filesDir.absolutePath + "/.mapbox/map_data"
414
+ val sourcePathName = mReactContext.filesDir.absolutePath + "/mbgl-offline.db"
415
+ val sourcePath = Paths.get(sourcePathName)
416
+ val targetPath = Paths.get("$targetDirectoryPathName/map_data.db")
417
+
418
+ try {
419
+ val source = File(sourcePath.toString())
420
+
421
+ if (!source.exists()) {
422
+ Log.d(LOG_TAG, "Nothing to migrate")
423
+ promise.resolve(false)
424
+ return
425
+ }
426
+
427
+ val directory = File(targetDirectoryPathName)
428
+
429
+ directory.mkdirs()
430
+ Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING)
431
+ Log.d(LOG_TAG, "v10 cache directory created successfully")
432
+ promise.resolve(true)
433
+ } catch (e: Exception) {
434
+ val mes = "${e}... file move unsuccessful"
435
+ Log.d(LOG_TAG, mes)
436
+ promise.reject(mes)
437
+ }
438
+ } else {
439
+ val mes = "\"migrateOfflineCache only supported on api level 26 or later\""
440
+ Log.w(LOG_TAG, "migrateOfflineCache only supported on api level 26 or later")
441
+ promise.reject(mes)
442
+ }
443
+ }
444
+ }
@@ -21,6 +21,10 @@ fun ViewAnnotationOptions.Builder.height(value: Double): ViewAnnotationOptions.B
21
21
  return this.height(value.toInt())
22
22
  }
23
23
 
24
+ fun com.mapbox.maps.ViewAnnotationOptions.Builder.allowOverlapWithPuck(value: Boolean): ViewAnnotationOptions.Builder {
25
+ return this;
26
+ }
27
+
24
28
  abstract class OnViewAnnotationUpdatedListener : _OnViewAnnotationUpdatedListener {
25
29
  override fun onViewAnnotationPositionUpdated(
26
30
  view: View,
@@ -27,7 +27,6 @@ fun ViewAnnotationOptions.Builder.offsets(x: Double, y: Double) {
27
27
  ))
28
28
  }
29
29
 
30
-
31
30
  abstract class OnViewAnnotationUpdatedListener : _OnViewAnnotationUpdatedListener {
32
31
 
33
32
  }
@@ -31,6 +31,9 @@ public class RNMBXMarkerViewManagerDelegate<T extends View, U extends BaseViewMa
31
31
  case "allowOverlap":
32
32
  mViewManager.setAllowOverlap(view, new DynamicFromObject(value));
33
33
  break;
34
+ case "allowOverlapWithPuck":
35
+ mViewManager.setAllowOverlapWithPuck(view, new DynamicFromObject(value));
36
+ break;
34
37
  case "isSelected":
35
38
  mViewManager.setIsSelected(view, new DynamicFromObject(value));
36
39
  break;
@@ -16,5 +16,6 @@ public interface RNMBXMarkerViewManagerInterface<T extends View> {
16
16
  void setCoordinate(T view, Dynamic value);
17
17
  void setAnchor(T view, Dynamic value);
18
18
  void setAllowOverlap(T view, Dynamic value);
19
+ void setAllowOverlapWithPuck(T view, Dynamic value);
19
20
  void setIsSelected(T view, Dynamic value);
20
21
  }
@@ -60,6 +60,12 @@ public class RNMBXMarkerView: UIView, RNMBXMapComponent {
60
60
  }
61
61
  }
62
62
 
63
+ @objc public var allowOverlapWithPuck: Bool = false {
64
+ didSet {
65
+ update()
66
+ }
67
+ }
68
+
63
69
  @objc public var isSelected: Bool = false {
64
70
  didSet {
65
71
  update()
@@ -227,7 +233,7 @@ public class RNMBXMarkerView: UIView, RNMBXMapComponent {
227
233
  let size = self.bounds.size
228
234
  let offset = calcOffset(size: size)
229
235
 
230
- let options = ViewAnnotationOptions(
236
+ var options = ViewAnnotationOptions(
231
237
  geometry: geometry,
232
238
  width: size.width,
233
239
  height: size.height,
@@ -236,6 +242,9 @@ public class RNMBXMarkerView: UIView, RNMBXMapComponent {
236
242
  offsetY: offset.dy,
237
243
  selected: isSelected
238
244
  )
245
+ #if RNMBX_11
246
+ options.allowOverlapWithPuck = allowOverlapWithPuck
247
+ #endif
239
248
  return options
240
249
  }
241
250
 
@@ -84,6 +84,10 @@ using namespace facebook::react;
84
84
  if (allowOverlap != nil) {
85
85
  _view.allowOverlap = allowOverlap;
86
86
  }
87
+ id allowOverlapWithPuck = RNMBXConvertFollyDynamicToId(newProps.allowOverlapWithPuck);
88
+ if (allowOverlapWithPuck != nil) {
89
+ _view.allowOverlapWithPuck = allowOverlapWithPuck;
90
+ }
87
91
  id isSelected = RNMBXConvertFollyDynamicToId(newProps.isSelected);
88
92
  if (isSelected != nil) {
89
93
  _view.isSelected = isSelected;
@@ -7,6 +7,7 @@
7
7
  RCT_EXPORT_VIEW_PROPERTY(coordinate, NSString)
8
8
  RCT_EXPORT_VIEW_PROPERTY(anchor, NSDictionary)
9
9
  RCT_EXPORT_VIEW_PROPERTY(allowOverlap, BOOL)
10
+ RCT_EXPORT_VIEW_PROPERTY(allowOverlapWithPuck, BOOL)
10
11
  RCT_EXPORT_VIEW_PROPERTY(isSelected, BOOL)
11
12
 
12
13
  @end
@@ -31,4 +31,4 @@ RCT_EXTERN_METHOD(migrateOfflineCache:(RCTPromiseResolveBlock)resolve reject:(RC
31
31
 
32
32
  RCT_EXTERN_METHOD(resetDatabase:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
33
33
 
34
- @end
34
+ @end