Fire notification dialog. Connectivity dialgo

This commit is contained in:
Vicente J. Ruiz Jurado 2018-08-03 23:07:13 +02:00
parent e67256c010
commit 10b8680490
7 changed files with 184 additions and 140 deletions

View file

@ -1,12 +1,6 @@
import 'dart:async';
import 'package:bson_objectid/bson_objectid.dart';
import 'package:comunes_flutter/comunes_flutter.dart'; import 'package:comunes_flutter/comunes_flutter.dart';
import 'package:connectivity/connectivity.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:fires_flutter/models/fireNotification.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
@ -53,36 +47,11 @@ class _FiresAppState extends State<FiresApp> {
}; };
final Store<AppState> store; final Store<AppState> store;
String _connectionStatus = 'Unknown';
final Connectivity _connectivity = new Connectivity();
StreamSubscription<ConnectivityResult> _connectivitySubscription;
// globals.getIt.registerSingleton // globals.getIt.registerSingleton
_FiresAppState(this.store); _FiresAppState(this.store);
// Platform messages are asynchronous, so we initialize in an async method.
Future<Null> initConnectivity() async {
String connectionStatus;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
connectionStatus = (await _connectivity.checkConnectivity()).toString();
} on PlatformException catch (e) {
print(e.toString());
connectionStatus = 'Failed to get connectivity.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
return;
}
setState(() {
// store.dispatch(action);
_connectionStatus = connectionStatus;
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -112,102 +81,4 @@ class _FiresAppState extends State<FiresApp> {
theme: firesTheme, theme: firesTheme,
routes: routes)); routes: routes));
} }
@override
void initState() {
super.initState();
_firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
debugPrint("onMessage in fireApp: $message");
_showItemDialog(message, store);
}, onLaunch: (Map<String, dynamic> message) {
debugPrint("onLaunch: $message");
_navigateToItemDetail(message, store);
}, onResume: (Map<String, dynamic> message) {
debugPrint("onResume: $message");
_navigateToItemDetail(message, store);
});
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
store.dispatch(new OnUserTokenAction(token));
setState(() {});
});
initConnectivity();
_connectivitySubscription =
_connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
setState(() => _connectionStatus = result.toString());
});
}
void _showItemDialog(Map<String, dynamic> message, Store store) {
final notif = _notifForMessage(message);
showDialog<bool>(
context: navigatorKey.currentContext,
builder: (_) => _buildDialog(navigatorKey.currentContext, notif),
).then((bool shouldNavigate) {
if (shouldNavigate == true) {
_navigateToItemDetail(message, store);
}
}).catchError((e) => print("$e"));
}
Widget _buildDialog(BuildContext context, FireNotification item) {
return new AlertDialog(
content: new Text(item.description),
actions: <Widget>[
new FlatButton(
child: Text(S.of(context).CLOSE),
onPressed: () {
Navigator.pop(context, false);
},
),
new FlatButton(
child: Text(S.of(context).SHOW),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
}
void _navigateToItemDetail(Map<String, dynamic> message, Store store) {
FireNotification notif = _notifForMessage(message);
// Clear away dialogs
Navigator.popUntil(navigatorKey.currentContext,
(Route<dynamic> route) => route is PageRoute);
if (!notif.getRoute(store).isCurrent) {
Navigator.push(navigatorKey.currentContext, notif.getRoute(store));
}
}
// https://pub.dartlang.org/packages/firebase_messaging#-example-tab-
final FirebaseMessaging _firebaseMessaging = new FirebaseMessaging();
FireNotification _notifForMessage(Map<String, dynamic> message) {
FireNotification notif;
// print('start parse notif');
try {
notif = new FireNotification(
id: new ObjectId.fromHexString(message['id']),
subsId: new ObjectId.fromHexString(message['subsId']),
lat: double.parse(message['lat']),
lon: double.parse(message['lon']),
description: message['description'],
read: false,
when: DateTime.parse(message['when']),
sealed: message['sealed']);
// print('end parse notif');
debugPrint(notif.toString());
} catch (e) {
debugPrint(e.toString());
}
if (notif != null) store.dispatch(new AddFireNotificationAction(notif));
return notif;
}
} }

View file

@ -57,6 +57,7 @@ class S implements WidgetsLocalizations {
String get firesNearPlace => "Fires near other place"; String get firesNearPlace => "Fires near other place";
String get getAlertsOfFiresinThatArea => "Get alerts of fires in that area"; String get getAlertsOfFiresinThatArea => "Get alerts of fires in that area";
String get isYourUbicationEnabled => "I cannot get your current location. It's your ubication enabled?"; String get isYourUbicationEnabled => "I cannot get your current location. It's your ubication enabled?";
String get noConnectivity => "This app require an Internet connection";
String get noFiresAround => "There is no fires"; String get noFiresAround => "There is no fires";
String get notPermsUbication => "We don't have permission to get your location"; String get notPermsUbication => "We don't have permission to get your location";
String get notifyAFire => "Notify a fire"; String get notifyAFire => "Notify a fire";
@ -125,6 +126,8 @@ class es extends S {
@override @override
String get 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)."; String get 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).";
@override @override
String get noConnectivity => "Esta aplicación necesita conexión a Internet";
@override
String get AvoidThisStringsIfisNotPlural => "Zero One Two Few Many Other"; String get AvoidThisStringsIfisNotPlural => "Zero One Two Few Many Other";
@override @override
String get unsubscribe => "Desuscríbete"; String get unsubscribe => "Desuscríbete";

View file

@ -1,15 +1,100 @@
import 'package:comunes_flutter/comunes_flutter.dart'; import 'package:comunes_flutter/comunes_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:fires_flutter/models/fireNotification.dart';
import 'redux/actions.dart';
import 'activeFires.dart'; import 'activeFires.dart';
import 'fireAlert.dart'; import 'fireAlert.dart';
import 'colors.dart'; import 'colors.dart';
import 'generated/i18n.dart'; import 'generated/i18n.dart';
import 'mainDrawer.dart'; import 'mainDrawer.dart';
import 'package:connectivity/connectivity.dart';
class HomePage extends StatelessWidget { import 'dart:async';
import 'package:flutter/services.dart';
import 'package:redux/redux.dart';
import 'models/appState.dart';
import 'package:bson_objectid/bson_objectid.dart';
import 'package:flutter_simple_dependency_injection/injector.dart';
import 'fireNotificationList.dart';
class HomePage extends StatefulWidget {
static const String routeName = '/home'; static const String routeName = '/home';
HomePage();
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final Store<AppState> store = Injector.getInjector().get<Store<AppState>>();
final Connectivity _connectivity = new Connectivity();
// Platform messages are asynchronous, so we initialize in an async method.
Future<Null> initConnectivity() async {
ConnectivityResult connectionStatus;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
connectionStatus = (await _connectivity.checkConnectivity());
} on PlatformException catch (e) {
print(e.toString());
connectionStatus = ConnectivityResult.none;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) {
return;
}
setState(() {
store.dispatch(new OnConnectivityChanged(connectionStatus));
if (connectionStatus == ConnectivityResult.none) {
_showDialog(S
.of(context)
.noConnectivity);
}
});
}
@override
void initState() {
super.initState();
_firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
debugPrint("onMessage in fireApp: $message");
_showItemDialog(message);
}, onLaunch: (Map<String, dynamic> message) {
debugPrint("onLaunch: $message");
_navigateToItemDetail(message);
}, onResume: (Map<String, dynamic> message) {
debugPrint("onResume: $message");
_navigateToItemDetail(message);
});
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
store.dispatch(new OnUserTokenAction(token));
setState(() {});
});
initConnectivity();
// StreamSubscription<ConnectivityResult> _connectivitySubscription =
_connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
if (!mounted) {
return;
}
setState(() {
store.dispatch(new OnConnectivityChanged(result));
// _showDialog(result.toString());
});
});
}
final _homeFont = const TextStyle( final _homeFont = const TextStyle(
fontSize: 50.0, fontSize: 50.0,
@ -96,4 +181,89 @@ class HomePage extends StatelessWidget {
])), ])),
)); ));
} }
void _showDialog(String message) {
showDialog<bool>(
context: _scaffoldKey.currentContext,
builder: (_) => new AlertDialog(
content: new Text(message),
actions: <Widget>[
new FlatButton(
child: Text(S.of(_scaffoldKey.currentContext).CLOSE),
onPressed: () {
Navigator.pop(_scaffoldKey.currentContext);
},
),
],
));
}
void _showItemDialog(Map<String, dynamic> message) {
final notif = _notifForMessage(message);
showDialog<bool>(
context: _scaffoldKey.currentContext,
builder: (_) => _buildDialog(_scaffoldKey.currentContext, notif),
).then((bool shouldNavigate) {
if (shouldNavigate == true) {
_navigateToItemDetail(message);
}
}).catchError((e) => print("$e"));
}
Widget _buildDialog(BuildContext context, FireNotification item) {
return new AlertDialog(
content: new Text(item.description),
actions: <Widget>[
new FlatButton(
child: Text(S.of(context).CLOSE),
onPressed: () {
Navigator.pop(context, false);
},
),
new FlatButton(
child: Text(S.of(context).SHOW),
onPressed: () {
Navigator.pop(context, true);
},
),
],
);
}
void _navigateToItemDetail(Map<String, dynamic> message) {
_notifForMessage(message);
// Clear away dialogs
Navigator.popUntil(_scaffoldKey.currentContext,
(Route<dynamic> route) => route is PageRoute);
/* if (!notif.getRoute(store).isCurrent) {
// Navigator.push(_scaffoldKey.currentContext, notif.getRoute(store));
} */
Navigator.pushNamed(_scaffoldKey.currentContext, FireNotificationList.routeName);
}
// https://pub.dartlang.org/packages/firebase_messaging#-example-tab-
final FirebaseMessaging _firebaseMessaging = new FirebaseMessaging();
FireNotification _notifForMessage(Map<String, dynamic> message) {
FireNotification notif;
try {
notif = new FireNotification(
id: new ObjectId.fromHexString(message['id']),
subsId: new ObjectId.fromHexString(message['subsId']),
lat: double.parse(message['lat']),
lon: double.parse(message['lon']),
description: message['description'],
read: false,
when: DateTime.parse(message['when']),
sealed: message['sealed']);
debugPrint(notif.toString());
} catch (e) {
debugPrint(e.toString());
}
if (notif != null) store.dispatch(new AddFireNotificationAction(notif));
return notif;
}
} }

