Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-66-open-app-from-qr-code

 Conflicts:
	lib/di.dart
	lib/src/screens/send/send_page.dart
	lib/src/screens/send/widgets/send_card.dart
	lib/utils/payment_request.dart
	res/values/strings_de.arb
	res/values/strings_en.arb
	res/values/strings_es.arb
	res/values/strings_fr.arb
	res/values/strings_hi.arb
	res/values/strings_hr.arb
	res/values/strings_it.arb
	res/values/strings_ja.arb
	res/values/strings_ko.arb
	res/values/strings_nl.arb
	res/values/strings_pl.arb
	res/values/strings_pt.arb
	res/values/strings_ru.arb
	res/values/strings_uk.arb
	res/values/strings_zh.arb
This commit is contained in:
OmarHatem
2022-11-08 14:44:58 +02:00
575 changed files with 10219 additions and 6811 deletions
+47 -40
View File
@@ -1,5 +1,5 @@
import 'package:another_flushbar/flushbar.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:flushbar/flushbar.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
@@ -8,14 +8,14 @@ import 'package:cake_wallet/view_model/auth_state.dart';
import 'package:cake_wallet/view_model/auth_view_model.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/entities/biometric_auth.dart';
import 'package:cake_wallet/core/execution_state.dart';
typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
class AuthPage extends StatefulWidget {
AuthPage(this.authViewModel,
{this.onAuthenticationFinished, this.closable = true});
{required this.onAuthenticationFinished,
this.closable = true});
final AuthViewModel authViewModel;
final OnAuthenticationFinished onAuthenticationFinished;
@@ -30,9 +30,9 @@ class AuthPageState extends State<AuthPage> {
final _pinCodeKey = GlobalKey<PinCodeState>();
final _backArrowImageDarkTheme =
Image.asset('assets/images/close_button.png');
ReactionDisposer _reaction;
Flushbar<void> _authBar;
Flushbar<void> _progressBar;
ReactionDisposer? _reaction;
Flushbar<void>? _authBar;
Flushbar<void>? _progressBar;
@override
void initState() {
@@ -40,18 +40,14 @@ class AuthPageState extends State<AuthPage> {
reaction((_) => widget.authViewModel.state, (ExecutionState state) {
if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_authBar?.dismiss();
if (widget.onAuthenticationFinished != null) {
widget.onAuthenticationFinished(true, this);
} else {
showBar<void>(context, S.of(context).authenticated);
}
widget.onAuthenticationFinished(true, this);
});
setState(() {});
}
if (state is IsExecutingState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
// null duration to make it indefinite until its disposed
_authBar =
createBar<void>(S.of(context).authentication, duration: null)
..show(context);
@@ -59,28 +55,26 @@ class AuthPageState extends State<AuthPage> {
}
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_pinCodeKey.currentState.clear();
_authBar?.dismiss();
print('X');
print(state.error);
WidgetsBinding.instance.addPostFrameCallback((_) async {
_pinCodeKey.currentState?.clear();
dismissFlushBar(_authBar);
showBar<void>(
context, S.of(context).failed_authentication(state.error));
if (widget.onAuthenticationFinished != null) {
widget.onAuthenticationFinished(false, this);
}
widget.onAuthenticationFinished(false, this);
});
}
if (state is AuthenticationBanned) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_pinCodeKey.currentState.clear();
_authBar?.dismiss();
WidgetsBinding.instance.addPostFrameCallback((_) async {
_pinCodeKey.currentState?.clear();
dismissFlushBar(_authBar);
showBar<void>(
context, S.of(context).failed_authentication(state.error));
if (widget.onAuthenticationFinished != null) {
widget.onAuthenticationFinished(false, this);
}
widget.onAuthenticationFinished(false, this);
});
}
});
@@ -97,25 +91,37 @@ class AuthPageState extends State<AuthPage> {
@override
void dispose() {
_reaction.reaction.dispose();
_reaction?.reaction.dispose();
super.dispose();
}
void changeProcessText(String text) {
_authBar?.dismiss();
dismissFlushBar(_authBar);
_progressBar = createBar<void>(text, duration: null)
..show(_key.currentContext);
..show(_key.currentContext!);
}
void hideProgressText() {
_progressBar?.dismiss();
dismissFlushBar(_progressBar);
_progressBar = null;
}
void close() {
_authBar?.dismiss();
_progressBar?.dismiss();
Navigator.of(_key.currentContext).pop();
Future<void> close({String? route, dynamic arguments}) async {
if (_key.currentContext == null) {
throw Exception('Key context is null. Should be not happened');
}
/// not the best scenario, but WidgetsBinding is not behaving correctly on Android
await Future<void>.delayed(Duration(milliseconds: 50));
await _authBar?.dismiss();
await Future<void>.delayed(Duration(milliseconds: 50));
await _progressBar?.dismiss();
await Future<void>.delayed(Duration(milliseconds: 50));
if (route != null) {
Navigator.of(_key.currentContext!).pushReplacementNamed(route, arguments: arguments);
} else {
Navigator.of(_key.currentContext!).pop();
}
}
@override
@@ -129,14 +135,9 @@ class AuthPageState extends State<AuthPage> {
child: SizedBox(
height: 37,
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
onPressed: () => Navigator.of(context).pop(),
child: _backArrowImageDarkTheme),
child: InkWell(
onTap: () => Navigator.of(context).pop(),
child: _backArrowImageDarkTheme,
),
))
: Container(),
@@ -146,4 +147,10 @@ class AuthPageState extends State<AuthPage> {
body: PinCode((pin, _) => widget.authViewModel.auth(password: pin),
(_) => null, widget.authViewModel.pinLength, false, _pinCodeKey));
}
void dismissFlushBar(Flushbar<dynamic>? bar) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await bar?.dismiss();
});
}
}
+20 -8
View File
@@ -1,10 +1,10 @@
import 'dart:io';
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:share_plus/share_plus.dart';
import 'package:cross_file/cross_file.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
@@ -80,7 +80,7 @@ class BackupPage extends BasePage {
isLoading: backupViewModelBase.state is IsExecutingState,
onPressed: () => onExportBackup(context),
text: S.of(context).export_backup,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white)),
bottom: 24,
left: 24,
@@ -103,11 +103,14 @@ class BackupPage extends BasePage {
Navigator.of(dialogContext).pop();
final backup = await backupViewModelBase.exportBackup();
if (backup == null) {
return;
}
if (Platform.isAndroid) {
onExportAndroid(context, backup);
} else {
await Share.file(S.of(context).backup_file, backup.name,
backup.content, 'application/*');
await share(backup);
}
},
actionLeftButton: () => Navigator.of(dialogContext).pop());
@@ -135,11 +138,20 @@ class BackupPage extends BasePage {
backup.name, backup.content);
Navigator.of(dialogContext).pop();
},
actionLeftButton: () {
actionLeftButton: () async {
Navigator.of(dialogContext).pop();
Share.file(S.of(context).backup_file, backup.name,
backup.content, 'application/*');
await share(backup);
});
});
}
Future<void> share(BackupExportFile backup) async {
const mimeType = 'application/*';
final path = await backupViewModelBase.saveBackupFileLocally(backup);
await Share.shareXFiles(<XFile>[XFile(
path,
name: backup.name,
mimeType: mimeType)]);
await backupViewModelBase.removeBackupFileLocally(backup);
}
}
@@ -39,13 +39,13 @@ class EditBackupPasswordPage extends BasePage {
controller: textEditingController,
style: TextStyle(
fontSize: 26,
color: Theme.of(context).primaryTextTheme.title.color)))),
color: Theme.of(context).primaryTextTheme!.headline6!.color!)))),
Positioned(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () => onSave(context),
text: S.of(context).save,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: !editBackupPasswordViewModel.canSave)),
bottom: 24,
+24 -20
View File
@@ -18,7 +18,7 @@ abstract class BasePage extends StatelessWidget {
final Image closeButtonImageDarkTheme =
Image.asset('assets/images/close_button_dark_theme.png');
String get title => null;
String? get title => null;
bool get isModalBackButton => false;
@@ -26,31 +26,31 @@ abstract class BasePage extends StatelessWidget {
Color get backgroundDarkColor => PaletteDark.backgroundColor;
Color get titleColor => null;
Color? get titleColor => null;
bool get resizeToAvoidBottomInset => true;
bool get extendBodyBehindAppBar => false;
Widget get endDrawer => null;
Widget? get endDrawer => null;
AppBarStyle get appBarStyle => AppBarStyle.regular;
Widget Function(BuildContext, Widget) get rootWrapper => null;
Widget Function(BuildContext, Widget)? get rootWrapper => null;
ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme;
void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer();
void onOpenEndDrawer() => _scaffoldKey.currentState!.openEndDrawer();
void onClose(BuildContext context) => Navigator.of(context).pop();
Widget leading(BuildContext context) {
if (ModalRoute.of(context).isFirst) {
Widget? leading(BuildContext context) {
if (ModalRoute.of(context)?.isFirst ?? true) {
return null;
}
final _backButton = Icon(Icons.arrow_back_ios,
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color,
color: titleColor ?? Theme.of(context).primaryTextTheme!.headline6!.color!,
size: 16,);
final _closeButton = currentTheme.type == ThemeType.dark
? closeButtonImageDarkTheme : closeButtonImage;
@@ -60,33 +60,34 @@ abstract class BasePage extends StatelessWidget {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onClose(context),
child: isModalBackButton ? _closeButton : _backButton),
),
);
}
Widget middle(BuildContext context) {
Widget? middle(BuildContext context) {
return title == null
? null
: Text(
title,
title!,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor ??
Theme.of(context).primaryTextTheme.title.color),
Theme.of(context).primaryTextTheme!.headline6!.color!),
);
}
Widget trailing(BuildContext context) => null;
Widget? trailing(BuildContext context) => null;
Widget floatingActionButton(BuildContext context) => null;
Widget? floatingActionButton(BuildContext context) => null;
ObstructingPreferredSizeWidget appBar(BuildContext context) {
final appBarColor = currentTheme.type == ThemeType.dark
@@ -94,16 +95,18 @@ abstract class BasePage extends StatelessWidget {
switch (appBarStyle) {
case AppBarStyle.regular:
// FIX-ME: NavBar no context
return NavBar(
context: context,
// context: context,
leading: leading(context),
middle: middle(context),
trailing: trailing(context),
backgroundColor: appBarColor);
case AppBarStyle.withShadow:
// FIX-ME: NavBar no context
return NavBar.withShadow(
context: context,
// context: context,
leading: leading(context),
middle: middle(context),
trailing: trailing(context),
@@ -119,8 +122,9 @@ abstract class BasePage extends StatelessWidget {
);
default:
// FIX-ME: NavBar no context
return NavBar(
context: context,
// context: context,
leading: leading(context),
middle: middle(context),
trailing: trailing(context),
+21 -14
View File
@@ -12,8 +12,8 @@ import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class BuyWebViewPage extends BasePage {
BuyWebViewPage({@required this.buyViewModel,
@required this.ordersStore, @required this.url});
BuyWebViewPage({required this.buyViewModel,
required this.ordersStore, required this.url});
final OrdersStore ordersStore;
final String url;
@@ -34,10 +34,10 @@ class BuyWebViewPage extends BasePage {
}
class BuyWebViewPageBody extends StatefulWidget {
BuyWebViewPageBody(this.buyViewModel, {this.ordersStore, this.url});
BuyWebViewPageBody(this.buyViewModel, {required this.ordersStore, this.url});
final OrdersStore ordersStore;
final String url;
final String? url;
final BuyViewModel buyViewModel;
@override
@@ -45,12 +45,16 @@ class BuyWebViewPageBody extends StatefulWidget {
}
class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
BuyWebViewPageBodyState()
: _webViewkey = GlobalKey(),
_isSaving = false,
orderId = '';
String orderId;
WebViewController _webViewController;
WebViewController? _webViewController;
GlobalKey _webViewkey;
Timer _timer;
Timer? _timer;
bool _isSaving;
BuyProvider _provider;
@override
void initState() {
@@ -58,15 +62,14 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
_webViewkey = GlobalKey();
_isSaving = false;
widget.ordersStore.orderId = '';
_provider = widget.buyViewModel.selectedProvider;
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
if (_provider is WyreBuyProvider) {
if (widget.buyViewModel.selectedProvider is WyreBuyProvider) {
_saveOrder(keyword: 'completed', splitSymbol: '/');
}
if (_provider is MoonPayBuyProvider) {
if (widget.buyViewModel.selectedProvider is MoonPayBuyProvider) {
_saveOrder(keyword: 'transactionId', splitSymbol: '=');
}
}
@@ -81,7 +84,7 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
setState(() => _webViewController = controller));
}
void _saveOrder({String keyword, String splitSymbol}) {
void _saveOrder({required String keyword, required String splitSymbol}) {
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 1), (timer) async {
@@ -90,10 +93,14 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
return;
}
final url = await _webViewController.currentUrl();
final url = await _webViewController!.currentUrl();
if (url.contains(keyword)) {
final urlParts = url.split(splitSymbol);
if (url == null) {
throw Exception('_saveOrder: Url is null');
}
if (url!.contains(keyword)) {
final urlParts = url!.split(splitSymbol);
orderId = urlParts.last;
widget.ordersStore.orderId = orderId;
+86
View File
@@ -0,0 +1,86 @@
import 'dart:io';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
class OnRamperPage extends BasePage {
OnRamperPage({
required this.settingsStore,
required this.wallet});
final SettingsStore settingsStore;
final WalletBase wallet;
@override
String get title => S.current.buy;
@override
Widget body(BuildContext context) {
final darkMode = Theme.of(context).brightness == Brightness.dark;
return OnRamperPageBody(
settingsStore: settingsStore,
wallet: wallet,
darkMode: darkMode,
backgroundColor: darkMode
? backgroundDarkColor
: backgroundLightColor,
supportSell: false,
supportSwap: false);
}
}
class OnRamperPageBody extends StatefulWidget {
OnRamperPageBody({
required this.settingsStore,
required this.wallet,
required this.darkMode,
required this.supportSell,
required this.supportSwap,
required this.backgroundColor});
static const baseUrl = 'widget.onramper.com';
final SettingsStore settingsStore;
final WalletBase wallet;
final Color backgroundColor;
final bool darkMode;
final bool supportSell;
final bool supportSwap;
Uri get uri
=> Uri.https(
baseUrl,
'',
<String, dynamic>{
'apiKey': secrets.onramperApiKey,
'defaultCrypto': wallet.currency.title,
'defaultFiat': settingsStore.fiatCurrency.title,
'wallets': '${wallet.currency.title}:${wallet.walletAddresses.address}',
'darkMode': darkMode.toString(),
'supportSell': supportSell.toString(),
'supportSwap': supportSwap.toString()});
@override
OnRamperPageBodyState createState() => OnRamperPageBodyState();
}
class OnRamperPageBodyState extends State<OnRamperPageBody> {
OnRamperPageBodyState();
@override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
@override
Widget build(BuildContext context) {
return WebView(
initialUrl: widget.uri.toString(),
backgroundColor: widget.backgroundColor,
javascriptMode: JavascriptMode.unrestricted);
}
}
+20 -23
View File
@@ -1,4 +1,3 @@
import 'dart:ui';
import 'package:cake_wallet/buy/buy_amount.dart';
import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
@@ -10,7 +9,6 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -26,7 +24,7 @@ import 'package:mobx/mobx.dart';
import 'package:url_launcher/url_launcher.dart';
class PreOrderPage extends BasePage {
PreOrderPage({@required this.buyViewModel})
PreOrderPage({required this.buyViewModel})
: _amountFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
@@ -82,8 +80,8 @@ class PreOrderPage extends BasePage {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2
.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme.bodyText1!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -104,11 +102,10 @@ class PreOrderPage extends BasePage {
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subtitle1!.color!,
Theme.of(context)
.primaryTextTheme
.subhead
.decorationColor,
.primaryTextTheme.subtitle1!
.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Padding(
@@ -163,11 +160,11 @@ class PreOrderPage extends BasePage {
),
),
hintText: '0.00',
borderColor: Theme.of(context).primaryTextTheme.body2.decorationColor,
borderColor: Theme.of(context).primaryTextTheme.bodyText1!.decorationColor!,
borderWidth: 0.5,
textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.decorationColor,
color: Theme.of(context).primaryTextTheme.headline5!.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 36,
),
@@ -182,7 +179,7 @@ class PreOrderPage extends BasePage {
S.of(context).buy_with + ':',
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
fontSize: 18,
fontWeight: FontWeight.bold
),
@@ -199,15 +196,16 @@ class PreOrderPage extends BasePage {
double achAmount;
int minAmount;
if (snapshot.hasData) {
sourceAmount = snapshot.data.sourceAmount;
destAmount = snapshot.data.destAmount;
minAmount = snapshot.data.minAmount;
achAmount = snapshot.data.achSourceAmount;
if (snapshot.hasData && snapshot.data != null) {
sourceAmount = snapshot.data!.sourceAmount;
destAmount = snapshot.data!.destAmount;
minAmount = snapshot.data!.minAmount;
achAmount = snapshot.data!.achSourceAmount ?? 0;
} else {
sourceAmount = 0.0;
destAmount = 0.0;
minAmount = 0;
achAmount = 0;
}
return Padding(
@@ -247,9 +245,8 @@ class PreOrderPage extends BasePage {
text: buyViewModel.selectedProvider == null
? S.of(context).buy
: S.of(context).buy_with +
' ${buyViewModel.selectedProvider
.description.title}',
color: Theme.of(context).accentTextTheme.body2.color,
' ${buyViewModel.selectedProvider!.description.title}',
color: Theme.of(context).accentTextTheme.bodyText1!.color!,
textColor: Colors.white,
isLoading: buyViewModel.isRunning,
isDisabled: (buyViewModel.selectedProvider == null) ||
@@ -261,8 +258,8 @@ class PreOrderPage extends BasePage {
);
}
void onSelectBuyProvider({BuildContext context, BuyProvider provider,
double sourceAmount, int minAmount}) {
void onSelectBuyProvider({required BuildContext context, required BuyProvider provider,
required double sourceAmount, required int minAmount}) {
if ((provider is MoonPayBuyProvider)&&
(buyViewModel.buyAmountViewModel.doubleAmount < minAmount)) {
@@ -285,7 +282,7 @@ class PreOrderPage extends BasePage {
: buyViewModel.isDisabled = true;
}
Future<void> onPresentProvider({BuildContext context}) async {
Future<void> onPresentProvider({required BuildContext context}) async {
if (buyViewModel.isRunning) {
return;
}
+12 -12
View File
@@ -8,24 +8,24 @@ import 'package:flutter/material.dart';
class BuyListItem extends StatelessWidget {
BuyListItem({
@required this.selectedProvider,
@required this.provider,
@required this.sourceAmount,
@required this.sourceCurrency,
@required this.destAmount,
@required this.destCurrency,
@required this.achSourceAmount,
@required this.onTap
required this.selectedProvider,
required this.provider,
required this.sourceAmount,
required this.sourceCurrency,
required this.destAmount,
required this.destCurrency,
required this.achSourceAmount,
this.onTap
});
final BuyProvider selectedProvider;
final BuyProvider? selectedProvider;
final BuyProvider provider;
final double sourceAmount;
final FiatCurrency sourceCurrency;
final double destAmount;
final CryptoCurrency destCurrency;
final double achSourceAmount;
final void Function() onTap;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
@@ -33,7 +33,7 @@ class BuyListItem extends StatelessWidget {
final iconColor = isSelected ? Colors.white : Colors.black;
final providerIcon = getBuyProviderIcon(provider.description,
iconColor: iconColor);
iconColor: iconColor)!;
final backgroundColor = isSelected
? Palette.greyBlueCraiola
@@ -48,7 +48,7 @@ class BuyListItem extends StatelessWidget {
: Palette.darkBlueCraiola;
return GestureDetector(
onTap: () => onTap?.call(),
onTap: onTap,
child: Container(
padding: EdgeInsets.only(
left: 20,
+50 -40
View File
@@ -1,4 +1,5 @@
import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
@@ -24,7 +25,7 @@ class ContactListPage extends BasePage {
String get title => S.current.address_book;
@override
Widget trailing(BuildContext context) {
Widget? trailing(BuildContext context) {
if (!isEditable) {
return null;
}
@@ -34,18 +35,19 @@ class ContactListPage extends BasePage {
height: 32.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).accentTextTheme.caption.color),
color: Theme.of(context).accentTextTheme.caption!.color!),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Icon(Icons.add,
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme.headline6!.color!,
size: 22.0),
ButtonTheme(
minWidth: 32.0,
height: 32.0,
child: FlatButton(
shape: CircleBorder(),
child: TextButton(
// FIX-ME: Style
//shape: CircleBorder(),
onPressed: () async {
await Navigator.of(context)
.pushNamed(Routes.addressBookAddContact);
@@ -65,9 +67,9 @@ class ContactListPage extends BasePage {
return CollapsibleSectionList(
context: context,
sectionCount: 2,
themeColor: Theme.of(context).primaryTextTheme.title.color,
themeColor: Theme.of(context).primaryTextTheme.headline6!.color!,
dividerThemeColor:
Theme.of(context).primaryTextTheme.caption.decorationColor,
Theme.of(context).primaryTextTheme.caption!.decorationColor!,
sectionTitleBuilder: (_, int sectionIndex) {
var title = 'Contacts';
@@ -90,36 +92,13 @@ class ContactListPage extends BasePage {
final contact = contactListViewModel.contacts[index];
final content = generateRaw(context, contact);
return !isEditable
? content
: Slidable(
key: Key('${contact.key}'),
actionPane: SlidableDrawerActionPane(),
endActionPane: _actionPane(context, contact),
child: content,
secondaryActions: <Widget>[
IconSlideAction(
caption: S.of(context).edit,
color: Colors.blue,
icon: Icons.edit,
onTap: () async => await Navigator.of(context)
.pushNamed(Routes.addressBookAddContact,
arguments: contact),
),
IconSlideAction(
caption: S.of(context).delete,
color: Colors.red,
icon: CupertinoIcons.delete,
onTap: () async {
final isDelete =
await showAlertDialog(context) ?? false;
if (isDelete) {
await contactListViewModel.delete(contact);
}
},
),
]);
);
},
);
},
@@ -139,7 +118,7 @@ class ContactListPage extends BasePage {
final isCopied = await showNameAndAddressDialog(
context, contact.name, contact.address);
if (isCopied != null && isCopied) {
if (isCopied) {
await Clipboard.setData(ClipboardData(text: contact.address));
await showBar<void>(context, S.of(context).copied_to_clipboard);
}
@@ -163,7 +142,7 @@ class ContactListPage extends BasePage {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme.headline6!.color!),
),
)
)
@@ -173,8 +152,9 @@ class ContactListPage extends BasePage {
);
}
Image _getCurrencyImage(CryptoCurrency currency) {
Image image;
Image? _getCurrencyImage(CryptoCurrency currency) {
Image? image;
switch (currency) {
case CryptoCurrency.xmr:
image =
@@ -236,7 +216,7 @@ class ContactListPage extends BasePage {
}
Future<bool> showAlertDialog(BuildContext context) async {
return await showPopUp(
return await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
@@ -246,12 +226,12 @@ class ContactListPage extends BasePage {
leftButtonText: S.of(context).cancel,
actionRightButton: () => Navigator.of(context).pop(true),
actionLeftButton: () => Navigator.of(context).pop(false));
});
}) ?? false;
}
Future<bool> showNameAndAddressDialog(
BuildContext context, String name, String address) async {
return await showPopUp(
return await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
@@ -261,6 +241,36 @@ class ContactListPage extends BasePage {
leftButtonText: S.of(context).cancel,
actionRightButton: () => Navigator.of(context).pop(true),
actionLeftButton: () => Navigator.of(context).pop(false));
});
}) ?? false;
}
ActionPane _actionPane(BuildContext context, ContactRecord contact) => ActionPane(
motion: const ScrollMotion(),
extentRatio: 0.4,
children: [
SlidableAction(
onPressed: (_) async => await Navigator.of(context)
.pushNamed(Routes.addressBookAddContact,
arguments: contact),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
icon: Icons.edit,
label: S.of(context).edit,
),
SlidableAction(
onPressed: (_) async {
final isDelete =
await showAlertDialog(context);
if (isDelete) {
await contactListViewModel.delete(contact);
}
},
backgroundColor: Colors.red,
foregroundColor: Colors.white,
icon: CupertinoIcons.delete,
label: S.of(context).delete,
),
],
);
}
+8 -6
View File
@@ -48,7 +48,7 @@ class ContactPage extends BasePage {
@override
Widget body(BuildContext context) {
final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context).primaryTextTheme.overline.color, height: 8);
color: Theme.of(context).primaryTextTheme!.overline!.color!, height: 8);
reaction((_) => contactViewModel.state, (ExecutionState state) {
if (state is FailureState) {
@@ -98,9 +98,9 @@ class ContactPage extends BasePage {
AddressTextFieldOption.paste,
AddressTextFieldOption.qrCode,
],
buttonColor: Theme.of(context).accentTextTheme.display2.color,
buttonColor: Theme.of(context).accentTextTheme!.headline3!.color!,
iconColor: PaletteDark.gray,
borderColor: Theme.of(context).primaryTextTheme.title.backgroundColor,
borderColor: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
validator: TextValidator()
// AddressValidator(
// type: contactViewModel.currency),
@@ -129,14 +129,14 @@ class ContactPage extends BasePage {
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await contactViewModel.save();
},
text: S.of(context).save,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: !contactViewModel.isReady)))
],
@@ -147,7 +147,9 @@ class ContactPage extends BasePage {
showPopUp<void>(
builder: (_) => CurrencyPicker(
selectedAtIndex:
contactViewModel.currencies.indexOf(contactViewModel.currency),
contactViewModel.currency != null
? contactViewModel.currencies.indexOf(contactViewModel.currency!)
: 0,
items: contactViewModel.currencies,
title: S.of(context).please_select,
hintText: S.of(context).search_currency,
+42 -57
View File
@@ -26,9 +26,9 @@ import 'package:url_launcher/url_launcher.dart';
class DashboardPage extends BasePage {
DashboardPage({
@required this.balancePage,
@required this.walletViewModel,
@required this.addressListViewModel,
required this.balancePage,
required this.walletViewModel,
required this.addressListViewModel,
});
final BalancePage balancePage;
@@ -66,15 +66,16 @@ class DashboardPage extends BasePage {
@override
Widget trailing(BuildContext context) {
final menuButton = Image.asset('assets/images/menu.png',
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
return Container(
alignment: Alignment.centerRight,
width: 40,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onOpenEndDrawer(),
child: menuButton));
}
@@ -85,18 +86,18 @@ class DashboardPage extends BasePage {
var pages = <Widget>[];
bool _isEffectsInstalled = false;
StreamSubscription<bool> _onInactiveSub;
StreamSubscription<bool>? _onInactiveSub;
@override
Widget body(BuildContext context) {
final sendImage = Image.asset('assets/images/upload.png',
height: 24,
width: 24,
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
final receiveImage = Image.asset('assets/images/received.png',
height: 24,
width: 24,
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
_setEffects(context);
return SafeArea(
@@ -121,9 +122,9 @@ class DashboardPage extends BasePage {
dotHeight: 6.0,
dotColor: Theme.of(context).indicatorColor,
activeDotColor: Theme.of(context)
.accentTextTheme
.display1
.backgroundColor),
.accentTextTheme!
.headline4!
.backgroundColor!),
)),
Observer(builder: (_) {
return ClipRect(
@@ -133,7 +134,7 @@ class DashboardPage extends BasePage {
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.0),
border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
color:Theme.of(context).textTheme.title.backgroundColor),
color:Theme.of(context).textTheme!.headline6!.backgroundColor!),
child: Container(
padding: EdgeInsets.only(left: 32, right: 32),
child: Row(
@@ -146,17 +147,17 @@ class DashboardPage extends BasePage {
width: 24,
color: !walletViewModel.isEnabledBuyAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
: Theme.of(context).accentTextTheme.display3.backgroundColor),
.accentTextTheme!
.headline3!
.backgroundColor!
: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
title: S.of(context).buy,
onClick: () async => await _onClickBuyButton(context),
textColor: !walletViewModel.isEnabledBuyAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
.accentTextTheme!
.headline3!
.backgroundColor!
: null),
ActionButton(
image: receiveImage,
@@ -169,17 +170,17 @@ class DashboardPage extends BasePage {
width: 24,
color: !walletViewModel.isEnabledExchangeAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
: Theme.of(context).accentTextTheme.display3.backgroundColor),
.accentTextTheme!
.headline3!
.backgroundColor!
: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
title: S.of(context).exchange,
onClick: () async => _onClickExchangeButton(context),
textColor: !walletViewModel.isEnabledExchangeAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
.accentTextTheme!
.headline3!
.backgroundColor!
: null),
ActionButton(
image: sendImage,
@@ -192,17 +193,17 @@ class DashboardPage extends BasePage {
width: 24,
color: !walletViewModel.isEnabledSellAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
: Theme.of(context).accentTextTheme.display3.backgroundColor),
.accentTextTheme!
.headline3!
.backgroundColor!
: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
title: S.of(context).sell,
onClick: () async => await _onClickSellButton(context),
textColor: !walletViewModel.isEnabledSellAction
? Theme.of(context)
.accentTextTheme
.display2
.backgroundColor
.accentTextTheme!
.headline3!
.backgroundColor!
: null),
],
),),
@@ -243,13 +244,13 @@ class DashboardPage extends BasePage {
var needToPresentYat = false;
var isInactive = false;
_onInactiveSub = rootKey.currentState.isInactive.listen((inactive) {
_onInactiveSub = rootKey.currentState!.isInactive.listen((inactive) {
isInactive = inactive;
if (needToPresentYat) {
Future<void>.delayed(Duration(milliseconds: 500)).then((_) {
showPopUp<void>(
context: navigatorKey.currentContext,
context: navigatorKey.currentContext!,
builder: (_) => YatEmojiId(walletViewModel.yatStore.emoji));
needToPresentYat = false;
});
@@ -270,10 +271,10 @@ class DashboardPage extends BasePage {
switch (walletType) {
case WalletType.bitcoin:
Navigator.of(context).pushNamed(Routes.preOrder);
Navigator.of(context).pushNamed(Routes.onramperPage);
break;
case WalletType.litecoin:
Navigator.of(context).pushNamed(Routes.preOrder);
Navigator.of(context).pushNamed(Routes.onramperPage);
break;
default:
await showPopUp<void>(
@@ -314,22 +315,6 @@ class DashboardPage extends BasePage {
}
Future<void> _onClickExchangeButton(BuildContext context) async {
final walletType = walletViewModel.type;
switch (walletType) {
case WalletType.haven:
await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: 'Exchange',
alertContent: 'Exchange for this asset is not supported yet.',
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
break;
default:
await Navigator.of(context).pushNamed(Routes.exchange);
}
await Navigator.of(context).pushNamed(Routes.exchange);
}
}
+16 -2
View File
@@ -42,8 +42,7 @@ class WalletMenu {
Navigator.of(context).pushNamed(Routes.auth,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
if (isAuthenticatedSuccessfully) {
auth.close();
Navigator.of(auth.context).pushNamed(Routes.showKeys);
auth.close(route: Routes.showKeys);
}
});
}),
@@ -52,6 +51,21 @@ class WalletMenu {
image: Image.asset('assets/images/open_book_menu.png',
height: 16, width: 16),
handler: () => Navigator.of(context).pushNamed(Routes.addressBook)),
WalletMenuItem(
title: S.current.backup,
image: Image.asset('assets/images/restore_wallet.png',
height: 16,
width: 16,
color: Palette.darkBlue),
handler: () {
Navigator.of(context).pushNamed(
Routes.auth,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
if (isAuthenticatedSuccessfully) {
auth.close(route:Routes.backup);
}
});
}),
WalletMenuItem(
title: S.current.settings_title,
image: Image.asset('assets/images/settings_menu.png',
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
class WalletMenuItem {
WalletMenuItem({
@required this.title,
@required this.image,
@required this.handler});
required this.title,
required this.image,
required this.handler});
final String title;
final Image image;
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
class ActionButton extends StatelessWidget {
ActionButton(
{@required this.image,
@required this.title,
{required this.image,
required this.title,
this.route,
this.onClick,
this.alignment = Alignment.center,
@@ -11,22 +11,17 @@ class ActionButton extends StatelessWidget {
final Image image;
final String title;
final String route;
final String? route;
final Alignment alignment;
final void Function() onClick;
final Color textColor;
final VoidCallback? onClick;
final Color? textColor;
@override
Widget build(BuildContext context) {
var _textColor = textColor ?? Theme.of(context)
.accentTextTheme
.display3
.backgroundColor;
return GestureDetector(
onTap: () {
if (route?.isNotEmpty ?? false) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
Navigator.of(context, rootNavigator: true).pushNamed(route!);
} else {
onClick?.call();
}
@@ -50,7 +45,7 @@ class ActionButton extends StatelessWidget {
title,
style: TextStyle(
fontSize: 10,
color: _textColor),
color: textColor ?? Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
)
],
),
@@ -15,11 +15,13 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart';
import 'package:share_plus/share_plus.dart';
class AddressPage extends BasePage {
AddressPage({@required this.addressListViewModel,
this.walletViewModel})
: _cryptoAmountFocus = FocusNode();
AddressPage({
required this.addressListViewModel,
required this.walletViewModel})
: _cryptoAmountFocus = FocusNode();
final WalletAddressListViewModel addressListViewModel;
final DashboardViewModel walletViewModel;
@@ -42,7 +44,7 @@ class AddressPage extends BasePage {
@override
Widget leading(BuildContext context) {
final _backButton = Icon(Icons.arrow_back_ios,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
size: 16,);
return SizedBox(
@@ -50,10 +52,11 @@ class AddressPage extends BasePage {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onClose(context),
child: _backButton),
),
@@ -68,7 +71,7 @@ class AddressPage extends BasePage {
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
);
}
@@ -83,6 +86,26 @@ class AddressPage extends BasePage {
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
child: scaffold);
@override
Widget? trailing(BuildContext context) {
final shareImage =
Image.asset('assets/images/share.png',
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
return !addressListViewModel.hasAddressList ? Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
iconSize: 25,
onPressed: () => Share.share(addressListViewModel.address.address),
icon: shareImage,
),
) : null;
}
@override
Widget body(BuildContext context) {
autorun((_) async {
@@ -115,7 +138,7 @@ class AddressPage extends BasePage {
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme.body2.backgroundColor,
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -148,7 +171,7 @@ class AddressPage extends BasePage {
BorderRadius.all(Radius.circular(25)),
border: Border.all(
color:
Theme.of(context).textTheme.subhead.color,
Theme.of(context).textTheme!.subtitle1!.color!,
width: 1),
color: Theme.of(context).buttonColor),
child: Row(
@@ -166,17 +189,17 @@ class AddressPage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor),
.accentTextTheme!
.headline2!
.backgroundColor!),
)),
Icon(
Icons.arrow_forward_ios,
size: 14,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
)
],
),
@@ -188,9 +211,9 @@ class AddressPage extends BasePage {
style: TextStyle(
fontSize: 15,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor));
.accentTextTheme!
.headline3!
.backgroundColor!));
})
],
),
@@ -7,9 +7,12 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/src/widgets/introducing_card.dart';
import 'package:cake_wallet/generated/i18n.dart';
class BalancePage extends StatelessWidget{
BalancePage({@required this.dashboardViewModel, @required this.settingsStore});
BalancePage({required this.dashboardViewModel, required this.settingsStore});
final DashboardViewModel dashboardViewModel;
final SettingsStore settingsStore;
@@ -37,13 +40,26 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center);
})),
Observer(builder: (_) {
if (dashboardViewModel.balanceViewModel.isShowCard){
return IntroducingCard(
title: S.of(context).introducing_cake_pay,
subTitle: S.of(context).cake_pay_learn_more,
borderColor: settingsStore.currentTheme.type == ThemeType.bright
? Color.fromRGBO(255, 255, 255, 0.2)
: Colors.transparent,
closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard
);
}
return Container ();
}),
Observer(builder: (_) {
return ListView.separated(
physics: NeverScrollableScrollPhysics(),
@@ -66,19 +82,19 @@ class BalancePage extends StatelessWidget{
}
Widget buildBalanceRow(BuildContext context,
{String availableBalanceLabel,
String availableBalance,
String availableFiatBalance,
String additionalBalanceLabel,
String additionalBalance,
String additionalFiatBalance,
String currency}) {
{required String availableBalanceLabel,
required String availableBalance,
required String availableFiatBalance,
required String additionalBalanceLabel,
required String additionalBalance,
required String additionalFiatBalance,
required String currency}) {
return Container(
margin: const EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
color:Theme.of(context).textTheme.title.backgroundColor
color:Theme.of(context).textTheme!.headline6!.backgroundColor!
),
child: Container(
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
@@ -93,9 +109,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
.accentTextTheme!
.headline3!
.backgroundColor!,
height: 1)),
SizedBox(height: 5),
Row(
@@ -108,9 +124,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
@@ -120,9 +136,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1)),
]),
SizedBox(height: 4,),
@@ -133,9 +149,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1)),
SizedBox(height: 26),
Text('${additionalBalanceLabel}',
@@ -145,9 +161,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
.accentTextTheme!
.headline3!
.backgroundColor!,
height: 1)),
SizedBox(height: 8),
AutoSizeText(
@@ -157,9 +173,9 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.center),
@@ -171,12 +187,13 @@ class BalancePage extends StatelessWidget{
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
.accentTextTheme!
.headline2!
.backgroundColor!,
height: 1),
)
])),
);
}
}
@@ -4,7 +4,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/utils/date_formatter.dart';
class DateSectionRaw extends StatelessWidget {
DateSectionRaw({this.date});
DateSectionRaw({required this.date});
final DateTime date;
@@ -36,6 +36,6 @@ class DateSectionRaw extends StatelessWidget {
child: Text(title,
style: TextStyle(
fontSize: 12,
color: Theme.of(context).textTheme.overline.backgroundColor)));
color: Theme.of(context).textTheme!.overline!.backgroundColor!)));
}
}
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
class FilterTile extends StatelessWidget {
FilterTile({@required this.child});
FilterTile({required this.child});
final Widget child;
@@ -8,10 +8,10 @@ import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
import 'package:cake_wallet/src/widgets/checkbox_widget.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
class FilterWidget extends StatelessWidget {
FilterWidget({@required this.dashboardViewModel});
FilterWidget({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
final backVector = Image.asset('assets/images/back_vector.png',
@@ -46,14 +46,14 @@ class FilterWidget extends StatelessWidget {
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
color: Theme.of(context).textTheme.body2.decorationColor,
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
child: ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: dashboardViewModel.filterItems.length,
separatorBuilder: (context, _) => Container(
height: 1,
color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
color: Theme.of(context).accentTextTheme!.subtitle1!.backgroundColor!,
),
itemBuilder: (_, index1) {
final title = dashboardViewModel.filterItems.keys.elementAt(index1);
@@ -71,7 +71,7 @@ class FilterWidget extends StatelessWidget {
child: Text(
title,
style: TextStyle(
color: Theme.of(context).accentTextTheme.subhead.color,
color: Theme.of(context).accentTextTheme!.subtitle1!.color!,
fontSize: 16,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
@@ -86,10 +86,10 @@ class FilterWidget extends StatelessWidget {
separatorBuilder: (context, _) => Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: Theme.of(context).textTheme.body2.decorationColor,
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
child: Container(
height: 1,
color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
color: Theme.of(context).accentTextTheme!.subtitle1!.backgroundColor!,
),
),
itemBuilder: (_, index2) {
@@ -103,29 +103,29 @@ class FilterWidget extends StatelessWidget {
)
: GestureDetector(
onTap: () async {
final List<DateTime> picked =
await date_rage_picker.showDatePicker(
context: context,
initialFirstDate: DateTime.now()
.subtract(Duration(days: 1)),
initialLastDate: (DateTime.now()),
firstDate: DateTime(2015),
lastDate: DateTime.now()
.add(Duration(days: 1)));
//final List<DateTime> picked =
//await date_rage_picker.showDatePicker(
// context: context,
// initialFirstDate: DateTime.now()
// .subtract(Duration(days: 1)),
// initialLastDate: (DateTime.now()),
// firstDate: DateTime(2015),
// lastDate: DateTime.now()
// .add(Duration(days: 1)));
if (picked != null && picked.length == 2) {
dashboardViewModel.transactionFilterStore
.changeStartDate(picked.first);
dashboardViewModel.transactionFilterStore
.changeEndDate(picked.last);
}
//if (picked != null && picked.length == 2) {
// dashboardViewModel.transactionFilterStore
// .changeStartDate(picked.first);
// dashboardViewModel.transactionFilterStore
// .changeEndDate(picked.last);
//}
},
child: Padding(
padding: EdgeInsets.only(left: 32),
child: Text(
item.caption,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
@@ -5,14 +5,14 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
class HeaderRow extends StatelessWidget {
HeaderRow({this.dashboardViewModel});
HeaderRow({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
@override
Widget build(BuildContext context) {
final filterIcon = Image.asset('assets/images/filter_icon.png',
color: Theme.of(context).textTheme.caption.decorationColor);
color: Theme.of(context).textTheme!.caption!.decorationColor!);
return Container(
height: 52,
@@ -27,7 +27,7 @@ class HeaderRow extends StatelessWidget {
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.display3.backgroundColor
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
),
),
GestureDetector(
@@ -43,7 +43,7 @@ class HeaderRow extends StatelessWidget {
width: 36,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).textTheme.overline.color
color: Theme.of(context).textTheme!.overline!.color!
),
child: filterIcon,
),
@@ -9,7 +9,7 @@ import 'package:cake_wallet/generated/i18n.dart';
class MarketPlacePage extends StatelessWidget {
MarketPlacePage({@required this.dashboardViewModel});
MarketPlacePage({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
final _scrollController = ScrollController();
@@ -35,7 +35,7 @@ class MarketPlacePage extends StatelessWidget {
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
),
Expanded(
@@ -19,10 +19,19 @@ class MenuWidget extends StatefulWidget {
}
class MenuWidgetState extends State<MenuWidget> {
Image moneroIcon;
Image bitcoinIcon;
Image litecoinIcon;
Image havenIcon;
MenuWidgetState()
: this.menuWidth = 0,
this.screenWidth = 0,
this.screenHeight = 0,
this.headerHeight = 120,
this.tileHeight = 60,
this.fromTopEdge = 50,
this.fromBottomEdge = 25,
this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
this.havenIcon = Image.asset('assets/images/haven_menu.png');
final largeScreen = 731;
double menuWidth;
@@ -34,6 +43,11 @@ class MenuWidgetState extends State<MenuWidget> {
double fromTopEdge;
double fromBottomEdge;
Image moneroIcon;
Image bitcoinIcon;
Image litecoinIcon;
Image havenIcon;
@override
void initState() {
menuWidth = 0;
@@ -75,9 +89,9 @@ class MenuWidgetState extends State<MenuWidget> {
final itemCount = walletMenu.items.length;
moneroIcon = Image.asset('assets/images/monero_menu.png',
color: Theme.of(context).accentTextTheme.overline.decorationColor);
color: Theme.of(context).accentTextTheme!.overline!.decorationColor!);
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
color: Theme.of(context).accentTextTheme.overline.decorationColor);
color: Theme.of(context).accentTextTheme!.overline!.decorationColor!);
litecoinIcon = Image.asset('assets/images/litecoin_menu.png');
havenIcon = Image.asset('assets/images/haven_menu.png');
@@ -101,7 +115,7 @@ class MenuWidgetState extends State<MenuWidget> {
topLeft: Radius.circular(24),
bottomLeft: Radius.circular(24)),
child: Container(
color: Theme.of(context).textTheme.body2.decorationColor,
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
child: ListView.separated(
padding: EdgeInsets.only(top: 0),
itemBuilder: (_, index) {
@@ -112,13 +126,13 @@ class MenuWidgetState extends State<MenuWidget> {
gradient: LinearGradient(
colors: [
Theme.of(context)
.accentTextTheme
.display1
.color,
.accentTextTheme!
.headline4!
.color!,
Theme.of(context)
.accentTextTheme
.display1
.decorationColor,
.accentTextTheme!
.headline4!
.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
@@ -159,9 +173,9 @@ class MenuWidgetState extends State<MenuWidget> {
.subname,
style: TextStyle(
color: Theme.of(context)
.accentTextTheme
.overline
.decorationColor,
.accentTextTheme!
.overline!
.decorationColor!,
fontWeight:
FontWeight.w500,
fontSize: 12),
@@ -188,9 +202,9 @@ class MenuWidgetState extends State<MenuWidget> {
},
child: Container(
color: Theme.of(context)
.textTheme
.body2
.decorationColor,
.textTheme!
.bodyText1!
.decorationColor!,
height: isLastTile ? headerHeight : tileHeight,
padding: isLastTile
? EdgeInsets.only(
@@ -212,9 +226,9 @@ class MenuWidgetState extends State<MenuWidget> {
title,
style: TextStyle(
color: Theme.of(context)
.textTheme
.display2
.color,
.textTheme!
.headline3!
.color!,
fontSize: 16,
fontWeight: FontWeight.bold),
))
@@ -225,9 +239,9 @@ class MenuWidgetState extends State<MenuWidget> {
separatorBuilder: (_, index) => Container(
height: 1,
color: Theme.of(context)
.primaryTextTheme
.caption
.decorationColor,
.primaryTextTheme!
.caption!
.decorationColor!,
),
itemCount: itemCount + 1),
)))
@@ -235,7 +249,7 @@ class MenuWidgetState extends State<MenuWidget> {
);
}
Image _iconFor({@required WalletType type}) {
Image _iconFor({required WalletType type}) {
switch (type) {
case WalletType.monero:
return moneroIcon;
@@ -246,7 +260,7 @@ class MenuWidgetState extends State<MenuWidget> {
case WalletType.haven:
return havenIcon;
default:
return null;
throw Exception('No icon for ${type.toString()}');
}
}
}
@@ -4,23 +4,23 @@ import 'package:flutter/material.dart';
class OrderRow extends StatelessWidget {
OrderRow({
@required this.onTap,
@required this.provider,
this.from,
this.to,
this.createdAtFormattedDate,
required this.provider,
required this.from,
required this.to,
required this.createdAtFormattedDate,
this.onTap,
this.formattedAmount});
final VoidCallback onTap;
final VoidCallback? onTap;
final BuyProviderDescription provider;
final String from;
final String to;
final String createdAtFormattedDate;
final String formattedAmount;
final String? formattedAmount;
@override
Widget build(BuildContext context) {
final iconColor =
Theme.of(context).primaryTextTheme.display4.backgroundColor;
Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!;
final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
@@ -48,16 +48,14 @@ class OrderRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
)),
formattedAmount != null
? Text(formattedAmount + ' ' + to,
? Text(formattedAmount! + ' ' + to,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
))
: Container()
]),
@@ -68,8 +66,8 @@ class OrderRow extends StatelessWidget {
Text(createdAtFormattedDate,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme
.overline.backgroundColor))
color: Theme.of(context).textTheme!
.overline!.backgroundColor!))
])
],
)
@@ -6,7 +6,7 @@ import 'package:cw_core/sync_status.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
class SyncIndicator extends StatelessWidget {
SyncIndicator({@required this.dashboardViewModel,this.onTap});
SyncIndicator({required this.dashboardViewModel, required this.onTap});
final DashboardViewModel dashboardViewModel;
final Function() onTap;
@@ -32,7 +32,7 @@ class SyncIndicator extends StatelessWidget {
child: Container(
height: 30,
width: syncIndicatorWidth,
color: Theme.of(context).textTheme.title.decorationColor,
color: Theme.of(context).textTheme!.headline6!.decorationColor!,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
@@ -44,7 +44,7 @@ class SyncIndicator extends StatelessWidget {
child: Container(
width: indicatorWidth,
height: 30,
color: Theme.of(context).textTheme.title.backgroundColor,
color: Theme.of(context).textTheme!.headline6!.backgroundColor!,
)
)
: Offstage(),
@@ -66,7 +66,7 @@ class SyncIndicator extends StatelessWidget {
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.title.color
color: Theme.of(context).textTheme!.headline6!.color!
),
),
)
@@ -2,20 +2,56 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class SyncIndicatorIcon extends StatelessWidget {
SyncIndicatorIcon({this.isSynced});
SyncIndicatorIcon(
{this.boolMode = true,
this.isSynced = false,
this.value = waiting,
this.size = 4.0});
final bool boolMode;
final bool isSynced;
final String value;
final double size;
static const String waiting = 'waiting';
static const String actionRequired = 'action required';
static const String created = 'created';
static const String fetching = 'fetching';
static const String finished = 'finished';
@override
Widget build(BuildContext context) {
Color indicatorColor;
if (boolMode) {
indicatorColor = isSynced
? PaletteDark.brightGreen
: Theme.of(context).textTheme!.caption!.color!;
} else {
switch (value.toLowerCase()) {
case waiting:
indicatorColor = Colors.red;
break;
case actionRequired:
indicatorColor = Theme.of(context).textTheme!.headline2!.decorationColor!;
break;
case created:
indicatorColor = PaletteDark.brightGreen;
break;
case fetching:
indicatorColor = Colors.red;
break;
case finished:
indicatorColor = PaletteDark.brightGreen;
break;
default:
indicatorColor = Colors.red;
}
}
return Container(
height: 4,
width: 4,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isSynced
? PaletteDark.brightGreen
: Theme.of(context).textTheme.caption.color),
);
height: size,
width: size,
decoration:
BoxDecoration(shape: BoxShape.circle, color: indicatorColor));
}
}
@@ -4,19 +4,19 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
class TradeRow extends StatelessWidget {
TradeRow({
this.provider,
this.from,
this.to,
this.createdAtFormattedDate,
this.formattedAmount,
@required this.onTap});
required this.provider,
required this.from,
required this.to,
required this.createdAtFormattedDate,
this.onTap,
this.formattedAmount,});
final VoidCallback onTap;
final VoidCallback? onTap;
final ExchangeProviderDescription provider;
final CryptoCurrency from;
final CryptoCurrency to;
final String createdAtFormattedDate;
final String formattedAmount;
final String? createdAtFormattedDate;
final String? formattedAmount;
@override
Widget build(BuildContext context) {
@@ -31,7 +31,7 @@ class TradeRow extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_getPoweredImage(provider),
_getPoweredImage(provider)!,
SizedBox(width: 12),
Expanded(
child: Column(
@@ -44,16 +44,14 @@ class TradeRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
)),
formattedAmount != null
? Text(formattedAmount + ' ' + amountCrypto,
? Text(formattedAmount! + ' ' + amountCrypto,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
))
: Container()
]),
@@ -61,11 +59,12 @@ class TradeRow extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(createdAtFormattedDate,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme
.overline.backgroundColor))
if (createdAtFormattedDate != null)
Text(createdAtFormattedDate!,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).textTheme!
.overline!.backgroundColor!))
])
],
)
@@ -75,8 +74,9 @@ class TradeRow extends StatelessWidget {
));
}
Image _getPoweredImage(ExchangeProviderDescription provider) {
Image image;
Image? _getPoweredImage(ExchangeProviderDescription provider) {
Image? image;
switch (provider) {
case ExchangeProviderDescription.xmrto:
image = Image.asset('assets/images/xmrto.png', height: 36, width: 36);
@@ -90,9 +90,13 @@ class TradeRow extends StatelessWidget {
case ExchangeProviderDescription.sideShift:
image = Image.asset('assets/images/sideshift.png', width: 36, height: 36);
break;
case ExchangeProviderDescription.simpleSwap:
image = Image.asset('assets/images/simpleSwap.png', width: 36, height: 36);
break;
default:
image = null;
}
return image;
}
}
@@ -4,12 +4,12 @@ import 'package:cake_wallet/generated/i18n.dart';
class TransactionRow extends StatelessWidget {
TransactionRow(
{this.direction,
this.formattedDate,
this.formattedAmount,
this.formattedFiatAmount,
this.isPending,
@required this.onTap});
{required this.direction,
required this.formattedDate,
required this.formattedAmount,
required this.formattedFiatAmount,
required this.isPending,
required this.onTap});
final VoidCallback onTap;
final TransactionDirection direction;
@@ -34,7 +34,7 @@ class TransactionRow extends StatelessWidget {
width: 36,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).textTheme.overline.decorationColor
color: Theme.of(context).textTheme!.overline!.decorationColor!
),
child: Image.asset(
direction == TransactionDirection.incoming
@@ -57,14 +57,14 @@ class TransactionRow extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor)),
color: Theme.of(context).accentTextTheme!
.headline2!.backgroundColor!)),
Text(formattedAmount,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.
display3.backgroundColor))
color: Theme.of(context).accentTextTheme!
.headline2!.backgroundColor!))
]),
SizedBox(height: 5),
Row(
@@ -74,16 +74,16 @@ class TransactionRow extends StatelessWidget {
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.textTheme
.overline
.backgroundColor)),
.textTheme!
.overline!
.backgroundColor!)),
Text(formattedFiatAmount,
style: TextStyle(
fontSize: 14,
color: Theme.of(context)
.textTheme
.overline
.backgroundColor))
.textTheme!
.overline!
.backgroundColor!))
])
],
)
@@ -15,7 +15,7 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
class TransactionsPage extends StatelessWidget {
TransactionsPage({@required this.dashboardViewModel});
TransactionsPage({required this.dashboardViewModel});
final DashboardViewModel dashboardViewModel;
@@ -72,7 +72,9 @@ class TransactionsPage extends StatelessWidget {
from: trade.from,
to: trade.to,
createdAtFormattedDate:
DateFormat('HH:mm').format(trade.createdAt),
trade.createdAt != null
? DateFormat('HH:mm').format(trade.createdAt!)
: null,
formattedAmount: item.tradeFormattedAmount
));
}
@@ -85,8 +87,8 @@ class TransactionsPage extends StatelessWidget {
Routes.orderDetails,
arguments: order),
provider: order.provider,
from: order.from,
to: order.to,
from: order.from!,
to: order.to!,
createdAtFormattedDate:
DateFormat('HH:mm').format(order.createdAt),
formattedAmount: item.orderFormattedAmount,
@@ -103,8 +105,8 @@ class TransactionsPage extends StatelessWidget {
S.of(context).placeholder_transactions,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).primaryTextTheme
.overline.decorationColor
color: Theme.of(context).primaryTextTheme!
.overline!.decorationColor!
),
),
);
+26 -26
View File
@@ -21,7 +21,7 @@ class DisclaimerPage extends BasePage {
String get title => 'Terms of Use';
@override
Widget leading(BuildContext context) =>
Widget? leading(BuildContext context) =>
isReadOnly ? super.leading(context) : null;
@override
@@ -30,7 +30,7 @@ class DisclaimerPage extends BasePage {
}
class DisclaimerPageBody extends StatefulWidget {
DisclaimerPageBody({this.isReadOnly});
DisclaimerPageBody({required this.isReadOnly});
final bool isReadOnly;
@@ -88,9 +88,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
),
)
],
@@ -108,9 +108,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontSize: 12.0,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
),
)
],
@@ -127,9 +127,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontSize: 12.0,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
))
],
),
@@ -147,9 +147,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontSize: 14.0,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
),
)
],
@@ -233,9 +233,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
.primaryTextTheme!
.caption!
.color!,
width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(8.0)),
@@ -254,9 +254,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
fontWeight: FontWeight.bold,
fontSize: 14.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
)
],
),
@@ -274,13 +274,13 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
: null,
text: 'Accept',
color: Theme.of(context)
.accentTextTheme
.subtitle
.decorationColor,
.accentTextTheme!
.subtitle2!
.decorationColor!,
textColor: Theme.of(context)
.accentTextTheme
.headline
.decorationColor),
.accentTextTheme!
.headline5!
.decorationColor!),
),
],
],
+111 -88
View File
@@ -82,7 +82,7 @@ class ExchangePage extends BasePage {
Widget trailing(BuildContext context) => TrailButton(
caption: S.of(context).reset,
onPressed: () {
_formKey.currentState.reset();
_formKey.currentState?.reset();
exchangeViewModel.reset();
});
@@ -111,12 +111,16 @@ class ExchangePage extends BasePage {
WidgetsBinding.instance
.addPostFrameCallback((_) => _setReactions(context, exchangeViewModel));
if (exchangeViewModel.isLowFee) {
_showFeeAlert(context);
}
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme.body2.backgroundColor,
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -142,11 +146,11 @@ class ExchangePage extends BasePage {
bottomRight: Radius.circular(24)),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.body1.color,
Theme.of(context).primaryTextTheme!.bodyText2!.color!,
Theme.of(context)
.primaryTextTheme
.body1
.decorationColor,
.primaryTextTheme!
.bodyText2!
.decorationColor!,
],
stops: [
0.35,
@@ -165,13 +169,13 @@ class ExchangePage extends BasePage {
gradient: LinearGradient(
colors: [
Theme.of(context)
.primaryTextTheme
.subtitle
.color,
.primaryTextTheme!
.subtitle2!
.color!,
Theme.of(context)
.primaryTextTheme
.subtitle
.decorationColor,
.primaryTextTheme!
.subtitle2!
.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
@@ -179,6 +183,7 @@ class ExchangePage extends BasePage {
padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
child: Observer(
builder: (_) => ExchangeCard(
onDispose: disposeBestRateSync,
hasAllAmount: exchangeViewModel.hasAllAmount,
allAmount: exchangeViewModel.hasAllAmount
? () => exchangeViewModel
@@ -190,7 +195,7 @@ class ExchangePage extends BasePage {
title: S.of(context).you_will_send,
initialCurrency:
exchangeViewModel.depositCurrency,
initialWalletName: depositWalletName,
initialWalletName: depositWalletName ?? '',
initialAddress:
exchangeViewModel.depositCurrency ==
exchangeViewModel.wallet.currency
@@ -230,11 +235,11 @@ class ExchangePage extends BasePage {
imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent,
addressButtonsColor:
Theme.of(context).focusColor,
Theme.of(context).focusColor!,
borderColor: Theme.of(context)
.primaryTextTheme
.body2
.color,
.primaryTextTheme!
.bodyText1!
.color!,
currencyValueValidator: AmountValidator(
type: exchangeViewModel.wallet.type),
addressTextFieldValidator: AddressValidator(
@@ -265,13 +270,14 @@ class ExchangePage extends BasePage {
EdgeInsets.only(top: 29, left: 24, right: 24),
child: Observer(
builder: (_) => ExchangeCard(
onDispose: disposeBestRateSync,
amountFocusNode: _receiveAmountFocus,
addressFocusNode: _receiveAddressFocus,
key: receiveKey,
title: S.of(context).you_will_get,
initialCurrency:
exchangeViewModel.receiveCurrency,
initialWalletName: receiveWalletName,
initialWalletName: receiveWalletName ?? '',
initialAddress: exchangeViewModel
.receiveCurrency ==
exchangeViewModel.wallet.currency
@@ -293,11 +299,11 @@ class ExchangePage extends BasePage {
imageArrow: arrowBottomCakeGreen,
currencyButtonColor: Colors.transparent,
addressButtonsColor:
Theme.of(context).focusColor,
Theme.of(context).focusColor!,
borderColor: Theme.of(context)
.primaryTextTheme
.body2
.decorationColor,
.primaryTextTheme!
.bodyText1!
.decorationColor!,
currencyValueValidator: AmountValidator(
type: exchangeViewModel.wallet.type),
addressTextFieldValidator:
@@ -354,17 +360,21 @@ class ExchangePage extends BasePage {
padding: EdgeInsets.only(bottom: 15),
child: Observer(builder: (_) {
final description = exchangeViewModel.isFixedRateMode
? exchangeViewModel.isAvailableInSelected
? S.of(context).amount_is_guaranteed
: S.of(context).amount_is_estimate;
: S.of(context).fixed_pair_not_supported
: exchangeViewModel.isAvailableInSelected
? S.of(context).amount_is_estimate
: S.of(context).variable_pair_not_supported;
return Center(
child: Text(
description,
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.display4
.decorationColor,
.primaryTextTheme!
.headline1!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
),
@@ -375,7 +385,7 @@ class ExchangePage extends BasePage {
builder: (_) => LoadingPrimaryButton(
text: S.of(context).exchange,
onPressed: () {
if (_formKey.currentState.validate()) {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
if ((exchangeViewModel.depositCurrency ==
CryptoCurrency.xmr) &&
(!(exchangeViewModel.status
@@ -397,10 +407,10 @@ class ExchangePage extends BasePage {
}
}
},
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isLoading:
exchangeViewModel.tradeState is TradeIsCreating)),
isDisabled: exchangeViewModel.selectedProviders.isEmpty,
isLoading: exchangeViewModel.tradeState is TradeIsCreating)),
]),
)),
));
@@ -428,9 +438,9 @@ class ExchangePage extends BasePage {
borderType: BorderType.RRect,
dashPattern: [6, 4],
color: Theme.of(context)
.primaryTextTheme
.display2
.decorationColor,
.primaryTextTheme!
.headline3!
.decorationColor!,
strokeWidth: 2,
radius: Radius.circular(20),
child: Container(
@@ -445,9 +455,9 @@ class ExchangePage extends BasePage {
? Icon(
Icons.add,
color: Theme.of(context)
.primaryTextTheme
.display3
.color,
.primaryTextTheme!
.headline2!
.color!,
)
: Text(
S.of(context).new_template,
@@ -455,9 +465,9 @@ class ExchangePage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.display3
.color,
.primaryTextTheme!
.headline2!
.color!,
),
),
),
@@ -518,13 +528,6 @@ class ExchangePage extends BasePage {
exchangeViewModel.changeReceiveCurrency(
currency: CryptoCurrency.fromString(template.receiveCurrency));
switch (template.provider) {
case 'ChangeNOW':
exchangeViewModel.changeProvider(
provider: exchangeViewModel.providerList[0]);
break;
}
exchangeViewModel.changeDepositAmount(amount: template.amount);
exchangeViewModel.depositAddress = template.depositAddress;
exchangeViewModel.receiveAddress = template.receiveAddress;
@@ -548,10 +551,10 @@ class ExchangePage extends BasePage {
return;
}
final depositAddressController = depositKey.currentState.addressController;
final depositAmountController = depositKey.currentState.amountController;
final receiveAddressController = receiveKey.currentState.addressController;
final receiveAmountController = receiveKey.currentState.amountController;
final depositAddressController = depositKey.currentState!.addressController;
final depositAmountController = depositKey.currentState!.amountController;
final receiveAddressController = receiveKey.currentState!.addressController;
final receiveAmountController = receiveKey.currentState!.amountController;
final limitsState = exchangeViewModel.limitsState;
if (limitsState is LimitsLoadedSuccessfully) {
@@ -564,7 +567,7 @@ class ExchangePage extends BasePage {
final key = exchangeViewModel.isFixedRateMode
? receiveKey
: depositKey;
key.currentState.changeLimits(min: min, max: max);
key.currentState!.changeLimits(min: min, max: max);
}
_onCurrencyChange(
@@ -593,43 +596,42 @@ class ExchangePage extends BasePage {
_onCurrencyChange(currency, exchangeViewModel, depositKey));
reaction((_) => exchangeViewModel.depositAmount, (String amount) {
if (depositKey.currentState.amountController.text != amount) {
depositKey.currentState.amountController.text = amount;
if (depositKey.currentState!.amountController.text != amount) {
depositKey.currentState!.amountController.text = amount;
}
});
reaction((_) => exchangeViewModel.depositAddress, (String address) {
if (depositKey.currentState.addressController.text != address) {
depositKey.currentState.addressController.text = address;
if (depositKey.currentState!.addressController.text != address) {
depositKey.currentState!.addressController.text = address;
}
});
reaction((_) => exchangeViewModel.isDepositAddressEnabled,
(bool isEnabled) {
depositKey.currentState.isAddressEditable(isEditable: isEnabled);
depositKey.currentState!.isAddressEditable(isEditable: isEnabled);
});
reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
if (receiveKey.currentState.amountController.text != amount) {
receiveKey.currentState.amountController.text = amount;
if (receiveKey.currentState!.amountController.text != amount) {
receiveKey.currentState!.amountController.text = amount;
}
});
reaction((_) => exchangeViewModel.receiveAddress, (String address) {
if (receiveKey.currentState.addressController.text != address) {
receiveKey.currentState.addressController.text = address;
if (receiveKey.currentState!.addressController.text != address) {
receiveKey.currentState!.addressController.text = address;
}
});
reaction((_) => exchangeViewModel.isReceiveAddressEnabled,
(bool isEnabled) {
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
receiveKey.currentState!.isAddressEditable(isEditable: isEnabled);
});
reaction((_) => exchangeViewModel.isReceiveAmountEditable,
(bool isReceiveAmountEditable) {
receiveKey.currentState
.isAmountEditable(isEditable: isReceiveAmountEditable);
receiveKey.currentState!.isAmountEditable(isEditable: isReceiveAmountEditable);
});
reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) {
@@ -653,8 +655,8 @@ class ExchangePage extends BasePage {
});
reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
String min;
String max;
String? min;
String? max;
if (state is LimitsLoadedSuccessfully) {
min = state.limits.min != null ? state.limits.min.toString() : null;
@@ -672,17 +674,17 @@ class ExchangePage extends BasePage {
}
if (exchangeViewModel.isFixedRateMode) {
depositKey.currentState.changeLimits(min: null, max: null);
receiveKey.currentState.changeLimits(min: min, max: max);
depositKey.currentState!.changeLimits(min: null, max: null);
receiveKey.currentState!.changeLimits(min: min, max: max);
} else {
depositKey.currentState.changeLimits(min: min, max: max);
receiveKey.currentState.changeLimits(min: null, max: null);
depositKey.currentState!.changeLimits(min: min, max: max);
receiveKey.currentState!.changeLimits(min: null, max: null);
}
});
reaction((_) => exchangeViewModel.isFixedRateMode, (bool value) {
if (checkBoxKey.currentState.value != exchangeViewModel.isFixedRateMode) {
checkBoxKey.currentState.value = exchangeViewModel.isFixedRateMode;
if (checkBoxKey.currentState!.value != exchangeViewModel.isFixedRateMode) {
checkBoxKey.currentState!.value = exchangeViewModel.isFixedRateMode;
}
});
@@ -715,11 +717,11 @@ class ExchangePage extends BasePage {
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
(String address) {
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
depositKey.currentState.changeAddress(address: address);
depositKey.currentState!.changeAddress(address: address);
}
if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
receiveKey.currentState.changeAddress(address: address);
receiveKey.currentState!.changeAddress(address: address);
}
});
@@ -744,15 +746,16 @@ class ExchangePage extends BasePage {
});
_receiveAmountFocus.addListener(() {
exchangeViewModel.isFixedRateMode = true;
exchangeViewModel.changeReceiveAmount(
amount: receiveAmountController.text);
if (_receiveAmountFocus.hasFocus) {
exchangeViewModel.isFixedRateMode = true;
}
// exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
});
_depositAmountFocus.addListener(() {
exchangeViewModel.isFixedRateMode = false;
exchangeViewModel.changeDepositAmount(
amount: depositAmountController.text);
// exchangeViewModel.changeDepositAmount(
// amount: depositAmountController.text);
});
_isReactionsSet = true;
@@ -762,15 +765,15 @@ class ExchangePage extends BasePage {
ExchangeViewModel exchangeViewModel, GlobalKey<ExchangeCardState> key) {
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
key.currentState.changeSelectedCurrency(currency);
key.currentState.changeWalletName(
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
key.currentState!.changeSelectedCurrency(currency);
key.currentState!.changeWalletName(
isCurrentTypeWallet ? exchangeViewModel.wallet.name : '');
key.currentState.changeAddress(
key.currentState!.changeAddress(
address: isCurrentTypeWallet
? exchangeViewModel.wallet.walletAddresses.address : '');
key.currentState.changeAmount(amount: '');
key.currentState!.changeAmount(amount: '');
}
void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
@@ -778,13 +781,13 @@ class ExchangePage extends BasePage {
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
if (isCurrentTypeWallet) {
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
key.currentState.addressController.text =
key.currentState!.changeWalletName(exchangeViewModel.wallet.name);
key.currentState!.addressController.text =
exchangeViewModel.wallet.walletAddresses.address;
} else if (key.currentState.addressController.text ==
} else if (key.currentState!.addressController.text ==
exchangeViewModel.wallet.walletAddresses.address) {
key.currentState.changeWalletName(null);
key.currentState.addressController.text = null;
key.currentState!.changeWalletName('');
key.currentState!.addressController.text = '';
}
}
@@ -794,4 +797,24 @@ class ExchangePage extends BasePage {
final address = await extractAddressFromParsed(context, parsedAddress);
return address;
}
void _showFeeAlert(BuildContext context) async {
await Future<void>.delayed(Duration(seconds: 1));
final confirmed = await showPopUp<bool>(
context: context,
builder: (dialogContext) {
return AlertWithTwoActions(
alertTitle: S.of(context).low_fee,
alertContent: S.of(context).low_fee_alert,
leftButtonText: S.of(context).ignor,
rightButtonText: S.of(context).use_suggested,
actionLeftButton: () => Navigator.of(context).pop(false),
actionRightButton: () => Navigator.of(context).pop(true));
}) ?? false;
if (confirmed) {
exchangeViewModel.setDefaultTransactionPriority();
}
}
void disposeBestRateSync() => exchangeViewModel.bestRateSync?.cancel();
}
@@ -1,8 +1,6 @@
import 'dart:ui';
import 'package:cake_wallet/exchange/exchange_provider.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@@ -19,9 +17,7 @@ import 'package:cake_wallet/exchange/xmrto/xmrto_exchange_provider.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/amount_validator.dart';
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
@@ -82,7 +78,7 @@ class ExchangeTemplatePage extends BasePage {
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme.body2.backgroundColor,
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -107,8 +103,8 @@ class ExchangeTemplatePage extends BasePage {
),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.body1.color,
Theme.of(context).primaryTextTheme.body1.decorationColor,
Theme.of(context).primaryTextTheme!.bodyText2!.color!,
Theme.of(context).primaryTextTheme!.bodyText2!.decorationColor!,
],
stops: [0.35, 1.0],
begin: Alignment.topLeft,
@@ -125,13 +121,13 @@ class ExchangeTemplatePage extends BasePage {
gradient: LinearGradient(
colors: [
Theme.of(context)
.primaryTextTheme
.subtitle
.color,
.primaryTextTheme!
.subtitle2!
.color!,
Theme.of(context)
.primaryTextTheme
.subtitle
.decorationColor,
.primaryTextTheme!
.subtitle2!
.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
@@ -144,7 +140,7 @@ class ExchangeTemplatePage extends BasePage {
title: S.of(context).you_will_send,
initialCurrency:
exchangeViewModel.depositCurrency,
initialWalletName: depositWalletName,
initialWalletName: depositWalletName ?? '',
initialAddress: exchangeViewModel
.depositCurrency ==
exchangeViewModel.wallet.currency
@@ -163,11 +159,11 @@ class ExchangeTemplatePage extends BasePage {
imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent,
addressButtonsColor:
Theme.of(context).focusColor,
Theme.of(context).focusColor!,
borderColor: Theme.of(context)
.primaryTextTheme
.body2
.color,
.primaryTextTheme!
.bodyText1!
.color!,
currencyValueValidator: AmountValidator(
type: exchangeViewModel.wallet.type),
//addressTextFieldValidator: AddressValidator(
@@ -184,7 +180,7 @@ class ExchangeTemplatePage extends BasePage {
title: S.of(context).you_will_get,
initialCurrency:
exchangeViewModel.receiveCurrency,
initialWalletName: receiveWalletName,
initialWalletName: receiveWalletName ?? '',
initialAddress:
exchangeViewModel.receiveCurrency ==
exchangeViewModel.wallet.currency
@@ -204,11 +200,11 @@ class ExchangeTemplatePage extends BasePage {
imageArrow: arrowBottomCakeGreen,
currencyButtonColor: Colors.transparent,
addressButtonsColor:
Theme.of(context).focusColor,
Theme.of(context).focusColor!,
borderColor: Theme.of(context)
.primaryTextTheme
.body2
.decorationColor,
.primaryTextTheme!
.bodyText1!
.decorationColor!,
currencyValueValidator: AmountValidator(
type: exchangeViewModel.wallet.type),
//addressTextFieldValidator: AddressValidator(
@@ -234,9 +230,9 @@ class ExchangeTemplatePage extends BasePage {
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.display4
.decorationColor,
.primaryTextTheme!
.headline1!
.decorationColor!,
fontWeight: FontWeight.w500,
fontSize: 12),
),
@@ -245,7 +241,7 @@ class ExchangeTemplatePage extends BasePage {
),
PrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
exchangeViewModel.addTemplate(
amount: exchangeViewModel.depositAmount,
depositCurrency:
@@ -274,10 +270,10 @@ class ExchangeTemplatePage extends BasePage {
return;
}
final depositAddressController = depositKey.currentState.addressController;
final depositAmountController = depositKey.currentState.amountController;
final receiveAddressController = receiveKey.currentState.addressController;
final receiveAmountController = receiveKey.currentState.amountController;
final depositAddressController = depositKey.currentState!.addressController;
final depositAmountController = depositKey.currentState!.amountController;
final receiveAddressController = receiveKey.currentState!.addressController;
final receiveAmountController = receiveKey.currentState!.amountController;
final limitsState = exchangeViewModel.limitsState;
// FIXME: FIXME
@@ -321,43 +317,43 @@ class ExchangeTemplatePage extends BasePage {
_onCurrencyChange(currency, exchangeViewModel, depositKey));
reaction((_) => exchangeViewModel.depositAmount, (String amount) {
if (depositKey.currentState.amountController.text != amount) {
depositKey.currentState.amountController.text = amount;
if (depositKey.currentState!.amountController.text != amount) {
depositKey.currentState!.amountController.text = amount;
}
});
reaction((_) => exchangeViewModel.depositAddress, (String address) {
if (depositKey.currentState.addressController.text != address) {
depositKey.currentState.addressController.text = address;
if (depositKey.currentState!.addressController.text != address) {
depositKey.currentState!.addressController.text = address;
}
});
reaction((_) => exchangeViewModel.isDepositAddressEnabled,
(bool isEnabled) {
depositKey.currentState.isAddressEditable(isEditable: isEnabled);
depositKey.currentState!.isAddressEditable(isEditable: isEnabled);
});
reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
if (receiveKey.currentState.amountController.text != amount) {
receiveKey.currentState.amountController.text = amount;
if (receiveKey.currentState!.amountController.text != amount) {
receiveKey.currentState!.amountController.text = amount;
}
});
reaction((_) => exchangeViewModel.receiveAddress, (String address) {
if (receiveKey.currentState.addressController.text != address) {
receiveKey.currentState.addressController.text = address;
if (receiveKey.currentState!.addressController.text != address) {
receiveKey.currentState!.addressController.text = address;
}
});
reaction((_) => exchangeViewModel.isReceiveAddressEnabled,
(bool isEnabled) {
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
receiveKey.currentState!.isAddressEditable(isEditable: isEnabled);
});
reaction((_) => exchangeViewModel.provider, (ExchangeProvider provider) {
reaction((_) => exchangeViewModel.provider, (ExchangeProvider? provider) {
provider is XMRTOExchangeProvider
? receiveKey.currentState.isAmountEditable(isEditable: true)
: receiveKey.currentState.isAmountEditable(isEditable: false);
? receiveKey.currentState!.isAmountEditable(isEditable: true)
: receiveKey.currentState!.isAmountEditable(isEditable: false);
});
/*reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
@@ -408,11 +404,11 @@ class ExchangeTemplatePage extends BasePage {
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
(String address) {
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
depositKey.currentState.changeAddress(address: address);
depositKey.currentState!.changeAddress(address: address);
}
if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
receiveKey.currentState.changeAddress(address: address);
receiveKey.currentState!.changeAddress(address: address);
}
});
@@ -423,15 +419,15 @@ class ExchangeTemplatePage extends BasePage {
ExchangeViewModel exchangeViewModel, GlobalKey<ExchangeCardState> key) {
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
key.currentState.changeSelectedCurrency(currency);
key.currentState.changeWalletName(
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
key.currentState!.changeSelectedCurrency(currency);
key.currentState!.changeWalletName(
isCurrentTypeWallet ? exchangeViewModel.wallet.name : '');
key.currentState.changeAddress(
key.currentState!.changeAddress(
address: isCurrentTypeWallet
? exchangeViewModel.wallet.walletAddresses.address : '');
key.currentState.changeAmount(amount: '');
key.currentState!.changeAmount(amount: '');
}
void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
@@ -439,13 +435,13 @@ class ExchangeTemplatePage extends BasePage {
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
if (isCurrentTypeWallet) {
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
key.currentState.addressController.text =
key.currentState!.changeWalletName(exchangeViewModel.wallet.name);
key.currentState!.addressController.text =
exchangeViewModel.wallet.walletAddresses.address;
} else if (key.currentState.addressController.text ==
} else if (key.currentState!.addressController.text ==
exchangeViewModel.wallet.walletAddresses.address) {
key.currentState.changeWalletName(null);
key.currentState.addressController.text = null;
key.currentState!.changeWalletName('');
key.currentState!.addressController.text = '';
}
}
}
@@ -6,13 +6,14 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/palette.dart';
import 'currency_picker_widget.dart';
class CurrencyPicker extends StatefulWidget {
CurrencyPicker(
{@required this.selectedAtIndex,
@required this.items,
@required this.onItemSelected,
{required this.selectedAtIndex,
required this.items,
required this.onItemSelected,
this.title,
this.hintText,
this.isMoneroWallet = false,
@@ -20,11 +21,11 @@ class CurrencyPicker extends StatefulWidget {
int selectedAtIndex;
final List<CryptoCurrency> items;
final String title;
final String? title;
final Function(CryptoCurrency) onItemSelected;
final bool isMoneroWallet;
final bool isConvertFrom;
final String hintText;
final String? hintText;
@override
CurrencyPickerState createState() => CurrencyPickerState(items);
@@ -36,9 +37,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
textFieldValue = '',
subPickerItemsList = items,
appBarTextStyle =
TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white);
TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white),
pickerItemsList = <PickerItem<CryptoCurrency>>[];
List<PickerItem<CryptoCurrency>> pickerItemsList;
List<CryptoCurrency> items;
@@ -55,8 +55,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
subPickerItemsList = items
.where((element) =>
(element.title != null ? element.title.toLowerCase().contains(subString.toLowerCase()) : false) ||
(element.tag != null ? element.tag.toLowerCase().contains(subString.toLowerCase()) : false) ||
(element.name != null ? element.name.toLowerCase().contains(subString.toLowerCase()) : false))
(element.tag != null ? element.tag!.toLowerCase().contains(subString.toLowerCase()) : false) ||
(element.name != null ? element.name!.toLowerCase().contains(subString.toLowerCase()) : false))
.toList();
return;
}
@@ -77,7 +77,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
Container(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Text(
widget.title,
widget.title!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
@@ -93,7 +93,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Container(
color: Theme.of(context).accentTextTheme.title.color,
color: Theme.of(context).accentTextTheme!.headline6!.color!,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.65,
@@ -105,7 +105,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
Padding(
padding: const EdgeInsets.all(16),
child: TextFormField(
style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
style: TextStyle(color: Palette.darkBlueCraiola),
decoration: InputDecoration(
hintText: widget.hintText,
prefixIcon: Image.asset("assets/images/search_icon.png"),
@@ -132,7 +132,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
),
),
Divider(
color: Theme.of(context).accentTextTheme.title.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
height: 1,
),
if (widget.selectedAtIndex != -1)
@@ -2,27 +2,32 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
class PickerItemWidget extends StatelessWidget {
const PickerItemWidget({this.iconPath, this.title, this.isSelected = false, this.tag, this.onTap});
const PickerItemWidget({
required this.title,
this.iconPath,
this.isSelected = false,
this.tag,
this.onTap});
final String iconPath;
final String? iconPath;
final String title;
final bool isSelected;
final String tag;
final void Function() onTap;
final String? tag;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
color: Theme.of(context).accentTextTheme.headline6.color,
color: Theme.of(context).accentTextTheme!.headline6!.color!,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
child: Row(
children: [
Container(
child: Image.asset(
iconPath,
iconPath ?? '',
height: 20.0,
width: 20.0,
),
@@ -34,7 +39,7 @@ class PickerItemWidget extends StatelessWidget {
Text(
title,
style: TextStyle(
color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme.title.color,
color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme!.headline6!.color!,
fontSize: isSelected ? 16 : 14.0,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
@@ -48,27 +53,26 @@ class PickerItemWidget extends StatelessWidget {
height: 18.0,
child: Center(
child: Text(
tag,
tag!,
style: TextStyle(
fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme.body1.color),
fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme!.bodyText2!.color!),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
//border: Border.all(color: ),
color: Theme.of(context).textTheme.body1.decorationColor,
color: Theme.of(context).textTheme!.bodyText2!.decorationColor!,
),
),
),
],
),
),
if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color)
if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme!.bodyText1!.color!)
],
),
),
),
);
;
}
}
@@ -5,10 +5,10 @@ import 'currency_picker_item_widget.dart';
class CurrencyPickerWidget extends StatelessWidget {
CurrencyPickerWidget({
@required this.crossAxisCount,
@required this.selectedAtIndex,
@required this.pickerItemsList,
@required this.pickListItem,
required this.crossAxisCount,
required this.selectedAtIndex,
required this.pickerItemsList,
required this.pickListItem,
});
final int crossAxisCount;
@@ -21,7 +21,7 @@ class CurrencyPickerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
child: Scrollbar(
controller: _scrollController,
child: GridView.builder(
@@ -14,30 +14,31 @@ import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
class ExchangeCard extends StatefulWidget {
ExchangeCard(
{Key key,
{Key? key,
required this.initialCurrency,
required this.initialAddress,
required this.initialWalletName,
required this.initialIsAmountEditable,
required this.initialIsAddressEditable,
required this.isAmountEstimated,
required this.currencies,
required this.onCurrencySelected,
required this.imageArrow,
this.currencyValueValidator,
this.addressTextFieldValidator,
this.title = '',
this.initialCurrency,
this.initialAddress,
this.initialWalletName,
this.initialIsAmountEditable,
this.initialIsAddressEditable,
this.isAmountEstimated,
this.hasRefundAddress = false,
this.isMoneroWallet = false,
this.currencies,
this.onCurrencySelected,
this.imageArrow,
this.currencyButtonColor = Colors.transparent,
this.addressButtonsColor = Colors.transparent,
this.borderColor = Colors.transparent,
this.currencyValueValidator,
this.addressTextFieldValidator,
this.hasAllAmount = false,
this.amountFocusNode,
this.addressFocusNode,
this.hasAllAmount = false,
this.allAmount,
this.onPushPasteButton,
this.onPushAddressBookButton})
this.onPushAddressBookButton,
this.onDispose})
: super(key: key);
final List<CryptoCurrency> currencies;
@@ -53,28 +54,40 @@ class ExchangeCard extends StatefulWidget {
final bool isMoneroWallet;
final Image imageArrow;
final Color currencyButtonColor;
final Color addressButtonsColor;
final Color? addressButtonsColor;
final Color borderColor;
final FormFieldValidator<String> currencyValueValidator;
final FormFieldValidator<String> addressTextFieldValidator;
final FocusNode amountFocusNode;
final FocusNode addressFocusNode;
final FormFieldValidator<String>? currencyValueValidator;
final FormFieldValidator<String>? addressTextFieldValidator;
final FocusNode? amountFocusNode;
final FocusNode? addressFocusNode;
final bool hasAllAmount;
final Function allAmount;
final Function(BuildContext context) onPushPasteButton;
final Function(BuildContext context) onPushAddressBookButton;
final VoidCallback? allAmount;
final void Function(BuildContext context)? onPushPasteButton;
final void Function(BuildContext context)? onPushAddressBookButton;
final Function()? onDispose;
@override
ExchangeCardState createState() => ExchangeCardState();
}
class ExchangeCardState extends State<ExchangeCard> {
ExchangeCardState()
: _title = '',
_min = '',
_max = '',
_isAmountEditable = false,
_isAddressEditable = false,
_walletName = '',
_selectedCurrency = CryptoCurrency.btc,
_isAmountEstimated = false,
_isMoneroWallet = false;
final addressController = TextEditingController();
final amountController = TextEditingController();
String _title;
String _min;
String _max;
String? _min;
String? _max;
CryptoCurrency _selectedCurrency;
String _walletName;
bool _isAmountEditable;
@@ -95,7 +108,14 @@ class ExchangeCardState extends State<ExchangeCard> {
super.initState();
}
void changeLimits({String min, String max}) {
@override
void dispose() {
widget.onDispose?.call();
super.dispose();
}
void changeLimits({String? min, String? max}) {
setState(() {
_min = min;
_max = max;
@@ -122,11 +142,11 @@ class ExchangeCardState extends State<ExchangeCard> {
setState(() => _isAddressEditable = isEditable);
}
void changeAddress({String address}) {
void changeAddress({required String address}) {
setState(() => addressController.text = address);
}
void changeAmount({String amount}) {
void changeAmount({required String amount}) {
setState(() => amountController.text = amount);
}
@@ -139,7 +159,7 @@ class ExchangeCardState extends State<ExchangeCard> {
final copyImage = Image.asset('assets/images/copy_content.png',
height: 16,
width: 16,
color: Theme.of(context).primaryTextTheme.display2.color);
color: Theme.of(context).primaryTextTheme!.headline3!.color!);
return Container(
width: double.infinity,
@@ -154,7 +174,7 @@ class ExchangeCardState extends State<ExchangeCard> {
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.headline.color),
color: Theme.of(context).textTheme!.headline5!.color!),
)
],
),
@@ -189,23 +209,20 @@ class ExchangeCardState extends State<ExchangeCard> {
child: Container(
height: 32,
decoration: BoxDecoration(
color: widget.addressButtonsColor ?? Theme.of(context)
.primaryTextTheme
.display1
.color,
color: widget.addressButtonsColor ?? Theme.of(context).primaryTextTheme!.headline4!.color!,
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Center(
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Text(_selectedCurrency.tag,
child: Text(_selectedCurrency.tag!,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor)),
.primaryTextTheme!
.headline4!
.decorationColor!)),
),
),
),
@@ -245,9 +262,9 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
.accentTextTheme!
.headline1!
.decorationColor!),
validator: _isAmountEditable
? widget.currencyValueValidator
: null),
@@ -258,9 +275,9 @@ class ExchangeCardState extends State<ExchangeCard> {
width: 32,
decoration: BoxDecoration(
color: Theme.of(context)
.primaryTextTheme
.display1
.color,
.primaryTextTheme!
.headline4!
.color!,
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: InkWell(
@@ -272,9 +289,9 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 12,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor)),
.primaryTextTheme!
.headline4!
.decorationColor!)),
),
),
)
@@ -284,9 +301,9 @@ class ExchangeCardState extends State<ExchangeCard> {
],
)),
Divider(height: 1,color: Theme.of(context)
.primaryTextTheme
.headline
.decorationColor),
.primaryTextTheme!
.headline5!
.decorationColor!),
Padding(
padding: EdgeInsets.only(top: 5),
child: Container(
@@ -298,14 +315,14 @@ class ExchangeCardState extends State<ExchangeCard> {
? Text(
S
.of(context)
.min_value(_min, _selectedCurrency.toString()),
.min_value(_min ?? '', _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
.accentTextTheme!
.headline1!
.decorationColor!),
)
: Offstage(),
_min != null ? SizedBox(width: 10) : Offstage(),
@@ -313,14 +330,14 @@ class ExchangeCardState extends State<ExchangeCard> {
? Text(
S
.of(context)
.max_value(_max, _selectedCurrency.toString()),
.max_value(_max ?? '', _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor))
.accentTextTheme!
.headline1!
.decorationColor!))
: Offstage(),
])),
),
@@ -333,9 +350,9 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
.accentTextTheme!
.headline1!
.decorationColor!),
))
: Offstage(),
_isAddressEditable
@@ -352,7 +369,7 @@ class ExchangeCardState extends State<ExchangeCard> {
_showAmountPopup(context, paymentRequest);
return;
}
widget.amountFocusNode.requestFocus();
widget.amountFocusNode?.requestFocus();
amountController.text = paymentRequest.amount;
},
placeholder: widget.hasRefundAddress
@@ -372,9 +389,9 @@ class ExchangeCardState extends State<ExchangeCard> {
fontSize: 16,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
.accentTextTheme!
.headline1!
.decorationColor!),
buttonColor: widget.addressButtonsColor,
validator: widget.addressTextFieldValidator,
onPushPasteButton: widget.onPushPasteButton,
@@ -439,9 +456,9 @@ class ExchangeCardState extends State<ExchangeCard> {
child: Image.asset(
'assets/images/open_book.png',
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor,
.primaryTextTheme!
.headline4!
.decorationColor!,
)),
)),
),
@@ -500,7 +517,7 @@ class ExchangeCardState extends State<ExchangeCard> {
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
actionRightButton: () {
widget.amountFocusNode.requestFocus();
widget.amountFocusNode?.requestFocus();
amountController.text = paymentRequest.amount;
Navigator.of(context).pop();
},
@@ -1,6 +1,9 @@
class PickerItem<T> {
PickerItem(this.original,
{this.title, this.iconPath, this.tag, this.description});
{required this.title,
required this.iconPath,
required this.tag,
required this.description});
final String title;
final String iconPath;
@@ -1,15 +1,13 @@
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/check_box_picker.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/exchange/exchange_provider.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
class PresentProviderPicker extends StatelessWidget {
PresentProviderPicker({@required this.exchangeViewModel});
PresentProviderPicker({required this.exchangeViewModel});
final ExchangeViewModel exchangeViewModel;
@@ -20,10 +18,14 @@ class PresentProviderPicker extends StatelessWidget {
color: Colors.white,
height: 6);
return FlatButton(
return TextButton(
onPressed: () => _presentProviderPicker(context),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
splashFactory: NoSplash.splashFactory,
foregroundColor: MaterialStateProperty.all(Colors.transparent),
overlayColor: MaterialStateProperty.all(Colors.transparent),
),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@@ -38,11 +40,16 @@ class PresentProviderPicker extends StatelessWidget {
fontWeight: FontWeight.w600,
color: Colors.white)),
Observer(
builder: (_) => Text('${exchangeViewModel.provider.title}',
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.headline.color)))
builder: (_) => Text(
exchangeViewModel.selectedProviders.isEmpty
? S.of(context).choose_one
: exchangeViewModel.selectedProviders.length > 1
? S.of(context).automatic
: exchangeViewModel.selectedProviders.first.title,
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.headline5!.color!)))
],
),
SizedBox(width: 5),
@@ -54,38 +61,19 @@ class PresentProviderPicker extends StatelessWidget {
));
}
void _presentProviderPicker(BuildContext context) {
final items = exchangeViewModel.providersForCurrentPair();
final selectedItem = items.indexOf(exchangeViewModel.provider);
final images = <Image>[];
String description;
for (var provider in items) {
switch (provider.description) {
case ExchangeProviderDescription.xmrto:
images.add(Image.asset('assets/images/xmr_btc.png'));
break;
case ExchangeProviderDescription.changeNow:
images.add(Image.asset('assets/images/change_now.png'));
break;
case ExchangeProviderDescription.morphToken:
images.add(Image.asset('assets/images/morph_icon.png'));
break;
case ExchangeProviderDescription.sideShift:
images.add(Image.asset('assets/images/sideshift.png', width: 20));
break;
}
}
showPopUp<void>(
builder: (BuildContext popUpContext) => Picker(
items: items,
images: images,
selectedAtIndex: selectedItem,
void _presentProviderPicker(BuildContext context) async {
await showPopUp<void>(
builder: (BuildContext popUpContext) => CheckBoxPicker(
items: exchangeViewModel.providerList
.map((e) => CheckBoxItem(
e.title,
exchangeViewModel.selectedProviders.contains(e),
isDisabled: !exchangeViewModel.providersForCurrentPair().contains(e),
))
.toList(),
title: S.of(context).change_exchange_provider,
description: description,
onItemSelected: (ExchangeProvider provider) {
if (!provider.isAvailable) {
onChanged: (int index, bool value) {
if (!exchangeViewModel.providerList[index].isAvailable) {
showPopUp<void>(
builder: (BuildContext popUpContext) => AlertWithOneAction(
alertTitle: 'Error',
@@ -95,8 +83,14 @@ class PresentProviderPicker extends StatelessWidget {
context: context);
return;
}
exchangeViewModel.changeProvider(provider: provider);
if (value) {
exchangeViewModel.addExchangeProvider(exchangeViewModel.providerList[index]);
} else {
exchangeViewModel.removeExchangeProvider(exchangeViewModel.providerList[index]);
}
}),
context: context);
exchangeViewModel.saveSelectedProviders();
}
}
@@ -1,3 +1,4 @@
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:flutter/material.dart';
@@ -10,7 +11,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/exchange/trade.dart';
class ExchangeConfirmPage extends BasePage {
ExchangeConfirmPage({@required this.tradesStore}) : trade = tradesStore.trade;
ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!;
final TradesStore tradesStore;
final Trade trade;
@@ -35,7 +36,7 @@ class ExchangeConfirmPage extends BasePage {
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
),
)),
Container(
@@ -44,8 +45,8 @@ class ExchangeConfirmPage extends BasePage {
borderRadius: BorderRadius.all(Radius.circular(30)),
border: Border.all(
width: 1,
color: Theme.of(context).accentTextTheme.caption.color),
color: Theme.of(context).accentTextTheme.title.color),
color: Theme.of(context).accentTextTheme!.caption!.color!),
color: Theme.of(context).accentTextTheme!.headline6!.color!),
child: Column(
children: <Widget>[
Expanded(
@@ -56,14 +57,14 @@ class ExchangeConfirmPage extends BasePage {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
S.of(context).trade_id,
"${trade.provider.title} ${S.of(context).trade_id}",
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme
.overline
.color),
.primaryTextTheme!
.overline!
.color!),
),
Text(
trade.id,
@@ -73,9 +74,9 @@ class ExchangeConfirmPage extends BasePage {
fontSize: 20,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
),
],
),
@@ -91,24 +92,40 @@ class ExchangeConfirmPage extends BasePage {
},
text: S.of(context).copy_id,
color: Theme.of(context)
.accentTextTheme
.caption
.backgroundColor,
.accentTextTheme!
.caption!
.backgroundColor!,
textColor:
Theme.of(context).primaryTextTheme.title.color),
Theme.of(context).primaryTextTheme!.headline6!.color!),
),
)
],
),
),
Flexible(child: Offstage()),
Flexible(
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
(trade.provider.image?.isNotEmpty ?? false)
? Image.asset(trade.provider.image, height: 50)
: const SizedBox(),
if (!trade.provider.horizontalLogo)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(trade.provider.title),
),
],
),
),
),
],
)),
PrimaryButton(
onPressed: () => Navigator.of(context)
.pushReplacementNamed(Routes.exchangeTrade),
text: S.of(context).saved_the_trade_id,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white)
],
),
@@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart';
class ExchangeTradeItem {
ExchangeTradeItem({
@required this.title,
@required this.data,
@required this.isCopied,
required this.title,
required this.data,
required this.isCopied,
});
String title;
@@ -40,7 +40,7 @@ void showInformation(
}
class ExchangeTradePage extends BasePage {
ExchangeTradePage({@required this.exchangeTradeViewModel});
ExchangeTradePage({required this.exchangeTradeViewModel});
final ExchangeTradeViewModel exchangeTradeViewModel;
@@ -50,17 +50,18 @@ class ExchangeTradePage extends BasePage {
@override
Widget trailing(BuildContext context) {
final questionImage = Image.asset('assets/images/question_mark.png',
color: Theme.of(context).primaryTextTheme.title.color);
color: Theme.of(context).primaryTextTheme!.headline6!.color!);
return SizedBox(
height: 20.0,
width: 20.0,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => showInformation(exchangeTradeViewModel, context),
child: questionImage),
),
@@ -109,7 +110,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
final copyImage = Image.asset('assets/images/copy_content.png',
height: 16,
width: 16,
color: Theme.of(context).primaryTextTheme.overline.color);
color: Theme.of(context).primaryTextTheme!.overline!.color!);
_setEffects(context);
@@ -132,15 +133,16 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
fontSize: 14.0,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme
.overline
.color),
.primaryTextTheme!
.overline!
.color!),
),
TimerWidget(trade.expiredAt,
color: Theme.of(context)
.primaryTextTheme
.title
.color)
if (trade.expiredAt != null)
TimerWidget(trade.expiredAt!,
color: Theme.of(context)
.primaryTextTheme!
.headline6!
.color!)
])
: Offstage(),
Padding(
@@ -158,18 +160,18 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
border: Border.all(
width: 3,
color: Theme.of(context)
.accentTextTheme
.subtitle
.color
.accentTextTheme!
.subtitle2!
.color!
)
),
child: QrImage(
data: trade.inputAddress ?? fetchingLabel,
backgroundColor: Colors.transparent,
foregroundColor: Theme.of(context)
.accentTextTheme
.subtitle
.color,
.accentTextTheme!
.subtitle2!
.color!,
),
)))),
Spacer(flex: 3)
@@ -184,9 +186,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
separatorBuilder: (context, index) => Container(
height: 1,
color: Theme.of(context)
.accentTextTheme
.subtitle
.backgroundColor,
.accentTextTheme!
.subtitle2!
.backgroundColor!,
),
itemBuilder: (context, index) {
final item = widget.exchangeTradeViewModel.items[index];
@@ -227,12 +229,12 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
!(sendingState is TransactionCommitted)
? LoadingPrimaryButton(
isDisabled: trade.inputAddress == null ||
trade.inputAddress.isEmpty,
trade.inputAddress!.isEmpty,
isLoading: sendingState is IsExecutingState,
onPressed: () =>
widget.exchangeTradeViewModel.confirmSending(),
text: S.of(context).confirm,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white)
: Offstage();
})),
@@ -269,10 +271,10 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
alertTitle: S.of(context).confirm_sending,
amount: S.of(context).send_amount,
amountValue: widget.exchangeTradeViewModel.sendViewModel
.pendingTransaction.amountFormatted,
.pendingTransaction!.amountFormatted,
fee: S.of(context).send_fee,
feeValue: widget.exchangeTradeViewModel.sendViewModel
.pendingTransaction.feeFormatted,
.pendingTransaction!.feeFormatted,
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
actionRightButton: () async {
@@ -311,8 +313,8 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
fontSize: 22,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.primaryTextTheme!
.headline6!
.color,
decoration: TextDecoration.none,
),
@@ -328,9 +330,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
Navigator.of(context).pop(),
text: S.of(context).send_got_it,
color: Theme.of(context)
.accentTextTheme
.body2
.color,
.accentTextTheme!
.bodyText1!
.color!,
textColor: Colors.white))
],
);
@@ -362,10 +364,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.primaryTextTheme
.title
.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
decoration: TextDecoration.none,
),
),
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
class InformationPage extends StatelessWidget {
InformationPage({@required this.information});
InformationPage({required this.information});
final String information;
@@ -21,7 +21,7 @@ class InformationPage extends StatelessWidget {
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
color: Theme.of(context).textTheme.body2.decorationColor
color: Theme.of(context).textTheme!.bodyText1!.decorationColor!
),
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -35,7 +35,7 @@ class InformationPage extends StatelessWidget {
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Theme.of(context).accentTextTheme.caption.decorationColor
color: Theme.of(context).accentTextTheme!.caption!.decorationColor!
),
),
),
@@ -44,8 +44,8 @@ class InformationPage extends StatelessWidget {
child: PrimaryButton(
onPressed: () => Navigator.of(context).pop(),
text: S.of(context).send_got_it,
color: Theme.of(context).accentTextTheme.caption.backgroundColor,
textColor: Theme.of(context).primaryTextTheme.title.color
color: Theme.of(context).accentTextTheme!.caption!.backgroundColor!,
textColor: Theme.of(context).primaryTextTheme!.headline6!.color!
),
)
],
@@ -13,13 +13,17 @@ class TimerWidget extends StatefulWidget {
}
class TimerWidgetState extends State<TimerWidget> {
TimerWidgetState();
TimerWidgetState()
: _leftSeconds = 0,
_minutes = 0,
_seconds = 0,
_isExpired = false;
int _leftSeconds;
int _minutes;
int _seconds;
bool _isExpired;
Timer _timer;
Timer? _timer;
@override
void initState() {
@@ -45,7 +49,7 @@ class TimerWidgetState extends State<TimerWidget> {
@override
void dispose() {
if (_timer != null) _timer.cancel();
_timer?.cancel();
super.dispose();
}
+6 -3
View File
@@ -12,6 +12,9 @@ class FAQItem extends StatefulWidget {
}
class FAQItemState extends State<FAQItem> {
FAQItemState()
: isActive = false;
bool isActive;
@override
@@ -23,12 +26,12 @@ class FAQItemState extends State<FAQItem> {
@override
Widget build(BuildContext context) {
final addIcon =
Icon(Icons.add, color: Theme.of(context).primaryTextTheme.title.color);
Icon(Icons.add, color: Theme.of(context).primaryTextTheme!.headline6!.color!);
final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
final icon = isActive ? removeIcon : addIcon;
final color = isActive
? Palette.blueCraiola
: Theme.of(context).primaryTextTheme.title.color;
: Theme.of(context).primaryTextTheme!.headline6!.color!;
return ListTileTheme(
contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
@@ -50,7 +53,7 @@ class FAQItemState extends State<FAQItem> {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
),
))
])
@@ -40,7 +40,7 @@ class IoniaCreateAccountPage extends BasePage {
return Text(
S.current.sign_up,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -78,13 +78,13 @@ class IoniaCreateAccountPage extends BasePage {
builder: (_) => LoadingPrimaryButton(
text: S.of(context).create_account,
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await _authViewModel.createUser(_emailController.text);
},
isLoading: _authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
),
@@ -104,7 +104,7 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan(
text: S.of(context).settings_terms_and_conditions,
style: TextStyle(
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
@@ -116,7 +116,7 @@ class IoniaCreateAccountPage extends BasePage {
TextSpan(
text: S.of(context).privacy_policy,
style: TextStyle(
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
@@ -26,9 +26,6 @@ class IoniaLoginPage extends BasePage {
final IoniaAuthViewModel _authViewModel;
@override
Color get titleColor => Colors.black;
final TextEditingController _emailController;
@override
@@ -36,7 +33,7 @@ class IoniaLoginPage extends BasePage {
return Text(
S.current.login,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -72,13 +69,13 @@ class IoniaLoginPage extends BasePage {
builder: (_) => LoadingPrimaryButton(
text: S.of(context).login,
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await _authViewModel.signIn(_emailController.text);
},
isLoading: _authViewModel.signInState is IoniaCreateStateLoading,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
),
@@ -41,7 +41,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
return Text(
S.current.verification,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -62,7 +62,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -119,7 +119,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
onPressed: () async => await _authViewModel.verifyEmail(_codeController.text),
isDisabled: _authViewModel.otpState is IoniaOtpSendDisabled,
isLoading: _authViewModel.otpState is IoniaOtpValidating,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
),
@@ -17,7 +17,7 @@ class IoniaWelcomePage extends BasePage {
return Text(
S.current.welcome_to_cakepay,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -45,7 +45,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
SizedBox(height: 20),
@@ -55,7 +55,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
],
@@ -66,7 +66,7 @@ class IoniaWelcomePage extends BasePage {
PrimaryButton(
text: S.of(context).create_account,
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaCreateAccountPage),
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
SizedBox(
@@ -78,7 +78,7 @@ class IoniaWelcomePage extends BasePage {
fontSize: 15,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
SizedBox(height: 8),
@@ -1,7 +1,6 @@
import 'dart:ffi';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
@@ -21,7 +20,7 @@ class IoniaAccountCardsPage extends BasePage {
return Text(
S.of(context).cards,
style: textLargeSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -42,7 +41,9 @@ class _IoniaCardTabs extends StatefulWidget {
}
class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProviderStateMixin {
TabController _tabController;
_IoniaCardTabsState();
TabController? _tabController;
@override
void initState() {
@@ -53,7 +54,7 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
@override
void dispose() {
super.dispose();
_tabController.dispose();
_tabController?.dispose();
}
@override
@@ -68,23 +69,23 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
width: 230,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
borderRadius: BorderRadius.circular(
25.0,
),
),
child: Theme(
data: ThemeData(primaryTextTheme: TextTheme(body2: TextStyle(backgroundColor: Colors.transparent))),
data: ThemeData(primaryTextTheme: TextTheme(bodyText1: TextStyle(backgroundColor: Colors.transparent))),
child: TabBar(
controller: _tabController,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(
25.0,
),
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
),
labelColor: Theme.of(context).primaryTextTheme.display4.backgroundColor,
unselectedLabelColor: Theme.of(context).primaryTextTheme.title.color,
labelColor: Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!,
unselectedLabelColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
tabs: [
Tab(
text: S.of(context).active,
@@ -106,6 +107,7 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
_IoniaCardListView(
emptyText: S.of(context).gift_card_balance_note,
merchList: viewModel.activeMechs,
isLoading: viewModel.merchantState is IoniaLoadingMerchantState,
onTap: (giftCard) {
Navigator.pushNamed(
context,
@@ -116,6 +118,7 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
_IoniaCardListView(
emptyText: S.of(context).gift_card_redeemed_note,
merchList: viewModel.redeemedMerchs,
isLoading: viewModel.merchantState is IoniaLoadingMerchantState,
onTap: (giftCard) {
Navigator.pushNamed(
context,
@@ -135,25 +138,35 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
class _IoniaCardListView extends StatelessWidget {
_IoniaCardListView({
Key key,
@required this.emptyText,
@required this.merchList,
@required this.onTap,
Key? key,
required this.emptyText,
required this.merchList,
required this.onTap,
this.isLoading = false,
}) : super(key: key);
final String emptyText;
final List<IoniaGiftCard> merchList;
final void Function(IoniaGiftCard giftCard) onTap;
final bool isLoading;
@override
Widget build(BuildContext context) {
if(isLoading){
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme!.bodyText2!.color!),
),
);
}
return merchList.isEmpty
? Center(
child: Text(
emptyText,
textAlign: TextAlign.center,
style: textSmall(
color: Theme.of(context).primaryTextTheme.overline.color,
color: Theme.of(context).primaryTextTheme!.overline!.color!,
),
),
)
@@ -166,10 +179,11 @@ class _IoniaCardListView extends StatelessWidget {
child: CardItem(
onTap: () => onTap?.call(merchant),
title: merchant.legalName,
backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
discount: 0,
hideBorder: true,
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
subtitleColor: Theme.of(context).hintColor,
subTitle: '',
logoUrl: merchant.logoUrl,
@@ -19,7 +19,7 @@ class IoniaAccountPage extends BasePage {
return Text(
S.current.account,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -124,7 +124,7 @@ class IoniaAccountPage extends BasePage {
//),
SizedBox(height: 40),
Observer(
builder: (_) => IoniaTile(title: S.of(context).email_address, subTitle: ioniaAccountViewModel.email),
builder: (_) => IoniaTile(title: S.of(context).email_address, subTitle: ioniaAccountViewModel.email ?? ''),
),
Divider()
],
@@ -133,7 +133,7 @@ class IoniaAccountPage extends BasePage {
bottomSection: Column(
children: [
PrimaryButton(
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
text: S.of(context).logout,
onPressed: () {
@@ -149,28 +149,26 @@ class IoniaAccountPage extends BasePage {
class _GradiantContainer extends StatelessWidget {
const _GradiantContainer({
Key key,
@required this.content,
this.padding,
this.width,
Key? key,
required this.content,
}) : super(key: key);
final Widget content;
final EdgeInsets padding;
final double width;
@override
Widget build(BuildContext context) {
return Container(
child: content,
width: width,
padding: padding ?? EdgeInsets.all(24),
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).accentColor,
Theme.of(context)
.primaryTextTheme!
.subtitle1!
.decorationColor!,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
@@ -23,7 +23,7 @@ class IoniaActivateDebitCardPage extends BasePage {
return Text(
S.current.debit_card,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -76,7 +76,7 @@ class IoniaActivateDebitCardPage extends BasePage {
},
isLoading: _cardsListViewModel.createCardState is IoniaCreateCardLoading,
text: S.of(context).agree_and_continue,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
);
@@ -1,4 +1,3 @@
import 'dart:ui';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart';
@@ -29,12 +28,12 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
Widget middle(BuildContext context) {
return Text(
ioniaPurchaseViewModel.ioniaMerchant.legalName,
style: textMediumSemiBold(color: Theme.of(context).accentTextTheme.display4.backgroundColor),
style: textMediumSemiBold(color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!),
);
}
@override
Widget trailing(BuildContext context)
Widget? trailing(BuildContext context)
=> ioniaPurchaseViewModel.ioniaMerchant.discount > 0
? DiscountBadge(percentage: ioniaPurchaseViewModel.ioniaMerchant.discount)
: null;
@@ -97,8 +96,8 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
@@ -155,15 +154,16 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
],
),
),
if(ioniaPurchaseViewModel.ioniaMerchant.acceptsTips)
Padding(
padding: const EdgeInsets.all(24.0),
padding: const EdgeInsets.fromLTRB(24.0, 24.0, 0, 24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.of(context).tip,
style: TextStyle(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
fontWeight: FontWeight.w700,
fontSize: 14,
),
@@ -171,9 +171,11 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
SizedBox(height: 4),
Observer(
builder: (_) => TipButtonGroup(
selectedTip: ioniaPurchaseViewModel.selectedTip.percentage,
selectedTip: ioniaPurchaseViewModel.selectedTip!.percentage,
tipsList: ioniaPurchaseViewModel.tips,
onSelect: (value) => ioniaPurchaseViewModel.addTip(value),
amount: ioniaPurchaseViewModel.amount,
merchant: ioniaPurchaseViewModel.ioniaMerchant,
),
)
],
@@ -200,7 +202,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
ioniaPurchaseViewModel.invoiceCommittingState is IsExecutingState,
onPressed: () => purchaseCard(context),
text: S.of(context).purchase_gift_card,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
);
}),
@@ -210,7 +212,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
onTap: () => _showTermsAndCondition(context),
child: Text(S.of(context).settings_terms_and_conditions,
style: textMediumSemiBold(
color: Theme.of(context).primaryTextTheme.body1.color,
color: Theme.of(context).primaryTextTheme!.bodyText2!.color!,
).copyWith(fontSize: 12)),
),
SizedBox(height: 16)
@@ -230,7 +232,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
child: Text(
ioniaPurchaseViewModel.ioniaMerchant.termsAndConditions,
style: textMedium(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
),
),
@@ -268,13 +270,13 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
child: Text(
instruction.header,
style: textLargeSemiBold(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
)),
Text(
instruction.body,
style: textMedium(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
)
];
@@ -287,8 +289,12 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
}
Future<void> _presentSuccessfulInvoiceCreationPopup(BuildContext context) async {
final amount = ioniaPurchaseViewModel.invoice.totalAmount;
final addresses = ioniaPurchaseViewModel.invoice.outAddresses;
if (ioniaPurchaseViewModel.invoice == null) {
return;
}
final amount = ioniaPurchaseViewModel.invoice!.totalAmount;
final addresses = ioniaPurchaseViewModel.invoice!.outAddresses;
await showPopUp<void>(
context: context,
@@ -307,7 +313,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
fontWeight: FontWeight.w400,
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none)),
Text(ioniaPurchaseViewModel.invoice.paymentId,
Text(ioniaPurchaseViewModel.invoice!.paymentId,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
@@ -323,7 +329,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
fontWeight: FontWeight.w400,
color: PaletteDark.pigeonBlue,
decoration: TextDecoration.none)),
Text('$amount ${ioniaPurchaseViewModel.invoice.chain}',
Text('$amount ${ioniaPurchaseViewModel.invoice!.chain}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
@@ -355,7 +361,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
leftActionColor: Color(0xffFF6600),
rightActionColor: Theme.of(context).accentTextTheme.body2.color,
rightActionColor: Theme.of(context).accentTextTheme!.bodyText1!.color!,
actionRightButton: () async {
Navigator.of(context).pop();
await ioniaPurchaseViewModel.commitPaymentInvoice();
@@ -368,17 +374,23 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
class TipButtonGroup extends StatelessWidget {
const TipButtonGroup({
Key key,
@required this.selectedTip,
@required this.onSelect,
@required this.tipsList,
Key? key,
required this.selectedTip,
required this.onSelect,
required this.tipsList,
required this.amount,
required this.merchant,
}) : super(key: key);
final Function(IoniaTip) onSelect;
final double selectedTip;
final List<IoniaTip> tipsList;
final double amount;
final IoniaMerchant merchant;
bool _isSelected(double value) => selectedTip == value;
Set<double> get filter => tipsList.map((e) => e.percentage).toSet();
bool get _isCustomSelected => !filter.contains(selectedTip);
@override
Widget build(BuildContext context) {
@@ -392,10 +404,17 @@ class TipButtonGroup extends StatelessWidget {
return Padding(
padding: EdgeInsets.only(right: 5),
child: TipButton(
isSelected: _isSelected(tip.percentage),
onTap: () => onSelect(tip),
caption: '${tip.percentage.toStringAsFixed(0)}%',
subTitle: '\$${tip.additionalAmount.toStringAsFixed(2)}',
isSelected: tip.isCustom ? _isCustomSelected : _isSelected(tip.percentage),
onTap: () async {
IoniaTip ioniaTip = tip;
if(tip.isCustom){
final customTip = await Navigator.pushNamed(context, Routes.ioniaCustomTipPage, arguments: [amount, merchant, tip]) as IoniaTip?;
ioniaTip = customTip ?? tip;
}
onSelect(ioniaTip);
},
caption: tip.isCustom ? S.of(context).custom : '${tip.percentage.toStringAsFixed(0)}%',
subTitle: tip.isCustom ? null : '\$${tip.additionalAmount.toStringAsFixed(2)}',
));
}));
}
@@ -403,14 +422,14 @@ class TipButtonGroup extends StatelessWidget {
class TipButton extends StatelessWidget {
const TipButton({
@required this.caption,
required this.caption,
required this.onTap,
this.subTitle,
@required this.onTap,
this.isSelected = false,
});
final String caption;
final String subTitle;
final String? subTitle;
final bool isSelected;
final void Function() onTap;
@@ -418,34 +437,34 @@ class TipButton extends StatelessWidget {
Color captionTextColor(BuildContext context) {
if (isDark(context)) {
return Theme.of(context).primaryTextTheme.title.color;
return Theme.of(context).primaryTextTheme!.headline6!.color!;
}
return isSelected
? Theme.of(context).accentTextTheme.title.color
: Theme.of(context).primaryTextTheme.title.color;
? Theme.of(context).accentTextTheme!.headline6!.color!
: Theme.of(context).primaryTextTheme!.headline6!.color!;
}
Color subTitleTextColor(BuildContext context) {
if (isDark(context)) {
return Theme.of(context).primaryTextTheme.title.color;
return Theme.of(context).primaryTextTheme!.headline6!.color!;
}
return isSelected
? Theme.of(context).accentTextTheme.title.color
: Theme.of(context).primaryTextTheme.overline.color;
? Theme.of(context).accentTextTheme!.headline6!.color!
: Theme.of(context).primaryTextTheme!.overline!.color!;
}
Color backgroundColor(BuildContext context) {
Color? backgroundColor(BuildContext context) {
if (isDark(context)) {
return isSelected
? null
: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.01);
: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.01);
}
return isSelected
? null
: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1);
: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1);
}
@override
@@ -463,7 +482,7 @@ class TipButton extends StatelessWidget {
if (subTitle != null) ...[
SizedBox(height: 4),
Text(
subTitle,
subTitle!,
style: textXxSmallSemiBold(
color: subTitleTextColor(context),
),
@@ -478,8 +497,8 @@ class TipButton extends StatelessWidget {
gradient: isSelected
? LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
@@ -1,4 +1,3 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
@@ -8,7 +7,6 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -52,7 +50,7 @@ class IoniaBuyGiftCardPage extends BasePage {
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -71,8 +69,8 @@ class IoniaBuyGiftCardPage extends BasePage {
decoration: BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
@@ -87,22 +85,19 @@ class IoniaBuyGiftCardPage extends BasePage {
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp('[\-|\ ]')),
WhitelistingTextInputFormatter(RegExp(r'^\d+(\.|\,)?\d{0,2}'))],
FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,2}'))],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color,
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
fontWeight: FontWeight.w600,
fontSize: 36,
),
borderColor: Theme.of(context).primaryTextTheme.headline.color,
borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
fontSize: 36,
),
suffixIcon: SizedBox(
width: _width / 6,
),
prefixIcon: Padding(
padding: EdgeInsets.only(
top: 5.0,
@@ -126,13 +121,13 @@ class IoniaBuyGiftCardPage extends BasePage {
Text(
S.of(context).min_amount(merchant.minimumCardPurchase.toStringAsFixed(2)),
style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color,
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
),
),
Text(
S.of(context).max_amount(merchant.maximumCardPurchase.toStringAsFixed(2)),
style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color,
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
),
),
],
@@ -145,9 +140,9 @@ class IoniaBuyGiftCardPage extends BasePage {
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: merchant.legalName,
backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
discount: merchant.discount,
titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
subtitleColor: Theme.of(context).hintColor,
subTitle: merchant.avaibilityStatus,
logoUrl: merchant.logoUrl,
@@ -170,7 +165,7 @@ class IoniaBuyGiftCardPage extends BasePage {
),
text: S.of(context).continue_text,
isDisabled: !ioniaBuyCardViewModel.isEnablePurchase,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
);
@@ -0,0 +1,167 @@
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/generated/i18n.dart';
class IoniaCustomRedeemPage extends BasePage {
IoniaCustomRedeemPage(
this.ioniaCustomRedeemViewModel,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
ioniaCustomRedeemViewModel.updateAmount(_amountController.text);
});
}
final IoniaCustomRedeemViewModel ioniaCustomRedeemViewModel;
@override
String get title => S.current.custom_redeem_amount;
@override
Color get titleColor => Colors.white;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
final TextEditingController _amountController;
final FocusNode _amountFieldFocus;
@override
Widget body(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final giftCard = ioniaCustomRedeemViewModel.giftCard;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFieldFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).backgroundColor,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 25),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 150),
BaseTextFormField(
controller: _amountController,
focusNode: _amountFieldFocus,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
fontWeight: FontWeight.w500,
fontSize: 36,
),
borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
fontSize: 36,
),
suffixIcon: SizedBox(
width: _width / 6,
),
prefixIcon: Padding(
padding: EdgeInsets.only(
top: 5.0,
left: _width / 4,
),
child: Text(
'USD: ',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 36,
),
),
),
),
SizedBox(height: 8),
Observer(builder: (_)=>
!ioniaCustomRedeemViewModel.disableRedeem ?
Center(
child: Text('\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.formattedRemaining} ${S.of(context).remaining}',
style: TextStyle(
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
),),
) : SizedBox.shrink(),
),
SizedBox(height: 24),
],
),
),
Padding(
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: giftCard.legalName,
backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
discount: giftCard.remainingAmount,
isAmount: true,
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
subtitleColor: Theme.of(context).hintColor,
subTitle: S.of(context).online,
logoUrl: giftCard.logoUrl,
),
),
],
),
bottomSection: Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () {
Navigator.of(context).pop(_amountController.text);
},
isDisabled: ioniaCustomRedeemViewModel.disableRedeem,
text: S.of(context).add_custom_redemption,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
),
SizedBox(height: 30),
],
),
),
),
);
}
}
@@ -6,7 +6,7 @@ import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -15,15 +15,15 @@ import 'package:cake_wallet/generated/i18n.dart';
class IoniaCustomTipPage extends BasePage {
IoniaCustomTipPage(
this.ioniaPurchaseViewModel,
this.customTipViewModel,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
// ioniaPurchaseViewModel.onTipChanged(_amountController.text);
customTipViewModel.onTipChanged(_amountController.text);
});
}
final IoniaMerchPurchaseViewModel ioniaPurchaseViewModel;
final IoniaCustomTipViewModel customTipViewModel;
@override
@@ -46,12 +46,12 @@ class IoniaCustomTipPage extends BasePage {
@override
Widget body(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final merchant = ioniaPurchaseViewModel.ioniaMerchant;
final merchant = customTipViewModel.ioniaMerchant;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -70,8 +70,8 @@ class IoniaCustomTipPage extends BasePage {
decoration: BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
@@ -86,11 +86,11 @@ class IoniaCustomTipPage extends BasePage {
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color,
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
fontWeight: FontWeight.w500,
fontSize: 36,
),
borderColor: Theme.of(context).primaryTextTheme.headline.color,
borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
@@ -116,7 +116,7 @@ class IoniaCustomTipPage extends BasePage {
),
SizedBox(height: 8),
Observer(builder: (_) {
if (ioniaPurchaseViewModel.percentage == 0.0) {
if (customTipViewModel.percentage == 0.0) {
return SizedBox.shrink();
}
@@ -125,12 +125,12 @@ class IoniaCustomTipPage extends BasePage {
text: TextSpan(
text: '\$${_amountController.text}',
style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color,
color: Theme.of(context).primaryTextTheme!.headline5!.color!,
),
children: [
TextSpan(text: ' ${S.of(context).is_percentage} '),
TextSpan(text: '${ioniaPurchaseViewModel.percentage}%'),
TextSpan(text: ' ${S.of(context).percentageOf(ioniaPurchaseViewModel.amount.toString())} '),
TextSpan(text: '${customTipViewModel.percentage.toStringAsFixed(2)}%'),
TextSpan(text: ' ${S.of(context).percentageOf(customTipViewModel.amount.toStringAsFixed(2))} '),
],
),
);
@@ -143,9 +143,9 @@ class IoniaCustomTipPage extends BasePage {
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: merchant.legalName,
backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
discount: 0.0,
titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
subtitleColor: Theme.of(context).hintColor,
subTitle: merchant.isOnline ? S.of(context).online : S.of(context).offline,
logoUrl: merchant.logoUrl,
@@ -159,10 +159,10 @@ class IoniaCustomTipPage extends BasePage {
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () {
Navigator.of(context).pop(_amountController.text);
Navigator.of(context).pop(customTipViewModel.customTip);
},
text: S.of(context).add_tip,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
),
@@ -23,7 +23,7 @@ class IoniaDebitCardPage extends BasePage {
return Text(
S.current.debit_card,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@@ -51,7 +51,7 @@ class IoniaDebitCardPage extends BasePage {
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Text(
S.of(context).billing_address_info,
style: textSmall(color: Theme.of(context).textTheme.display1.color),
style: textSmall(color: Theme.of(context).textTheme!.headline4!.color!),
textAlign: TextAlign.center,
),
),
@@ -60,13 +60,13 @@ class IoniaDebitCardPage extends BasePage {
text: S.of(context).order_physical_card,
onPressed: () {},
color: Color(0xffE9F2FC),
textColor: Theme.of(context).textTheme.display2.color,
textColor: Theme.of(context).textTheme!.headline3!.color!,
),
SizedBox(height: 8),
PrimaryButton(
text: S.of(context).add_value,
onPressed: () {},
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
SizedBox(height: 16)
@@ -112,11 +112,11 @@ class IoniaDebitCardPage extends BasePage {
child: RichText(
text: TextSpan(
text: S.of(context).get_a,
style: textMedium(color: Theme.of(context).textTheme.display2.color),
style: textMedium(color: Theme.of(context).textTheme!.headline3!.color!),
children: [
TextSpan(
text: S.of(context).digital_and_physical_card,
style: textMediumBold(color: Theme.of(context).textTheme.display2.color),
style: textMediumBold(color: Theme.of(context).textTheme!.headline3!.color!),
),
TextSpan(
text: S.of(context).get_card_note,
@@ -134,7 +134,7 @@ class IoniaDebitCardPage extends BasePage {
bottomSection: PrimaryButton(
text: S.of(context).activate,
onPressed: () => _showHowToUseCard(context, activate: true),
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
);
@@ -165,7 +165,7 @@ class IoniaDebitCardPage extends BasePage {
Text(
S.of(context).how_to_use_card,
style: textLargeSemiBold(
color: Theme.of(context).textTheme.body1.color,
color: Theme.of(context).textTheme!.bodyText2!.color!,
),
),
SizedBox(height: 24),
@@ -174,7 +174,7 @@ class IoniaDebitCardPage extends BasePage {
child: Text(
S.of(context).signup_for_card_accept_terms,
style: textSmallSemiBold(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
),
),
@@ -195,7 +195,7 @@ class IoniaDebitCardPage extends BasePage {
: Navigator.pop(context),
text: S.of(context).send_got_it,
color: Color.fromRGBO(233, 242, 252, 1),
textColor: Theme.of(context).textTheme.display2.color,
textColor: Theme.of(context).textTheme!.headline3!.color!,
),
SizedBox(height: 21),
],
@@ -223,14 +223,15 @@ class IoniaDebitCardPage extends BasePage {
}
class _IoniaDebitCard extends StatefulWidget {
final bool isCardSample;
final IoniaVirtualCard cardInfo;
const _IoniaDebitCard({
Key key,
this.isCardSample = false,
Key? key,
this.cardInfo,
this.isCardSample = false,
}) : super(key: key);
final bool isCardSample;
final IoniaVirtualCard? cardInfo;
@override
_IoniaDebitCardState createState() => _IoniaDebitCardState();
}
@@ -246,9 +247,9 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
return pan.replaceAllMapped(RegExp(r'.{4}'), (match) => '${match.group(0)} ');
}
String get _getLast4 => widget.isCardSample ? '0000' : widget.cardInfo.pan.substring(widget.cardInfo.pan.length - 5);
String get _getLast4 => widget.isCardSample ? '0000' : widget.cardInfo!.pan.substring(widget.cardInfo!.pan.length - 5);
String get _getSpendLimit => widget.isCardSample ? '10000' : widget.cardInfo.spendLimit.toStringAsFixed(2);
String get _getSpendLimit => widget.isCardSample ? '10000' : widget.cardInfo!.spendLimit.toStringAsFixed(2);
@override
Widget build(BuildContext context) {
@@ -258,8 +259,8 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
colors: [
Theme.of(context).primaryTextTheme.subhead.color,
Theme.of(context).primaryTextTheme.subhead.decorationColor,
Theme.of(context).primaryTextTheme!.subtitle1!.color!,
Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
@@ -289,7 +290,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
),
SizedBox(height: 16),
Text(
_showDetails ? _formatPan(widget.cardInfo.pan) : '**** **** **** $_getLast4',
_showDetails ? _formatPan(widget.cardInfo?.pan ?? '') : '**** **** **** $_getLast4',
style: textMediumSemiBold(),
),
SizedBox(height: 32),
@@ -310,7 +311,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
),
SizedBox(height: 4),
Text(
_showDetails ? widget.cardInfo.cvv : '***',
_showDetails ? widget.cardInfo!.cvv : '***',
style: textMediumSemiBold(),
)
],
@@ -324,7 +325,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
),
SizedBox(height: 4),
Text(
'${widget.cardInfo.expirationMonth ?? S.of(context).mm}/${widget.cardInfo.expirationYear ?? S.of(context).yy}',
'${widget.cardInfo?.expirationMonth ?? S.of(context).mm}/${widget.cardInfo?.expirationYear ?? S.of(context).yy}',
style: textMediumSemiBold(),
)
],
@@ -351,13 +352,14 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
}
class _TitleSubtitleTile extends StatelessWidget {
const _TitleSubtitleTile({
Key? key,
required this.title,
required this.subtitle,
}) : super(key: key);
final String title;
final String subtitle;
const _TitleSubtitleTile({
Key key,
@required this.title,
@required this.subtitle,
}) : super(key: key);
@override
Widget build(BuildContext context) {
@@ -366,12 +368,12 @@ class _TitleSubtitleTile extends StatelessWidget {
children: [
Text(
title,
style: textSmallSemiBold(color: Theme.of(context).textTheme.display2.color),
style: textSmallSemiBold(color: Theme.of(context).textTheme!.headline3!.color!),
),
SizedBox(height: 4),
Text(
subtitle,
style: textSmall(color: Theme.of(context).textTheme.display2.color),
style: textSmall(color: Theme.of(context).textTheme!.headline3!.color!),
),
],
);
@@ -5,7 +5,6 @@ import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_tile.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
@@ -13,9 +12,9 @@ import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart';
import 'package:device_display_brightness/device_display_brightness.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
@@ -26,14 +25,14 @@ class IoniaGiftCardDetailPage extends BasePage {
final IoniaGiftCardDetailsViewModel viewModel;
@override
Widget leading(BuildContext context) {
if (ModalRoute.of(context).isFirst) {
Widget? leading(BuildContext context) {
if (ModalRoute.of(context)!.isFirst) {
return null;
}
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
size: 16,
);
return Padding(
@@ -43,11 +42,15 @@ class IoniaGiftCardDetailPage extends BasePage {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
onPressed: () => onClose(context),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () {
onClose(context);
DeviceDisplayBrightness.setBrightness(viewModel.brightness);
},
child: _backButton),
),
),
@@ -58,12 +61,13 @@ class IoniaGiftCardDetailPage extends BasePage {
Widget middle(BuildContext context) {
return Text(
viewModel.giftCard.legalName,
style: textMediumSemiBold(color: Theme.of(context).accentTextTheme.display4.backgroundColor),
style: textMediumSemiBold(color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!),
);
}
@override
Widget body(BuildContext context) {
viewModel.increaseBrightness();
reaction((_) => viewModel.redeemState, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -110,7 +114,7 @@ class IoniaGiftCardDetailPage extends BasePage {
buildIoniaTile(
context,
title: S.of(context).amount,
subTitle: viewModel.giftCard.remainingAmount.toStringAsFixed(2) ?? '0.00',
subTitle: viewModel.remainingAmount.toStringAsFixed(2) ?? '0.00',
)),
Divider(height: 50),
TextIconButton(
@@ -120,25 +124,49 @@ class IoniaGiftCardDetailPage extends BasePage {
],
),
bottomSection: Padding(
padding: EdgeInsets.only(bottom: 12),
child: Observer(builder: (_) {
if (!viewModel.giftCard.isEmpty) {
return LoadingPrimaryButton(
isLoading: viewModel.redeemState is IsExecutingState,
onPressed: () => viewModel.redeem().then((_){
Navigator.of(context).pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst);
}),
text: S.of(context).mark_as_redeemed,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white);
}
padding: EdgeInsets.only(bottom: 12),
child: Observer(
builder: (_) {
if (!viewModel.giftCard.isEmpty) {
return Column(
children: [
//PrimaryButton(
// onPressed: () async {
// final amount = await Navigator.of(context)
// .pushNamed(Routes.ioniaMoreOptionsPage, arguments: [viewModel.giftCard]) as String;
// if (amount != null) {
// viewModel.updateRemaining(double.parse(amount));
// }
// },
// text: S.of(context).more_options,
// color: Theme.of(context).accentTextTheme!.caption!.color!,
// textColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
//),
//SizedBox(height: 12),
LoadingPrimaryButton(
isLoading: viewModel.redeemState is IsExecutingState,
onPressed: () => viewModel.redeem().then(
(_) {
Navigator.of(context)
.pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst);
},
),
text: S.of(context).mark_as_redeemed,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
),
],
);
}
return Container();
})),
return Container();
},
),
),
);
}
Widget buildIoniaTile(BuildContext context, {@required String title, @required String subTitle}) {
Widget buildIoniaTile(BuildContext context, {required String title, required String subTitle}) {
return IoniaTile(
title: title,
subTitle: subTitle,
@@ -168,13 +196,13 @@ class IoniaGiftCardDetailPage extends BasePage {
child: Text(
instruction.header,
style: textLargeSemiBold(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
)),
Text(
instruction.body,
style: textMedium(
color: Theme.of(context).textTheme.display2.color,
color: Theme.of(context).textTheme!.headline3!.color!,
),
)
];
@@ -1,5 +1,4 @@
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
@@ -12,7 +11,6 @@ import 'package:cake_wallet/utils/debounce.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_filter_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
@@ -27,6 +25,9 @@ class IoniaManageCardsPage extends BasePage {
});
}
});
_cardsListViewModel.getMerchants();
}
final IoniaGiftCardsListViewModel _cardsListViewModel;
@@ -68,7 +69,7 @@ class IoniaManageCardsPage extends BasePage {
Widget leading(BuildContext context) {
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
size: 16,
);
@@ -77,10 +78,11 @@ class IoniaManageCardsPage extends BasePage {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => Navigator.pop(context),
child: _backButton),
),
@@ -92,7 +94,7 @@ class IoniaManageCardsPage extends BasePage {
return Text(
S.of(context).gift_cards,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
);
}
@@ -107,15 +109,27 @@ class IoniaManageCardsPage extends BasePage {
@override
Widget body(BuildContext context) {
final filterIcon = InkWell(
final filterButton = InkWell(
onTap: () async {
final selectedFilters = await showCategoryFilter(context, _cardsListViewModel);
_cardsListViewModel.setSelectedFilter(selectedFilters);
await showCategoryFilter(context);
_cardsListViewModel.getMerchants();
},
child: Image.asset(
'assets/images/filter.png',
color: Theme.of(context).textTheme.caption.decorationColor,
));
child: Container(
width: 32,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
border: Border.all(
color: Colors.white.withOpacity(0.2),
),
borderRadius: BorderRadius.circular(10),
),
child: Image.asset(
'assets/images/filter.png',
color: Theme.of(context).textTheme!.caption!.decorationColor!,
),
)
);
return Padding(
padding: const EdgeInsets.all(14.0),
@@ -131,18 +145,7 @@ class IoniaManageCardsPage extends BasePage {
controller: _searchController,
)),
SizedBox(width: 10),
Container(
width: 32,
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.15),
border: Border.all(
color: Colors.white.withOpacity(0.2),
),
borderRadius: BorderRadius.circular(10),
),
child: filterIcon,
)
filterButton
],
),
),
@@ -157,16 +160,12 @@ class IoniaManageCardsPage extends BasePage {
);
}
Future<List<IoniaCategory>> showCategoryFilter(
BuildContext context,
IoniaGiftCardsListViewModel viewModel,
) async {
return await showPopUp<List<IoniaCategory>>(
Future <void> showCategoryFilter(BuildContext context) async {
return showPopUp<void>(
context: context,
builder: (BuildContext context) {
return IoniaFilterModal(
filterViewModel: getIt.get<IoniaFilterViewModel>(),
selectedCategories: viewModel.selectedFilters,
ioniaGiftCardsListViewModel: _cardsListViewModel,
);
},
);
@@ -175,8 +174,8 @@ class IoniaManageCardsPage extends BasePage {
class IoniaManageCardsPageBody extends StatefulWidget {
const IoniaManageCardsPageBody({
Key key,
@required this.cardsListViewModel,
Key? key,
required this.cardsListViewModel,
}) : super(key: key);
final IoniaGiftCardsListViewModel cardsListViewModel;
@@ -208,7 +207,10 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
@override
Widget build(BuildContext context) {
return Observer(
builder: (_) => Stack(children: [
builder: (_) {
final merchantState = widget.cardsListViewModel.merchantState;
if (merchantState is IoniaLoadedMerchantState) {
return Stack(children: [
ListView.separated(
padding: EdgeInsets.only(left: 2, right: 22),
controller: _scrollController,
@@ -223,9 +225,9 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
},
title: merchant.legalName,
subTitle: merchant.avaibilityStatus,
backgroundColor: Theme.of(context).textTheme.title.backgroundColor,
titleColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
subtitleColor: Theme.of(context).accentTextTheme.display2.backgroundColor,
backgroundColor: Theme.of(context).textTheme!.headline6!.backgroundColor!,
titleColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
subtitleColor: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
discount: merchant.discount,
);
},
@@ -236,20 +238,28 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
thumbHeight: thumbHeight,
rightOffset: 1,
width: 3,
backgroundColor: Theme.of(context).textTheme.caption.decorationColor.withOpacity(0.05),
thumbColor: Theme.of(context).textTheme.caption.decorationColor.withOpacity(0.5),
backgroundColor: Theme.of(context).textTheme!.caption!.decorationColor!.withOpacity(0.05),
thumbColor: Theme.of(context).textTheme!.caption!.decorationColor!.withOpacity(0.5),
fromTop: widget.cardsListViewModel.scrollOffsetFromTop,
)
: Offstage()
]),
]);
}
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme!.bodyText2!.color!),
),
);
}
);
}
}
class _SearchWidget extends StatelessWidget {
const _SearchWidget({
Key key,
@required this.controller,
Key? key,
required this.controller,
}) : super(key: key);
final TextEditingController controller;
@@ -259,12 +269,12 @@ class _SearchWidget extends StatelessWidget {
padding: EdgeInsets.all(8),
child: Image.asset(
'assets/images/mini_search_icon.png',
color: Theme.of(context).textTheme.caption.decorationColor,
color: Theme.of(context).textTheme!.caption!.decorationColor!,
),
);
return TextField(
style: TextStyle(color: Colors.white),
style: TextStyle(color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
controller: controller,
decoration: InputDecoration(
filled: true,
@@ -272,10 +282,10 @@ class _SearchWidget extends StatelessWidget {
top: 10,
left: 10,
),
fillColor: Colors.white.withOpacity(0.15),
fillColor: Theme.of(context).textTheme!.headline6!.backgroundColor!,
hintText: S.of(context).search,
hintStyle: TextStyle(
color: Colors.white.withOpacity(0.6),
color: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
),
alignLabelWithHint: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
@@ -301,24 +311,25 @@ class _SearchWidget extends StatelessWidget {
}
class _TrailingIcon extends StatelessWidget {
final String asset;
final VoidCallback onPressed;
const _TrailingIcon({required this.asset, this.onPressed});
const _TrailingIcon({this.asset, this.onPressed});
final String asset;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.centerRight,
width: 25,
child: FlatButton(
return Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
iconSize: 25,
onPressed: onPressed,
child: Image.asset(
icon: Image.asset(
asset,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
),
);
@@ -0,0 +1,85 @@
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
class IoniaMoreOptionsPage extends BasePage {
IoniaMoreOptionsPage(this.giftCard);
final IoniaGiftCard giftCard;
@override
Widget middle(BuildContext context) {
return Text(
S.current.more_options,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
),
);
}
@override
Widget body(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 10,),
Center(child: Text(S.of(context).choose_from_available_options, style: textMedium(
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),)),
SizedBox(height: 40,),
InkWell(
onTap: () async {
final amount = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String;
if(amount.isNotEmpty){
Navigator.pop(context, amount);
}
},
child: _GradiantContainer(
content: Padding(
padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50),
child: Text(
S.of(context).custom_redeem_amount,
style: textXLargeSemiBold(),
),
),
),
)
],
),
);
}
}
class _GradiantContainer extends StatelessWidget {
const _GradiantContainer({
Key? key,
required this.content
}) : super(key: key);
final Widget content;
@override
Widget build(BuildContext context) {
return Container(
child: content,
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
Theme.of(context).scaffoldBackgroundColor,
Theme.of(context).accentColor,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
),
),
);
}
}
@@ -23,7 +23,7 @@ class IoniaPaymentStatusPage extends BasePage {
S.of(context).generating_gift_card,
textAlign: TextAlign.center,
style: textMediumSemiBold(
color: Theme.of(context).accentTextTheme.display4.backgroundColor));
color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!));
}
@override
@@ -42,7 +42,7 @@ class _IoniaPaymentStatusPageBody extends StatefulWidget {
}
class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPageBody> {
ReactionDisposer _onGiftCardReaction;
ReactionDisposer? _onGiftCardReaction;
@override
void initState() {
@@ -53,7 +53,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
});
}
_onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard giftCard) {
_onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard? giftCard) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context)
.pushReplacementNamed(Routes.ioniaGiftCardDetailPage, arguments: [giftCard]);
@@ -65,8 +65,8 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
@override
void dispose() {
_onGiftCardReaction?.reaction?.dispose();
widget.viewModel.timer.cancel();
_onGiftCardReaction?.reaction.dispose();
widget.viewModel.timer?.cancel();
super.dispose();
}
@@ -90,7 +90,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
Text(
S.of(context).awaiting_payment_confirmation,
style: textLargeSemiBold(
color: Theme.of(context).primaryTextTheme.title.color))
color: Theme.of(context).primaryTextTheme!.headline6!.color!))
]),
SizedBox(height: 40),
Row(children: [
@@ -129,7 +129,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
Text(
S.of(context).gift_card_is_generated,
style: textLargeSemiBold(
color: Theme.of(context).primaryTextTheme.title.color))
color: Theme.of(context).primaryTextTheme!.headline6!.color!))
]));
}
@@ -147,7 +147,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
Text(
S.of(context).generating_gift_card,
style: textLargeSemiBold(
color: Theme.of(context).primaryTextTheme.title.color))]);
color: Theme.of(context).primaryTextTheme!.headline6!.color!))]);
}),
],
),
@@ -159,7 +159,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
child: Text(
S.of(context).proceed_after_one_minute,
style: textMedium(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
).copyWith(fontWeight: FontWeight.w500),
textAlign: TextAlign.center,
)),
@@ -171,15 +171,15 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
Routes.ioniaGiftCardDetailPage,
arguments: [widget.viewModel.giftCard]),
text: S.of(context).open_gift_card,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white);
}
return PrimaryButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.support),
text: S.of(context).contact_support,
color: Theme.of(context).accentTextTheme.caption.color,
textColor: Theme.of(context).primaryTextTheme.title.color);
color: Theme.of(context).accentTextTheme!.caption!.color!,
textColor: Theme.of(context).primaryTextTheme!.headline6!.color!);
})
])
),
@@ -195,14 +195,14 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
Text(
title,
style: textXSmall(
color: Theme.of(context).primaryTextTheme.overline.color,
color: Theme.of(context).primaryTextTheme!.overline!.color!,
),
),
SizedBox(height: 8),
Text(
subtitle,
style: textMedium(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
],
+18 -13
View File
@@ -3,26 +3,30 @@ import 'package:flutter/material.dart';
class CardItem extends StatelessWidget {
CardItem({
@required this.title,
@required this.subTitle,
@required this.backgroundColor,
@required this.titleColor,
@required this.subtitleColor,
required this.title,
required this.subTitle,
required this.backgroundColor,
required this.titleColor,
required this.subtitleColor,
this.hideBorder = false,
this.discount = 0.0,
this.isAmount = false,
this.discountBackground,
this.onTap,
this.logoUrl,
this.discount,
});
final VoidCallback onTap;
final VoidCallback? onTap;
final String title;
final String subTitle;
final String logoUrl;
final String? logoUrl;
final double discount;
final bool isAmount;
final bool hideBorder;
final Color backgroundColor;
final Color titleColor;
final Color subtitleColor;
final AssetImage discountBackground;
final AssetImage? discountBackground;
@override
Widget build(BuildContext context) {
@@ -36,7 +40,7 @@ class CardItem extends StatelessWidget {
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(
border: hideBorder ? Border.symmetric(horizontal: BorderSide.none, vertical: BorderSide.none) : Border.all(
color: Colors.white.withOpacity(0.20),
),
),
@@ -45,11 +49,11 @@ class CardItem extends StatelessWidget {
if (logoUrl != null) ...[
ClipOval(
child: Image.network(
logoUrl,
logoUrl!,
width: 40.0,
height: 40.0,
fit: BoxFit.cover,
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent loadingProgress) {
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
@@ -100,6 +104,7 @@ class CardItem extends StatelessWidget {
padding: const EdgeInsets.only(top: 20.0),
child: DiscountBadge(
percentage: discount,
isAmount: isAmount,
discountBackground: discountBackground,
),
),
@@ -111,7 +116,7 @@ class CardItem extends StatelessWidget {
}
class _PlaceholderContainer extends StatelessWidget {
const _PlaceholderContainer({@required this.text});
const _PlaceholderContainer({required this.text});
final String text;
@@ -5,14 +5,14 @@ import 'package:flutter/material.dart';
class IoniaConfirmModal extends StatelessWidget {
IoniaConfirmModal({
@required this.alertTitle,
@required this.alertContent,
@required this.leftButtonText,
@required this.rightButtonText,
@required this.actionLeftButton,
@required this.actionRightButton,
this.leftActionColor,
this.rightActionColor,
required this.alertTitle,
required this.alertContent,
required this.leftButtonText,
required this.rightButtonText,
required this.actionLeftButton,
required this.actionRightButton,
required this.leftActionColor,
required this.rightActionColor,
this.hideActions = false,
});
@@ -57,7 +57,7 @@ class IoniaConfirmModal extends StatelessWidget {
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
decoration: TextDecoration.none,
),
);
@@ -78,7 +78,7 @@ class IoniaConfirmModal extends StatelessWidget {
borderRadius: BorderRadius.all(Radius.circular(30)),
child: Container(
width: 327,
color: Theme.of(context).accentTextTheme.title.decorationColor,
color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
@@ -109,9 +109,9 @@ class IoniaConfirmModal extends StatelessWidget {
class IoniaActionButton extends StatelessWidget {
const IoniaActionButton({
@required this.buttonText,
@required this.action,
this.backgoundColor,
required this.buttonText,
required this.action,
required this.backgoundColor,
});
final String buttonText;
@@ -127,10 +127,11 @@ class IoniaActionButton extends StatelessWidget {
color: backgoundColor,
child: ButtonTheme(
minWidth: double.infinity,
child: FlatButton(
child: TextButton(
onPressed: action,
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
// FIX-ME: ignored highlightColor and splashColor
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
child: Text(
buttonText,
textAlign: TextAlign.center,
@@ -138,7 +139,7 @@ class IoniaActionButton extends StatelessWidget {
fontSize: 15,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme.body1.backgroundColor,
color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
decoration: TextDecoration.none,
),
)),
@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
class IoniaAlertModal extends StatelessWidget {
const IoniaAlertModal({
Key key,
@required this.title,
@required this.content,
@required this.actionTitle,
Key? key,
required this.title,
required this.content,
required this.actionTitle,
this.heightFactor = 0.4,
this.showCloseButton = true,
}) : super(key: key);
@@ -41,7 +41,7 @@ class IoniaAlertModal extends StatelessWidget {
Text(
title,
style: textLargeSemiBold(
color: Theme.of(context).textTheme.body1.color,
color: Theme.of(context).textTheme!.bodyText2!.color!,
),
),
Container(
@@ -56,8 +56,8 @@ class IoniaAlertModal extends StatelessWidget {
PrimaryButton(
onPressed: () => Navigator.pop(context),
text: actionTitle,
color: Theme.of(context).accentTextTheme.caption.color,
textColor: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).accentTextTheme!.caption!.color!,
textColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
SizedBox(height: 21),
],
@@ -1,22 +1,18 @@
import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart';
import 'package:cake_wallet/view_model/ionia/ionia_filter_view_model.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/palette.dart';
class IoniaFilterModal extends StatelessWidget {
IoniaFilterModal({
@required this.filterViewModel,
@required this.selectedCategories,
}) {
filterViewModel.setSelectedCategories(this.selectedCategories);
IoniaFilterModal({required this.ioniaGiftCardsListViewModel}){
ioniaGiftCardsListViewModel.resetIoniaCategories();
}
final IoniaFilterViewModel filterViewModel;
final List<IoniaCategory> selectedCategories;
final IoniaGiftCardsListViewModel ioniaGiftCardsListViewModel;
@override
Widget build(BuildContext context) {
@@ -48,16 +44,16 @@ class IoniaFilterModal extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.only(left: 24, right: 24),
child: TextField(
onChanged: filterViewModel.onSearchFilter,
onChanged: ioniaGiftCardsListViewModel.onSearchFilter,
style: textMedium(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
decoration: InputDecoration(
filled: true,
prefixIcon: searchIcon,
hintText: S.of(context).search_category,
contentPadding: EdgeInsets.only(bottom: 5),
fillColor: Theme.of(context).textTheme.subhead.backgroundColor,
fillColor: Theme.of(context).textTheme!.subtitle1!.backgroundColor!,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8),
@@ -73,13 +69,13 @@ class IoniaFilterModal extends StatelessWidget {
return ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: filterViewModel.ioniaCategories.length,
itemCount: ioniaGiftCardsListViewModel.ioniaCategories.length,
itemBuilder: (_, index) {
final category = filterViewModel.ioniaCategories[index];
final category = ioniaGiftCardsListViewModel.ioniaCategories[index];
return Padding(
padding: const EdgeInsets.only(left: 24, right: 24, bottom: 24),
child: InkWell(
onTap: () => filterViewModel.selectFilter(category),
onTap: () => ioniaGiftCardsListViewModel.setSelectedFilter(category),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -88,19 +84,19 @@ class IoniaFilterModal extends StatelessWidget {
children: [
Image.asset(
category.iconPath,
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
SizedBox(width: 10),
Text(category.title,
style: textSmall(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
).copyWith(fontWeight: FontWeight.w500)),
],
),
Observer(builder: (_) {
final value = filterViewModel.selectedIndices;
final value = ioniaGiftCardsListViewModel.selectedIndices;
return RoundedCheckbox(
value: value.contains(category.index),
value: value.contains(category),
);
}),
],
@@ -114,13 +110,13 @@ class IoniaFilterModal extends StatelessWidget {
),
),
InkWell(
onTap: () => Navigator.pop(context, filterViewModel.selectedCategories),
onTap: () => Navigator.pop(context),
child: Container(
margin: EdgeInsets.only(bottom: 40),
child: CircleAvatar(
child: Icon(
Icons.close,
color: Colors.black,
color: Palette.darkBlueCraiola,
),
backgroundColor: Colors.white,
),
@@ -3,20 +3,20 @@ import 'package:flutter/material.dart';
class IoniaTile extends StatelessWidget {
const IoniaTile({
Key key,
@required this.title,
@required this.subTitle,
Key? key,
required this.title,
required this.subTitle,
this.onTap,
}) : super(key: key);
final VoidCallback onTap;
final VoidCallback? onTap;
final String title;
final String subTitle;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap(),
onTap: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -26,14 +26,14 @@ class IoniaTile extends StatelessWidget {
Text(
title,
style: textXSmall(
color: Theme.of(context).primaryTextTheme.overline.color,
color: Theme.of(context).primaryTextTheme!.overline!.color!,
),
),
SizedBox(height: 8),
Text(
subTitle,
style: textMediumBold(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
],
@@ -3,7 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class RoundedCheckbox extends StatelessWidget {
RoundedCheckbox({Key key, @required this.value}) : super(key: key);
RoundedCheckbox({Key? key, required this.value}) : super(key: key);
final bool value;
@@ -15,7 +15,7 @@ class RoundedCheckbox extends StatelessWidget {
width: 20.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50.0)),
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
),
child: Icon(
Icons.check,
@@ -2,14 +2,15 @@ import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
class TextIconButton extends StatelessWidget {
final String label;
final VoidCallback onTap;
const TextIconButton({
Key key,
this.label,
Key? key,
required this.label,
this.onTap,
}) : super(key: key);
final String label;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return
@@ -21,12 +22,12 @@ class TextIconButton extends StatelessWidget {
Text(
label,
style: textMediumSemiBold(
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
),
Icon(
Icons.chevron_right_rounded,
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
),
],
),
@@ -10,7 +10,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
class MoneroAccountEditOrCreatePage extends BasePage {
MoneroAccountEditOrCreatePage({@required this.moneroAccountCreationViewModel})
MoneroAccountEditOrCreatePage({required this.moneroAccountCreationViewModel})
: _formKey = GlobalKey<FormState>(),
_textController = TextEditingController() {
_textController.addListener(
@@ -45,7 +45,7 @@ class MoneroAccountEditOrCreatePage extends BasePage {
builder: (_) =>
LoadingPrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
@@ -56,7 +56,7 @@ class MoneroAccountEditOrCreatePage extends BasePage {
text: moneroAccountCreationViewModel.isEdit
? S.of(context).rename
: S.of(context).add,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isLoading: moneroAccountCreationViewModel.state
is IsExecutingState,
@@ -12,12 +12,11 @@ import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
class MoneroAccountListPage extends StatelessWidget {
MoneroAccountListPage({@required this.accountListViewModel}) {
backgroundHeight = 194;
thumbHeight = 72;
isAlwaysShowScrollThumb = false;
controller = ScrollController();
MoneroAccountListPage({required this.accountListViewModel})
: backgroundHeight = 194,
thumbHeight = 72,
isAlwaysShowScrollThumb = false,
controller = ScrollController() {
controller.addListener(() {
final scrollOffsetFromTop = controller.hasClients
? (controller.offset / controller.position.maxScrollExtent * (backgroundHeight - thumbHeight))
@@ -67,7 +66,7 @@ class MoneroAccountListPage extends StatelessWidget {
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
height: 296,
color: Theme.of(context).textTheme.display4.decorationColor,
color: Theme.of(context).textTheme!.headline1!.decorationColor!,
child: Column(
children: <Widget>[
Expanded(
@@ -4,10 +4,10 @@ import 'package:cake_wallet/generated/i18n.dart';
class AccountTile extends StatelessWidget {
AccountTile({
@required this.isCurrent,
@required this.accountName,
@required this.onTap,
@required this.onEdit
required this.isCurrent,
required this.accountName,
required this.onTap,
required this.onEdit
});
final bool isCurrent;
@@ -18,11 +18,11 @@ class AccountTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final color = isCurrent
? Theme.of(context).textTheme.subtitle.decorationColor
: Theme.of(context).textTheme.display4.decorationColor;
? Theme.of(context).textTheme!.subtitle2!.decorationColor!
: Theme.of(context).textTheme!.headline1!.decorationColor!;
final textColor = isCurrent
? Theme.of(context).textTheme.subtitle.color
: Theme.of(context).textTheme.display4.color;
? Theme.of(context).textTheme!.subtitle2!.color!
: Theme.of(context).textTheme!.headline1!.color!;
final Widget cell = GestureDetector(
onTap: onTap,
@@ -43,17 +43,18 @@ class AccountTile extends StatelessWidget {
),
),
);
return Slidable(
key: Key(accountName),
child: cell,
actionPane: SlidableDrawerActionPane(),
secondaryActions: <Widget>[
IconSlideAction(
caption: S.of(context).edit,
color: Colors.blue,
icon: Icons.edit,
onTap: () => onEdit?.call())
]);
// FIX-ME: Splidable
return cell;
// return Slidable(
// key: Key(accountName),
// child: cell,
// actionPane: SlidableDrawerActionPane(),
// secondaryActions: <Widget>[
// IconSlideAction(
// caption: S.of(context).edit,
// color: Colors.blue,
// icon: Icons.edit,
// onTap: () => onEdit?.call())
// ]);
}
}
+50 -48
View File
@@ -49,16 +49,18 @@ class WalletNameForm extends StatefulWidget {
}
class _WalletNameFormState extends State<WalletNameForm> {
_WalletNameFormState(this._walletNewVM);
_WalletNameFormState(this._walletNewVM)
: _formKey = GlobalKey<FormState>(),
_languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
_controller = TextEditingController();
static const aspectRatioImage = 1.22;
final _formKey = GlobalKey<FormState>();
final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
ReactionDisposer _stateReaction;
final GlobalKey<FormState> _formKey;
final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
final WalletNewVM _walletNewVM;
final TextEditingController _controller = TextEditingController();
final TextEditingController _controller;
ReactionDisposer? _stateReaction;
@override
void initState() {
@@ -116,63 +118,63 @@ class _WalletNameFormState extends State<WalletNameForm> {
fontSize: 20.0,
fontWeight: FontWeight.w600,
color:
Theme.of(context).primaryTextTheme.title.color),
Theme.of(context).primaryTextTheme!.headline6!.color!),
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme
.display3
.color),
.accentTextTheme!
.headline2!
.color!),
hintText: S.of(context).wallet_name,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme
.display3
.decorationColor,
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentTextTheme
.display3
.decorationColor,
.accentTextTheme!
.headline2!
.decorationColor!,
width: 1.0),
),
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
_controller.text = rName;
_walletNewVM.name = rName;
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length));
});
},
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
),
width: 34,
height: 34,
child: Image.asset(
'assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme!
.headline4!
.decorationColor!,
),
),
),
),
validator: WalletNameValidator(),
),
IconButton(
onPressed: () async {
final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
_controller.text = rName;
_walletNewVM.name = rName;
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length));
});
},
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
),
width: 34,
height: 34,
child: Image.asset(
'assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor,
),
),
),
],
),
),
@@ -186,7 +188,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
),
),
Padding(
@@ -215,7 +217,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
}
void _confirmForm() {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
if (_walletNewVM.nameExists(_walletNewVM.name)) {
@@ -231,7 +233,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
} else {
_walletNewVM.create(
options: _walletNewVM.hasLanguageSelector
? _languageSelectorKey.currentState.selected
? _languageSelectorKey.currentState!.selected
: null);
}
}
@@ -1,15 +1,6 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/di.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:flushbar/flushbar.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
@@ -18,35 +9,29 @@ import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/wallet_types.g.dart';
class NewWalletTypePage extends BasePage {
NewWalletTypePage(this.walletNewVM, {this.onTypeSelected, this.isNewWallet});
NewWalletTypePage({required this.onTypeSelected});
final void Function(BuildContext, WalletType) onTypeSelected;
final bool isNewWallet;
final WalletNewVM walletNewVM;
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
final walletTypeLightImage =
Image.asset('assets/images/wallet_type_light.png');
@override
String get title =>
isNewWallet ? S.current.new_wallet : S.current.wallet_list_restore_wallet;
String get title => S.current.wallet_list_restore_wallet;
@override
Widget body(BuildContext context) => WalletTypeForm(walletNewVM, isNewWallet,
onTypeSelected: onTypeSelected,
walletImage: currentTheme.type == ThemeType.dark
? walletTypeImage
: walletTypeLightImage);
Widget body(BuildContext context) => WalletTypeForm(
onTypeSelected: onTypeSelected,
walletImage: currentTheme.type == ThemeType.dark
? walletTypeImage
: walletTypeLightImage);
}
class WalletTypeForm extends StatefulWidget {
WalletTypeForm(this.walletNewVM, this.isNewWallet,
{this.onTypeSelected, this.walletImage});
WalletTypeForm({required this.onTypeSelected,
required this.walletImage});
final void Function(BuildContext, WalletType) onTypeSelected;
final WalletNewVM walletNewVM;
final bool isNewWallet;
final Image walletImage;
@override
@@ -54,6 +39,9 @@ class WalletTypeForm extends StatefulWidget {
}
class WalletTypeFormState extends State<WalletTypeForm> {
WalletTypeFormState()
: types = availableWalletTypes;
static const aspectRatioImage = 1.22;
final moneroIcon =
@@ -68,9 +56,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
final havenIcon =
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
WalletType selected;
WalletType? selected;
List<WalletType> types;
Flushbar<void> _progressBar;
@override
void initState() {
@@ -99,7 +86,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme.headline6!.color!),
),
),
...types.map((type) => Padding(
@@ -116,7 +103,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
bottomSection: PrimaryButton(
onPressed: () => onTypeSelected(),
text: S.of(context).seed_language_next,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme.bodyText1!.color!,
textColor: Colors.white,
isDisabled: selected == null,
),
@@ -134,38 +121,15 @@ class WalletTypeFormState extends State<WalletTypeForm> {
case WalletType.haven:
return havenIcon;
default:
return null;
throw Exception('_iconFor: Incorrect Wallet Type. Cannot find icon for Wallet Type: ${type.toString()}');
}
}
Future<void> onTypeSelected() async {
if (!widget.isNewWallet) {
widget.onTypeSelected(context, selected);
return;
if (selected == null) {
throw Exception('Wallet Type is not selected yet.');
}
try {
_changeProcessText(S.of(context).creating_new_wallet);
widget.walletNewVM.type = selected;
await widget.walletNewVM
.create(options: 'English'); // FIXME: Unnamed constant
await _progressBar?.dismiss();
final state = widget.walletNewVM.state;
if (state is ExecutedSuccessfullyState) {
widget.onTypeSelected(context, selected);
}
if (state is FailureState) {
_changeProcessText(
S.of(context).creating_new_wallet_error(state.error));
}
} catch (e) {
_changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
}
}
void _changeProcessText(String text) {
_progressBar = createBar<void>(text, duration: null)..show(context);
widget.onTypeSelected(context, selected!);
}
}
@@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
class SelectButton extends StatelessWidget {
SelectButton({
@required this.image,
@required this.text,
@required this.onTap,
required this.text,
required this.onTap,
this.image,
this.isSelected = false,
});
final Image image;
final Image? image;
final String text;
final bool isSelected;
final VoidCallback onTap;
@@ -17,13 +17,13 @@ class SelectButton extends StatelessWidget {
Widget build(BuildContext context) {
final color = isSelected
? Colors.green
: Theme.of(context).accentTextTheme.caption.color;
: Theme.of(context).accentTextTheme!.caption!.color!;
final textColor = isSelected
? Theme.of(context).accentTextTheme.headline.decorationColor
: Theme.of(context).primaryTextTheme.title.color;
? Theme.of(context).accentTextTheme!.headline5!.decorationColor!
: Theme.of(context).primaryTextTheme!.headline6!.color!;
final arrowColor = isSelected
? Theme.of(context).accentTextTheme.headline.decorationColor
: Theme.of(context).accentTextTheme.subhead.color;
? Theme.of(context).accentTextTheme!.headline5!.decorationColor!
: Theme.of(context).accentTextTheme!.subtitle1!.color!;
final selectArrowImage = Image.asset('assets/images/select_arrow.png',
color: arrowColor);
@@ -187,7 +187,7 @@ class NodeCreateOrEditPage extends BasePage {
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
@@ -205,7 +205,7 @@ class NodeCreateOrEditPage extends BasePage {
padding: EdgeInsets.only(left: 8.0),
child: PrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
@@ -213,7 +213,7 @@ class NodeCreateOrEditPage extends BasePage {
Navigator.of(context).pop();
},
text: S.of(context).save,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: (!nodeCreateOrEditViewModel.isReady)||
(nodeCreateOrEditViewModel
+44 -35
View File
@@ -1,4 +1,5 @@
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/node.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -26,10 +27,10 @@ class NodeListPage extends BasePage {
height: 32,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
color: Theme.of(context).accentTextTheme.caption.color),
color: Theme.of(context).accentTextTheme.caption!.color!),
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
child: TextButton(
onPressed: () async {
await showPopUp<void>(
context: context,
@@ -85,7 +86,7 @@ class NodeListPage extends BasePage {
final node = nodeListViewModel.nodes[index];
final isSelected =
node.keyIndex == nodeListViewModel.currentNode?.keyIndex;
node.keyIndex == nodeListViewModel.currentNode.keyIndex;
final nodeListRow = NodeListRow(
title: node.uriRaw,
isSelected: isSelected,
@@ -116,42 +117,50 @@ class NodeListPage extends BasePage {
});
final dismissibleRow = Slidable(
key: Key('${node.keyIndex}'),
actionPane: SlidableDrawerActionPane(),
child: nodeListRow,
secondaryActions: <Widget>[
IconSlideAction(
caption: S.of(context).delete,
color: Colors.red,
icon: CupertinoIcons.delete,
onTap: () async {
final confirmed = await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).remove_node,
alertContent:
S.of(context).remove_node_message,
rightButtonText: S.of(context).remove,
leftButtonText: S.of(context).cancel,
actionRightButton: () =>
Navigator.pop(context, true),
actionLeftButton: () =>
Navigator.pop(context, false));
}) ??
false;
if (confirmed) {
await nodeListViewModel.delete(node);
}
},
),
]);
key: Key('${node.keyIndex}'),
startActionPane: _actionPane(context, node),
endActionPane: _actionPane(context, node),
child: nodeListRow,
);
return isSelected ? nodeListRow : dismissibleRow;
});
},
),
);
}
ActionPane _actionPane(BuildContext context, Node node) => ActionPane(
motion: const ScrollMotion(),
extentRatio: 0.3,
children: [
SlidableAction(
onPressed: (context) async {
final confirmed = await showPopUp<bool>(
context: context,
builder: (BuildContext context) {
return AlertWithTwoActions(
alertTitle: S.of(context).remove_node,
alertContent:
S.of(context).remove_node_message,
rightButtonText: S.of(context).remove,
leftButtonText: S.of(context).cancel,
actionRightButton: () =>
Navigator.pop(context, true),
actionLeftButton: () =>
Navigator.pop(context, false));
}) ??
false;
if (confirmed) {
await nodeListViewModel.delete(node);
}
},
backgroundColor: Colors.red,
foregroundColor: Colors.white,
icon: CupertinoIcons.delete,
label: S.of(context).delete,
),
],
);
}
@@ -8,10 +8,10 @@ import 'package:flutter/material.dart';
class NodeListRow extends StandardListRow {
NodeListRow(
{@required String title,
@required void Function(BuildContext context) onTap,
@required bool isSelected,
@required this.isAlive})
{required String title,
required void Function(BuildContext context) onTap,
required bool isSelected,
required this.isAlive})
: super(title: title, onTap: onTap, isSelected: isSelected);
final Future<bool> isAlive;
@@ -32,12 +32,12 @@ class NodeListRow extends StandardListRow {
}
class NodeHeaderListRow extends StandardListRow {
NodeHeaderListRow({@required String title, @required void Function(BuildContext context) onTap})
NodeHeaderListRow({required String title, required void Function(BuildContext context) onTap})
: super(title: title, onTap: onTap, isSelected: false);
@override
Widget buildTrailing(BuildContext context) {
return Icon(Icons.add,
color: Theme.of(context).accentTextTheme.subhead.color, size: 24.0);
color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0);
}
}
@@ -48,6 +48,7 @@ class OrderDetailsPageBodyState extends State<OrderDetailsPageBody> {
Widget build(BuildContext context) {
return Observer(builder: (_) {
return SectionStandardList(
context: context,
sectionCount: 1,
itemCounter: (int _) => orderDetailsViewModel.items.length,
itemBuilder: (_, __, index) {
+44 -37
View File
@@ -1,22 +1,21 @@
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:flushbar/flushbar.dart';
import 'package:another_flushbar/flushbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/generated/i18n.dart';
class PinCodeWidget extends StatefulWidget {
PinCodeWidget(
{Key key,
@required this.onFullPin,
@required this.initialPinLength,
this.onChangedPin,
this.onChangedPinLength,
this.hasLengthSwitcher})
{required Key key,
required this.onFullPin,
required this.initialPinLength,
required this.onChangedPin,
required this.hasLengthSwitcher,
this.onChangedPinLength,})
: super(key: key);
final void Function(String pin, PinCodeState state) onFullPin;
final void Function(String pin) onChangedPin;
final void Function(int length) onChangedPinLength;
final void Function(int length)? onChangedPinLength;
final bool hasLengthSwitcher;
final int initialPinLength;
@@ -25,6 +24,11 @@ class PinCodeWidget extends StatefulWidget {
}
class PinCodeState<T extends PinCodeWidget> extends State<T> {
PinCodeState()
: _aspectRatio = 0,
pinLength = 0,
pin = '',
title = '';
static const defaultPinLength = fourPinLength;
static const sixPinLength = 6;
static const fourPinLength = 4;
@@ -35,7 +39,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
String pin;
String title;
double _aspectRatio;
Flushbar<void> _progressBar;
Flushbar<void>? _progressBar;
int currentPinLength() => pin.length;
@@ -72,7 +76,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
void calculateAspectRatio() {
final renderBox =
_gridViewKey.currentContext.findRenderObject() as RenderBox;
_gridViewKey.currentContext!.findRenderObject() as RenderBox;
final cellWidth = renderBox.size.width / 3;
final cellHeight = renderBox.size.height / 4;
@@ -86,12 +90,12 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
void changeProcessText(String text) {
hideProgressText();
_progressBar = createBar<void>(text, duration: null)
..show(_key.currentContext);
..show(_key.currentContext!);
}
void close() {
_progressBar?.dismiss();
Navigator.of(_key.currentContext).pop();
Navigator.of(_key.currentContext!).pop();
}
void hideProgressText() {
@@ -106,11 +110,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
Widget body(BuildContext context) {
final deleteIconImage = Image.asset(
'assets/images/delete_icon.png',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
);
final faceImage = Image.asset(
'assets/images/face.png',
color: Theme.of(context).primaryTextTheme.title.color,
color: Theme.of(context).primaryTextTheme!.headline6!.color!,
);
return Container(
@@ -122,7 +126,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color)),
color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
Spacer(flex: 3),
Container(
width: 180,
@@ -138,11 +142,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isFilled
? Theme.of(context).primaryTextTheme.title.color
? Theme.of(context).primaryTextTheme!.headline6!.color!
: Theme.of(context)
.accentTextTheme
.body1
.color
.accentTextTheme!
.bodyText2!
.color!
.withOpacity(0.25),
));
}),
@@ -150,7 +154,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
),
Spacer(flex: 2),
if (widget.hasLengthSwitcher) ...[
FlatButton(
TextButton(
onPressed: () {
changePinLength(pinLength == PinCodeState.fourPinLength
? PinCodeState.sixPinLength
@@ -162,9 +166,9 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
fontSize: 14.0,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.accentTextTheme
.body1
.decorationColor),
.accentTextTheme!
.bodyText2!
.decorationColor!),
))
],
Spacer(flex: 1),
@@ -186,7 +190,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
child: FlatButton(
child: TextButton(
onPressed: () => null,
// (widget.hasLengthSwitcher ||
// !settingsStore
@@ -213,9 +217,10 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
// });
// }
// },
color: Theme.of(context).backgroundColor,
shape: CircleBorder(),
child: null
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: Container()
// (widget.hasLengthSwitcher ||
// !settingsStore
// .allowBiometricalAuthentication)
@@ -229,10 +234,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
child: FlatButton(
child: TextButton(
onPressed: () => _pop(),
color: Theme.of(context).backgroundColor,
shape: CircleBorder(),
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: deleteIconImage,
),
);
@@ -243,18 +249,19 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
return Container(
margin: EdgeInsets.only(
left: marginLeft, right: marginRight),
child: FlatButton(
child: TextButton(
onPressed: () => _push(index),
color: Theme.of(context).backgroundColor,
shape: CircleBorder(),
// FIX-ME: Style
//color: Theme.of(context).backgroundColor,
//shape: CircleBorder(),
child: Text('$index',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.title
.color)),
.primaryTextTheme!
.headline6!
.color!)),
),
);
}),
@@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
class FullscreenQRPage extends BasePage {
FullscreenQRPage({@required this.qrData, @required this.isLight});
FullscreenQRPage({required this.qrData, required this.isLight});
final bool isLight;
final String qrData;
@@ -23,7 +23,7 @@ class FullscreenQRPage extends BasePage {
Widget leading(BuildContext context) {
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
size: 16,
);
@@ -32,10 +32,11 @@ class FullscreenQRPage extends BasePage {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onClose(context),
child: _backButton,
),
@@ -70,11 +71,11 @@ class FullscreenQRPage extends BasePage {
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
border: Border.all(width: 3, color: Theme.of(context).accentTextTheme.display3.backgroundColor)),
border: Border.all(width: 3, color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!)),
child: QrImage(
data: qrData,
backgroundColor: isLight ? Colors.transparent : Colors.black,
foregroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
),
),
+34 -35
View File
@@ -6,7 +6,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:share_plus/share_plus.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/di.dart';
@@ -22,7 +22,7 @@ import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class ReceivePage extends BasePage {
ReceivePage({this.addressListViewModel}) : _cryptoAmountFocus = FocusNode();
ReceivePage({required this.addressListViewModel}) : _cryptoAmountFocus = FocusNode();
final WalletAddressListViewModel addressListViewModel;
@@ -44,7 +44,7 @@ class ReceivePage extends BasePage {
@override
Widget leading(BuildContext context) {
final _backButton = Icon(Icons.arrow_back_ios,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
size: 16,);
return SizedBox(
@@ -52,10 +52,11 @@ class ReceivePage extends BasePage {
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: () => onClose(context),
child: _backButton),
),
@@ -70,7 +71,7 @@ class ReceivePage extends BasePage {
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
);
}
@@ -89,21 +90,19 @@ class ReceivePage extends BasePage {
Widget trailing(BuildContext context) {
final shareImage =
Image.asset('assets/images/share.png',
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
return SizedBox(
height: 20.0,
width: 20.0,
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
return Material(
color: Colors.transparent,
child: IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
padding: EdgeInsets.all(0),
onPressed: () => Share.text(S.current.share_address,
addressListViewModel.address.address, 'text/plain'),
child: shareImage),
),
iconSize: 25,
onPressed: () => Share.share(addressListViewModel.address.address),
icon: shareImage
)
);
}
@@ -113,8 +112,8 @@ class ReceivePage extends BasePage {
? KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2
.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -156,7 +155,7 @@ class ReceivePage extends BasePage {
Icons.arrow_forward_ios,
size: 14,
color:
Theme.of(context).textTheme.display1.color,
Theme.of(context).textTheme!.headline4!.color!,
));
}
@@ -169,7 +168,7 @@ class ReceivePage extends BasePage {
Icons.add,
size: 20,
color:
Theme.of(context).textTheme.display1.color,
Theme.of(context).textTheme!.headline4!.color!,
));
}
@@ -179,16 +178,16 @@ class ReceivePage extends BasePage {
addressListViewModel.address.address;
final backgroundColor = isCurrent
? Theme.of(context)
.textTheme
.display3
.decorationColor
.textTheme!
.headline2!
.decorationColor!
: Theme.of(context)
.textTheme
.display2
.decorationColor;
.textTheme!
.headline3!
.decorationColor!;
final textColor = isCurrent
? Theme.of(context).textTheme.display3.color
: Theme.of(context).textTheme.display2.color;
? Theme.of(context).textTheme!.headline2!.color!
: Theme.of(context).textTheme!.headline3!.color!;
return AddressCell.fromItem(item,
isCurrent: isCurrent,
@@ -233,9 +232,9 @@ class ReceivePage extends BasePage {
style: TextStyle(
fontSize: 15,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor)),
.accentTextTheme!
.headline3!
.backgroundColor!)),
],
),
);
@@ -4,15 +4,25 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
class AddressCell extends StatelessWidget {
AddressCell(
{required this.address,
required this.name,
required this.isCurrent,
required this.isPrimary,
required this.backgroundColor,
required this.textColor,
this.onTap,
this.onEdit});
factory AddressCell.fromItem(WalletAddressListItem item,
{@required bool isCurrent,
@required Color backgroundColor,
@required Color textColor,
Function(String) onTap,
Function() onEdit}) =>
{required bool isCurrent,
required Color backgroundColor,
required Color textColor,
Function(String)? onTap,
Function()? onEdit}) =>
AddressCell(
address: item.address,
name: item.name,
name: item.name ?? '',
isCurrent: isCurrent,
isPrimary: item.isPrimary,
backgroundColor: backgroundColor,
@@ -20,24 +30,14 @@ class AddressCell extends StatelessWidget {
onTap: onTap,
onEdit: onEdit);
AddressCell(
{@required this.address,
@required this.name,
@required this.isCurrent,
@required this.isPrimary,
@required this.backgroundColor,
@required this.textColor,
this.onTap,
this.onEdit});
final String address;
final String name;
final bool isCurrent;
final bool isPrimary;
final Color backgroundColor;
final Color textColor;
final Function(String) onTap;
final Function() onEdit;
final Function(String)? onTap;
final Function()? onEdit;
String get label {
if (name.isEmpty){
@@ -55,8 +55,9 @@ class AddressCell extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Widget cell = InkWell(
onTap: () => onTap(address),
onTap: () => onTap?.call(address),
child: Container(
width: double.infinity,
color: backgroundColor,
padding: EdgeInsets.only(left: 24, right: 24, top: 28, bottom: 28),
child: Text(
@@ -69,19 +70,25 @@ class AddressCell extends StatelessWidget {
),
),
));
return Container(
color: backgroundColor,
child: Slidable(
key: Key(address),
actionPane: SlidableDrawerActionPane(),
child: cell,
secondaryActions: <Widget>[
IconSlideAction(
caption: S.of(context).edit,
color: Colors.blue,
icon: Icons.edit,
onTap: () => onEdit?.call())
]));
return Slidable(
key: Key(address),
startActionPane: _actionPane(context),
endActionPane: _actionPane(context),
child: cell,
);
}
ActionPane _actionPane(BuildContext context) => ActionPane(
motion: const ScrollMotion(),
extentRatio: 0.3,
children: [
SlidableAction(
onPressed: (_) => onEdit?.call(),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
icon: Icons.edit,
label: S.of(context).edit,
),
],
);
}
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
class HeaderTile extends StatelessWidget {
HeaderTile({
@required this.onTap,
@required this.title,
@required this.icon
required this.onTap,
required this.title,
required this.icon
});
final VoidCallback onTap;
@@ -22,7 +22,7 @@ class HeaderTile extends StatelessWidget {
top: 24,
bottom: 24
),
color: Theme.of(context).textTheme.display2.decorationColor,
color: Theme.of(context).textTheme!.headline3!.decorationColor!,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -32,7 +32,7 @@ class HeaderTile extends StatelessWidget {
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.display2.color
color: Theme.of(context).textTheme!.headline3!.color!
),
),
Container(
@@ -40,7 +40,7 @@ class HeaderTile extends StatelessWidget {
width: 32,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).textTheme.display1.decorationColor
color: Theme.of(context).textTheme!.headline4!.decorationColor!
),
child: icon,
)
@@ -4,16 +4,16 @@ import 'package:cake_wallet/src/screens/receive/widgets/qr_painter.dart';
class QrImage extends StatelessWidget {
QrImage({
@required String data,
required String data,
this.size = 100.0,
this.backgroundColor,
Color foregroundColor = Colors.black,
int version = 7,
int version = 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ???
int errorCorrectionLevel = QrErrorCorrectLevel.L,
}) : _painter = QrPainter(data, foregroundColor, version, errorCorrectionLevel);
final QrPainter _painter;
final Color backgroundColor;
final Color? backgroundColor;
final double size;
@override
@@ -7,11 +7,10 @@ class QrPainter extends CustomPainter {
this.color,
this.version,
this.errorCorrectionLevel,
) : this._qr = QrCode(version, errorCorrectionLevel) {
) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) {
_p.color = this.color;
_qr.addData(data);
_qr.make();
_qrImage = QrImage(_qr);
}
final int version;
@@ -20,13 +19,14 @@ class QrPainter extends CustomPainter {
final QrCode _qr;
final _p = Paint()..style = PaintingStyle.fill;
late QrImage _qrImage;
@override
void paint(Canvas canvas, Size size) {
final squareSize = size.shortestSide / _qr.moduleCount;
for (int x = 0; x < _qr.moduleCount; x++) {
for (int y = 0; y < _qr.moduleCount; y++) {
if (_qr.isDark(y, x)) {
if (_qrImage.isDark(y, x)) {
final squareRect = Rect.fromLTWH(
x * squareSize, y * squareSize, squareSize, squareSize);
canvas.drawRect(squareRect, _p);
+15 -14
View File
@@ -13,27 +13,27 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
class QRWidget extends StatelessWidget {
QRWidget(
{@required this.addressListViewModel,
{required this.addressListViewModel,
required this.isLight,
this.isAmountFieldShow = false,
this.amountTextFieldFocusNode,
this.isLight})
this.amountTextFieldFocusNode})
: amountController = TextEditingController(),
_formKey = GlobalKey<FormState>() {
amountController.addListener(() => addressListViewModel.amount =
_formKey.currentState.validate() ? amountController.text : '');
_formKey.currentState!.validate() ? amountController.text : '');
}
final WalletAddressListViewModel addressListViewModel;
final bool isAmountFieldShow;
final TextEditingController amountController;
final FocusNode amountTextFieldFocusNode;
final FocusNode? amountTextFieldFocusNode;
final GlobalKey<FormState> _formKey;
final bool isLight;
@override
Widget build(BuildContext context) {
final copyImage = Image.asset('assets/images/copy_address.png',
color: Theme.of(context).textTheme.subhead.decorationColor);
color: Theme.of(context).textTheme!.subtitle1!.decorationColor!);
return Column(
mainAxisSize: MainAxisSize.min,
@@ -49,7 +49,7 @@ class QRWidget extends StatelessWidget {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
),
),
Row(
@@ -86,13 +86,13 @@ class QRWidget extends StatelessWidget {
decoration: BoxDecoration(
border: Border.all(
width: 3,
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
),
child: QrImage(
data: addressListViewModel.uri.toString(),
backgroundColor: isLight ? Colors.transparent : Colors.black,
foregroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
),
),
),
@@ -118,13 +118,14 @@ class QRWidget extends StatelessWidget {
focusNode: amountTextFieldFocusNode,
controller: amountController,
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [BlacklistingTextInputFormatter(RegExp('[\\-|\\ ]'))],
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
textAlign: TextAlign.center,
hintText: S.of(context).receive_amount,
textColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
borderColor: Theme.of(context).textTheme.headline.decorationColor,
textColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
borderColor: Theme.of(context).textTheme!.headline5!.decorationColor!,
validator: AmountValidator(type: addressListViewModel.type, isAutovalidate: true),
autovalidate: true,
// FIX-ME: Check does it equal to autovalidate: true,
autovalidateMode: AutovalidateMode.always,
placeholderTextStyle: TextStyle(
color: Theme.of(context).hoverColor,
fontSize: 18,
@@ -156,7 +157,7 @@ class QRWidget extends StatelessWidget {
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
),
),
Padding(
+2 -2
View File
@@ -32,10 +32,10 @@ class RescanPage extends BasePage {
onPressed: () async {
await _rescanViewModel.rescanCurrentWallet(
restoreHeight:
_blockchainHeightWidgetKey.currentState.height);
_blockchainHeightWidgetKey.currentState!.height);
Navigator.of(context).pop();
},
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: !_rescanViewModel.isButtonEnabled,
))
@@ -71,7 +71,7 @@ class RestoreFromBackupPage extends BasePage {
restoreFromBackupViewModel.state is IsExecutingState,
onPressed: () => onImportHandler(context),
text: S.of(context).import,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white);
}))
])),
@@ -85,7 +85,7 @@ class RestoreFromBackupPage extends BasePage {
return;
}
restoreFromBackupViewModel.filePath = result.files.first.path;
restoreFromBackupViewModel.filePath = result!.files.first.path!;
}
Future<void> onImportHandler(BuildContext context) async {
@@ -15,7 +15,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
class RestoreWalletFromKeysPage extends BasePage {
RestoreWalletFromKeysPage(
{@required this.walletRestorationFromKeysVM});
{required this.walletRestorationFromKeysVM});
final WalletRestorationFromKeysVM walletRestorationFromKeysVM;
@@ -190,7 +190,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
bottomSection: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
/*walletRestorationStore.restoreFromKeys(
name: _nameController.text,
language: seedLanguageStore.selectedSeedLanguage,
@@ -201,7 +201,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
}
},
text: S.of(context).restore_recover,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
//isDisabled: walletRestorationStore.disabledState,
);
@@ -15,7 +15,7 @@ import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
class RestoreWalletFromSeedDetailsPage extends BasePage {
RestoreWalletFromSeedDetailsPage(
{@required this.walletRestorationFromSeedVM});
{required this.walletRestorationFromSeedVM});
final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
@@ -28,7 +28,7 @@ class RestoreWalletFromSeedDetailsPage extends BasePage {
}
class RestoreFromSeedDetailsForm extends StatefulWidget {
RestoreFromSeedDetailsForm({@required this.walletRestorationFromSeedVM});
RestoreFromSeedDetailsForm({required this.walletRestorationFromSeedVM});
final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
@@ -42,7 +42,7 @@ class _RestoreFromSeedDetailsFormState
final _formKey = GlobalKey<FormState>();
final _blockchainHeightKey = GlobalKey<BlockchainHeightState>();
final _nameController = TextEditingController();
ReactionDisposer _stateReaction;
ReactionDisposer? _stateReaction;
@override
void initState() {
@@ -75,7 +75,7 @@ class _RestoreFromSeedDetailsFormState
@override
void dispose() {
_nameController.dispose();
_stateReaction.reaction.dispose();
_stateReaction?.reaction.dispose();
super.dispose();
}
@@ -127,14 +127,14 @@ class _RestoreFromSeedDetailsFormState
bottomSection: Observer(builder: (_) {
return LoadingPrimaryButton(
onPressed: () {
if (_formKey.currentState.validate()) {
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
widget.walletRestorationFromSeedVM.create();
}
},
isLoading:
widget.walletRestorationFromSeedVM.state is IsExecutingState,
text: S.of(context).restore_recover,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: _nameController.text.isNotEmpty,
);
@@ -19,7 +19,8 @@ import 'package:cake_wallet/core/mnemonic_length.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class RestoreWalletFromSeedPage extends BasePage {
RestoreWalletFromSeedPage({@required this.type});
RestoreWalletFromSeedPage({required this.type})
: _pages = <Widget>[];
final WalletType type;
final String language = 'en';
@@ -51,9 +52,9 @@ class RestoreWalletFromSeedPage extends BasePage {
void _setPages(BuildContext context) {
_pages = <Widget>[
WalletRestoreFromSeedForm(),
// FIX-ME: Added args (displayBlockHeightSelector: true, displayLanguageSelector: true, type: type)
WalletRestoreFromSeedForm(displayBlockHeightSelector: true, displayLanguageSelector: true, type: type),
RestoreFromKeysFrom(),
// Container(color: Colors.yellow)
];
}
@@ -87,7 +88,7 @@ class RestoreWalletFromSeedPage extends BasePage {
text: S.of(context).restore_recover,
isDisabled: false,
onPressed: () => null,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white)),
]);
@@ -105,7 +106,7 @@ class RestoreWalletFromSeedPage extends BasePage {
// text: S.of(context).restore_next,
// isDisabled: false,
// onPressed: () => null,
// color: Theme.of(context).accentTextTheme.body2.color,
// color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
// textColor: Colors.white)
// ]),
// contentPadding: EdgeInsets.only(bottom: 24),
@@ -135,12 +136,16 @@ class RestoreWalletFromSeedPage extends BasePage {
class RestoreFromSeedForm extends StatefulWidget {
RestoreFromSeedForm(
{Key key, this.type, this.language, this.leading, this.middle})
{Key? key,
required this.type,
this.language,
this.leading,
this.middle})
: super(key: key);
final WalletType type;
final String language;
final Widget leading;
final Widget middle;
final String? language;
final Widget? leading;
final Widget? middle;
@override
_RestoreFromSeedFormState createState() => _RestoreFromSeedFormState();
@@ -163,6 +168,8 @@ class _RestoreFromSeedFormState extends State<RestoreFromSeedForm> {
// height: 300,
child: Column(children: [
SeedWidget(
type: widget.type,
language: widget.language ?? '',
// key: _seedKey,
// maxLength: mnemonicLength(widget.type),
// onMnemonicChange: (seed) => null,
@@ -6,9 +6,9 @@ import 'package:cake_wallet/generated/i18n.dart';
class RestoreWalletOptionsPage extends BasePage {
RestoreWalletOptionsPage(
{@required this.type,
@required this.onRestoreFromSeed,
@required this.onRestoreFromKeys});
{required this.type,
required this.onRestoreFromSeed,
required this.onRestoreFromKeys});
final WalletType type;
final Function(BuildContext context) onRestoreFromSeed;
@@ -12,10 +12,13 @@ import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
class WalletRestoreFromKeysFrom extends StatefulWidget {
WalletRestoreFromKeysFrom({Key key, this.onHeightOrDateEntered, this.walletRestoreViewModel})
WalletRestoreFromKeysFrom({
required this.walletRestoreViewModel,
Key? key,
this.onHeightOrDateEntered,})
: super(key: key);
final Function(bool) onHeightOrDateEntered;
final Function(bool)? onHeightOrDateEntered;
final WalletRestoreViewModel walletRestoreViewModel;
@override
@@ -64,33 +67,33 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
controller: nameTextEditingController,
hintText: S.of(context).wallet_name,
validator: WalletNameValidator(),
),
IconButton(
onPressed: () async {
final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus();
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
nameTextEditingController.text = rName;
nameTextEditingController.selection =
TextSelection.fromPosition(TextPosition(
offset: nameTextEditingController.text.length));
});
},
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
),
width: 34,
height: 34,
child: Image.asset(
'assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor,
setState(() {
nameTextEditingController.text = rName;
nameTextEditingController.selection =
TextSelection.fromPosition(TextPosition(
offset: nameTextEditingController.text.length));
});
},
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
),
width: 34,
height: 34,
child: Image.asset(
'assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme!
.headline4!
.decorationColor!,
),
),
),
),
@@ -14,10 +14,10 @@ import 'package:cake_wallet/core/wallet_name_validator.dart';
class WalletRestoreFromSeedForm extends StatefulWidget {
WalletRestoreFromSeedForm(
{Key key,
@required this.displayLanguageSelector,
@required this.displayBlockHeightSelector,
@required this.type,
{Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.type,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
@@ -27,10 +27,10 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
final WalletType type;
final bool displayLanguageSelector;
final bool displayBlockHeightSelector;
final FocusNode blockHeightFocusNode;
final Function(bool) onHeightOrDateEntered;
final void Function(String) onSeedChange;
final void Function(String) onLanguageChange;
final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered;
final void Function(String)? onSeedChange;
final void Function(String)? onLanguageChange;
@override
WalletRestoreFromSeedFormState createState() =>
@@ -71,16 +71,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
BaseTextFormField(
controller: nameTextEditingController,
hintText: S.of(context).wallet_name,
validator: WalletNameValidator(),
),
Container(
width: 34,
height: 34,
margin: const EdgeInsets.only(bottom: 15, left: 13),
child: InkWell(
onTap: () async {
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
nameTextEditingController.text = rName;
nameTextEditingController.selection =
@@ -88,17 +83,24 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
offset: nameTextEditingController.text.length));
});
},
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Theme.of(context).hintColor,
borderRadius: BorderRadius.all(Radius.circular(6))),
child: Image.asset('assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme
.display1
.decorationColor)),
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
),
width: 34,
height: 34,
child: Image.asset(
'assets/images/refresh_icon.png',
color: Theme.of(context)
.primaryTextTheme!
.headline4!
.decorationColor!,
),
),
),
validator: WalletNameValidator(),
),
],
)),
@@ -142,7 +144,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
void _changeLanguage(String language) {
setState(() {
this.language = language;
seedWidgetStateKey.currentState.changeSeedLanguage(language);
seedWidgetStateKey.currentState!.changeSeedLanguage(language);
_setLanguageLabel(language);
widget.onLanguageChange?.call(language);
});
@@ -38,7 +38,7 @@ class WalletRestorePage extends BasePage {
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
displayLanguageSelector:
walletRestoreViewModel.hasSeedLanguageSelector,
type: walletRestoreViewModel.type,
type: walletRestoreViewModel.type!,
key: walletRestoreFromSeedFormKey,
blockHeightFocusNode: _blockHeightFocusNode,
onHeightOrDateEntered: (value) {
@@ -49,10 +49,7 @@ class WalletRestorePage extends BasePage {
onSeedChange: (String seed) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState
.blockchainHeightKey
.currentState
.restoreHeightController
.currentState!.blockchainHeightKey.currentState!.restoreHeightController
.text
.isNotEmpty;
if (hasHeight) {
@@ -65,10 +62,7 @@ class WalletRestorePage extends BasePage {
onLanguageChange: (_) {
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
final hasHeight = walletRestoreFromSeedFormKey
.currentState
.blockchainHeightKey
.currentState
.restoreHeightController
.currentState!.blockchainHeightKey.currentState!.restoreHeightController
.text
.isNotEmpty;
@@ -104,7 +98,7 @@ class WalletRestorePage extends BasePage {
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor ??
Theme.of(context).primaryTextTheme.title.color),
Theme.of(context).primaryTextTheme!.headline6!.color!),
));
final WalletRestoreViewModel walletRestoreViewModel;
@@ -135,24 +129,24 @@ class WalletRestorePage extends BasePage {
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
walletRestoreViewModel.isButtonEnabled = false;
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
.restoreHeightController.text = '';
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
.dateController.text = '';
walletRestoreFromSeedFormKey.currentState.nameTextEditingController.text = '';
walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState
!.restoreHeightController.text = '';
walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState
!.dateController.text = '';
walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text = '';
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
.restoreHeightController.text = '';
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
.dateController.text = '';
walletRestoreFromKeysFormKey.currentState.nameTextEditingController.text = '';
walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState
!.restoreHeightController.text = '';
walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState
!.dateController.text = '';
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text = '';
});
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).accentTextTheme.body2
.backgroundColor,
keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
@@ -196,9 +190,9 @@ class WalletRestorePage extends BasePage {
onPressed: _confirmForm,
text: S.of(context).restore_recover,
color:
Theme.of(context).accentTextTheme.subtitle.decorationColor,
Theme.of(context).accentTextTheme!.subtitle2!.decorationColor!,
textColor:
Theme.of(context).accentTextTheme.headline.decorationColor,
Theme.of(context).accentTextTheme!.headline5!.decorationColor!,
isLoading: walletRestoreViewModel.state is IsExecutingState,
isDisabled: !walletRestoreViewModel.isButtonEnabled,
);
@@ -210,9 +204,9 @@ class WalletRestorePage extends BasePage {
bool _isValidSeed() {
final seedWords = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
!.seedWidgetStateKey
.currentState
.text
!.text
.split(' ');
if ((walletRestoreViewModel.type == WalletType.monero || walletRestoreViewModel.type == WalletType.haven) &&
@@ -229,9 +223,9 @@ class WalletRestorePage extends BasePage {
final words = walletRestoreFromSeedFormKey
.currentState
.seedWidgetStateKey
!.seedWidgetStateKey
.currentState
.words
!.words
.toSet();
return seedWords
.toSet()
@@ -245,24 +239,24 @@ class WalletRestorePage extends BasePage {
if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
credentials['seed'] = walletRestoreFromSeedFormKey
.currentState.seedWidgetStateKey.currentState.text;
.currentState!.seedWidgetStateKey.currentState!.text;
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
credentials['height'] = walletRestoreFromSeedFormKey
.currentState.blockchainHeightKey.currentState.height;
.currentState!.blockchainHeightKey.currentState!.height;
}
credentials['name'] = walletRestoreFromSeedFormKey.currentState.nameTextEditingController.text;
credentials['name'] = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
} else {
credentials['address'] =
walletRestoreFromKeysFormKey.currentState.addressController.text;
walletRestoreFromKeysFormKey.currentState!.addressController.text;
credentials['viewKey'] =
walletRestoreFromKeysFormKey.currentState.viewKeyController.text;
walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
credentials['spendKey'] =
walletRestoreFromKeysFormKey.currentState.spendKeyController.text;
walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
credentials['height'] = walletRestoreFromKeysFormKey
.currentState.blockchainHeightKey.currentState.height;
credentials['name'] = walletRestoreFromKeysFormKey.currentState.nameTextEditingController.text;
.currentState!.blockchainHeightKey.currentState!.height;
credentials['name'] = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
}
return credentials;
@@ -274,21 +268,21 @@ class WalletRestorePage extends BasePage {
: walletRestoreFromKeysFormKey.currentContext;
final formKey = walletRestoreViewModel.mode == WalletRestoreMode.seed
? walletRestoreFromSeedFormKey.currentState.formKey
: walletRestoreFromKeysFormKey.currentState.formKey;
? walletRestoreFromSeedFormKey.currentState!.formKey
: walletRestoreFromKeysFormKey.currentState!.formKey;
final name = walletRestoreViewModel.mode == WalletRestoreMode.seed
? walletRestoreFromSeedFormKey
.currentState.nameTextEditingController.value.text
.currentState!.nameTextEditingController.value.text
: walletRestoreFromKeysFormKey
.currentState.nameTextEditingController.value.text;
.currentState!.nameTextEditingController.value.text;
if (!formKey.currentState.validate()) {
if (!formKey.currentState!.validate()) {
return;
}
if (walletRestoreViewModel.nameExists(name)) {
showNameExistsAlert(formContext);
showNameExistsAlert(formContext!);
return;
}
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
class RestoreButton extends StatelessWidget {
const RestoreButton({
@required this.onPressed,
@required this.image,
@required this.title,
@required this.description});
required this.onPressed,
required this.image,
required this.title,
required this.description});
final VoidCallback onPressed;
final Image image;
@@ -24,7 +24,7 @@ class RestoreButton extends StatelessWidget {
alignment: Alignment.topLeft,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12)),
color: Theme.of(context).accentTextTheme.caption.color,
color: Theme.of(context).accentTextTheme!.caption!.color!,
),
child: Row(
mainAxisSize: MainAxisSize.max,
@@ -45,7 +45,7 @@ class RestoreButton extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color
color: Theme.of(context).primaryTextTheme!.headline6!.color!
),
),
Padding(
@@ -55,7 +55,7 @@ class RestoreButton extends StatelessWidget {
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context).primaryTextTheme.overline.color
color: Theme.of(context).primaryTextTheme!.overline!.color!
),
),
)
+11 -6
View File
@@ -8,11 +8,11 @@ import 'package:cake_wallet/entities/qr_scanner.dart';
class Root extends StatefulWidget {
Root(
{Key key,
this.authenticationStore,
this.appStore,
this.child,
this.navigatorKey})
{required Key key,
required this.authenticationStore,
required this.appStore,
required this.child,
required this.navigatorKey})
: super(key: key);
final AuthenticationStore authenticationStore;
@@ -25,6 +25,11 @@ class Root extends StatefulWidget {
}
class RootState extends State<Root> with WidgetsBindingObserver {
RootState()
: _isInactiveController = StreamController<bool>.broadcast(),
_isInactive = false,
_postFrameCallback = false;
Stream<bool> get isInactive => _isInactiveController.stream;
StreamController<bool> _isInactiveController;
bool _isInactive;
@@ -63,7 +68,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
if (_isInactive && !_postFrameCallback) {
_postFrameCallback = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.navigatorKey.currentState.pushNamed(Routes.unlock,
widget.navigatorKey.currentState?.pushNamed(Routes.unlock,
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
if (!isAuthenticatedSuccessfully) {
return;
+6 -6
View File
@@ -21,10 +21,10 @@ class PreSeedPage extends BasePage {
final int wordsCount;
@override
Widget leading(BuildContext context) => null;
Widget? leading(BuildContext context) => null;
@override
String get title => S.current.pre_seed_title;
String? get title => S.current.pre_seed_title;
@override
Widget body(BuildContext context) {
@@ -57,16 +57,16 @@ class PreSeedPage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
.primaryTextTheme!
.caption!
.color!),
),
),
PrimaryButton(
onPressed: () => Navigator.of(context)
.popAndPushNamed(Routes.seed, arguments: true),
text: S.of(context).pre_seed_button_text,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white)
],
))
+18 -20
View File
@@ -6,7 +6,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:esys_flutter_share/esys_flutter_share.dart';
import 'package:share_plus/share_plus.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
@@ -14,7 +14,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
class WalletSeedPage extends BasePage {
WalletSeedPage(this.walletSeedViewModel, {@required this.isNewWalletCreated});
WalletSeedPage(this.walletSeedViewModel, {required this.isNewWalletCreated});
final imageLight = Image.asset('assets/images/crypto_lock_light.png');
final imageDark = Image.asset('assets/images/crypto_lock.png');
@@ -52,7 +52,7 @@ class WalletSeedPage extends BasePage {
}
@override
Widget leading(BuildContext context) =>
Widget? leading(BuildContext context) =>
isNewWalletCreated ? Offstage() : super.leading(context);
@override
@@ -67,7 +67,7 @@ class WalletSeedPage extends BasePage {
margin: EdgeInsets.only(left: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
color: Theme.of(context).accentTextTheme.caption.color),
color: Theme.of(context).accentTextTheme!.caption!.color!),
child: Text(
S.of(context).seed_language_next,
style: TextStyle(
@@ -110,9 +110,9 @@ class WalletSeedPage extends BasePage {
fontSize: 20,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
.primaryTextTheme!
.headline6!
.color!),
),
Padding(
padding:
@@ -124,9 +124,9 @@ class WalletSeedPage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.caption
.color),
.primaryTextTheme!
.caption!
.color!),
),
)
],
@@ -146,9 +146,9 @@ class WalletSeedPage extends BasePage {
fontSize: 12,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.overline
.color),
.primaryTextTheme!
.overline!
.color!),
),
)
: Offstage(),
@@ -159,10 +159,8 @@ class WalletSeedPage extends BasePage {
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: PrimaryButton(
onPressed: () => Share.text(
S.of(context).seed_share,
walletSeedViewModel.seed,
'text/plain'),
onPressed: () =>
Share.share(walletSeedViewModel.seed),
text: S.of(context).save,
color: Colors.green,
textColor: Colors.white),
@@ -180,9 +178,9 @@ class WalletSeedPage extends BasePage {
},
text: S.of(context).copy,
color: Theme.of(context)
.accentTextTheme
.body2
.color,
.accentTextTheme!
.bodyText2!
.color!,
textColor: Colors.white)),
))
],
@@ -10,7 +10,7 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
class SeedLanguage extends BasePage {
SeedLanguage({this.onConfirm});
SeedLanguage({required this.onConfirm});
final Function(BuildContext, String) onConfirm;
@@ -30,7 +30,7 @@ class SeedLanguage extends BasePage {
}
class SeedLanguageForm extends StatefulWidget {
SeedLanguageForm({this.onConfirm, this.walletImage});
SeedLanguageForm({required this.onConfirm, required this.walletImage});
final Function(BuildContext, String) onConfirm;
final Image walletImage;
@@ -66,7 +66,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryTextTheme.title.color),
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
),
),
Padding(
@@ -82,7 +82,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
builder: (context) {
return PrimaryButton(
onPressed: () => widget.onConfirm(
context, _languageSelectorKey.currentState.selected),
context, _languageSelectorKey.currentState!.selected),
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white);
@@ -50,7 +50,9 @@ const List<String> seedLanguages = [
enum Places { topLeft, topRight, bottomLeft, bottomRight, inside }
class SeedLanguagePicker extends StatefulWidget {
SeedLanguagePicker({Key key, this.selected = defaultSeedLanguage})
SeedLanguagePicker({
Key? key,
this.selected = defaultSeedLanguage})
: super(key: key);
final String selected;
@@ -61,7 +63,7 @@ class SeedLanguagePicker extends StatefulWidget {
}
class SeedLanguagePickerState extends State<SeedLanguagePicker> {
SeedLanguagePickerState({this.selected});
SeedLanguagePickerState({required this.selected});
final closeButton = Image.asset('assets/images/close.png');
String selected;
@@ -96,7 +98,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
height: 300,
width: 300,
color:
Theme.of(context).accentTextTheme.title.backgroundColor,
Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
child: GridView.count(
padding: EdgeInsets.all(0),
shrinkWrap: true,
@@ -111,7 +113,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
isCurrent: false,
image: null,
text: '',
onTap: null);
onTap: () {});
}
final code = languageCodes[index];
@@ -140,16 +142,16 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
}
Widget gridTile(
{@required bool isCurrent,
@required Image image,
@required String text,
@required VoidCallback onTap}) {
{required bool isCurrent,
required String text,
required VoidCallback onTap,
Image? image}) {
final color = isCurrent
? Theme.of(context).textTheme.body2.color
: Theme.of(context).accentTextTheme.title.color;
? Theme.of(context).textTheme!.bodyText1!.color!
: Theme.of(context).accentTextTheme!.headline6!.color!;
final textColor = isCurrent
? Palette.blueCraiola
: Theme.of(context).primaryTextTheme.title.color;
: Theme.of(context).primaryTextTheme!.headline6!.color!;
return GestureDetector(
onTap: onTap,
+44 -36
View File
@@ -30,8 +30,8 @@ import 'package:cw_core/crypto_currency.dart';
class SendPage extends BasePage {
SendPage({
@required this.sendViewModel,
@required this.settingsViewModel,
required this.sendViewModel,
required this.settingsViewModel,
this.initialPaymentRequest,
}) : _formKey = GlobalKey<FormState>(),fiatFromSettings = settingsViewModel.fiatCurrency;
@@ -40,7 +40,7 @@ class SendPage extends BasePage {
final GlobalKey<FormState> _formKey;
final controller = PageController(initialPage: 0);
final FiatCurrency fiatFromSettings;
final PaymentRequest initialPaymentRequest;
final PaymentRequest? initialPaymentRequest;
bool _effectsInstalled = false;
@@ -66,15 +66,20 @@ class SendPage extends BasePage {
}
@override
Widget middle(BuildContext context) => Row(
Widget? middle(BuildContext context) {
final supMiddle = super.middle(context);
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right:8.0),
child: Observer(builder: (_) => SyncIndicatorIcon(isSynced: sendViewModel.isReadyForSend),),
),super.middle(context),
),
if (supMiddle != null)
supMiddle
],
);
}
@override
Widget trailing(context) => Observer(builder: (_) {
@@ -82,7 +87,7 @@ class SendPage extends BasePage {
? TrailButton(
caption: S.of(context).remove,
onPressed: () {
var pageToJump = controller.page.round() - 1;
var pageToJump = (controller.page?.round() ?? 0) - 1;
pageToJump = pageToJump > 0 ? pageToJump : 0;
final output = _defineCurrentOutput();
sendViewModel.removeOutput(output);
@@ -92,7 +97,7 @@ class SendPage extends BasePage {
caption: S.of(context).clear,
onPressed: () {
final output = _defineCurrentOutput();
_formKey.currentState.reset();
_formKey.currentState?.reset();
output.reset();
});
});
@@ -146,13 +151,13 @@ class SendPage extends BasePage {
dotWidth: 6.0,
dotHeight: 6.0,
dotColor: Theme.of(context)
.primaryTextTheme
.display2
.backgroundColor,
.primaryTextTheme!
.headline3!
.backgroundColor!,
activeDotColor: Theme.of(context)
.primaryTextTheme
.display3
.backgroundColor),
.primaryTextTheme!
.headline2!
.backgroundColor!),
)
: Offstage();
},
@@ -182,9 +187,9 @@ class SendPage extends BasePage {
borderType: BorderType.RRect,
dashPattern: [6, 4],
color: Theme.of(context)
.primaryTextTheme
.headline2
.decorationColor,
.primaryTextTheme!
.headline2!
.decorationColor!,
strokeWidth: 2,
radius: Radius.circular(20),
child: Container(
@@ -200,9 +205,9 @@ class SendPage extends BasePage {
? Icon(
Icons.add,
color: Theme.of(context)
.primaryTextTheme
.display3
.color,
.primaryTextTheme!
.headline2!
.color!,
)
: Text(
S.of(context).new_template,
@@ -210,9 +215,9 @@ class SendPage extends BasePage {
fontSize: 14,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.primaryTextTheme
.display3
.color,
.primaryTextTheme!
.headline2!
.color!,
),
),
),
@@ -291,9 +296,9 @@ class SendPage extends BasePage {
text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme
.display2
.decorationColor,
.accentTextTheme!
.headline3!
.decorationColor!,
)
)
),
@@ -310,20 +315,20 @@ class SendPage extends BasePage {
text: S.of(context).add_receiver,
color: Colors.transparent,
textColor: Theme.of(context)
.accentTextTheme
.display2
.decorationColor,
.accentTextTheme!
.headline3!
.decorationColor!,
isDottedBorder: true,
borderColor: Theme.of(context)
.primaryTextTheme
.display2
.decorationColor,
.primaryTextTheme!
.headline3!
.decorationColor!,
)),
Observer(
builder: (_) {
return LoadingPrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
if (sendViewModel.outputs.length > 1) {
showErrorValidationAlert(context);
}
@@ -345,7 +350,7 @@ class SendPage extends BasePage {
},
text: S.of(context).send,
color: Theme.of(context).accentTextTheme.body2.color,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isLoading: sendViewModel.state is IsExecutingState ||
sendViewModel.state is TransactionCommitting,
@@ -387,13 +392,13 @@ class SendPage extends BasePage {
alertTitle: S.of(context).confirm_sending,
amount: S.of(context).send_amount,
amountValue:
sendViewModel.pendingTransaction.amountFormatted,
sendViewModel.pendingTransaction!.amountFormatted,
fiatAmountValue:
sendViewModel.pendingTransactionFiatAmount +
' ' +
sendViewModel.fiat.title,
fee: S.of(context).send_fee,
feeValue: sendViewModel.pendingTransaction.feeFormatted,
feeValue: sendViewModel.pendingTransaction!.feeFormatted,
feeFiatAmount:
sendViewModel.pendingTransactionFeeFiatAmount +
' ' +
@@ -444,7 +449,10 @@ class SendPage extends BasePage {
}
Output _defineCurrentOutput() {
final itemCount = controller.page.round();
if (controller.page == null) {
throw Exception('Controller page is null');
}
final itemCount = controller.page!.round();
return sendViewModel.outputs[itemCount];
}

Some files were not shown because too many files have changed in this diff Show More