react-native-google-maps-plus 1.0.3-dev.1 → 1.1.0-dev.1

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 (82) hide show
  1. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +122 -29
  2. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +44 -44
  3. package/android/src/main/java/com/rngooglemapsplus/{MapCircle.kt → MapCircleBuilder.kt} +2 -12
  4. package/android/src/main/java/com/rngooglemapsplus/{MapMarker.kt → MapMarkerBuilder.kt} +1 -1
  5. package/android/src/main/java/com/rngooglemapsplus/{MapPolygon.kt → MapPolygonBuilder.kt} +2 -18
  6. package/android/src/main/java/com/rngooglemapsplus/{MapPolyline.kt → MapPolylineBuilder.kt.kt} +2 -19
  7. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +43 -54
  8. package/android/src/main/java/com/rngooglemapsplus/extensions/RNCameraExtension.kt +19 -0
  9. package/android/src/main/java/com/rngooglemapsplus/extensions/RNLocationPriorityExtension.kt +12 -0
  10. package/android/src/main/java/com/rngooglemapsplus/extensions/RNMapCircleExtension.kt +14 -0
  11. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolygonExtension.kt +20 -0
  12. package/android/src/main/java/com/rngooglemapsplus/extensions/RNPolylineExtension.kt +21 -0
  13. package/android/src/main/java/com/rngooglemapsplus/extensions/RNUserInterfaceExtension.kt +12 -0
  14. package/android/src/main/java/com/rngooglemapsplus/{Color.kt → extensions/StringExtension.kt} +1 -1
  15. package/android/src/main/java/com/rngooglemapsplus/extensions/ThrowableExtension.kt +38 -0
  16. package/ios/GoogleMapViewImpl.swift +165 -22
  17. package/ios/LocationHandler.swift +29 -69
  18. package/ios/MapCircleBuilder.swift +20 -0
  19. package/ios/{MapMarker.swift → MapMarkerBuilder.swift} +1 -25
  20. package/ios/MapPolygonBuilder.swift +20 -0
  21. package/ios/MapPolylineBuilder.swift +24 -0
  22. package/ios/RNGoogleMapsPlusView.swift +63 -115
  23. package/ios/extensions/RNCamera+Extension.swift +22 -0
  24. package/ios/{MapCircle.swift → extensions/RNCircle+Extension.swift} +0 -19
  25. package/ios/extensions/RNIOSLocationAccuracy+Extensions.swift +19 -0
  26. package/ios/extensions/RNMarker+Extension.swift +24 -0
  27. package/ios/{MapPolygon.swift → extensions/RNPolygon+Extension.swift.swift} +0 -19
  28. package/ios/{MapPolyline.swift → extensions/RNPolyline+Extension.swift.swift} +16 -39
  29. package/ios/extensions/RNUserInterface+Extension.swift +16 -0
  30. package/lib/module/types.js +14 -0
  31. package/lib/module/types.js.map +1 -1
  32. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +5 -1
  33. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -1
  34. package/lib/typescript/src/types.d.ts +39 -1
  35. package/lib/typescript/src/types.d.ts.map +1 -1
  36. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +60 -0
  37. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +8 -0
  38. package/nitrogen/generated/android/c++/JRNAndroidLocationConfig.hpp +63 -0
  39. package/nitrogen/generated/android/c++/JRNAndroidLocationPriority.hpp +65 -0
  40. package/nitrogen/generated/android/c++/JRNIOSLocationAccuracy.hpp +65 -0
  41. package/nitrogen/generated/android/c++/JRNIOSLocationConfig.hpp +59 -0
  42. package/nitrogen/generated/android/c++/JRNInitialProps.hpp +4 -4
  43. package/nitrogen/generated/android/c++/JRNLocationConfig.hpp +65 -0
  44. package/nitrogen/generated/android/c++/JRNMapUiSettings.hpp +93 -0
  45. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +16 -0
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +24 -0
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationConfig.kt +35 -0
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationPriority.kt +23 -0
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationAccuracy.kt +23 -0
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSLocationConfig.kt +32 -0
  51. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +1 -1
  52. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationConfig.kt +32 -0
  53. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapUiSettings.kt +59 -0
  54. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +108 -0
  55. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +18 -0
  56. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +46 -0
  57. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +20 -0
  58. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +4 -0
  59. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +82 -0
  60. package/nitrogen/generated/ios/swift/RNAndroidLocationConfig.swift +93 -0
  61. package/nitrogen/generated/ios/swift/RNAndroidLocationPriority.swift +48 -0
  62. package/nitrogen/generated/ios/swift/RNIOSLocationAccuracy.swift +48 -0
  63. package/nitrogen/generated/ios/swift/RNIOSLocationConfig.swift +70 -0
  64. package/nitrogen/generated/ios/swift/RNInitialProps.swift +6 -6
  65. package/nitrogen/generated/ios/swift/RNLocationConfig.swift +84 -0
  66. package/nitrogen/generated/ios/swift/RNMapUiSettings.swift +277 -0
  67. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +8 -0
  68. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +14 -0
  69. package/nitrogen/generated/shared/c++/RNAndroidLocationConfig.hpp +77 -0
  70. package/nitrogen/generated/shared/c++/RNAndroidLocationPriority.hpp +64 -0
  71. package/nitrogen/generated/shared/c++/RNIOSLocationAccuracy.hpp +64 -0
  72. package/nitrogen/generated/shared/c++/RNIOSLocationConfig.hpp +73 -0
  73. package/nitrogen/generated/shared/c++/RNInitialProps.hpp +5 -5
  74. package/nitrogen/generated/shared/c++/RNLocationConfig.hpp +76 -0
  75. package/nitrogen/generated/shared/c++/RNMapUiSettings.hpp +107 -0
  76. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +48 -0
  77. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +6 -0
  78. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +4 -0
  79. package/package.json +1 -1
  80. package/src/RNGoogleMapsPlusView.nitro.ts +6 -0
  81. package/src/types.ts +44 -1
  82. /package/ios/{Color.swift → extensions/String+Extensions.swift} +0 -0
