Location edition
This commit is contained in:
parent
e55edce3d4
commit
87718b7ad5
15 changed files with 138 additions and 75 deletions
|
|
@ -33,18 +33,25 @@ class _ViewModel {
|
|||
@required this.yourLocations});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
other is _ViewModel &&
|
||||
runtimeType == other.runtimeType &&
|
||||
yourLocations == other.yourLocations;
|
||||
runtimeType == other.runtimeType &&
|
||||
yourLocations == other.yourLocations;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => yourLocations.hashCode;
|
||||
}
|
||||
|
||||
class ActiveFiresPage extends StatelessWidget {
|
||||
static const String routeName = '/fires';
|
||||
class ActiveFiresPage extends StatefulWidget {
|
||||
static const String routeName = '/fires';
|
||||
|
||||
@override
|
||||
_ActiveFiresPageState createState() => _ActiveFiresPageState();
|
||||
}
|
||||
|
||||
class _ActiveFiresPageState extends State<ActiveFiresPage> {
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
|
|
@ -134,6 +141,7 @@ class ActiveFiresPage extends StatelessWidget {
|
|||
return new StoreConnector<AppState, _ViewModel>(
|
||||
distinct: true,
|
||||
converter: (store) {
|
||||
print('New ViewModel of Active Fires');
|
||||
return new _ViewModel(
|
||||
onAdd: (loc) {
|
||||
if (store.state.yourLocations
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ class FiresApp extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new StoreProvider(
|
||||
StatefulWidget home = new MaterialAppWithIntroHome(
|
||||
introWidget, continueWidget, 'showInitialWizard-2018-06-27-01');
|
||||
return new StoreProvider<AppState>(
|
||||
|
||||
store: this.store,
|
||||
child: new MaterialApp(
|
||||
localizationsDelegates: [
|
||||
|
|
@ -42,8 +45,7 @@ class FiresApp extends StatelessWidget {
|
|||
supportedLocales: S.delegate.supportedLocales,
|
||||
localeResolutionCallback:
|
||||
S.delegate.resolution(fallback: new Locale("en", "")),
|
||||
home: new MaterialAppWithIntroHome(
|
||||
introWidget, continueWidget, 'showInitialWizard-2018-06-27-01'),
|
||||
home: home,
|
||||
onGenerateTitle: (context) {
|
||||
print('MaterialApp onGenerateTitle');
|
||||
if (store.state.user.lang == null) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'dart:convert';
|
||||
import 'globals.dart' as globals;
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'package:comunes_flutter/comunes_flutter.dart';
|
||||
import 'customBottomAppBar.dart';
|
||||
import 'colors.dart';
|
||||
import 'generated/i18n.dart';
|
||||
import 'customMoment.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_simple_dependency_injection/injector.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'colors.dart';
|
||||
import 'customBottomAppBar.dart';
|
||||
import 'customMoment.dart';
|
||||
import 'generated/i18n.dart';
|
||||
|
||||
class GlobalFiresBottomStats extends StatefulWidget {
|
||||
@override
|
||||
|
|
@ -22,7 +23,7 @@ class _GlobalFiresBottomStatsState extends State<GlobalFiresBottomStats> {
|
|||
@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']);
|
||||
|
|
@ -42,27 +43,29 @@ class _GlobalFiresBottomStatsState extends State<GlobalFiresBottomStats> {
|
|||
print('Cannot get the last fire check');
|
||||
print(e);
|
||||
}
|
||||
}); */
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new CustomBottomAppBar(
|
||||
fabLocation: FloatingActionButtonLocation.centerDocked,
|
||||
showNotch: true,
|
||||
color: fires100,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
actions: listWithoutNulls(<Widget>[
|
||||
activeFires > 0 && lastCheck != null
|
||||
? new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
new Text(S.of(context).activeFiresWorldWide(activeFires.toString())),
|
||||
new Text(S.of(context).updatedLastCheck(lastCheck))
|
||||
])
|
||||
: null,
|
||||
SizedBox(width: 10.0)
|
||||
]));
|
||||
fabLocation: FloatingActionButtonLocation.centerDocked,
|
||||
showNotch: true,
|
||||
color: fires100,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
actions: listWithoutNulls(<Widget>[
|
||||
activeFires > 0 && lastCheck != null
|
||||
? new Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
new Text(S
|
||||
.of(context)
|
||||
.activeFiresWorldWide(activeFires.toString())),
|
||||
new Text(S.of(context).updatedLastCheck(lastCheck))
|
||||
])
|
||||
: null,
|
||||
SizedBox(width: 10.0)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ void mainCommon(List<Middleware<AppState>> otherMiddleware) {
|
|||
});
|
||||
|
||||
// Listen to store changes, and re-render when the state is updated
|
||||
// store.onChange.listen((state) {
|
||||
// });
|
||||
store.onChange.listen((state) {
|
||||
// print('Store onChange');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ void main() {
|
|||
dynamic action,
|
||||
DateTime timestamp,
|
||||
) {
|
||||
return "${action.toString().replaceAll('Instance of ', '')}";
|
||||
return ">>>>> ${action.toString().replaceAll('Instance of ', '')}";
|
||||
}
|
||||
|
||||
LogLevel logRedux = LogLevel.actions;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Widget mainDrawer(BuildContext context) {
|
|||
children: listWithoutNulls(<Widget>[
|
||||
new GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, '/');
|
||||
},
|
||||
child: new DrawerHeader(
|
||||
|
|
@ -46,6 +47,7 @@ Widget mainDrawer(BuildContext context) {
|
|||
leading: const Icon(Icons.whatshot),
|
||||
title: new Text(S.of(context).activeFires),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, ActiveFiresPage.routeName);
|
||||
},
|
||||
),
|
||||
|
|
@ -54,6 +56,7 @@ Widget mainDrawer(BuildContext context) {
|
|||
title: new Text(S.of(context).notifyAFire),
|
||||
onTap: () {
|
||||
// Then close the drawer
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, Sandbox.routeName);
|
||||
},
|
||||
),
|
||||
|
|
@ -63,6 +66,7 @@ Widget mainDrawer(BuildContext context) {
|
|||
title: new Text(S.of(context).supportThisInitiative),
|
||||
onTap: () {
|
||||
// Then close the drawer
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, '/subscriptions');
|
||||
},
|
||||
),
|
||||
|
|
@ -71,6 +75,7 @@ Widget mainDrawer(BuildContext context) {
|
|||
leading: const Icon(Icons.bug_report),
|
||||
title: new Text('Sandbox'),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.pushNamed(context, Sandbox.routeName);
|
||||
},
|
||||
): null,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:bson_objectid/bson_objectid.dart';
|
||||
import 'package:comunes_flutter/comunes_flutter.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
|
|
|||
|
|
@ -39,6 +39,24 @@ class YourLocation extends Object with _$YourLocationSerializerMixin {
|
|||
if (this.id == null) this.id = new ObjectId();
|
||||
}
|
||||
|
||||
YourLocation copyWith(
|
||||
{id,
|
||||
lat,
|
||||
lon,
|
||||
description,
|
||||
distance,
|
||||
subscribed}) {
|
||||
return new YourLocation(
|
||||
id: id?? this.id,
|
||||
lat: lat?? this.lat,
|
||||
lon: lon?? this.lon,
|
||||
description: description?? this.description,
|
||||
distance: distance?? this.distance,
|
||||
subscribed: subscribed?? this.subscribed
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
|
|
|
|||
|
|
@ -19,23 +19,16 @@ YourLocation _$YourLocationFromJson(Map<String, dynamic> json) =>
|
|||
|
||||
abstract class _$YourLocationSerializerMixin {
|
||||
ObjectId get id;
|
||||
|
||||
double get lat;
|
||||
|
||||
double get lon;
|
||||
|
||||
String get description;
|
||||
|
||||
bool get subscribed;
|
||||
|
||||
int get distance;
|
||||
|
||||
Map<String, dynamic> toJson() => new _$YourLocationJsonMapWrapper(this);
|
||||
}
|
||||
|
||||
class _$YourLocationJsonMapWrapper extends $JsonMapWrapper {
|
||||
final _$YourLocationSerializerMixin _v;
|
||||
|
||||
_$YourLocationJsonMapWrapper(this._v);
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ Future<List<YourLocation>> loadYourLocations() async {
|
|||
}
|
||||
|
||||
persistYourLocations(List<YourLocation> yl) {
|
||||
print('Persisting $yl');
|
||||
globals.prefs.then((prefs) {
|
||||
List<String> ylAsString = [];
|
||||
yl.forEach((location) {
|
||||
|
|
|
|||
|
|
@ -41,15 +41,16 @@ void fetchYourLocationsMiddleware(
|
|||
// 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,
|
||||
(sub) => store.dispatch(new AddedYourLocationAction(sub)));
|
||||
(sub) {
|
||||
store.dispatch(new AddedYourLocationAction(sub));
|
||||
persistYourLocations(store.state.yourLocations);
|
||||
});
|
||||
} else {
|
||||
// No subscribed (only local)
|
||||
store.dispatch(new AddedYourLocationAction(action.loc));
|
||||
|
|
@ -73,7 +74,6 @@ void fetchYourLocationsMiddleware(
|
|||
.getYourLocationFireStats(store.state, action.loc)
|
||||
.then((result) => store.dispatch(result));
|
||||
}
|
||||
|
||||
if (action is UpdateYourLocationAction) {
|
||||
if (action.loc.subscribed)
|
||||
Debounce.seconds(
|
||||
|
|
@ -84,6 +84,8 @@ void fetchYourLocationsMiddleware(
|
|||
else {
|
||||
// FIXME do something?
|
||||
}
|
||||
store.dispatch(new UpdatedYourLocationAction(action.loc));
|
||||
persistYourLocations(store.state.yourLocations);
|
||||
}
|
||||
|
||||
if (action is SubscribeConfirmAction) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:bson_objectid/bson_objectid.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
abstract class YourLocationActions {}
|
||||
|
||||
|
|
@ -34,6 +33,12 @@ class UpdateYourLocationAction extends YourLocationActions {
|
|||
UpdateYourLocationAction(this.loc);
|
||||
}
|
||||
|
||||
class UpdatedYourLocationAction extends YourLocationActions {
|
||||
YourLocation loc;
|
||||
|
||||
UpdatedYourLocationAction(this.loc);
|
||||
}
|
||||
|
||||
class ToggleSubscriptionAction extends YourLocationActions {
|
||||
YourLocation loc;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ final yourLocationsReducer = combineReducers<List<YourLocation>>([
|
|||
_addedYourLocation),
|
||||
new TypedReducer<List<YourLocation>, DeletedYourLocationAction>(
|
||||
_deletedYourLocation),
|
||||
new TypedReducer<List<YourLocation>, UpdateYourLocationAction>(
|
||||
_updateYourLocation),
|
||||
new TypedReducer<List<YourLocation>, UpdatedYourLocationAction>(
|
||||
_updatedYourLocation),
|
||||
new TypedReducer<List<YourLocation>, ToggledSubscriptionAction>(
|
||||
_toggledSubscriptionAction)
|
||||
]);
|
||||
|
|
@ -26,8 +26,8 @@ List<YourLocation> _deletedYourLocation(
|
|||
.toList();
|
||||
}
|
||||
|
||||
List<YourLocation> _updateYourLocation(
|
||||
List<YourLocation> yourLocations, UpdateYourLocationAction action) {
|
||||
List<YourLocation> _updatedYourLocation(
|
||||
List<YourLocation> yourLocations, UpdatedYourLocationAction action) {
|
||||
return yourLocations
|
||||
.map((yourLocation) =>
|
||||
yourLocation.id == action.loc.id ? action.loc : yourLocation)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class Sandbox extends StatelessWidget {
|
|||
return Scaffold(
|
||||
appBar: new AppBar(
|
||||
title: new TextField(
|
||||
autofocus: true,
|
||||
controller: new TextEditingController(text: "kk"),
|
||||
decoration: new InputDecoration(),
|
||||
onSubmitted: (todoText) {},
|
||||
|
|
@ -23,4 +24,3 @@ class Sandbox extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
-añ
|
||||
|
|
@ -54,9 +54,17 @@ class _ViewModel {
|
|||
int get hashCode => mapState.hashCode;
|
||||
}
|
||||
|
||||
class YourLocationMap extends StatelessWidget {
|
||||
class YourLocationMap extends StatefulWidget {
|
||||
@override
|
||||
_YourLocationMapState createState() => _YourLocationMapState();
|
||||
}
|
||||
|
||||
class _YourLocationMapState extends State<YourLocationMap> {
|
||||
// This needs to be stateful so when resizes don't get a new globalkey
|
||||
// https://github.com/flutter/flutter/issues/1632#issuecomment-180478202
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final FirebaseMessaging _firebaseMessaging = new FirebaseMessaging();
|
||||
YourLocation editingLocation;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -80,16 +88,19 @@ class YourLocationMap extends StatelessWidget {
|
|||
store.dispatch(new UpdateYourLocationMapAction(loc));
|
||||
},
|
||||
onEdit: (loc) => store.dispatch(new EditYourLocationAction(loc)),
|
||||
onEditConfirm: (loc) =>
|
||||
store.dispatch(new EditConfirmYourLocationAction(loc)),
|
||||
onEditConfirm: (loc) {
|
||||
store.dispatch(new UpdateYourLocationAction(loc));
|
||||
store.dispatch(new UpdateYourLocationMapAction(loc));
|
||||
store.dispatch(new EditConfirmYourLocationAction(loc));
|
||||
},
|
||||
mapState: store.state.fireMapState);
|
||||
},
|
||||
builder: (context, view) {
|
||||
print('New map builder');
|
||||
YourLocation location = view.mapState.yourLocation;
|
||||
editingLocation = location.copyWith();
|
||||
print('New map builder with ${editingLocation.description}');
|
||||
|
||||
assert(location != null);
|
||||
TextEditingController textController =
|
||||
new TextEditingController(text: location.description);
|
||||
|
||||
MapOptions mapOptions = new MapOptions(
|
||||
center: new LatLng(location.lat, location.lon),
|
||||
|
|
@ -151,29 +162,23 @@ class YourLocationMap extends StatelessWidget {
|
|||
// Do something with it
|
||||
return new Scaffold(
|
||||
key: _scaffoldKey,
|
||||
resizeToAvoidBottomPadding: true,
|
||||
appBar: new AppBar(
|
||||
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 = '';
|
||||
},*/
|
||||
controller: new TextEditingController.fromValue(new TextEditingValue(text: editingLocation.description,selection: new TextSelection.collapsed(offset: editingLocation.description.length-1))),
|
||||
onChanged: (newDesc) {
|
||||
editingLocation =
|
||||
location.copyWith(description: newDesc);
|
||||
},
|
||||
)
|
||||
: new Text(location.description),
|
||||
actions: listWithoutNulls(<Widget>[
|
||||
status == FireMapStatus.view ||
|
||||
status == FireMapStatus.unsubscribe
|
||||
? new IconButton(
|
||||
icon: new Icon(Icons.edit),
|
||||
onPressed: () => view.onEdit(location))
|
||||
: null
|
||||
]),
|
||||
actions: buildAppBarActions(status, view, location),
|
||||
),
|
||||
floatingActionButton: status == FireMapStatus.edit
|
||||
? null
|
||||
|
|
@ -239,6 +244,27 @@ class YourLocationMap extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
|
||||
List<Widget> buildAppBarActions(
|
||||
FireMapStatus status, _ViewModel view, YourLocation location) {
|
||||
switch (status) {
|
||||
case FireMapStatus.view:
|
||||
case FireMapStatus.unsubscribe:
|
||||
return <Widget>[
|
||||
new IconButton(
|
||||
icon: new Icon(Icons.edit),
|
||||
onPressed: () => view.onEdit(location))
|
||||
];
|
||||
case FireMapStatus.edit:
|
||||
return <Widget>[
|
||||
new IconButton(
|
||||
icon: new Icon(Icons.save),
|
||||
onPressed: () => view.onEditConfirm(editingLocation))
|
||||
];
|
||||
default:
|
||||
return <Widget>[];
|
||||
}
|
||||
}
|
||||
|
||||
List<Marker> buildMarkers(YourLocation yourLocation, List<dynamic> fires,
|
||||
List<dynamic> falsePos, List<dynamic> industries) {
|
||||
List<Marker> markers = [];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue