Skip to content

Commit d9768d6

Browse files
authored
chore: merge dev into main
2 parents 33b57cf + 66ba52f commit d9768d6

38 files changed

+1642
-504
lines changed

.github/workflows/pull_request.yml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,7 @@ jobs:
105105
with:
106106
xcode-version: ${{ env.XCODE_VERSION }}
107107

108-
- name: Cache Pods
109-
id: pods-cache
110-
uses: actions/[email protected]
111-
with:
112-
path: example/ios/Pods
113-
key: ${{ runner.os }}-pods-${{ hashFiles('example/ios/Podfile', 'example/ios/Podfile.lock', 'example/package.json') }}
114-
restore-keys: |
115-
${{ runner.os }}-pods-
116-
117108
- name: Install cocoapods
118-
if: steps.pods-cache.outputs.cache-hit != 'true'
119109
working-directory: example
120110
run: yarn ios:pods
121111

CHANGELOG.md

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,6 @@
1717
* fix CHANGELOG.md ([2f2bb2c](https://github.com/pinpong/react-native-google-maps-plus/commit/2f2bb2c617260166551abbc07dfa9a8ae27cf31e))
1818
* merge dev into main ([a510e2a](https://github.com/pinpong/react-native-google-maps-plus/commit/a510e2a1bebabde03e319256b2a1246f10ce1b95))
1919

20-
## [1.2.0-dev.1](https://github.com/pinpong/react-native-google-maps-plus/compare/v1.1.0...v1.2.0-dev.1) (2025-10-09)
21-
22-
### ✨ Features
23-
24-
* add kml layer support ([4faf558](https://github.com/pinpong/react-native-google-maps-plus/commit/4faf558425831cc18a6e9c9e2d20ef0c4f42e702))
25-
* add kml layer support ([35098bd](https://github.com/pinpong/react-native-google-maps-plus/commit/35098bd4c75b825f96f58696cbb37a4fcdebbdb8))
26-
27-
### 🐛 Bug Fixes
28-
29-
* **example:** build issues ([cee0708](https://github.com/pinpong/react-native-google-maps-plus/commit/cee0708dfdee185ee4c8bb2836abd2a3c022fc93))
30-
31-
### 🛠️ Other changes
32-
33-
* **ci:** move PR template to root for auto-apply ([03e8a84](https://github.com/pinpong/react-native-google-maps-plus/commit/03e8a8438b0d5edab80fcdf2f2c8abf3372288c2))
34-
* **example:** beautify example app UI ([4f390ec](https://github.com/pinpong/react-native-google-maps-plus/commit/4f390ecd9ebc2f3e559913882ac56d33a30ac45b))
35-
* **example:** beautify example app UI ([73c997c](https://github.com/pinpong/react-native-google-maps-plus/commit/73c997c69f23deeb48eb9b2be5df76a36ff0afea))
36-
* fix CHANGELOG.md ([2f2bb2c](https://github.com/pinpong/react-native-google-maps-plus/commit/2f2bb2c617260166551abbc07dfa9a8ae27cf31e))
37-
3820
## [1.1.0](https://github.com/pinpong/react-native-google-maps-plus/compare/v1.0.2...v1.1.0) (2025-10-08)
3921

4022
### ✨ Features
@@ -78,18 +60,6 @@
7860
* update to react-native 0.82.0 ([31d5ff5](https://github.com/pinpong/react-native-google-maps-plus/commit/31d5ff5157ec8357b9d699d4dcc09bda09e11afb))
7961
* update to react-native 0.82.0 ([8c8e8ae](https://github.com/pinpong/react-native-google-maps-plus/commit/8c8e8ae1c4fcf97e04059d873461f083e4c346cf))
8062

81-
## [1.1.0-dev.5](https://github.com/pinpong/react-native-google-maps-plus/compare/v1.1.0-dev.4...v1.1.0-dev.5) (2025-10-08)
82-
83-
### 🐛 Bug Fixes
84-
85-
* **example:** build issues ([cee0708](https://github.com/pinpong/react-native-google-maps-plus/commit/cee0708dfdee185ee4c8bb2836abd2a3c022fc93))
86-
87-
### 🛠️ Other changes
88-
89-
* **example:** beautify example app UI ([4f390ec](https://github.com/pinpong/react-native-google-maps-plus/commit/4f390ecd9ebc2f3e559913882ac56d33a30ac45b))
90-
* **example:** beautify example app UI ([73c997c](https://github.com/pinpong/react-native-google-maps-plus/commit/73c997c69f23deeb48eb9b2be5df76a36ff0afea))
91-
* fix CHANGELOG.md ([2f2bb2c](https://github.com/pinpong/react-native-google-maps-plus/commit/2f2bb2c617260166551abbc07dfa9a8ae27cf31e))
92-
9363
## [1.1.0](https://github.com/pinpong/react-native-google-maps-plus/compare/v1.0.2...v1.1.0) (2025-10-08)
9464

9565
### ✨ Features

android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt

Lines changed: 149 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.rngooglemapsplus
22

33
import android.annotation.SuppressLint
4+
import android.graphics.Bitmap
45
import android.location.Location
6+
import android.util.Base64
7+
import android.util.Size
58
import android.widget.FrameLayout
9+
import androidx.core.graphics.scale
610
import com.facebook.react.bridge.LifecycleEventListener
711
import com.facebook.react.bridge.UiThreadUtil
812
import com.facebook.react.uimanager.PixelUtil.dpToPx
@@ -15,6 +19,7 @@ import com.google.android.gms.maps.MapView
1519
import com.google.android.gms.maps.model.CameraPosition
1620
import com.google.android.gms.maps.model.Circle
1721
import com.google.android.gms.maps.model.CircleOptions
22+
import com.google.android.gms.maps.model.IndoorBuilding
1823
import com.google.android.gms.maps.model.LatLng
1924
import com.google.android.gms.maps.model.LatLngBounds
2025
import com.google.android.gms.maps.model.MapColorScheme
@@ -28,9 +33,15 @@ import com.google.android.gms.maps.model.PolylineOptions
2833
import com.google.android.gms.maps.model.TileOverlay
2934
import com.google.android.gms.maps.model.TileOverlayOptions
3035
import com.google.maps.android.data.kml.KmlLayer
36+
import com.margelo.nitro.core.Promise
3137
import com.rngooglemapsplus.extensions.toGooglePriority
3238
import com.rngooglemapsplus.extensions.toLocationErrorCode
39+
import com.rngooglemapsplus.extensions.toRNIndoorBuilding
40+
import com.rngooglemapsplus.extensions.toRNIndoorLevel
3341
import java.io.ByteArrayInputStream
42+
import java.io.ByteArrayOutputStream
43+
import java.io.File
44+
import java.io.FileOutputStream
3445
import java.nio.charset.StandardCharsets
3546

3647
class GoogleMapsViewImpl(
@@ -47,6 +58,8 @@ class GoogleMapsViewImpl(
4758
GoogleMap.OnPolylineClickListener,
4859
GoogleMap.OnPolygonClickListener,
4960
GoogleMap.OnCircleClickListener,
61+
GoogleMap.OnMarkerDragListener,
62+
GoogleMap.OnIndoorStateChangeListener,
5063
LifecycleEventListener {
5164
private var initialized = false
5265
private var mapReady = false
@@ -136,12 +149,13 @@ class GoogleMapsViewImpl(
136149
googleMap?.setOnPolygonClickListener(this@GoogleMapsViewImpl)
137150
googleMap?.setOnCircleClickListener(this@GoogleMapsViewImpl)
138151
googleMap?.setOnMapClickListener(this@GoogleMapsViewImpl)
152+
googleMap?.setOnMarkerDragListener(this@GoogleMapsViewImpl)
139153
}
140154
initLocationCallbacks()
141155
applyPending()
156+
mapReady = true
157+
onMapReady?.invoke(true)
142158
}
143-
mapReady = true
144-
onMapReady?.invoke(true)
145159
}
146160

147161
override fun onCameraMoveStarted(reason: Int) {
@@ -182,6 +196,8 @@ class GoogleMapsViewImpl(
182196
if (cameraPosition == lastSubmittedCameraPosition) {
183197
return
184198
}
199+
lastSubmittedCameraPosition = cameraPosition
200+
185201
val isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason
186202

187203
val latDelta = bounds.northeast.latitude - bounds.southwest.latitude
@@ -201,7 +217,6 @@ class GoogleMapsViewImpl(
201217
),
202218
isGesture,
203219
)
204-
lastSubmittedCameraPosition = cameraPosition
205220
}
206221

207222
override fun onCameraIdle() {
@@ -357,6 +372,8 @@ class GoogleMapsViewImpl(
357372
}
358373
}
359374

375+
var initialProps: RNInitialProps? = null
376+
360377
var uiSettings: RNMapUiSettings? = null
361378
set(value) {
362379
field = value
@@ -481,18 +498,23 @@ class GoogleMapsViewImpl(
481498
var onLocationUpdate: ((RNLocation) -> Unit)? = null
482499
var onLocationError: ((RNLocationErrorCode) -> Unit)? = null
483500
var onMapPress: ((RNLatLng) -> Unit)? = null
484-
var onMarkerPress: ((String) -> Unit)? = null
485-
var onPolylinePress: ((String) -> Unit)? = null
486-
var onPolygonPress: ((String) -> Unit)? = null
487-
var onCirclePress: ((String) -> Unit)? = null
501+
var onMarkerPress: ((String?) -> Unit)? = null
502+
var onPolylinePress: ((String?) -> Unit)? = null
503+
var onPolygonPress: ((String?) -> Unit)? = null
504+
var onCirclePress: ((String?) -> Unit)? = null
505+
var onMarkerDragStart: ((String?, RNLatLng) -> Unit)? = null
506+
var onMarkerDrag: ((String?, RNLatLng) -> Unit)? = null
507+
var onMarkerDragEnd: ((String?, RNLatLng) -> Unit)? = null
508+
var onIndoorBuildingFocused: ((RNIndoorBuilding) -> Unit)? = null
509+
var onIndoorLevelActivated: ((RNIndoorLevel) -> Unit)? = null
488510
var onCameraChangeStart: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
489511
var onCameraChange: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
490512
var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
491513

492514
fun setCamera(
493515
cameraPosition: CameraPosition,
494516
animated: Boolean,
495-
durationMS: Int,
517+
durationMs: Int,
496518
) {
497519
onUi {
498520
val current = googleMap?.cameraPosition
@@ -503,7 +525,7 @@ class GoogleMapsViewImpl(
503525
val update = CameraUpdateFactory.newCameraPosition(cameraPosition)
504526

505527
if (animated) {
506-
googleMap?.animateCamera(update, durationMS, null)
528+
googleMap?.animateCamera(update, durationMs, null)
507529
} else {
508530
googleMap?.moveCamera(update)
509531
}
@@ -514,7 +536,7 @@ class GoogleMapsViewImpl(
514536
coordinates: Array<RNLatLng>,
515537
padding: RNMapPadding,
516538
animated: Boolean,
517-
durationMS: Int,
539+
durationMs: Int,
518540
) {
519541
if (coordinates.isEmpty()) {
520542
return
@@ -572,13 +594,85 @@ class GoogleMapsViewImpl(
572594
0,
573595
)
574596
if (animated) {
575-
googleMap?.animateCamera(update, durationMS, null)
597+
googleMap?.animateCamera(update, durationMs, null)
576598
} else {
577599
googleMap?.moveCamera(update)
578600
}
579601
}
580602
}
581603

604+
fun setCameraBounds(bounds: LatLngBounds?) {
605+
onUi {
606+
googleMap?.setLatLngBoundsForCameraTarget(bounds)
607+
}
608+
}
609+
610+
fun animateToBounds(
611+
bounds: LatLngBounds,
612+
padding: Int,
613+
durationMs: Int,
614+
lockBounds: Boolean,
615+
) {
616+
onUi {
617+
if (lockBounds) {
618+
googleMap?.setLatLngBoundsForCameraTarget(bounds)
619+
}
620+
val update =
621+
CameraUpdateFactory.newLatLngBounds(
622+
bounds,
623+
padding,
624+
)
625+
googleMap?.animateCamera(update, durationMs, null)
626+
}
627+
}
628+
629+
fun snapshot(
630+
size: Size?,
631+
format: String,
632+
compressFormat: Bitmap.CompressFormat,
633+
quality: Double,
634+
resultIsFile: Boolean,
635+
): Promise<String?> {
636+
val promise = Promise<String?>()
637+
onUi {
638+
googleMap?.snapshot { bitmap ->
639+
try {
640+
if (bitmap == null) {
641+
promise.resolve(null)
642+
return@snapshot
643+
}
644+
645+
val scaledBitmap =
646+
size?.let {
647+
bitmap.scale(it.width, it.height)
648+
} ?: bitmap
649+
650+
val output = ByteArrayOutputStream()
651+
scaledBitmap.compress(compressFormat, (quality * 100).toInt().coerceIn(0, 100), output)
652+
val bytes = output.toByteArray()
653+
654+
if (resultIsFile) {
655+
val file = File(context.cacheDir, "map_snapshot_${System.currentTimeMillis()}.$format")
656+
FileOutputStream(file).use { it.write(bytes) }
657+
promise.resolve(file.absolutePath)
658+
} else {
659+
val base64 = Base64.encodeToString(bytes, Base64.NO_WRAP)
660+
promise.resolve("data:image/$format;base64,$base64")
661+
}
662+
663+
if (scaledBitmap != bitmap) {
664+
scaledBitmap.recycle()
665+
}
666+
bitmap.recycle()
667+
} catch (e: Exception) {
668+
promise.resolve(null)
669+
}
670+
}
671+
}
672+
673+
return promise
674+
}
675+
582676
fun addMarker(
583677
id: String,
584678
opts: MarkerOptions,
@@ -883,14 +977,14 @@ class GoogleMapsViewImpl(
883977

884978
fun destroyInternal() {
885979
onUi {
980+
locationHandler.stop()
886981
markerBuilder.cancelAllJobs()
887982
clearMarkers()
888983
clearPolylines()
889984
clearPolygons()
890985
clearCircles()
891986
clearHeatmaps()
892987
clearKmlLayer()
893-
locationHandler.stop()
894988
googleMap?.apply {
895989
setOnCameraMoveStartedListener(null)
896990
setOnCameraMoveListener(null)
@@ -900,6 +994,7 @@ class GoogleMapsViewImpl(
900994
setOnPolygonClickListener(null)
901995
setOnCircleClickListener(null)
902996
setOnMapClickListener(null)
997+
setOnMarkerDragListener(null)
903998
}
904999
googleMap = null
9051000
mapView?.apply {
@@ -910,6 +1005,7 @@ class GoogleMapsViewImpl(
9101005
}
9111006
super.removeAllViews()
9121007
reactContext.removeLifecycleEventListener(this)
1008+
initialized = false
9131009
}
9141010
}
9151011

@@ -954,27 +1050,64 @@ class GoogleMapsViewImpl(
9541050
}
9551051

9561052
override fun onMarkerClick(marker: Marker): Boolean {
957-
onMarkerPress?.invoke(marker.tag?.toString() ?: "unknown")
1053+
marker.showInfoWindow()
1054+
onMarkerPress?.invoke(marker.tag?.toString())
9581055
return true
9591056
}
9601057

9611058
override fun onPolylineClick(polyline: Polyline) {
962-
onPolylinePress?.invoke(polyline.tag?.toString() ?: "unknown")
1059+
onPolylinePress?.invoke(polyline.tag?.toString())
9631060
}
9641061

9651062
override fun onPolygonClick(polygon: Polygon) {
966-
onPolygonPress?.invoke(polygon.tag?.toString() ?: "unknown")
1063+
onPolygonPress?.invoke(polygon.tag?.toString())
9671064
}
9681065

9691066
override fun onCircleClick(circle: Circle) {
970-
onCirclePress?.invoke(circle.tag?.toString() ?: "unknown")
1067+
onCirclePress?.invoke(circle.tag?.toString())
9711068
}
9721069

9731070
override fun onMapClick(coordinates: LatLng) {
9741071
onMapPress?.invoke(
9751072
RNLatLng(coordinates.latitude, coordinates.longitude),
9761073
)
9771074
}
1075+
1076+
override fun onMarkerDragStart(marker: Marker) {
1077+
onMarkerDragStart?.invoke(
1078+
marker.tag?.toString(),
1079+
RNLatLng(marker.position.latitude, marker.position.longitude),
1080+
)
1081+
}
1082+
1083+
override fun onMarkerDrag(marker: Marker) {
1084+
onMarkerDrag?.invoke(
1085+
marker.tag?.toString(),
1086+
RNLatLng(marker.position.latitude, marker.position.longitude),
1087+
)
1088+
}
1089+
1090+
override fun onMarkerDragEnd(marker: Marker) {
1091+
onMarkerDragEnd?.invoke(
1092+
marker.tag?.toString(),
1093+
RNLatLng(marker.position.latitude, marker.position.longitude),
1094+
)
1095+
}
1096+
1097+
override fun onIndoorBuildingFocused() {
1098+
val building = googleMap?.focusedBuilding ?: return
1099+
onIndoorBuildingFocused?.invoke(building.toRNIndoorBuilding())
1100+
}
1101+
1102+
override fun onIndoorLevelActivated(indoorBuilding: IndoorBuilding) {
1103+
val activeLevel = indoorBuilding.levels.getOrNull(indoorBuilding.activeLevelIndex) ?: return
1104+
onIndoorLevelActivated?.invoke(
1105+
activeLevel.toRNIndoorLevel(
1106+
indoorBuilding.activeLevelIndex,
1107+
true,
1108+
),
1109+
)
1110+
}
9781111
}
9791112

9801113
private inline fun onUi(crossinline block: () -> Unit) {

android/src/main/java/com/rngooglemapsplus/LocationHandler.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ class LocationHandler(
131131

132132
private fun restartLocationUpdates() {
133133
stop()
134-
// 4) Google Play Services checken – früh zurückmelden
135134
val playServicesStatus =
136135
GoogleApiAvailability
137136
.getInstance()

0 commit comments

Comments
 (0)