Better fire stats. False positives mark api part
This commit is contained in:
parent
e9c6c3fc55
commit
cb02156ae1
10 changed files with 174 additions and 75 deletions
|
|
@ -7,12 +7,12 @@ import 'fireMarkType.dart';
|
|||
|
||||
class FireMarker extends Marker {
|
||||
|
||||
FireMarker(location, type,
|
||||
FireMarker(LatLng pos, type,
|
||||
[onTap = null, AnchorPos anchor = AnchorPos.center, Anchor anchorOverride])
|
||||
: super(
|
||||
width: 80.0,
|
||||
height: 80.0,
|
||||
point: new LatLng(location.lat, location.lon),
|
||||
point: pos,
|
||||
builder: (ctx) => new Container(
|
||||
child: new GestureDetector(
|
||||
child: new FireMarkerIcon(type), onTap: onTap)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:core';
|
||||
|
||||
import 'package:comunes_flutter/comunes_flutter.dart';
|
||||
import 'package:fires_flutter/models/basicLocation.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
|
|
@ -18,12 +17,13 @@ import 'fireMarker.dart';
|
|||
import 'generated/i18n.dart';
|
||||
import 'genericMapBottom.dart';
|
||||
import 'globals.dart' as globals;
|
||||
import 'layerSelectorMapPlugin.dart';
|
||||
import 'models/appState.dart';
|
||||
import 'models/fireMapState.dart';
|
||||
import 'redux/actions.dart';
|
||||
import 'slider.dart';
|
||||
import 'zoomMapPlugin.dart';
|
||||
import 'layerSelectorMapPlugin.dart';
|
||||
|
||||
@immutable
|
||||
class _ViewModel {
|
||||
final String serverUrl;
|
||||
|
|
@ -36,6 +36,7 @@ class _ViewModel {
|
|||
final OnLocationEditConfirm onEditConfirm;
|
||||
final OnLocationEditCancel onEditCancel;
|
||||
final OnLocationEditing onEditing;
|
||||
final OnFalsePositive onFalsePositive;
|
||||
|
||||
_ViewModel(
|
||||
{@required this.mapState,
|
||||
|
|
@ -47,6 +48,7 @@ class _ViewModel {
|
|||
@required this.onEdit,
|
||||
@required this.onEditing,
|
||||
@required this.onEditConfirm,
|
||||
@required this.onFalsePositive,
|
||||
@required this.onEditCancel});
|
||||
|
||||
@override
|
||||
|
|
@ -108,6 +110,8 @@ class _genericMapState extends State<genericMap> {
|
|||
store.dispatch(new UpdateYourLocationMapAction(loc));
|
||||
store.dispatch(new EditConfirmYourLocationAction(loc));
|
||||
},
|
||||
onFalsePositive: (notif, type) => store
|
||||
.dispatch(new MarkFireAsFalsePositiveAction(notif, type)),
|
||||
serverUrl: store.state.serverUrl,
|
||||
mapState: store.state.fireMapState);
|
||||
},
|
||||
|
|
@ -127,8 +131,16 @@ class _genericMapState extends State<genericMap> {
|
|||
MapOptions mapOptions = new MapOptions(
|
||||
center: new LatLng(_location.lat, _location.lon),
|
||||
plugins: globals.isDevelopment
|
||||
? [new ZoomMapPlugin(), new AttributionPlugin(), new LayerSelectorMapPlugin()]
|
||||
: [new DummyMapPlugin(), new AttributionPlugin(), new LayerSelectorMapPlugin()],
|
||||
? [
|
||||
new ZoomMapPlugin(),
|
||||
new AttributionPlugin(),
|
||||
new LayerSelectorMapPlugin()
|
||||
]
|
||||
: [
|
||||
new DummyMapPlugin(),
|
||||
new AttributionPlugin(),
|
||||
new LayerSelectorMapPlugin()
|
||||
],
|
||||
// this works ?
|
||||
interactive: false,
|
||||
zoom: 13.0,
|
||||
|
|
@ -166,8 +178,8 @@ class _genericMapState extends State<genericMap> {
|
|||
switch (layer) {
|
||||
case FireMapLayer.osmc:
|
||||
case FireMapLayer.osmcGrey:
|
||||
attribution = '© OpenStreetMap contributors';
|
||||
break;
|
||||
attribution = '© OpenStreetMap contributors';
|
||||
break;
|
||||
case FireMapLayer.esri:
|
||||
case FireMapLayer.esriSatellite:
|
||||
case FireMapLayer.esriTerrain:
|
||||
|
|
@ -177,20 +189,24 @@ class _genericMapState extends State<genericMap> {
|
|||
switch (layer) {
|
||||
case FireMapLayer.osmc:
|
||||
subdomains = ['a', 'b', 'c'];
|
||||
baseLayer = 'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png';
|
||||
baseLayer =
|
||||
'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png';
|
||||
break;
|
||||
case FireMapLayer.osmcGrey:
|
||||
subdomains = ['a', 'b', 'c'];
|
||||
baseLayer = 'https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png';
|
||||
baseLayer = 'https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png';
|
||||
break;
|
||||
case FireMapLayer.esri:
|
||||
baseLayer = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}';
|
||||
baseLayer =
|
||||
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}';
|
||||
break;
|
||||
case FireMapLayer.esriSatellite:
|
||||
baseLayer = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}';
|
||||
baseLayer =
|
||||
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}';
|
||||
break;
|
||||
case FireMapLayer.esriTerrain:
|
||||
baseLayer = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';
|
||||
baseLayer =
|
||||
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}';
|
||||
}
|
||||
FlutterMap map = new FlutterMap(
|
||||
options: mapOptions,
|
||||
|
|
@ -209,7 +225,7 @@ class _genericMapState extends State<genericMap> {
|
|||
: new DummyMapPluginOptions(),
|
||||
new MarkerLayerOptions(
|
||||
markers: buildMarkers(
|
||||
_location,
|
||||
mapState.status == FireMapStatus.viewFireNotification ? new LatLng(mapState.fireNotification.lat, mapState.fireNotification.lon): new LatLng(_location.lat, _location.lon),
|
||||
mapState.fires,
|
||||
mapState.industries,
|
||||
mapState.falsePos,
|
||||
|
|
@ -290,9 +306,11 @@ class _genericMapState extends State<genericMap> {
|
|||
floatingActionButtonLocation:
|
||||
FloatingActionButtonLocation.centerFloat,
|
||||
bottomNavigationBar: new GenericMapBottom(
|
||||
onSave: () => view.onEditConfirm(_location),
|
||||
onCancel: () => view.onEditCancel(_initialLocation),
|
||||
state: view.mapState,
|
||||
onSave: () => view.onEditConfirm(_location),
|
||||
onCancel: () => view.onEditCancel(_initialLocation),
|
||||
onFalsePositive: (sealed, type) =>
|
||||
view.onFalsePositive(sealed, type),
|
||||
state: view.mapState,
|
||||
scaffoldKey: _scaffoldKey,
|
||||
),
|
||||
body: LayoutBuilder(
|
||||
|
|
@ -362,28 +380,30 @@ class _genericMapState extends State<genericMap> {
|
|||
}
|
||||
}
|
||||
|
||||
List<Marker> buildMarkers(YourLocation yourLocation, List<dynamic> fires,
|
||||
List<dynamic> falsePos, List<dynamic> industries, bool isNotif) {
|
||||
List<Marker> buildMarkers(LatLng pos, List<dynamic> fires,
|
||||
List<dynamic> falsePosList, List<dynamic> industries, bool isNotif) {
|
||||
List<Marker> markers = [];
|
||||
print('building markers: fires: ${fires.length} falsePos: ${falsePosList.length} industries: ${industries.length}, isNotif: ${isNotif} ');
|
||||
const calibrate = false; // useful when we change the fire icons size
|
||||
markers.add(FireMarker(
|
||||
yourLocation, isNotif ? FireMarkType.fire : FireMarkType.position));
|
||||
if (calibrate) markers.add(FireMarker(yourLocation, FireMarkType.pixel));
|
||||
falsePos.forEach((fire) {
|
||||
var coords = fire['geo']['coordinates'];
|
||||
var loc = BasicLocation(lon: coords[0], lat: coords[1]);
|
||||
pos, isNotif ? FireMarkType.fire : FireMarkType.position));
|
||||
if (calibrate) markers.add(FireMarker(pos, FireMarkType.pixel));
|
||||
falsePosList.forEach((falsePos) {
|
||||
var coords = falsePos['geo']['coordinates'];
|
||||
print('false pos: ${coords}');
|
||||
var loc = LatLng(coords[1], coords[0]);
|
||||
markers.add(FireMarker(loc, FireMarkType.falsePos));
|
||||
if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
|
||||
});
|
||||
industries.forEach((fire) {
|
||||
industries.forEach((industry) {
|
||||
// print(fire['geo']['coordinates']);
|
||||
var coords = fire['geo']['coordinates'];
|
||||
var loc = BasicLocation(lon: coords[0], lat: coords[1]);
|
||||
var coords = industry['geo']['coordinates'];
|
||||
var loc = LatLng(coords[1], coords[0]);
|
||||
markers.add(FireMarker(loc, FireMarkType.industry));
|
||||
if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
|
||||
});
|
||||
fires.forEach((fire) {
|
||||
var loc = new BasicLocation(lat: fire['lat'], lon: fire['lon']);
|
||||
var loc = new LatLng(fire['lat'], fire['lon']);
|
||||
markers.add(
|
||||
FireMarker(loc, FireMarkType.fire, () => print('marker pressed')));
|
||||
markers.add(FireMarker(loc, FireMarkType.pixel));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:comunes_flutter/comunes_flutter.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:fires_flutter/models/fireNotification.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
|
|
@ -14,17 +15,19 @@ import 'models/fireMapState.dart';
|
|||
|
||||
typedef void OnSave();
|
||||
typedef void OnCancel();
|
||||
typedef void OnFalsePositive();
|
||||
typedef void OnFalsePositive(FireNotification notif, FalsePositiveType type);
|
||||
|
||||
class GenericMapBottom extends StatelessWidget {
|
||||
final OnSave onSave;
|
||||
final OnCancel onCancel;
|
||||
final OnFalsePositive onFalsePositive;
|
||||
final FireMapState state;
|
||||
final GlobalKey<ScaffoldState> scaffoldKey;
|
||||
|
||||
GenericMapBottom(
|
||||
{@required this.onSave,
|
||||
@required this.onCancel,
|
||||
@required this.onFalsePositive,
|
||||
@required this.state,
|
||||
@required this.scaffoldKey});
|
||||
|
||||
|
|
@ -107,7 +110,7 @@ class GenericMapBottom extends StatelessWidget {
|
|||
value: value, child: new Text(menuText));
|
||||
}).toList(),
|
||||
onChanged: (value) async {
|
||||
// FIXME api call
|
||||
onFalsePositive(state.fireNotification, value);
|
||||
await new Future.delayed(
|
||||
new Duration(milliseconds: 500));
|
||||
scaffoldKey.currentState.showSnackBar(new SnackBar(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:fires_flutter/models/fireNotification.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
enum FireMapStatus { view, subscriptionConfirm, unsubscribe, edit, viewFireNotification }
|
||||
enum FireMapStatus {
|
||||
view,
|
||||
subscriptionConfirm,
|
||||
unsubscribe,
|
||||
edit,
|
||||
viewFireNotification
|
||||
}
|
||||
enum FireMapLayer { osmcGrey, esriSatellite, osmc, esri, esriTerrain }
|
||||
|
||||
@immutable
|
||||
|
|
@ -18,9 +24,9 @@ class FireMapState {
|
|||
|
||||
const FireMapState.initial()
|
||||
: this.status = FireMapStatus.view,
|
||||
this.layer = FireMapLayer.osmcGrey,
|
||||
this.layer = FireMapLayer.osmcGrey,
|
||||
this.yourLocation = null,
|
||||
this.fireNotification = null,
|
||||
this.fireNotification = null,
|
||||
this.numFires = 0,
|
||||
this.fires = const [],
|
||||
this.falsePos = const [],
|
||||
|
|
@ -28,11 +34,11 @@ class FireMapState {
|
|||
|
||||
FireMapState(
|
||||
{this.status: FireMapStatus.view,
|
||||
this.layer: FireMapLayer.osmcGrey,
|
||||
this.layer: FireMapLayer.osmcGrey,
|
||||
this.yourLocation,
|
||||
this.numFires,
|
||||
this.fires,
|
||||
this.fireNotification,
|
||||
this.fires,
|
||||
this.fireNotification,
|
||||
this.falsePos,
|
||||
this.industries});
|
||||
|
||||
|
|
@ -63,9 +69,9 @@ class FireMapState {
|
|||
other is FireMapState &&
|
||||
runtimeType == other.runtimeType &&
|
||||
status == other.status &&
|
||||
layer == other.layer &&
|
||||
layer == other.layer &&
|
||||
numFires == other.numFires &&
|
||||
fireNotification == other.fireNotification &&
|
||||
fireNotification == other.fireNotification &&
|
||||
fires == other.fires &&
|
||||
falsePos == other.falsePos &&
|
||||
industries == other.industries &&
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
import 'dart:convert';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'falsePositiveTypes.dart';
|
||||
|
||||
import 'package:bson_objectid/bson_objectid.dart';
|
||||
import 'package:fires_flutter/models/yourLocation.dart';
|
||||
|
|
@ -18,8 +19,8 @@ class FiresApi {
|
|||
resty.globalClient = new ht.IOClient();
|
||||
}
|
||||
|
||||
Future<String> createUser(
|
||||
AppState state, String mobileToken, String lang) async {
|
||||
Future<String> createUser(AppState state, String mobileToken,
|
||||
String lang) async {
|
||||
assert(state.firesApiUrl != null);
|
||||
assert(state.firesApiKey != null);
|
||||
assert(mobileToken != null);
|
||||
|
|
@ -50,18 +51,18 @@ class FiresApi {
|
|||
if (response.statusCode == 200) {
|
||||
// print(response.body);
|
||||
final dataSubscriptions =
|
||||
json.decode(response.body)['data']['subscriptions'];
|
||||
json.decode(response.body)['data']['subscriptions'];
|
||||
List<YourLocation> subscribed = [];
|
||||
for (int i = 0; i < dataSubscriptions.length; i++) {
|
||||
var el = dataSubscriptions[i];
|
||||
var lat = el['location']['lat'];
|
||||
var lon = el['location']['lon'];
|
||||
subscribed.add(new YourLocation(
|
||||
id: ObjectId.fromHexString(el['_id']['_str']),
|
||||
lat: lat,
|
||||
lon: lon,
|
||||
subscribed: true,
|
||||
distance: el['distance']));
|
||||
id: ObjectId.fromHexString(el['_id']['_str']),
|
||||
lat: lat,
|
||||
lon: lon,
|
||||
subscribed: true,
|
||||
distance: el['distance']));
|
||||
}
|
||||
|
||||
return subscribed;
|
||||
|
|
@ -116,12 +117,13 @@ class FiresApi {
|
|||
});
|
||||
}
|
||||
|
||||
Future<UpdateYourLocationMapStatsAction> getFiresInLocation(
|
||||
{AppState state, double lat, double lon, int distance}) async {
|
||||
Future<UpdateFireMapStatsAction> getFiresInLocation(
|
||||
{AppState state, double lat, double lon, int distance}) async {
|
||||
assert(state.firesApiUrl != null);
|
||||
assert(state.firesApiKey != null);
|
||||
var url = '${state.firesApiUrl}fires-in-full/${state
|
||||
.firesApiKey}/${lat}/${lon}/${distance}';
|
||||
if (globals.isDevelopment) print(url);
|
||||
return await resty.get(url).go().then((response) {
|
||||
if (response.statusCode == 200) {
|
||||
var resultDecoded = json.decode(response.body);
|
||||
|
|
@ -135,13 +137,13 @@ class FiresApi {
|
|||
var industriesCount = industries.length;
|
||||
var falsePosCount = falsePos.length;
|
||||
print(
|
||||
'real: $numFires, fire: $firesCount falsePos: $falsePosCount industries: $industriesCount');
|
||||
'(Pos: $lat, $lon) real: $numFires, fire: $firesCount falsePos: $falsePosCount industries: $industriesCount');
|
||||
}
|
||||
return new UpdateYourLocationMapStatsAction(
|
||||
numFires: numFires,
|
||||
fires: fires,
|
||||
falsePos: falsePos,
|
||||
industries: industries);
|
||||
return new UpdateFireMapStatsAction(
|
||||
numFires: numFires,
|
||||
fires: fires,
|
||||
falsePos: falsePos,
|
||||
industries: industries);
|
||||
} else
|
||||
throw Exception('Wrong response trying to get fire data');
|
||||
});
|
||||
|
|
@ -159,15 +161,16 @@ class FiresApi {
|
|||
// print(resultDecoded['data']['union']);
|
||||
List<Polyline> union = [];
|
||||
final multipolygon =
|
||||
json.decode(resultDecoded['data']['union']['value'])['geometry']
|
||||
['coordinates'];
|
||||
json.decode(resultDecoded['data']['union']['value'])['geometry']
|
||||
['coordinates'];
|
||||
for (List<dynamic> polygon in multipolygon) {
|
||||
for (List<dynamic> hole in polygon) {
|
||||
List<LatLng> points = [];
|
||||
for (List<dynamic> point in hole) {
|
||||
points.add(new LatLng(point[1].toDouble(), point[0].toDouble()));
|
||||
}
|
||||
union.add(new Polyline(points: points, color: color, strokeWidth: 3.0));
|
||||
union.add(
|
||||
new Polyline(points: points, color: color, strokeWidth: 3.0));
|
||||
}
|
||||
}
|
||||
return union;
|
||||
|
|
@ -175,4 +178,32 @@ class FiresApi {
|
|||
throw Exception('Wrong response trying to get fire data');
|
||||
});
|
||||
}
|
||||
|
||||
Future<bool> markFalsePositive(AppState state, String mobileToken,
|
||||
String sealed, FalsePositiveType type) async {
|
||||
assert(state.firesApiUrl != null);
|
||||
assert(state.firesApiKey != null);
|
||||
assert(mobileToken != null);
|
||||
assert(sealed != null);
|
||||
assert(type != null);
|
||||
|
||||
final params = {
|
||||
"token": state.firesApiKey,
|
||||
"mobileToken": mobileToken,
|
||||
"sealed": sealed,
|
||||
"type": type.toString()
|
||||
};
|
||||
final String url = '${state.firesApiUrl}mobile/falsepositive';
|
||||
return await resty.post(url).json(params).go().then((response) {
|
||||
if (response.statusCode == 200) {
|
||||
// print(response.body);
|
||||
if (globals.isDevelopment) print(
|
||||
json.decode(response.body)['data']['upsert']);
|
||||
return true;
|
||||
} else {
|
||||
debugPrint(json.decode(response.body));
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,13 +97,7 @@ void fetchDataMiddleware(Store<AppState> store, action, NextDispatcher next) {
|
|||
}
|
||||
|
||||
if (action is ShowFireNotificationMapAction) {
|
||||
api
|
||||
.getFiresInLocation(
|
||||
state: store.state,
|
||||
lat: action.notif.lat,
|
||||
lon: action.notif.lon,
|
||||
distance: 1) // FalsePositive/server/publications.js
|
||||
.then((result) => store.dispatch(result));
|
||||
getFiresStatsInFire(store, action.notif);
|
||||
}
|
||||
|
||||
if (action is UpdateYourLocationAction) {
|
||||
|
|
@ -221,10 +215,30 @@ void fetchDataMiddleware(Store<AppState> store, action, NextDispatcher next) {
|
|||
});
|
||||
}
|
||||
|
||||
if (action is MarkFireAsFalsePositiveAction) {
|
||||
api.markFalsePositive(store.state, store.state.user.token, action.notif.sealed, action.type).then((result) {
|
||||
if (result) {
|
||||
// Not necessary
|
||||
// store.dispatch(new UpdatedFireNotificationAction(action.notif));
|
||||
getFiresStatsInFire(store, action.notif);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure our actions continue on to the reducer.
|
||||
next(action);
|
||||
}
|
||||
|
||||
void getFiresStatsInFire(Store<AppState> store, FireNotification notif) {
|
||||
api
|
||||
.getFiresInLocation(
|
||||
state: store.state,
|
||||
lat: notif.lat,
|
||||
lon: notif.lon,
|
||||
distance: 1) // FalsePositive/server/publications.js
|
||||
.then((result) => store.dispatch(result));
|
||||
}
|
||||
|
||||
void unsubsViaApi(Store<AppState> store, ObjectId id, onUnsubs) {
|
||||
api.unsubscribe(store.state, id.toHexString()).then((res) {
|
||||
onUnsubs();
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ class UpdateYourLocationMapAction extends FiresMapActions {
|
|||
);
|
||||
}
|
||||
|
||||
class UpdateYourLocationMapStatsAction extends FiresMapActions {
|
||||
class UpdateFireMapStatsAction extends FiresMapActions {
|
||||
int numFires;
|
||||
List<dynamic> fires = [];
|
||||
List<dynamic> falsePos = [];
|
||||
List<dynamic> industries = [];
|
||||
|
||||
UpdateYourLocationMapStatsAction(
|
||||
UpdateFireMapStatsAction(
|
||||
{@required this.numFires,
|
||||
@required this.fires,
|
||||
@required this.falsePos,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ final fireMapReducer = combineReducers<FireMapState>([
|
|||
_showYourLocationMap),
|
||||
new TypedReducer<FireMapState, ShowFireNotificationMapAction>(
|
||||
_showFireNotificationMap),
|
||||
new TypedReducer<FireMapState, UpdateYourLocationMapStatsAction>(
|
||||
new TypedReducer<FireMapState, UpdateFireMapStatsAction>(
|
||||
_updateYourLocationMapStats),
|
||||
new TypedReducer<FireMapState, SubscribeAction>(_subscribeYourLocationMap),
|
||||
new TypedReducer<FireMapState, SubscribeConfirmAction>(
|
||||
|
|
@ -27,7 +27,7 @@ final fireMapReducer = combineReducers<FireMapState>([
|
|||
]);
|
||||
|
||||
FireMapState _updateYourLocationMapStats(
|
||||
FireMapState state, UpdateYourLocationMapStatsAction action) {
|
||||
FireMapState state, UpdateFireMapStatsAction action) {
|
||||
return state.copyWith(
|
||||
numFires: action.numFires,
|
||||
fires: action.fires,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:fires_flutter/models/fireNotification.dart';
|
||||
import '../models/falsePositiveTypes.dart';
|
||||
|
||||
abstract class FireNotificationActions {}
|
||||
|
||||
|
|
@ -45,3 +46,16 @@ class ReadedFireNotificationAction extends FireNotificationActions {
|
|||
|
||||
ReadedFireNotificationAction(this.notif);
|
||||
}
|
||||
|
||||
class MarkFireAsFalsePositiveAction extends FireNotificationActions {
|
||||
final FireNotification notif;
|
||||
final FalsePositiveType type;
|
||||
|
||||
MarkFireAsFalsePositiveAction(this.notif, this.type);
|
||||
}
|
||||
|
||||
class UpdatedFireNotificationAction extends FireNotificationActions {
|
||||
final FireNotification notif;
|
||||
|
||||
UpdatedFireNotificationAction(this.notif);
|
||||
}
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
import 'package:fires_flutter/models/fireNotification.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
|
||||
import 'actions.dart';
|
||||
import 'package:fires_flutter/models/fireNotification.dart';
|
||||
|
||||
final fireNotificationReducer = combineReducers<List<FireNotification>>([
|
||||
new TypedReducer<List<FireNotification>, AddedFireNotificationAction>(
|
||||
_addedFireNotification),
|
||||
new TypedReducer<List<FireNotification>, DeletedFireNotificationAction>(
|
||||
_deletedFireNotification),
|
||||
_deletedFireNotification),
|
||||
new TypedReducer<List<FireNotification>, UpdatedFireNotificationAction>(
|
||||
_updatedFireNotification),
|
||||
new TypedReducer<List<FireNotification>, DeletedAllFireNotificationAction>(
|
||||
_deletedAllFireNotifications),
|
||||
_deletedAllFireNotifications),
|
||||
new TypedReducer<List<FireNotification>, ReadedFireNotificationAction>(
|
||||
_readedFireNotification)
|
||||
_readedFireNotification)
|
||||
]);
|
||||
|
||||
List<FireNotification> _addedFireNotification(
|
||||
|
|
@ -20,10 +22,18 @@ List<FireNotification> _addedFireNotification(
|
|||
}
|
||||
|
||||
List<FireNotification> _deletedFireNotification(
|
||||
List<FireNotification> notifications, DeletedFireNotificationAction action) {
|
||||
List<FireNotification> notifications,
|
||||
DeletedFireNotificationAction action) {
|
||||
return new List.from(notifications)..remove(action.notif);
|
||||
}
|
||||
|
||||
List<FireNotification> _updatedFireNotification(
|
||||
List<FireNotification> notifications, UpdatedFireNotificationAction action) {
|
||||
return notifications
|
||||
.map((notif) => notif.id == action.notif.id ? action.notif : notif)
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<FireNotification> _readedFireNotification(
|
||||
List<FireNotification> notifications, ReadedFireNotificationAction action) {
|
||||
return notifications
|
||||
|
|
@ -33,6 +43,7 @@ List<FireNotification> _readedFireNotification(
|
|||
}
|
||||
|
||||
List<FireNotification> _deletedAllFireNotifications(
|
||||
List<FireNotification> notifications, DeletedAllFireNotificationAction action) {
|
||||
List<FireNotification> notifications,
|
||||
DeletedAllFireNotificationAction action) {
|
||||
return new List<FireNotification>();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue