@lugg/maps 0.2.0-alpha.0 → 0.2.0-alpha.10

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 (152) hide show
  1. package/README.md +17 -4
  2. package/android/src/main/java/com/luggmaps/{LuggMapsGoogleMapView.kt → LuggGoogleMapView.kt} +111 -36
  3. package/android/src/main/java/com/luggmaps/{LuggMapsGoogleMapViewManager.kt → LuggGoogleMapViewManager.kt} +66 -39
  4. package/android/src/main/java/com/luggmaps/{LuggMapsWrapperView.kt → LuggMapWrapperView.kt} +1 -1
  5. package/android/src/main/java/com/luggmaps/LuggMapWrapperViewManager.kt +25 -0
  6. package/android/src/main/java/com/luggmaps/{LuggMapsMarkerView.kt → LuggMarkerView.kt} +13 -7
  7. package/android/src/main/java/com/luggmaps/{LuggMapsMarkerViewManager.kt → LuggMarkerViewManager.kt} +23 -17
  8. package/android/src/main/java/com/luggmaps/{LuggMapsPackage.kt → LuggPackage.kt} +2 -2
  9. package/android/src/main/java/com/luggmaps/{LuggMapsPolylineView.kt → LuggPolylineView.kt} +11 -4
  10. package/android/src/main/java/com/luggmaps/{LuggMapsPolylineViewManager.kt → LuggPolylineViewManager.kt} +22 -16
  11. package/android/src/main/java/com/luggmaps/core/PolylineAnimator.kt +89 -43
  12. package/android/src/main/java/com/luggmaps/events/CameraIdleEvent.kt +10 -2
  13. package/android/src/main/java/com/luggmaps/events/CameraMoveEvent.kt +6 -5
  14. package/android/src/main/java/com/luggmaps/events/ReadyEvent.kt +12 -0
  15. package/android/src/main/java/com/luggmaps/extensions/ViewExtensions.kt +14 -0
  16. package/ios/{LuggMapsAppleMapView.h → LuggAppleMapView.h} +2 -2
  17. package/ios/{LuggMapsAppleMapView.mm → LuggAppleMapView.mm} +140 -71
  18. package/ios/{LuggMapsGoogleMapView.h → LuggGoogleMapView.h} +1 -1
  19. package/ios/{LuggMapsGoogleMapView.mm → LuggGoogleMapView.mm} +82 -64
  20. package/ios/{LuggMapsWrapperView.h → LuggMapWrapperView.h} +1 -1
  21. package/ios/{LuggMapsWrapperView.mm → LuggMapWrapperView.mm} +7 -7
  22. package/ios/{LuggMapsMarkerView.h → LuggMarkerView.h} +8 -6
  23. package/ios/{LuggMapsMarkerView.mm → LuggMarkerView.mm} +21 -8
  24. package/ios/{LuggMapsPolylineView.h → LuggPolylineView.h} +6 -5
  25. package/ios/{LuggMapsPolylineView.mm → LuggPolylineView.mm} +14 -9
  26. package/ios/core/GMSPolylineAnimator.m +85 -36
  27. package/ios/core/MKPolylineAnimator.m +63 -32
  28. package/ios/events/CameraIdleEvent.h +6 -1
  29. package/ios/events/CameraMoveEvent.h +6 -3
  30. package/ios/events/ReadyEvent.h +20 -0
  31. package/lib/module/MapProvider.js +13 -0
  32. package/lib/module/MapProvider.js.map +1 -0
  33. package/lib/module/MapProvider.types.js +4 -0
  34. package/lib/module/MapProvider.types.js.map +1 -0
  35. package/lib/module/MapProvider.web.js +14 -0
  36. package/lib/module/MapProvider.web.js.map +1 -0
  37. package/lib/module/MapView.js +21 -7
  38. package/lib/module/MapView.js.map +1 -1
  39. package/lib/module/MapView.web.js +266 -0
  40. package/lib/module/MapView.web.js.map +1 -0
  41. package/lib/module/{Marker.js → components/Marker.js} +6 -3
  42. package/lib/module/components/Marker.js.map +1 -0
  43. package/lib/module/components/Marker.web.js +34 -0
  44. package/lib/module/components/Marker.web.js.map +1 -0
  45. package/lib/module/{Polyline.js → components/Polyline.js} +7 -4
  46. package/lib/module/components/Polyline.js.map +1 -0
  47. package/lib/module/components/Polyline.web.js +177 -0
  48. package/lib/module/components/Polyline.web.js.map +1 -0
  49. package/lib/module/components/index.js +5 -0
  50. package/lib/module/components/index.js.map +1 -0
  51. package/lib/module/components/index.web.js +5 -0
  52. package/lib/module/components/index.web.js.map +1 -0
  53. package/{src/fabric/LuggMapsAppleMapViewNativeComponent.ts → lib/module/fabric/LuggAppleMapViewNativeComponent.ts} +13 -3
  54. package/lib/module/fabric/{LuggMapsGoogleMapViewNativeComponent.ts → LuggGoogleMapViewNativeComponent.ts} +13 -3
  55. package/{src/fabric/LuggMapsWrapperViewNativeComponent.ts → lib/module/fabric/LuggMapWrapperViewNativeComponent.ts} +1 -1
  56. package/lib/module/fabric/{LuggMapsMarkerViewNativeComponent.ts → LuggMarkerViewNativeComponent.ts} +1 -1
  57. package/{src/fabric/LuggMapsPolylineViewNativeComponent.ts → lib/module/fabric/LuggPolylineViewNativeComponent.ts} +1 -1
  58. package/lib/module/index.js +3 -3
  59. package/lib/module/index.js.map +1 -1
  60. package/lib/module/index.web.js +6 -0
  61. package/lib/module/index.web.js.map +1 -0
  62. package/lib/typescript/plugin/src/withLuggMapsAndroid.d.ts +6 -0
  63. package/lib/typescript/plugin/src/withLuggMapsAndroid.d.ts.map +1 -0
  64. package/lib/typescript/plugin/src/withLuggMapsIOS.d.ts +6 -0
  65. package/lib/typescript/plugin/src/withLuggMapsIOS.d.ts.map +1 -0
  66. package/lib/typescript/src/MapProvider.d.ts +8 -0
  67. package/lib/typescript/src/MapProvider.d.ts.map +1 -0
  68. package/lib/typescript/src/MapProvider.types.d.ts +16 -0
  69. package/lib/typescript/src/MapProvider.types.d.ts.map +1 -0
  70. package/lib/typescript/src/MapProvider.web.d.ts +3 -0
  71. package/lib/typescript/src/MapProvider.web.d.ts.map +1 -0
  72. package/lib/typescript/src/MapView.d.ts.map +1 -1
  73. package/lib/typescript/src/MapView.types.d.ts +24 -14
  74. package/lib/typescript/src/MapView.types.d.ts.map +1 -1
  75. package/lib/typescript/src/MapView.web.d.ts +12 -0
  76. package/lib/typescript/src/MapView.web.d.ts.map +1 -0
  77. package/lib/typescript/src/{Marker.types.d.ts → components/Marker.d.ts} +10 -5
  78. package/lib/typescript/src/components/Marker.d.ts.map +1 -0
  79. package/lib/typescript/src/{Marker.d.ts → components/Marker.web.d.ts} +2 -2
  80. package/lib/typescript/src/components/Marker.web.d.ts.map +1 -0
  81. package/lib/typescript/src/{Polyline.types.d.ts → components/Polyline.d.ts} +10 -5
  82. package/lib/typescript/src/components/Polyline.d.ts.map +1 -0
  83. package/lib/typescript/src/components/Polyline.web.d.ts +6 -0
  84. package/lib/typescript/src/components/Polyline.web.d.ts.map +1 -0
  85. package/lib/typescript/src/components/index.d.ts +3 -0
  86. package/lib/typescript/src/components/index.d.ts.map +1 -0
  87. package/lib/typescript/src/components/index.web.d.ts +5 -0
  88. package/lib/typescript/src/components/index.web.d.ts.map +1 -0
  89. package/lib/typescript/src/fabric/{LuggMapsAppleMapViewNativeComponent.d.ts → LuggAppleMapViewNativeComponent.d.ts} +10 -3
  90. package/lib/typescript/src/fabric/LuggAppleMapViewNativeComponent.d.ts.map +1 -0
  91. package/lib/typescript/src/fabric/{LuggMapsGoogleMapViewNativeComponent.d.ts → LuggGoogleMapViewNativeComponent.d.ts} +10 -3
  92. package/lib/typescript/src/fabric/LuggGoogleMapViewNativeComponent.d.ts.map +1 -0
  93. package/lib/typescript/src/fabric/{LuggMapsWrapperViewNativeComponent.d.ts → LuggMapWrapperViewNativeComponent.d.ts} +1 -1
  94. package/lib/typescript/src/fabric/LuggMapWrapperViewNativeComponent.d.ts.map +1 -0
  95. package/lib/typescript/src/fabric/{LuggMapsMarkerViewNativeComponent.d.ts → LuggMarkerViewNativeComponent.d.ts} +1 -1
  96. package/lib/typescript/src/fabric/LuggMarkerViewNativeComponent.d.ts.map +1 -0
  97. package/lib/typescript/src/fabric/{LuggMapsPolylineViewNativeComponent.d.ts → LuggPolylineViewNativeComponent.d.ts} +1 -1
  98. package/lib/typescript/src/fabric/LuggPolylineViewNativeComponent.d.ts.map +1 -0
  99. package/lib/typescript/src/index.d.ts +5 -6
  100. package/lib/typescript/src/index.d.ts.map +1 -1
  101. package/lib/typescript/src/index.web.d.ts +7 -0
  102. package/lib/typescript/src/index.web.d.ts.map +1 -0
  103. package/package.json +20 -7
  104. package/plugin/build/index.js +4 -4
  105. package/{lib/typescript/plugin/src/withMapsAndroid.d.ts → plugin/build/withLuggMapsAndroid.d.ts} +0 -1
  106. package/plugin/build/withLuggMapsAndroid.js +15 -0
  107. package/{lib/typescript/plugin/src/withMapsIOS.d.ts → plugin/build/withLuggMapsIOS.d.ts} +0 -1
  108. package/plugin/build/withLuggMapsIOS.js +27 -0
  109. package/plugin/build/withMapsAndroid.d.ts +1 -1
  110. package/plugin/build/withMapsIOS.d.ts +1 -1
  111. package/src/MapProvider.tsx +10 -0
  112. package/src/MapProvider.types.ts +16 -0
  113. package/src/MapProvider.web.tsx +6 -0
  114. package/src/MapView.tsx +27 -10
  115. package/src/MapView.types.ts +24 -15
  116. package/src/MapView.web.tsx +319 -0
  117. package/src/components/Marker.tsx +63 -0
  118. package/src/components/Marker.web.tsx +32 -0
  119. package/src/components/Polyline.tsx +57 -0
  120. package/src/components/Polyline.web.tsx +222 -0
  121. package/src/components/index.ts +2 -0
  122. package/src/components/index.web.ts +4 -0
  123. package/{lib/module/fabric/LuggMapsAppleMapViewNativeComponent.ts → src/fabric/LuggAppleMapViewNativeComponent.ts} +13 -3
  124. package/src/fabric/{LuggMapsGoogleMapViewNativeComponent.ts → LuggGoogleMapViewNativeComponent.ts} +13 -3
  125. package/{lib/module/fabric/LuggMapsWrapperViewNativeComponent.ts → src/fabric/LuggMapWrapperViewNativeComponent.ts} +1 -1
  126. package/src/fabric/{LuggMapsMarkerViewNativeComponent.ts → LuggMarkerViewNativeComponent.ts} +1 -1
  127. package/{lib/module/fabric/LuggMapsPolylineViewNativeComponent.ts → src/fabric/LuggPolylineViewNativeComponent.ts} +1 -1
  128. package/src/index.ts +11 -7
  129. package/src/index.web.ts +17 -0
  130. package/android/src/main/java/com/luggmaps/LuggMapsWrapperViewManager.kt +0 -25
  131. package/lib/module/Marker.js.map +0 -1
  132. package/lib/module/Marker.types.js +0 -4
  133. package/lib/module/Marker.types.js.map +0 -1
  134. package/lib/module/Polyline.js.map +0 -1
  135. package/lib/module/Polyline.types.js +0 -4
  136. package/lib/module/Polyline.types.js.map +0 -1
  137. package/lib/typescript/plugin/src/withMapsAndroid.d.ts.map +0 -1
  138. package/lib/typescript/plugin/src/withMapsIOS.d.ts.map +0 -1
  139. package/lib/typescript/src/Marker.d.ts.map +0 -1
  140. package/lib/typescript/src/Marker.types.d.ts.map +0 -1
  141. package/lib/typescript/src/Polyline.d.ts +0 -6
  142. package/lib/typescript/src/Polyline.d.ts.map +0 -1
  143. package/lib/typescript/src/Polyline.types.d.ts.map +0 -1
  144. package/lib/typescript/src/fabric/LuggMapsAppleMapViewNativeComponent.d.ts.map +0 -1
  145. package/lib/typescript/src/fabric/LuggMapsGoogleMapViewNativeComponent.d.ts.map +0 -1
  146. package/lib/typescript/src/fabric/LuggMapsMarkerViewNativeComponent.d.ts.map +0 -1
  147. package/lib/typescript/src/fabric/LuggMapsPolylineViewNativeComponent.d.ts.map +0 -1
  148. package/lib/typescript/src/fabric/LuggMapsWrapperViewNativeComponent.d.ts.map +0 -1
  149. package/src/Marker.tsx +0 -31
  150. package/src/Marker.types.ts +0 -32
  151. package/src/Polyline.tsx +0 -32
  152. package/src/Polyline.types.ts +0 -24
