diff --git a/lib/screens/currencies_screen.dart b/lib/screens/currencies_screen.dart index fd2da59..18376df 100644 --- a/lib/screens/currencies_screen.dart +++ b/lib/screens/currencies_screen.dart @@ -7,7 +7,7 @@ import '../utils/currencies.dart'; class CurrenciesScreen extends StatelessWidget { final List currencies; - CurrenciesScreen(this.currencies); + const CurrenciesScreen(this.currencies, {Key key}) : super(key: key); Widget _renderItem(BuildContext context, int i) { final currency = currencies[i]; @@ -25,7 +25,7 @@ class CurrenciesScreen extends StatelessWidget { title: Text(currency.name), onTap: () => Navigator.of(context).pop({'code': currency.code}), ), - Divider(height: 1), + const Divider(height: 1), ], ); } @@ -36,7 +36,7 @@ class CurrenciesScreen extends StatelessWidget { appBar: PlatformAppBar( trailingActions: [ IconButton( - icon: Icon(Icons.search), + icon: const Icon(Icons.search), onPressed: () async { Currency result = await showSearch( context: context, @@ -96,7 +96,7 @@ class CurrenciesSearchDelegate extends SearchDelegate { List buildActions(BuildContext context) { return [ IconButton( - icon: Icon(Icons.clear), + icon: const Icon(Icons.clear), onPressed: () { query = ''; }, diff --git a/lib/screens/edit_email.dart b/lib/screens/edit_email.dart index 62222b7..2e882a5 100644 --- a/lib/screens/edit_email.dart +++ b/lib/screens/edit_email.dart @@ -1,10 +1,10 @@ -import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; -import 'package:provider/provider.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; +import 'package:provider/provider.dart'; -import '../services/api.dart'; import '../providers/account.dart'; +import '../services/api.dart'; class EditEmailScreen extends StatefulWidget { static const routeName = '/edit-email'; diff --git a/lib/screens/edit_name.dart b/lib/screens/edit_name.dart index 9125eb6..6251220 100644 --- a/lib/screens/edit_name.dart +++ b/lib/screens/edit_name.dart @@ -96,7 +96,7 @@ class _EditNameState extends State { Widget build(BuildContext context) { return PlatformScaffold( appBar: PlatformAppBar( - title: Text('Edit Name'), + title: const Text('Edit Name'), trailingActions: [ PlatformIconButton( iosIcon: Icon(CupertinoIcons.check_mark), @@ -116,7 +116,7 @@ class _EditNameState extends State { controller: _firstNameController, textInputAction: TextInputAction.next, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'First name', ), ), @@ -131,7 +131,7 @@ class _EditNameState extends State { controller: _lastNameController, focusNode: _lastNameFocusNode, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Last name', ), ), diff --git a/lib/screens/forgot_password.dart b/lib/screens/forgot_password.dart index 3272cb0..7886283 100644 --- a/lib/screens/forgot_password.dart +++ b/lib/screens/forgot_password.dart @@ -23,7 +23,7 @@ class _ForgotPasswordState extends State { content: Text(message), actions: [ PlatformDialogAction( - child: Text('OK'), + child: const Text('OK'), onPressed: () => Navigator.of(context, rootNavigator: true).pop(), ) ], @@ -59,7 +59,7 @@ class _ForgotPasswordState extends State { Widget build(BuildContext context) { return PlatformScaffold( appBar: PlatformAppBar( - title: Text('Reset password'), + title: const Text('Reset password'), ), body: SafeArea( child: SingleChildScrollView( @@ -70,9 +70,7 @@ class _ForgotPasswordState extends State { Text( 'Enter the email address and we’ll send you instructions to reset your password.', ), - SizedBox( - height: 16, - ), + const SizedBox(height: 16), PlatformTextField( autofocus: true, autocorrect: false, @@ -80,7 +78,7 @@ class _ForgotPasswordState extends State { keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.send, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Email', ), ), @@ -89,9 +87,7 @@ class _ForgotPasswordState extends State { ), onEditingComplete: _resetPassword, ), - SizedBox( - height: 16, - ), + const SizedBox(height: 16), PlatformButton( color: Theme.of(context).primaryColor, android: (_) => MaterialRaisedButtonData( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index c1c1bd3..13a463f 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -70,6 +70,25 @@ class _HomeScreenState extends State { } class _AndroidHome extends StatelessWidget { + final _tabs = [ + Tab( + child: Align( + alignment: Alignment.center, + child: const Text('Balance'), + ), + ), + Tab( + child: Align( + alignment: Alignment.center, + child: const Text('Expenses'), + ), + ), + ]; + final _tabsViews = [ + BalanceList(), + ExpensesList(), + ]; + @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); @@ -125,32 +144,14 @@ class _AndroidHome extends StatelessWidget { indicator: TabBarIndicator( color: theme.primaryColorLight.withOpacity(0.3), ), - tabs: [ - Tab( - child: Align( - alignment: Alignment.center, - child: Text('Balance'), - ), - ), - Tab( - child: Align( - alignment: Alignment.center, - child: Text('Expenses'), - ), - ), - ], + tabs: _tabs, ), ), - body: TabBarView( - children: [ - BalanceList(), - ExpensesList(), - ], - ), - drawer: AppDrawer(), + body: TabBarView(children: _tabsViews), + drawer: const AppDrawer(), floatingActionButton: SpeedDial( tooltip: 'Add Expense or Payment', - child: Icon(Icons.add), + child: const Icon(Icons.add), visible: true, curve: Curves.decelerate, overlayOpacity: theme.brightness == Brightness.dark ? 0.54 : 0.8, @@ -160,7 +161,7 @@ class _AndroidHome extends StatelessWidget { SpeedDialChild( child: const Icon(Icons.shopping_basket), onTap: () {}, - labelWidget: SpeedDialLabel( + labelWidget: const SpeedDialLabel( title: 'New Expense', subTitle: 'A purchase made for the group', ), @@ -168,7 +169,7 @@ class _AndroidHome extends StatelessWidget { SpeedDialChild( child: const Icon(Icons.account_balance_wallet), onTap: () => {}, - labelWidget: SpeedDialLabel( + labelWidget: const SpeedDialLabel( title: 'New Payment', subTitle: 'Record a payment made in the group', ), diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 717dfc5..25135b6 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -81,7 +81,7 @@ class _LoginScreenState extends State { Widget build(BuildContext context) { return PlatformScaffold( appBar: PlatformAppBar( - title: Text('Login'), + title: const Text('Login'), ), body: SafeArea( child: SingleChildScrollView( @@ -96,7 +96,7 @@ class _LoginScreenState extends State { keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Email', ), ), @@ -113,7 +113,7 @@ class _LoginScreenState extends State { controller: _passwordController, textInputAction: TextInputAction.go, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Password', ), ), @@ -123,7 +123,7 @@ class _LoginScreenState extends State { focusNode: _passwordFocusNode, onSubmitted: (_) => _handleSubmit(), ), - SizedBox(height: 16), + const SizedBox(height: 16), Selector( selector: (_, auth) => auth.isFetching, builder: (_, isFetching, __) => PlatformButton( @@ -137,7 +137,7 @@ class _LoginScreenState extends State { ), PlatformButton( androidFlat: (_) => MaterialFlatButtonData(), - child: Text('Forgot password?'), + child: const Text('Forgot password?'), onPressed: _forgotPassword, ), ], diff --git a/lib/screens/offline.dart b/lib/screens/offline.dart index 02b5cad..4309c35 100644 --- a/lib/screens/offline.dart +++ b/lib/screens/offline.dart @@ -37,6 +37,10 @@ class OfflineScreen extends StatelessWidget { selector: (_, groups) => Tuple2(groups.status, groups.fetchGroups), builder: (_, data, __) => PlatformButton( + color: Theme.of(context).primaryColor, + android: (_) => MaterialRaisedButtonData( + colorBrightness: Brightness.dark, + ), child: Text('Try again'), onPressed: data.item1 == Status.PENDING ? null : data.item2, diff --git a/lib/screens/register.dart b/lib/screens/register.dart index 409af42..220064e 100644 --- a/lib/screens/register.dart +++ b/lib/screens/register.dart @@ -91,7 +91,7 @@ class _RegisterScreenState extends State { Widget build(BuildContext context) { return PlatformScaffold( appBar: PlatformAppBar( - title: Text('Sign up'), + title: const Text('Sign up'), ), body: SafeArea( child: SingleChildScrollView( @@ -105,7 +105,7 @@ class _RegisterScreenState extends State { keyboardType: TextInputType.text, textInputAction: TextInputAction.next, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'First name', ), ), @@ -121,7 +121,7 @@ class _RegisterScreenState extends State { keyboardType: TextInputType.text, textInputAction: TextInputAction.next, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Last name', ), ), @@ -138,7 +138,7 @@ class _RegisterScreenState extends State { keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Email', ), ), @@ -155,7 +155,7 @@ class _RegisterScreenState extends State { focusNode: _passwordFocusNode, textInputAction: TextInputAction.go, android: (_) => MaterialTextFieldData( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Password', ), ), @@ -164,7 +164,7 @@ class _RegisterScreenState extends State { ), onSubmitted: (_) => _handleSubmit(), ), - SizedBox(height: 16), + const SizedBox(height: 16), Selector( selector: (_, auth) => auth.isFetching, builder: (_, isFetching, __) => PlatformButton( diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 37c839a..8db058a 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -16,6 +16,7 @@ import '../providers/auth.dart'; import '../providers/account.dart'; import '../providers/groups.dart'; import '../widgets/avatar.dart'; +import '../widgets/loading_dialog.dart'; import '../utils/constants.dart'; enum MoreMenuOptions { @@ -224,6 +225,7 @@ class _SettingsScreenState extends State { PlatformDialogAction( onPressed: () => Navigator.of(context).pop(true), child: Text('Delete'), + ios: (_) => CupertinoDialogActionData(isDestructiveAction: true), ), ], ), @@ -233,18 +235,7 @@ class _SettingsScreenState extends State { showPlatformDialog( androidBarrierDismissible: false, context: context, - builder: (_) => PlatformAlertDialog( - content: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - PlatformCircularProgressIndicator(), - SizedBox(height: 12), - Text('Loading...'), - ], - ), - ), + builder: (_) => LoadingDialog(), ); try { await Provider.of(context, listen: false) diff --git a/lib/utils/currencies.dart b/lib/utils/currencies.dart index 52f1316..28ec159 100644 --- a/lib/utils/currencies.dart +++ b/lib/utils/currencies.dart @@ -1,8 +1,11 @@ +import 'package:flutter/foundation.dart'; + +@immutable class Currency { final String name; final String symbol; final String code; - Currency({this.name, this.symbol, this.code}); + const Currency({this.name, this.symbol, this.code}); factory Currency.fromMap(Map map) => Currency( name: map['name'], @@ -11,7 +14,7 @@ class Currency { ); } -final Map> currencies = { +const Map> currencies = const { "AED": {"name": "Emirati Dirham", "code": "AED", "symbol": ".د.ب"}, "AFN": {"name": "Afghan Afghani", "code": "AFN", "symbol": "؋"}, "ALL": {"name": "Albanian lek", "code": "ALL", "symbol": "lek"}, diff --git a/lib/widgets/app_drawer.dart b/lib/widgets/app_drawer.dart index c051973..b7f718e 100644 --- a/lib/widgets/app_drawer.dart +++ b/lib/widgets/app_drawer.dart @@ -8,6 +8,8 @@ import '../screens/group.dart'; import '../screens/settings.dart'; class AppDrawer extends StatefulWidget { + const AppDrawer({Key key}) : super(key: key); + @override _AppDrawerState createState() => _AppDrawerState(); } diff --git a/lib/widgets/empty_expenses.dart b/lib/widgets/empty_expenses.dart index 490439b..064468b 100644 --- a/lib/widgets/empty_expenses.dart +++ b/lib/widgets/empty_expenses.dart @@ -4,6 +4,7 @@ class EmptyExpenses extends StatelessWidget { @override Widget build(BuildContext context) { return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ CircleAvatar( @@ -20,6 +21,7 @@ class EmptyExpenses extends StatelessWidget { Text( 'No expenses', style: Theme.of(context).textTheme.body2.copyWith(fontSize: 18), + textAlign: TextAlign.center, ), const SizedBox(height: 4), SizedBox( diff --git a/lib/widgets/expenses_list.dart b/lib/widgets/expenses_list.dart index 82822db..e05fb86 100644 --- a/lib/widgets/expenses_list.dart +++ b/lib/widgets/expenses_list.dart @@ -5,17 +5,7 @@ import './empty_expenses.dart'; import '../models/expense.dart'; class ExpensesList extends StatelessWidget { - final List _expenses = [ - Expense( - id: '1', - name: 'Groceries', - payerId: '1', - date: DateTime.now(), - createdAt: DateTime.now(), - currency: 'EUR', - amount: 10.00, - ) - ]; + final List _expenses = []; Widget _renderItem(BuildContext context, int i) { return Column( diff --git a/lib/widgets/loading_dialog.dart b/lib/widgets/loading_dialog.dart new file mode 100644 index 0000000..685ad30 --- /dev/null +++ b/lib/widgets/loading_dialog.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; + +class LoadingDialog extends StatelessWidget { + @override + Widget build(BuildContext context) { + return PlatformAlertDialog( + content: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + PlatformCircularProgressIndicator(), + const SizedBox(height: 12), + const Text('Loading...'), + ], + ), + ); + } +} diff --git a/lib/widgets/speed_dial_label.dart b/lib/widgets/speed_dial_label.dart index c979180..8dcd30c 100644 --- a/lib/widgets/speed_dial_label.dart +++ b/lib/widgets/speed_dial_label.dart @@ -4,10 +4,11 @@ class SpeedDialLabel extends StatelessWidget { final String title; final String subTitle; - SpeedDialLabel({ + const SpeedDialLabel({ + Key key, @required this.title, @required this.subTitle, - }); + }) : super(key: key); @override Widget build(BuildContext context) {