Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
concurrency:
group: release-${{ github.ref_name }}
cancel-in-progress: true

permissions:
contents: read

Expand Down
25 changes: 15 additions & 10 deletions PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,39 @@ CI already runs linting, formatting, and build checks automatically.
---

### Summary

Short description of what this PR changes or adds.

---

### Type of change
- [ ] Feature
- [ ] Fix
- [ ] Refactor
- [ ] Internal / CI
- [ ] Documentation

- [ ] Feature
- [ ] Fix
- [ ] Refactor
- [ ] Internal / CI
- [ ] Documentation

---

### Scope
- [ ] Android
- [ ] iOS
- [ ] Core
- [ ] Example App
- [ ] Docs

- [ ] Android
- [ ] iOS
- [ ] Core
- [ ] Example App
- [ ] Docs

---

### Related

List any related issues, pull requests, or discussions.
Use the format:
`Fixes #123`, `Refs #456`, `Close #789`

---

### Additional notes

_(Optional – anything relevant for the reviewer)_
139 changes: 37 additions & 102 deletions android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,9 @@ class GoogleMapsViewImpl(
userInterfaceStyle?.let {
googleMap?.mapColorScheme = it
}
minZoomLevel?.let {
googleMap?.setMinZoomPreference(it.toFloat())
}
maxZoomLevel?.let {
googleMap?.setMaxZoomPreference(it.toFloat())
mapZoomConfig?.let {
googleMap?.setMinZoomPreference(it.min?.toFloat() ?: 2.0f)
googleMap?.setMaxZoomPreference(it.max?.toFloat() ?: 21.0f)
}
}

Expand Down Expand Up @@ -340,56 +338,34 @@ class GoogleMapsViewImpl(
set(value) {
field = value
onUi {
value?.let { v ->
googleMap?.uiSettings?.apply {
v.allGesturesEnabled?.let { setAllGesturesEnabled(it) }
v.compassEnabled?.let { isCompassEnabled = it }
v.indoorLevelPickerEnabled?.let { isIndoorLevelPickerEnabled = it }
v.mapToolbarEnabled?.let { isMapToolbarEnabled = it }
v.myLocationButtonEnabled?.let {
googleMap?.setLocationSource(locationHandler)
isMyLocationButtonEnabled = it
}
v.rotateEnabled?.let { isRotateGesturesEnabled = it }
v.scrollEnabled?.let { isScrollGesturesEnabled = it }
v.scrollDuringRotateOrZoomEnabled?.let {
isScrollGesturesEnabledDuringRotateOrZoom = it
}
v.tiltEnabled?.let { isTiltGesturesEnabled = it }
v.zoomControlsEnabled?.let { isZoomControlsEnabled = it }
v.zoomGesturesEnabled?.let { isZoomGesturesEnabled = it }
}
googleMap?.uiSettings?.apply {
setAllGesturesEnabled(value?.allGesturesEnabled ?: true)
isCompassEnabled = value?.compassEnabled ?: false
isIndoorLevelPickerEnabled = value?.indoorLevelPickerEnabled ?: false
isMapToolbarEnabled = value?.mapToolbarEnabled ?: false

val myLocationEnabled = value?.myLocationButtonEnabled ?: false
googleMap?.setLocationSource(if (myLocationEnabled) locationHandler else null)
isMyLocationButtonEnabled = myLocationEnabled

isRotateGesturesEnabled = value?.rotateEnabled ?: true
isScrollGesturesEnabled = value?.scrollEnabled ?: true
isScrollGesturesEnabledDuringRotateOrZoom =
value?.scrollDuringRotateOrZoomEnabled ?: true
isTiltGesturesEnabled = value?.tiltEnabled ?: true
isZoomControlsEnabled = value?.zoomControlsEnabled ?: false
isZoomGesturesEnabled = value?.zoomGesturesEnabled ?: false
}
?: run {
googleMap?.uiSettings?.apply {
setAllGesturesEnabled(true)
isCompassEnabled = false
isIndoorLevelPickerEnabled = false
isMapToolbarEnabled = false
isMyLocationButtonEnabled = false
googleMap?.setLocationSource(null)
isRotateGesturesEnabled = true
isScrollGesturesEnabled = true
isScrollGesturesEnabledDuringRotateOrZoom = true
isTiltGesturesEnabled = true
isZoomControlsEnabled = false
isZoomGesturesEnabled = false
}
}
}
}

@SuppressLint("MissingPermission")
var myLocationEnabled: Boolean? = null
set(value) {
field = value
onUi {
try {
value?.let {
googleMap?.isMyLocationEnabled = it
}
?: run {
googleMap?.isMyLocationEnabled = false
}
googleMap?.isMyLocationEnabled = value ?: false
} catch (se: SecurityException) {
onLocationError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
} catch (ex: Exception) {
Expand All @@ -403,37 +379,23 @@ class GoogleMapsViewImpl(
set(value) {
field = value
onUi {
value?.let {
googleMap?.isBuildingsEnabled = it
}
?: run {
googleMap?.isBuildingsEnabled = false
}
googleMap?.isBuildingsEnabled = value ?: false
}
}

var trafficEnabled: Boolean? = null
set(value) {
field = value
onUi {
value?.let {
googleMap?.isTrafficEnabled = it
} ?: run {
googleMap?.isTrafficEnabled = false
}
googleMap?.isTrafficEnabled = value ?: false
}
}

var indoorEnabled: Boolean? = null
set(value) {
field = value
onUi {
value?.let {
googleMap?.isIndoorEnabled = it
}
?: run {
googleMap?.isIndoorEnabled = false
}
googleMap?.isIndoorEnabled = value ?: false
}
}

Expand All @@ -449,64 +411,37 @@ class GoogleMapsViewImpl(
set(value) {
field = value
onUi {
value?.let {
googleMap?.mapColorScheme = it
} ?: run {
googleMap?.mapColorScheme = MapColorScheme.FOLLOW_SYSTEM
}
googleMap?.mapColorScheme = value ?: MapColorScheme.FOLLOW_SYSTEM
}
}

var minZoomLevel: Double? = null
var mapZoomConfig: RNMapZoomConfig? = null
set(value) {
field = value
onUi {
value?.let {
googleMap?.setMinZoomPreference(it.toFloat())
} ?: run {
googleMap?.setMinZoomPreference(2.0f)
}
}
}

var maxZoomLevel: Double? = null
set(value) {
field = value
onUi {
value?.let {
googleMap?.setMaxZoomPreference(it.toFloat())
} ?: run {
googleMap?.setMaxZoomPreference(21.0f)
}
googleMap?.setMinZoomPreference(value?.min?.toFloat() ?: 2.0f)
googleMap?.setMaxZoomPreference(value?.max?.toFloat() ?: 21.0f)
}
}

var mapPadding: RNMapPadding? = null
set(value) {
field = value
value?.let {
onUi {
googleMap?.setPadding(
it.left.dpToPx().toInt(),
it.top.dpToPx().toInt(),
it.right.dpToPx().toInt(),
it.bottom.dpToPx().toInt(),
)
}
} ?: run {
googleMap?.setPadding(0, 0, 0, 0)
onUi {
googleMap?.setPadding(
value?.left?.dpToPx()?.toInt() ?: 0,
value?.top?.dpToPx()?.toInt() ?: 0,
value?.right?.dpToPx()?.toInt() ?: 0,
value?.bottom?.dpToPx()?.toInt() ?: 0,
)
}
}

var mapType: Int? = null
set(value) {
field = value
onUi {
value?.let {
googleMap?.mapType = it
} ?: run {
googleMap?.mapType = 1
}
googleMap?.mapType = value ?: 1
}
}

Expand Down
6 changes: 3 additions & 3 deletions android/src/main/java/com/rngooglemapsplus/LocationHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ class LocationHandler(

var priority: Int? = PRIORITY_DEFAULT
set(value) {
field = value
field = value ?: PRIORITY_DEFAULT
start()
}

var interval: Long? = INTERVAL_DEFAULT
set(value) {
field = value
field = value ?: INTERVAL_DEFAULT
buildLocationRequest()
}

var minUpdateInterval: Long? = MIN_UPDATE_INTERVAL
set(value) {
field = value
field = value ?: MIN_UPDATE_INTERVAL
buildLocationRequest()
}

Expand Down
18 changes: 16 additions & 2 deletions android/src/main/java/com/rngooglemapsplus/MapCircleBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
package com.rngooglemapsplus

import android.graphics.Color
import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.google.android.gms.maps.model.Circle
import com.google.android.gms.maps.model.CircleOptions
import com.google.android.gms.maps.model.LatLng
import com.rngooglemapsplus.extensions.toColor

class MapCircleBuilder {
fun buildCircleOptions(circle: RNCircle): CircleOptions =
fun build(circle: RNCircle): CircleOptions =
CircleOptions().apply {
center(LatLng(circle.center.latitude, circle.center.longitude))
circle.radius?.let { radius(it) }
radius(circle.radius)
circle.strokeWidth?.let { strokeWidth(it.dpToPx()) }
circle.strokeColor?.let { strokeColor(it.toColor()) }
circle.fillColor?.let { fillColor(it.toColor()) }
circle.pressable?.let { clickable(it) }
circle.zIndex?.let { zIndex(it.toFloat()) }
}

fun update(
circle: Circle,
next: RNCircle,
) {
circle.center = LatLng(next.center.latitude, next.center.longitude)
circle.radius = next.radius
circle.strokeWidth = next.strokeWidth?.dpToPx() ?: 1f
circle.strokeColor = next.strokeColor?.toColor() ?: Color.BLACK
circle.fillColor = next.fillColor?.toColor() ?: Color.TRANSPARENT
circle.zIndex = next.zIndex?.toFloat() ?: 0f
}
}
25 changes: 25 additions & 0 deletions android/src/main/java/com/rngooglemapsplus/MapMarkerBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import com.facebook.react.uimanager.PixelUtil.dpToPx
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.rngooglemapsplus.extensions.markerStyleEquals
import com.rngooglemapsplus.extensions.styleHash
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -44,6 +46,29 @@ class MapMarkerBuilder(
m.zIndex?.let { zIndex(it.toFloat()) }
}

fun update(
marker: Marker,
prev: RNMarker,
next: RNMarker,
) {
marker.position =
LatLng(
next.coordinate.latitude,
next.coordinate.longitude,
)
marker.zIndex = next.zIndex?.toFloat() ?: 0f

if (!prev.markerStyleEquals(next)) {
buildIconAsync(marker.id, next) { icon ->
marker.setIcon(icon)
}
}
marker.setAnchor(
(next.anchor?.x ?: 0.5).toFloat(),
(next.anchor?.y ?: 0.5).toFloat(),
)
}

fun buildIconAsync(
id: String,
m: RNMarker,
Expand Down
Loading
Loading