@@ -1,5 +1,6 @@
1
1
  package com.rngooglemapsplus
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.location.Location
4
5
  import android.widget.FrameLayout
5
6
  import com.facebook.react.bridge.LifecycleEventListener
@@ -24,12 +25,14 @@ import com.google.android.gms.maps.model.Polygon
24
25
  import com.google.android.gms.maps.model.PolygonOptions
25
26
  import com.google.android.gms.maps.model.Polyline
26
27
  import com.google.android.gms.maps.model.PolylineOptions
28
+ import com.rngooglemapsplus.extensions.toGooglePriority
29
+ import com.rngooglemapsplus.extensions.toLocationErrorCode
27
30
 
28
31
  class GoogleMapsViewImpl(
29
32
  val reactContext: ThemedReactContext,
30
33
  val locationHandler: LocationHandler,
31
34
  val playServiceHandler: PlayServicesHandler,
32
- val markerOptions: com.rngooglemapsplus.MarkerOptions,
35
+ val markerBuilder: MarkerBuilder,
33
36
  ) : FrameLayout(reactContext),
34
37
  GoogleMap.OnCameraMoveStartedListener,
35
38
  GoogleMap.OnCameraMoveListener,
@@ -252,12 +255,37 @@ class GoogleMapsViewImpl(
252
255
  it.bottom.dpToPx().toInt(),
253
256
  )
254
257
  }
258
+
259
+ uiSettings?.let { v ->
260
+ googleMap?.uiSettings?.apply {
261
+ v.allGesturesEnabled?.let { setAllGesturesEnabled(it) }
262
+ v.compassEnabled?.let { isCompassEnabled = it }
263
+ v.indoorLevelPickerEnabled?.let { isIndoorLevelPickerEnabled = it }
264
+ v.mapToolbarEnabled?.let { isMapToolbarEnabled = it }
265
+ v.myLocationButtonEnabled?.let {
266
+ googleMap?.setLocationSource(locationHandler)
267
+ isMyLocationButtonEnabled = it
268
+ }
269
+ v.rotateEnabled?.let { isRotateGesturesEnabled = it }
270
+ v.scrollEnabled?.let { isScrollGesturesEnabled = it }
271
+ v.scrollDuringRotateOrZoomEnabled?.let {
272
+ isScrollGesturesEnabledDuringRotateOrZoom = it
273
+ }
274
+ v.tiltEnabled?.let { isTiltGesturesEnabled = it }
275
+ v.zoomControlsEnabled?.let { isZoomControlsEnabled = it }
276
+ v.zoomGesturesEnabled?.let { isZoomGesturesEnabled = it }
277
+ }
278
+ }
279
+
255
280
  buildingEnabled?.let {
256
281
  googleMap?.isBuildingsEnabled = it
257
282
  }
258
283
  trafficEnabled?.let {
259
284
  googleMap?.isTrafficEnabled = it
260
285
  }
286
+ indoorEnabled?.let {
287
+ googleMap?.isIndoorEnabled = it
288
+ }
261
289
  googleMap?.setMapStyle(customMapStyle)
262
290
  mapType?.let {
263
291
  googleMap?.mapType = it
@@ -273,6 +301,12 @@ class GoogleMapsViewImpl(
273
301
  }
274
302
  }
275
303
 
