@lugg/maps 0.2.0-alpha.21 → 0.2.0-alpha.23

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 (45) hide show
  1. package/README.md +5 -0
  2. package/android/src/main/java/com/luggmaps/LuggMapView.kt +201 -0
  3. package/android/src/main/java/com/luggmaps/{LuggGoogleMapViewManager.kt → LuggMapViewManager.kt} +39 -29
  4. package/android/src/main/java/com/luggmaps/LuggPackage.kt +1 -4
  5. package/android/src/main/java/com/luggmaps/{LuggGoogleMapView.kt → core/GoogleMapProvider.kt} +174 -189
  6. package/android/src/main/java/com/luggmaps/core/MapProviderDelegate.kt +51 -0
  7. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +28 -24
  8. package/ios/LuggMapView.h +9 -0
  9. package/ios/LuggMapView.mm +303 -0
  10. package/ios/core/AppleMapProvider.h +15 -0
  11. package/ios/{LuggAppleMapView.mm → core/AppleMapProvider.mm} +317 -410
  12. package/ios/core/GMSPolylineAnimator.m +16 -4
  13. package/ios/core/GoogleMapProvider.h +13 -0
  14. package/ios/{LuggGoogleMapView.mm → core/GoogleMapProvider.mm} +179 -218
  15. package/ios/core/MapProviderDelegate.h +68 -0
  16. package/lib/module/MapView.js +9 -12
  17. package/lib/module/MapView.js.map +1 -1
  18. package/lib/module/MapView.web.js +4 -1
  19. package/lib/module/MapView.web.js.map +1 -1
  20. package/lib/module/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  21. package/lib/typescript/src/MapView.d.ts +0 -1
  22. package/lib/typescript/src/MapView.d.ts.map +1 -1
  23. package/lib/typescript/src/MapView.types.d.ts +6 -1
  24. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  25. package/lib/typescript/src/MapView.web.d.ts.map +1 -1
  26. package/lib/typescript/src/fabric/{LuggGoogleMapViewNativeComponent.d.ts → LuggMapViewNativeComponent.d.ts} +4 -2
  27. package/lib/typescript/src/fabric/LuggMapViewNativeComponent.d.ts.map +1 -0
  28. package/lib/typescript/src/index.d.ts +1 -1
  29. package/lib/typescript/src/index.d.ts.map +1 -1
  30. package/lib/typescript/src/types.d.ts +4 -0
  31. package/lib/typescript/src/types.d.ts.map +1 -1
  32. package/package.json +5 -3
  33. package/src/MapView.tsx +11 -21
  34. package/src/MapView.types.ts +6 -1
  35. package/src/MapView.web.tsx +10 -0
  36. package/src/fabric/{LuggGoogleMapViewNativeComponent.ts → LuggMapViewNativeComponent.ts} +4 -1
  37. package/src/index.ts +1 -0
  38. package/src/types.ts +5 -0
  39. package/ios/LuggAppleMapView.h +0 -16
  40. package/ios/LuggGoogleMapView.h +0 -13
  41. package/lib/module/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
  42. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts +0 -54
  43. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +0 -1
  44. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +0 -1
  45. package/src/fabric/LuggAppleMapViewNativeComponent.ts +0 -83
@@ -1,12 +1,10 @@
1
- package com.luggmaps
1
+ package com.luggmaps.core
2
2
 
3
3
  import android.annotation.SuppressLint
4
+ import android.content.Context
4
5
  import android.view.View
5
- import android.view.ViewGroup
6
6
  import com.facebook.react.uimanager.PixelUtil.dpToPx
7
- import com.facebook.react.uimanager.ThemedReactContext
8
7
  import com.facebook.react.util.RNLog
9
- import com.facebook.react.views.view.ReactViewGroup
10
8
  import com.google.android.gms.maps.CameraUpdateFactory
11
9
  import com.google.android.gms.maps.GoogleMap