package/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # @lugg/maps
2
2
 
3
- React Native Fabric maps library for iOS and Android.
4
-
5
- - Google Maps (iOS & Android)
6
- - Apple Maps (iOS only)
3
+ Universal maps for your React Native apps 📍
7
4
 
8
5
  ## Installation
9
6
 
@@ -56,6 +53,22 @@ Add your Google Maps API key to `AndroidManifest.xml`:
56
53
  </application>
57
54
  ```
58
55
 
56
+ ### Web
57
+
58
+ Wrap your app with `MapProvider` and pass your Google Maps API key:
59
+
60
+ ```tsx
61
+ import { MapProvider } from '@lugg/maps';
62
+
63
+ function App() {
64
+ return (
65
+ <MapProvider apiKey="YOUR_WEB_API_KEY">
66
+ {/* Your app */}
67
+ </MapProvider>
68
+ );
69
+ }
70
+ ```
71
+
59
72
  ## Usage
60
73
 
61
74
  ```tsx
@@ -1,7 +1,6 @@
1
1
  package com.luggmaps
2
2
 
3
3
  import android.annotation.SuppressLint
4
- import android.util.Log
5
4
  import android.view.View
6
5
  import android.view.ViewGroup
7
6
  import com.facebook.react.uimanager.PixelUtil.dpToPx
