diff --git a/.gitignore b/.gitignore
index c13c084..dca3b69 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,6 @@ pubspec.lock
# Directory created by dartdoc
# If you don't generate documentation locally you can remove this line.
doc/api/
+
+assets/private-settings.json
+android/app/src/main/AndroidManifest.xml
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest-Sample.xml
similarity index 51%
rename from android/app/src/main/AndroidManifest.xml
rename to android/app/src/main/AndroidManifest-Sample.xml
index 425bbec..b5d30e4 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest-Sample.xml
@@ -1,11 +1,13 @@
+ package="org.comunes.firesflutter">
+
+
+ android:name="io.flutter.app.FlutterApplication"
+ android:label="All Against The Fire!"
+ android:icon="@mipmap/launch_image">
+
+
+ android:name=".MainActivity"
+ android:launchMode="singleTop"
+ android:theme="@style/LaunchTheme"
+ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
+ android:hardwareAccelerated="true"
+ android:windowSoftInputMode="adjustResize">
+ android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
+ android:value="true"/>
+
diff --git a/android/build.gradle b/android/build.gradle
index 4476887..b7d7695 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -6,6 +6,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.2-4'
}
}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index cdde493..03878f6 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -41,5 +41,9 @@
UIViewControllerBasedStatusBarAppearance
+ NSLocationWhenInUseUsageDescription
+ Your location will be used to center our map and display fires near you
+ NSLocationAlwaysUsageDescription
+ Your location will be used notify fires near you
diff --git a/lib/activeFires.dart b/lib/activeFires.dart
index a871105..99d74cf 100644
--- a/lib/activeFires.dart
+++ b/lib/activeFires.dart
@@ -1,34 +1,244 @@
import 'package:flutter/material.dart';
+import 'package:location/location.dart';
import 'mainDrawer.dart';
+import 'genericMap.dart';
+import 'dart:async';
+import 'package:flutter/services.dart';
+import 'package:comunes_flutter/comunes_flutter.dart';
+import 'colors.dart';
+import 'placesAutocompleteUtils.dart';
+import 'basicLocation.dart';
+import 'package:collection/collection.dart' show lowerBound;
-class ActiveFiresMap extends StatelessWidget {
- static const String routeName = '/fires';
+class _ActiveFiresPageState extends State {
final GlobalKey _scaffoldKey = new GlobalKey();
+ // https://docs.flutter.io/flutter/dart-core/List-class.html
+ final List _saved = [];
+ int length;
+
+ _ActiveFiresPageState();
+
+ Widget _buildRow(BasicLocation loc) {
+ String desc = loc.description != null ? loc.description:
+ 'Position: ${loc.lat}, ${loc.lon}';
+ return new ListTile(
+ dense: false,
+ leading: const Icon(Icons.location_on),
+ // trailing: const Icon(Icons.delete),
+ title: new Text(desc),
+ onTap: () {
+ Navigator.push(context,
+ new MaterialPageRoute(builder: (context) => new GenericMap(title: desc, latitude: loc.lat, longitude: loc.lon)));
+ });
+ }
+
+ Widget _buildSavedLocations() {
+ return new ListView.builder(
+ padding: const EdgeInsets.all(16.0),
+ itemCount: _saved.length,
+ itemBuilder: (BuildContext _context, int i) {
+ // Add a one-pixel-high divider widget before each row
+ // in the ListView.
+ /* if (i.isOdd) {
+ return new Divider();
+ } */
+
+ // The syntax "i ~/ 2" divides i by 2 and returns an
+ // integer result.
+ // For example: 1, 2, 3, 4, 5 becomes 0, 1, 1, 2, 2.
+ // This calculates the actual number of saved items
+ // in the ListView, minus the divider widgets.
+ // final int index = i ~/ 2;
+ // print('$i $index');
+ // if (index >= _saved.length) return null;
+ return _buildItem(_saved.elementAt(i));
+ });
+ }
+
+ void handleUndo(BasicLocation item) {
+ print('Undo $item');
+ final int insertionIndex = lowerBound(_saved, item);
+ setState(() {
+ _saved.insert(insertionIndex, item);
+ });
+ }
+
+ Widget _buildItem(BasicLocation item) {
+ final ThemeData theme = Theme.of(context);
+ return new Dismissible(
+ key: new ObjectKey(item),
+ direction: DismissDirection.horizontal,
+ onDismissed: (DismissDirection direction) {
+ setState(() {
+ _saved.remove(item);
+ });
+ final String action = 'deleted';
+ _scaffoldKey.currentState.showSnackBar(new SnackBar(
+ content: new Text('You $action item'), // ${item.index}'),
+ action: new SnackBarAction(
+ label: 'UNDO',
+ onPressed: () {
+ handleUndo(item);
+ })));
+ },
+ background: new Container(
+ color: theme.primaryColor,
+ child: const ListTile(
+ leading:
+ const Icon(Icons.delete, color: Colors.white, size: 36.0))),
+ secondaryBackground: new Container(
+ color: theme.primaryColor,
+ child: const ListTile(
+ trailing:
+ const Icon(Icons.delete, color: Colors.white, size: 36.0))),
+ child: new Container(
+ decoration: new BoxDecoration(
+ color: theme.canvasColor,
+ border: new Border(
+ bottom: new BorderSide(color: theme.dividerColor))),
+ child: _buildRow(item)));
+ }
+
+ Future getUserLocation() async {
+ // FIXME do something with this
+
+ String error;
+ // Platform messages may fail, so we use a try/catch PlatformException.
+ try {
+ Location _location = new Location();
+ Map location = await _location.getLocation;
+ error = null;
+ print('location $location');
+
+ // It seems that the lib fails with lat/lon values
+ return new BasicLocation(
+ lon: location['latitude'], lat: location['longitude']);
+ } on PlatformException catch (e) {
+ if (e.code == 'PERMISSION_DENIED') {
+ error = 'Permission denied';
+ } else if (e.code == 'PERMISSION_DENIED_NEVER_ASK') {
+ error =
+ 'Permission denied - please ask the user to enable it from the app settings';
+ }
+ // FIXME
+ throw e;
+ }
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ length = _saved.length;
+ }
@override
Widget build(BuildContext context) {
+ print('Building Active Fires, saved $length');
+ final title = 'Active fires locations';
return Scaffold(
- key: _scaffoldKey,
- drawer: new MainDrawer(context),
- appBar: new AppBar(
- title: Text('Active fires'),
- leading: IconButton(
- icon: Icon(Icons.menu),
+ key: _scaffoldKey,
+ drawer: new MainDrawer(context),
+ appBar: new AppBar(
+ title: Text(title),
+ leading: IconButton(
+ icon: Icon(Icons.menu),
+ onPressed: () {
+ _scaffoldKey.currentState.openDrawer();
+ },
+ ),
+ /* actions: [
+ new IconButton(
+ icon: Icon(Icons.location_searching), onPressed: () {}),
+ IconButton(
+ icon: Icon(Icons.more_vert),
onPressed: () {
- _scaffoldKey.currentState.openDrawer();
+ print('More button');
},
),
- actions: [
- new IconButton(
- icon: Icon(Icons.location_searching), onPressed: () => {}),
- IconButton(
- icon: Icon(Icons.more_vert),
- onPressed: () {
- print('More button');
- },
- ),
- ],
- ),
- body: new Text('No active fires'));
+ ], */
+ ),
+ body: length > 0
+ ? _buildSavedLocations()
+ : new Center(
+ child: new CenteredColumn(children: [
+ new RoundedBtn(
+ icon: Icons.location_searching,
+ text: 'Add your position',
+ onPressed: onAddYourLocation,
+ backColor: fires600),
+ const SizedBox(height: 26.0),
+ new RoundedBtn(
+ icon: Icons.edit_location,
+ text: 'Add some other place',
+ onPressed: () {
+ onAddOtherLocation(context);
+ },
+ backColor: fires600),
+ ])),
+ floatingActionButton: length > 0
+ ? Column(mainAxisAlignment: MainAxisAlignment.end, children: [
+ FloatingActionButton.extended(
+ onPressed: onAddYourLocation,
+ heroTag: 'yourposition',
+ label: const Text('Add your position'),
+ icon: const Icon(Icons.location_searching),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 16.0),
+ child: FloatingActionButton.extended(
+ onPressed: () {
+ onAddOtherLocation(context);
+ },
+ heroTag: 'otherplace',
+ label: new Text('Add some other place'),
+ icon: const Icon(Icons.edit_location),
+ ),
+ )
+ ])
+ : null,
+ );
+ }
+
+ void onAddYourLocation() {
+ Future location = getUserLocation();
+ _saveLocation(location);
+ }
+
+ void onAddOtherLocation(BuildContext context) {
+ Future location = openPlacesDialog(context);
+ _saveLocation(location);
+ }
+
+ void _saveLocation(Future location) {
+ location.then((newLocation) {
+ this.setState(() {
+ _saved.add(newLocation);
+ length = _saved.length;
+ });
+ });
}
}
+
+class MyDrawer extends StatelessWidget {
+ static final MyDrawer _drawer = new MyDrawer._internal();
+
+ factory MyDrawer() {
+ return _drawer;
+ }
+
+ MyDrawer._internal();
+
+ @override
+ Widget build(BuildContext context) {
+ return new Text("Drawer");
+ }
+}
+
+class ActiveFiresPage extends StatefulWidget {
+ static const String routeName = '/fires';
+
+ ActiveFiresPage();
+
+ @override
+ _ActiveFiresPageState createState() => _ActiveFiresPageState();
+}
diff --git a/lib/basicLocation.dart b/lib/basicLocation.dart
new file mode 100644
index 0000000..4f04154
--- /dev/null
+++ b/lib/basicLocation.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/material.dart';
+
+class BasicLocation {
+ final double lat;
+ final double lon;
+ final String description;
+
+ BasicLocation({@required this.lat, @required this.lon, this.description});
+}
diff --git a/lib/firesApp.dart b/lib/firesApp.dart
index 3aed60a..2fca976 100644
--- a/lib/firesApp.dart
+++ b/lib/firesApp.dart
@@ -5,16 +5,26 @@ import 'theme.dart';
import 'introPage.dart';
import 'sandbox.dart';
import 'activeFires.dart';
+import 'placesAutocompleteWidget.dart';
+import 'globals.dart' as globals;
class FiresApp extends StatelessWidget {
- final Map routes = {
- Sandbox.routeName: (BuildContext context) => new Sandbox(),
- ActiveFiresMap.routeName: (BuildContext context) => new ActiveFiresMap(),
- IntroPage.routeName: (BuildContext context) => new IntroPage(),
- };
+
+
+ Map routes = {
+ PlacesAutocompleteWidget.routeName: (BuildContext context) =>
+ new PlacesAutocompleteWidget(),
+ Sandbox.routeName: (BuildContext context) => new Sandbox(),
+ ActiveFiresPage.routeName: (BuildContext context) =>
+ new ActiveFiresPage(),
+ IntroPage.routeName: (BuildContext context) => new IntroPage(),
+ };
final WidgetBuilder introWidget = (context) => new IntroPage();
final WidgetBuilder continueWidget = (context) => new HomePage();
+ // globals.getIt.registerSingleton
+ FiresApp();
+
@override
Widget build(BuildContext context) {
return new MaterialApp(
diff --git a/lib/genericMap.dart b/lib/genericMap.dart
new file mode 100644
index 0000000..eefb53e
--- /dev/null
+++ b/lib/genericMap.dart
@@ -0,0 +1,173 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:map_view/map_view.dart';
+import 'globals.dart' as globals;
+
+class GenericMap extends StatefulWidget {
+ final String title;
+ final double latitude;
+ final double longitude;
+
+ GenericMap(
+ {@required this.title,
+ @required this.latitude,
+ @required this.longitude});
+
+ @override
+ _GenericMapState createState() => new _GenericMapState(
+ title: this.title, latitude: this.latitude, longitude: this.longitude);
+}
+
+class _GenericMapState extends State {
+ MapView mapView = new MapView();
+ CameraPosition cameraPosition;
+ var compositeSubscription = new CompositeSubscription();
+ var staticMapProvider;
+ Uri staticMapUri;
+ final String title;
+ Location location;
+
+ _GenericMapState(
+ {@required this.title, @required latitude, @required longitude}) {
+ MapView.setApiKey(globals.gmapKey);
+ this.staticMapProvider = new StaticMapProvider(globals.gmapKey);
+ this.location = new Location(latitude, longitude);
+ }
+
+ List _markers = [
+ new Marker("1", "Work", 45.523970, -122.663081, color: Colors.blue),
+ new Marker("2", "Nossa Familia Coffee", 45.528788, -122.684633),
+ ];
+
+ @override
+ initState() {
+ super.initState();
+ cameraPosition = new CameraPosition(location, 2.0);
+ staticMapUri = staticMapProvider.getStaticUri(location, 12,
+ width: 900, height: 400, mapType: StaticMapViewType.roadmap);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ appBar: new AppBar(
+ title: new Text(title),
+ ),
+ body: new Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ new Container(
+ height: 250.0,
+ child: new Stack(
+ children: [
+ new InkWell(
+ child: new Center(
+ child: new Image.network(staticMapUri.toString()),
+ ),
+ onTap: showMap,
+ )
+ ],
+ ),
+ ),
+ new Container(
+ padding: new EdgeInsets.only(top: 10.0),
+ child: new Text(
+ "Tap the map to interact",
+ style: new TextStyle(fontWeight: FontWeight.bold),
+ ),
+ ),
+ ]));
+ }
+
+ showMap() {
+ mapView.show(
+ new MapOptions(
+ mapViewType: MapViewType.normal,
+ showUserLocation: true,
+ initialCameraPosition: new CameraPosition(new Location(45.5235258, -122.6732493), 14.0),
+ title: this.title),
+ toolbarActions: [new ToolbarAction("Close", 1)]);
+
+ var sub = mapView.onMapReady.listen((_) {
+ mapView.setMarkers(_markers);
+ mapView.addMarker(new Marker("3", "10 Barrel", 45.5259467, -122.687747,
+ color: Colors.purple));
+ mapView.zoomToFit(padding: 100);
+ });
+ compositeSubscription.add(sub);
+
+ sub = mapView.onLocationUpdated
+ .listen((location) => print("Location updated $location"));
+ compositeSubscription.add(sub);
+
+ sub = mapView.onTouchAnnotation
+ .listen((annotation) => print("annotation tapped"));
+ compositeSubscription.add(sub);
+
+ sub = mapView.onMapTapped
+ .listen((location) => print("Touched location $location"));
+ compositeSubscription.add(sub);
+
+ sub = mapView.onCameraChanged.listen((cameraPosition) =>
+ this.setState(() => this.cameraPosition = cameraPosition));
+ compositeSubscription.add(sub);
+
+ sub = mapView.onToolbarAction.listen((id) {
+ if (id == 1) {
+ _handleDismiss();
+ }
+ });
+ compositeSubscription.add(sub);
+
+ sub = mapView.onInfoWindowTapped.listen((marker) {
+ print("Info Window Tapped for ${marker.title}");
+ });
+ compositeSubscription.add(sub);
+ }
+
+ _handleDismiss() async {
+ double zoomLevel = await mapView.zoomLevel;
+ Location centerLocation = await mapView.centerLocation;
+ List visibleAnnotations = await mapView.visibleAnnotations;
+ print("Zoom Level: $zoomLevel");
+ print("Center: $centerLocation");
+ print("Visible Annotation Count: ${visibleAnnotations.length}");
+ var uri = await staticMapProvider.getImageUriFromMap(mapView,
+ width: 900, height: 400);
+ setState(() => staticMapUri = uri);
+ mapView.dismiss();
+ compositeSubscription.cancel();
+ }
+}
+
+class CompositeSubscription {
+ Set _subscriptions = new Set();
+
+ void cancel() {
+ for (var n in this._subscriptions) {
+ n.cancel();
+ }
+ this._subscriptions = new Set();
+ }
+
+ void add(StreamSubscription subscription) {
+ this._subscriptions.add(subscription);
+ }
+
+ void addAll(Iterable subs) {
+ _subscriptions.addAll(subs);
+ }
+
+ bool remove(StreamSubscription subscription) {
+ return this._subscriptions.remove(subscription);
+ }
+
+ bool contains(StreamSubscription subscription) {
+ return this._subscriptions.contains(subscription);
+ }
+
+ List toList() {
+ return this._subscriptions.toList();
+ }
+}
diff --git a/lib/globals.dart b/lib/globals.dart
new file mode 100644
index 0000000..6ce67a5
--- /dev/null
+++ b/lib/globals.dart
@@ -0,0 +1,6 @@
+library fires.globals;
+import 'package:get_it/get_it.dart';
+
+String gmapKey;
+
+final GetIt getIt = new GetIt();
\ No newline at end of file
diff --git a/lib/homePage.dart b/lib/homePage.dart
index 7fa8905..6e3e5f2 100644
--- a/lib/homePage.dart
+++ b/lib/homePage.dart
@@ -33,12 +33,12 @@ class HomePage extends StatelessWidget {
heightFactor: 0.9,
child: new CenteredColumn(
children: [
- customBtn(
- Icons.whatshot,
- "Active fires",
- context,
- // const EdgeInsets.only(left: 60.0),
- ActiveFiresMap.routeName),
+ new RoundedBtn.nav(
+ icon: Icons.whatshot,
+ text: 'Active fires',
+ context: context,
+ route: ActiveFiresPage.routeName,
+ backColor: fires600),
],
)))
])),
diff --git a/lib/main.dart b/lib/main.dart
index 20e7a70..33c03b2 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,18 @@
import 'package:flutter/material.dart';
import 'firesApp.dart';
+import 'package:comunes_flutter/comunes_flutter.dart';
+import 'dart:async';
+import 'globals.dart' as globals;
-void main() => runApp(new FiresApp());
+Future getGMapKey() async {
+ Secret secret = await SecretLoader(secretPath: 'assets/private-settings.json')
+ .load('gmap_key');
+ return secret.apiKey;
+}
+
+void main() {
+ getGMapKey().then((String gmapKey) {
+ globals.gmapKey = gmapKey;
+ runApp(new FiresApp());
+ });
+}
diff --git a/lib/mainDrawer.dart b/lib/mainDrawer.dart
index f64f5b3..87fe116 100644
--- a/lib/mainDrawer.dart
+++ b/lib/mainDrawer.dart
@@ -4,6 +4,7 @@ import 'colors.dart';
import 'sandbox.dart';
import 'introPage.dart';
import 'activeFires.dart';
+import 'placesAutocompleteWidget.dart';
class MainDrawer extends Drawer {
MainDrawer(BuildContext context, {key})
@@ -60,7 +61,7 @@ Widget mainDrawer(BuildContext context) {
leading: const Icon(Icons.whatshot),
title: new Text('Active fires'),
onTap: () {
- Navigator.pushNamed(context, ActiveFiresMap.routeName);
+ Navigator.pushNamed(context, ActiveFiresPage.routeName);
},
),
new ListTile(
@@ -71,6 +72,14 @@ Widget mainDrawer(BuildContext context) {
Navigator.pushNamed(context, '/subscriptions');
},
),
+ new ListTile(
+ leading: const Icon(Icons.location_on),
+ title: new Text('Places'),
+ onTap: () {
+ // Then close the drawer
+ Navigator.pushNamed(context, PlacesAutocompleteWidget.routeName);
+ },
+ ),
new Divider(),
new ListTile(
leading: const Icon(Icons.bug_report),
diff --git a/lib/placesAutocompleteUtils.dart b/lib/placesAutocompleteUtils.dart
new file mode 100644
index 0000000..7044703
--- /dev/null
+++ b/lib/placesAutocompleteUtils.dart
@@ -0,0 +1,32 @@
+import 'package:flutter_google_places_autocomplete/flutter_google_places_autocomplete.dart';
+import 'package:flutter/material.dart';
+import 'dart:async';
+import 'basicLocation.dart';
+import 'globals.dart' as globals;
+
+Future openPlacesDialog(BuildContext context) async {
+ Mode _mode = Mode.overlay;
+ GoogleMapsPlaces _places = new GoogleMapsPlaces(globals.gmapKey);
+ Prediction p = await showGooglePlacesAutocomplete(
+ context: context,
+ hint: 'Type the name of a place, region, etc',
+ apiKey: globals.gmapKey,
+ onError: (res) {
+ /* homeScaffoldKey.currentState.showSnackBar(
+ new SnackBar(content: new Text(res.errorMessage))); */
+ print('Error $res');
+ },
+ mode: _mode,
+ // FIXME
+ language: "es",
+ components: [new Component(Component.country, "es")]);
+ if (p != null) {
+ // get detail (lat/lng)
+ PlacesDetailsResponse detail = await _places.getDetailsByPlaceId(p.placeId);
+ final lat = detail.result.geometry.location.lat;
+ final lng = detail.result.geometry.location.lng;
+
+ return new BasicLocation(lat: lat, lon: lng, description: p.description);
+ }
+ return null;
+}
diff --git a/lib/placesAutocompleteWidget.dart b/lib/placesAutocompleteWidget.dart
new file mode 100644
index 0000000..043e932
--- /dev/null
+++ b/lib/placesAutocompleteWidget.dart
@@ -0,0 +1,75 @@
+import 'package:flutter_google_places_autocomplete/flutter_google_places_autocomplete.dart';
+import 'package:flutter/material.dart';
+import 'dart:async';
+import 'globals.dart' as globals;
+
+class PlacesAutocompleteWidget extends StatefulWidget {
+ static const String routeName = '/place';
+
+ PlacesAutocompleteWidget();
+
+ @override
+ _PlacesAutocompleteWidgetState createState() =>
+ _PlacesAutocompleteWidgetState();
+}
+
+// to get places detail (lat/lng)
+
+final homeScaffoldKey = new GlobalKey();
+final searchScaffoldKey = new GlobalKey();
+
+GoogleMapsPlaces _places;
+
+class _PlacesAutocompleteWidgetState extends State {
+ Mode _mode = Mode.overlay;
+
+ _PlacesAutocompleteWidgetState() {
+ _places = new GoogleMapsPlaces(globals.gmapKey);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ key: homeScaffoldKey,
+ appBar: new AppBar(
+ title: new Text("My App"),
+ ),
+ body:
+
+ new RaisedButton.icon(
+ icon: const Icon(Icons.location_searching),
+ label: new Text('Write a location'),
+ onPressed: () async {
+ // show input autocomplete with selected mode
+ // then get the Prediction selected
+ Prediction p = await showGooglePlacesAutocomplete(
+ context: context,
+ hint: 'Type the name of place, region, etc',
+ apiKey: globals.gmapKey,
+ onError: (res) {
+ homeScaffoldKey.currentState.showSnackBar(
+ new SnackBar(content: new Text(res.errorMessage)));
+ },
+ mode: _mode,
+ // FIXME
+ language: "es",
+ components: [new Component(Component.country, "es")]);
+ displayPrediction(p, homeScaffoldKey.currentState);
+ },
+ )
+
+ );
+ }
+}
+
+Future displayPrediction(Prediction p, ScaffoldState scaffold) async {
+ if (p != null) {
+ // get detail (lat/lng)
+ PlacesDetailsResponse detail = await _places.getDetailsByPlaceId(p.placeId);
+ final lat = detail.result.geometry.location.lat;
+ final lng = detail.result.geometry.location.lng;
+
+ scaffold.showSnackBar(
+ new SnackBar(content: new Text("${p.description} - $lat/$lng")));
+ }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 7c1e5c8..1497f8e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -4,17 +4,22 @@ description: All Against Fire
dependencies:
flutter:
sdk: flutter
- intl: ^0.15.6
+ intl: "^0.15.6"
# https://pub.dartlang.org/packages/padder
- padder: ^1.0.1
+ padder: "^1.0.1"
# https://pub.dartlang.org/packages/flutter
fluttery: "^0.0.7"
shared_preferences: "^0.4.2"
comunes_flutter:
path: /home/vjrj/dev/comunes_flutter
+ version: "^0.0.4"
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
- cupertino_icons: ^0.1.2
+ cupertino_icons: "^0.1.2"
+ map_view: "^0.0.12"
+ location: "^1.3.4"
+ flutter_google_places_autocomplete: "^0.0.4"
+ get_it: "^1.0.1+1"
dev_dependencies:
flutter_test:
@@ -39,6 +44,7 @@ flutter:
assets:
- images/logo-200.png
+ - assets/private-settings.json
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.