Navigation improvements

This commit is contained in:
Vicente J. Ruiz Jurado 2018-08-06 11:36:50 +02:00
parent ff854b2a06
commit 0b56a02a0b
9 changed files with 151 additions and 160 deletions

View file

@ -203,7 +203,7 @@ class _ActiveFiresPageState extends State<ActiveFiresPage> {
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
// FIXME new? // FIXME new?
drawer: MainDrawer.getDrawer(context), drawer: new MainDrawer(context, ActiveFiresPage.routeName),
appBar: new AppBar( appBar: new AppBar(
title: Text(title), title: Text(title),
leading: IconButton( leading: IconButton(

View file

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:share/share.dart'; import 'package:share/share.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'customStepper.dart'; import 'customStepper.dart';
import 'mainDrawer.dart';
import 'generated/i18n.dart'; import 'generated/i18n.dart';
import 'placesAutocompleteUtils.dart'; import 'placesAutocompleteUtils.dart';
@ -83,6 +84,7 @@ class _FireAlertState extends State<FireAlert> {
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
appBar: new AppBar(title: new Text(S.of(context).notifyAFire)), appBar: new AppBar(title: new Text(S.of(context).notifyAFire)),
drawer: new MainDrawer(context, FireAlert.routeName),
body: new CustomStepper( body: new CustomStepper(
currentCustomStep: _currentStep, currentCustomStep: _currentStep,
// type: StepperType.horizontal, // type: StepperType.horizontal,

View file

@ -178,7 +178,8 @@ class _FireNotificationListState extends State<FireNotificationList> {
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
drawer: MainDrawer.getDrawer(context), drawer: new MainDrawer(context, FireNotificationList.routeName),
appBar: new AppBar( appBar: new AppBar(
title: Text(title), title: Text(title),
leading: IconButton( leading: IconButton(

View file

@ -16,6 +16,7 @@ import 'models/appState.dart';
import 'package:bson_objectid/bson_objectid.dart'; import 'package:bson_objectid/bson_objectid.dart';
import 'package:flutter_simple_dependency_injection/injector.dart'; import 'package:flutter_simple_dependency_injection/injector.dart';
import 'fireNotificationList.dart'; import 'fireNotificationList.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
static const String routeName = '/home'; static const String routeName = '/home';
@ -52,9 +53,7 @@ class _HomePageState extends State<HomePage> {
setState(() { setState(() {
store.dispatch(new OnConnectivityChanged(connectionStatus)); store.dispatch(new OnConnectivityChanged(connectionStatus));
if (connectionStatus == ConnectivityResult.none) { if (connectionStatus == ConnectivityResult.none) {
_showDialog(S _showDialog(S.of(context).noConnectivity);
.of(context)
.noConnectivity);
} }
}); });
} }
@ -73,9 +72,9 @@ class _HomePageState extends State<HomePage> {
_navigateToItemDetail(message); _navigateToItemDetail(message);
}); });
_firebaseMessaging.requestNotificationPermissions( _firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true)); const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered _firebaseMessaging.onIosSettingsRegistered
.listen((IosNotificationSettings settings) { .listen((IosNotificationSettings settings) {
print("Settings registered: $settings"); print("Settings registered: $settings");
}); });
_firebaseMessaging.getToken().then((String token) { _firebaseMessaging.getToken().then((String token) {
@ -85,15 +84,15 @@ class _HomePageState extends State<HomePage> {
}); });
initConnectivity(); initConnectivity();
// StreamSubscription<ConnectivityResult> _connectivitySubscription = // StreamSubscription<ConnectivityResult> _connectivitySubscription =
_connectivity.onConnectivityChanged.listen((ConnectivityResult result) { _connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
if (!mounted) { if (!mounted) {
return; return;
} }
setState(() { setState(() {
store.dispatch(new OnConnectivityChanged(result)); store.dispatch(new OnConnectivityChanged(result));
// _showDialog(result.toString()); // _showDialog(result.toString());
});
}); });
});
} }
final _homeFont = const TextStyle( final _homeFont = const TextStyle(
@ -101,25 +100,24 @@ class _HomePageState extends State<HomePage> {
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
// color: Colors.white, // color: Colors.white,
); );
final _btnFont = const TextStyle( final _btnFont = const TextStyle(
fontSize: 20.0, fontSize: 20.0,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
// color: Colors.white, // color: Colors.white,
); );
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Scaffold( return new Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
drawer: MainDrawer.getDrawer(context), drawer: new MainDrawer(context, HomePage.routeName),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: floatingActionButton:
Column(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ Column(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
FloatingActionButton.extended( FloatingActionButton.extended(
elevation: 0.0, elevation: 0.0,
onPressed: () { onPressed: () {
Navigator.pushNamed(context, ActiveFiresPage.routeName); Navigator.pushNamed(context, ActiveFiresPage.routeName);
}, },
label: Text(S.of(context).activeFires, style: _btnFont), label: Text(S.of(context).activeFires, style: _btnFont),
backgroundColor: fires600, backgroundColor: fires600,
@ -172,7 +170,6 @@ class _HomePageState extends State<HomePage> {
child: new Text(S.of(context).appName, child: new Text(S.of(context).appName,
maxLines: 2, maxLines: 2,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: _homeFont), style: _homeFont),
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
)), )),
@ -182,22 +179,20 @@ class _HomePageState extends State<HomePage> {
)); ));
} }
void _showDialog(String message) { void _showDialog(String message) {
showDialog<bool>( showDialog<bool>(
context: _scaffoldKey.currentContext, context: _scaffoldKey.currentContext,
builder: (_) => new AlertDialog( builder: (_) => new AlertDialog(
content: new Text(message), content: new Text(message),
actions: <Widget>[ actions: <Widget>[
new FlatButton( new FlatButton(
child: Text(S.of(_scaffoldKey.currentContext).CLOSE), child: Text(S.of(_scaffoldKey.currentContext).CLOSE),
onPressed: () { onPressed: () {
Navigator.pop(_scaffoldKey.currentContext); Navigator.pop(_scaffoldKey.currentContext);
}, },
), ),
], ],
)); ));
} }
void _showItemDialog(Map<String, dynamic> message) { void _showItemDialog(Map<String, dynamic> message) {
@ -240,7 +235,8 @@ class _HomePageState extends State<HomePage> {
/* if (!notif.getRoute(store).isCurrent) { /* if (!notif.getRoute(store).isCurrent) {
// Navigator.push(_scaffoldKey.currentContext, notif.getRoute(store)); // Navigator.push(_scaffoldKey.currentContext, notif.getRoute(store));
} */ } */
Navigator.pushNamed(_scaffoldKey.currentContext, FireNotificationList.routeName); Navigator.pushNamed(
_scaffoldKey.currentContext, FireNotificationList.routeName);
} }
// https://pub.dartlang.org/packages/firebase_messaging#-example-tab- // https://pub.dartlang.org/packages/firebase_messaging#-example-tab-
@ -250,14 +246,14 @@ class _HomePageState extends State<HomePage> {
FireNotification notif; FireNotification notif;
try { try {
notif = new FireNotification( notif = new FireNotification(
id: new ObjectId.fromHexString(message['id']), id: new ObjectId.fromHexString(message['id']),
subsId: new ObjectId.fromHexString(message['subsId']), subsId: new ObjectId.fromHexString(message['subsId']),
lat: double.parse(message['lat']), lat: double.parse(message['lat']),
lon: double.parse(message['lon']), lon: double.parse(message['lon']),
description: message['description'], description: message['description'],
read: false, read: false,
when: DateTime.parse(message['when']), when: DateTime.parse(message['when']),
sealed: message['sealed']); sealed: message['sealed']);
debugPrint(notif.toString()); debugPrint(notif.toString());
} catch (e) { } catch (e) {
debugPrint(e.toString()); debugPrint(e.toString());
@ -265,5 +261,4 @@ class _HomePageState extends State<HomePage> {
if (notif != null) store.dispatch(new AddFireNotificationAction(notif)); if (notif != null) store.dispatch(new AddFireNotificationAction(notif));
return notif; return notif;
} }
} }

View file

@ -2,7 +2,6 @@ import 'package:badge/badge.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:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter_simple_dependency_injection/injector.dart';
import 'activeFires.dart'; import 'activeFires.dart';
import 'colors.dart'; import 'colors.dart';
@ -37,30 +36,19 @@ class _ViewModel {
} }
class MainDrawer extends Drawer { class MainDrawer extends Drawer {
MainDrawer(BuildContext context, {key}) MainDrawer(BuildContext context, String currentRoute, {key})
: super(key: key, child: mainDrawer(context)); : super(key: key, child: mainDrawer(context, currentRoute));
static getDrawer(BuildContext context) {
Injector inj = Injector.getInjector();
MainDrawer d;
try {
d = inj.get<MainDrawer>();
} catch (e) {
inj.map<MainDrawer>((i) => new MainDrawer(context), isSingleton: true);
d = inj.get<MainDrawer>();
}
return d;
}
} }
Widget mainDrawer(BuildContext context) { Widget mainDrawer(BuildContext context, String currentRoute) {
return new StoreConnector<AppState, _ViewModel>( return new StoreConnector<AppState, _ViewModel>(
distinct: true, distinct: true,
converter: (store) { converter: (store) {
return new _ViewModel(unreadCount: store.state.fireNotificationsUnread); return new _ViewModel(unreadCount: store.state.fireNotificationsUnread);
}, },
builder: (context, view) { builder: (context, view) {
final bottomTextStyle = new TextStyle(fontSize: 12.0, color: Colors.grey); final bottomTextStyle =
new TextStyle(fontSize: 12.0, color: Colors.grey);
return new ListView( return new ListView(
// Important: Remove any padding from the ListView. // Important: Remove any padding from the ListView.
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
@ -68,7 +56,7 @@ Widget mainDrawer(BuildContext context) {
new GestureDetector( new GestureDetector(
onTap: () { onTap: () {
Navigator.pop(context); Navigator.pop(context);
Navigator.pushNamed(context, '/'); Navigator.popAndPushNamed(context, '/');
}, },
child: new DrawerHeader( child: new DrawerHeader(
child: new Column( child: new Column(
@ -94,22 +82,22 @@ Widget mainDrawer(BuildContext context) {
new ListTile( new ListTile(
leading: const Icon(Icons.whatshot), leading: const Icon(Icons.whatshot),
title: new Text(S.of(context).activeFires), title: new Text(S.of(context).activeFires),
selected: currentRoute == ActiveFiresPage.routeName,
onTap: () { onTap: () {
Navigator.pop(context); Navigator.popAndPushNamed(context, ActiveFiresPage.routeName);
Navigator.pushNamed(context, ActiveFiresPage.routeName);
}, },
), ),
new ListTile( new ListTile(
leading: const Icon(Icons.notifications_active), leading: const Icon(Icons.notifications_active),
selected: currentRoute == FireAlert.routeName,
title: new Text(S.of(context).notifyAFire), title: new Text(S.of(context).notifyAFire),
onTap: () { onTap: () {
// Then close the drawer Navigator.popAndPushNamed(context, FireAlert.routeName);
Navigator.pop(context);
Navigator.pushNamed(context, FireAlert.routeName);
}, },
), ),
new ListTile( new ListTile(
leading: const Icon(Icons.notifications), leading: const Icon(Icons.notifications),
selected: currentRoute == FireNotificationList.routeName,
title: view.unreadCount > 0 title: view.unreadCount > 0
? Badge.after( ? Badge.after(
spacing: 5.0, spacing: 5.0,
@ -118,47 +106,45 @@ Widget mainDrawer(BuildContext context) {
value: ' ${view.unreadCount.toString()} ') value: ' ${view.unreadCount.toString()} ')
: Text(S.of(context).fireNotificationsTitleShort), : Text(S.of(context).fireNotificationsTitleShort),
onTap: () { onTap: () {
// Then close the drawer Navigator.popAndPushNamed(context, FireNotificationList.routeName);
Navigator.pop(context);
Navigator.pushNamed(context, FireNotificationList.routeName);
}, },
), ),
globals.isDevelopment globals.isDevelopment
? new ListTile( ? new ListTile(
leading: const Icon(Icons.map), leading: const Icon(Icons.map),
title: new Text(S.of(context).monitoredAreasTitle), selected: currentRoute == MonitoredAreasPage.routeName,
onTap: () { title: new Text(S.of(context).monitoredAreasTitle),
Navigator.pop(context); onTap: () {
Navigator.pushNamed(context, MonitoredAreasPage.routeName); Navigator.pop(context);
}, Navigator.popAndPushNamed(
) context, MonitoredAreasPage.routeName);
: null, },
)
: null,
new Divider(), new Divider(),
new ListTile( new ListTile(
leading: const Icon(Icons.favorite), leading: const Icon(Icons.favorite),
selected: currentRoute == SupportPage.routeName,
title: new Text(S.of(context).supportThisInitiative), title: new Text(S.of(context).supportThisInitiative),
onTap: () { onTap: () {
// Then close the drawer Navigator.popAndPushNamed(context, SupportPage.routeName);
Navigator.pop(context);
Navigator.pushNamed(context, SupportPage.routeName);
}, },
), ),
new ListTile( new ListTile(
leading: const Icon(Icons.lock), leading: const Icon(Icons.lock),
selected: currentRoute == PrivacyPage.routeName,
title: new Text(S.of(context).privacyPolicy), title: new Text(S.of(context).privacyPolicy),
onTap: () { onTap: () {
// Then close the drawer Navigator.popAndPushNamed(context, PrivacyPage.routeName);
Navigator.pop(context);
Navigator.pushNamed(context, PrivacyPage.routeName);
}, },
), ),
globals.isDevelopment globals.isDevelopment
? new ListTile( ? new ListTile(
leading: const Icon(Icons.bug_report), leading: const Icon(Icons.bug_report),
title: new Text('Sandbox'), title: new Text('Sandbox'),
selected: currentRoute == Sandbox.routeName,
onTap: () { onTap: () {
Navigator.pop(context); Navigator.popAndPushNamed(context, Sandbox.routeName);
Navigator.pushNamed(context, Sandbox.routeName);
}, },
) )
: null, : null,
@ -167,10 +153,12 @@ Widget mainDrawer(BuildContext context) {
applicationName: S.of(context).appName, applicationName: S.of(context).appName,
applicationVersion: globals.appVersion, applicationVersion: globals.appVersion,
applicationIcon: globals.appMediumIcon, applicationIcon: globals.appMediumIcon,
applicationLegalese: S.of(context).appLicense(DateTime.now().year.toString()), applicationLegalese:
S.of(context).appLicense(DateTime.now().year.toString()),
aboutBoxChildren: <Widget>[ aboutBoxChildren: <Widget>[
new SizedBox(height: 10.0), new SizedBox(height: 10.0),
new Text(S.of(context).appMoto), // , style: new TextStyle(fontStyle: FontStyle.italic)), new Text(S.of(context).appMoto),
// , style: new TextStyle(fontStyle: FontStyle.italic)),
new SizedBox(height: 10.0), new SizedBox(height: 10.0),
new Text(S.of(context).NASAAck, style: bottomTextStyle), new Text(S.of(context).NASAAck, style: bottomTextStyle),
// More ? // More ?

View file

@ -5,24 +5,27 @@ import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
import 'mainDrawer.dart';
abstract class MarkdownPage extends StatefulWidget { abstract class MarkdownPage extends StatefulWidget {
final String title; final String title;
final Future<String> file; final Future<String> file;
final String route;
MarkdownPage({this.title, this.file}); MarkdownPage({this.title, this.route, this.file});
@override @override
_MarkdownPageState createState() => _MarkdownPageState createState() =>
_MarkdownPageState(title: this.title, file: this.file); _MarkdownPageState(title: this.title, file: this.file, route: this.route);
} }
class _MarkdownPageState extends State<MarkdownPage> { class _MarkdownPageState extends State<MarkdownPage> {
final String title; final String title;
final String route;
final Future<String> file; final Future<String> file;
String pageData = ""; String pageData = "";
_MarkdownPageState({this.title, this.file}); _MarkdownPageState({this.title, this.file, this.route});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -37,6 +40,7 @@ class _MarkdownPageState extends State<MarkdownPage> {
}); });
return new Scaffold( return new Scaffold(
appBar: new AppBar(title: new Text(title ?? '')), appBar: new AppBar(title: new Text(title ?? '')),
drawer: new MainDrawer(context, route),
body: new Markdown(data: pageData)); body: new Markdown(data: pageData));
} }
} }

View file

@ -1,4 +1,3 @@
import 'package:comunes_flutter/comunes_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
@ -18,10 +17,10 @@ class _ViewModel {
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
other is _ViewModel && other is _ViewModel &&
runtimeType == other.runtimeType && runtimeType == other.runtimeType &&
monitoredAreas == other.monitoredAreas; monitoredAreas == other.monitoredAreas;
@override @override
int get hashCode => monitoredAreas.hashCode; int get hashCode => monitoredAreas.hashCode;
@ -33,70 +32,66 @@ class MonitoredAreasPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new StoreConnector<AppState, _ViewModel>( return new StoreConnector<AppState, _ViewModel>(
distinct: true, distinct: true,
converter: (store) { converter: (store) {
return new _ViewModel(store.state.monitoredAreas); return new _ViewModel(store.state.monitoredAreas);
}, },
builder: (context, view) { builder: (context, view) {
return new Scaffold( return new Scaffold(
appBar: appBar:
new AppBar(title: new Text(S new AppBar(title: new Text(S.of(context).monitoredAreasTitle)),
.of(context) drawer: new MainDrawer(context, MonitoredAreasPage.routeName),
.monitoredAreasTitle)), bottomNavigationBar: new CustomBottomAppBar(
drawer: MainDrawer.getDrawer(context), fabLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: new CustomBottomAppBar( showNotch: true,
fabLocation: FloatingActionButtonLocation.centerDocked, color: fires100,
showNotch: true, mainAxisAlignment: MainAxisAlignment.center,
color: fires100, actions: <Widget>[
mainAxisAlignment: MainAxisAlignment.center, new Flexible(
actions: <Widget>[new Flexible(child: child: new Padding(
new Padding( padding: new EdgeInsets.only(left: 10.0, right: 10.0),
padding: new EdgeInsets.only(left: 10.0, right: 10.0), child: child: new Column(
new Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, children: [
children: [ new Text(S.of(context).mapPrivacy,
new Text(S style: new TextStyle(
.of(context) fontStyle: FontStyle.italic,
.mapPrivacy, color: Colors.black38))
style: new TextStyle( ])))
fontStyle: FontStyle.italic, color: Colors.black38)) ]),
]))) body: !(view.monitoredAreas is List)
]), ? new SpinKitPulse(color: fires600)
body: !(view.monitoredAreas is List) : new Padding(
? new SpinKitPulse(color: fires600) padding: new EdgeInsets.all(10.0),
: new Padding( child: new Column(
padding: new EdgeInsets.all(10.0), children: [
child: new Column( new Padding(
children: [ padding: new EdgeInsets.only(
new Padding( top: 8.0, bottom: 8.0, left: 0.0, right: 0.0),
padding: new EdgeInsets.only( child: new Text(S.of(context).inGreenMonitoredAreas),
top: 8.0, bottom: 8.0, left: 0.0, right: 0.0), ),
child: new Text(S new Flexible(
.of(context) child: new FlutterMap(
.inGreenMonitoredAreas), options: new MapOptions(
), center: new LatLng(53.5775, 3.106111),
new Flexible( zoom: 1.0,
child: new FlutterMap( ),
options: new MapOptions( layers: [
center: new LatLng(53.5775, 3.106111), new TileLayerOptions(
zoom: 1.0, urlTemplate:
"https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']),
new PolylineLayerOptions(
polylines: view.monitoredAreas,
)
],
),
),
],
), ),
layers: [
new TileLayerOptions(
urlTemplate:
"https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png",
subdomains: ['a', 'b', 'c']),
new PolylineLayerOptions(
polylines: view.monitoredAreas,
)
],
), ),
), );
], });
),
),
);
});
} }
} }

View file

@ -10,6 +10,7 @@ class PrivacyPage extends MarkdownPage {
PrivacyPage(context) PrivacyPage(context)
: super( : super(
title: S.of(context).privacyPolicy, title: S.of(context).privacyPolicy,
route: routeName,
file: getFileNameOfLang( file: getFileNameOfLang(
dir: 'assets/pages', dir: 'assets/pages',
fileName: 'privacy', fileName: 'privacy',

View file

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'generated/i18n.dart'; import 'generated/i18n.dart';
import 'mainDrawer.dart';
class SupportPage extends StatefulWidget { class SupportPage extends StatefulWidget {
static const String routeName = '/support'; static const String routeName = '/support';
@ -33,12 +34,16 @@ class _SupportPageState extends State<SupportPage> {
key: _scaffoldKey, key: _scaffoldKey,
appBar: appBar:
new AppBar(title: new Text(S.of(context).supportThisInitiative)), new AppBar(title: new Text(S.of(context).supportThisInitiative)),
drawer: new MainDrawer(context, SupportPage.routeName),
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: new CenteredColumn(children: <Widget>[ child: new CenteredColumn(children: <Widget>[
new Flexible( new Flexible(
child: new CenteredColumn(children: <Widget>[ child: new CenteredColumn(children: <Widget>[
new Text(S.of(context).supportPageDescription, textAlign: TextAlign.center,), new Text(
S.of(context).supportPageDescription,
textAlign: TextAlign.center,
),
new SizedBox(height: 20.0), new SizedBox(height: 20.0),
buildSupportButton() buildSupportButton()
])) ]))