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

Commit 1c57e27

Browse files
[google_maps_flutter] Switch web to structured options (#5965)
1 parent 4274bba commit 1c57e27

File tree

9 files changed

+155
-143
lines changed

9 files changed

+155
-143
lines changed

packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
## NEXT
1+
## 0.4.0
22

3+
* Implements the new platform interface versions of `buildView` and
4+
`updateOptions` with structured option types.
5+
* **BREAKING CHANGE**: No longer implements the unstructured option dictionary
6+
versions of those methods, so this version can only be used with
7+
`google_maps_flutter` 2.1.8 or later.
38
* Adds `const` constructor parameters in example tests.
49

510
## 0.3.3

packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,17 @@ void main() {
4040
GoogleMapController _createController({
4141
CameraPosition initialCameraPosition =
4242
const CameraPosition(target: LatLng(0, 0)),
43-
Set<Marker> markers = const <Marker>{},
44-
Set<Polygon> polygons = const <Polygon>{},
45-
Set<Polyline> polylines = const <Polyline>{},
46-
Set<Circle> circles = const <Circle>{},
47-
Map<String, dynamic> options = const <String, dynamic>{},
43+
MapObjects mapObjects = const MapObjects(),
44+
MapConfiguration mapConfiguration = const MapConfiguration(),
4845
}) {
4946
return GoogleMapController(
5047
mapId: mapId,
5148
streamController: stream,
52-
initialCameraPosition: initialCameraPosition,
53-
markers: markers,
54-
polygons: polygons,
55-
polylines: polylines,
56-
circles: circles,
57-
mapOptions: options,
49+
widgetConfiguration: MapWidgetConfiguration(
50+
initialCameraPosition: initialCameraPosition,
51+
textDirection: TextDirection.ltr),
52+
mapObjects: mapObjects,
53+
mapConfiguration: mapConfiguration,
5854
);
5955
}
6056

@@ -284,7 +280,8 @@ void main() {
284280
});
285281

286282
testWidgets('renders initial geometry', (WidgetTester tester) async {
287-
controller = _createController(circles: <Circle>{
283+
controller = _createController(
284+
mapObjects: MapObjects(circles: <Circle>{
288285
const Circle(
289286
circleId: CircleId('circle-1'),
290287
zIndex: 1234,
@@ -327,7 +324,7 @@ void main() {
327324
LatLng(43.354469, -5.851318),
328325
LatLng(43.354762, -5.850824),
329326
])
330-
});
327+
}));
331328

332329
controller.debugSetOverrides(
333330
circles: circles,
@@ -363,9 +360,10 @@ void main() {
363360

364361
testWidgets('empty infoWindow does not create InfoWindow instance.',
365362
(WidgetTester tester) async {
366-
controller = _createController(markers: <Marker>{
363+
controller = _createController(
364+
mapObjects: MapObjects(markers: <Marker>{
367365
const Marker(markerId: MarkerId('marker-1')),
368-
});
366+
}));
369367

370368
controller.debugSetOverrides(
371369
markers: markers,
@@ -385,10 +383,11 @@ void main() {
385383
capturedOptions = null;
386384
});
387385
testWidgets('translates initial options', (WidgetTester tester) async {
388-
controller = _createController(options: <String, dynamic>{
389-
'mapType': 2,
390-
'zoomControlsEnabled': true,
391-
});
386+
controller = _createController(
387+
mapConfiguration: const MapConfiguration(
388+
mapType: MapType.satellite,
389+
zoomControlsEnabled: true,
390+
));
392391
controller.debugSetOverrides(
393392
createMap: (_, gmaps.MapOptions options) {
394393
capturedOptions = options;
@@ -407,9 +406,10 @@ void main() {
407406

408407
testWidgets('disables gestureHandling with scrollGesturesEnabled false',
409408
(WidgetTester tester) async {
410-
controller = _createController(options: <String, dynamic>{
411-
'scrollGesturesEnabled': false,
412-
});
409+
controller = _createController(
410+
mapConfiguration: const MapConfiguration(
411+
scrollGesturesEnabled: false,
412+
));
413413
controller.debugSetOverrides(
414414
createMap: (_, gmaps.MapOptions options) {
415415
capturedOptions = options;
@@ -426,9 +426,10 @@ void main() {
426426

427427
testWidgets('disables gestureHandling with zoomGesturesEnabled false',
428428
(WidgetTester tester) async {
429-
controller = _createController(options: <String, dynamic>{
430-
'zoomGesturesEnabled': false,
431-
});
429+
controller = _createController(
430+
mapConfiguration: const MapConfiguration(
431+
zoomGesturesEnabled: false,
432+
));
432433
controller.debugSetOverrides(
433434
createMap: (_, gmaps.MapOptions options) {
434435
capturedOptions = options;
@@ -477,9 +478,10 @@ void main() {
477478

478479
testWidgets('initializes with traffic layer',
479480
(WidgetTester tester) async {
480-
controller = _createController(options: <String, dynamic>{
481-
'trafficEnabled': true,
482-
});
481+
controller = _createController(
482+
mapConfiguration: const MapConfiguration(
483+
trafficEnabled: true,
484+
));
483485
controller.debugSetOverrides(createMap: (_, __) => map);
484486
controller.init();
485487
expect(controller.trafficLayer, isNotNull);
@@ -505,25 +507,25 @@ void main() {
505507

506508
group('updateRawOptions', () {
507509
testWidgets('can update `options`', (WidgetTester tester) async {
508-
controller.updateRawOptions(<String, dynamic>{
509-
'mapType': 2,
510-
});
510+
controller.updateMapConfiguration(const MapConfiguration(
511+
mapType: MapType.satellite,
512+
));
511513

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

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

518-
controller.updateRawOptions(<String, dynamic>{
519-
'trafficEnabled': true,
520-
});
520+
controller.updateMapConfiguration(const MapConfiguration(
521+
trafficEnabled: true,
522+
));
521523

522524
expect(controller.trafficLayer, isNotNull);
523525

524-
controller.updateRawOptions(<String, dynamic>{
525-
'trafficEnabled': false,
526-
});
526+
controller.updateMapConfiguration(const MapConfiguration(
527+
trafficEnabled: false,
528+
));
527529

528530
expect(controller.trafficLayer, isNull);
529531
});

packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.dart

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ void main() {
7979
<int, GoogleMapController>{};
8080
plugin.debugSetMapById(cache);
8181

82-
final Widget widget = plugin.buildView(
82+
final Widget widget = plugin.buildViewWithConfiguration(
8383
testMapId,
8484
onPlatformViewCreated,
85-
initialCameraPosition: initialCameraPosition,
85+
widgetConfiguration: const MapWidgetConfiguration(
86+
initialCameraPosition: initialCameraPosition,
87+
textDirection: TextDirection.ltr,
88+
),
8689
);
8790

8891
expect(widget, isA<HtmlElementView>());
@@ -114,10 +117,13 @@ void main() {
114117
testMapId: controller,
115118
});
116119

117-
final Widget widget = plugin.buildView(
120+
final Widget widget = plugin.buildViewWithConfiguration(
118121
testMapId,
119122
onPlatformViewCreated,
120-
initialCameraPosition: initialCameraPosition,
123+
widgetConfiguration: const MapWidgetConfiguration(
124+
initialCameraPosition: initialCameraPosition,
125+
textDirection: TextDirection.ltr,
126+
),
121127
);
122128

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

133-
plugin.buildView(
139+
plugin.buildViewWithConfiguration(
134140
testMapId,
135141
onPlatformViewCreated,
136-
initialCameraPosition: initialCameraPosition,
142+
widgetConfiguration: const MapWidgetConfiguration(
143+
initialCameraPosition: initialCameraPosition,
144+
textDirection: TextDirection.ltr,
145+
),
137146
);
138147

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

178187
final dynamic captured =
179-
verify(controller.updateRawOptions(captureThat(isMap))).captured[0];
188+
verify(controller.updateStyles(captureThat(isList))).captured[0];
180189

181-
expect(captured, contains('styles'));
182190
final List<gmaps.MapTypeStyle> styles =
183-
captured['styles'] as List<gmaps.MapTypeStyle>;
191+
captured as List<gmaps.MapTypeStyle>;
184192
expect(styles.length, 1);
185193
// Let's peek inside the styles...
186194
final gmaps.MapTypeStyle style = styles[0];
@@ -221,14 +229,13 @@ void main() {
221229
plugin.debugSetMapById(<int, GoogleMapController>{mapId: controller});
222230
});
223231
// Options
224-
testWidgets('updateMapOptions', (WidgetTester tester) async {
225-
final Map<String, dynamic> expectedMapOptions = <String, dynamic>{
226-
'someOption': 12345
227-
};
232+
testWidgets('updateMapConfiguration', (WidgetTester tester) async {
233+
const MapConfiguration configuration =
234+
MapConfiguration(mapType: MapType.satellite);
228235

229-
await plugin.updateMapOptions(expectedMapOptions, mapId: mapId);
236+
await plugin.updateMapConfiguration(configuration, mapId: mapId);
230237

231-
verify(controller.updateRawOptions(expectedMapOptions));
238+
verify(controller.updateMapConfiguration(configuration));
232239
});
233240
// Geometry
234241
testWidgets('updateMarkers', (WidgetTester tester) async {

packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_plugin_test.mocks.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'dart:async' as _i2;
66

7+
import 'package:google_maps/google_maps.dart' as _i5;
78
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'
89
as _i3;
910
import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' as _i4;
@@ -68,8 +69,12 @@ class MockGoogleMapController extends _i1.Mock
6869
void init() => super.noSuchMethod(Invocation.method(#init, []),
6970
returnValueForMissingStub: null);
7071
@override
71-
void updateRawOptions(Map<String, dynamic>? optionsUpdate) =>
72-
super.noSuchMethod(Invocation.method(#updateRawOptions, [optionsUpdate]),
72+
void updateMapConfiguration(_i3.MapConfiguration? update) =>
73+
super.noSuchMethod(Invocation.method(#updateMapConfiguration, [update]),
74+
returnValueForMissingStub: null);
75+
@override
76+
void updateStyles(List<_i5.MapTypeStyle>? styles) =>
77+
super.noSuchMethod(Invocation.method(#updateStyles, [styles]),
7378
returnValueForMissingStub: null);
7479
@override
7580
_i2.Future<_i3.LatLngBounds> getVisibleRegion() => (super.noSuchMethod(

packages/google_maps_flutter/google_maps_flutter_web/lib/google_maps_flutter_web.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import 'dart:html';
1010
import 'dart:js_util';
1111

1212
import 'package:flutter/foundation.dart';
13-
import 'package:flutter/gestures.dart';
1413
import 'package:flutter/material.dart';
1514
import 'package:flutter/services.dart';
1615
import 'package:flutter/widgets.dart';

packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,6 @@ final gmaps.LatLngBounds _nullGmapsLatLngBounds =
1313
const String _defaultCssColor = '#000000';
1414
const double _defaultCssOpacity = 0.0;
1515

16-
// Indices in the plugin side don't match with the ones
17-
// in the gmaps lib. This translates from plugin -> gmaps.
18-
final Map<int, gmaps.MapTypeId> _mapTypeToMapTypeId = <int, gmaps.MapTypeId>{
19-
0: gmaps.MapTypeId.ROADMAP, // "none" in the plugin
20-
1: gmaps.MapTypeId.ROADMAP,
21-
2: gmaps.MapTypeId.SATELLITE,
22-
3: gmaps.MapTypeId.TERRAIN,
23-
4: gmaps.MapTypeId.HYBRID,
24-
};
25-
2616
// Converts a [Color] into a valid CSS value #RRGGBB.
2717
String _getCssColor(Color color) {
2818
if (color == null) {
@@ -55,49 +45,64 @@ double _getCssOpacity(Color color) {
5545
// indoorViewEnabled seems to not have an equivalent in web
5646
// buildingsEnabled seems to not have an equivalent in web
5747
// padding seems to behave differently in web than mobile. You can't move UI elements in web.
58-
gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, Object?> rawOptions) {
48+
gmaps.MapOptions _configurationAndStyleToGmapsOptions(
49+
MapConfiguration configuration, List<gmaps.MapTypeStyle> styles) {
5950
final gmaps.MapOptions options = gmaps.MapOptions();
6051

61-
if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) {
62-
options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']];
52+
if (configuration.mapType != null) {
53+
options.mapTypeId = _gmapTypeIDForPluginType(configuration.mapType!);
6354
}
6455

65-
if (rawOptions['minMaxZoomPreference'] != null) {
66-
final List<Object?> minMaxPreference =
67-
rawOptions['minMaxZoomPreference']! as List<Object?>;
56+
final MinMaxZoomPreference? zoomPreference =
57+
configuration.minMaxZoomPreference;
58+
if (zoomPreference != null) {
6859
options
69-
..minZoom = minMaxPreference[0] as num?
70-
..maxZoom = minMaxPreference[1] as num?;
60+
..minZoom = zoomPreference.minZoom
61+
..maxZoom = zoomPreference.maxZoom;
7162
}
7263

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

78-
if (rawOptions['zoomControlsEnabled'] != null) {
79-
options.zoomControl = rawOptions['zoomControlsEnabled'] as bool?;
80-
}
81-
82-
if (rawOptions['styles'] != null) {
83-
options.styles = rawOptions['styles'] as List<gmaps.MapTypeStyle?>?;
69+
if (configuration.zoomControlsEnabled != null) {
70+
options.zoomControl = configuration.zoomControlsEnabled;
8471
}
8572

86-
if (rawOptions['scrollGesturesEnabled'] == false ||
87-
rawOptions['zoomGesturesEnabled'] == false) {
73+
if (configuration.scrollGesturesEnabled == false ||
74+
configuration.zoomGesturesEnabled == false) {
8875
options.gestureHandling = 'none';
8976
} else {
9077
options.gestureHandling = 'auto';
9178
}
9279

93-
// These don't have any rawOptions entry, but they seem to be off in the native maps.
80+
// These don't have any configuration entries, but they seem to be off in the
81+
// native maps.
9482
options.mapTypeControl = false;
9583
options.fullscreenControl = false;
9684
options.streetViewControl = false;
9785

86+
options.styles = styles;
87+
9888
return options;
9989
}
10090

91+
gmaps.MapTypeId _gmapTypeIDForPluginType(MapType type) {
92+
switch (type) {
93+
case MapType.satellite:
94+
return gmaps.MapTypeId.SATELLITE;
95+
case MapType.terrain:
96+
return gmaps.MapTypeId.TERRAIN;
97+
case MapType.hybrid:
98+
return gmaps.MapTypeId.HYBRID;
99+
case MapType.normal:
100+
case MapType.none:
101+
default:
102+
return gmaps.MapTypeId.ROADMAP;
103+
}
104+
}
105+
101106
gmaps.MapOptions _applyInitialPosition(
102107
CameraPosition initialPosition,
103108
gmaps.MapOptions options,
@@ -111,11 +116,6 @@ gmaps.MapOptions _applyInitialPosition(
111116
return options;
112117
}
113118

114-
// Extracts the status of the traffic layer from the rawOptions map.
115-
bool _isTrafficLayerEnabled(Map<String, Object?> rawOptions) {
116-
return rawOptions['trafficEnabled'] as bool? ?? false;
117-
}
118-
119119
// The keys we'd expect to see in a serialized MapTypeStyle JSON object.
120120
final Set<String> _mapStyleKeys = <String>{
121121
'elementType',

0 commit comments

Comments
 (0)