Added toast library

This commit is contained in:
Hillel Coren 2020-11-08 04:58:50 +02:00
parent 827b38fdff
commit d47763869a
6 changed files with 248 additions and 248 deletions

View File

@ -190,6 +190,7 @@ abstract class TaskEntity extends Object
TaskEntity get clone => rebuild((b) => b TaskEntity get clone => rebuild((b) => b
..id = BaseEntity.nextId ..id = BaseEntity.nextId
..number = ''
..isChanged = false ..isChanged = false
..isDeleted = false ..isDeleted = false
..invoiceId = null ..invoiceId = null

View File

@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:invoiceninja_flutter/constants.dart'; import 'package:invoiceninja_flutter/constants.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
@ -173,221 +174,242 @@ class InvoiceNinjaAppState extends State<InvoiceNinjaApp> {
TargetPlatform.android: ZoomPageTransitionsBuilder(), TargetPlatform.android: ZoomPageTransitionsBuilder(),
}); });
Intl.defaultLocale = localeSelector(state); Intl.defaultLocale = localeSelector(state);
final locale = AppLocalization.createLocale(localeSelector(state));
return MaterialApp( return StyledToast(
supportedLocales: kLanguages locale: locale,
.map((String locale) => AppLocalization.createLocale(locale)) duration: Duration(seconds: 3),
.toList(), backgroundColor:
//debugShowCheckedModeBanner: false, state.prefState.enableDarkMode ? Colors.white : Colors.black,
//showPerformanceOverlay: true, textStyle: TextStyle(
localizationsDelegates: [ color:
const AppLocalizationsDelegate(), state.prefState.enableDarkMode ? Colors.black87 : Colors.white,
GlobalCupertinoLocalizations.delegate, ),
GlobalWidgetsLocalizations.delegate, child: MaterialApp(
GlobalMaterialLocalizations.delegate supportedLocales: kLanguages
], .map((String locale) => AppLocalization.createLocale(locale))
home: state.prefState.requireAuthentication && !_authenticated .toList(),
? LockScreen(onAuthenticatePressed: _authenticate) //debugShowCheckedModeBanner: false,
: InitScreen(), //showPerformanceOverlay: true,
locale: AppLocalization.createLocale(localeSelector(state)), localizationsDelegates: [
theme: state.prefState.enableDarkMode const AppLocalizationsDelegate(),
? ThemeData( GlobalCupertinoLocalizations.delegate,
pageTransitionsTheme: pageTransitionsTheme, GlobalWidgetsLocalizations.delegate,
brightness: Brightness.dark, GlobalMaterialLocalizations.delegate
accentColor: accentColor, ],
indicatorColor: accentColor, home: state.prefState.requireAuthentication && !_authenticated
textSelectionHandleColor: accentColor, ? LockScreen(onAuthenticatePressed: _authenticate)
fontFamily: fontFamily, : InitScreen(),
backgroundColor: Colors.black, locale: locale,
canvasColor: Colors.black, theme: state.prefState.enableDarkMode
cardColor: const Color(0xFF1B1C1E), ? ThemeData(
bottomAppBarColor: const Color(0xFF1B1C1E), pageTransitionsTheme: pageTransitionsTheme,
primaryColorDark: Colors.black, brightness: Brightness.dark,
buttonColor: accentColor, accentColor: accentColor,
) indicatorColor: accentColor,
: ThemeData( textSelectionHandleColor: accentColor,
pageTransitionsTheme: pageTransitionsTheme, fontFamily: fontFamily,
primaryColor: accentColor, backgroundColor: Colors.black,
accentColor: accentColor, canvasColor: Colors.black,
indicatorColor: accentColor, cardColor: const Color(0xFF1B1C1E),
textSelectionColor: accentColor, bottomAppBarColor: const Color(0xFF1B1C1E),
fontFamily: fontFamily, primaryColorDark: Colors.black,
backgroundColor: Colors.white, buttonColor: accentColor,
canvasColor: Colors.white, )
cardColor: Colors.white, : ThemeData(
bottomAppBarColor: Colors.white, pageTransitionsTheme: pageTransitionsTheme,
primaryColorDark: primaryColor: accentColor,
hasAccentColor ? accentColor : const Color(0xFF0D5D91), accentColor: accentColor,
primaryColorLight: indicatorColor: accentColor,
hasAccentColor ? accentColor : const Color(0xFF5dabf4), textSelectionColor: accentColor,
buttonColor: fontFamily: fontFamily,
hasAccentColor ? accentColor : const Color(0xFF0D5D91), backgroundColor: Colors.white,
scaffoldBackgroundColor: const Color(0xFFE7EBEE), canvasColor: Colors.white,
tabBarTheme: TabBarTheme( cardColor: Colors.white,
labelColor: hasAccentColor ? Colors.white : Colors.black, bottomAppBarColor: Colors.white,
unselectedLabelColor: hasAccentColor primaryColorDark:
? Colors.white.withOpacity(.65) hasAccentColor ? accentColor : const Color(0xFF0D5D91),
: Colors.black.withOpacity(.65), primaryColorLight:
), hasAccentColor ? accentColor : const Color(0xFF5dabf4),
/* buttonColor:
buttonTheme: ButtonThemeData( hasAccentColor ? accentColor : const Color(0xFF0D5D91),
textTheme: ButtonTextTheme.primary, scaffoldBackgroundColor: const Color(0xFFE7EBEE),
colorScheme: ColorScheme.light( tabBarTheme: TabBarTheme(
//primary: hasAccentColor ? Colors.white : Colors.black, labelColor: hasAccentColor ? Colors.white : Colors.black,
unselectedLabelColor: hasAccentColor
? Colors.white.withOpacity(.65)
: Colors.black.withOpacity(.65),
), ),
), /*
*/ buttonTheme: ButtonThemeData(
iconTheme: IconThemeData( textTheme: ButtonTextTheme.primary,
color: hasAccentColor ? null : accentColor, colorScheme: ColorScheme.light(
), //primary: hasAccentColor ? Colors.white : Colors.black,
appBarTheme: AppBarTheme(
brightness: Brightness.light,
color: hasAccentColor ? accentColor : Colors.white,
iconTheme: IconThemeData(
color: hasAccentColor ? Colors.white : accentColor,
),
textTheme: TextTheme(
headline6: Theme.of(context).textTheme.headline6.copyWith(
color: hasAccentColor ? Colors.white : Colors.black,
),
),
),
),
title: kAppName,
onGenerateRoute: isMobile(context) ? null : generateRoute,
routes: isMobile(context)
? {
LoginScreen.route: (context) => LoginScreen(),
MainScreen.route: (context) => MainScreen(),
DashboardScreenBuilder.route: (context) => ChangeLayoutBanner(
suggestedLayout: AppLayout.mobile,
appLayout: state.prefState.appLayout,
child: DashboardScreenBuilder(),
), ),
ProductScreen.route: (context) => ProductScreenBuilder(), ),
ProductViewScreen.route: (context) => ProductViewScreen(), */
ProductEditScreen.route: (context) => ProductEditScreen(), iconTheme: IconThemeData(
ClientScreen.route: (context) => ClientScreenBuilder(), color: hasAccentColor ? null : accentColor,
ClientViewScreen.route: (context) => ClientViewScreen(), ),
ClientEditScreen.route: (context) => ClientEditScreen(), appBarTheme: AppBarTheme(
InvoiceScreen.route: (context) => InvoiceScreenBuilder(), brightness: Brightness.light,
InvoiceViewScreen.route: (context) => InvoiceViewScreen(), color: hasAccentColor ? accentColor : Colors.white,
InvoiceEditScreen.route: (context) => InvoiceEditScreen(), iconTheme: IconThemeData(
InvoiceEmailScreen.route: (context) => InvoiceEmailScreen(), color: hasAccentColor ? Colors.white : accentColor,
DocumentScreen.route: (context) => DocumentScreenBuilder(), ),
DocumentViewScreen.route: (context) => DocumentViewScreen(), textTheme: TextTheme(
DocumentEditScreen.route: (context) => DocumentEditScreen(), headline6: Theme.of(context)
ExpenseScreen.route: (context) => ExpenseScreenBuilder(), .textTheme
ExpenseViewScreen.route: (context) => ExpenseViewScreen(), .headline6
ExpenseEditScreen.route: (context) => ExpenseEditScreen(), .copyWith(
VendorScreen.route: (context) => VendorScreenBuilder(), color:
VendorViewScreen.route: (context) => VendorViewScreen(), hasAccentColor ? Colors.white : Colors.black,
VendorEditScreen.route: (context) => VendorEditScreen(), ),
TaskScreen.route: (context) => TaskScreenBuilder(), ),
TaskViewScreen.route: (context) => TaskViewScreen(), ),
TaskEditScreen.route: (context) => TaskEditScreen(), ),
ProjectScreen.route: (context) => ProjectScreenBuilder(), title: kAppName,
ProjectViewScreen.route: (context) => ProjectViewScreen(), onGenerateRoute: isMobile(context) ? null : generateRoute,
ProjectEditScreen.route: (context) => ProjectEditScreen(), routes: isMobile(context)
PaymentScreen.route: (context) => PaymentScreenBuilder(), ? {
PaymentViewScreen.route: (context) => PaymentViewScreen(), LoginScreen.route: (context) => LoginScreen(),
PaymentEditScreen.route: (context) => PaymentEditScreen(), MainScreen.route: (context) => MainScreen(),
PaymentRefundScreen.route: (context) => PaymentRefundScreen(), DashboardScreenBuilder.route: (context) =>
QuoteScreen.route: (context) => QuoteScreenBuilder(), ChangeLayoutBanner(
QuoteViewScreen.route: (context) => QuoteViewScreen(), suggestedLayout: AppLayout.mobile,
QuoteEditScreen.route: (context) => QuoteEditScreen(), appLayout: state.prefState.appLayout,
QuoteEmailScreen.route: (context) => QuoteEmailScreen(), child: DashboardScreenBuilder(),
// STARTER: routes - do not remove comment ),
TaskStatusScreen.route: (context) => ProductScreen.route: (context) => ProductScreenBuilder(),
TaskStatusScreenBuilder(), ProductViewScreen.route: (context) => ProductViewScreen(),
TaskStatusViewScreen.route: (context) => ProductEditScreen.route: (context) => ProductEditScreen(),
TaskStatusViewScreen(), ClientScreen.route: (context) => ClientScreenBuilder(),
TaskStatusEditScreen.route: (context) => ClientViewScreen.route: (context) => ClientViewScreen(),
TaskStatusEditScreen(), ClientEditScreen.route: (context) => ClientEditScreen(),
ExpenseCategoryScreen.route: (context) => InvoiceScreen.route: (context) => InvoiceScreenBuilder(),
ExpenseCategoryScreenBuilder(), InvoiceViewScreen.route: (context) => InvoiceViewScreen(),
ExpenseCategoryViewScreen.route: (context) => InvoiceEditScreen.route: (context) => InvoiceEditScreen(),
ExpenseCategoryViewScreen(), InvoiceEmailScreen.route: (context) => InvoiceEmailScreen(),
ExpenseCategoryEditScreen.route: (context) => DocumentScreen.route: (context) => DocumentScreenBuilder(),
ExpenseCategoryEditScreen(), DocumentViewScreen.route: (context) => DocumentViewScreen(),
RecurringInvoiceScreen.route: (context) => DocumentEditScreen.route: (context) => DocumentEditScreen(),
RecurringInvoiceScreenBuilder(), ExpenseScreen.route: (context) => ExpenseScreenBuilder(),
RecurringInvoiceViewScreen.route: (context) => ExpenseViewScreen.route: (context) => ExpenseViewScreen(),
RecurringInvoiceViewScreen(), ExpenseEditScreen.route: (context) => ExpenseEditScreen(),
RecurringInvoiceEditScreen.route: (context) => VendorScreen.route: (context) => VendorScreenBuilder(),
RecurringInvoiceEditScreen(), VendorViewScreen.route: (context) => VendorViewScreen(),
WebhookScreen.route: (context) => WebhookScreenBuilder(), VendorEditScreen.route: (context) => VendorEditScreen(),
WebhookViewScreen.route: (context) => WebhookViewScreen(), TaskScreen.route: (context) => TaskScreenBuilder(),
WebhookEditScreen.route: (context) => WebhookEditScreen(), TaskViewScreen.route: (context) => TaskViewScreen(),
TokenScreen.route: (context) => TokenScreenBuilder(), TaskEditScreen.route: (context) => TaskEditScreen(),
TokenViewScreen.route: (context) => TokenViewScreen(), ProjectScreen.route: (context) => ProjectScreenBuilder(),
TokenEditScreen.route: (context) => TokenEditScreen(), ProjectViewScreen.route: (context) => ProjectViewScreen(),
PaymentTermScreen.route: (context) => ProjectEditScreen.route: (context) => ProjectEditScreen(),
PaymentTermScreenBuilder(), PaymentScreen.route: (context) => PaymentScreenBuilder(),
PaymentTermEditScreen.route: (context) => PaymentViewScreen.route: (context) => PaymentViewScreen(),
PaymentTermEditScreen(), PaymentEditScreen.route: (context) => PaymentEditScreen(),
PaymentTermViewScreen.route: (context) => PaymentRefundScreen.route: (context) =>
PaymentTermViewScreen(), PaymentRefundScreen(),
DesignScreen.route: (context) => DesignScreenBuilder(), QuoteScreen.route: (context) => QuoteScreenBuilder(),
DesignViewScreen.route: (context) => DesignViewScreen(), QuoteViewScreen.route: (context) => QuoteViewScreen(),
DesignEditScreen.route: (context) => DesignEditScreen(), QuoteEditScreen.route: (context) => QuoteEditScreen(),
CreditScreen.route: (context) => CreditScreenBuilder(), QuoteEmailScreen.route: (context) => QuoteEmailScreen(),
CreditViewScreen.route: (context) => CreditViewScreen(), // STARTER: routes - do not remove comment
CreditEditScreen.route: (context) => CreditEditScreen(), TaskStatusScreen.route: (context) =>
UserScreen.route: (context) => UserScreenBuilder(), TaskStatusScreenBuilder(),
UserViewScreen.route: (context) => UserViewScreen(), TaskStatusViewScreen.route: (context) =>
UserEditScreen.route: (context) => UserEditScreen(), TaskStatusViewScreen(),
GroupSettingsScreen.route: (context) => GroupScreenBuilder(), TaskStatusEditScreen.route: (context) =>
GroupViewScreen.route: (context) => GroupViewScreen(), TaskStatusEditScreen(),
GroupEditScreen.route: (context) => GroupEditScreen(), ExpenseCategoryScreen.route: (context) =>
SettingsScreen.route: (context) => SettingsScreenBuilder(), ExpenseCategoryScreenBuilder(),
ReportsScreen.route: (context) => ReportsScreenBuilder(), ExpenseCategoryViewScreen.route: (context) =>
CompanyDetailsScreen.route: (context) => ExpenseCategoryViewScreen(),
CompanyDetailsScreen(), ExpenseCategoryEditScreen.route: (context) =>
UserDetailsScreen.route: (context) => UserDetailsScreen(), ExpenseCategoryEditScreen(),
LocalizationScreen.route: (context) => LocalizationScreen(), RecurringInvoiceScreen.route: (context) =>
OnlinePaymentsScreen.route: (context) => RecurringInvoiceScreenBuilder(),
OnlinePaymentsScreen(), RecurringInvoiceViewScreen.route: (context) =>
CompanyGatewayScreen.route: (context) => RecurringInvoiceViewScreen(),
CompanyGatewayScreenBuilder(), RecurringInvoiceEditScreen.route: (context) =>
CompanyGatewayViewScreen.route: (context) => RecurringInvoiceEditScreen(),
CompanyGatewayViewScreen(), WebhookScreen.route: (context) => WebhookScreenBuilder(),
CompanyGatewayEditScreen.route: (context) => WebhookViewScreen.route: (context) => WebhookViewScreen(),
CompanyGatewayEditScreen(), WebhookEditScreen.route: (context) => WebhookEditScreen(),
TaxSettingsScreen.route: (context) => TaxSettingsScreen(), TokenScreen.route: (context) => TokenScreenBuilder(),
TaxRateSettingsScreen.route: (context) => TokenViewScreen.route: (context) => TokenViewScreen(),
TaxRateScreenBuilder(), TokenEditScreen.route: (context) => TokenEditScreen(),
TaxRateViewScreen.route: (context) => TaxRateViewScreen(), PaymentTermScreen.route: (context) =>
TaxRateEditScreen.route: (context) => TaxRateEditScreen(), PaymentTermScreenBuilder(),
ProductSettingsScreen.route: (context) => PaymentTermEditScreen.route: (context) =>
ProductSettingsScreen(), PaymentTermEditScreen(),
ExpenseSettingsScreen.route: (context) => PaymentTermViewScreen.route: (context) =>
ExpenseSettingsScreen(), PaymentTermViewScreen(),
TaskSettingsScreen.route: (context) => TaskSettingsScreen(), DesignScreen.route: (context) => DesignScreenBuilder(),
IntegrationSettingsScreen.route: (context) => DesignViewScreen.route: (context) => DesignViewScreen(),
IntegrationSettingsScreen(), DesignEditScreen.route: (context) => DesignEditScreen(),
ImportExportScreen.route: (context) => ImportExportScreen(), CreditScreen.route: (context) => CreditScreenBuilder(),
DeviceSettingsScreen.route: (context) => CreditViewScreen.route: (context) => CreditViewScreen(),
DeviceSettingsScreen(), CreditEditScreen.route: (context) => CreditEditScreen(),
AccountManagementScreen.route: (context) => UserScreen.route: (context) => UserScreenBuilder(),
AccountManagementScreen(), UserViewScreen.route: (context) => UserViewScreen(),
CustomFieldsScreen.route: (context) => CustomFieldsScreen(), UserEditScreen.route: (context) => UserEditScreen(),
GeneratedNumbersScreen.route: (context) => GroupSettingsScreen.route: (context) =>
GeneratedNumbersScreen(), GroupScreenBuilder(),
WorkflowSettingsScreen.route: (context) => GroupViewScreen.route: (context) => GroupViewScreen(),
WorkflowSettingsScreen(), GroupEditScreen.route: (context) => GroupEditScreen(),
InvoiceDesignScreen.route: (context) => InvoiceDesignScreen(), SettingsScreen.route: (context) => SettingsScreenBuilder(),
ClientPortalScreen.route: (context) => ClientPortalScreen(), ReportsScreen.route: (context) => ReportsScreenBuilder(),
BuyNowButtonsScreen.route: (context) => BuyNowButtonsScreen(), CompanyDetailsScreen.route: (context) =>
EmailSettingsScreen.route: (context) => EmailSettingsScreen(), CompanyDetailsScreen(),
TemplatesAndRemindersScreen.route: (context) => UserDetailsScreen.route: (context) => UserDetailsScreen(),
TemplatesAndRemindersScreen(), LocalizationScreen.route: (context) => LocalizationScreen(),
CreditCardsAndBanksScreen.route: (context) => OnlinePaymentsScreen.route: (context) =>
CreditCardsAndBanksScreen(), OnlinePaymentsScreen(),
DataVisualizationsScreen.route: (context) => CompanyGatewayScreen.route: (context) =>
DataVisualizationsScreen(), CompanyGatewayScreenBuilder(),
} CompanyGatewayViewScreen.route: (context) =>
: {}, CompanyGatewayViewScreen(),
CompanyGatewayEditScreen.route: (context) =>
CompanyGatewayEditScreen(),
TaxSettingsScreen.route: (context) => TaxSettingsScreen(),
TaxRateSettingsScreen.route: (context) =>
TaxRateScreenBuilder(),
TaxRateViewScreen.route: (context) => TaxRateViewScreen(),
TaxRateEditScreen.route: (context) => TaxRateEditScreen(),
ProductSettingsScreen.route: (context) =>
ProductSettingsScreen(),
ExpenseSettingsScreen.route: (context) =>
ExpenseSettingsScreen(),
TaskSettingsScreen.route: (context) => TaskSettingsScreen(),
IntegrationSettingsScreen.route: (context) =>
IntegrationSettingsScreen(),
ImportExportScreen.route: (context) => ImportExportScreen(),
DeviceSettingsScreen.route: (context) =>
DeviceSettingsScreen(),
AccountManagementScreen.route: (context) =>
AccountManagementScreen(),
CustomFieldsScreen.route: (context) => CustomFieldsScreen(),
GeneratedNumbersScreen.route: (context) =>
GeneratedNumbersScreen(),
WorkflowSettingsScreen.route: (context) =>
WorkflowSettingsScreen(),
InvoiceDesignScreen.route: (context) =>
InvoiceDesignScreen(),
ClientPortalScreen.route: (context) => ClientPortalScreen(),
BuyNowButtonsScreen.route: (context) =>
BuyNowButtonsScreen(),
EmailSettingsScreen.route: (context) =>
EmailSettingsScreen(),
TemplatesAndRemindersScreen.route: (context) =>
TemplatesAndRemindersScreen(),
CreditCardsAndBanksScreen.route: (context) =>
CreditCardsAndBanksScreen(),
DataVisualizationsScreen.route: (context) =>
DataVisualizationsScreen(),
}
: {},
),
); );
}), }),
); );

