From e55edce3d4d9030ffd99d3affaf5729103e92d91 Mon Sep 17 00:00:00 2001 From: vjrj Date: Tue, 3 Jul 2018 13:07:02 +0200 Subject: [PATCH] More work with redux, and location edit (wip) --- lib/activeFires.dart | 4 +- lib/firesApp.dart | 7 +- lib/generated/i18n.dart | 6 + lib/globalFiresBottomStats.dart | 28 ++-- lib/mainDev.dart | 24 ++- lib/models/appState.dart | 6 + lib/models/fireMapState.dart | 2 +- lib/redux/actions.dart | 3 +- lib/redux/fetchDataMiddleware.dart | 19 ++- lib/redux/fireMapReducer.dart | 30 ++++ lib/redux/yourLocationActions.dart | 39 +++-- lib/redux/yourLocationsReducer.dart | 8 +- lib/sandbox.dart | 28 +--- lib/yourLocationMap.dart | 222 ++++++++++++++++------------ lib/yourLocationMapBottom.dart | 63 +++++--- res/values/strings_en.arb | 4 +- res/values/strings_es.arb | 4 +- 17 files changed, 311 insertions(+), 186 deletions(-) diff --git a/lib/activeFires.dart b/lib/activeFires.dart index 01928df..1a01812 100644 --- a/lib/activeFires.dart +++ b/lib/activeFires.dart @@ -199,13 +199,13 @@ class ActiveFiresPage extends StatelessWidget { child: new CenteredColumn(children: [ new RoundedBtn( icon: Icons.location_searching, - text: 'Fires near your', + text: S.of(context).addYourCurrentPosition, onPressed: () => onAddYourLocation(view.onAdd), backColor: fires600), const SizedBox(height: 26.0), new RoundedBtn( icon: Icons.edit_location, - text: S.of(context).firesNearPlace, + text: S.of(context).addSomePlace, onPressed: () => onAddOtherLocation(view.onAdd), backColor: fires600), ])), diff --git a/lib/firesApp.dart b/lib/firesApp.dart index 343433a..aeee1a2 100644 --- a/lib/firesApp.dart +++ b/lib/firesApp.dart @@ -45,8 +45,11 @@ class FiresApp extends StatelessWidget { home: new MaterialAppWithIntroHome( introWidget, continueWidget, 'showInitialWizard-2018-06-27-01'), onGenerateTitle: (context) { - String lang = Localizations.localeOf(context).languageCode; - this.store.dispatch(new OnUserLangAction(lang)); + print('MaterialApp onGenerateTitle'); + if (store.state.user.lang == null) { + String lang = Localizations.localeOf(context).languageCode; + this.store.dispatch(new OnUserLangAction(lang)); + } return S.of(context).appName; }, theme: firesTheme, diff --git a/lib/generated/i18n.dart b/lib/generated/i18n.dart index 5d9fe6e..ddbafe5 100644 --- a/lib/generated/i18n.dart +++ b/lib/generated/i18n.dart @@ -22,6 +22,8 @@ class S implements WidgetsLocalizations { TextDirection get textDirection => TextDirection.ltr; String get AvoidThisStringsIfisNotPlural => "Zero One Two Few Many Other"; + String get CANCEL => "CANCEL"; + String get SAVE => "SAVE"; String get UNDO => "UNDO"; String get aDay => "a day"; String get aF3wSeconds => "a few seconds"; @@ -104,6 +106,8 @@ class es extends S { @override String get supportThisInitiative => "Apoya esta iniciativa"; @override + String get SAVE => "GUARDAR"; + @override String get toFiresNotifications => "Suscríbete a alertas de fuegos"; @override String get notPermsUbication => "No tenemos permisos para conocer tu ubicación"; @@ -134,6 +138,8 @@ class es extends S { @override String get chooseAWatchRadio => "Elige un radio de vigilancia"; @override + String get CANCEL => "CANCELAR"; + @override String get chooseAPlace => "Elige un lugar"; @override String get firesNearPlace => "Fuegos cercanos a ti"; diff --git a/lib/globalFiresBottomStats.dart b/lib/globalFiresBottomStats.dart index fbed8dd..b78b90e 100644 --- a/lib/globalFiresBottomStats.dart +++ b/lib/globalFiresBottomStats.dart @@ -22,27 +22,27 @@ class _GlobalFiresBottomStatsState extends State { @override void initState() { super.initState(); - http.read('${firesApiUrl}status/last-fire-check').then((result) { + /* http.read('${firesApiUrl}status/last-fire-check').then((result) { try { var now = Moment.now(); var last = DateTime.parse(json.decode(result)['value']); - setState(() { - lastCheck = now.from(context, last); + http.read('${firesApiUrl}status/active-fires-count').then((result) { + try { + int count = json.decode(result)['total']; + setState(() { + lastCheck = now.from(context, last); + activeFires = count; + }); + } catch (e) { + print('Cannot get the last fire stats'); + print(e); + } }); } catch (e) { print('Cannot get the last fire check'); + print(e); } - }); - http.read('${firesApiUrl}status/active-fires-count').then((result) { - try { - int count = json.decode(result)['total']; - setState(() { - activeFires = count; - }); - } catch (e) { - print('Cannot get the last fire stats'); - } - }); + }); */ } @override diff --git a/lib/mainDev.dart b/lib/mainDev.dart index a1d08a7..7bbad21 100644 --- a/lib/mainDev.dart +++ b/lib/mainDev.dart @@ -1,16 +1,30 @@ +import 'package:redux/redux.dart'; import 'package:redux_logging/redux_logging.dart'; import 'globals.dart' as globals; import 'mainCommon.dart'; -import 'package:redux/redux.dart'; + +enum LogLevel { none, actions, full } void main() { globals.isDevelopment = true; - var logRedux = false; - List devMiddlewares = logRedux ? [ - LoggingMiddleware.printer(formatter: LoggingMiddleware.multiLineFormatter) - ] : []; + String onlyLogActionFormatter( + State state, + dynamic action, + DateTime timestamp, + ) { + return "${action.toString().replaceAll('Instance of ', '')}"; + } + + LogLevel logRedux = LogLevel.actions; + + List devMiddlewares = logRedux == LogLevel.none + ? [] + : [LoggingMiddleware.printer( + formatter: logRedux == LogLevel.full + ? LoggingMiddleware.multiLineFormatter + : onlyLogActionFormatter)]; mainCommon(devMiddlewares); } diff --git a/lib/models/appState.dart b/lib/models/appState.dart index a8bb432..3e86dd0 100644 --- a/lib/models/appState.dart +++ b/lib/models/appState.dart @@ -7,6 +7,8 @@ import 'package:meta/meta.dart'; import 'fireMapState.dart'; import 'user.dart'; +export 'fireMapState.dart'; + part 'appState.g.dart'; @immutable @@ -86,5 +88,9 @@ typedef void OnSubscribeDistanceChangeFunction(YourLocation loc); typedef void OnUnSubscribeFunction(YourLocation loc); typedef void OnSubscribeConfirmedFunction(YourLocation loc); +typedef void OnLocationEdit(YourLocation loc); +typedef void OnLocationEditConfirm(YourLocation loc); +typedef void OnLocationEditCancel(YourLocation loc); + // unused // typedef void UpdateYourLocationFunction(ObjectId id, YourLocation loc); diff --git a/lib/models/fireMapState.dart b/lib/models/fireMapState.dart index a8e2fe8..8551aba 100644 --- a/lib/models/fireMapState.dart +++ b/lib/models/fireMapState.dart @@ -1,7 +1,7 @@ import 'package:fires_flutter/models/yourLocation.dart'; import 'package:meta/meta.dart'; -enum FireMapStatus { view, subscriptionConfirm, unsubscribe } +enum FireMapStatus { view, subscriptionConfirm, unsubscribe, edit } @immutable class FireMapState { diff --git a/lib/redux/actions.dart b/lib/redux/actions.dart index e6fc95b..385fa38 100644 --- a/lib/redux/actions.dart +++ b/lib/redux/actions.dart @@ -1,2 +1,3 @@ export 'appActions.dart'; -export 'yourLocationActions.dart'; \ No newline at end of file +export 'yourLocationActions.dart'; +export 'fireMapActions.dart'; \ No newline at end of file diff --git a/lib/redux/fetchDataMiddleware.dart b/lib/redux/fetchDataMiddleware.dart index 32b0eb9..e578280 100644 --- a/lib/redux/fetchDataMiddleware.dart +++ b/lib/redux/fetchDataMiddleware.dart @@ -36,6 +36,16 @@ void fetchYourLocationsMiddleware( createUser(store, store.state.user.lang, action.token); } + if (action is EditConfirmYourLocationAction) { + if (action.loc.subscribed) { + // FXIME save lat/lon + } else { + // No subscribed (only local) + store.dispatch(new UpdateYourLocationAction(action.loc)); + persistYourLocations(store.state.yourLocations); + } + } + if (action is AddYourLocationAction) { if (action.loc.subscribed) { subscribeViaApi(store, action.loc, @@ -64,25 +74,28 @@ void fetchYourLocationsMiddleware( .then((result) => store.dispatch(result)); } - if (action is UpdateLocalYourLocationAction) { + if (action is UpdateYourLocationAction) { if (action.loc.subscribed) Debounce.seconds( 2, () => api .getYourLocationFireStats(store.state, action.loc) .then((result) => store.dispatch(result))); + else { + // FIXME do something? + } } if (action is SubscribeConfirmAction) { subscribeViaApi(store, action.loc, (sub) { - store.dispatch(new UpdateLocalYourLocationAction(action.loc)); + store.dispatch(new UpdateYourLocationAction(action.loc)); persistYourLocations(store.state.yourLocations); }); } if (action is UnSubscribeAction) { unsubsViaApi(store, action.loc.id, () { - store.dispatch(new UpdateLocalYourLocationAction(action.loc)); + store.dispatch(new UpdateYourLocationAction(action.loc)); persistYourLocations(store.state.yourLocations); }); } diff --git a/lib/redux/fireMapReducer.dart b/lib/redux/fireMapReducer.dart index 27e6664..fbfdede 100644 --- a/lib/redux/fireMapReducer.dart +++ b/lib/redux/fireMapReducer.dart @@ -13,6 +13,13 @@ final fireMapReducer = combineReducers([ _subscribeConfirmYourLocationMap), new TypedReducer( _unsubscribeYourLocationMap), + new TypedReducer(_editYourLocationMap), + new TypedReducer( + _editConfirmYourLocationMap), + new TypedReducer( + _editCancelYourLocationMap), + new TypedReducer( + _updateYourLocationMap) ]); FireMapState _updateYourLocationMapStats( @@ -24,6 +31,11 @@ FireMapState _updateYourLocationMapStats( industries: action.industries); } +FireMapState _updateYourLocationMap( + FireMapState state, UpdateYourLocationMapAction action) { + return state.copyWith(yourLocation: action.loc); +} + FireMapState _showYourLocationMap( FireMapState state, ShowYourLocationMapAction action) { return state.copyWith( @@ -47,3 +59,21 @@ FireMapState _unsubscribeYourLocationMap( FireMapState state, UnSubscribeAction action) { return state.copyWith(status: FireMapStatus.view); } + +FireMapState _editYourLocationMap( + FireMapState state, EditYourLocationAction action) { + return state.copyWith(status: FireMapStatus.edit); +} + +FireMapState _editConfirmYourLocationMap( + FireMapState state, EditConfirmYourLocationAction action) { + return state.copyWith(status: restoreStatusAfterSave(action.loc)); +} + +FireMapState _editCancelYourLocationMap( + FireMapState state, EditCancelYourLocationAction action) { + return state.copyWith(status: restoreStatusAfterSave(action.loc)); +} + +FireMapStatus restoreStatusAfterSave(loc) => + loc.subscribed ? FireMapStatus.unsubscribe : FireMapStatus.view; diff --git a/lib/redux/yourLocationActions.dart b/lib/redux/yourLocationActions.dart index f98661f..68088d3 100644 --- a/lib/redux/yourLocationActions.dart +++ b/lib/redux/yourLocationActions.dart @@ -16,25 +16,6 @@ class AddedYourLocationAction extends YourLocationActions { AddedYourLocationAction(this.loc); } -class ShowYourLocationMapAction extends YourLocationActions { - YourLocation loc; - - ShowYourLocationMapAction(this.loc); -} - -class UpdateYourLocationMapStatsAction extends YourLocationActions { - int numFires; - List fires = []; - List falsePos = []; - List industries = []; - - UpdateYourLocationMapStatsAction( - {@required this.numFires, - @required this.fires, - @required this.falsePos, - @required this.industries}); -} - class DeleteYourLocationAction extends YourLocationActions { YourLocation loc; @@ -47,10 +28,10 @@ class DeletedYourLocationAction extends YourLocationActions { DeletedYourLocationAction(this.id); } -class UpdateLocalYourLocationAction extends YourLocationActions { +class UpdateYourLocationAction extends YourLocationActions { YourLocation loc; - UpdateLocalYourLocationAction(this.loc); + UpdateYourLocationAction(this.loc); } class ToggleSubscriptionAction extends YourLocationActions { @@ -81,3 +62,19 @@ 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/redux/yourLocationsReducer.dart b/lib/redux/yourLocationsReducer.dart index e5cb001..ee3557b 100644 --- a/lib/redux/yourLocationsReducer.dart +++ b/lib/redux/yourLocationsReducer.dart @@ -8,8 +8,8 @@ final yourLocationsReducer = combineReducers>([ _addedYourLocation), new TypedReducer, DeletedYourLocationAction>( _deletedYourLocation), - new TypedReducer, UpdateLocalYourLocationAction>( - _updateLocalYourLocation), + new TypedReducer, UpdateYourLocationAction>( + _updateYourLocation), new TypedReducer, ToggledSubscriptionAction>( _toggledSubscriptionAction) ]); @@ -26,8 +26,8 @@ List _deletedYourLocation( .toList(); } -List _updateLocalYourLocation( - List yourLocations, UpdateLocalYourLocationAction action) { +List _updateYourLocation( + List yourLocations, UpdateYourLocationAction action) { return yourLocations .map((yourLocation) => yourLocation.id == action.loc.id ? action.loc : yourLocation) diff --git a/lib/sandbox.dart b/lib/sandbox.dart index 192593a..db7a095 100644 --- a/lib/sandbox.dart +++ b/lib/sandbox.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:comunes_flutter/comunes_flutter.dart'; -import 'slider.dart'; /* Useful for debug @@ -15,24 +13,14 @@ class Sandbox extends StatelessWidget { Widget build(BuildContext context) { //showDialog(context: context, child: builder(context)); return Scaffold( - body: LayoutBuilder( - builder: (context, constraints) => - Stack(fit: StackFit.expand, children: [ - // Material(color: Colors.yellowAccent), - Positioned( - top: 0.0, - child: Icon(Icons.star, size: 40.0), - ), - Positioned( - top: constraints.maxHeight - 80, - right: 10.0, - left: 10.0, - child: new CenteredRow( - children: [new FireDistanceSlider()], - ), - ) - ]), - ), + appBar: new AppBar( + title: new TextField( + controller: new TextEditingController(text: "kk"), + decoration: new InputDecoration(), + onSubmitted: (todoText) {}, + )), + body: new Text("Sandbox"), ); } } +-añ \ No newline at end of file diff --git a/lib/yourLocationMap.dart b/lib/yourLocationMap.dart index 5485c47..abc8ba4 100644 --- a/lib/yourLocationMap.dart +++ b/lib/yourLocationMap.dart @@ -7,6 +7,7 @@ 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'; @@ -30,13 +31,17 @@ class _ViewModel { final OnSubscribeConfirmedFunction onSubsConfirmed; final OnUnSubscribeFunction onUnSubs; final OnSubscribeDistanceChangeFunction onSlide; + final OnLocationEdit onEdit; + final OnLocationEditConfirm onEditConfirm; _ViewModel( {@required this.mapState, @required this.onSubs, @required this.onSubsConfirmed, @required this.onUnSubs, - @required this.onSlide}); + @required this.onSlide, + @required this.onEdit, + @required this.onEditConfirm}); @override bool operator ==(Object other) => @@ -58,6 +63,7 @@ class YourLocationMap extends StatelessWidget { return new StoreConnector( distinct: true, converter: (store) { + print('New map viewer'); return new _ViewModel( onSubs: (loc) { store.dispatch(new SubscribeAction()); @@ -71,20 +77,27 @@ class YourLocationMap extends StatelessWidget { store.dispatch(new UnSubscribeAction(loc)); }, onSlide: (loc) { - store.dispatch(new UpdateLocalYourLocationAction(loc)); + store.dispatch(new UpdateYourLocationMapAction(loc)); }, + onEdit: (loc) => store.dispatch(new EditYourLocationAction(loc)), + onEditConfirm: (loc) => + store.dispatch(new EditConfirmYourLocationAction(loc)), mapState: store.state.fireMapState); }, builder: (context, view) { + print('New map builder'); YourLocation location = view.mapState.yourLocation; assert(location != null); + TextEditingController textController = + new TextEditingController(text: location.description); + MapOptions mapOptions = new MapOptions( center: new LatLng(location.lat, location.lon), plugins: globals.isDevelopment ? [new ZoomMapPlugin()] : [new DummyMapPlugin()], // this works ? - // interactive: false, + interactive: false, zoom: 13.0, // THIS does not works as expected // maxZoom: 6.0, @@ -93,115 +106,136 @@ class YourLocationMap extends StatelessWidget { // print('${positionCallback.center}, ${positionCallback.zoom}'); }); var mapController = new MapController(); + // mapController.fitBounds(bounds); // mapController.center FireMapState mapState = view.mapState; - FireMapStatus operation = mapState.status; - print('Build map with operation: $operation'); - final btnText = operation == FireMapStatus.view + FireMapStatus status = mapState.status; + print('Build map with status: $status'); + final btnText = status == FireMapStatus.view ? S.of(context).toFiresNotifications - : operation == FireMapStatus.subscriptionConfirm + : status == FireMapStatus.subscriptionConfirm ? S.of(context).confirm : S.of(context).unsubscribe; - final btnIcon = operation == FireMapStatus.view + final btnIcon = status == FireMapStatus.view ? Icons.notifications_active - : operation == FireMapStatus.subscriptionConfirm + : status == FireMapStatus.subscriptionConfirm ? Icons.check : Icons.notifications_off; + FlutterMap map = new FlutterMap( + options: mapOptions, + mapController: mapController, + layers: [ + new TileLayerOptions( + maxZoom: 6.0, + subdomains: ['a', 'b', 'c'], + urlTemplate: + 'https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', + additionalOptions: { + // 'opacity': '0.1', + 'attribution': + '© OpenStreetMap contributors' + }, + ), + globals.isDevelopment + ? new ZoomMapPluginOptions() + : new DummyMapPluginOptions(), + new MarkerLayerOptions( + markers: buildMarkers(location, mapState.fires, + mapState.industries, mapState.falsePos), + ), + ], + ); + FlutterMapState leafletState = map.createState(); + // Do something with it return new Scaffold( key: _scaffoldKey, appBar: new AppBar( - title: new Text(location.description), - ), - floatingActionButton: FloatingActionButton.extended( - onPressed: () { - switch (operation) { - case FireMapStatus.view: - view.onSubs(location); - break; - case FireMapStatus.subscriptionConfirm: - view.onSubsConfirmed(location); - // IOS specific - _firebaseMessaging.requestNotificationPermissions(); - break; - case FireMapStatus.unsubscribe: - view.onUnSubs(location); - break; - } - }, - // https://github.com/flutter/flutter/issues/17583 - heroTag: "firesmap" + location.id.toHexString(), - icon: new Icon(btnIcon, color: fires600), - label: new Text( - btnText, - style: const TextStyle(color: fires600), - ), - backgroundColor: Colors.white, + title: status == FireMapStatus.edit + ? new TextField( + // autofocus: true, + key: new Key('LocationDescField'), + keyboardType: TextInputType.text, + controller: textController, + decoration: new InputDecoration(), + /* onSubmitted: (newDesc) { + // location.description = newDesc; + // view.onEditConfirm(location); + // view.editController.text = ''; + },*/ + ) + : new Text(location.description), + actions: listWithoutNulls([ + status == FireMapStatus.view || + status == FireMapStatus.unsubscribe + ? new IconButton( + icon: new Icon(Icons.edit), + onPressed: () => view.onEdit(location)) + : null + ]), ), + floatingActionButton: status == FireMapStatus.edit + ? null + : FloatingActionButton.extended( + onPressed: () { + switch (status) { + case FireMapStatus.view: + view.onSubs(location); + break; + case FireMapStatus.subscriptionConfirm: + view.onSubsConfirmed(location); + // IOS specific + _firebaseMessaging.requestNotificationPermissions(); + break; + case FireMapStatus.unsubscribe: + view.onUnSubs(location); + break; + case FireMapStatus.edit: + break; + } + }, + // https://github.com/flutter/flutter/issues/17583 + heroTag: "firesmap" + location.id.toHexString(), + icon: new Icon(btnIcon, color: fires600), + label: new Text( + btnText, + style: const TextStyle(color: fires600), + ), + backgroundColor: Colors.white, + ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, bottomNavigationBar: new YourLocationMapBottom(), body: LayoutBuilder( - builder: (context, constraints) => - Stack(fit: StackFit.expand, children: [ - // Material(color: Colors.yellowAccent), - new Opacity( - opacity: - operation == FireMapStatus.subscriptionConfirm - ? 0.5 - : 1.0, - child: new FlutterMap( - options: mapOptions, - mapController: mapController, - layers: [ - new TileLayerOptions( - maxZoom: 6.0, - subdomains: ['a', 'b', 'c'], - urlTemplate: - 'https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', - additionalOptions: { - // 'opacity': '0.1', - 'attribution': - '© OpenStreetMap contributors' - }, - ), - globals.isDevelopment - ? new ZoomMapPluginOptions() - : new DummyMapPluginOptions(), - new MarkerLayerOptions( - markers: buildMarkers(location, mapState.fires, - mapState.industries, mapState.falsePos), - ), - ], - )), - Positioned( - top: constraints.maxHeight - 200, - right: 10.0, - left: 10.0, - child: new CenteredRow( - // Fit sample: - // https://github.com/apptreesoftware/flutter_map/blob/master/flutter_map_example/lib/pages/map_controller.dart - children: - operation == FireMapStatus.subscriptionConfirm - ? [ - new FireDistanceSlider( - initialValue: location.distance, - onSlide: (distance) { - location.distance = distance; - view.onSlide(location); - /* FIXME - setState(() { - kmAround = distance; - Debounce.seconds(1, updateFireStats); - }); */ - }) - ] - : [], - ), - ) - ]), - )); + builder: (context, constraints) => + Stack(fit: StackFit.expand, children: [ + // Material(color: Colors.yellowAccent), + new Opacity( + opacity: status == FireMapStatus.subscriptionConfirm + ? 0.5 + : 1.0, + child: map), + Positioned( + top: constraints.maxHeight - 200, + right: 10.0, + left: 10.0, + child: new CenteredRow( + // Fit sample: + // https://github.com/apptreesoftware/flutter_map/blob/master/flutter_map_example/lib/pages/map_controller.dart + children: + status == FireMapStatus.subscriptionConfirm + ? [ + new FireDistanceSlider( + initialValue: location.distance, + onSlide: (distance) { + location.distance = distance; + view.onSlide(location); + }) + ] + : []), + ) + ]))); }); } diff --git a/lib/yourLocationMapBottom.dart b/lib/yourLocationMapBottom.dart index 352022e..09fb3eb 100644 --- a/lib/yourLocationMapBottom.dart +++ b/lib/yourLocationMapBottom.dart @@ -1,4 +1,4 @@ -import 'package:comunes_flutter/comunes_flutter.dart'; +import 'package:fires_flutter/models/yourLocation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; @@ -7,12 +7,18 @@ 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}); + _ViewModel( + {@required this.state, + @required this.onLocationEditConfirm, + @required this.onLocationEditCancel}); @override bool operator ==(Object other) => @@ -29,30 +35,53 @@ class YourLocationMapBottom extends StatelessWidget { @override Widget build(BuildContext context) { return new StoreConnector( - distinct: true, // FIXME + distinct: true, converter: (store) { - return new _ViewModel(state: store.state.fireMapState); + return new _ViewModel( + state: store.state.fireMapState, + onLocationEditConfirm: (loc) => + store.dispatch(new EditConfirmYourLocationAction(loc)), + onLocationEditCancel: (loc) => + store.dispatch(new + EditCancelYourLocationAction(loc))); }, builder: (context, view) { - int kmAround = view.state.yourLocation.distance; + 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: listWithoutNulls([ - view.state.status == FireMapStatus.subscriptionConfirm || - view.state.numFires == null - ? null - : new Text(view.state.numFires > 0 - ? S.of(context).firesAroundThisArea( - view.state.numFires.toString(), kmAround.toString()) - : S - .of(context) - .noFiresAroundThisArea(kmAround.toString())), - SizedBox(width: 10.0) - ])); + actions: buildActionList(view, loc, context, kmAround)); }); } + + List buildActionList( + _ViewModel view, YourLocation loc, BuildContext context, int kmAround) { + List actionList = new List(); + switch (view.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))); + actionList.add(new FlatButton( + onPressed: () => view.onLocationEditCancel(loc), + 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 + ? S.of(context).firesAroundThisArea( + view.state.numFires.toString(), kmAround.toString()) + : S.of(context).noFiresAroundThisArea(kmAround.toString()))); + // SizedBox(width: 10.0) + } + } + return actionList; + } } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 96f3310..ac996ec 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -42,5 +42,7 @@ "aYear": "a year", "inYears": "$value years", "somethingAgo": "$something ago", - "inSomething": "in $something" + "inSomething": "in $something", + "SAVE": "SAVE", + "CANCEL": "CANCEL" } \ No newline at end of file diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 9e12b25..c9acfee 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -42,5 +42,7 @@ "aYear": "un año", "inYears": "$value años", "somethingAgo": "hace $something", - "inSomething": "en $something" + "inSomething": "en $something", + "SAVE": "GUARDAR", + "CANCEL": "CANCELAR" } \ No newline at end of file