View file

@ -31,6 +31,7 @@ void mainCommon(List<Middleware<AppState>> otherMiddleware) {
middleware: List.from(otherMiddleware) middleware: List.from(otherMiddleware)
..add(fetchDataMiddleware)); ..add(fetchDataMiddleware));
injector.map<Store<AppState>>((i) => store);
injector.map<String>((i) => store.state.firesApiUrl, key: "firesApiUrl"); injector.map<String>((i) => store.state.firesApiUrl, key: "firesApiUrl");
injector.map<String>((i) => store.state.firesApiKey, key: "firesApiKey"); injector.map<String>((i) => store.state.firesApiKey, key: "firesApiKey");
injector.map<String>((i) => store.state.serverUrl, key: "serverUrl"); injector.map<String>((i) => store.state.serverUrl, key: "serverUrl");

View file

@ -2,11 +2,7 @@ import 'package:bson_objectid/bson_objectid.dart';
import 'package:comunes_flutter/comunes_flutter.dart'; import 'package:comunes_flutter/comunes_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:redux/src/store.dart';
import '../genericMap.dart';
import '../objectIdUtils.dart'; import '../objectIdUtils.dart';
import '../redux/actions.dart';
part 'fireNotification.g.dart'; part 'fireNotification.g.dart';
@ -84,6 +80,7 @@ class FireNotification extends Object with _$FireNotificationSerializerMixin {
static final Map<String, Route<Null>> routes = <String, Route<Null>>{}; static final Map<String, Route<Null>> routes = <String, Route<Null>>{};
/*
Route<Null> getRoute(Store store) { Route<Null> getRoute(Store store) {
final String routeName = '/fire/${id}'; final String routeName = '/fire/${id}';
return routes.putIfAbsent( return routes.putIfAbsent(
@ -99,5 +96,5 @@ class FireNotification extends Object with _$FireNotificationSerializerMixin {
}, },
), ),
); );
} } */
} }

View file

@ -63,5 +63,6 @@
"deleteAllFireNotificationsAlertDescription": "This will remove all your fire notifications", "deleteAllFireNotificationsAlertDescription": "This will remove all your fire notifications",
"DELETE": "DELETE", "DELETE": "DELETE",
"SHOW": "SHOW", "SHOW": "SHOW",
"CLOSE": "CLOSE" "CLOSE": "CLOSE",
"noConnectivity": "This app require an Internet connection"
} }

View file

@ -63,5 +63,6 @@
"deleteAllFireNotificationsAlertDescription": "Esto borrará todas las notificaciones de fuegos", "deleteAllFireNotificationsAlertDescription": "Esto borrará todas las notificaciones de fuegos",
"DELETE": "BORRAR", "DELETE": "BORRAR",
"SHOW": "MOSTRAR", "SHOW": "MOSTRAR",
"CLOSE": "CERRAR" "CLOSE": "CERRAR",
"noConnectivity": "Esta aplicación necesita conexión a Internet"
} }