12
10
  import com.google.android.gms.maps.GoogleMapOptions
@@ -14,32 +12,16 @@ import com.google.android.gms.maps.MapView
14
12
  import com.google.android.gms.maps.OnMapReadyCallback
15
13
  import com.google.android.gms.maps.model.AdvancedMarker
16
14
  import com.google.android.gms.maps.model.AdvancedMarkerOptions
17
- import com.google.android.gms.maps.model.AdvancedMarkerOptions.CollisionBehavior
18
15
  import com.google.android.gms.maps.model.LatLng
16
+ import com.google.android.gms.maps.model.MapColorScheme
19
17
  import com.google.android.gms.maps.model.PolylineOptions
20
- import com.luggmaps.core.PolylineAnimator
21
-
22
- interface LuggGoogleMapViewEventDelegate {
23
- fun onCameraMove(
24
- view: LuggGoogleMapView,
25
- latitude: Double,
26
- longitude: Double,
27
- zoom: Float,
28
- gesture: Boolean
29
- )
30
- fun onCameraIdle(
31
- view: LuggGoogleMapView,
32
- latitude: Double,
33
- longitude: Double,
34
- zoom: Float,
35
- gesture: Boolean
36
- )
37
- fun onReady(view: LuggGoogleMapView)
38
- }
18
+ import com.luggmaps.LuggMarkerView
19
+ import com.luggmaps.LuggMarkerViewDelegate
20
+ import com.luggmaps.LuggPolylineView
21
+ import com.luggmaps.LuggPolylineViewDelegate
39
22
 
40
- @SuppressLint("ViewConstructor")
41
- class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
42
- ReactViewGroup(reactContext),
23
+ class GoogleMapProvider(private val context: Context) :
24
+ MapProvider,
43
25
  OnMapReadyCallback,
44
26
  LuggMarkerViewDelegate,
45
27
  LuggPolylineViewDelegate,
@@ -47,21 +29,23 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
47
29
  GoogleMap.OnCameraMoveListener,
