Fire notification map

This commit is contained in:
Vicente J. Ruiz Jurado 2018-07-26 22:32:30 +02:00
parent b7468de0d1
commit 8926fc20d9
12 changed files with 99 additions and 29 deletions

View file

@ -15,7 +15,7 @@ import 'mainDrawer.dart';
import 'models/appState.dart'; import 'models/appState.dart';
import 'placesAutocompleteUtils.dart'; import 'placesAutocompleteUtils.dart';
import 'redux/actions.dart'; import 'redux/actions.dart';
import 'yourLocationMap.dart'; import 'genericMap.dart';
@immutable @immutable
class _ViewModel { class _ViewModel {
@ -225,7 +225,7 @@ class _ActiveFiresPageState extends State<ActiveFiresPage> {
Store<AppState> store, YourLocation loc, BuildContext context) { Store<AppState> store, YourLocation loc, BuildContext context) {
store.dispatch(new ShowYourLocationMapAction(loc)); store.dispatch(new ShowYourLocationMapAction(loc));
Navigator.push(context, Navigator.push(context,
new MaterialPageRoute(builder: (context) => new YourLocationMap())); new MaterialPageRoute(builder: (context) => new genericMap()));
} }
void onAddYourLocation(AddYourLocationFunction onAdd) { void onAddYourLocation(AddYourLocationFunction onAdd) {

View file

@ -11,7 +11,7 @@ import 'generated/i18n.dart';
import 'mainDrawer.dart'; import 'mainDrawer.dart';
import 'models/appState.dart'; import 'models/appState.dart';
import 'redux/actions.dart'; import 'redux/actions.dart';
// import 'fireNotificationMap.dart'; import 'genericMap.dart';
@immutable @immutable
class _ViewModel { class _ViewModel {
@ -145,6 +145,9 @@ class _FireNotificationListState extends State<FireNotificationList> {
store.dispatch(new ReadFireNotificationAction( store.dispatch(new ReadFireNotificationAction(
notif.copyWith(read: true))); notif.copyWith(read: true)));
} }
new Timer(new Duration(milliseconds: 1000), () {
gotoMap(store, notif, context);
});
}, },
fireNotifications: store.state.fireNotifications); fireNotifications: store.state.fireNotifications);
}, },
@ -193,11 +196,11 @@ class _FireNotificationListState extends State<FireNotificationList> {
}); });
} }
void gotoLocationMap( void gotoMap(
Store<AppState> store, FireNotification notif, BuildContext context) { Store<AppState> store, FireNotification notif, BuildContext context) {
/* store.dispatch(new ShowFireNotificationMapAction(notif)); store.dispatch(new ShowFireNotificationMapAction(notif));
Navigator.push(context, Navigator.push(context,
new MaterialPageRoute(builder: (context) => new FireNotificationMap())); */ new MaterialPageRoute(builder: (context) => new genericMap()));
} }
_showConfirmDialog(_ViewModel view) { _showConfirmDialog(_ViewModel view) {

View file

@ -46,8 +46,10 @@ class S implements WidgetsLocalizations {
String get confirm => "Confirm"; String get confirm => "Confirm";
String get deleteAllFireNotificationsAlertDescription => "This will remove all your fire notifications"; String get deleteAllFireNotificationsAlertDescription => "This will remove all your fire notifications";
String get errorFirePlaceDialog => "We couldn't get the location of the fire"; String get errorFirePlaceDialog => "We couldn't get the location of the fire";
String get fireNotificationTitle => "Fire Notification";
String get fireNotificationsDescription => "Here you will receive fire notifications in locations you are subscribed to"; String get fireNotificationsDescription => "Here you will receive fire notifications in locations you are subscribed to";
String get fireNotificationsTitle => "Fire Notifications"; String get fireNotificationsTitle => "Fire Notifications";
String get fireNotificationsTitleShort => "Notifications";
String get firesInTheWorld => "Active fires in the world"; String get firesInTheWorld => "Active fires in the world";
String get firesInYourPlaces => "Active fires in your places"; String get firesInYourPlaces => "Active fires in your places";
String get firesNearPlace => "Fires near other place"; String get firesNearPlace => "Fires near other place";
@ -127,6 +129,8 @@ class es extends S {
@override @override
String get notPermsUbication => "No tenemos permisos para conocer tu ubicación"; String get notPermsUbication => "No tenemos permisos para conocer tu ubicación";
@override @override
String get fireNotificationTitle => "Notificación de fuego";
@override
String get youDeletedThisPlace => "Has borrado este lugar"; String get youDeletedThisPlace => "Has borrado este lugar";
@override @override
String get callEmergencyServicesTitle => "Llama al 112"; String get callEmergencyServicesTitle => "Llama al 112";
@ -151,6 +155,8 @@ class es extends S {
@override @override
String get isYourUbicationEnabled => "No podemos saber tu ubicación actual. ¿Están los servicios de ubicación en tu móvil activados?"; String get isYourUbicationEnabled => "No podemos saber tu ubicación actual. ¿Están los servicios de ubicación en tu móvil activados?";
@override @override
String get fireNotificationsTitleShort => "Notificaciones";
@override
String get DELETE => "BORRAR"; String get DELETE => "BORRAR";
@override @override
String get aDay => "un día"; String get aDay => "un día";

View file

@ -15,12 +15,12 @@ import 'dummyMapPlugin.dart';
import 'fireMarkType.dart'; import 'fireMarkType.dart';
import 'fireMarker.dart'; import 'fireMarker.dart';
import 'generated/i18n.dart'; import 'generated/i18n.dart';
import 'genericMapBottom.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
import 'models/appState.dart'; import 'models/appState.dart';
import 'models/fireMapState.dart'; import 'models/fireMapState.dart';
import 'redux/actions.dart'; import 'redux/actions.dart';
import 'slider.dart'; import 'slider.dart';
import 'yourLocationMapBottom.dart';
import 'zoomMapPlugin.dart'; import 'zoomMapPlugin.dart';
@immutable @immutable
@ -57,12 +57,12 @@ class _ViewModel {
int get hashCode => mapState.hashCode; int get hashCode => mapState.hashCode;
} }
class YourLocationMap extends StatefulWidget { class genericMap extends StatefulWidget {
@override @override
_YourLocationMapState createState() => _YourLocationMapState(); _genericMapState createState() => _genericMapState();
} }
class _YourLocationMapState extends State<YourLocationMap> { class _genericMapState extends State<genericMap> {
// This needs to be stateful so when resizes don't get a new globalkey // This needs to be stateful so when resizes don't get a new globalkey
// https://github.com/flutter/flutter/issues/1632#issuecomment-180478202 // https://github.com/flutter/flutter/issues/1632#issuecomment-180478202
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@ -128,7 +128,6 @@ class _YourLocationMapState extends State<YourLocationMap> {
// THIS does not works as expected // THIS does not works as expected
// maxZoom: 6.0, // maxZoom: 6.0,
onTap: (callback) { onTap: (callback) {
print('On tap ${callback}');
if (status == FireMapStatus.edit) { if (status == FireMapStatus.edit) {
_location = _location.copyWith( _location = _location.copyWith(
lat: callback.latitude, lon: callback.longitude); lat: callback.latitude, lon: callback.longitude);
@ -172,8 +171,12 @@ class _YourLocationMapState extends State<YourLocationMap> {
? new ZoomMapPluginOptions() ? new ZoomMapPluginOptions()
: new DummyMapPluginOptions(), : new DummyMapPluginOptions(),
new MarkerLayerOptions( new MarkerLayerOptions(
markers: buildMarkers(_location, mapState.fires, markers: buildMarkers(
mapState.industries, mapState.falsePos), _location,
mapState.fires,
mapState.industries,
mapState.falsePos,
mapState.fireNotification != null),
), ),
], ],
); );
@ -204,10 +207,13 @@ class _YourLocationMapState extends State<YourLocationMap> {
_location = _location.copyWith(description: newDesc); _location = _location.copyWith(description: newDesc);
}, },
) )
: status == FireMapStatus.viewFireNotification
? new Text(S.of(context).fireNotificationTitle)
: new Text(_location.description), : new Text(_location.description),
actions: buildAppBarActions(status, view, _location), actions: buildAppBarActions(status, view, _location),
), ),
floatingActionButton: status == FireMapStatus.edit floatingActionButton: status == FireMapStatus.edit ||
status == FireMapStatus.viewFireNotification
? null ? null
: FloatingActionButton.extended( : FloatingActionButton.extended(
onPressed: () { onPressed: () {
@ -224,6 +230,7 @@ class _YourLocationMapState extends State<YourLocationMap> {
view.onUnSubs(_location); view.onUnSubs(_location);
break; break;
case FireMapStatus.edit: case FireMapStatus.edit:
case FireMapStatus.viewFireNotification:
break; break;
} }
}, },
@ -238,7 +245,7 @@ class _YourLocationMapState extends State<YourLocationMap> {
), ),
floatingActionButtonLocation: floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat, FloatingActionButtonLocation.centerFloat,
bottomNavigationBar: new YourLocationMapBottom( bottomNavigationBar: new GenericMapBottom(
onSave: () => view.onEditConfirm(_location), onSave: () => view.onEditConfirm(_location),
onCancel: () => view.onEditCancel(_initialLocation), onCancel: () => view.onEditCancel(_initialLocation),
state: view.mapState), state: view.mapState),
@ -298,10 +305,11 @@ class _YourLocationMapState extends State<YourLocationMap> {
} }
List<Marker> buildMarkers(YourLocation yourLocation, List<dynamic> fires, List<Marker> buildMarkers(YourLocation yourLocation, List<dynamic> fires,
List<dynamic> falsePos, List<dynamic> industries) { List<dynamic> falsePos, List<dynamic> industries, bool isNotif) {
List<Marker> markers = []; List<Marker> markers = [];
const calibrate = false; // useful when we change the fire icons size const calibrate = false; // useful when we change the fire icons size
markers.add(FireMarker(yourLocation, FireMarkType.position)); markers.add(FireMarker(
yourLocation, isNotif ? FireMarkType.fire : FireMarkType.position));
if (calibrate) markers.add(FireMarker(yourLocation, FireMarkType.pixel)); if (calibrate) markers.add(FireMarker(yourLocation, FireMarkType.pixel));
falsePos.forEach((fire) { falsePos.forEach((fire) {
var coords = fire['geo']['coordinates']; var coords = fire['geo']['coordinates'];
@ -318,7 +326,8 @@ class _YourLocationMapState extends State<YourLocationMap> {
}); });
fires.forEach((fire) { fires.forEach((fire) {
var loc = new BasicLocation(lat: fire['lat'], lon: fire['lon']); var loc = new BasicLocation(lat: fire['lat'], lon: fire['lon']);
markers.add(FireMarker(loc, FireMarkType.fire, () => print('marker pressed'))); markers.add(
FireMarker(loc, FireMarkType.fire, () => print('marker pressed')));
markers.add(FireMarker(loc, FireMarkType.pixel)); markers.add(FireMarker(loc, FireMarkType.pixel));
}); });
return markers; return markers;

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'colors.dart'; import 'colors.dart';
import 'customBottomAppBar.dart'; import 'customBottomAppBar.dart';
import 'customMoment.dart';
import 'generated/i18n.dart'; import 'generated/i18n.dart';
import 'models/appState.dart'; import 'models/appState.dart';
import 'models/fireMapState.dart'; import 'models/fireMapState.dart';
@ -10,12 +11,13 @@ import 'models/fireMapState.dart';
typedef void OnSave(); typedef void OnSave();
typedef void OnCancel(); typedef void OnCancel();
class YourLocationMapBottom extends StatelessWidget { class GenericMapBottom extends StatelessWidget {
final OnSave onSave; final OnSave onSave;
final OnCancel onCancel; final OnCancel onCancel;
final FireMapState state; final FireMapState state;
YourLocationMapBottom({@required this.onSave,@required this.onCancel,@required this.state}); GenericMapBottom(
{@required this.onSave, @required this.onCancel, @required this.state});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -25,7 +27,6 @@ class YourLocationMapBottom extends StatelessWidget {
fabLocation: FloatingActionButtonLocation.centerFloat, fabLocation: FloatingActionButtonLocation.centerFloat,
showNotch: false, showNotch: false,
color: fires100, color: fires100,
// height: 170.0,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
actions: buildActionList(loc, context, kmAround)); actions: buildActionList(loc, context, kmAround));
} }
@ -46,6 +47,27 @@ class YourLocationMapBottom extends StatelessWidget {
break; break;
case FireMapStatus.subscriptionConfirm: case FireMapStatus.subscriptionConfirm:
break; break;
case FireMapStatus.viewFireNotification:
actionList.add(new Flexible(
child: new Padding(
padding: new EdgeInsets.all(10.0),
child: new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Text(state.fireNotification.description),
new SizedBox(height: 5.0),
new Row(
children: <Widget>[
new Icon(Icons.access_time),
new SizedBox(width: 5.0),
new Text(Moment
.now()
.from(context, state.fireNotification.when))
],
)
]))));
break;
case FireMapStatus.unsubscribe: case FireMapStatus.unsubscribe:
case FireMapStatus.view: case FireMapStatus.view:
if (state.numFires != null) { if (state.numFires != null) {

View file

@ -67,7 +67,7 @@ Widget mainDrawer(BuildContext context) {
), ),
new ListTile( new ListTile(
leading: const Icon(Icons.notifications), leading: const Icon(Icons.notifications),
title: new Text(S.of(context).fireNotificationsTitle), title: new Text(S.of(context).fireNotificationsTitleShort),
onTap: () { onTap: () {
// Then close the drawer // Then close the drawer
Navigator.pop(context); Navigator.pop(context);

View file

@ -1,12 +1,14 @@
import 'package:fires_flutter/models/yourLocation.dart'; import 'package:fires_flutter/models/yourLocation.dart';
import 'package:fires_flutter/models/fireNotification.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
enum FireMapStatus { view, subscriptionConfirm, unsubscribe, edit } enum FireMapStatus { view, subscriptionConfirm, unsubscribe, edit, viewFireNotification }
@immutable @immutable
class FireMapState { class FireMapState {
final FireMapStatus status; final FireMapStatus status;
final int numFires; final int numFires;
final FireNotification fireNotification;
final List<dynamic> fires; final List<dynamic> fires;
final List<dynamic> falsePos; final List<dynamic> falsePos;
final List<dynamic> industries; final List<dynamic> industries;
@ -15,6 +17,7 @@ class FireMapState {
const FireMapState.initial() const FireMapState.initial()
: this.status = FireMapStatus.view, : this.status = FireMapStatus.view,
this.yourLocation = null, this.yourLocation = null,
this.fireNotification = null,
this.numFires = 0, this.numFires = 0,
this.fires = const [], this.fires = const [],
this.falsePos = const [], this.falsePos = const [],
@ -25,12 +28,14 @@ class FireMapState {
this.yourLocation, this.yourLocation,
this.numFires, this.numFires,
this.fires, this.fires,
this.fireNotification,
this.falsePos, this.falsePos,
this.industries}); this.industries});
FireMapState copyWith({ FireMapState copyWith({
FireMapStatus status, FireMapStatus status,
YourLocation yourLocation, YourLocation yourLocation,
FireNotification fireNotication,
int numFires, int numFires,
List<dynamic> fires, List<dynamic> fires,
List<dynamic> falsePos, List<dynamic> falsePos,
@ -38,6 +43,7 @@ class FireMapState {
}) { }) {
return new FireMapState( return new FireMapState(
yourLocation: yourLocation ?? this.yourLocation, yourLocation: yourLocation ?? this.yourLocation,
fireNotification: fireNotication ?? this.fireNotification,
numFires: numFires ?? this.numFires, numFires: numFires ?? this.numFires,
fires: fires ?? this.fires, fires: fires ?? this.fires,
falsePos: falsePos ?? this.falsePos, falsePos: falsePos ?? this.falsePos,
@ -52,6 +58,7 @@ class FireMapState {
runtimeType == other.runtimeType && runtimeType == other.runtimeType &&
status == other.status && status == other.status &&
numFires == other.numFires && numFires == other.numFires &&
fireNotification == other.fireNotification &&
fires == other.fires && fires == other.fires &&
falsePos == other.falsePos && falsePos == other.falsePos &&
industries == other.industries && industries == other.industries &&
@ -61,6 +68,7 @@ class FireMapState {
int get hashCode => int get hashCode =>
status.hashCode ^ status.hashCode ^
numFires.hashCode ^ numFires.hashCode ^
fireNotification.hashCode ^
fires.hashCode ^ fires.hashCode ^
falsePos.hashCode ^ falsePos.hashCode ^
industries.hashCode ^ industries.hashCode ^
@ -70,6 +78,6 @@ class FireMapState {
String toString() { String toString() {
return 'FireMapState{status: $status, numFires: $numFires, fires: ${fires return 'FireMapState{status: $status, numFires: $numFires, fires: ${fires
.length}, falsePos: ${falsePos.length}, industries: ${industries .length}, falsePos: ${falsePos.length}, industries: ${industries
.length}, yourLocation: $yourLocation}'; .length}, yourLocation: $yourLocation, fireNotification: $fireNotification}';
} }
} }

View file

@ -1,4 +1,5 @@
import 'package:fires_flutter/models/yourLocation.dart'; import 'package:fires_flutter/models/yourLocation.dart';
import 'package:fires_flutter/models/fireNotification.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
abstract class FiresMapActions {} abstract class FiresMapActions {}
@ -30,6 +31,12 @@ class ShowYourLocationMapAction extends FiresMapActions {
ShowYourLocationMapAction(this.loc); ShowYourLocationMapAction(this.loc);
} }
class ShowFireNotificationMapAction extends FiresMapActions {
FireNotification notif;
ShowFireNotificationMapAction(this.notif);
}
class EditYourLocationAction extends FiresMapActions { class EditYourLocationAction extends FiresMapActions {
YourLocation loc; YourLocation loc;

View file

@ -1,11 +1,13 @@
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:fires_flutter/models/yourLocation.dart';
import '../models/fireMapState.dart'; import '../models/fireMapState.dart';
import 'actions.dart'; import 'actions.dart';
final fireMapReducer = combineReducers<FireMapState>([ final fireMapReducer = combineReducers<FireMapState>([
new TypedReducer<FireMapState, ShowYourLocationMapAction>( new TypedReducer<FireMapState, ShowYourLocationMapAction>(
_showYourLocationMap), _showYourLocationMap),
new TypedReducer<FireMapState, ShowFireNotificationMapAction>(
_showFireNotificationMap),
new TypedReducer<FireMapState, UpdateYourLocationMapStatsAction>( new TypedReducer<FireMapState, UpdateYourLocationMapStatsAction>(
_updateYourLocationMapStats), _updateYourLocationMapStats),
new TypedReducer<FireMapState, SubscribeAction>(_subscribeYourLocationMap), new TypedReducer<FireMapState, SubscribeAction>(_subscribeYourLocationMap),
@ -45,6 +47,14 @@ FireMapState _showYourLocationMap(
yourLocation: action.loc); yourLocation: action.loc);
} }
FireMapState _showFireNotificationMap(
FireMapState state, ShowFireNotificationMapAction action) {
// TODO: use here you real location?
YourLocation pseudoLoc = new YourLocation(lat: action.notif.lat, lon: action.notif.lon, description: action.notif.description);
return state.copyWith(
status: FireMapStatus.viewFireNotification, yourLocation: pseudoLoc, fireNotication: action.notif);
}
FireMapState _subscribeYourLocationMap( FireMapState _subscribeYourLocationMap(
FireMapState state, SubscribeAction action) { FireMapState state, SubscribeAction action) {
return state.copyWith(status: FireMapStatus.subscriptionConfirm); return state.copyWith(status: FireMapStatus.subscriptionConfirm);
@ -52,7 +62,8 @@ FireMapState _subscribeYourLocationMap(
FireMapState _subscribeConfirmYourLocationMap( FireMapState _subscribeConfirmYourLocationMap(
FireMapState state, SubscribeConfirmAction action) { FireMapState state, SubscribeConfirmAction action) {
return state.copyWith(status: FireMapStatus.unsubscribe, yourLocation: action.loc); return state.copyWith(
status: FireMapStatus.unsubscribe, yourLocation: action.loc);
} }
FireMapState _unsubscribeYourLocationMap( FireMapState _unsubscribeYourLocationMap(

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
/* /*
Useful for debug Useful for debug
import 'package:fluttery/framing.dart'; import 'package:fluttery/framing.dart';
new RandomColorBlock( child: new RandomColorBlock( child
*/ */
class Sandbox extends StatelessWidget { class Sandbox extends StatelessWidget {

View file

@ -53,7 +53,9 @@
"tweetAboutAFireTitle": "Tweet about", "tweetAboutAFireTitle": "Tweet about",
"tweetAboutAFireDescription": "Additionally if you use twitter you can share additional information with the emergency services, for example, attaching photos to the tweet if you have good visibility of the fire, when you took the photos, exact location, etc. Use #hashtags type #IFMinicipalTerminal for example #IFJumilla (Forest Fire in Jumilla).", "tweetAboutAFireDescription": "Additionally if you use twitter you can share additional information with the emergency services, for example, attaching photos to the tweet if you have good visibility of the fire, when you took the photos, exact location, etc. Use #hashtags type #IFMinicipalTerminal for example #IFJumilla (Forest Fire in Jumilla).",
"supportPageDescription": "You can support this initiative, spreading the word, helping us to develop our software, translating this app to your language, etc.", "supportPageDescription": "You can support this initiative, spreading the word, helping us to develop our software, translating this app to your language, etc.",
"fireNotificationsTitleShort": "Notifications",
"fireNotificationsTitle": "Fire Notifications", "fireNotificationsTitle": "Fire Notifications",
"fireNotificationTitle": "Fire Notification",
"fireNotificationsDescription": "Here you will receive fire notifications in locations you are subscribed to", "fireNotificationsDescription": "Here you will receive fire notifications in locations you are subscribed to",
"areYouSureTitle": "Are you sure?", "areYouSureTitle": "Are you sure?",
"deleteAllFireNotificationsAlertDescription": "This will remove all your fire notifications", "deleteAllFireNotificationsAlertDescription": "This will remove all your fire notifications",

View file

@ -54,6 +54,8 @@
"tweetAboutAFireDescription": "Adicionalmente si usas twitter puedes compartir información adicional con los servicios de emergencia, por ejemplo, adjuntando fotos al tweet si tienes buena visibilidad del fuego, cuando tomaste las fotos, ubicación exacta, etc. Usa #hashtags tipo #IFTerminoMunicipal por ejemplo #IFJumilla (Incendio Forestal en Jumilla).", "tweetAboutAFireDescription": "Adicionalmente si usas twitter puedes compartir información adicional con los servicios de emergencia, por ejemplo, adjuntando fotos al tweet si tienes buena visibilidad del fuego, cuando tomaste las fotos, ubicación exacta, etc. Usa #hashtags tipo #IFTerminoMunicipal por ejemplo #IFJumilla (Incendio Forestal en Jumilla).",
"supportPageDescription": "Puedes apoyar esta iniciativa, dando difusión, ayudándonos a desarrollar nuestro software, traduciendo esta aplicación a tu idioma, etc.", "supportPageDescription": "Puedes apoyar esta iniciativa, dando difusión, ayudándonos a desarrollar nuestro software, traduciendo esta aplicación a tu idioma, etc.",
"fireNotificationsTitle": "Notificaciones de fuegos", "fireNotificationsTitle": "Notificaciones de fuegos",
"fireNotificationTitle": "Notificación de fuego",
"fireNotificationsTitleShort": "Notificaciones",
"fireNotificationsDescription": "Aquí recibirás las notificaciones de fuegos en los lugares a los que te subscribas", "fireNotificationsDescription": "Aquí recibirás las notificaciones de fuegos en los lugares a los que te subscribas",
"areYouSureTitle": "¿Seguro?", "areYouSureTitle": "¿Seguro?",
"deleteAllFireNotificationsAlertDescription": "Esto borrará todas las notificaciones de fuegos", "deleteAllFireNotificationsAlertDescription": "Esto borrará todas las notificaciones de fuegos",