From c0e8524692fc20b9bf08939632938387b4c02177 Mon Sep 17 00:00:00 2001 From: vjrj Date: Thu, 5 Jul 2018 17:17:45 +0200 Subject: [PATCH] Location edition --- lib/activeFires.dart | 1 + lib/models/appState.dart | 1 + lib/redux/fireMapActions.dart | 23 ++++++++ lib/redux/fireMapReducer.dart | 10 +++- lib/redux/yourLocationActions.dart | 17 ------ lib/yourLocationMap.dart | 84 ++++++++++++++++++++---------- lib/yourLocationMapBottom.dart | 82 ++++++++++------------------- 7 files changed, 119 insertions(+), 99 deletions(-) diff --git a/lib/activeFires.dart b/lib/activeFires.dart index c6934f4..707767a 100644 --- a/lib/activeFires.dart +++ b/lib/activeFires.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:just_debounce_it/just_debounce_it.dart'; import 'package:comunes_flutter/comunes_flutter.dart'; import 'package:fires_flutter/models/yourLocation.dart'; import 'package:flutter/material.dart'; diff --git a/lib/models/appState.dart b/lib/models/appState.dart index c965108..4c278d2 100644 --- a/lib/models/appState.dart +++ b/lib/models/appState.dart @@ -88,6 +88,7 @@ typedef void OnUnSubscribeFunction(YourLocation loc); typedef void OnSubscribeConfirmedFunction(YourLocation loc); typedef void OnLocationEdit(YourLocation loc); +typedef void OnLocationEditing(YourLocation loc); typedef void OnLocationEditConfirm(YourLocation loc); typedef void OnLocationEditCancel(YourLocation loc); diff --git a/lib/redux/fireMapActions.dart b/lib/redux/fireMapActions.dart index f9f452a..eebbf56 100644 --- a/lib/redux/fireMapActions.dart +++ b/lib/redux/fireMapActions.dart @@ -29,3 +29,26 @@ class ShowYourLocationMapAction extends FiresMapActions { ShowYourLocationMapAction(this.loc); } + +class EditYourLocationAction extends FiresMapActions { + YourLocation loc; + + EditYourLocationAction(this.loc); +} + +class EditingYourLocationAction extends FiresMapActions { + YourLocation loc; + + EditingYourLocationAction(this.loc); +} + +class EditConfirmYourLocationAction extends FiresMapActions{ + YourLocation loc; + + EditConfirmYourLocationAction(this.loc); +} + +class EditCancelYourLocationAction extends FiresMapActions { + YourLocation loc; + EditCancelYourLocationAction(this.loc); +} diff --git a/lib/redux/fireMapReducer.dart b/lib/redux/fireMapReducer.dart index fbfdede..e1a58d4 100644 --- a/lib/redux/fireMapReducer.dart +++ b/lib/redux/fireMapReducer.dart @@ -16,6 +16,8 @@ final fireMapReducer = combineReducers([ new TypedReducer(_editYourLocationMap), new TypedReducer( _editConfirmYourLocationMap), + new TypedReducer( + _editingYourLocationMap), new TypedReducer( _editCancelYourLocationMap), new TypedReducer( @@ -65,6 +67,11 @@ FireMapState _editYourLocationMap( return state.copyWith(status: FireMapStatus.edit); } +FireMapState _editingYourLocationMap( + FireMapState state, EditingYourLocationAction action) { + return state.copyWith(yourLocation: action.loc); +} + FireMapState _editConfirmYourLocationMap( FireMapState state, EditConfirmYourLocationAction action) { return state.copyWith(status: restoreStatusAfterSave(action.loc)); @@ -72,7 +79,8 @@ FireMapState _editConfirmYourLocationMap( FireMapState _editCancelYourLocationMap( FireMapState state, EditCancelYourLocationAction action) { - return state.copyWith(status: restoreStatusAfterSave(action.loc)); + return state.copyWith( + status: restoreStatusAfterSave(action.loc), yourLocation: action.loc); } FireMapStatus restoreStatusAfterSave(loc) => diff --git a/lib/redux/yourLocationActions.dart b/lib/redux/yourLocationActions.dart index 47ae75c..8cacef8 100644 --- a/lib/redux/yourLocationActions.dart +++ b/lib/redux/yourLocationActions.dart @@ -66,20 +66,3 @@ class UnSubscribeAction extends YourLocationActions { UnSubscribeAction(this.loc); } - -class EditYourLocationAction extends YourLocationActions { - YourLocation loc; - - EditYourLocationAction(this.loc); -} - -class EditConfirmYourLocationAction extends YourLocationActions { - YourLocation loc; - - EditConfirmYourLocationAction(this.loc); -} - -class EditCancelYourLocationAction extends YourLocationActions { - YourLocation loc; - EditCancelYourLocationAction(this.loc); -} diff --git a/lib/yourLocationMap.dart b/lib/yourLocationMap.dart index b3ec8ba..1d37f05 100644 --- a/lib/yourLocationMap.dart +++ b/lib/yourLocationMap.dart @@ -7,7 +7,6 @@ import 'package:fires_flutter/models/yourLocation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/plugin_api.dart'; -import 'package:flutter_map/src/map/flutter_map_state.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:latlong/latlong.dart'; @@ -33,6 +32,8 @@ class _ViewModel { final OnSubscribeDistanceChangeFunction onSlide; final OnLocationEdit onEdit; final OnLocationEditConfirm onEditConfirm; + final OnLocationEditCancel onEditCancel; + final OnLocationEditing onEditing; _ViewModel( {@required this.mapState, @@ -41,7 +42,9 @@ class _ViewModel { @required this.onUnSubs, @required this.onSlide, @required this.onEdit, - @required this.onEditConfirm}); + @required this.onEditing, + @required this.onEditConfirm, + @required this.onEditCancel}); @override bool operator ==(Object other) => @@ -64,12 +67,16 @@ class _YourLocationMapState extends State { // https://github.com/flutter/flutter/issues/1632#issuecomment-180478202 final GlobalKey _scaffoldKey = new GlobalKey(); final FirebaseMessaging _firebaseMessaging = new FirebaseMessaging(); - YourLocation editingLocation; + YourLocation _location; + YourLocation _initialLocation; @override Widget build(BuildContext context) { return new StoreConnector( distinct: true, + onInitialBuild: (store) { + _initialLocation = _location.copyWith(); + }, converter: (store) { print('New map viewer'); return new _ViewModel( @@ -88,6 +95,11 @@ class _YourLocationMapState extends State { store.dispatch(new UpdateYourLocationMapAction(loc)); }, onEdit: (loc) => store.dispatch(new EditYourLocationAction(loc)), + onEditing: (loc) { + store.dispatch(new UpdateYourLocationMapAction(loc)); + }, + onEditCancel: (loc) => + store.dispatch(new EditCancelYourLocationAction(loc)), onEditConfirm: (loc) { store.dispatch(new UpdateYourLocationAction(loc)); store.dispatch(new UpdateYourLocationMapAction(loc)); @@ -97,13 +109,16 @@ class _YourLocationMapState extends State { }, builder: (context, view) { YourLocation location = view.mapState.yourLocation; - editingLocation = location.copyWith(); - print('New map builder with ${editingLocation.description}'); + _location = location.copyWith(); + print('New map builder with ${_location.description}'); - assert(location != null); + assert(_location != null); + FireMapState mapState = view.mapState; + FireMapStatus status = mapState.status; + print('Build map with status: $status'); MapOptions mapOptions = new MapOptions( - center: new LatLng(location.lat, location.lon), + center: new LatLng(_location.lat, _location.lon), plugins: globals.isDevelopment ? [new ZoomMapPlugin()] : [new DummyMapPlugin()], @@ -112,8 +127,15 @@ class _YourLocationMapState extends State { zoom: 13.0, // THIS does not works as expected // maxZoom: 6.0, + onTap: (callback) { + print('On tap ${callback}'); + if (status == FireMapStatus.edit) { + _location = _location.copyWith( + lat: callback.latitude, lon: callback.longitude); + view.onEditing(_location); + } + }, onPositionChanged: (positionCallback) { - // decouple // print('${positionCallback.center}, ${positionCallback.zoom}'); }); var mapController = new MapController(); @@ -121,9 +143,6 @@ class _YourLocationMapState extends State { // mapController.fitBounds(bounds); // mapController.center - FireMapState mapState = view.mapState; - FireMapStatus status = mapState.status; - print('Build map with status: $status'); final btnText = status == FireMapStatus.view ? S.of(context).toFiresNotifications : status == FireMapStatus.subscriptionConfirm @@ -153,12 +172,17 @@ class _YourLocationMapState extends State { ? new ZoomMapPluginOptions() : new DummyMapPluginOptions(), new MarkerLayerOptions( - markers: buildMarkers(location, mapState.fires, + markers: buildMarkers(_location, mapState.fires, mapState.industries, mapState.falsePos), ), ], ); - FlutterMapState leafletState = map.createState(); + // mapController. + /* FlutterMapState leafletState = map.createState(); + leafletState.mapState.onMoved.listen((Null) { + + ; + }); */ // Do something with it return new Scaffold( key: _scaffoldKey, @@ -171,14 +195,17 @@ class _YourLocationMapState extends State { keyboardType: TextInputType.text, decoration: new InputDecoration(), - controller: new TextEditingController.fromValue(new TextEditingValue(text: editingLocation.description,selection: new TextSelection.collapsed(offset: editingLocation.description.length-1))), + controller: new TextEditingController.fromValue( + new TextEditingValue( + text: _location.description, + selection: new TextSelection.collapsed( + offset: _location.description.length - 1))), onChanged: (newDesc) { - editingLocation = - location.copyWith(description: newDesc); + _location = _location.copyWith(description: newDesc); }, ) - : new Text(location.description), - actions: buildAppBarActions(status, view, location), + : new Text(_location.description), + actions: buildAppBarActions(status, view, _location), ), floatingActionButton: status == FireMapStatus.edit ? null @@ -186,22 +213,22 @@ class _YourLocationMapState extends State { onPressed: () { switch (status) { case FireMapStatus.view: - view.onSubs(location); + view.onSubs(_location); break; case FireMapStatus.subscriptionConfirm: - view.onSubsConfirmed(location); + view.onSubsConfirmed(_location); // IOS specific _firebaseMessaging.requestNotificationPermissions(); break; case FireMapStatus.unsubscribe: - view.onUnSubs(location); + view.onUnSubs(_location); break; case FireMapStatus.edit: break; } }, // https://github.com/flutter/flutter/issues/17583 - heroTag: "firesmap" + location.id.toHexString(), + heroTag: "firesmap" + _location.id.toHexString(), icon: new Icon(btnIcon, color: fires600), label: new Text( btnText, @@ -211,7 +238,10 @@ class _YourLocationMapState extends State { ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - bottomNavigationBar: new YourLocationMapBottom(), + bottomNavigationBar: new YourLocationMapBottom( + onSave: () => view.onEditConfirm(_location), + onCancel: () => view.onEditCancel(_initialLocation), + state: view.mapState), body: LayoutBuilder( builder: (context, constraints) => Stack(fit: StackFit.expand, children: [ @@ -232,10 +262,10 @@ class _YourLocationMapState extends State { status == FireMapStatus.subscriptionConfirm ? [ new FireDistanceSlider( - initialValue: location.distance, + initialValue: _location.distance, onSlide: (distance) { - location.distance = distance; - view.onSlide(location); + _location.distance = distance; + view.onSlide(_location); }) ] : []), @@ -258,7 +288,7 @@ class _YourLocationMapState extends State { return [ new IconButton( icon: new Icon(Icons.save), - onPressed: () => view.onEditConfirm(editingLocation)) + onPressed: () => view.onEditConfirm(_location)) ]; default: return []; diff --git a/lib/yourLocationMapBottom.dart b/lib/yourLocationMapBottom.dart index 09fb3eb..3fd3b02 100644 --- a/lib/yourLocationMapBottom.dart +++ b/lib/yourLocationMapBottom.dart @@ -1,83 +1,57 @@ import 'package:fires_flutter/models/yourLocation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_redux/flutter_redux.dart'; import 'colors.dart'; import 'customBottomAppBar.dart'; import 'generated/i18n.dart'; import 'models/appState.dart'; import 'models/fireMapState.dart'; -import 'redux/actions.dart'; -@immutable -class _ViewModel { - final FireMapState state; - final OnLocationEditConfirm onLocationEditConfirm; - final OnLocationEditCancel onLocationEditCancel; - - _ViewModel( - {@required this.state, - @required this.onLocationEditConfirm, - @required this.onLocationEditCancel}); - - @override - bool operator ==(Object other) => - identical(this, other) || - other is _ViewModel && - runtimeType == other.runtimeType && - state == other.state; - - @override - int get hashCode => state.hashCode; -} +typedef void OnSave(); +typedef void OnCancel(); class YourLocationMapBottom extends StatelessWidget { + final OnSave onSave; + final OnCancel onCancel; + final FireMapState state; + + YourLocationMapBottom({@required this.onSave,@required this.onCancel,@required this.state}); + @override Widget build(BuildContext context) { - return new StoreConnector( - distinct: true, - converter: (store) { - return new _ViewModel( - state: store.state.fireMapState, - onLocationEditConfirm: (loc) => - store.dispatch(new EditConfirmYourLocationAction(loc)), - onLocationEditCancel: (loc) => - store.dispatch(new - EditCancelYourLocationAction(loc))); - }, - builder: (context, view) { - YourLocation loc = view.state.yourLocation; - int kmAround = loc.distance; - return new CustomBottomAppBar( - fabLocation: FloatingActionButtonLocation.centerFloat, - showNotch: false, - color: fires100, - // height: 170.0, - mainAxisAlignment: MainAxisAlignment.center, - actions: buildActionList(view, loc, context, kmAround)); - }); + YourLocation loc = state.yourLocation; + int kmAround = loc.distance; + return new CustomBottomAppBar( + fabLocation: FloatingActionButtonLocation.centerFloat, + showNotch: false, + color: fires100, + // height: 170.0, + mainAxisAlignment: MainAxisAlignment.center, + actions: buildActionList(loc, context, kmAround)); } List buildActionList( - _ViewModel view, YourLocation loc, BuildContext context, int kmAround) { + YourLocation loc, BuildContext context, int kmAround) { List actionList = new List(); - switch (view.state.status) { + switch (state.status) { case FireMapStatus.edit: actionList.add(new FlatButton( - onPressed: () => view.onLocationEditConfirm(loc), - child: new Text(S.of(context).SAVE, style: Theme.of(context).textTheme.button))); + onPressed: onSave, + child: new Text(S.of(context).SAVE, + style: Theme.of(context).textTheme.button))); actionList.add(new FlatButton( - onPressed: () => view.onLocationEditCancel(loc), - child: new Text(S.of(context).CANCEL, style: Theme.of(context).textTheme.button))); + onPressed: onCancel, + child: new Text(S.of(context).CANCEL, + style: Theme.of(context).textTheme.button))); break; case FireMapStatus.subscriptionConfirm: break; case FireMapStatus.unsubscribe: case FireMapStatus.view: - if (view.state.numFires != null) { - actionList.add(new Text(view.state.numFires > 0 + if (state.numFires != null) { + actionList.add(new Text(state.numFires > 0 ? S.of(context).firesAroundThisArea( - view.state.numFires.toString(), kmAround.toString()) + state.numFires.toString(), kmAround.toString()) : S.of(context).noFiresAroundThisArea(kmAround.toString()))); // SizedBox(width: 10.0) }