Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[google_maps_flutter] Switch web to structured options #5965

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a1c4c0c
Temp pubspec overrides
stuartmorgan May 24, 2022
00af9e6
Add new type and methods to platform interface and default impl
stuartmorgan May 24, 2022
56c5ec3
Update app-facing to use new methods, adding necessary utility method…
stuartmorgan May 24, 2022
388b35e
Update web
stuartmorgan May 24, 2022
67b0e57
Version bumps and changelogs
stuartmorgan May 24, 2022
0ddc037
Don't pre-bump versions
stuartmorgan May 25, 2022
849dd3d
Merge branch 'main' into maps-options-structured
stuartmorgan Jun 7, 2022
c7dbf82
Merge branch 'main' into maps-options-structured
stuartmorgan Jun 10, 2022
9bf7782
Fix typos
stuartmorgan Jun 10, 2022
b4610b6
Merge branch 'main' into maps-options-structured
stuartmorgan Jun 13, 2022
4cf719a
Update test for intentionally broken functionality
stuartmorgan Jun 13, 2022
23b88f4
Merge branch 'main' into maps-options-structured
stuartmorgan Jun 14, 2022
b018b02
Replace overrides with published version
stuartmorgan Jun 14, 2022
26c1252
Revert non-web changes
stuartmorgan Jun 14, 2022
a8e0a45
Typo fix
stuartmorgan Jun 14, 2022
ac4eafb
Merge branch 'main' into maps-options-structured-web
stuartmorgan Jun 14, 2022
ab69717
Update mocks and tests
stuartmorgan Jun 14, 2022
a1f1c44
Restore a husk of buildView so an integration test can pass.
ditman Jun 14, 2022
9638a77
Revert "Restore a husk of buildView so an integration test can pass."
ditman Jun 14, 2022
cb7b963
Merge branch 'main' into maps-options-structured-web
ditman Jun 14, 2022
8b587f0
Adjust changelog.
stuartmorgan Jun 14, 2022
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
## NEXT

## 0.4.0

* Implements the new platform interface versions of `buildView` and
`updateOptions` with structured option types.
* **BREAKING CHANGE**: No longer implements the unstructured option dictionary
versions of those methods, so this version can only be adopted when updating
`google_maps_flutter` to a version that uses the new methods. This will be
noted in the `google_maps_flutter` changelog as adding compatibility with
`google_maps_flutter_web` 0.4.0.
* Adds `const` constructor parameters in example tests.

## 0.3.3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,17 @@ void main() {
GoogleMapController _createController({
CameraPosition initialCameraPosition =
const CameraPosition(target: LatLng(0, 0)),
Set<Marker> markers = const <Marker>{},
Set<Polygon> polygons = const <Polygon>{},
Set<Polyline> polylines = const <Polyline>{},
Set<Circle> circles = const <Circle>{},
Map<String, dynamic> options = const <String, dynamic>{},
MapObjects mapObjects = const MapObjects(),
MapConfiguration mapConfiguration = const MapConfiguration(),
}) {
return GoogleMapController(
mapId: mapId,
streamController: stream,
initialCameraPosition: initialCameraPosition,
markers: markers,
polygons: polygons,
polylines: polylines,
circles: circles,
mapOptions: options,
widgetConfiguration: MapWidgetConfiguration(
initialCameraPosition: initialCameraPosition,
textDirection: TextDirection.ltr),
mapObjects: mapObjects,
mapConfiguration: mapConfiguration,
);
}

Expand Down Expand Up @@ -284,7 +280,8 @@ void main() {
});

