diff --git a/lib/homePage.dart b/lib/homePage.dart index 8a6ea4b..5e1aaf1 100644 --- a/lib/homePage.dart +++ b/lib/homePage.dart @@ -7,9 +7,11 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:fires_flutter/models/fireNotification.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_simple_dependency_injection/injector.dart'; import 'package:redux/redux.dart'; +import 'firesSpinner.dart'; import 'activeFires.dart'; import 'colors.dart'; import 'fireAlert.dart'; @@ -19,6 +21,23 @@ import 'mainDrawer.dart'; import 'models/appState.dart'; import 'redux/actions.dart'; +class _ViewModel { + final bool isLoaded; + + _ViewModel({@required this.isLoaded}); + + @override + bool operator ==(Object other) => + identical(this, other) || + other is _ViewModel && + runtimeType == other.runtimeType && + isLoaded == other.isLoaded; + + @override + int get hashCode => isLoaded.hashCode; + +} + class HomePage extends StatefulWidget { static const String routeName = '/home'; @@ -31,8 +50,8 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { final GlobalKey _scaffoldKey = new GlobalKey(); final Store store = Injector.getInjector().get>(); - final Connectivity _connectivity = new Connectivity(); + final List newNotifications = []; // Platform messages are asynchronous, so we initialize in an async method. Future initConnectivity() async { @@ -64,14 +83,14 @@ class _HomePageState extends State { void initState() { super.initState(); _firebaseMessaging.configure(onMessage: (Map message) { - debugPrint("onMessage in fireApp: $message"); + debugPrint("onMessage in fireApp (isLoaded: ${store.state.isLoaded}): $message"); _showItemDialog(message, _notifForMessage(message)); }, onLaunch: (Map message) { - debugPrint("onLaunch: $message"); + debugPrint("onLaunch (isLoaded: ${store.state.isLoaded}): $message"); _notifForMessage(message); _navigateToItemDetail(message); }, onResume: (Map message) { - debugPrint("onResume: $message"); + debugPrint("onResume (isLoaded: ${store.state.isLoaded}): $message"); _notifForMessage(message); _navigateToItemDetail(message); }); @@ -111,75 +130,95 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { - return new Scaffold( - key: _scaffoldKey, - drawer: new MainDrawer(context, HomePage.routeName), - floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: - Column(mainAxisAlignment: MainAxisAlignment.end, children: [ - FloatingActionButton.extended( - elevation: 0.0, - onPressed: () { - Navigator.pushNamed(context, ActiveFiresPage.routeName); - }, - label: Text(S.of(context).activeFires, style: _btnFont), - backgroundColor: fires600, - heroTag: 'activeFires', - icon: const Icon(Icons.whatshot, size: 32.0), - ), - Padding( - padding: const EdgeInsets.only(top: 16.0, bottom: 26.0), - child: FloatingActionButton.extended( - elevation: 0.0, - onPressed: () { - Navigator.pushNamed(context, FireAlert.routeName); - }, - heroTag: 'notifyFire', - backgroundColor: fires600, - label: new Text(S.of(context).notifyAFire, style: _btnFont), - icon: const Icon(Icons.notifications_active, size: 32.0), - ), - ), - ]), - body: new SafeArea( - child: Center( - child: new CenteredColumn(children: [ - new Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - new IconButton( + return new StoreConnector( + distinct: true, + converter: (store) { + bool isLoaded = store.state.isLoaded; + if (isLoaded && newNotifications.isNotEmpty) { + newNotifications.forEach((notif) { + store.dispatch(new AddFireNotificationAction(notif)); + }); + newNotifications.clear(); + } + return new _ViewModel( + isLoaded: store.state.isLoaded + ); + }, + builder: (context, view) { + return new Scaffold( + key: _scaffoldKey, + drawer: new MainDrawer(context, HomePage.routeName), + floatingActionButtonLocation: + FloatingActionButtonLocation.centerFloat, + floatingActionButton: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FloatingActionButton.extended( + elevation: 0.0, onPressed: () { - _scaffoldKey.currentState.openDrawer(); + Navigator.pushNamed(context, ActiveFiresPage.routeName); }, - icon: new Icon(Icons.menu, - size: 30.0, color: Colors.black38)), - ]), - new Expanded( - child: new FractionallySizedBox( - alignment: FractionalOffset.center, - heightFactor: 0.7, - child: new Image.asset('images/logo-200.png', - fit: BoxFit.fitHeight))), - new Expanded( - child: new FractionallySizedBox( - alignment: FractionalOffset.topCenter, - heightFactor: 1.0, - child: new Column( + label: Text(S.of(context).activeFires, style: _btnFont), + backgroundColor: fires600, + heroTag: 'activeFires', + icon: const Icon(Icons.whatshot, size: 32.0), + ), + Padding( + padding: const EdgeInsets.only(top: 16.0, bottom: 26.0), + child: FloatingActionButton.extended( + elevation: 0.0, + onPressed: () { + Navigator.pushNamed(context, FireAlert.routeName); + }, + heroTag: 'notifyFire', + backgroundColor: fires600, + label: new Text(S.of(context).notifyAFire, + style: _btnFont), + icon: + const Icon(Icons.notifications_active, size: 32.0), + ), + ), + ]), + body: !view.isLoaded? new FiresSpinner(): new SafeArea( + child: Center( + child: new CenteredColumn(children: [ + new Row( + mainAxisAlignment: MainAxisAlignment.start, children: [ - new Padding( - padding: const EdgeInsets.symmetric( - vertical: 10.0, horizontal: 20.0), - child: FittedBox( - child: new Text(S.of(context).appName, - maxLines: 2, - textAlign: TextAlign.center, - style: _homeFont), - fit: BoxFit.scaleDown, - )), - ], - ))) - ])), - )); + new IconButton( + onPressed: () { + _scaffoldKey.currentState.openDrawer(); + }, + icon: new Icon(Icons.menu, + size: 30.0, color: Colors.black38)), + ]), + new Expanded( + child: new FractionallySizedBox( + alignment: FractionalOffset.center, + heightFactor: 0.7, + child: new Image.asset('images/logo-200.png', + fit: BoxFit.fitHeight))), + new Expanded( + child: new FractionallySizedBox( + alignment: FractionalOffset.topCenter, + heightFactor: 1.0, + child: new Column( + children: [ + new Padding( + padding: const EdgeInsets.symmetric( + vertical: 10.0, horizontal: 20.0), + child: FittedBox( + child: new Text(S.of(context).appName, + maxLines: 2, + textAlign: TextAlign.center, + style: _homeFont), + fit: BoxFit.scaleDown, + )), + ], + ))) + ])), + )); + }); } void _showDialog(String message) { @@ -259,7 +298,8 @@ class _HomePageState extends State { } catch (e) { debugPrint(e.toString()); } - if (notif != null) store.dispatch(new AddFireNotificationAction(notif)); + if (notif != null) + newNotifications.add(notif); return notif; } }