diff --git a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md index ba2011f39be2..a099bb5ef424 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md @@ -1,5 +1,7 @@ -## NEXT +## 2.7.0 +* Adds support for `MapConfiguration.style`. +* Adds support for `getStyleError`. * Updates minimum supported SDK version to Flutter 3.13/Dart 3.1. * Updates compileSdk version to 34. diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java index 78c7dc2428c6..b473f1ea17d8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Convert.java @@ -377,6 +377,10 @@ static void interpretGoogleMapOptions(Object o, GoogleMapOptionsSink sink) { if (buildingsEnabled != null) { sink.setBuildingsEnabled(toBoolean(buildingsEnabled)); } + final Object style = data.get("style"); + if (style != null) { + sink.setMapStyle(toString(style)); + } } /** Returns the dartMarkerId of the interpreted marker. */ diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index fa82b77743d2..dfbaf02b9d4a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -6,6 +6,7 @@ import android.content.Context; import android.graphics.Rect; +import androidx.annotation.Nullable; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLngBounds; @@ -27,6 +28,7 @@ class GoogleMapBuilder implements GoogleMapOptionsSink { private Object initialCircles; private List> initialTileOverlays; private Rect padding = new Rect(0, 0, 0, 0); + private @Nullable String style; GoogleMapController build( int id, @@ -48,6 +50,7 @@ GoogleMapController build( controller.setInitialCircles(initialCircles); controller.setPadding(padding.top, padding.left, padding.bottom, padding.right); controller.setInitialTileOverlays(initialTileOverlays); + controller.setMapStyle(style); return controller; } @@ -178,4 +181,9 @@ public void setInitialCircles(Object initialCircles) { public void setInitialTileOverlays(List> initialTileOverlays) { this.initialTileOverlays = initialTileOverlays; } + + @Override + public void setMapStyle(@Nullable String style) { + this.style = style; + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 917d45218345..b4102471c4b2 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** Controller of a single GoogleMaps MapView instance. */ final class GoogleMapController @@ -87,6 +88,9 @@ final class GoogleMapController private List initialPolylines; private List initialCircles; private List> initialTileOverlays; + // Null except between initialization and onMapReady. + private @Nullable String initialMapStyle; + private @Nullable String lastStyleError; @VisibleForTesting List initialPadding; GoogleMapController( @@ -169,6 +173,10 @@ public void onMapReady(GoogleMap googleMap) { initialPadding.get(2), initialPadding.get(3)); } + if (initialMapStyle != null) { + updateMapStyle(initialMapStyle); + initialMapStyle = null; + } } // Returns the first TextureView found in the view hierarchy. @@ -459,26 +467,22 @@ public void onSnapshotReady(Bitmap bitmap) { } case "map#setStyle": { - boolean mapStyleSet; - if (call.arguments instanceof String) { - String mapStyle = (String) call.arguments; - if (mapStyle == null) { - mapStyleSet = googleMap.setMapStyle(null); - } else { - mapStyleSet = googleMap.setMapStyle(new MapStyleOptions(mapStyle)); - } - } else { - mapStyleSet = googleMap.setMapStyle(null); - } + Object arg = call.arguments; + final String style = arg instanceof String ? (String) arg : null; + final boolean mapStyleSet = updateMapStyle(style); ArrayList mapStyleResult = new ArrayList<>(2); mapStyleResult.add(mapStyleSet); if (!mapStyleSet) { - mapStyleResult.add( - "Unable to set the map style. Please check console logs for errors."); + mapStyleResult.add(lastStyleError); } result.success(mapStyleResult); break; } + case "map#getStyleError": + { + result.success(lastStyleError); + break; + } case "tileOverlays#update": { List> tileOverlaysToAdd = call.argument("tileOverlaysToAdd"); @@ -926,4 +930,22 @@ public void setTrafficEnabled(boolean trafficEnabled) { public void setBuildingsEnabled(boolean buildingsEnabled) { this.buildingsEnabled = buildingsEnabled; } + + public void setMapStyle(@Nullable String style) { + if (googleMap == null) { + initialMapStyle = style; + } else { + updateMapStyle(style); + } + } + + private boolean updateMapStyle(String style) { + // Dart passes an empty string to indicate that the style should be cleared. + final MapStyleOptions mapStyleOptions = + style == null || style.isEmpty() ? null : new MapStyleOptions(style); + final boolean set = Objects.requireNonNull(googleMap).setMapStyle(mapStyleOptions); + lastStyleError = + set ? null : "Unable to set the map style. Please check console logs for errors."; + return set; + } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java index 17f0d970a4ef..95c550c92fd8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java +++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapOptionsSink.java @@ -4,6 +4,7 @@ package io.flutter.plugins.googlemaps; +import androidx.annotation.Nullable; import com.google.android.gms.maps.model.LatLngBounds; import java.util.List; import java.util.Map; @@ -55,4 +56,6 @@ interface GoogleMapOptionsSink { void setInitialCircles(Object initialCircles); void setInitialTileOverlays(List> initialTileOverlays); + + void setMapStyle(@Nullable String style); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart index 97e7dfa0a37e..e03fe8f8851b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart @@ -722,7 +722,8 @@ void googleMapsTests() { await controllerCompleter.future; const String mapStyle = '[{"elementType":"geometry","stylers":[{"color":"#242f3e"}]}]'; - await controller.setMapStyle(mapStyle); + await GoogleMapsFlutterPlatform.instance + .setMapStyle(mapStyle, mapId: controller.mapId); }); testWidgets('testSetMapStyle invalid Json String', @@ -746,10 +747,12 @@ void googleMapsTests() { await controllerCompleter.future; try { - await controller.setMapStyle('invalid_value'); + await GoogleMapsFlutterPlatform.instance + .setMapStyle('invalid_value', mapId: controller.mapId); fail('expected MapStyleException'); } on MapStyleException catch (e) { expect(e.cause, isNotNull); + expect(await controller.getStyleError(), isNotNull); } }); @@ -771,7 +774,8 @@ void googleMapsTests() { final ExampleGoogleMapController controller = await controllerCompleter.future; - await controller.setMapStyle(null); + await GoogleMapsFlutterPlatform.instance + .setMapStyle(null, mapId: controller.mapId); }); testWidgets('testGetLatLng', (WidgetTester tester) async { @@ -1211,6 +1215,58 @@ void googleMapsTests() { await mapIdCompleter.future; }, ); + + testWidgets('getStyleError reports last error', (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + style: '[[[this is an invalid style', + onMapCreated: (ExampleGoogleMapController controller) { + controllerCompleter.complete(controller); + }, + ), + )); + + final ExampleGoogleMapController controller = + await controllerCompleter.future; + String? error = await controller.getStyleError(); + for (int i = 0; i < 1000 && error == null; i++) { + await Future.delayed(const Duration(milliseconds: 10)); + error = await controller.getStyleError(); + } + expect(error, isNotNull); + }); + + testWidgets('getStyleError returns null for a valid style', + (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + // An empty array is the simplest valid style. + style: '[]', + onMapCreated: (ExampleGoogleMapController controller) { + controllerCompleter.complete(controller); + }, + ), + )); + + final ExampleGoogleMapController controller = + await controllerCompleter.future; + final String? error = await controller.getStyleError(); + expect(error, isNull); + }); } class _DebugTileProvider implements TileProvider { diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart index f176b987e28b..0734731af7c3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/example_google_map.dart @@ -144,12 +144,6 @@ class ExampleGoogleMapController { .moveCamera(cameraUpdate, mapId: mapId); } - /// Sets the styling of the base map. - Future setMapStyle(String? mapStyle) { - return GoogleMapsFlutterPlatform.instance - .setMapStyle(mapStyle, mapId: mapId); - } - /// Return [LatLngBounds] defining the region that is visible in a map. Future getVisibleRegion() { return GoogleMapsFlutterPlatform.instance.getVisibleRegion(mapId: mapId); @@ -195,6 +189,11 @@ class ExampleGoogleMapController { return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId); } + /// Returns the last style error, if any. + Future getStyleError() { + return GoogleMapsFlutterPlatform.instance.getStyleError(mapId: mapId); + } + /// Disposes of the platform resources void dispose() { GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId); @@ -245,6 +244,7 @@ class ExampleGoogleMap extends StatefulWidget { this.onTap, this.onLongPress, this.cloudMapId, + this.style, }); /// Callback method for when the map is ready to be used. @@ -353,6 +353,9 @@ class ExampleGoogleMap extends StatefulWidget { /// for more details. final String? cloudMapId; + /// The locally configured style for the map. + final String? style; + /// Creates a [State] for this [ExampleGoogleMap]. @override State createState() => _ExampleGoogleMapState(); @@ -539,5 +542,6 @@ MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { trafficEnabled: map.trafficEnabled, buildingsEnabled: map.buildingsEnabled, cloudMapId: map.cloudMapId, + style: map.style, ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart index 311e2267aa0c..105676da9ed5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/map_ui.dart @@ -60,6 +60,7 @@ class MapUiBodyState extends State { bool _myLocationButtonEnabled = true; late ExampleGoogleMapController _controller; bool _nightMode = false; + String _mapStyle = ''; @override void initState() { @@ -244,27 +245,16 @@ class MapUiBodyState extends State { return rootBundle.loadString(path); } - void _setMapStyle(String mapStyle) { - setState(() { - _nightMode = true; - _controller.setMapStyle(mapStyle); - }); - } - - // Should only be called if _isMapCreated is true. Widget _nightModeToggler() { - assert(_isMapCreated); return TextButton( child: Text('${_nightMode ? 'disable' : 'enable'} night mode'), - onPressed: () { - if (_nightMode) { - setState(() { - _nightMode = false; - _controller.setMapStyle(null); - }); - } else { - _getFileData('assets/night_mode.json').then(_setMapStyle); - } + onPressed: () async { + _nightMode = !_nightMode; + final String style = + _nightMode ? await _getFileData('assets/night_mode.json') : ''; + setState(() { + _mapStyle = style; + }); }, ); } @@ -279,6 +269,7 @@ class MapUiBodyState extends State { cameraTargetBounds: _cameraTargetBounds, minMaxZoomPreference: _minMaxZoomPreference, mapType: _mapType, + style: _mapStyle, rotateGesturesEnabled: _rotateGesturesEnabled, scrollGesturesEnabled: _scrollGesturesEnabled, tiltGesturesEnabled: _tiltGesturesEnabled, @@ -353,5 +344,11 @@ class MapUiBodyState extends State { _controller = controller; _isMapCreated = true; }); + // Log any style errors to the console for debugging. + _controller.getStyleError().then((String? error) { + if (error != null) { + debugPrint(error); + } + }); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml index f241ddc6c920..533ca53c2914 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/example/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 dev_dependencies: build_runner: ^2.1.10 diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart index 4cb87722f375..d40d795d6a32 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart +++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart @@ -484,6 +484,11 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform { return _channel(mapId).invokeMethod('map#takeSnapshot'); } + @override + Future getStyleError({required int mapId}) { + return _channel(mapId).invokeMethod('map#getStyleError'); + } + /// Set [GoogleMapsFlutterPlatform] to use [AndroidViewSurface] to build the /// Google Maps widget. /// @@ -727,6 +732,7 @@ Map _jsonForMapConfiguration(MapConfiguration config) { if (config.buildingsEnabled != null) 'buildingsEnabled': config.buildingsEnabled!, if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, + if (config.style != null) 'style': config.style!, }; } diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml index 30b1644e313c..1f2a3be877c1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_android description: Android implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.6.2 +version: 2.7.0 environment: sdk: ^3.1.0 @@ -21,7 +21,7 @@ dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^2.0.1 - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 stream_transform: ^2.0.0 dev_dependencies: diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md index 4eae3cfc1f0f..6778f3b8e1ee 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.5.0 + +* Adds support for `MapConfiguration.style`. +* Adds support for `getStyleError`. + ## 2.4.2 * Fixes a bug in "takeSnapshot" function that incorrectly returns a blank image on iOS 17. diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/integration_test/google_maps_test.dart index 9902456444d6..e49c451d08ee 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/integration_test/google_maps_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/integration_test/google_maps_test.dart @@ -583,7 +583,8 @@ void main() { await controllerCompleter.future; const String mapStyle = '[{"elementType":"geometry","stylers":[{"color":"#242f3e"}]}]'; - await controller.setMapStyle(mapStyle); + await GoogleMapsFlutterPlatform.instance + .setMapStyle(mapStyle, mapId: controller.mapId); }); testWidgets('testSetMapStyle invalid Json String', @@ -607,10 +608,12 @@ void main() { await controllerCompleter.future; try { - await controller.setMapStyle('invalid_value'); + await GoogleMapsFlutterPlatform.instance + .setMapStyle('invalid_value', mapId: controller.mapId); fail('expected MapStyleException'); } on MapStyleException catch (e) { expect(e.cause, isNotNull); + expect(await controller.getStyleError(), isNotNull); } }); @@ -632,7 +635,8 @@ void main() { final ExampleGoogleMapController controller = await controllerCompleter.future; - await controller.setMapStyle(null); + await GoogleMapsFlutterPlatform.instance + .setMapStyle(null, mapId: controller.mapId); }); testWidgets('testGetLatLng', (WidgetTester tester) async { @@ -1048,6 +1052,54 @@ void main() { ), )); }); + + testWidgets('getStyleError reports last error', (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + style: '[[[this is an invalid style', + onMapCreated: (ExampleGoogleMapController controller) { + controllerCompleter.complete(controller); + }, + ), + )); + + final ExampleGoogleMapController controller = + await controllerCompleter.future; + final String? error = await controller.getStyleError(); + expect(error, isNotNull); + }); + + testWidgets('getStyleError returns null for a valid style', + (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: ExampleGoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + // An empty array is the simplest valid style. + style: '[]', + onMapCreated: (ExampleGoogleMapController controller) { + controllerCompleter.complete(controller); + }, + ), + )); + + final ExampleGoogleMapController controller = + await controllerCompleter.future; + final String? error = await controller.getStyleError(); + expect(error, isNull); + }); } class _DebugTileProvider implements TileProvider { diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/pubspec.yaml index e5e0cd2a4b1e..a0b172a65e1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../ - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 maps_example_dart: path: ../shared/maps_example_dart/ diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios13/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios13/pubspec.yaml index e5e0cd2a4b1e..a0b172a65e1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios13/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios13/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../ - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 maps_example_dart: path: ../shared/maps_example_dart/ diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml index e5e0cd2a4b1e..a0b172a65e1c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/ios14/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../ - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 maps_example_dart: path: ../shared/maps_example_dart/ diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart index f176b987e28b..0734731af7c3 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/example_google_map.dart @@ -144,12 +144,6 @@ class ExampleGoogleMapController { .moveCamera(cameraUpdate, mapId: mapId); } - /// Sets the styling of the base map. - Future setMapStyle(String? mapStyle) { - return GoogleMapsFlutterPlatform.instance - .setMapStyle(mapStyle, mapId: mapId); - } - /// Return [LatLngBounds] defining the region that is visible in a map. Future getVisibleRegion() { return GoogleMapsFlutterPlatform.instance.getVisibleRegion(mapId: mapId); @@ -195,6 +189,11 @@ class ExampleGoogleMapController { return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId); } + /// Returns the last style error, if any. + Future getStyleError() { + return GoogleMapsFlutterPlatform.instance.getStyleError(mapId: mapId); + } + /// Disposes of the platform resources void dispose() { GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId); @@ -245,6 +244,7 @@ class ExampleGoogleMap extends StatefulWidget { this.onTap, this.onLongPress, this.cloudMapId, + this.style, }); /// Callback method for when the map is ready to be used. @@ -353,6 +353,9 @@ class ExampleGoogleMap extends StatefulWidget { /// for more details. final String? cloudMapId; + /// The locally configured style for the map. + final String? style; + /// Creates a [State] for this [ExampleGoogleMap]. @override State createState() => _ExampleGoogleMapState(); @@ -539,5 +542,6 @@ MapConfiguration _configurationFromMapWidget(ExampleGoogleMap map) { trafficEnabled: map.trafficEnabled, buildingsEnabled: map.buildingsEnabled, cloudMapId: map.cloudMapId, + style: map.style, ); } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart index 311e2267aa0c..105676da9ed5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/lib/map_ui.dart @@ -60,6 +60,7 @@ class MapUiBodyState extends State { bool _myLocationButtonEnabled = true; late ExampleGoogleMapController _controller; bool _nightMode = false; + String _mapStyle = ''; @override void initState() { @@ -244,27 +245,16 @@ class MapUiBodyState extends State { return rootBundle.loadString(path); } - void _setMapStyle(String mapStyle) { - setState(() { - _nightMode = true; - _controller.setMapStyle(mapStyle); - }); - } - - // Should only be called if _isMapCreated is true. Widget _nightModeToggler() { - assert(_isMapCreated); return TextButton( child: Text('${_nightMode ? 'disable' : 'enable'} night mode'), - onPressed: () { - if (_nightMode) { - setState(() { - _nightMode = false; - _controller.setMapStyle(null); - }); - } else { - _getFileData('assets/night_mode.json').then(_setMapStyle); - } + onPressed: () async { + _nightMode = !_nightMode; + final String style = + _nightMode ? await _getFileData('assets/night_mode.json') : ''; + setState(() { + _mapStyle = style; + }); }, ); } @@ -279,6 +269,7 @@ class MapUiBodyState extends State { cameraTargetBounds: _cameraTargetBounds, minMaxZoomPreference: _minMaxZoomPreference, mapType: _mapType, + style: _mapStyle, rotateGesturesEnabled: _rotateGesturesEnabled, scrollGesturesEnabled: _scrollGesturesEnabled, tiltGesturesEnabled: _tiltGesturesEnabled, @@ -353,5 +344,11 @@ class MapUiBodyState extends State { _controller = controller; _isMapCreated = true; }); + // Log any style errors to the console for debugging. + _controller.getStyleError().then((String? error) { + if (error != null) { + debugPrint(error); + } + }); } } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml index 38259978c902..77063ec00061 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/example/shared/maps_example_dart/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../../../ - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m index 06e7838d9f4d..0b9b09b7748c 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/GoogleMapController.m @@ -67,6 +67,11 @@ @interface FLTGoogleMapController () @property(nonatomic, strong) FLTPolylinesController *polylinesController; @property(nonatomic, strong) FLTCirclesController *circlesController; @property(nonatomic, strong) FLTTileOverlaysController *tileOverlaysController; +// The resulting error message, if any, from the last attempt to set the map style. +// This is used to provide access to errors after the fact, since the map style is generally set at +// creation time and there's no mechanism to return non-fatal error details during platform view +// initialization. +@property(nonatomic, copy) NSString *styleError; @end @@ -400,13 +405,15 @@ - (void)onMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { NSNumber *isBuildingsEnabled = @(self.mapView.buildingsEnabled); result(isBuildingsEnabled); } else if ([call.method isEqualToString:@"map#setStyle"]) { - NSString *mapStyle = [call arguments]; - NSString *error = [self setMapStyle:mapStyle]; - if (error == nil) { + id mapStyle = [call arguments]; + self.styleError = [self setMapStyle:(mapStyle == [NSNull null] ? nil : mapStyle)]; + if (self.styleError == nil) { result(@[ @(YES) ]); } else { - result(@[ @(NO), error ]); + result(@[ @(NO), self.styleError ]); } + } else if ([call.method isEqualToString:@"map#getStyleError"]) { + result(self.styleError); } else if ([call.method isEqualToString:@"map#getTileOverlayInfo"]) { NSString *rawTileOverlayId = call.arguments[@"tileOverlayId"]; result([self.tileOverlaysController tileOverlayInfoWithIdentifier:rawTileOverlayId]); @@ -506,7 +513,7 @@ - (void)setMyLocationButtonEnabled:(BOOL)enabled { } - (NSString *)setMapStyle:(NSString *)mapStyle { - if (mapStyle == (id)[NSNull null] || mapStyle.length == 0) { + if (mapStyle.length == 0) { self.mapView.mapStyle = nil; return nil; } @@ -658,6 +665,10 @@ - (void)interpretMapOptions:(NSDictionary *)data { if (myLocationButtonEnabled && myLocationButtonEnabled != (id)[NSNull null]) { [self setMyLocationButtonEnabled:[myLocationButtonEnabled boolValue]]; } + NSString *style = data[@"style"]; + if (style) { + self.styleError = [self setMapStyle:style]; + } } @end diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart index 642febcdd3b9..56f3cc5a0794 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart +++ b/packages/google_maps_flutter/google_maps_flutter_ios/lib/src/google_maps_flutter_ios.dart @@ -466,6 +466,12 @@ class GoogleMapsFlutterIOS extends GoogleMapsFlutterPlatform { return _channel(mapId).invokeMethod('map#takeSnapshot'); } + @override + Future getStyleError({required int mapId}) { + final MethodChannel channel = ensureChannelInitialized(mapId); + return channel.invokeMethod('map#getStyleError'); + } + Widget _buildView( int creationId, PlatformViewCreatedCallback onPlatformViewCreated, { @@ -618,6 +624,7 @@ Map _jsonForMapConfiguration(MapConfiguration config) { if (config.buildingsEnabled != null) 'buildingsEnabled': config.buildingsEnabled!, if (config.cloudMapId != null) 'cloudMapId': config.cloudMapId!, + if (config.style != null) 'style': config.style!, }; } diff --git a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml index 502db892ac53..a90927475205 100644 --- a/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_ios description: iOS implementation of the google_maps_flutter plugin. repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 2.4.2 +version: 2.5.0 environment: sdk: ^3.2.3 @@ -19,7 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 stream_transform: ^2.0.0 dev_dependencies: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 8476953537fe..49ed230183c5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,5 +1,9 @@ -## 0.5.5 +## 0.5.6 + +* Adds support for `MapConfiguration.style`. +* Adds support for `getStyleError`. +## 0.5.5 * Migrates to `dart:js_interop` and `package:web` APIs. * Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 5c3ccbdc8c76..aa7e0ae4fe41 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -357,11 +357,8 @@ void main() { }); group('Initialization options', () { - gmaps.MapOptions? capturedOptions; - setUp(() { - capturedOptions = null; - }); testWidgets('translates initial options', (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; controller = createController( mapConfiguration: const MapConfiguration( mapType: MapType.satellite, @@ -390,6 +387,7 @@ void main() { testWidgets('translates fortyFiveDegreeImageryEnabled option', (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; controller = createController( mapConfiguration: const MapConfiguration( scrollGesturesEnabled: false, @@ -410,6 +408,7 @@ void main() { testWidgets('translates webGestureHandling option', (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; controller = createController( mapConfiguration: const MapConfiguration( zoomGesturesEnabled: false, @@ -429,6 +428,7 @@ void main() { testWidgets('sets initial position when passed', (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; controller = createController( initialCameraPosition: const CameraPosition( target: LatLng(43.308, -5.6910), @@ -445,6 +445,81 @@ void main() { expect(capturedOptions!.zoom, 12); expect(capturedOptions!.center, isNotNull); }); + + testWidgets('translates style option', (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; + const String style = ''' +[{ + "featureType": "poi.park", + "elementType": "labels.text.fill", + "stylers": [{"color": "#6b9a76"}] +}]'''; + controller = createController( + mapConfiguration: const MapConfiguration(style: style)); + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions!.styles?.length, 1); + }); + + testWidgets('stores style errors for later querying', + (WidgetTester tester) async { + gmaps.MapOptions? capturedOptions; + controller = createController( + mapConfiguration: const MapConfiguration( + style: '[[invalid style', zoomControlsEnabled: true)); + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { + capturedOptions = options; + return map; + }); + + controller.init(); + + expect(controller.lastStyleError, isNotNull); + // Style failures should not prevent other options from being set. + expect(capturedOptions, isNotNull); + expect(capturedOptions!.zoomControl, true); + }); + + testWidgets('setting invalid style leaves previous style', + (WidgetTester tester) async { + gmaps.MapOptions? initialCapturedOptions; + gmaps.MapOptions? updatedCapturedOptions; + const String style = ''' +[{ + "featureType": "poi.park", + "elementType": "labels.text.fill", + "stylers": [{"color": "#6b9a76"}] +}]'''; + controller = createController( + mapConfiguration: const MapConfiguration(style: style)); + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { + initialCapturedOptions = options; + return map; + }, + setOptions: (gmaps.MapOptions options) { + updatedCapturedOptions = options; + }, + ); + + controller.init(); + controller.updateMapConfiguration( + const MapConfiguration(style: '[[invalid style')); + + expect(initialCapturedOptions, isNotNull); + expect(initialCapturedOptions!.styles?.length, 1); + // The styles should not have changed. + expect( + updatedCapturedOptions!.styles, initialCapturedOptions!.styles); + }); }); group('Traffic Layer', () { @@ -482,7 +557,7 @@ void main() { ..init(); }); - group('updateRawOptions', () { + group('updateMapConfiguration', () { testWidgets('can update `options`', (WidgetTester tester) async { controller.updateMapConfiguration(const MapConfiguration( mapType: MapType.satellite, @@ -506,6 +581,27 @@ void main() { expect(controller.trafficLayer, isNull); }); + + testWidgets('can update style', (WidgetTester tester) async { + const String style = ''' +[{ + "featureType": "poi.park", + "elementType": "labels.text.fill", + "stylers": [{"color": "#6b9a76"}] +}]'''; + controller + .updateMapConfiguration(const MapConfiguration(style: style)); + + expect(controller.styles.length, 1); + }); + + testWidgets('can update style', (WidgetTester tester) async { + controller.updateMapConfiguration( + const MapConfiguration(style: '[[[invalid style')); + + expect(controller.styles, isEmpty); + expect(controller.lastStyleError, isNotNull); + }); }); group('viewport getters', () { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart index 76bf2e672a3e..3f84b40adc88 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart @@ -123,9 +123,17 @@ class MockGoogleMapController extends _i1.Mock returnValueForMissingStub: false, ) as bool); + @override + List<_i5.MapTypeStyle> get styles => (super.noSuchMethod( + Invocation.getter(#styles), + returnValue: <_i5.MapTypeStyle>[], + returnValueForMissingStub: <_i5.MapTypeStyle>[], + ) as List<_i5.MapTypeStyle>); + @override void debugSetOverrides({ _i4.DebugCreateMapFunction? createMap, + _i4.DebugSetOptionsFunction? setOptions, _i4.MarkersController? markers, _i4.CirclesController? circles, _i4.PolygonsController? polygons, @@ -138,6 +146,7 @@ class MockGoogleMapController extends _i1.Mock [], { #createMap: createMap, + #setOptions: setOptions, #markers: markers, #circles: circles, #polygons: polygons, diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 1a02cfa2a658..28381575ea0a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: flutter: sdk: flutter - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 google_maps_flutter_web: path: ../ web: ^0.5.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index d8d77a7728a8..6702d5f520b8 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -80,6 +80,7 @@ gmaps.MapOptions _configurationAndStyleToGmapsOptions( options.fullscreenControl = false; options.streetViewControl = false; + // See updateMapConfiguration for why this is not using configuration.style. options.styles = styles; options.mapId = configuration.cloudMapId; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart index c577ba300214..c60dd92a0aca 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_controller.dart @@ -9,6 +9,10 @@ part of '../google_maps_flutter_web.dart'; typedef DebugCreateMapFunction = gmaps.GMap Function( HTMLElement div, gmaps.MapOptions options); +/// Type used when passing an override to the _setOptions function. +@visibleForTesting +typedef DebugSetOptionsFunction = void Function(gmaps.MapOptions options); + /// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered. class GoogleMapController { /// Initializes the GMap, and the sub-controllers related to it. Wires events. @@ -32,6 +36,7 @@ class GoogleMapController { _polylinesController = PolylinesController(stream: _streamController); _markersController = MarkersController(stream: _streamController); _tileOverlaysController = TileOverlaysController(); + _updateStylesFromConfiguration(mapConfiguration); // Register the view factory that will hold the `_div` that holds the map in the DOM. // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can @@ -60,6 +65,8 @@ class GoogleMapController { // Caching this allows us to re-create the map faithfully when needed. MapConfiguration _lastMapConfiguration = const MapConfiguration(); List _lastStyles = const []; + // The last error resulting from providing a map style, if any. + String? _lastStyleError; /// Configuration accessor for the [GoogleMapsInspectorWeb]. /// @@ -122,6 +129,7 @@ class GoogleMapController { @visibleForTesting void debugSetOverrides({ DebugCreateMapFunction? createMap, + DebugSetOptionsFunction? setOptions, MarkersController? markers, CirclesController? circles, PolygonsController? polygons, @@ -129,6 +137,7 @@ class GoogleMapController { TileOverlaysController? tileOverlays, }) { _overrideCreateMap = createMap; + _overrideSetOptions = setOptions; _markersController = markers ?? _markersController; _circlesController = circles ?? _circlesController; _polygonsController = polygons ?? _polygonsController; @@ -137,6 +146,7 @@ class GoogleMapController { } DebugCreateMapFunction? _overrideCreateMap; + DebugSetOptionsFunction? _overrideSetOptions; gmaps.GMap _createMap(HTMLElement div, gmaps.MapOptions options) { if (_overrideCreateMap != null) { @@ -279,15 +289,36 @@ class GoogleMapController { return _lastMapConfiguration; } + // TODO(stuartmorgan): Refactor so that _lastMapConfiguration.style is the + // source of truth for style info. Currently it's tracked and handled + // separately since style didn't used to be part of the configuration. + List _updateStylesFromConfiguration( + MapConfiguration update) { + if (update.style != null) { + // Provide async access to the error rather than throwing, to match the + // behavior of other platforms where there's no mechanism to return errors + // from configuration updates. + try { + _lastStyles = _mapStyles(update.style); + _lastStyleError = null; + } on MapStyleException catch (e) { + _lastStyleError = e.cause; + } + } + return _lastStyles; + } + /// Updates the map options from a [MapConfiguration]. /// /// This method converts the map into the proper [gmaps.MapOptions]. void updateMapConfiguration(MapConfiguration update) { assert(_googleMap != null, 'Cannot update options on a null map.'); + final List styles = + _updateStylesFromConfiguration(update); final MapConfiguration newConfiguration = _mergeConfigurations(update); final gmaps.MapOptions newOptions = - _configurationAndStyleToGmapsOptions(newConfiguration, _lastStyles); + _configurationAndStyleToGmapsOptions(newConfiguration, styles); _setOptions(newOptions); _setTrafficLayer(_googleMap!, newConfiguration.trafficEnabled ?? false); @@ -300,9 +331,19 @@ class GoogleMapController { _configurationAndStyleToGmapsOptions(_lastMapConfiguration, styles)); } + /// A getter for the current styles. Only for tests. + @visibleForTesting + List get styles => _lastStyles; + + /// Returns the last error from setting the map's style, if any. + String? get lastStyleError => _lastStyleError; + // Sets new [gmaps.MapOptions] on the wrapped map. // ignore: use_setters_to_change_properties void _setOptions(gmaps.MapOptions options) { + if (_overrideSetOptions != null) { + return _overrideSetOptions!(options); + } _googleMap?.options = options; } diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart index 140fd3e1888d..805887f0d7f5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/google_maps_flutter_web.dart @@ -279,6 +279,11 @@ class GoogleMapsPlugin extends GoogleMapsFlutterPlatform { return _events(mapId).whereType(); } + @override + Future getStyleError({required int mapId}) async { + return _map(mapId).lastStyleError; + } + /// Disposes of the current map. It can't be used afterwards! @override void dispose({required int mapId}) { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index f78289d04fce..df6988f11c6a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.5.5 +version: 0.5.6 environment: sdk: ^3.3.0 @@ -23,7 +23,7 @@ dependencies: flutter_web_plugins: sdk: flutter google_maps: ^7.1.0 - google_maps_flutter_platform_interface: ^2.4.0 + google_maps_flutter_platform_interface: ^2.5.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 web: ^0.5.0