Skip to content

Commit bc2514e

Browse files
[google_maps_flutter_web] Make google_maps_flutter_web work with latest plugins (flutter#3673)
Co-authored-by: David Iglesias Teixeira <ditman@gmail.com>
1 parent 025c8c1 commit bc2514e

File tree

8 files changed

+224
-288
lines changed

8 files changed

+224
-288
lines changed

packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.2.0
2+
3+
* Make this plugin compatible with the rest of null-safe plugins.
4+
* Noop tile overlays methods, so they don't crash on web.
5+
6+
**NOTE**: This plugin is **not** null-safe yet!
7+
18
## 0.1.2
29

310
* Update min Flutter SDK to 1.20.0.

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

Lines changed: 19 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ final _nullLatLngBounds = LatLngBounds(
1111
);
1212

1313
// Defaults taken from the Google Maps Platform SDK documentation.
14-
final _defaultStrokeColor = Colors.black.value;
15-
final _defaultFillColor = Colors.transparent.value;
1614
final _defaultCssColor = '#000000';
1715
final _defaultCssOpacity = 0.0;
1816

@@ -59,41 +57,39 @@ double _getCssOpacity(Color color) {
5957
// buildingsEnabled seems to not have an equivalent in web
6058
// padding seems to behave differently in web than mobile. You can't move UI elements in web.
6159
gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, dynamic> rawOptions) {
62-
Map<String, dynamic> optionsUpdate = rawOptions['options'] ?? {};
63-
6460
gmaps.MapOptions options = gmaps.MapOptions();
6561

66-
if (_mapTypeToMapTypeId.containsKey(optionsUpdate['mapType'])) {
67-
options.mapTypeId = _mapTypeToMapTypeId[optionsUpdate['mapType']];
62+
if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) {
63+
options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']];
6864
}
6965

70-
if (optionsUpdate['minMaxZoomPreference'] != null) {
66+
if (rawOptions['minMaxZoomPreference'] != null) {
7167
options
72-
..minZoom = optionsUpdate['minMaxZoomPreference'][0]
73-
..maxZoom = optionsUpdate['minMaxZoomPreference'][1];
68+
..minZoom = rawOptions['minMaxZoomPreference'][0]
69+
..maxZoom = rawOptions['minMaxZoomPreference'][1];
7470
}
7571

76-
if (optionsUpdate['cameraTargetBounds'] != null) {
72+
if (rawOptions['cameraTargetBounds'] != null) {
7773
// Needs gmaps.MapOptions.restriction and gmaps.MapRestriction
7874
// see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction
7975
}
8076

81-
if (optionsUpdate['zoomControlsEnabled'] != null) {
82-
options.zoomControl = optionsUpdate['zoomControlsEnabled'];
77+
if (rawOptions['zoomControlsEnabled'] != null) {
78+
options.zoomControl = rawOptions['zoomControlsEnabled'];
8379
}
8480

85-
if (optionsUpdate['styles'] != null) {
86-
options.styles = optionsUpdate['styles'];
81+
if (rawOptions['styles'] != null) {
82+
options.styles = rawOptions['styles'];
8783
}
8884

89-
if (optionsUpdate['scrollGesturesEnabled'] == false ||
90-
optionsUpdate['zoomGesturesEnabled'] == false) {
85+
if (rawOptions['scrollGesturesEnabled'] == false ||
86+
rawOptions['zoomGesturesEnabled'] == false) {
9187
options.gestureHandling = 'none';
9288
} else {
9389
options.gestureHandling = 'auto';
9490
}
9591

96-
// These don't have any optionUpdate entry, but they seem to be off in the native maps.
92+
// These don't have any rawOptions entry, but they seem to be off in the native maps.
9793
options.mapTypeControl = false;
9894
options.fullscreenControl = false;
9995
options.streetViewControl = false;
@@ -102,26 +98,21 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, dynamic> rawOptions) {
10298
}
10399

104100
gmaps.MapOptions _applyInitialPosition(
105-
Map<String, dynamic> rawOptions,
101+
CameraPosition initialPosition,
106102
gmaps.MapOptions options,
107103
) {
108104
// Adjust the initial position, if passed...
109-
Map<String, dynamic> initialPosition = rawOptions['initialCameraPosition'];
110105
if (initialPosition != null) {
111-
final position = CameraPosition.fromMap(initialPosition);
112-
options.zoom = position.zoom;
113-
options.center =
114-
gmaps.LatLng(position.target.latitude, position.target.longitude);
106+
options.zoom = initialPosition.zoom;
107+
options.center = gmaps.LatLng(
108+
initialPosition.target.latitude, initialPosition.target.longitude);
115109
}
116110
return options;
117111
}
118112

119113
// Extracts the status of the traffic layer from the rawOptions map.
120114
bool _isTrafficLayerEnabled(Map<String, dynamic> rawOptions) {
121-
if (rawOptions['options'] == null) {
122-
return false;
123-
}
124-
return rawOptions['options']['trafficEnabled'] ?? false;
115+
return rawOptions['trafficEnabled'] ?? false;
125116
}
126117

127118
// Coverts the incoming JSON object into a List of MapTypeStyler objects.
@@ -257,126 +248,6 @@ CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) {
257248
);
258249
}
259250

260-
Set<Marker> _rawOptionsToInitialMarkers(Map<String, dynamic> rawOptions) {
261-
final List<Map<String, dynamic>> list = rawOptions['markersToAdd'];
262-
Set<Marker> markers = {};
263-
markers.addAll(list?.map((rawMarker) {
264-
Offset offset;
265-
LatLng position;
266-
InfoWindow infoWindow;
267-
BitmapDescriptor icon;
268-
if (rawMarker['anchor'] != null) {
269-
offset = Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1]));
270-
}
271-
if (rawMarker['position'] != null) {
272-
position = LatLng.fromJson(rawMarker['position']);
273-
}
274-
if (rawMarker['infoWindow'] != null) {
275-
final String title = rawMarker['infoWindow']['title'];
276-
final String snippet = rawMarker['infoWindow']['snippet'];
277-
if (title != null || snippet != null) {
278-
infoWindow = InfoWindow(
279-
title: title ?? '',
280-
snippet: snippet ?? '',
281-
);
282-
}
283-
}
284-
if (rawMarker['icon'] != null) {
285-
icon = BitmapDescriptor.fromJson(rawMarker['icon']);
286-
}
287-
return Marker(
288-
markerId: MarkerId(rawMarker['markerId']),
289-
alpha: rawMarker['alpha'],
290-
anchor: offset,
291-
consumeTapEvents: rawMarker['consumeTapEvents'],
292-
draggable: rawMarker['draggable'],
293-
flat: rawMarker['flat'],
294-
icon: icon,
295-
infoWindow: infoWindow,
296-
position: position ?? _nullLatLng,
297-
rotation: rawMarker['rotation'],
298-
visible: rawMarker['visible'],
299-
zIndex: rawMarker['zIndex'],
300-
);
301-
}) ??
302-
[]);
303-
return markers;
304-
}
305-
306-
Set<Circle> _rawOptionsToInitialCircles(Map<String, dynamic> rawOptions) {
307-
final List<Map<String, dynamic>> list = rawOptions['circlesToAdd'];
308-
Set<Circle> circles = {};
309-
circles.addAll(list?.map((rawCircle) {
310-
LatLng center;
311-
if (rawCircle['center'] != null) {
312-
center = LatLng.fromJson(rawCircle['center']);
313-
}
314-
return Circle(
315-
circleId: CircleId(rawCircle['circleId']),
316-
consumeTapEvents: rawCircle['consumeTapEvents'],
317-
fillColor: Color(rawCircle['fillColor'] ?? _defaultFillColor),
318-
center: center ?? _nullLatLng,
319-
radius: rawCircle['radius'],
320-
strokeColor: Color(rawCircle['strokeColor'] ?? _defaultStrokeColor),
321-
strokeWidth: rawCircle['strokeWidth'],
322-
visible: rawCircle['visible'],
323-
zIndex: rawCircle['zIndex'],
324-
);
325-
}) ??
326-
[]);
327-
return circles;
328-
}
329-
330-
// Unsupported on the web: endCap, jointType, patterns and startCap.
331-
Set<Polyline> _rawOptionsToInitialPolylines(Map<String, dynamic> rawOptions) {
332-
final List<Map<String, dynamic>> list = rawOptions['polylinesToAdd'];
333-
Set<Polyline> polylines = {};
334-
polylines.addAll(list?.map((rawPolyline) {
335-
return Polyline(
336-
polylineId: PolylineId(rawPolyline['polylineId']),
337-
consumeTapEvents: rawPolyline['consumeTapEvents'],
338-
color: Color(rawPolyline['color'] ?? _defaultStrokeColor),
339-
geodesic: rawPolyline['geodesic'],
340-
visible: rawPolyline['visible'],
341-
zIndex: rawPolyline['zIndex'],
342-
width: rawPolyline['width'],
343-
points: rawPolyline['points']
344-
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
345-
?.toList(),
346-
);
347-
}) ??
348-
[]);
349-
return polylines;
350-
}
351-
352-
Set<Polygon> _rawOptionsToInitialPolygons(Map<String, dynamic> rawOptions) {
353-
final List<Map<String, dynamic>> list = rawOptions['polygonsToAdd'];
354-
Set<Polygon> polygons = {};
355-
356-
polygons.addAll(list?.map((rawPolygon) {
357-
return Polygon(
358-
polygonId: PolygonId(rawPolygon['polygonId']),
359-
consumeTapEvents: rawPolygon['consumeTapEvents'],
360-
fillColor: Color(rawPolygon['fillColor'] ?? _defaultFillColor),
361-
geodesic: rawPolygon['geodesic'],
362-
strokeColor: Color(rawPolygon['strokeColor'] ?? _defaultStrokeColor),
363-
strokeWidth: rawPolygon['strokeWidth'],
364-
visible: rawPolygon['visible'],
365-
zIndex: rawPolygon['zIndex'],
366-
points: rawPolygon['points']
367-
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
368-
?.toList(),
369-
holes: rawPolygon['holes']
370-
?.map<List<LatLng>>((List hole) => hole
371-
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
372-
?.toList())
373-
?.toList(),
374-
);
375-
}) ??
376-
[]);
377-
return polygons;
378-
}
379-
380251
// Convert plugin objects to gmaps.Options objects
381252
// TODO: Move to their appropriate objects, maybe make these copy constructors:
382253
// Marker.fromMarker(anotherMarker, moreOptions);
@@ -550,7 +421,7 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline(
550421

551422
// Translates a [CameraUpdate] into operations on a [gmaps.GMap].
552423
void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) {
553-
final json = update.toJson();
424+
final json = update.toJson() as List<dynamic>;
554425
switch (json[0]) {
555426
case 'newCameraPosition':
556427
map.heading = json[1]['bearing'];

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

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@ class GoogleMapController {
1414
// The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed.
1515
final int _mapId;
1616

17+
final CameraPosition _initialCameraPosition;
18+
final Set<Marker> _markers;
19+
final Set<Polygon> _polygons;
20+
final Set<Polyline> _polylines;
21+
final Set<Circle> _circles;
1722
// The raw options passed by the user, before converting to gmaps.
1823
// Caching this allows us to re-create the map faithfully when needed.
19-
Map<String, dynamic> _rawOptions = {
20-
'options': {},
21-
};
24+
Map<String, dynamic> _rawMapOptions = <String, dynamic>{};
2225

2326
// Creates the 'viewType' for the _widget
2427
String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId';
@@ -68,10 +71,23 @@ class GoogleMapController {
6871
GoogleMapController({
6972
@required int mapId,
7073
@required StreamController<MapEvent> streamController,
71-
@required Map<String, dynamic> rawOptions,
72-
}) : this._mapId = mapId,
73-
this._streamController = streamController,
74-
this._rawOptions = rawOptions {
74+
@required CameraPosition initialCameraPosition,
75+
Set<Marker> markers = const <Marker>{},
76+
Set<Polygon> polygons = const <Polygon>{},
77+
Set<Polyline> polylines = const <Polyline>{},
78+
Set<Circle> circles = const <Circle>{},
79+
Set<TileOverlay> tileOverlays = const <TileOverlay>{},
80+
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers =
81+
const <Factory<OneSequenceGestureRecognizer>>{},
82+
Map<String, dynamic> mapOptions = const <String, dynamic>{},
83+
}) : _mapId = mapId,
84+
_streamController = streamController,
85+
_initialCameraPosition = initialCameraPosition,
86+
_markers = markers,
87+
_polygons = polygons,
88+
_polylines = polylines,
89+
_circles = circles,
90+
_rawMapOptions = mapOptions {
7591
_circlesController = CirclesController(stream: this._streamController);
7692
_polygonsController = PolygonsController(stream: this._streamController);
7793
_polylinesController = PolylinesController(stream: this._streamController);
@@ -121,9 +137,9 @@ class GoogleMapController {
121137
/// Failure to call this method would result in the GMap not rendering at all,
122138
/// and most of the public methods on this class no-op'ing.
123139
void init() {
124-
var options = _rawOptionsToGmapsOptions(_rawOptions);
140+
var options = _rawOptionsToGmapsOptions(_rawMapOptions);
125141
// Initial position can only to be set here!
126-
options = _applyInitialPosition(_rawOptions, options);
142+
options = _applyInitialPosition(_initialCameraPosition, options);
127143

128144
// Create the map...
129145
_googleMap = _createMap(_div, options);
@@ -132,13 +148,13 @@ class GoogleMapController {
132148
_attachGeometryControllers(_googleMap);
133149

134150
_renderInitialGeometry(
135-
markers: _rawOptionsToInitialMarkers(_rawOptions),
136-
circles: _rawOptionsToInitialCircles(_rawOptions),
137-
polygons: _rawOptionsToInitialPolygons(_rawOptions),
138-
polylines: _rawOptionsToInitialPolylines(_rawOptions),
151+
markers: _markers,
152+
circles: _circles,
153+
polygons: _polygons,
154+
polylines: _polylines,
139155
);
140156

141-
_setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawOptions));
157+
_setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawMapOptions));
142158
}
143159

144160
// Funnels map gmap events into the plugin's stream controller.
@@ -196,20 +212,15 @@ class GoogleMapController {
196212
_polylinesController.addPolylines(polylines);
197213
}
198214

199-
// Merges new options coming from the plugin into the `key` entry of the _rawOptions map.
215+
// Merges new options coming from the plugin into the _rawMapOptions map.
200216
//
201-
// By default: `key` is 'options'.
202-
//
203-
// Returns the updated _rawOptions object.
204-
Map<String, dynamic> _mergeRawOptions(
205-
Map<String, dynamic> newOptions, {
206-
String key = 'options',
207-
}) {
208-
_rawOptions[key] = <String, dynamic>{
209-
...(_rawOptions[key] ?? {}),
217+
// Returns the updated _rawMapOptions object.
218+
Map<String, dynamic> _mergeRawOptions(Map<String, dynamic> newOptions) {
219+
_rawMapOptions = <String, dynamic>{
220+
..._rawMapOptions,
210221
...newOptions,
211222
};
212-
return _rawOptions;
223+
return _rawMapOptions;
213224
}
214225

215226
/// Updates the map options from a `Map<String, dynamic>`.

0 commit comments

Comments
 (0)