View File

@ -40,7 +40,9 @@ class BottomButtons extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: InkWell( child: InkWell(
onTap: action1Enabled && !entity.isDeleted onTap: action1Enabled &&
(!entity.isDeleted ||
action1 == EntityAction.viewPdf)
? () { ? () {
handleEntityAction(context, entity, action1); handleEntityAction(context, entity, action1);
} }

View File

@ -1,51 +1,18 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
/*
Completer<Null> refreshCompleter(BuildContext context) {
final Completer<Null> completer = Completer<Null>();
completer.future.then((_) {
Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow(
message: AppLocalization.of(context).refreshComplete,
)));
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
return completer;
}
*/
Completer<T> snackBarCompleter<T>(BuildContext context, String message, Completer<T> snackBarCompleter<T>(BuildContext context, String message,
{bool shouldPop = false}) { {bool shouldPop = false}) {
final Completer<T> completer = Completer<T>(); final Completer<T> completer = Completer<T>();
ScaffoldState scaffold;
try {
scaffold = Scaffold.of(context);
} catch (e) {
//
}
completer.future.then((_) { completer.future.then((_) {
if (shouldPop && Navigator.of(context).canPop()) { if (shouldPop && Navigator.of(context).canPop()) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
if (scaffold != null) { showToast(message);
scaffold.showSnackBar(SnackBar(
content: SnackBarRow(
message: message,
)));
}
}).catchError((Object error) { }).catchError((Object error) {
if (shouldPop && Navigator.of(context).canPop()) { if (shouldPop && Navigator.of(context).canPop()) {
Navigator.of(context).pop(); Navigator.of(context).pop();

View File

@ -415,6 +415,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.7" version: "0.5.7"
flutter_styled_toast:
dependency: "direct main"
description:
name: flutter_styled_toast
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0+1"
flutter_test: flutter_test:
dependency: transitive dependency: transitive
description: flutter description: flutter

View File

@ -57,6 +57,7 @@ dependencies:
#idb_shim: ^1.11.1+1 #idb_shim: ^1.11.1+1
flutter_launcher_icons: ^0.8.0 flutter_launcher_icons: ^0.8.0
overflow_view: ^0.2.1 overflow_view: ^0.2.1
flutter_styled_toast: ^1.4.0+1
dev_dependencies: dev_dependencies:
flutter_driver: flutter_driver: