diff --git a/lib/activeFires.dart b/lib/activeFires.dart index da04de6..6f590ea 100644 --- a/lib/activeFires.dart +++ b/lib/activeFires.dart @@ -25,6 +25,7 @@ class _ViewModel { final DeleteYourLocationFunction onDelete; final ToggleSubscriptionFunction onToggleSubs; final OnLocationTapFunction onTap; + final OnRefreshYourLocationsFunction onRefresh; final bool isLoading; _ViewModel( @@ -32,6 +33,7 @@ class _ViewModel { @required this.onDelete, @required this.onToggleSubs, @required this.onTap, + @required this.onRefresh, @required this.yourLocations, @required this.isLoading}); @@ -91,7 +93,12 @@ class _ActiveFiresPageState extends State { loc.subscribed = !loc.subscribed; onToggle(loc); }), - title: new Text(loc.description), + title: + new Text(loc.description) + , + subtitle: loc.currentNumFires == YourLocation.withoutStats || + loc.currentNumFires == 0 ? null: new Text(S.of(context).firesAroundThisArea( + loc.currentNumFires.toString(), loc.distance.toString())), onLongPress: () { showSnackMsg(S.of(context).toDeleteThisPlace); }, @@ -173,6 +180,8 @@ class _ActiveFiresPageState extends State { onTap: (loc) { gotoLocationMap(store, loc, context); }, + onRefresh: (refreshCallback) => + store.dispatch(new FetchYourLocationsAction(refreshCallback)), yourLocations: store.state.yourLocations, isLoading: !store.state.isLoaded); }, @@ -203,8 +212,19 @@ class _ActiveFiresPageState extends State { ? new SpinKitPulse(color: fires600) : hasLocations ? new Stack(children: [ - _buildSavedLocations(context, view.yourLocations, - view.onDelete, view.onToggleSubs, view.onTap), + new RefreshIndicator( + child: _buildSavedLocations( + context, + view.yourLocations, + view.onDelete, + view.onToggleSubs, + view.onTap), + onRefresh: () async { + final Completer completer = + new Completer(); + view.onRefresh(completer); + return completer.future; + }), new FabDialer(_fabMiniMenuItemList(context, view.onAdd), fires600, new Icon(Icons.add)) ]) diff --git a/lib/models/appState.dart b/lib/models/appState.dart index 107c108..068b3a2 100644 --- a/lib/models/appState.dart +++ b/lib/models/appState.dart @@ -3,6 +3,8 @@ import 'package:fires_flutter/models/fireNotification.dart'; import 'package:fires_flutter/models/yourLocation.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:meta/meta.dart'; +import 'package:flutter/material.dart'; +import 'dart:async'; import 'fireMapState.dart'; import 'user.dart'; @@ -95,6 +97,7 @@ class AppState extends Object with _$AppStateSerializerMixin { typedef void AddYourLocationFunction(YourLocation loc); typedef void DeleteYourLocationFunction(YourLocation loc); +typedef void OnRefreshYourLocationsFunction(Completer callback); typedef void ToggleSubscriptionFunction(YourLocation loc); typedef void OnLocationTapFunction(YourLocation loc); typedef void OnSubscribeFunction(YourLocation loc); diff --git a/lib/models/yourLocation.dart b/lib/models/yourLocation.dart index b3354ba..b0b2472 100644 --- a/lib/models/yourLocation.dart +++ b/lib/models/yourLocation.dart @@ -16,18 +16,20 @@ class YourLocation extends Object with _$YourLocationSerializerMixin { String description; bool subscribed; int distance; + int currentNumFires; factory YourLocation.fromJson(Map json) => _$YourLocationFromJson(json); static YourLocation noLocation = new YourLocation(lat: 0.0, lon: 0.0); - +static const int withoutStats = null; YourLocation( {this.id, @required this.lat, @required this.lon, this.description, this.distance: 10, + int currentNumFires: withoutStats, this.subscribed: false}) { if (this.description == null) this.description = 'Position: ${this.lat}, ${this.lon}'; @@ -40,6 +42,7 @@ class YourLocation extends Object with _$YourLocationSerializerMixin { lon, description, distance, + currentNumFires, subscribed}) { return new YourLocation( id: id?? this.id, @@ -47,6 +50,7 @@ class YourLocation extends Object with _$YourLocationSerializerMixin { lon: lon?? this.lon, description: description?? this.description, distance: distance?? this.distance, + currentNumFires: currentNumFires ?? this.currentNumFires, subscribed: subscribed?? this.subscribed ); } @@ -62,6 +66,7 @@ class YourLocation extends Object with _$YourLocationSerializerMixin { lon == other.lon && description == other.description && subscribed == other.subscribed && + currentNumFires == other.currentNumFires && distance == other.distance; @override @@ -71,10 +76,11 @@ class YourLocation extends Object with _$YourLocationSerializerMixin { lon.hashCode ^ description.hashCode ^ subscribed.hashCode ^ + currentNumFires.hashCode ^ distance.hashCode; @override String toString() { - return 'YourLocation {id: $id, lat: $lat, lon: $lon, description: $description, subscribed: $subscribed, distance: $distance}'; + return 'YourLocation {id: $id, lat: $lat, lon: $lon, description: $description, subscribed: $subscribed, distance: $distance, currentNumFires: $currentNumFires}'; } } diff --git a/lib/redux/appActions.dart b/lib/redux/appActions.dart index ba31c32..55f6765 100644 --- a/lib/redux/appActions.dart +++ b/lib/redux/appActions.dart @@ -1,9 +1,14 @@ import 'package:fires_flutter/models/yourLocation.dart'; import 'package:fires_flutter/models/fireNotification.dart'; +import 'dart:async'; abstract class AppActions {} -class FetchYourLocationsAction extends AppActions {} +class FetchYourLocationsAction extends AppActions { + Completer refreshCallback; + + FetchYourLocationsAction([this.refreshCallback]); +} class PersistAppStateAction extends AppActions {} diff --git a/lib/redux/fetchDataMiddleware.dart b/lib/redux/fetchDataMiddleware.dart index 20f36b1..34bbe25 100644 --- a/lib/redux/fetchDataMiddleware.dart +++ b/lib/redux/fetchDataMiddleware.dart @@ -4,6 +4,7 @@ import 'package:fires_flutter/models/fireNotification.dart'; import 'package:flutter_simple_dependency_injection/injector.dart'; import 'package:just_debounce_it/just_debounce_it.dart'; import 'package:redux/redux.dart'; +import 'dart:async'; import '../models/appState.dart'; import '../models/fireNotificationsPersist.dart'; @@ -150,8 +151,20 @@ void fetchDataMiddleware(Store store, action, NextDispatcher next) { localLocations.add(subsLoc); }).subscribed = true; }); + + localLocations.forEach((yl) { + api.getYourLocationFireStats(store.state, yl).then((value) { + yl.currentNumFires = value.numFires; + store.dispatch(new UpdateYourLocationAction(yl)); + }); + }); + store.dispatch(new FetchYourLocationsSucceededAction(localLocations)); persistYourLocations(localLocations); + Completer completer = action.refreshCallback; + if (completer != null) { + completer.complete(null); + } }); }).catchError((Exception error) { // If it fails, dispatch a failure action. The reducer will diff --git a/lib/redux/yourLocationActions.dart b/lib/redux/yourLocationActions.dart index 8cacef8..0fec9b7 100644 --- a/lib/redux/yourLocationActions.dart +++ b/lib/redux/yourLocationActions.dart @@ -51,9 +51,7 @@ class ToggledSubscriptionAction extends YourLocationActions { ToggledSubscriptionAction(this.loc); } -class SubscribeAction extends YourLocationActions { - SubscribeAction(); -} +class SubscribeAction extends YourLocationActions {} class SubscribeConfirmAction extends YourLocationActions { YourLocation loc;