mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-20 06:08:34 +02:00
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:
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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!
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -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!),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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!,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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())
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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!,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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!
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
],
|
||||
))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user