@@ -20,37 +19,44 @@ import com.google.android.gms.maps.model.LatLng
20
19
  import com.google.android.gms.maps.model.PolylineOptions
21
20
  import com.luggmaps.core.PolylineAnimator
22
21
 
23
- interface LuggMapsGoogleMapViewEventDelegate {
22
+ interface LuggGoogleMapViewEventDelegate {
24
23
  fun onCameraMove(
25
- view: LuggMapsGoogleMapView,
24
+ view: LuggGoogleMapView,
26
25
  latitude: Double,
27
26
  longitude: Double,
28
27
  zoom: Float,
29
- dragging: Boolean
28
+ gesture: Boolean
30
29
  )
31
- fun onCameraIdle(view: LuggMapsGoogleMapView, latitude: Double, longitude: Double, zoom: Float)
30
+ fun onCameraIdle(
31
+ view: LuggGoogleMapView,
32
+ latitude: Double,
33
+ longitude: Double,
34
+ zoom: Float,
35
+ gesture: Boolean
36
+ )
37
+ fun onReady(view: LuggGoogleMapView)
32
38
  }
33
39
 
34
40
  @SuppressLint("ViewConstructor")
35
- class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
41
+ class LuggGoogleMapView(private val reactContext: ThemedReactContext) :
36
42
  ReactViewGroup(reactContext),
37
43
  OnMapReadyCallback,
38
- LuggMapsMarkerViewDelegate,
39
- LuggMapsPolylineViewDelegate,
44
+ LuggMarkerViewDelegate,
45
+ LuggPolylineViewDelegate,
40
46
  GoogleMap.OnCameraMoveStartedListener,
41
47
  GoogleMap.OnCameraMoveListener,
42
48
  GoogleMap.OnCameraIdleListener {
43
49
 
44
- var eventDelegate: LuggMapsGoogleMapViewEventDelegate? = null
50
+ var eventDelegate: LuggGoogleMapViewEventDelegate? = null
45
51
  private var mapView: MapView? = null
46
- private var mapWrapperView: LuggMapsWrapperView? = null
52
+ private var mapWrapperView: LuggMapWrapperView? = null
47
53
  private var googleMap: GoogleMap? = null
48
54
  private var isMapReady = false
49
55
  private var isDragging = false
50
56
  private var mapId: String = DEMO_MAP_ID
51
- private val pendingMarkerViews = mutableListOf<LuggMapsMarkerView>()
52
- private val pendingPolylineViews = mutableListOf<LuggMapsPolylineView>()
53
- private val polylineAnimators = mutableMapOf<LuggMapsPolylineView, PolylineAnimator>()
57
+ private val pendingMarkerViews = mutableListOf<LuggMarkerView>()
58
+ private val pendingPolylineViews = mutableListOf<LuggPolylineView>()
59
+ private val polylineAnimators = mutableMapOf<LuggPolylineView, PolylineAnimator>()
54
60
 
55
61
  // Initial camera settings
56
62
  private var initialLatitude: Double = 37.78
@@ -62,6 +68,11 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
62
68
  private var scrollEnabled: Boolean = true
63
69
  private var rotateEnabled: Boolean = true
64
70
  private var pitchEnabled: Boolean = true
71
+ private var userLocationEnabled: Boolean = false
72
+
73
+ // Zoom limits
74
+ private var minZoom: Float? = null
75
+ private var maxZoom: Float? = null
65
76
 
66
77
  // Padding
67
78
  private var paddingTop: Int = 0
@@ -74,14 +85,14 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
74
85
  override fun addView(child: View?, index: Int) {
75
86
  super.addView(child, index)
76
87
  when (child) {
77
- is LuggMapsWrapperView -> mapWrapperView = child
88
+ is LuggMapWrapperView -> mapWrapperView = child
78
89
 
79
- is LuggMapsMarkerView -> {
90
+ is LuggMarkerView -> {
80
91
  child.delegate = this
81
92
  syncMarkerView(child)
82
93
  }
83
94
 
84
- is LuggMapsPolylineView -> {
95
+ is LuggPolylineView -> {
85
96
  child.delegate = this
86
97
  syncPolylineView(child)
87
98
  }
@@ -90,11 +101,10 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
90
101
 
91
102
  override fun removeViewAt(index: Int) {
92
103
  val view = getChildAt(index)
93
- if (view is LuggMapsMarkerView) {
94
- Log.d(TAG, "removing markerView: ${view.name}")
104
+ if (view is LuggMarkerView) {
95
105
  view.marker?.remove()
96
106
  view.marker = null
97
- } else if (view is LuggMapsPolylineView) {
107
+ } else if (view is LuggPolylineView) {
98
108
  polylineAnimators[view]?.destroy()
99
109
  polylineAnimators.remove(view)
100
110
  view.polyline?.remove()
@@ -111,7 +121,6 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
111
121
  }
112
122
 
113
123
  fun onDropViewInstance() {
114
- Log.d(TAG, "dropping mapView instance")
115
124
  pendingMarkerViews.clear()
116
125
  pendingPolylineViews.clear()
117
126
  polylineAnimators.values.forEach { it.destroy() }
@@ -156,9 +165,13 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
156
165
  map.setOnCameraIdleListener(this)
157
166
 
158
167
  applyUiSettings()
168
+ applyZoomLimits()
159
169
  applyPadding()
170
+ applyUserLocation()
160
171
  processPendingMarkers()
161
172
  processPendingPolylines()
173
+
174
+ eventDelegate?.onReady(this)
162
175
  }
163
176
 
164
177
  override fun onCameraMoveStarted(reason: Int) {
@@ -174,8 +187,8 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
174
187
  override fun onCameraIdle() {
175
188
  val map = googleMap ?: return
176
189
  val position = map.cameraPosition
190
+ eventDelegate?.onCameraIdle(this, position.target.latitude, position.target.longitude, position.zoom, isDragging)
177
191
  isDragging = false
178
- eventDelegate?.onCameraIdle(this, position.target.latitude, position.target.longitude, position.zoom)
179
192
  }
180
193
 
181
194
  private fun applyUiSettings() {
@@ -187,15 +200,33 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
187
200
  }
188
201
  }
189
202
 
203
+ private fun applyZoomLimits() {
204
+ googleMap?.apply {
205
+ minZoom?.let { setMinZoomPreference(it) }
206
+ maxZoom?.let { setMaxZoomPreference(it) }
207
+ }
208
+ }
209
+
190
210
  private fun applyPadding() {
191
211
  googleMap?.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
192
212
  }
193
213
 
214
+ @SuppressLint("MissingPermission")
215
+ private fun applyUserLocation() {
216
+ val hasPermission =
217
+ context.checkSelfPermission(
218
+ android.Manifest.permission.ACCESS_FINE_LOCATION
219
+ ) == android.content.pm.PackageManager.PERMISSION_GRANTED ||
220
+ context.checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
221
+ android.content.pm.PackageManager.PERMISSION_GRANTED
222
+ googleMap?.isMyLocationEnabled = userLocationEnabled && hasPermission
223
+ }
224
+
194
225
  // endregion
195
226
 
196
227
  // region PolylineViewDelegate
197
228
 
198
- override fun polylineViewDidUpdate(polylineView: LuggMapsPolylineView) {
229
+ override fun polylineViewDidUpdate(polylineView: LuggPolylineView) {
199
230
  syncPolylineView(polylineView)
200
231
  }
201
232
 
@@ -203,7 +234,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
203
234
 
204
235
  // region MarkerViewDelegate
205
236
 
206
- override fun markerViewDidLayout(markerView: LuggMapsMarkerView) {
237
+ override fun markerViewDidLayout(markerView: LuggMarkerView) {
207
238
  if (googleMap == null) {
208
239
  if (!pendingMarkerViews.contains(markerView)) {
209
240
  pendingMarkerViews.add(markerView)
@@ -220,7 +251,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
220
251
  }
221
252
  }
222
253
 
223
- override fun markerViewDidUpdate(markerView: LuggMapsMarkerView) {
254
+ override fun markerViewDidUpdate(markerView: LuggMarkerView) {
224
255
  syncMarkerView(markerView)
225
256
  }
226
257
 
@@ -228,7 +259,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
228
259
 
229
260
  // region Marker Management
230
261
 
231
- private fun syncMarkerView(markerView: LuggMapsMarkerView) {
262
+ private fun syncMarkerView(markerView: LuggMarkerView) {
232
263
  if (googleMap == null) {
233
264
  if (!pendingMarkerViews.contains(markerView)) {
234
265
  pendingMarkerViews.add(markerView)
@@ -248,6 +279,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
248
279
  title = markerView.title
249
280
  snippet = markerView.description
250
281
  setAnchor(markerView.anchorX, markerView.anchorY)
282
+ zIndex = markerView.zIndex
251
283
  if (!markerView.hasCustomView) {
252
284
  iconView = null
253
285
  }
@@ -257,14 +289,13 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
257
289
  private fun processPendingMarkers() {
258
290
  if (googleMap == null) return
259
291
 
260
- Log.d(TAG, "processing pending markers ${pendingMarkerViews.size}")
261
292
  pendingMarkerViews.forEach { addMarkerViewToMap(it) }
262
293
  pendingMarkerViews.clear()
263
294
  }
264
295
 
265
- private fun addMarkerViewToMap(markerView: LuggMapsMarkerView) {
296
+ private fun addMarkerViewToMap(markerView: LuggMarkerView) {
266
297
  val map = googleMap ?: run {
267
- RNLog.w(reactContext, "LuggMaps: addMarkerViewToMap called without a map")
298
+ RNLog.w(reactContext, "Lugg: addMarkerViewToMap called without a map")
268
299
  return
269
300
  }
270
301
 
@@ -277,15 +308,14 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
277
308
  .position(position)
278
309
  .title(markerView.title)
279
310
  .snippet(markerView.description)
280
- .collisionBehavior(CollisionBehavior.REQUIRED)
281
311
 
282
- Log.d(TAG, "adding marker: ${markerView.name} customview: ${markerView.hasCustomView}")
283
312
  if (markerView.hasCustomView) {
284
313
  options.iconView(iconView)
285
314
  }
286
315
 
287
316
  val marker = map.addMarker(options) as AdvancedMarker
288
317
  marker.setAnchor(markerView.anchorX, markerView.anchorY)
318
+ marker.zIndex = markerView.zIndex
289
319
 
290
320
  markerView.marker = marker
291
321
  }
@@ -294,7 +324,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
294
324
 
295
325
  // region Polyline Management
296
326
 
297
- private fun syncPolylineView(polylineView: LuggMapsPolylineView) {
327
+ private fun syncPolylineView(polylineView: LuggPolylineView) {
298
328
  if (googleMap == null) {
299
329
  if (!pendingPolylineViews.contains(polylineView)) {
300
330
  pendingPolylineViews.add(polylineView)
@@ -308,6 +338,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
308
338
  }
309
339
 
310
340
  polylineView.polyline?.width = polylineView.strokeWidth.dpToPx()
341
+ polylineView.polyline?.zIndex = polylineView.zIndex
311
342
 
312
343
  polylineAnimators[polylineView]?.apply {
313
344
  coordinates = polylineView.coordinates
@@ -325,11 +356,12 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
325
356
  pendingPolylineViews.clear()
326
357
  }
327
358
 
328
- private fun addPolylineViewToMap(polylineView: LuggMapsPolylineView) {
359
+ private fun addPolylineViewToMap(polylineView: LuggPolylineView) {
329
360
  val map = googleMap ?: return
330
361
 
331
362
  val options = PolylineOptions()
332
363
  .width(polylineView.strokeWidth.dpToPx())
364
+ .zIndex(polylineView.zIndex)
333
365
 
334
366
  val polyline = map.addPolyline(options)
335
367
  polylineView.polyline = polyline
@@ -354,7 +386,7 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
354
386
  if (value.isNullOrEmpty()) return
355
387
 
356
388
  if (mapView != null) {
357
- RNLog.w(reactContext, "LuggMaps: mapId cannot be changed after map is initialized")
389
+ RNLog.w(reactContext, "Lugg: mapId cannot be changed after map is initialized")
358
390
  return
359
391
  }
360
392
 
@@ -390,6 +422,25 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
390
422
  googleMap?.uiSettings?.isTiltGesturesEnabled = enabled
391
423
  }
392
424
 
425
+ fun setUserLocationEnabled(enabled: Boolean) {
426
+ userLocationEnabled = enabled
427
+ applyUserLocation()
428
+ }
429
+
430
+ fun setMinZoom(zoom: Double) {
431
+ minZoom = if (zoom > 0) zoom.toFloat() else null
432
+ googleMap?.let { map ->
433
+ minZoom?.let { map.setMinZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
434
+ }
435
+ }
436
+
437
+ fun setMaxZoom(zoom: Double) {
438
+ maxZoom = if (zoom > 0) zoom.toFloat() else null
439
+ googleMap?.let { map ->
440
+ maxZoom?.let { map.setMaxZoomPreference(it) } ?: map.resetMinMaxZoomPreference()
441
+ }
442
+ }
443
+
393
444
  fun setMapPadding(top: Int, left: Int, bottom: Int, right: Int) {
394
445
  paddingTop = top
395
446
  paddingLeft = left
@@ -413,7 +464,14 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
413
464
  }
414
465
  }
415
466
 
416
- fun fitCoordinates(coordinates: List<LatLng>, padding: Int, duration: Int) {
467
+ fun fitCoordinates(
468
+ coordinates: List<LatLng>,
469
+ paddingTop: Int,
470
+ paddingLeft: Int,
471
+ paddingBottom: Int,
472
+ paddingRight: Int,
473
+ duration: Int
474
+ ) {
417
475
  val map = googleMap ?: return
418
476
  if (coordinates.isEmpty()) return
419
477
 
@@ -421,18 +479,35 @@ class LuggMapsGoogleMapView(private val reactContext: ThemedReactContext) :
421
479
  coordinates.forEach { boundsBuilder.include(it) }
422
480
  val bounds = boundsBuilder.build()
423
481
 
424
- val cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padding.toFloat().dpToPx().toInt())
482
+ val top = paddingTop.toFloat().dpToPx().toInt()
483
+ val left = paddingLeft.toFloat().dpToPx().toInt()
484
+ val bottom = paddingBottom.toFloat().dpToPx().toInt()
485
+ val right = paddingRight.toFloat().dpToPx().toInt()
486
+
487
+ // Set padding before camera update, then restore after
488
+ map.setPadding(
489
+ this.paddingLeft + left,
490
+ this.paddingTop + top,
491
+ this.paddingRight + right,
492
+ this.paddingBottom + bottom
493
+ )
494
+
495
+ val cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 0)
496
+
425
497
  when {
426
498
  duration < 0 -> map.animateCamera(cameraUpdate)
427
499
  duration > 0 -> map.animateCamera(cameraUpdate, duration, null)
428
500
  else -> map.moveCamera(cameraUpdate)
429
501
  }
502
+
503
+ // Restore base padding
504
+ map.setPadding(this.paddingLeft, this.paddingTop, this.paddingRight, this.paddingBottom)
430
505
  }
431
506
 
432
507
  // endregion
433
508
 
434
509
  companion object {
435
- private const val TAG = "LuggMaps"
510
+ private const val TAG = "Lugg"
436
511
  const val DEMO_MAP_ID = "DEMO_MAP_ID"
437
512
  }
438
513
  }
@@ -5,29 +5,30 @@ import com.facebook.react.bridge.ReadableMap
5
5
  import com.facebook.react.module.annotations.ReactModule
6
6
  import com.facebook.react.uimanager.PixelUtil.dpToPx
7
7
  import com.facebook.react.uimanager.ThemedReactContext
8
- import com.facebook.react.uimanager.UIManagerHelper
9
8
  import com.facebook.react.uimanager.ViewGroupManager
10
9
  import com.facebook.react.uimanager.ViewManagerDelegate
11
10
  import com.facebook.react.uimanager.annotations.ReactProp
12
- import com.facebook.react.viewmanagers.LuggMapsGoogleMapViewManagerDelegate
13
- import com.facebook.react.viewmanagers.LuggMapsGoogleMapViewManagerInterface
11
+ import com.facebook.react.viewmanagers.LuggGoogleMapViewManagerDelegate
12
+ import com.facebook.react.viewmanagers.LuggGoogleMapViewManagerInterface
14
13
  import com.google.android.gms.maps.model.LatLng
15
14
  import com.luggmaps.events.CameraIdleEvent
16
15
  import com.luggmaps.events.CameraMoveEvent
16
+ import com.luggmaps.events.ReadyEvent
17
+ import com.luggmaps.extensions.dispatchEvent
17
18
 
18
- @ReactModule(name = LuggMapsGoogleMapViewManager.NAME)
19
- class LuggMapsGoogleMapViewManager :
20
- ViewGroupManager<LuggMapsGoogleMapView>(),
21
- LuggMapsGoogleMapViewManagerInterface<LuggMapsGoogleMapView>,
22
- LuggMapsGoogleMapViewEventDelegate {
23
- private val delegate: ViewManagerDelegate<LuggMapsGoogleMapView> = LuggMapsGoogleMapViewManagerDelegate(this)
19
+ @ReactModule(name = LuggGoogleMapViewManager.NAME)
20
+ class LuggGoogleMapViewManager :
21
+ ViewGroupManager<LuggGoogleMapView>(),
22
+ LuggGoogleMapViewManagerInterface<LuggGoogleMapView>,
23
+ LuggGoogleMapViewEventDelegate {
24
+ private val delegate: ViewManagerDelegate<LuggGoogleMapView> = LuggGoogleMapViewManagerDelegate(this)
24
25
 
25
- override fun getDelegate(): ViewManagerDelegate<LuggMapsGoogleMapView> = delegate
26
+ override fun getDelegate(): ViewManagerDelegate<LuggGoogleMapView> = delegate
26
27
 
27
28
  override fun getName(): String = NAME
28
29
 
29
- override fun createViewInstance(context: ThemedReactContext): LuggMapsGoogleMapView {
30
- val view = LuggMapsGoogleMapView(context)
30
+ override fun createViewInstance(context: ThemedReactContext): LuggGoogleMapView {
31
+ val view = LuggGoogleMapView(context)
31
32
  view.eventDelegate = this
32
33
  return view
33
34
  }
@@ -35,38 +36,41 @@ class LuggMapsGoogleMapViewManager :
35
36
  override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> =
36
37
  mapOf(
37
38
  "topCameraMove" to mapOf("registrationName" to "onCameraMove"),
38
- "topCameraIdle" to mapOf("registrationName" to "onCameraIdle")
39
+ "topCameraIdle" to mapOf("registrationName" to "onCameraIdle"),
40
+ "topReady" to mapOf("registrationName" to "onReady")
39
41
  )
40
42
 
41
43
  override fun onCameraMove(
42
- view: LuggMapsGoogleMapView,
44
+ view: LuggGoogleMapView,
43
45
  latitude: Double,
44
46
  longitude: Double,
45
47
  zoom: Float,
46
- dragging: Boolean
48
+ gesture: Boolean
47
49
  ) {
48
- val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(
49
- view.context as ThemedReactContext,
50
- view.id
51
- )
52
- eventDispatcher?.dispatchEvent(CameraMoveEvent(UIManagerHelper.getSurfaceId(view), view.id, latitude, longitude, zoom, dragging))
50
+ view.dispatchEvent(CameraMoveEvent(view, latitude, longitude, zoom, gesture))
53
51
  }
54
52
 
55
- override fun onCameraIdle(view: LuggMapsGoogleMapView, latitude: Double, longitude: Double, zoom: Float) {
56
- val eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(
57
- view.context as ThemedReactContext,
58
- view.id
59
- )
60
- eventDispatcher?.dispatchEvent(CameraIdleEvent(UIManagerHelper.getSurfaceId(view), view.id, latitude, longitude, zoom))
53
+ override fun onCameraIdle(
54
+ view: LuggGoogleMapView,
55
+ latitude: Double,
56
+ longitude: Double,
57
+ zoom: Float,
58
+ gesture: Boolean
59
+ ) {
60
+ view.dispatchEvent(CameraIdleEvent(view, latitude, longitude, zoom, gesture))
61
+ }
62
+
63
+ override fun onReady(view: LuggGoogleMapView) {
64
+ view.dispatchEvent(ReadyEvent(view))
61
65
  }
62
66
 
63
67
  @ReactProp(name = "mapId")
64
- override fun setMapId(view: LuggMapsGoogleMapView, value: String?) {
68
+ override fun setMapId(view: LuggGoogleMapView, value: String?) {
65
69
  view.setMapId(value)
66
70
  }
67
71
 
68
72
  @ReactProp(name = "initialCoordinate")
69
- override fun setInitialCoordinate(view: LuggMapsGoogleMapView, value: ReadableMap?) {
73
+ override fun setInitialCoordinate(view: LuggGoogleMapView, value: ReadableMap?) {
70
74
  value?.let {
71
75
  val latitude = if (it.hasKey("latitude")) it.getDouble("latitude") else 0.0
72
76
  val longitude = if (it.hasKey("longitude")) it.getDouble("longitude") else 0.0
@@ -75,32 +79,47 @@ class LuggMapsGoogleMapViewManager :
75
79
  }
76
80
 
77
81
  @ReactProp(name = "initialZoom", defaultDouble = 10.0)
78
- override fun setInitialZoom(view: LuggMapsGoogleMapView, value: Double) {
82
+ override fun setInitialZoom(view: LuggGoogleMapView, value: Double) {
79
83
  view.setInitialZoom(value)
80
84
  }
81
85
 
82
86
  @ReactProp(name = "zoomEnabled", defaultBoolean = true)
83
- override fun setZoomEnabled(view: LuggMapsGoogleMapView, value: Boolean) {
87
+ override fun setZoomEnabled(view: LuggGoogleMapView, value: Boolean) {
84
88
  view.setZoomEnabled(value)
85
89
  }
86
90
 
87
91
  @ReactProp(name = "scrollEnabled", defaultBoolean = true)
88
- override fun setScrollEnabled(view: LuggMapsGoogleMapView, value: Boolean) {
92
+ override fun setScrollEnabled(view: LuggGoogleMapView, value: Boolean) {
89
93
  view.setScrollEnabled(value)
90
94
  }
91
95
 
92
96
  @ReactProp(name = "rotateEnabled", defaultBoolean = true)
93
- override fun setRotateEnabled(view: LuggMapsGoogleMapView, value: Boolean) {
97
+ override fun setRotateEnabled(view: LuggGoogleMapView, value: Boolean) {
94
98
  view.setRotateEnabled(value)
95
99
  }
96
100
 
97
101
  @ReactProp(name = "pitchEnabled", defaultBoolean = true)
98
- override fun setPitchEnabled(view: LuggMapsGoogleMapView, value: Boolean) {
102
+ override fun setPitchEnabled(view: LuggGoogleMapView, value: Boolean) {
99
103
  view.setPitchEnabled(value)
100
104
  }
101
105
 
106
+ @ReactProp(name = "userLocationEnabled", defaultBoolean = false)
107
+ override fun setUserLocationEnabled(view: LuggGoogleMapView, value: Boolean) {
108
+ view.setUserLocationEnabled(value)
109
+ }
110
+
111
+ @ReactProp(name = "minZoom")
112
+ override fun setMinZoom(view: LuggGoogleMapView, value: Double) {
113
+ view.setMinZoom(value)
114
+ }
115
+
116
+ @ReactProp(name = "maxZoom")
117
+ override fun setMaxZoom(view: LuggGoogleMapView, value: Double) {
118
+ view.setMaxZoom(value)
119
+ }
120
+
102
121
  @ReactProp(name = "padding")
103
- override fun setPadding(view: LuggMapsGoogleMapView, value: ReadableMap?) {
122
+ override fun setPadding(view: LuggGoogleMapView, value: ReadableMap?) {
104
123
  value?.let {
105
124
  val top = if (it.hasKey("top")) it.getDouble("top").toFloat().dpToPx().toInt() else 0
106
125
  val left = if (it.hasKey("left")) it.getDouble("left").toFloat().dpToPx().toInt() else 0
@@ -110,13 +129,13 @@ class LuggMapsGoogleMapViewManager :
110
129
  }
111
130
  }
112
131
 
113
- override fun onDropViewInstance(view: LuggMapsGoogleMapView) {
132
+ override fun onDropViewInstance(view: LuggGoogleMapView) {
114
133
  super.onDropViewInstance(view)
115
134
  view.onDropViewInstance()
116
135
  }
117
136
 
118
137
  override fun moveCamera(
119
- view: LuggMapsGoogleMapView,
138
+ view: LuggGoogleMapView,
120
139
  latitude: Double,
121
140
  longitude: Double,
122
141
  zoom: Double,
@@ -125,7 +144,15 @@ class LuggMapsGoogleMapViewManager :
125
144
  view.moveCamera(latitude, longitude, zoom, duration.toInt())
126
145
  }
127
146
 
128
- override fun fitCoordinates(view: LuggMapsGoogleMapView, coordinates: ReadableArray?, padding: Double, duration: Double) {
147
+ override fun fitCoordinates(
148
+ view: LuggGoogleMapView,
149
+ coordinates: ReadableArray?,
150
+ paddingTop: Double,
151
+ paddingLeft: Double,
152
+ paddingBottom: Double,
153
+ paddingRight: Double,
154
+ duration: Double
155
+ ) {
129
156
  val coords = mutableListOf<LatLng>()
130
157
  coordinates?.let {
131
158
  for (i in 0 until it.size()) {
@@ -135,10 +162,10 @@ class LuggMapsGoogleMapViewManager :
135
162
  coords.add(LatLng(lat, lng))
136
163
  }
137
164
  }
138
- view.fitCoordinates(coords, padding.toInt(), duration.toInt())
165
+ view.fitCoordinates(coords, paddingTop.toInt(), paddingLeft.toInt(), paddingBottom.toInt(), paddingRight.toInt(), duration.toInt())
139
166
  }
140
167
 
141
168
  companion object {
142
- const val NAME = "LuggMapsGoogleMapView"
169
+ const val NAME = "LuggGoogleMapView"
143
170
  }
144
171
  }
@@ -5,7 +5,7 @@ import com.facebook.react.uimanager.ThemedReactContext
5
5
  import com.facebook.react.views.view.ReactViewGroup
6
6
 
7
7
  @SuppressLint("ViewConstructor")
8
- class LuggMapsWrapperView(context: ThemedReactContext) : ReactViewGroup(context) {
8
+ class LuggMapWrapperView(context: ThemedReactContext) : ReactViewGroup(context) {
9
9
 
10
10
  override fun requestLayout() {
11
11
  super.requestLayout()
@@ -0,0 +1,25 @@
1
+ package com.luggmaps
2
+
3
+ import com.facebook.react.module.annotations.ReactModule
4
+ import com.facebook.react.uimanager.ThemedReactContext
5
+ import com.facebook.react.uimanager.ViewGroupManager
6
+ import com.facebook.react.uimanager.ViewManagerDelegate
7
+ import com.facebook.react.viewmanagers.LuggMapWrapperViewManagerDelegate
8
+ import com.facebook.react.viewmanagers.LuggMapWrapperViewManagerInterface
9
+
10
+ @ReactModule(name = LuggMapWrapperViewManager.NAME)
11
+ class LuggMapWrapperViewManager :
12
+ ViewGroupManager<LuggMapWrapperView>(),
13
+ LuggMapWrapperViewManagerInterface<LuggMapWrapperView> {
14
+ private val delegate: ViewManagerDelegate<LuggMapWrapperView> = LuggMapWrapperViewManagerDelegate(this)
15
+
16
+ override fun getDelegate(): ViewManagerDelegate<LuggMapWrapperView> = delegate
17
+
18
+ override fun getName(): String = NAME
19
+
20
+ override fun createViewInstance(context: ThemedReactContext): LuggMapWrapperView = LuggMapWrapperView(context)
21
+
22
+ companion object {
23
+ const val NAME = "LuggMapWrapperView"
24
+ }
25
+ }
@@ -1,18 +1,17 @@
1
1
  package com.luggmaps
2
2
 
3
3
  import android.content.Context
4
- import android.util.Log
5
4
  import android.view.View
6
5
  import androidx.core.view.isNotEmpty
7
6
  import com.facebook.react.views.view.ReactViewGroup
8
7
  import com.google.android.gms.maps.model.AdvancedMarker
9
8
 
10
- interface LuggMapsMarkerViewDelegate {
11
- fun markerViewDidUpdate(markerView: LuggMapsMarkerView)
12
- fun markerViewDidLayout(markerView: LuggMapsMarkerView)
9
+ interface LuggMarkerViewDelegate {
10
+ fun markerViewDidUpdate(markerView: LuggMarkerView)
11
+ fun markerViewDidLayout(markerView: LuggMarkerView)
13
12
  }
14
13
 
15
- class LuggMapsMarkerView(context: Context) : ReactViewGroup(context) {
14
+ class LuggMarkerView(context: Context) : ReactViewGroup(context) {
16
15
  var name: String? = null
17
16
  private set
18
17
 
@@ -26,7 +25,7 @@ class LuggMapsMarkerView(context: Context) : ReactViewGroup(context) {
26
25
  var description: String? = null
27
26
  private set
28
27
 
29
- var delegate: LuggMapsMarkerViewDelegate? = null
28
+ var delegate: LuggMarkerViewDelegate? = null
30
29
  var marker: AdvancedMarker? = null
31
30
 
32
31
  var anchorX: Float = 0.5f
@@ -34,6 +33,9 @@ class LuggMapsMarkerView(context: Context) : ReactViewGroup(context) {
34
33
  var anchorY: Float = 1.0f
35
34
  private set
36
35
 
36
+ var zIndex: Float = 0f
37
+ private set
38
+
37
39
  var didLayout: Boolean = false
38
40
  private set
39
41
 
@@ -114,6 +116,10 @@ class LuggMapsMarkerView(context: Context) : ReactViewGroup(context) {
114
116
  anchorY = y.toFloat()
115
117
  }
116
118
 
119
+ fun setZIndex(zIndex: Float) {
120
+ this.zIndex = zIndex
121
+ }
122
+
117
123
  fun setName(name: String?) {
118
124
  this.name = name
119
125
  }
@@ -129,6 +135,6 @@ class LuggMapsMarkerView(context: Context) : ReactViewGroup(context) {
129
135
  }
130
136
 
131
137
  companion object {
132
- private const val TAG = "LuggMaps"
138
+ private const val TAG = "Lugg"
133
139
  }
134
140
  }