48
30
  GoogleMap.OnCameraIdleListener {
49
31
 
50
- var eventDelegate: LuggGoogleMapViewEventDelegate? = null
32
+ override var delegate: MapProviderDelegate? = null
33
+ override val isMapReady: Boolean get() = _isMapReady
34
+
35
+ var mapId: String = DEMO_MAP_ID
36
+
51
37
  private var mapView: MapView? = null
52
- private var mapWrapperView: LuggMapWrapperView? = null
53
38
  private var googleMap: GoogleMap? = null
54
- private var isMapReady = false
39
+ private var _isMapReady = false
55
40
  private var isDragging = false
56
- private var mapId: String = DEMO_MAP_ID
57
41
  private val pendingMarkerViews = mutableSetOf<LuggMarkerView>()
58
42
  private val pendingPolylineViews = mutableSetOf<LuggPolylineView>()
59
43
  private val polylineAnimators = mutableMapOf<LuggPolylineView, PolylineAnimator>()
60
44
 
61
45
  // Initial camera settings
62
- private var initialLatitude: Double = 37.78
63
- private var initialLongitude: Double = -122.43
64
- private var initialZoom: Float = 14f
46
+ private var initialLatitude: Double = 0.0
47
+ private var initialLongitude: Double = 0.0
48
+ private var initialZoom: Float = 10f
65
49
 
66
50
  // UI settings
67
51
  private var zoomEnabled: Boolean = true
@@ -74,85 +58,49 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
74
58
  private var minZoom: Float? = null
75
59
  private var maxZoom: Float? = null
76
60
 
61
+ // Theme
62
+ private var theme: String = "system"
63
+
77
64
  // Padding
78
65
  private var paddingTop: Int = 0
79
66
  private var paddingLeft: Int = 0
80
67
  private var paddingBottom: Int = 0
81
68
  private var paddingRight: Int = 0
82
69
 
83
- // region View Lifecycle
84
-
85
- override fun addView(child: View?, index: Int) {
86
- super.addView(child, index)
87
- when (child) {
88
- is LuggMapWrapperView -> mapWrapperView = child
89
-
90
- is LuggMarkerView -> {
91
- child.delegate = this
92
- syncMarkerView(child)
93
- }
70
+ // region MapProvider
94
71
 
95
- is LuggPolylineView -> {
96
- child.delegate = this
97
- syncPolylineView(child)
98
- }
99
- }
100
- }
72
+ override fun initializeMap(wrapperView: View, latitude: Double, longitude: Double, zoom: Float) {
73
+ if (mapView != null) return
101
74
 
102
- override fun removeViewAt(index: Int) {
103
- val view = getChildAt(index)
104
- if (view is LuggMarkerView) {
105
- view.marker?.remove()
106
- view.marker = null
107
- } else if (view is LuggPolylineView) {
108
- polylineAnimators[view]?.destroy()
109
- polylineAnimators.remove(view)
110
- view.polyline?.remove()
111
- view.polyline = null
112
- }
113
- super.removeViewAt(index)
114
- }
75
+ initialLatitude = latitude
76
+ initialLongitude = longitude
77
+ initialZoom = zoom
115
78
 
116
- override fun onAttachedToWindow() {
117
- super.onAttachedToWindow()
118
- if (mapView == null && mapWrapperView != null) {
119
- initializeMap()
79
+ val options = GoogleMapOptions().mapId(mapId)
80
+ mapView = MapView(context, options).also { view ->
81
+ view.onCreate(null)
82
+ view.onResume()
83
+ view.getMapAsync(this)
84
+ (wrapperView as android.view.ViewGroup).addView(view)
120
85
  }
121
86
  }
122
87
 
123
- fun onDropViewInstance() {
88
+ override fun destroy() {
124
89
  pendingMarkerViews.clear()
125
90
  pendingPolylineViews.clear()
126
91
  polylineAnimators.values.forEach { it.destroy() }
127
92
  polylineAnimators.clear()
128
93
  googleMap?.clear()
129
94
  googleMap = null
130
- isMapReady = false
95
+ _isMapReady = false
131
96
  mapView?.onPause()
132
97
  mapView?.onDestroy()
133
98
  mapView = null
134
- mapWrapperView = null
135
- }
136
-
137
- // endregion
138
-
139
- // region Map Initialization
140
-
141
- private fun initializeMap() {
142
- if (mapView != null || mapWrapperView == null) return
143
-
144
- val options = GoogleMapOptions().mapId(mapId)
145
- mapView = MapView(context, options).also { view ->
146
- view.onCreate(null)
147
- view.onResume()
148
- view.getMapAsync(this)
149
- mapWrapperView?.addView(view)
150
- }
151
99
  }
152
100
 
153
101
  override fun onMapReady(map: GoogleMap) {
154
102
  googleMap = map
155
- isMapReady = true
103
+ _isMapReady = true
156
104
 
157
105
  val position = LatLng(initialLatitude, initialLongitude)
158
106
  map.moveCamera(CameraUpdateFactory.newLatLngZoom(position, initialZoom))
@@ -164,13 +112,18 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
164
112
  applyUiSettings()
165
113
  applyZoomLimits()
166
114
  applyPadding()
115
+ applyTheme()
167
116
  applyUserLocation()
168
117
  processPendingMarkers()
169
118
  processPendingPolylines()
170
119
 
171
- eventDelegate?.onReady(this)
120
+ delegate?.mapProviderDidReady()
172
121
  }
173
122
 
123
+ // endregion
124
+
125
+ // region Camera Listeners
126
+
174
127
  override fun onCameraMoveStarted(reason: Int) {
175
128
  isDragging = reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE
176
129
  if (isDragging) {
@@ -181,41 +134,46 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
181
134
  override fun onCameraMove() {
182
135
  val map = googleMap ?: return
183
136
  val position = map.cameraPosition
184
- eventDelegate?.onCameraMove(this, position.target.latitude, position.target.longitude, position.zoom, isDragging)
137
+ delegate?.mapProviderDidMoveCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
185
138
  }
186
139
 
187
140
  override fun onCameraIdle() {
188
141
  val map = googleMap ?: return
189
142
  val position = map.cameraPosition
190
- eventDelegate?.onCameraIdle(this, position.target.latitude, position.target.longitude, position.zoom, isDragging)
143
+ delegate?.mapProviderDidIdleCamera(position.target.latitude, position.target.longitude, position.zoom, isDragging)
191
144
  if (isDragging) {
192
145
  polylineAnimators.values.forEach { it.resume() }
193
146
  }
194
147
  isDragging = false
195
148
  }
196
149
 
197
- private fun applyUiSettings() {
198
- googleMap?.uiSettings?.apply {
199
- isZoomGesturesEnabled = zoomEnabled
200
- isScrollGesturesEnabled = scrollEnabled
201
- isRotateGesturesEnabled = rotateEnabled
202
- isTiltGesturesEnabled = pitchEnabled
203
- }
150
+ // endregion
151
+
152
+ // region Props
153
+
154
+ override fun setZoomEnabled(enabled: Boolean) {
155
+ zoomEnabled = enabled
156
+ googleMap?.uiSettings?.isZoomGesturesEnabled = enabled
204
157
  }
205
158
 
206
- private fun applyZoomLimits() {
207
- googleMap?.apply {
208
- minZoom?.let { setMinZoomPreference(it) }
209
- maxZoom?.let { setMaxZoomPreference(it) }
210
- }
159
+ override fun setScrollEnabled(enabled: Boolean) {
160
+ scrollEnabled = enabled
161
+ googleMap?.uiSettings?.isScrollGesturesEnabled = enabled
211
162
  }
212
163
 
213
- private fun applyPadding() {
214
- googleMap?.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
164
+ override fun setRotateEnabled(enabled: Boolean) {
165
+ rotateEnabled = enabled
166
+ googleMap?.uiSettings?.isRotateGesturesEnabled = enabled
167
+ }
168
+
169
+ override fun setPitchEnabled(enabled: Boolean) {
170
+ pitchEnabled = enabled
171
+ googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
215
172
  }
216
173
 
217
174
  @SuppressLint("MissingPermission")
218
- private fun applyUserLocation() {
175
+ override fun setUserLocationEnabled(enabled: Boolean) {
176
+ userLocationEnabled = enabled
219
177
  val hasPermission =
220
178
  context.checkSelfPermission(
221
179
  android.Manifest.permission.ACCESS_FINE_LOCATION
@@ -225,12 +183,31 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
225
183
  googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
226
184
  }
227
185
 
228
- // endregion
186
+ override fun setTheme(value: String) {
187
+ theme = value
188
+ applyTheme()
189
+ }
229
190
 
230
- // region PolylineViewDelegate
191
+ override fun setMinZoom(zoom: Double) {
192
+ minZoom = if (zoom > 0) zoom.toFloat() else null
193
+ googleMap?.let { map ->
194
+ minZoom?.let { map.setMinZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
195
+ }
196
+ }
231
197
 
232
- override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
233
- syncPolylineView(polylineView)
198
+ override fun setMaxZoom(zoom: Double) {
199
+ maxZoom = if (zoom > 0) zoom.toFloat() else null
200
+ googleMap?.let { map ->
201
+ maxZoom?.let { map.setMaxZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
202
+ }
203
+ }
204
+
205
+ override fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
206
+ paddingTop = top
207
+ paddingLeft = left
208
+ paddingBottom = bottom
209
+ paddingRight = right
210
+ applyPadding()
234
211
  }
235
212
 
236
213
  // endregion
@@ -256,8 +233,26 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
256
233
 
257
234
  // endregion
258
235
 
236
+ // region PolylineViewDelegate
237
+
238
+ override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
239
+ syncPolylineView(polylineView)
240
+ }
241
+
242
+ // endregion
243
+
259
244
  // region Marker Management
260
245
 
246
+ override fun addMarkerView(markerView: LuggMarkerView) {
247
+ markerView.delegate = this
248
+ syncMarkerView(markerView)
249
+ }
250
+
251
+ override fun removeMarkerView(markerView: LuggMarkerView) {
252
+ markerView.marker?.remove()
253
+ markerView.marker = null
254
+ }
255
+
261
256
  private fun syncMarkerView(markerView: LuggMarkerView) {
262
257
  if (googleMap == null) {
263
258
  pendingMarkerViews.add(markerView)
@@ -265,7 +260,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
265
260
  }
266
261
 
267
262
  if (markerView.marker == null) {
268
- // Custom views need layout first before adding to map
269
263
  if (markerView.hasCustomView) return
270
264
  addMarkerViewToMap(markerView)
271
265
  return
@@ -288,19 +282,14 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
288
282
 
289
283
  private fun processPendingMarkers() {
290
284
  if (googleMap == null) return
291
-
292
285
  pendingMarkerViews.forEach { addMarkerViewToMap(it) }
293
286
  pendingMarkerViews.clear()
294
287
  }
295
288
 
296
289
  private fun addMarkerViewToMap(markerView: LuggMarkerView) {
297
- val map = googleMap ?: run {
298
- RNLog.w(reactContext, "LuggMaps: addMarkerViewToMap called without a map")
299
- return
300
- }
290
+ val map = googleMap ?: return
301
291
 
302
292
  val position = LatLng(markerView.latitude, markerView.longitude)
303
-
304
293
  val options = AdvancedMarkerOptions()
305
294
  .position(position)
306
295
  .title(markerView.title)
@@ -319,6 +308,18 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
319
308
 
320
309
  // region Polyline Management
321
310
 
311
+ override fun addPolylineView(polylineView: LuggPolylineView) {
312
+ polylineView.delegate = this
313
+ syncPolylineView(polylineView)
314
+ }
315
+
316
+ override fun removePolylineView(polylineView: LuggPolylineView) {
317
+ polylineAnimators[polylineView]?.destroy()
318
+ polylineAnimators.remove(polylineView)
319
+ polylineView.polyline?.remove()
320
+ polylineView.polyline = null
321
+ }
322
+
322
323
  private fun syncPolylineView(polylineView: LuggPolylineView) {
323
324
  if (googleMap == null) {
324
325
  pendingPolylineViews.add(polylineView)
@@ -345,7 +346,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
345
346
 
346
347
  private fun processPendingPolylines() {
347
348
  if (googleMap == null) return
348
-
349
349
  pendingPolylineViews.forEach { addPolylineViewToMap(it) }
350
350
  pendingPolylineViews.clear()
351
351
  }
@@ -375,80 +375,21 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
375
375
 
376
376
  // endregion
377
377
 
378
- // region Property Setters
379
-
380
- fun setMapId(value: String?) {
381
- if (value.isNullOrEmpty()) return
382
-
383
- if (mapView != null) {
384
- RNLog.w(reactContext, "LuggMaps: mapId cannot be changed after map is initialized")
385
- return
386
- }
387
-
388
- mapId = value
389
- }
390
-
391
- fun setInitialCoordinate(latitude: Double, longitude: Double) {
392
- initialLatitude = latitude
393
- initialLongitude = longitude
394
- }
395
-
396
- fun setInitialZoom(zoom: Double) {
397
- initialZoom = zoom.toFloat()
398
- }
399
-
400
- fun setZoomEnabled(enabled: Boolean) {
401
- zoomEnabled = enabled
402
- googleMap?.uiSettings?.isZoomGesturesEnabled = enabled
403
- }
404
-
405
- fun setScrollEnabled(enabled: Boolean) {
406
- scrollEnabled = enabled
407
- googleMap?.uiSettings?.isScrollGesturesEnabled = enabled
408
- }
409
-
410
- fun setRotateEnabled(enabled: Boolean) {
411
- rotateEnabled = enabled
412
- googleMap?.uiSettings?.isRotateGesturesEnabled = enabled
413
- }
414
-
415
- fun setPitchEnabled(enabled: Boolean) {
416
- pitchEnabled = enabled
417
- googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
418
- }
378
+ // region Lifecycle
419
379
 
420
- fun setUserLocationEnabled(enabled: Boolean) {
421
- userLocationEnabled = enabled
422
- applyUserLocation()
380
+ override fun pauseAnimations() {
381
+ polylineAnimators.values.forEach { it.pause() }
423
382
  }
424
383
 
425
- fun setMinZoom(zoom: Double) {
426
- minZoom = if (zoom > 0) zoom.toFloat() else null
427
- googleMap?.let { map ->
428
- minZoom?.let { map.setMinZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
429
- }
430
- }
431
-
432
- fun setMaxZoom(zoom: Double) {
433
- maxZoom = if (zoom > 0) zoom.toFloat() else null
434
- googleMap?.let { map ->
435
- maxZoom?.let { map.setMaxZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
436
- }
437
- }
438
-
439
- fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
440
- paddingTop = top
441
- paddingLeft = left
442
- paddingBottom = bottom
443
- paddingRight = right
444
- applyPadding()
384
+ override fun resumeAnimations() {
385
+ polylineAnimators.values.forEach { it.resume() }
445
386
  }
446
387
 
447
388
  // endregion
448
389
 
449
390
  // region Commands
450
391
 
451
- fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
392
+ override fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int) {
452
393
  val map = googleMap ?: return
453
394
  val position = LatLng(latitude, longitude)
454
395
  val targetZoom = if (zoom > 0) zoom.toFloat() else map.cameraPosition.zoom
@@ -460,8 +401,8 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
460
401
  }
461
402
  }
462
403
 
463
- fun fitCoordinates(
464
- coordinates: List<LatLng>,
404
+ override fun fitCoordinates(
405
+ coordinates: List<Any>,
465
406
  paddingTop: Int,
466
407
  paddingLeft: Int,
467
408
  paddingBottom: Int,
@@ -471,8 +412,11 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
471
412
  val map = googleMap ?: return
472
413
  if (coordinates.isEmpty()) return
473
414
 
415
+ val latLngs = coordinates.filterIsInstance<LatLng>()
416
+ if (latLngs.isEmpty()) return
417
+
474
418
  val boundsBuilder = com.google.android.gms.maps.model.LatLngBounds.Builder()
475
- coordinates.forEach { boundsBuilder.include(it) }
419
+ latLngs.forEach { boundsBuilder.include(it) }
476
420
  val bounds = boundsBuilder.build()
477
421
 
478
422
  val top = paddingTop.toFloat().dpToPx().toInt()
@@ -480,7 +424,6 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
480
424
  val bottom = paddingBottom.toFloat().dpToPx().toInt()
481
425
  val right = paddingRight.toFloat().dpToPx().toInt()
482
426
 
483
- // Set padding before camera update, then restore after
484
427
  map.setPadding(
485
428
  this.paddingLeft + left,
486
429
  this.paddingTop + top,
@@ -496,14 +439,56 @@ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
496
439
  else -> map.moveCamera(cameraUpdate)
497
440
  }
498
441
 
499
- // Restore base padding
500
442
  map.setPadding(this.paddingLeft, this.paddingTop, this.paddingRight, this.paddingBottom)
501
443
  }
502
444
 
503
445
  // endregion
504
446
 
447
+ // region Private
448
+
449
+ private fun applyUiSettings() {
450
+ googleMap?.uiSettings?.apply {
451
+ isZoomGesturesEnabled = zoomEnabled
452
+ isScrollGesturesEnabled = scrollEnabled
453
+ isRotateGesturesEnabled = rotateEnabled
454
+ isTiltGesturesEnabled = pitchEnabled
455
+ }
456
+ }
457
+
458
+ private fun applyZoomLimits() {
459
+ googleMap?.apply {
460
+ minZoom?.let { setMinZoomPreference(it) }
461
+ maxZoom?.let { setMaxZoomPreference(it) }
462
+ }
463
+ }
464
+
465
+ private fun applyPadding() {
466
+ googleMap?.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
467
+ }
468
+
469
+ private fun applyTheme() {
470
+ val colorScheme = when (theme) {
471
+ "dark" -> MapColorScheme.DARK
472
+ "light" -> MapColorScheme.LIGHT
473
+ else -> MapColorScheme.FOLLOW_SYSTEM
474
+ }
475
+ googleMap?.setMapColorScheme(colorScheme)
476
+ }
477
+
478
+ @SuppressLint("MissingPermission")
479
+ private fun applyUserLocation() {
480
+ val hasPermission =
481
+ context.checkSelfPermission(
482
+ android.Manifest.permission.ACCESS_FINE_LOCATION
483
+ ) == android.content.pm.PackageManager.PERMISSION_GRANTED ||
484
+ context.checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
485
+ android.content.pm.PackageManager.PERMISSION_GRANTED
486
+ googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
487
+ }
488
+
489
+ // endregion
490
+
505
491
  companion object {
506
- private const val TAG = "Lugg"
507
492
  const val DEMO_MAP_ID = "DEMO_MAP_ID"
508
493
  }
509
494
  }
@@ -0,0 +1,51 @@
1
+ package com.luggmaps.core
2
+
3
+ import android.view.View
4
+ import com.luggmaps.LuggMarkerView
5
+ import com.luggmaps.LuggPolylineView
6
+
7
+ interface MapProviderDelegate {
8
+ fun mapProviderDidReady()
9
+ fun mapProviderDidMoveCamera(latitude: Double, longitude: Double, zoom: Float, gesture: Boolean)
10
+ fun mapProviderDidIdleCamera(latitude: Double, longitude: Double, zoom: Float, gesture: Boolean)
11
+ }
12
+
13
+ interface MapProvider {
14
+ var delegate: MapProviderDelegate?
15
+ val isMapReady: Boolean
16
+
17
+ fun initializeMap(wrapperView: View, latitude: Double, longitude: Double, zoom: Float)
18
+ fun destroy()
19
+
20
+ // Props
21
+ fun setZoomEnabled(enabled: Boolean)
22
+ fun setScrollEnabled(enabled: Boolean)
23
+ fun setRotateEnabled(enabled: Boolean)
24
+ fun setPitchEnabled(enabled: Boolean)
25
+ fun setUserLocationEnabled(enabled: Boolean)
26
+ fun setTheme(value: String)
27
+ fun setMinZoom(zoom: Double)
28
+ fun setMaxZoom(zoom: Double)
29
+ fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int)
30
+
31
+ // Children
32
+ fun addMarkerView(markerView: LuggMarkerView)
33
+ fun removeMarkerView(markerView: LuggMarkerView)
34
+ fun addPolylineView(polylineView: LuggPolylineView)
35
+ fun removePolylineView(polylineView: LuggPolylineView)
36
+
37
+ // Lifecycle
38
+ fun pauseAnimations()
39
+ fun resumeAnimations()
40
+
41
+ // Commands
42
+ fun moveCamera(latitude: Double, longitude: Double, zoom: Double, duration: Int)
43
+ fun fitCoordinates(
44
+ coordinates: List<Any>,
45
+ paddingTop: Int,
46
+ paddingLeft: Int,
47
+ paddingBottom: Int,
48
+ paddingRight: Int,
49
+ duration: Int
50
+ )
51
+ }