From a8e0c53be04c9cb77a7f43895ce2639361e5000d Mon Sep 17 00:00:00 2001 From: daplugg23 Date: Thu, 5 Feb 2026 15:30:14 -0600 Subject: [PATCH] feat(location): implement location search provider toggle Add config properties for locationSearchProvider (osm/google_maps) and googleMapsApiKey to BetterLocationConfig. Modify ChooseLocationDialog to switch between OpenStreetMap (MAPNIK) and Google Maps tile sources based on user preference. - Add locationSearchProvider unique config property - Add googleMapsApiKey string config property (SENSITIVE flag) - Add XYTileSource for Google Maps tiles in AlertDialogs - Pass locationSearchProvider from BetterLocationRoot to dialog Translation keys already existed in all 28 language files. --- .../ui/manager/pages/location/BetterLocationRoot.kt | 12 +++++++++--- .../me/eternal/purrfectsnap/ui/util/AlertDialogs.kt | 13 ++++++++++++- .../purrfectsnap/common/config/impl/Global.kt | 2 ++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/location/BetterLocationRoot.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/location/BetterLocationRoot.kt index e0f2549a..ccbab3ea 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/location/BetterLocationRoot.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/manager/pages/location/BetterLocationRoot.kt @@ -337,9 +337,15 @@ class BetterLocationRoot : Routes.Route() { ) ) { Box(modifier = Modifier.background(PurrfectPalette.cardOverlay)) { - alertDialogs.ChooseLocationDialog(property = coordinatesProperty, marker, mapView, saveCoordinates = { - addSavedCoordinateDialog = true - }) { + alertDialogs.ChooseLocationDialog( + property = coordinatesProperty, + marker = marker, + mapView = mapView, + locationSearchProvider = context.config.root.global.betterLocation.locationSearchProvider.get(), + saveCoordinates = { + addSavedCoordinateDialog = true + } + ) { showMap = false context.config.writeConfig() } diff --git a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt index cf630238..07797b89 100644 --- a/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt +++ b/app/src/main/kotlin/me/eternal/purrfectsnap/ui/util/AlertDialogs.kt @@ -58,6 +58,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.tileprovider.tilesource.XYTileSource import org.osmdroid.util.GeoPoint import org.osmdroid.views.CustomZoomButtonsController import org.osmdroid.views.MapView @@ -592,6 +593,7 @@ class AlertDialogs( property: PropertyPair<*>, marker: MutableState = remember { mutableStateOf(null) }, mapView: MutableState = remember { mutableStateOf(null) }, + locationSearchProvider: String = "osm", saveCoordinates: (() -> Unit)? = null, dismiss: () -> Unit = {} ) { @@ -611,7 +613,16 @@ class AlertDialogs( MapView(context).apply { setMultiTouchControls(true) zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) - setTileSource(TileSourceFactory.MAPNIK) + val tileSource = if (locationSearchProvider == "google_maps") { + XYTileSource( + "GoogleMaps", + 0, 19, 256, ".png", + arrayOf("https://mt0.google.com/vt/lyrs=m&x=", "https://mt1.google.com/vt/lyrs=m&x=") + ) + } else { + TileSourceFactory.MAPNIK + } + setTileSource(tileSource) val startPoint = GeoPoint(coordinates.first, coordinates.second) controller.setZoom(10.0) diff --git a/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/Global.kt b/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/Global.kt index bd317986..7888b3ff 100644 --- a/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/Global.kt +++ b/common/src/main/kotlin/me/eternal/purrfectsnap/common/config/impl/Global.kt @@ -28,6 +28,8 @@ class Global : ConfigContainer() { val spoofBatteryLevel = string("spoof_battery_level") { requireRestart(); inputCheck = { it.isEmpty() || it.toIntOrNull() in 0..100 } } val spoofHeadphones = boolean("spoof_headphones") { requireRestart() } val showBatteryLevel = boolean("show_battery_level") { requireRestart() } + val locationSearchProvider = unique("location_search_provider", "osm", "google_maps") + val googleMapsApiKey = string("google_maps_api_key") { addFlags(ConfigFlag.SENSITIVE) } } inner class MediaUploadQualityConfig : ConfigContainer() {