diff --git a/android/build.gradle b/android/build.gradle index b7d7695..4476887 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -6,7 +6,6 @@ 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/images/fire-marker-l.png b/images/fire-marker-l.png new file mode 100644 index 0000000..ea5a5f3 Binary files /dev/null and b/images/fire-marker-l.png differ diff --git a/images/fire-marker-m.png b/images/fire-marker-m.png new file mode 100644 index 0000000..972273d Binary files /dev/null and b/images/fire-marker-m.png differ diff --git a/images/fire-marker-s.png b/images/fire-marker-s.png new file mode 100644 index 0000000..c2a1113 Binary files /dev/null and b/images/fire-marker-s.png differ diff --git a/images/fire-marker.png b/images/fire-marker.png new file mode 100644 index 0000000..0a20859 Binary files /dev/null and b/images/fire-marker.png differ diff --git a/lib/activeFires.dart b/lib/activeFires.dart index 3040fcf..3089553 100644 --- a/lib/activeFires.dart +++ b/lib/activeFires.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'mainDrawer.dart'; -import 'genericMap.dart'; +import 'leafletMap.dart'; import 'dart:async'; import 'package:comunes_flutter/comunes_flutter.dart'; import 'colors.dart'; @@ -10,6 +10,7 @@ import 'package:collection/collection.dart' show lowerBound; import 'locationUtils.dart'; import 'globals.dart' as globals; import 'basicLocationPersist.dart'; +import 'package:http/http.dart' as http; class ActiveFiresPage extends StatefulWidget { static const String routeName = '/fires'; @@ -36,16 +37,25 @@ class _ActiveFiresPageState extends State { title: new Text(desc), onLongPress: () { _scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text( - 'Slide horizontally to delete this location'), - )); + content: new Text('Slide horizontally to delete this location'), + )); }, onTap: () { + const String km = '100'; + var url = 'https://fires.comunes.org/api/v1/fires-in/${globals.firesApiKey}/${loc.lat}/${loc + .lon}/$km'; + /* http.post(url, body: {"name": "doodle", "color": "blue"}) + .then((response) { + print("Response status: ${response.statusCode}"); + print("Response body: ${response.body}"); + }); */ + // print(url); + http.read(url).then(print); Navigator.push( context, new MaterialPageRoute( - builder: (context) => new GenericMap( - title: desc, latitude: loc.lat, longitude: loc.lon))); + builder: (context) => + new LeafletMap(title: desc, location: loc))); }); } diff --git a/lib/basicLocationPersist.dart b/lib/basicLocationPersist.dart index 826f9ef..a721b87 100644 --- a/lib/basicLocationPersist.dart +++ b/lib/basicLocationPersist.dart @@ -5,6 +5,10 @@ final String locationKey = 'yourlocations'; void loadYourLocations(prefs) { List yourLocations = prefs.getStringList(locationKey); + if (yourLocations == null) { + yourLocations = []; + persistYourLocations(prefs); + } yourLocations.forEach((locationString) { Map locationMap = json.decode(locationString); globals.yourLocations.add(BasicLocation.fromJson(locationMap)); diff --git a/lib/genericMap.dart b/lib/genericMap.dart deleted file mode 100644 index eefb53e..0000000 --- a/lib/genericMap.dart +++ /dev/null @@ -1,173 +0,0 @@ -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 index 1f65950..564a0e2 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -5,7 +5,8 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'basicLocation.dart'; String gmapKey; -String appName = 'All Against Fire!'; +String firesApiKey; +String appName = 'All Against The Fire!'; Future prefs = SharedPreferences.getInstance(); final List yourLocations = []; final GetIt getIt = new GetIt(); diff --git a/lib/homePage.dart b/lib/homePage.dart index d4b76da..c14208d 100644 --- a/lib/homePage.dart +++ b/lib/homePage.dart @@ -11,7 +11,7 @@ class HomePage extends StatelessWidget { final GlobalKey _scaffoldKey = new GlobalKey(); final _homeFont = const TextStyle( - fontSize: 40.0, + fontSize: 35.0, fontWeight: FontWeight.w400, // color: Colors.white, ); @@ -37,7 +37,7 @@ class HomePage extends StatelessWidget { new Expanded( child: new FractionallySizedBox( alignment: FractionalOffset.bottomCenter, - heightFactor: 0.8, + heightFactor: 0.9, child: new Image.asset('images/logo-200.png', fit: BoxFit.fitHeight))), new Expanded( @@ -46,7 +46,13 @@ class HomePage extends StatelessWidget { heightFactor: 0.9, child: new CenteredColumn( children: [ - new Text(globals.appName, style: _homeFont), + new Padding( + padding: const EdgeInsets.all(10.0), + child: new Text( + globals.appName, + textAlign: TextAlign.center, + softWrap: true, style: _homeFont), + ), new SizedBox(height: 20.0), new RoundedBtn.nav( icon: Icons.whatshot, @@ -54,6 +60,13 @@ class HomePage extends StatelessWidget { context: context, route: ActiveFiresPage.routeName, backColor: fires600), + new SizedBox(height: 20.0), + new RoundedBtn.nav( + icon: Icons.notifications_active, + text: 'Notify a fire', + context: context, + route: ActiveFiresPage.routeName, + backColor: fires600), ], ))) ])), diff --git a/lib/leafletMap.dart b/lib/leafletMap.dart new file mode 100644 index 0000000..84541be --- /dev/null +++ b/lib/leafletMap.dart @@ -0,0 +1,144 @@ +import 'package:flutter/material.dart'; +import 'basicLocation.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_map/plugin_api.dart'; +import 'package:latlong/latlong.dart'; +import 'colors.dart'; +import 'mainDrawer.dart' + ''; +class LeafletMap extends StatefulWidget { + final BasicLocation location; + final String title; + + LeafletMap({@required this.title, @required this.location}); + + @override + _LeafletMapState createState() => _LeafletMapState(title: title, location: location); +} + +class _LeafletMapState extends State { + final GlobalKey _scaffoldKey = new GlobalKey(); + + final BasicLocation location; + final String title; + _LeafletMapState({@required this.title, @required this.location}); + @override + Widget build(BuildContext context) { + return new Scaffold( + key: _scaffoldKey, + // drawer: new MainDrawer(context), + appBar: new AppBar( + title: new Text(title), + ), + floatingActionButton: FloatingActionButton( + onPressed: () { + + }, + child: const Icon(Icons.notifications_none), + backgroundColor: Colors.orange, + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + bottomNavigationBar: new MapBottomAppBar( + menuCallback: () { + // _scaffoldKey.currentState.openDrawer(); + }, + fabLocation: FloatingActionButtonLocation.centerDocked, + showNotch: true, + bottomActions: [ + new Text('10 fires near you'), + SizedBox(width: 10.0) + ]), + body: new FlutterMap( + options: new MapOptions( + center: new LatLng(this.location.lat, this.location.lon), + zoom: 13.0, + // THIS does not works as expected + // maxZoom: 6.0, + onPositionChanged: (positionCallback) { + print('$positionCallback'); + } + ), + layers: [ + new TileLayerOptions( + maxZoom: 6.0, + urlTemplate: 'https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', + additionalOptions: { + // 'opacity': '0.1', + 'attribution': '© OpenStreetMap contributors' + }, + ), /* + new TileLayerOptions( + urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + additionalOptions: { + // 'opacity': '0.1', + 'attribution': '&copy OpenStreetMap contributors' + }, + + ), */ + new MarkerLayerOptions( + markers: [ + new Marker( + width: 80.0, + height: 80.0, + point: new LatLng(this.location.lat, this.location.lon), + builder: (ctx) => + new Container( + child: new Image.asset('images/fire-marker-l.png'), + ), + ), + ], + ), + ], + )); + } +} + +class MapBottomAppBar extends StatelessWidget { + const MapBottomAppBar( + {this.menuCallback, + this.fabLocation, + this.showNotch, + this.bottomActions}); + + final Color color = fires600; + final FloatingActionButtonLocation fabLocation; + final bool showNotch; + final VoidCallback menuCallback; + final List bottomActions; + + static final List kCenterLocations = + [ + FloatingActionButtonLocation.centerDocked, + FloatingActionButtonLocation.centerFloat, + ]; + + @override + Widget build(BuildContext context) { + final List rowContents = [ + /* new IconButton( + icon: const Icon(Icons.menu), + onPressed: () { + menuCallback(); + /* showModalBottomSheet( + context: context, + builder: (BuildContext context) => const _DemoDrawer(), + ); */ + }, + ), */ + ]; + + if (kCenterLocations.contains(fabLocation)) { + rowContents.add( + const Expanded(child: const SizedBox()), + ); + } + + rowContents.addAll(this.bottomActions); + + return new BottomAppBar( + color: color, + hasNotch: showNotch, + child: new Row(children: rowContents), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 54aef75..9dd4715 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; import 'firesApp.dart'; + import 'package:comunes_flutter/comunes_flutter.dart'; import 'dart:async'; import 'globals.dart' as globals; import 'basicLocationPersist.dart'; -Future getGMapKey() async { - Secret secret = await SecretLoader(secretPath: 'assets/private-settings.json') - .load('gmap_key'); - return secret.apiKey; +Future> loadSecrets() async { + return await SecretLoader(secretPath: 'assets/private-settings.json').load(); } void main() { - getGMapKey().then((String gmapKey) { - globals.gmapKey = gmapKey; + loadSecrets().then((secrets) { + globals.firesApiKey = secrets['firesApiKey']; + globals.gmapKey = secrets['gmapKey']; globals.prefs.then((prefs) { loadYourLocations(prefs); diff --git a/pubspec.yaml b/pubspec.yaml index a0229e1..f90fe44 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,14 +12,16 @@ dependencies: shared_preferences: "^0.4.2" comunes_flutter: path: /home/vjrj/dev/comunes_flutter - version: "^0.0.5" + version: "^0.0.7" # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. 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" + flutter_map: "^0.0.1" + http: "^0.11.3+16" + simple_moment: "^0.0.3" dev_dependencies: flutter_test: @@ -45,6 +47,10 @@ flutter: assets: - images/logo-200.png - assets/private-settings.json + - images/fire-marker-l.png + - images/fire-marker-m.png + - images/fire-marker-s.png + - images/fire-marker.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.io/assets-and-images/#resolution-aware.