304
+ locationConfig?.let {
305
+ locationHandler.priority = it.android?.priority?.toGooglePriority()
306
+ locationHandler.interval = it.android?.interval?.toLong()
307
+ locationHandler.minUpdateInterval = it.android?.minUpdateInterval?.toLong()
308
+ }
309
+
276
310
  if (pendingMarkers.isNotEmpty()) {
277
311
  pendingMarkers.forEach { (id, opts) ->
278
312
  internalAddMarker(id, opts)
@@ -302,6 +336,69 @@ class GoogleMapsViewImpl(
302
336
  }
303
337
  }
304
338
 
339
+ var uiSettings: RNMapUiSettings? = null
340
+ set(value) {
341
+ field = value
342
+ onUi {
343
+ value?.let { v ->
344
+ googleMap?.uiSettings?.apply {
345
+ v.allGesturesEnabled?.let { setAllGesturesEnabled(it) }
346
+ v.compassEnabled?.let { isCompassEnabled = it }
347
+ v.indoorLevelPickerEnabled?.let { isIndoorLevelPickerEnabled = it }
348
+ v.mapToolbarEnabled?.let { isMapToolbarEnabled = it }
349
+ v.myLocationButtonEnabled?.let {
350
+ googleMap?.setLocationSource(locationHandler)
351
+ isMyLocationButtonEnabled = it
352
+ }
353
+ v.rotateEnabled?.let { isRotateGesturesEnabled = it }
354
+ v.scrollEnabled?.let { isScrollGesturesEnabled = it }
355
+ v.scrollDuringRotateOrZoomEnabled?.let {
356
+ isScrollGesturesEnabledDuringRotateOrZoom = it
357
+ }
358
+ v.tiltEnabled?.let { isTiltGesturesEnabled = it }
359
+ v.zoomControlsEnabled?.let { isZoomControlsEnabled = it }
360
+ v.zoomGesturesEnabled?.let { isZoomGesturesEnabled = it }
361
+ }
362
+ }
363
+ ?: run {
364
+ googleMap?.uiSettings?.apply {
365
+ setAllGesturesEnabled(true)
366
+ isCompassEnabled = false
367
+ isIndoorLevelPickerEnabled = false
368
+ isMapToolbarEnabled = false
369
+ isMyLocationButtonEnabled = false
370
+ googleMap?.setLocationSource(null)
371
+ isRotateGesturesEnabled = true
372
+ isScrollGesturesEnabled = true
373
+ isScrollGesturesEnabledDuringRotateOrZoom = true
374
+ isTiltGesturesEnabled = true
375
+ isZoomControlsEnabled = false
376
+ isZoomGesturesEnabled = false
377
+ }
378
+ }
379
+ }
380
+ }
381
+
382
+ @SuppressLint("MissingPermission")
383
+ var myLocationEnabled: Boolean? = null
384
+ set(value) {
385
+ onUi {
386
+ try {
387
+ value?.let {
388
+ googleMap?.isMyLocationEnabled = it
389
+ }
390
+ ?: run {
391
+ googleMap?.isMyLocationEnabled = false
392
+ }
393
+ } catch (se: SecurityException) {
394
+ onLocationError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
395
+ } catch (ex: Exception) {
396
+ val error = ex.toLocationErrorCode(context)
397
+ onLocationError?.invoke(error)
398
+ }
399
+ }
400
+ }
401
+
305
402
  var buildingEnabled: Boolean? = null
306
403
  set(value) {
307
404
  field = value
@@ -327,6 +424,19 @@ class GoogleMapsViewImpl(
327
424
  }
328
425
  }
329
426
 
427
+ var indoorEnabled: Boolean? = null
428
+ set(value) {
429
+ field = value
430
+ onUi {
431
+ value?.let {
432
+ googleMap?.isIndoorEnabled = it
433
+ }
434
+ ?: run {
435
+ googleMap?.isIndoorEnabled = false
436
+ }
437
+ }
438
+ }
439
+
330
440
  var customMapStyle: MapStyleOptions? = null
331
441
  set(value) {
332
442
  field = value
@@ -400,6 +510,14 @@ class GoogleMapsViewImpl(
400
510
  }
401
511
  }
402
512
 
513
+ var locationConfig: RNLocationConfig? = null
514
+ set(value) {
515
+ field = value
516
+ locationHandler.priority = value?.android?.priority?.toGooglePriority()
517
+ locationHandler.interval = value?.android?.interval?.toLong()
518
+ locationHandler.minUpdateInterval = value?.android?.minUpdateInterval?.toLong()
519
+ }
520
+
403
521
  var onMapError: ((RNMapErrorCode) -> Unit)? = null
404
522
  var onMapReady: ((Boolean) -> Unit)? = null
405
523
  var onLocationUpdate: ((RNLocation) -> Unit)? = null
@@ -414,7 +532,7 @@ class GoogleMapsViewImpl(
414
532
  var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
415
533
 
416
534
  fun setCamera(
417
- camera: RNCamera,
535
+ cameraPosition: CameraPosition,
418
536
  animated: Boolean,
419
537
  durationMS: Int,
420
538
  ) {
@@ -423,33 +541,8 @@ class GoogleMapsViewImpl(
423
541
  if (current == null) {
424
542
  return@onUi
425
543
  }
426
- val camPosBuilder =
427
- CameraPosition.Builder(
428
- current,
429
- )
430
-
431
- camera.center?.let {
432
- camPosBuilder.target(
433
- LatLng(
434
- it.latitude,
435
- it.longitude,
436
- ),
437
- )
438
- }
439
-
440
- camera.zoom?.let {
441
- camPosBuilder.zoom(it.toFloat())
442
- }
443
- camera.bearing?.let {
444
- camPosBuilder.bearing(it.toFloat())
445
- }
446
- camera.tilt?.let {
447
- camPosBuilder.tilt(it.toFloat())
448
- }
449
-
450
- val camPos = camPosBuilder.build()
451
544
 
452
- val update = CameraUpdateFactory.newCameraPosition(camPos)
545
+ val update = CameraUpdateFactory.newCameraPosition(cameraPosition)
453
546
 
454
547
  if (animated) {
455
548
  googleMap?.animateCamera(update, durationMS, null)
@@ -746,7 +839,7 @@ class GoogleMapsViewImpl(
746
839
 
747
840
  fun destroyInternal() {
748
841
  onUi {
749
- markerOptions.cancelAllJobs()
842
+ markerBuilder.cancelAllJobs()
750
843
  clearMarkers()
751
844
  clearPolylines()
752
845
  clearPolygons()
@@ -10,8 +10,6 @@ import com.facebook.react.bridge.ReactContext
10
10
  import com.facebook.react.bridge.UiThreadUtil
11
11
  import com.google.android.gms.common.ConnectionResult
12
12
  import com.google.android.gms.common.GoogleApiAvailability
13
- import com.google.android.gms.common.api.ApiException
14
- import com.google.android.gms.common.api.CommonStatusCodes
15
13
  import com.google.android.gms.common.api.ResolvableApiException
16
14
  import com.google.android.gms.location.FusedLocationProviderClient
17
15
  import com.google.android.gms.location.LocationCallback
@@ -19,22 +17,43 @@ import com.google.android.gms.location.LocationRequest
19
17
  import com.google.android.gms.location.LocationResult
20
18
  import com.google.android.gms.location.LocationServices
21
19
  import com.google.android.gms.location.LocationSettingsRequest
22
- import com.google.android.gms.location.LocationSettingsStatusCodes
23
20
  import com.google.android.gms.location.Priority
21
+ import com.google.android.gms.maps.LocationSource
24
22
  import com.google.android.gms.tasks.OnSuccessListener
23
+ import com.rngooglemapsplus.extensions.toLocationErrorCode
25
24
 
26
25
  private const val REQ_LOCATION_SETTINGS = 2001
26
+ private const val PRIORITY_DEFAULT = Priority.PRIORITY_BALANCED_POWER_ACCURACY
27
+ private const val INTERVAL_DEFAULT = 600000L
28
+ private const val MIN_UPDATE_INTERVAL = 3600000L
27
29
 
28
30
  class LocationHandler(
29
31
  val context: ReactContext,
30
- ) {
32
+ ) : LocationSource {
31
33
  private val fusedLocationClientProviderClient: FusedLocationProviderClient =
32
34
  LocationServices.getFusedLocationProviderClient(context)
35
+ private var listener: LocationSource.OnLocationChangedListener? = null
33
36
  private var locationRequest: LocationRequest? = null
34
37
  private var locationCallback: LocationCallback? = null
35
- private var priority = Priority.PRIORITY_HIGH_ACCURACY
36
- private var interval: Long = 5000
37
- private var minUpdateInterval: Long = 5000
38
+
39
+ var priority: Int? = PRIORITY_DEFAULT
40
+ set(value) {
41
+ field = value
42
+ start()
43
+ }
44
+
45
+ var interval: Long? = INTERVAL_DEFAULT
46
+ set(value) {
47
+ field = value
48
+ buildLocationRequest()
49
+ }
50
+
51
+ var minUpdateInterval: Long? = MIN_UPDATE_INTERVAL
52
+ set(value) {
53
+ field = value
54
+ buildLocationRequest()
55
+ }
56
+
38
57
  var onUpdate: ((Location) -> Unit)? = null
39
58
  var onError: ((RNLocationErrorCode) -> Unit)? = null
40
59
 
@@ -90,6 +109,10 @@ class LocationHandler(
90
109
 
91
110
  @Suppress("deprecation")
92
111
  private fun buildLocationRequest() {
112
+ val priority = priority ?: Priority.PRIORITY_BALANCED_POWER_ACCURACY
113
+ val interval = interval ?: INTERVAL_DEFAULT
114
+ val minUpdateInterval = minUpdateInterval ?: MIN_UPDATE_INTERVAL
115
+
93
116
  locationRequest =
94
117
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
95
118
  LocationRequest
@@ -106,21 +129,6 @@ class LocationHandler(
106
129
  restartLocationUpdates()
107
130
  }
108
131
 
109
- fun setPriority(priority: Int) {
110
- this.priority = priority
111
- buildLocationRequest()
112
- }
113
-
114
- fun setInterval(interval: Int) {
115
- this.interval = interval.toLong()
116
- buildLocationRequest()
117
- }
118
-
119
- fun setFastestInterval(fastestInterval: Int) {
120
- this.minUpdateInterval = fastestInterval.toLong()
121
- buildLocationRequest()
122
- }
123
-
124
132
  private fun restartLocationUpdates() {
125
133
  stop()
126
134
  // 4) Google Play Services checken – früh zurückmelden
@@ -146,7 +154,7 @@ class LocationHandler(
146
154
  }
147
155
  },
148
156
  ).addOnFailureListener { e ->
149
- val error = mapThrowableToCode(e)
157
+ val error = e.toLocationErrorCode(context)
150
158
  onError?.invoke(error)
151
159
  }
152
160
  locationCallback =
@@ -154,6 +162,7 @@ class LocationHandler(
154
162
  override fun onLocationResult(locationResult: LocationResult) {
155
163
  val location = locationResult.lastLocation
156
164
  if (location != null) {
165
+ listener?.onLocationChanged(location)
157
166
  onUpdate?.invoke(location)
158
167
  } else {
159
168
  onError?.invoke(RNLocationErrorCode.POSITION_UNAVAILABLE)
@@ -166,40 +175,31 @@ class LocationHandler(
166
175
  locationCallback!!,
167
176
  Looper.getMainLooper(),
168
177
  ).addOnFailureListener { e ->
169
- val error = mapThrowableToCode(e)
178
+ val error = e.toLocationErrorCode(context)
170
179
  onError?.invoke(error)
171
180
  }
172
181
  } catch (se: SecurityException) {
173
182
  onError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
174
183
  } catch (ex: Exception) {
175
- val error = mapThrowableToCode(ex)
184
+ val error = ex.toLocationErrorCode(context)
176
185
  onError?.invoke(error)
177
186
  }
178
187
  }
179
188
 
180
- private fun mapThrowableToCode(t: Throwable): RNLocationErrorCode {
181
- if (t is SecurityException) return RNLocationErrorCode.PERMISSION_DENIED
182
- if (t.message?.contains("GoogleApi", ignoreCase = true) == true) {
183
- val gms = GoogleApiAvailability.getInstance()
184
- val status = gms.isGooglePlayServicesAvailable(context)
185
- if (status != ConnectionResult.SUCCESS) return RNLocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE
186
- }
187
- if (t is ApiException) {
188
- when (t.statusCode) {
189
- CommonStatusCodes.NETWORK_ERROR -> return RNLocationErrorCode.POSITION_UNAVAILABLE
190
- LocationSettingsStatusCodes.RESOLUTION_REQUIRED,
191
- LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE,
192
- -> return RNLocationErrorCode.SETTINGS_NOT_SATISFIED
193
- }
194
- return RNLocationErrorCode.INTERNAL_ERROR
195
- }
196
- return RNLocationErrorCode.INTERNAL_ERROR
197
- }
198
-
199
189
  fun stop() {
190
+ listener = null
200
191
  if (locationCallback != null) {
201
192
  fusedLocationClientProviderClient.removeLocationUpdates(locationCallback!!)
202
193
  locationCallback = null
203
194
  }
204
195
  }
196
+
197
+ override fun activate(listener: LocationSource.OnLocationChangedListener) {
198
+ this.listener = listener
199
+ start()
200
+ }
201
+
202
+ override fun deactivate() {
203
+ stop()
204
+ }
205
205
  }
@@ -3,8 +3,9 @@ package com.rngooglemapsplus
3
3
  import com.facebook.react.uimanager.PixelUtil.dpToPx
4
4
  import com.google.android.gms.maps.model.CircleOptions
5
5
  import com.google.android.gms.maps.model.LatLng
6
+ import com.rngooglemapsplus.extensions.toColor
6
7
 
7
- class MapCircleOptions {
8
+ class MapCircleBuilder {
8
9
  fun buildCircleOptions(circle: RNCircle): CircleOptions =
9
10
  CircleOptions().apply {
10
11
  center(LatLng(circle.center.latitude, circle.center.longitude))
@@ -16,14 +17,3 @@ class MapCircleOptions {
16
17
  circle.zIndex?.let { zIndex(it.toFloat()) }
17
18
  }
18
19
  }
19
-
20
- fun RNCircle.circleEquals(b: RNCircle): Boolean {
21
- if (zIndex != b.zIndex) return false
22
- if (pressable != b.pressable) return false
23
- if (center != b.center) return false
24
- if (radius != b.radius) return false
25
- if (strokeWidth != b.strokeWidth) return false
26
- if (strokeColor != b.strokeColor) return false
27
- if (fillColor != b.fillColor) return false
28
- return true
29
- }
@@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
19
19
  import kotlinx.coroutines.withContext
20
20
  import kotlin.coroutines.coroutineContext
21
21
 
22
- class MarkerOptions(
22
+ class MarkerBuilder(
23
23
  private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default),
24
24
  ) {
25
25
  private val iconCache =
@@ -2,8 +2,9 @@ package com.rngooglemapsplus
2
2
 
3
3
  import com.facebook.react.uimanager.PixelUtil.dpToPx
4
4
  import com.google.android.gms.maps.model.PolygonOptions
5
+ import com.rngooglemapsplus.extensions.toColor
5
6
 
6
- class MapPolygonOptions {
7
+ class MapPolygonBuilder {
7
8
  fun buildPolygonOptions(poly: RNPolygon): PolygonOptions =
8
9
  PolygonOptions().apply {
9
10
  poly.coordinates.forEach { pt ->
@@ -19,20 +20,3 @@ class MapPolygonOptions {
19
20
  poly.zIndex?.let { zIndex(it.toFloat()) }
20
21
  }
21
22
  }
22
-
23
- fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
24
- if (zIndex != b.zIndex) return false
25
- if (pressable != b.pressable) return false
26
- if (strokeWidth != b.strokeWidth) return false
27
- if (fillColor != b.fillColor) return false
28
- if (strokeColor != b.strokeColor) return false
29
- val ac = coordinates
30
- val bc = b.coordinates
31
- if (ac.size != bc.size) return false
32
- for (i in ac.indices) {
33
- val p = ac[i]
34
- val q = bc[i]
35
- if (p.latitude != q.latitude || p.longitude != q.longitude) return false
36
- }
37
- return true
38
- }
@@ -7,8 +7,9 @@ import com.google.android.gms.maps.model.JointType
7
7
  import com.google.android.gms.maps.model.PolylineOptions
8
8
  import com.google.android.gms.maps.model.RoundCap
9
9
  import com.google.android.gms.maps.model.SquareCap
10
+ import com.rngooglemapsplus.extensions.toColor
10
11
 
11
- class MapPolylineOptions {
12
+ class MapPolylineBuilder {
12
13
  fun buildPolylineOptions(pl: RNPolyline): PolylineOptions =
13
14
  PolylineOptions().apply {
14
15
  pl.coordinates.forEach { pt ->
@@ -41,21 +42,3 @@ class MapPolylineOptions {
41
42
  null -> JointType.DEFAULT
42
43
  }
43
44
  }
44
-
45
- fun RNPolyline.polylineEquals(b: RNPolyline): Boolean {
46
- if (zIndex != b.zIndex) return false
47
- if (pressable != b.pressable) return false
48
- if ((width ?: 0.0) != (b.width ?: 0.0)) return false
49
- if (lineCap != b.lineCap) return false
50
- if (lineJoin != b.lineJoin) return false
51
- if (color != b.color) return false
52
- val ac = coordinates
53
- val bc = b.coordinates
54
- if (ac.size != bc.size) return false
55
- for (i in ac.indices) {
56
- val p = ac[i]
57
- val q = bc[i]
58
- if (p.latitude != q.latitude || p.longitude != q.longitude) return false
59
- }
60
- return true
61
- }
@@ -4,11 +4,15 @@ import com.facebook.proguard.annotations.DoNotStrip
4
4
  import com.facebook.react.bridge.UiThreadUtil
5
5
  import com.facebook.react.uimanager.PixelUtil.dpToPx
6
6
  import com.facebook.react.uimanager.ThemedReactContext
7
- import com.google.android.gms.maps.model.CameraPosition
8
7
  import com.google.android.gms.maps.model.LatLng
9
- import com.google.android.gms.maps.model.MapColorScheme
10
8
  import com.google.android.gms.maps.model.MapStyleOptions
11
9
  import com.margelo.nitro.core.Promise
10
+ import com.rngooglemapsplus.extensions.circleEquals
11
+ import com.rngooglemapsplus.extensions.polygonEquals
12
+ import com.rngooglemapsplus.extensions.polylineEquals
13
+ import com.rngooglemapsplus.extensions.toCameraPosition
14
+ import com.rngooglemapsplus.extensions.toColor
15
+ import com.rngooglemapsplus.extensions.toMapColorScheme
12
16
 
13
17
  @DoNotStrip
14
18
  class RNGoogleMapsPlusView(
@@ -19,23 +23,33 @@ class RNGoogleMapsPlusView(
19
23
  private var locationHandler = LocationHandler(context)
20
24
  private var playServiceHandler = PlayServicesHandler(context)
21
25
 
22
- private val markerOptions = MarkerOptions()
23
- private val polylineOptions = MapPolylineOptions()
24
- private val polygonOptions = MapPolygonOptions()
25
- private val circleOptions = MapCircleOptions()
26
+ private val markerBuilder = MarkerBuilder()
27
+ private val polylineBuilder = MapPolylineBuilder()
28
+ private val polygonBuilder = MapPolygonBuilder()
29
+ private val circleBuilder = MapCircleBuilder()
26
30
 
27
31
  override val view =
28
- GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerOptions)
32
+ GoogleMapsViewImpl(context, locationHandler, playServiceHandler, markerBuilder)
29
33
 
30
34
  override var initialProps: RNInitialProps? = null
31
35
  set(value) {
32
36
  view.initMapView(
33
37
  value?.mapId,
34
38
  value?.liteMode,
35
- mapCameraToCameraPosition(value?.initialCamera),
39
+ value?.camera?.toCameraPosition(),
36
40
  )
37
41
  }
38
42
 
43
+ override var uiSettings: RNMapUiSettings? = null
44
+ set(value) {
45
+ view.uiSettings = value
46
+ }
47
+
48
+ override var myLocationEnabled: Boolean? = null
49
+ set(value) {
50
+ view.myLocationEnabled = value
51
+ }
52
+
39
53
  override var buildingEnabled: Boolean? = null
40
54
  set(value) {
41
55
  view.buildingEnabled = value
@@ -46,6 +60,11 @@ class RNGoogleMapsPlusView(
46
60
  view.trafficEnabled = value
47
61
  }
48
62
 
63
+ override var indoorEnabled: Boolean? = null
64
+ set(value) {
65
+ view.indoorEnabled = value
66
+ }
67
+
49
68
  override var customMapStyle: String? = null
50
69
  set(value) {
51
70
  currentCustomMapStyle = value
@@ -56,7 +75,7 @@ class RNGoogleMapsPlusView(
56
75
 
57
76
  override var userInterfaceStyle: RNUserInterfaceStyle? = null
58
77
  set(value) {
59
- view.userInterfaceStyle = userInterfaceStyleToMapColorScheme(value)
78
+ view.userInterfaceStyle = value.toMapColorScheme()
60
79
  }
61
80
 
62
81
  override var minZoomLevel: Double? = null
@@ -87,17 +106,17 @@ class RNGoogleMapsPlusView(
87
106
  val nextById = value?.associateBy { it.id } ?: emptyMap()
88
107
 
89
108
  (prevById.keys - nextById.keys).forEach { id ->
90
- markerOptions.cancelIconJob(id)
109
+ markerBuilder.cancelIconJob(id)
91
110
  view.removeMarker(id)
92
111
  }
93
112
 
94
113
  nextById.forEach { (id, next) ->
95
114
  val prev = prevById[id]
96
115
  if (prev == null) {
97
- markerOptions.buildIconAsync(id, next) { icon ->
116
+ markerBuilder.buildIconAsync(id, next) { icon ->
98
117
  view.addMarker(
99
118
  id,
100
- markerOptions.build(next, icon),
119
+ markerBuilder.build(next, icon),
101
120
  )
102
121
  }
103
122
  } else if (!prev.markerEquals(next)) {
@@ -113,7 +132,7 @@ class RNGoogleMapsPlusView(
113
132
  }
114
133
 
115
134
  if (!prev.markerStyleEquals(next)) {
116
- markerOptions.buildIconAsync(id, next) { icon ->
135
+ markerBuilder.buildIconAsync(id, next) { icon ->
117
136
  m.setIcon(icon)
118
137
  }
119
138
  }
@@ -140,7 +159,7 @@ class RNGoogleMapsPlusView(
140
159
  nextById.forEach { (id, next) ->
141
160
  val prev = prevById[id]
142
161
  if (prev == null) {
143
- view.addPolyline(id, polylineOptions.buildPolylineOptions(next))
162
+ view.addPolyline(id, polylineBuilder.buildPolylineOptions(next))
144
163
  } else if (!prev.polylineEquals(next)) {
145
164
  view.updatePolyline(id) { gms ->
146
165
  onUi {
@@ -151,11 +170,11 @@ class RNGoogleMapsPlusView(
151
170
  }
152
171
  next.width?.let { gms.width = it.dpToPx() }
153
172
  next.lineCap?.let {
154
- val cap = polylineOptions.mapLineCap(it)
173
+ val cap = polylineBuilder.mapLineCap(it)
155
174
  gms.startCap = cap
156
175
  gms.endCap = cap
157
176
  }
158
- next.lineJoin?.let { gms.jointType = polylineOptions.mapLineJoin(it) }
177
+ next.lineJoin?.let { gms.jointType = polylineBuilder.mapLineJoin(it) }
159
178
  next.color?.let { gms.color = it.toColor() }
160
179
  next.zIndex?.let { gms.zIndex = it.toFloat() }
161
180
  }
@@ -177,7 +196,7 @@ class RNGoogleMapsPlusView(
177
196
  nextById.forEach { (id, next) ->
178
197
  val prev = prevById[id]
179
198
  if (prev == null) {
180
- view.addPolygon(id, polygonOptions.buildPolygonOptions(next))
199
+ view.addPolygon(id, polygonBuilder.buildPolygonOptions(next))
181
200
  } else if (!prev.polygonEquals(next)) {
182
201
  view.updatePolygon(id) { gmsPoly ->
183
202
  onUi {
@@ -209,7 +228,7 @@ class RNGoogleMapsPlusView(
209
228
  nextById.forEach { (id, next) ->
210
229
  val prev = prevById[id]
211
230
  if (prev == null) {
212
- view.addCircle(id, circleOptions.buildCircleOptions(next))
231
+ view.addCircle(id, circleBuilder.buildCircleOptions(next))
213
232
  } else if (!prev.circleEquals(next)) {
214
233
  view.updateCircle(id) { gmsCircle ->
215
234
  onUi {
@@ -226,6 +245,11 @@ class RNGoogleMapsPlusView(
226
245
  field = value
227
246
  }
228
247
 
248
+ override var locationConfig: RNLocationConfig? = null
249
+ set(value) {
250
+ view.locationConfig = value
251
+ }
252
+
229
253
  override var onMapError: ((RNMapErrorCode) -> Unit)? = null
230
254
  set(cb) {
231
255
  view.onMapError = cb
@@ -290,7 +314,7 @@ class RNGoogleMapsPlusView(
290
314
  animated: Boolean?,
291
315
  durationMS: Double?,
292
316
  ) {
293
- view.setCamera(camera, animated == true, durationMS?.toInt() ?: 3000)
317
+ view.setCamera(camera.toCameraPosition(), animated == true, durationMS?.toInt() ?: 3000)
294
318
  }
295
319
 
296
320
  override fun setCameraToCoordinates(
@@ -318,41 +342,6 @@ class RNGoogleMapsPlusView(
318
342
  override fun requestLocationPermission(): Promise<RNLocationPermissionResult> = permissionHandler.requestLocationPermission()
319
343
 
320
344
  override fun isGooglePlayServicesAvailable(): Boolean = playServiceHandler.isPlayServicesAvailable()
321
-
322
- fun userInterfaceStyleToMapColorScheme(value: RNUserInterfaceStyle?): Int? {
323
- value ?: return null
324
- return when (value) {
325
- RNUserInterfaceStyle.LIGHT -> {
326
- MapColorScheme.LIGHT
327
- }
328
-
329
- RNUserInterfaceStyle.DARK -> {
330
- MapColorScheme.DARK
331
- }
332
-
333
- RNUserInterfaceStyle.DEFAULT -> {
334
- MapColorScheme.FOLLOW_SYSTEM
335
- }
336
- }
337
- }
338
-
339
- fun mapCameraToCameraPosition(camera: RNCamera?): CameraPosition? {
340
- camera ?: return null
341
- val builder = CameraPosition.builder()
342
- camera.center?.let {
343
- builder.target(
344
- com.google.android.gms.maps.model.LatLng(
345
- camera.center.latitude,
346
- camera.center.longitude,
347
- ),
348
- )
349
- }
350
- camera.zoom?.let { builder.zoom(it.toFloat()) }
351
- camera.bearing?.let { builder.bearing(it.toFloat()) }
352
- camera.tilt?.let { builder.tilt(it.toFloat()) }
353
-
354
- return builder.build()
355
- }
356
345
  }
357
346
 
358
347
  private inline fun onUi(crossinline block: () -> Unit) {