mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
Update Place Tracker to use latest version of plugin (#59)
This commit is contained in:
10
place_tracker/analysis_options.yaml
Normal file
10
place_tracker/analysis_options.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
analyzer:
|
||||||
|
errors:
|
||||||
|
# treat missing required parameters as a warning (not a hint)
|
||||||
|
missing_required_param: warning
|
||||||
|
# treat missing returns as a warning (not a hint)
|
||||||
|
missing_return: warning
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
- unawaited_futures
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# platform :ios, '9.0'
|
platform :ios, '9.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#include "AppDelegate.h"
|
#include "AppDelegate.h"
|
||||||
#include "GeneratedPluginRegistrant.h"
|
#include "GeneratedPluginRegistrant.h"
|
||||||
|
#import "GoogleMaps/GoogleMaps.h"
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application
|
- (BOOL)application:(UIApplication *)application
|
||||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
|
[GMSServices provideAPIKey:@"YOUR KEY HERE"];
|
||||||
[GeneratedPluginRegistrant registerWithRegistry:self];
|
[GeneratedPluginRegistrant registerWithRegistry:self];
|
||||||
// Override point for customization after application launch.
|
// Override point for customization after application launch.
|
||||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||||
|
|||||||
@@ -41,5 +41,7 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>io.flutter.embedded_views_preview</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class PlaceDetails extends StatefulWidget {
|
|||||||
class PlaceDetailsState extends State<PlaceDetails> {
|
class PlaceDetailsState extends State<PlaceDetails> {
|
||||||
Place _place;
|
Place _place;
|
||||||
GoogleMapController _mapController;
|
GoogleMapController _mapController;
|
||||||
|
final Set<Marker> _markers = {};
|
||||||
|
|
||||||
final TextEditingController _nameController = TextEditingController();
|
final TextEditingController _nameController = TextEditingController();
|
||||||
final TextEditingController _descriptionController = TextEditingController();
|
final TextEditingController _descriptionController = TextEditingController();
|
||||||
@@ -39,7 +40,12 @@ class PlaceDetailsState extends State<PlaceDetails> {
|
|||||||
|
|
||||||
void _onMapCreated(GoogleMapController controller) {
|
void _onMapCreated(GoogleMapController controller) {
|
||||||
_mapController = controller;
|
_mapController = controller;
|
||||||
_mapController.addMarker(MarkerOptions(position: _place.latLng));
|
setState(() {
|
||||||
|
_markers.add(Marker(
|
||||||
|
markerId: MarkerId(_place.latLng.toString()),
|
||||||
|
position: _place.latLng,
|
||||||
|
));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _detailsBody() {
|
Widget _detailsBody() {
|
||||||
@@ -74,6 +80,7 @@ class PlaceDetailsState extends State<PlaceDetails> {
|
|||||||
center: _place.latLng,
|
center: _place.latLng,
|
||||||
mapController: _mapController,
|
mapController: _mapController,
|
||||||
onMapCreated: _onMapCreated,
|
onMapCreated: _onMapCreated,
|
||||||
|
markers: _markers,
|
||||||
),
|
),
|
||||||
const _Reviews(),
|
const _Reviews(),
|
||||||
],
|
],
|
||||||
@@ -210,6 +217,7 @@ class _Map extends StatelessWidget {
|
|||||||
@required this.center,
|
@required this.center,
|
||||||
@required this.mapController,
|
@required this.mapController,
|
||||||
@required this.onMapCreated,
|
@required this.onMapCreated,
|
||||||
|
@required this.markers,
|
||||||
Key key,
|
Key key,
|
||||||
}) : assert(center != null),
|
}) : assert(center != null),
|
||||||
assert(onMapCreated != null),
|
assert(onMapCreated != null),
|
||||||
@@ -218,6 +226,7 @@ class _Map extends StatelessWidget {
|
|||||||
final LatLng center;
|
final LatLng center;
|
||||||
final GoogleMapController mapController;
|
final GoogleMapController mapController;
|
||||||
final ArgumentCallback<GoogleMapController> onMapCreated;
|
final ArgumentCallback<GoogleMapController> onMapCreated;
|
||||||
|
final Set<Marker> markers;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -229,16 +238,15 @@ class _Map extends StatelessWidget {
|
|||||||
height: 240.0,
|
height: 240.0,
|
||||||
child: GoogleMap(
|
child: GoogleMap(
|
||||||
onMapCreated: onMapCreated,
|
onMapCreated: onMapCreated,
|
||||||
options: GoogleMapOptions(
|
initialCameraPosition: CameraPosition(
|
||||||
cameraPosition: CameraPosition(
|
target: center,
|
||||||
target: center,
|
zoom: 16.0,
|
||||||
zoom: 16.0,
|
|
||||||
),
|
|
||||||
zoomGesturesEnabled: false,
|
|
||||||
rotateGesturesEnabled: false,
|
|
||||||
tiltGesturesEnabled: false,
|
|
||||||
scrollGesturesEnabled: false,
|
|
||||||
),
|
),
|
||||||
|
markers: markers,
|
||||||
|
zoomGesturesEnabled: false,
|
||||||
|
rotateGesturesEnabled: false,
|
||||||
|
tiltGesturesEnabled: false,
|
||||||
|
scrollGesturesEnabled: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -41,49 +41,55 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
return places.where((Place place) => place.category == category).toList();
|
return places.where((Place place) => place.category == category).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
GoogleMapController mapController;
|
Completer<GoogleMapController> mapController = Completer();
|
||||||
|
|
||||||
|
MapType _currentMapType = MapType.normal;
|
||||||
|
|
||||||
|
LatLng _lastMapPosition;
|
||||||
|
|
||||||
Map<Marker, Place> _markedPlaces = Map<Marker, Place>();
|
Map<Marker, Place> _markedPlaces = Map<Marker, Place>();
|
||||||
|
|
||||||
|
final Set<Marker> _markers = {};
|
||||||
|
|
||||||
Marker _pendingMarker;
|
Marker _pendingMarker;
|
||||||
|
|
||||||
MapConfiguration _configuration;
|
MapConfiguration _configuration;
|
||||||
|
|
||||||
void onMapCreated(GoogleMapController controller) async {
|
void onMapCreated(GoogleMapController controller) async {
|
||||||
mapController = controller;
|
mapController.complete(controller);
|
||||||
mapController.onInfoWindowTapped.add(_onInfoWindowTapped);
|
_lastMapPosition = widget.center;
|
||||||
|
|
||||||
// Draw initial place markers on creation so that we have something
|
// Draw initial place markers on creation so that we have something
|
||||||
// interesting to look at.
|
// interesting to look at.
|
||||||
final Map<Marker, Place> places = await _markPlaces();
|
setState(() {
|
||||||
_zoomToFitPlaces(
|
for (Place place in AppState.of(context).places) {
|
||||||
|
_markers.add(_createPlaceMarker(place));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zoom to fit the initially selected category.
|
||||||
|
await _zoomToFitPlaces(
|
||||||
_getPlacesForCategory(
|
_getPlacesForCategory(
|
||||||
AppState.of(context).selectedCategory,
|
AppState.of(context).selectedCategory,
|
||||||
places.values.toList(),
|
_markedPlaces.values.toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<Marker, Place>> _markPlaces() async {
|
Marker _createPlaceMarker(Place place) {
|
||||||
await Future.wait(
|
final marker = Marker(
|
||||||
AppState.of(context).places.map((Place place) => _markPlace(place)));
|
markerId: MarkerId(place.latLng.toString()),
|
||||||
return _markedPlaces;
|
position: place.latLng,
|
||||||
}
|
infoWindow: InfoWindow(
|
||||||
|
title: place.name,
|
||||||
Future<void> _markPlace(Place place) async {
|
snippet: '${place.starRating} Star Rating',
|
||||||
final Marker marker = await mapController.addMarker(
|
onTap: () => _pushPlaceDetailsScreen(place),
|
||||||
MarkerOptions(
|
|
||||||
position: place.latLng,
|
|
||||||
icon: _getPlaceMarkerIcon(place.category),
|
|
||||||
infoWindowText: InfoWindowText(
|
|
||||||
place.name,
|
|
||||||
'${place.starRating} Star Rating',
|
|
||||||
),
|
|
||||||
visible: place.category == AppState.of(context).selectedCategory,
|
|
||||||
),
|
),
|
||||||
|
icon: _getPlaceMarkerIcon(place.category),
|
||||||
|
visible: place.category == AppState.of(context).selectedCategory,
|
||||||
);
|
);
|
||||||
_markedPlaces[marker] = place;
|
_markedPlaces[marker] = place;
|
||||||
}
|
return marker;
|
||||||
|
|
||||||
void _onInfoWindowTapped(Marker marker) {
|
|
||||||
_pushPlaceDetailsScreen(_markedPlaces[marker]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pushPlaceDetailsScreen(Place place) {
|
void _pushPlaceDetailsScreen(Place place) {
|
||||||
@@ -120,55 +126,64 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
AppState.updateWith(context, places: newPlaces);
|
AppState.updateWith(context, places: newPlaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateExistingPlaceMarker({@required Place place}) async {
|
void _updateExistingPlaceMarker({@required Place place}) {
|
||||||
Marker marker = _markedPlaces.keys
|
Marker marker = _markedPlaces.keys
|
||||||
.singleWhere((Marker value) => _markedPlaces[value].id == place.id);
|
.singleWhere((Marker value) => _markedPlaces[value].id == place.id);
|
||||||
|
|
||||||
// Set marker visibility to false to ensure the info window is hidden. Once
|
setState(() {
|
||||||
// the plugin fully supports the Google Maps API, use hideInfoWindow()
|
final updatedMarker = marker.copyWith(
|
||||||
// instead.
|
infoWindowParam: InfoWindow(
|
||||||
await mapController.updateMarker(
|
title: place.name,
|
||||||
marker,
|
snippet:
|
||||||
MarkerOptions(
|
place.starRating != 0 ? '${place.starRating} Star Rating' : null,
|
||||||
visible: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await mapController.updateMarker(
|
|
||||||
marker,
|
|
||||||
MarkerOptions(
|
|
||||||
infoWindowText: InfoWindowText(
|
|
||||||
place.name,
|
|
||||||
place.starRating != 0 ? '${place.starRating} Star Rating' : null,
|
|
||||||
),
|
),
|
||||||
visible: true,
|
);
|
||||||
),
|
_updateMarker(marker: marker, updatedMarker: updatedMarker, place: place);
|
||||||
);
|
});
|
||||||
|
|
||||||
_markedPlaces[marker] = place;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _switchSelectedCategory(PlaceCategory category) {
|
void _updateMarker({
|
||||||
|
@required Marker marker,
|
||||||
|
@required Marker updatedMarker,
|
||||||
|
@required Place place,
|
||||||
|
}) {
|
||||||
|
_markers.remove(marker);
|
||||||
|
_markedPlaces.remove(marker);
|
||||||
|
|
||||||
|
_markers.add(updatedMarker);
|
||||||
|
_markedPlaces[updatedMarker] = place;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _switchSelectedCategory(PlaceCategory category) async {
|
||||||
AppState.updateWith(context, selectedCategory: category);
|
AppState.updateWith(context, selectedCategory: category);
|
||||||
_showPlacesForSelectedCategory(category);
|
await _showPlacesForSelectedCategory(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _showPlacesForSelectedCategory(PlaceCategory category) async {
|
Future<void> _showPlacesForSelectedCategory(PlaceCategory category) async {
|
||||||
await Future.wait(
|
setState(() {
|
||||||
_markedPlaces.keys.map(
|
for (Marker marker in List.of(_markedPlaces.keys)) {
|
||||||
(Marker marker) => mapController.updateMarker(
|
final place = _markedPlaces[marker];
|
||||||
marker,
|
final updatedMarker = marker.copyWith(
|
||||||
MarkerOptions(
|
visibleParam: place.category == category,
|
||||||
visible: _markedPlaces[marker].category == category,
|
);
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
_zoomToFitPlaces(
|
_updateMarker(
|
||||||
_getPlacesForCategory(category, _markedPlaces.values.toList()));
|
marker: marker,
|
||||||
|
updatedMarker: updatedMarker,
|
||||||
|
place: place,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await _zoomToFitPlaces(_getPlacesForCategory(
|
||||||
|
category,
|
||||||
|
_markedPlaces.values.toList(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _zoomToFitPlaces(List<Place> places) {
|
Future<void> _zoomToFitPlaces(List<Place> places) async {
|
||||||
|
GoogleMapController controller = await mapController.future;
|
||||||
|
|
||||||
// Default min/max values to latitude and longitude of center.
|
// Default min/max values to latitude and longitude of center.
|
||||||
double minLat = widget.center.latitude;
|
double minLat = widget.center.latitude;
|
||||||
double maxLat = widget.center.latitude;
|
double maxLat = widget.center.latitude;
|
||||||
@@ -182,7 +197,7 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
maxLong = max(maxLong, place.longitude);
|
maxLong = max(maxLong, place.longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
mapController.animateCamera(
|
await controller.animateCamera(
|
||||||
CameraUpdate.newLatLngBounds(
|
CameraUpdate.newLatLngBounds(
|
||||||
LatLngBounds(
|
LatLngBounds(
|
||||||
southwest: LatLng(minLat, minLong),
|
southwest: LatLng(minLat, minLong),
|
||||||
@@ -194,40 +209,49 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _onAddPlacePressed() async {
|
void _onAddPlacePressed() async {
|
||||||
Marker newMarker = await mapController.addMarker(
|
setState(() {
|
||||||
MarkerOptions(
|
final newMarker = Marker(
|
||||||
position: LatLng(
|
markerId: MarkerId(_lastMapPosition.toString()),
|
||||||
mapController.cameraPosition.target.latitude,
|
position: _lastMapPosition,
|
||||||
mapController.cameraPosition.target.longitude,
|
infoWindow: InfoWindow(title: 'New Place'),
|
||||||
),
|
|
||||||
draggable: true,
|
draggable: true,
|
||||||
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen),
|
icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueGreen),
|
||||||
),
|
);
|
||||||
);
|
_markers.add(newMarker);
|
||||||
setState(() {
|
|
||||||
_pendingMarker = newMarker;
|
_pendingMarker = newMarker;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _confirmAddPlace(BuildContext context) async {
|
void _confirmAddPlace(BuildContext context) async {
|
||||||
if (_pendingMarker != null) {
|
if (_pendingMarker != null) {
|
||||||
await mapController.updateMarker(
|
|
||||||
_pendingMarker,
|
|
||||||
MarkerOptions(
|
|
||||||
icon: _getPlaceMarkerIcon(AppState.of(context).selectedCategory),
|
|
||||||
infoWindowText: InfoWindowText('New Place', null),
|
|
||||||
draggable: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create a new Place and map it to the marker we just added.
|
// Create a new Place and map it to the marker we just added.
|
||||||
final Place newPlace = Place(
|
final Place newPlace = Place(
|
||||||
id: Uuid().v1(),
|
id: Uuid().v1(),
|
||||||
latLng: _pendingMarker.options.position,
|
latLng: _pendingMarker.position,
|
||||||
name: _pendingMarker.options.infoWindowText.title,
|
name: _pendingMarker.infoWindow.title,
|
||||||
category: AppState.of(context).selectedCategory,
|
category: AppState.of(context).selectedCategory,
|
||||||
);
|
);
|
||||||
_markedPlaces[_pendingMarker] = newPlace;
|
|
||||||
|
setState(() {
|
||||||
|
final updatedMarker = _pendingMarker.copyWith(
|
||||||
|
iconParam: _getPlaceMarkerIcon(AppState.of(context).selectedCategory),
|
||||||
|
infoWindowParam: InfoWindow(
|
||||||
|
title: 'New Place',
|
||||||
|
snippet: null,
|
||||||
|
onTap: () => _pushPlaceDetailsScreen(newPlace),
|
||||||
|
),
|
||||||
|
draggableParam: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
_updateMarker(
|
||||||
|
marker: _pendingMarker,
|
||||||
|
updatedMarker: updatedMarker,
|
||||||
|
place: newPlace,
|
||||||
|
);
|
||||||
|
|
||||||
|
_pendingMarker = null;
|
||||||
|
});
|
||||||
|
|
||||||
// Show a confirmation snackbar that has an action to edit the new place.
|
// Show a confirmation snackbar that has an action to edit the new place.
|
||||||
Scaffold.of(context).showSnackBar(
|
Scaffold.of(context).showSnackBar(
|
||||||
@@ -257,29 +281,25 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
AppState.updateWith(context, places: newPlaces);
|
AppState.updateWith(context, places: newPlaces);
|
||||||
|
|
||||||
setState(() {
|
|
||||||
_pendingMarker = null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _cancelAddPlace() {
|
void _cancelAddPlace() {
|
||||||
if (_pendingMarker != null) {
|
if (_pendingMarker != null) {
|
||||||
mapController.removeMarker(_pendingMarker);
|
|
||||||
setState(() {
|
setState(() {
|
||||||
|
_markers.remove(_pendingMarker);
|
||||||
_pendingMarker = null;
|
_pendingMarker = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onToggleMapTypePressed() {
|
void _onToggleMapTypePressed() {
|
||||||
final MapType nextType = MapType.values[
|
final MapType nextType =
|
||||||
(mapController.options.mapType.index + 1) % MapType.values.length];
|
MapType.values[(_currentMapType.index + 1) % MapType.values.length];
|
||||||
|
|
||||||
mapController.updateMapOptions(
|
setState(() {
|
||||||
GoogleMapOptions(mapType: nextType),
|
_currentMapType = nextType;
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _maybeUpdateMapConfiguration() async {
|
Future<void> _maybeUpdateMapConfiguration() async {
|
||||||
@@ -297,16 +317,15 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
newConfiguration.selectedCategory) {
|
newConfiguration.selectedCategory) {
|
||||||
// If the configuration change is only a category change, just update
|
// If the configuration change is only a category change, just update
|
||||||
// the marker visibilities.
|
// the marker visibilities.
|
||||||
_showPlacesForSelectedCategory(newConfiguration.selectedCategory);
|
await _showPlacesForSelectedCategory(newConfiguration.selectedCategory);
|
||||||
} else {
|
} else {
|
||||||
// At this point, we know the places have been updated from the list
|
// At this point, we know the places have been updated from the list
|
||||||
// view. We need to reconfigure the map to respect the updates.
|
// view. We need to reconfigure the map to respect the updates.
|
||||||
await Future.wait(
|
newConfiguration.places
|
||||||
newConfiguration.places
|
.where((Place p) => !_configuration.places.contains(p))
|
||||||
.where((Place p) => !_configuration.places.contains(p))
|
.map((Place value) => _updateExistingPlaceMarker(place: value));
|
||||||
.map((Place value) => _updateExistingPlaceMarker(place: value)),
|
|
||||||
);
|
await _zoomToFitPlaces(
|
||||||
_zoomToFitPlaces(
|
|
||||||
_getPlacesForCategory(
|
_getPlacesForCategory(
|
||||||
newConfiguration.selectedCategory,
|
newConfiguration.selectedCategory,
|
||||||
newConfiguration.places,
|
newConfiguration.places,
|
||||||
@@ -331,13 +350,13 @@ class PlaceMapState extends State<PlaceMap> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
GoogleMap(
|
GoogleMap(
|
||||||
onMapCreated: onMapCreated,
|
onMapCreated: onMapCreated,
|
||||||
options: GoogleMapOptions(
|
initialCameraPosition: CameraPosition(
|
||||||
trackCameraPosition: true,
|
target: widget.center,
|
||||||
cameraPosition: CameraPosition(
|
zoom: 11.0,
|
||||||
target: widget.center,
|
|
||||||
zoom: 11.0,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
mapType: _currentMapType,
|
||||||
|
markers: _markers,
|
||||||
|
onCameraMove: (position) => _lastMapPosition = position.target,
|
||||||
),
|
),
|
||||||
_CategoryButtonBar(
|
_CategoryButtonBar(
|
||||||
selectedPlaceCategory: AppState.of(context).selectedCategory,
|
selectedPlaceCategory: AppState.of(context).selectedCategory,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ dependencies:
|
|||||||
|
|
||||||
cupertino_icons: ^0.1.2
|
cupertino_icons: ^0.1.2
|
||||||
|
|
||||||
google_maps_flutter: ^0.0.3
|
google_maps_flutter: ^0.4.0
|
||||||
|
|
||||||
uuid: 1.0.3
|
uuid: 1.0.3
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user