testWidgets('renders initial geometry', (WidgetTester tester) async {
controller = _createController(circles: <Circle>{
controller = _createController(
mapObjects: MapObjects(circles: <Circle>{
const Circle(
circleId: CircleId('circle-1'),
zIndex: 1234,
Expand Down Expand Up @@ -327,7 +324,7 @@ void main() {
LatLng(43.354469, -5.851318),
LatLng(43.354762, -5.850824),
])
});
}));

controller.debugSetOverrides(
circles: circles,
Expand Down Expand Up @@ -363,9 +360,10 @@ void main() {

testWidgets('empty infoWindow does not create InfoWindow instance.',
(WidgetTester tester) async {
controller = _createController(markers: <Marker>{
controller = _createController(
mapObjects: MapObjects(markers: <Marker>{
const Marker(markerId: MarkerId('marker-1')),
});
}));

controller.debugSetOverrides(
markers: markers,
Expand All @@ -385,10 +383,11 @@ void main() {
capturedOptions = null;
});
testWidgets('translates initial options', (WidgetTester tester) async {
controller = _createController(options: <String, dynamic>{
'mapType': 2,
'zoomControlsEnabled': true,
});
controller = _createController(
mapConfiguration: const MapConfiguration(
mapType: MapType.satellite,
zoomControlsEnabled: true,
));
controller.debugSetOverrides(
createMap: (_, gmaps.MapOptions options) {
capturedOptions = options;
Expand All @@ -407,9 +406,10 @@ void main() {

testWidgets('disables gestureHandling with scrollGesturesEnabled false',
(WidgetTester tester) async {
controller = _createController(options: <String, dynamic>{
'scrollGesturesEnabled': false,
});
controller = _createController(
mapConfiguration: const MapConfiguration(
scrollGesturesEnabled: false,
));
controller.debugSetOverrides(
createMap: (_, gmaps.MapOptions options) {
capturedOptions = options;
Expand All @@ -426,9 +426,10 @@ void main() {

testWidgets('disables gestureHandling with zoomGesturesEnabled false',
(WidgetTester tester) async {
controller = _createController(options: <String, dynamic>{
'zoomGesturesEnabled': false,
});
controller = _createController(
mapConfiguration: const MapConfiguration(
zoomGesturesEnabled: false,
));
controller.debugSetOverrides(
createMap: (_, gmaps.MapOptions options) {
capturedOptions = options;
Expand Down Expand Up @@ -477,9 +478,10 @@ void main() {

testWidgets('initializes with traffic layer',
(WidgetTester tester) async {
controller = _createController(options: <String, dynamic>{
'trafficEnabled': true,
});
controller = _createController(
mapConfiguration: const MapConfiguration(
trafficEnabled: true,
));
controller.debugSetOverrides(createMap: (_, __) => map);
controller.init();
expect(controller.trafficLayer, isNotNull);
Expand All @@ -505,25 +507,25 @@ void main() {

group('updateRawOptions', () {
testWidgets('can update `options`', (WidgetTester tester) async {
controller.updateRawOptions(<String, dynamic>{
'mapType': 2,
});
controller.updateMapConfiguration(const MapConfiguration(
mapType: MapType.satellite,
));

expect(map.mapTypeId, gmaps.MapTypeId.SATELLITE);
});

testWidgets('can turn on/off traffic', (WidgetTester tester) async {
expect(controller.trafficLayer, isNull);

controller.updateRawOptions(<String, dynamic>{
'trafficEnabled': true,
});
controller.updateMapConfiguration(const MapConfiguration(
trafficEnabled: true,
));

expect(controller.trafficLayer, isNotNull);

controller.updateRawOptions(<String, dynamic>{
'trafficEnabled': false,
});
controller.updateMapConfiguration(const MapConfiguration(
trafficEnabled: false,
));

expect(controller.trafficLayer, isNull);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ void main() {
<int, GoogleMapController>{};
plugin.debugSetMapById(cache);

final Widget widget = plugin.buildView(
final Widget widget = plugin.buildViewWithConfiguration(
testMapId,
onPlatformViewCreated,
initialCameraPosition: initialCameraPosition,
widgetConfiguration: const MapWidgetConfiguration(
initialCameraPosition: initialCameraPosition,
textDirection: TextDirection.ltr,
),
);

expect(widget, isA<HtmlElementView>());
Expand Down Expand Up @@ -114,10 +117,13 @@ void main() {
testMapId: controller,
});

final Widget widget = plugin.buildView(
final Widget widget = plugin.buildViewWithConfiguration(
testMapId,
onPlatformViewCreated,
initialCameraPosition: initialCameraPosition,
widgetConfiguration: const MapWidgetConfiguration(
initialCameraPosition: initialCameraPosition,
textDirection: TextDirection.ltr,
),
);

expect(widget, equals(expected));
Expand All @@ -130,10 +136,13 @@ void main() {
<int, GoogleMapController>{};
plugin.debugSetMapById(cache);

plugin.buildView(
plugin.buildViewWithConfiguration(
testMapId,
onPlatformViewCreated,
initialCameraPosition: initialCameraPosition,
widgetConfiguration: const MapWidgetConfiguration(
initialCameraPosition: initialCameraPosition,
textDirection: TextDirection.ltr,
),
);

// Simulate Google Maps JS SDK being "ready"
Expand Down Expand Up @@ -176,11 +185,10 @@ void main() {
await plugin.setMapStyle(mapStyle, mapId: 0);

final dynamic captured =
verify(controller.updateRawOptions(captureThat(isMap))).captured[0];
verify(controller.updateStyles(captureThat(isList))).captured[0];

expect(captured, contains('styles'));
final List<gmaps.MapTypeStyle> styles =
captured['styles'] as List<gmaps.MapTypeStyle>;
captured as List<gmaps.MapTypeStyle>;
expect(styles.length, 1);
// Let's peek inside the styles...
final gmaps.MapTypeStyle style = styles[0];
Expand Down Expand Up @@ -221,14 +229,13 @@ void main() {
plugin.debugSetMapById(<int, GoogleMapController>{mapId: controller});
});
// Options
testWidgets('updateMapOptions', (WidgetTester tester) async {
final Map<String, dynamic> expectedMapOptions = <String, dynamic>{
'someOption': 12345
};
testWidgets('updateMapConfiguration', (WidgetTester tester) async {
const MapConfiguration configuration =
MapConfiguration(mapType: MapType.satellite);

await plugin.updateMapOptions(expectedMapOptions, mapId: mapId);
await plugin.updateMapConfiguration(configuration, mapId: mapId);

verify(controller.updateRawOptions(expectedMapOptions));
verify(controller.updateMapConfiguration(configuration));
});
// Geometry
testWidgets('updateMarkers', (WidgetTester tester) async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:async' as _i2;

import 'package:google_maps/google_maps.dart' as _i5;
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'
as _i3;
import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4;
Expand Down Expand Up @@ -68,8 +69,12 @@ class MockGoogleMapController extends _i1.Mock
void init() => super.noSuchMethod(Invocation.method(#init, []),
returnValueForMissingStub: null);
@override
void updateRawOptions(Map<String, dynamic>? optionsUpdate) =>
super.noSuchMethod(Invocation.method(#updateRawOptions, [optionsUpdate]),
void updateMapConfiguration(_i3.MapConfiguration? update) =>
super.noSuchMethod(Invocation.method(#updateMapConfiguration, [update]),
returnValueForMissingStub: null);
@override
void updateStyles(List<_i5.MapTypeStyle>? styles) =>
super.noSuchMethod(Invocation.method(#updateStyles, [styles]),
returnValueForMissingStub: null);
@override
_i2.Future<_i3.LatLngBounds> getVisibleRegion() => (super.noSuchMethod(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'dart:html';
import 'dart:js_util';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ final gmaps.LatLngBounds _nullGmapsLatLngBounds =
const String _defaultCssColor = '#000000';
const double _defaultCssOpacity = 0.0;

// Indices in the plugin side don't match with the ones
// in the gmaps lib. This translates from plugin -> gmaps.
final Map<int, gmaps.MapTypeId> _mapTypeToMapTypeId = <int, gmaps.MapTypeId>{
0: gmaps.MapTypeId.ROADMAP, // "none" in the plugin
1: gmaps.MapTypeId.ROADMAP,
2: gmaps.MapTypeId.SATELLITE,
3: gmaps.MapTypeId.TERRAIN,
4: gmaps.MapTypeId.HYBRID,
};

// Converts a [Color] into a valid CSS value #RRGGBB.
String _getCssColor(Color color) {
if (color == null) {
Expand Down Expand Up @@ -55,49 +45,64 @@ double _getCssOpacity(Color color) {
// indoorViewEnabled seems to not have an equivalent in web
// buildingsEnabled seems to not have an equivalent in web
// padding seems to behave differently in web than mobile. You can't move UI elements in web.
gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, Object?> rawOptions) {
gmaps.MapOptions _configurationAndStyleToGmapsOptions(
MapConfiguration configuration, List<gmaps.MapTypeStyle> styles) {
final gmaps.MapOptions options = gmaps.MapOptions();

if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) {
options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']];
if (configuration.mapType != null) {
options.mapTypeId = _gmapTypeIDForPluginType(configuration.mapType!);
}

if (rawOptions['minMaxZoomPreference'] != null) {
final List<Object?> minMaxPreference =
rawOptions['minMaxZoomPreference']! as List<Object?>;
final MinMaxZoomPreference? zoomPreference =
configuration.minMaxZoomPreference;
if (zoomPreference != null) {
options
..minZoom = minMaxPreference[0] as num?
..maxZoom = minMaxPreference[1] as num?;
..minZoom = zoomPreference.minZoom
..maxZoom = zoomPreference.maxZoom;
}

if (rawOptions['cameraTargetBounds'] != null) {
if (configuration.cameraTargetBounds != null) {
// Needs gmaps.MapOptions.restriction and gmaps.MapRestriction
// see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction
}

if (rawOptions['zoomControlsEnabled'] != null) {
options.zoomControl = rawOptions['zoomControlsEnabled'] as bool?;
}

if (rawOptions['styles'] != null) {
options.styles = rawOptions['styles'] as List<gmaps.MapTypeStyle?>?;
if (configuration.zoomControlsEnabled != null) {
options.zoomControl = configuration.zoomControlsEnabled;
}

if (rawOptions['scrollGesturesEnabled'] == false ||
rawOptions['zoomGesturesEnabled'] == false) {
if (configuration.scrollGesturesEnabled == false ||
configuration.zoomGesturesEnabled == false) {
options.gestureHandling = 'none';
} else {
options.gestureHandling = 'auto';
}

// These don't have any rawOptions entry, but they seem to be off in the native maps.
// These don't have any configuration entries, but they seem to be off in the
// native maps.
options.mapTypeControl = false;
options.fullscreenControl = false;
options.streetViewControl = false;

options.styles = styles;

return options;
}

gmaps.MapTypeId _gmapTypeIDForPluginType(MapType type) {
switch (type) {
case MapType.satellite:
return gmaps.MapTypeId.SATELLITE;
case MapType.terrain:
return gmaps.MapTypeId.TERRAIN;
case MapType.hybrid:
return gmaps.MapTypeId.HYBRID;
case MapType.normal:
case MapType.none:
default:
return gmaps.MapTypeId.ROADMAP;
}
}

gmaps.MapOptions _applyInitialPosition(
CameraPosition initialPosition,
gmaps.MapOptions options,
Expand All @@ -111,11 +116,6 @@ gmaps.MapOptions _applyInitialPosition(
return options;
}

// Extracts the status of the traffic layer from the rawOptions map.
bool _isTrafficLayerEnabled(Map<String, Object?> rawOptions) {
return rawOptions['trafficEnabled'] as bool? ?? false;
}

// The keys we'd expect to see in a serialized MapTypeStyle JSON object.
final Set<String> _mapStyleKeys = <String>{
'elementType',
Expand Down
Loading