CAKE-20 | updated exchange and exchange template pages; created exchange_view_model and applied to exchange and exchange template pages; applied new design to menu widget; changed text validator and amount validator
BIN
assets/images/2.0x/eye_menu.png
Normal file
After Width: | Height: | Size: 939 B |
BIN
assets/images/2.0x/key_menu.png
Normal file
After Width: | Height: | Size: 923 B |
BIN
assets/images/2.0x/monero_menu.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
assets/images/2.0x/nodes_menu.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/2.0x/open_book_menu.png
Normal file
After Width: | Height: | Size: 735 B |
BIN
assets/images/2.0x/reconnect_menu.png
Normal file
After Width: | Height: | Size: 875 B |
BIN
assets/images/2.0x/settings_menu.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
assets/images/2.0x/wallet_menu.png
Normal file
After Width: | Height: | Size: 659 B |
BIN
assets/images/3.0x/eye_menu.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/3.0x/key_menu.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/3.0x/monero_menu.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
assets/images/3.0x/nodes_menu.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/3.0x/open_book_menu.png
Normal file
After Width: | Height: | Size: 994 B |
BIN
assets/images/3.0x/reconnect_menu.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/3.0x/settings_menu.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/3.0x/wallet_menu.png
Normal file
After Width: | Height: | Size: 920 B |
BIN
assets/images/eye_menu.png
Normal file
After Width: | Height: | Size: 536 B |
BIN
assets/images/key_menu.png
Normal file
After Width: | Height: | Size: 518 B |
BIN
assets/images/monero_menu.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/nodes_menu.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
assets/images/open_book_menu.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
assets/images/reconnect_menu.png
Normal file
After Width: | Height: | Size: 495 B |
BIN
assets/images/settings_menu.png
Normal file
After Width: | Height: | Size: 594 B |
BIN
assets/images/wallet_menu.png
Normal file
After Width: | Height: | Size: 358 B |
|
@ -3,10 +3,11 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||||
|
|
||||||
class AmountValidator extends TextValidator {
|
class AmountValidator extends TextValidator {
|
||||||
AmountValidator({WalletType type})
|
AmountValidator({WalletType type, bool isAutovalidate = false})
|
||||||
: super(
|
: super(
|
||||||
errorMessage: S.current.error_text_amount,
|
errorMessage: S.current.error_text_amount,
|
||||||
pattern: _pattern(type),
|
pattern: _pattern(type),
|
||||||
|
isAutovalidate: isAutovalidate,
|
||||||
minLength: 0,
|
minLength: 0,
|
||||||
maxLength: 0);
|
maxLength: 0);
|
||||||
|
|
||||||
|
|
|
@ -16,18 +16,20 @@ class TextValidator extends Validator<String> {
|
||||||
this.maxLength,
|
this.maxLength,
|
||||||
this.pattern,
|
this.pattern,
|
||||||
this.length,
|
this.length,
|
||||||
|
this.isAutovalidate = false,
|
||||||
String errorMessage})
|
String errorMessage})
|
||||||
: super(errorMessage: errorMessage);
|
: super(errorMessage: errorMessage);
|
||||||
|
|
||||||
final int minLength;
|
final int minLength;
|
||||||
final int maxLength;
|
final int maxLength;
|
||||||
final List<int> length;
|
final List<int> length;
|
||||||
|
final bool isAutovalidate;
|
||||||
String pattern;
|
String pattern;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isValid(String value) {
|
bool isValid(String value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return false;
|
return isAutovalidate ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.length > (minLength ?? 0) &&
|
return value.length > (minLength ?? 0) &&
|
||||||
|
|
16
lib/di.dart
|
@ -10,6 +10,8 @@ import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/send/send_template_page.dart';
|
import 'package:cake_wallet/src/screens/send/send_template_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/settings/settings.dart';
|
import 'package:cake_wallet/src/screens/settings/settings.dart';
|
||||||
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
||||||
import 'package:cake_wallet/store/contact_list_store.dart';
|
import 'package:cake_wallet/store/contact_list_store.dart';
|
||||||
import 'package:cake_wallet/store/node_list_store.dart';
|
import 'package:cake_wallet/store/node_list_store.dart';
|
||||||
import 'package:cake_wallet/store/settings_store.dart';
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
@ -42,6 +44,7 @@ import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -299,4 +302,17 @@ Future setup(
|
||||||
|
|
||||||
getIt.registerFactory(
|
getIt.registerFactory(
|
||||||
() => NodeCreateOrEditPage(getIt.get<NodeCreateOrEditViewModel>()));
|
() => NodeCreateOrEditPage(getIt.get<NodeCreateOrEditViewModel>()));
|
||||||
|
|
||||||
|
getIt.registerFactory(() =>
|
||||||
|
ExchangeViewModel(
|
||||||
|
wallet: getIt.get<AppStore>().wallet,
|
||||||
|
exchangeTemplateStore: getIt.get<ExchangeTemplateStore>(),
|
||||||
|
trades: tradesSource
|
||||||
|
));
|
||||||
|
|
||||||
|
getIt.registerFactory(() =>
|
||||||
|
ExchangePage(getIt.get<ExchangeViewModel>()));
|
||||||
|
|
||||||
|
getIt.registerFactory(() =>
|
||||||
|
ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ class S implements WidgetsLocalizations {
|
||||||
String get reconnect => "Reconnect";
|
String get reconnect => "Reconnect";
|
||||||
String get reconnect_alert_text => "Are you sure to reconnect?";
|
String get reconnect_alert_text => "Are you sure to reconnect?";
|
||||||
String get reconnection => "Reconnection";
|
String get reconnection => "Reconnection";
|
||||||
|
String get refund_address => "Refund address";
|
||||||
String get remove => "Remove";
|
String get remove => "Remove";
|
||||||
String get remove_node => "Remove node";
|
String get remove_node => "Remove node";
|
||||||
String get remove_node_message => "Are you sure that you want to remove selected node?";
|
String get remove_node_message => "Are you sure that you want to remove selected node?";
|
||||||
|
@ -372,6 +373,8 @@ class $de extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Unterbezahlt";
|
String get trade_state_underpaid => "Unterbezahlt";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Rückerstattungsadresse";
|
||||||
|
@override
|
||||||
String get welcome => "Willkommen zu";
|
String get welcome => "Willkommen zu";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Adresse teilen ";
|
String get share_address => "Adresse teilen ";
|
||||||
|
@ -998,6 +1001,8 @@ class $hi extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "के तहत भुगतान किया";
|
String get trade_state_underpaid => "के तहत भुगतान किया";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "वापसी का पता";
|
||||||
|
@override
|
||||||
String get welcome => "स्वागत हे सेवा मेरे";
|
String get welcome => "स्वागत हे सेवा मेरे";
|
||||||
@override
|
@override
|
||||||
String get share_address => "पता साझा करें";
|
String get share_address => "पता साझा करें";
|
||||||
|
@ -1624,6 +1629,8 @@ class $ru extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Недоплаченная";
|
String get trade_state_underpaid => "Недоплаченная";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Адрес возврата";
|
||||||
|
@override
|
||||||
String get welcome => "Приветствуем в";
|
String get welcome => "Приветствуем в";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Поделиться адресом";
|
String get share_address => "Поделиться адресом";
|
||||||
|
@ -2250,6 +2257,8 @@ class $ko extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "미지급";
|
String get trade_state_underpaid => "미지급";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "환불 주소";
|
||||||
|
@override
|
||||||
String get welcome => "환영 에";
|
String get welcome => "환영 에";
|
||||||
@override
|
@override
|
||||||
String get share_address => "주소 공유";
|
String get share_address => "주소 공유";
|
||||||
|
@ -2876,6 +2885,8 @@ class $pt extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Parcialmente paga";
|
String get trade_state_underpaid => "Parcialmente paga";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Endereço de reembolso";
|
||||||
|
@override
|
||||||
String get welcome => "Bem-vindo ao";
|
String get welcome => "Bem-vindo ao";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Compartilhar endereço";
|
String get share_address => "Compartilhar endereço";
|
||||||
|
@ -3502,6 +3513,8 @@ class $uk extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Недоплачена";
|
String get trade_state_underpaid => "Недоплачена";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Адреса повернення коштів";
|
||||||
|
@override
|
||||||
String get welcome => "Вітаємо в";
|
String get welcome => "Вітаємо в";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Поділитися адресою";
|
String get share_address => "Поділитися адресою";
|
||||||
|
@ -4128,6 +4141,8 @@ class $ja extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "支払不足";
|
String get trade_state_underpaid => "支払不足";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "払い戻し住所";
|
||||||
|
@override
|
||||||
String get welcome => "ようこそ に";
|
String get welcome => "ようこそ に";
|
||||||
@override
|
@override
|
||||||
String get share_address => "住所を共有する";
|
String get share_address => "住所を共有する";
|
||||||
|
@ -4758,6 +4773,8 @@ class $pl extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Niedopłacone";
|
String get trade_state_underpaid => "Niedopłacone";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Adres zwrotu";
|
||||||
|
@override
|
||||||
String get welcome => "Witamy w";
|
String get welcome => "Witamy w";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Udostępnij adres";
|
String get share_address => "Udostępnij adres";
|
||||||
|
@ -5384,6 +5401,8 @@ class $es extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Poco pagado";
|
String get trade_state_underpaid => "Poco pagado";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Dirección de reembolso";
|
||||||
|
@override
|
||||||
String get welcome => "Bienvenido";
|
String get welcome => "Bienvenido";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Compartir dirección";
|
String get share_address => "Compartir dirección";
|
||||||
|
@ -6010,6 +6029,8 @@ class $nl extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "Slecht betaald";
|
String get trade_state_underpaid => "Slecht betaald";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "Adres voor terugbetaling";
|
||||||
|
@override
|
||||||
String get welcome => "Welkom bij";
|
String get welcome => "Welkom bij";
|
||||||
@override
|
@override
|
||||||
String get share_address => "Deel adres";
|
String get share_address => "Deel adres";
|
||||||
|
@ -6636,6 +6657,8 @@ class $zh extends S {
|
||||||
@override
|
@override
|
||||||
String get trade_state_underpaid => "支付不足";
|
String get trade_state_underpaid => "支付不足";
|
||||||
@override
|
@override
|
||||||
|
String get refund_address => "退款地址";
|
||||||
|
@override
|
||||||
String get welcome => "歡迎來到";
|
String get welcome => "歡迎來到";
|
||||||
@override
|
@override
|
||||||
String get share_address => "分享地址";
|
String get share_address => "分享地址";
|
||||||
|
|
|
@ -23,8 +23,8 @@ class PaletteDark {
|
||||||
static const Color lightDistantBlue = Color.fromRGBO(81, 96, 147, 1.0); // borderCardColor
|
static const Color lightDistantBlue = Color.fromRGBO(81, 96, 147, 1.0); // borderCardColor
|
||||||
static const Color gray = Color.fromRGBO(140, 153, 201, 1.0); // walletCardText
|
static const Color gray = Color.fromRGBO(140, 153, 201, 1.0); // walletCardText
|
||||||
static const Color violetBlue = Color.fromRGBO(51, 63, 104, 1.0); // walletCardAddressField
|
static const Color violetBlue = Color.fromRGBO(51, 63, 104, 1.0); // walletCardAddressField
|
||||||
static const Color moderateBlue = Color.fromRGBO(63, 77, 122, 1.0); // walletCardSubAddressField
|
//static const Color moderateBlue = Color.fromRGBO(63, 77, 122, 1.0); // walletCardSubAddressField
|
||||||
static const Color darkNightBlue = Color.fromRGBO(33, 43, 73, 1.0); // historyPanel
|
//static const Color darkNightBlue = Color.fromRGBO(33, 43, 73, 1.0); // historyPanel
|
||||||
static const Color pigeonBlue = Color.fromRGBO(91, 112, 146, 1.0); // historyPanelText
|
static const Color pigeonBlue = Color.fromRGBO(91, 112, 146, 1.0); // historyPanelText
|
||||||
static const Color moderateNightBlue = Color.fromRGBO(39, 53, 96, 1.0); // historyPanelButton
|
static const Color moderateNightBlue = Color.fromRGBO(39, 53, 96, 1.0); // historyPanelButton
|
||||||
static const Color headerNightBlue = Color.fromRGBO(41, 52, 84, 1.0); // menuHeader
|
static const Color headerNightBlue = Color.fromRGBO(41, 52, 84, 1.0); // menuHeader
|
||||||
|
@ -46,6 +46,12 @@ class PaletteDark {
|
||||||
static const Color lightBlueGrey = Color.fromRGBO(125, 141, 183, 1.0);
|
static const Color lightBlueGrey = Color.fromRGBO(125, 141, 183, 1.0);
|
||||||
static const Color lightVioletBlue = Color.fromRGBO(56, 71, 109, 1.0);
|
static const Color lightVioletBlue = Color.fromRGBO(56, 71, 109, 1.0);
|
||||||
static const Color darkVioletBlue = Color.fromRGBO(49, 60, 96, 1.0);
|
static const Color darkVioletBlue = Color.fromRGBO(49, 60, 96, 1.0);
|
||||||
|
static const Color wildVioletBlue = Color.fromRGBO(45, 60, 97, 1.0);
|
||||||
|
static const Color darkNightBlue = Color.fromRGBO(33, 45, 76, 1.0);
|
||||||
|
static const Color blueGrey = Color.fromRGBO(87, 98, 138, 1.0);
|
||||||
|
static const Color moderateBlue = Color.fromRGBO(60, 73, 118, 1.0);
|
||||||
|
static const Color deepPurpleBlue = Color.fromRGBO(19, 29, 56, 1.0);
|
||||||
|
static const Color lightOceanBlue = Color.fromRGBO(30, 42, 73, 1.0);
|
||||||
|
|
||||||
// FIXME: Rename.
|
// FIXME: Rename.
|
||||||
static const Color eee = Color.fromRGBO(236, 239, 245, 1.0);
|
static const Color eee = Color.fromRGBO(236, 239, 245, 1.0);
|
||||||
|
|
|
@ -411,45 +411,12 @@ class Router {
|
||||||
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
|
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
|
||||||
|
|
||||||
case Routes.exchange:
|
case Routes.exchange:
|
||||||
return MaterialPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
builder: (_) => MultiProvider(providers: [
|
builder: (_) => getIt.get<ExchangePage>());
|
||||||
Provider(create: (_) {
|
|
||||||
final xmrtoprovider = XMRTOExchangeProvider();
|
|
||||||
|
|
||||||
return ExchangeStore(
|
|
||||||
initialProvider: xmrtoprovider,
|
|
||||||
initialDepositCurrency: CryptoCurrency.xmr,
|
|
||||||
initialReceiveCurrency: CryptoCurrency.btc,
|
|
||||||
trades: trades,
|
|
||||||
providerList: [
|
|
||||||
xmrtoprovider,
|
|
||||||
ChangeNowExchangeProvider(),
|
|
||||||
MorphTokenExchangeProvider(trades: trades)
|
|
||||||
],
|
|
||||||
walletStore: walletStore);
|
|
||||||
}),
|
|
||||||
], child: ExchangePage()));
|
|
||||||
|
|
||||||
case Routes.exchangeTemplate:
|
case Routes.exchangeTemplate:
|
||||||
return MaterialPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
builder: (_) => Provider(
|
builder: (_) => getIt.get<ExchangeTemplatePage>());
|
||||||
create: (_) {
|
|
||||||
final xmrtoprovider = XMRTOExchangeProvider();
|
|
||||||
|
|
||||||
return ExchangeStore(
|
|
||||||
initialProvider: xmrtoprovider,
|
|
||||||
initialDepositCurrency: CryptoCurrency.xmr,
|
|
||||||
initialReceiveCurrency: CryptoCurrency.btc,
|
|
||||||
trades: trades,
|
|
||||||
providerList: [
|
|
||||||
xmrtoprovider,
|
|
||||||
ChangeNowExchangeProvider(),
|
|
||||||
MorphTokenExchangeProvider(trades: trades)
|
|
||||||
],
|
|
||||||
walletStore: walletStore);
|
|
||||||
},
|
|
||||||
child: ExchangeTemplatePage(),
|
|
||||||
));
|
|
||||||
|
|
||||||
case Routes.settings:
|
case Routes.settings:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
|
|
|
@ -19,10 +19,14 @@ abstract class BasePage extends StatelessWidget {
|
||||||
|
|
||||||
bool get resizeToAvoidBottomPadding => true;
|
bool get resizeToAvoidBottomPadding => true;
|
||||||
|
|
||||||
|
Widget get endDrawer => null;
|
||||||
|
|
||||||
AppBarStyle get appBarStyle => AppBarStyle.regular;
|
AppBarStyle get appBarStyle => AppBarStyle.regular;
|
||||||
|
|
||||||
Widget Function(BuildContext, Widget) get rootWrapper => null;
|
Widget Function(BuildContext, Widget) get rootWrapper => null;
|
||||||
|
|
||||||
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
final _backArrowImage = Image.asset('assets/images/back_arrow.png',
|
final _backArrowImage = Image.asset('assets/images/back_arrow.png',
|
||||||
color: Colors.white);
|
color: Colors.white);
|
||||||
final _backArrowImageDarkTheme =
|
final _backArrowImageDarkTheme =
|
||||||
|
@ -32,6 +36,8 @@ abstract class BasePage extends StatelessWidget {
|
||||||
final _closeButtonImageDarkTheme =
|
final _closeButtonImageDarkTheme =
|
||||||
Image.asset('assets/images/close_button_dark_theme.png');
|
Image.asset('assets/images/close_button_dark_theme.png');
|
||||||
|
|
||||||
|
void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer();
|
||||||
|
|
||||||
void onClose(BuildContext context) => Navigator.of(context).pop();
|
void onClose(BuildContext context) => Navigator.of(context).pop();
|
||||||
|
|
||||||
Widget leading(BuildContext context) {
|
Widget leading(BuildContext context) {
|
||||||
|
@ -123,9 +129,11 @@ abstract class BasePage extends StatelessWidget {
|
||||||
final _isDarkTheme = _themeChanger.getTheme() == Themes.darkTheme;
|
final _isDarkTheme = _themeChanger.getTheme() == Themes.darkTheme;
|
||||||
|
|
||||||
final root = Scaffold(
|
final root = Scaffold(
|
||||||
|
key: _scaffoldKey,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
_isDarkTheme ? backgroundDarkColor : backgroundLightColor,
|
_isDarkTheme ? backgroundDarkColor : backgroundLightColor,
|
||||||
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
|
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
|
||||||
|
endDrawer: endDrawer,
|
||||||
appBar: appBar(context),
|
appBar: appBar(context),
|
||||||
body: body(context), //SafeArea(child: ),
|
body: body(context), //SafeArea(child: ),
|
||||||
floatingActionButton: floatingActionButton(context));
|
floatingActionButton: floatingActionButton(context));
|
||||||
|
|
|
@ -23,6 +23,12 @@ class DashboardPage extends BasePage {
|
||||||
@override
|
@override
|
||||||
Color get backgroundDarkColor => PaletteDark.backgroundColor;
|
Color get backgroundDarkColor => PaletteDark.backgroundColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget get endDrawer => MenuWidget(
|
||||||
|
name: walletViewModel.name,
|
||||||
|
subname: walletViewModel.subname,
|
||||||
|
type: walletViewModel.type);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget middle(BuildContext context) {
|
Widget middle(BuildContext context) {
|
||||||
return SyncIndicator(dashboardViewModel: walletViewModel);
|
return SyncIndicator(dashboardViewModel: walletViewModel);
|
||||||
|
@ -40,14 +46,7 @@ class DashboardPage extends BasePage {
|
||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
splashColor: Colors.transparent,
|
splashColor: Colors.transparent,
|
||||||
padding: EdgeInsets.all(0),
|
padding: EdgeInsets.all(0),
|
||||||
onPressed: () async {
|
onPressed: () => onOpenEndDrawer(),
|
||||||
await showDialog<void>(
|
|
||||||
builder: (_) => MenuWidget(
|
|
||||||
name: walletViewModel.name,
|
|
||||||
subname: walletViewModel.subname,
|
|
||||||
type: walletViewModel.type),
|
|
||||||
context: context);
|
|
||||||
},
|
|
||||||
child: menuButton
|
child: menuButton
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,13 +20,13 @@ class WalletMenu {
|
||||||
];
|
];
|
||||||
|
|
||||||
final List<Image> images = [
|
final List<Image> images = [
|
||||||
Image.asset('assets/images/reconnect.png'),
|
Image.asset('assets/images/reconnect_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/wallet.png'),
|
Image.asset('assets/images/wallet_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/nodes.png'),
|
Image.asset('assets/images/nodes_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/eye.png'),
|
Image.asset('assets/images/eye_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/key.png'),
|
Image.asset('assets/images/key_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/open_book.png'),
|
Image.asset('assets/images/open_book_menu.png', height: 16, width: 16),
|
||||||
Image.asset('assets/images/settings.png'),
|
Image.asset('assets/images/settings_menu.png', height: 16, width: 16),
|
||||||
];
|
];
|
||||||
|
|
||||||
final BuildContext context;
|
final BuildContext context;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
|
import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart';
|
||||||
|
@ -15,7 +16,7 @@ class MenuWidget extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuWidgetState extends State<MenuWidget> {
|
class MenuWidgetState extends State<MenuWidget> {
|
||||||
final moneroIcon = Image.asset('assets/images/monero.png');
|
final moneroIcon = Image.asset('assets/images/monero_menu.png');
|
||||||
final bitcoinIcon = Image.asset('assets/images/bitcoin.png');
|
final bitcoinIcon = Image.asset('assets/images/bitcoin.png');
|
||||||
final largeScreen = 731;
|
final largeScreen = 731;
|
||||||
|
|
||||||
|
@ -36,10 +37,10 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
screenHeight = 0;
|
screenHeight = 0;
|
||||||
opacity = 0;
|
opacity = 0;
|
||||||
|
|
||||||
headerHeight = 120;
|
headerHeight = 125;
|
||||||
tileHeight = 75;
|
tileHeight = 75;
|
||||||
fromTopEdge = 50;
|
fromTopEdge = 50;
|
||||||
fromBottomEdge = 30;
|
fromBottomEdge = 21;//30;
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
|
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
|
||||||
|
@ -66,10 +67,10 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final walletMenu = WalletMenu(context);
|
final walletMenu = WalletMenu(context);
|
||||||
// final walletStore = Provider.of<WalletStore>(context);
|
|
||||||
final itemCount = walletMenu.items.length;
|
final itemCount = walletMenu.items.length;
|
||||||
|
|
||||||
return Row(
|
return SafeArea(
|
||||||
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
@ -84,45 +85,32 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
)),
|
)),
|
||||||
SizedBox(width: 12),
|
SizedBox(width: 12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => null,
|
|
||||||
child: Container(
|
|
||||||
width: menuWidth,
|
|
||||||
height: double.infinity,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(24),
|
|
||||||
bottomLeft: Radius.circular(24)),
|
|
||||||
color: Theme.of(context).primaryTextTheme.display1.color),
|
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.only(
|
borderRadius: BorderRadius.only(
|
||||||
topLeft: Radius.circular(24),
|
topLeft: Radius.circular(24),
|
||||||
bottomLeft: Radius.circular(24)),
|
bottomLeft: Radius.circular(24)),
|
||||||
child: ListView.separated(
|
child: Container(
|
||||||
itemBuilder: (_, index) {
|
width: menuWidth,
|
||||||
if (index == 0) {
|
height: double.infinity,
|
||||||
return Container(
|
color: PaletteDark.deepPurpleBlue,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
height: headerHeight,
|
height: headerHeight,
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
left: 24,
|
left: 24,
|
||||||
top: fromTopEdge,
|
top: fromTopEdge,
|
||||||
right: 24,
|
right: 24,
|
||||||
bottom: fromBottomEdge),
|
bottom: fromBottomEdge),
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius:
|
|
||||||
BorderRadius.only(topLeft: Radius.circular(24)),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.primaryTextTheme
|
|
||||||
.display2
|
|
||||||
.color),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_iconFor(type: widget.type),
|
_iconFor(type: widget.type),
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 40,
|
height: 42,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: widget.subname != null
|
mainAxisAlignment: widget.subname != null
|
||||||
|
@ -132,25 +120,16 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
Text(
|
Text(
|
||||||
widget.name,
|
widget.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Colors.white,
|
||||||
.primaryTextTheme
|
fontSize: 16,
|
||||||
.title
|
|
||||||
.color,
|
|
||||||
decoration: TextDecoration.none,
|
|
||||||
fontFamily: 'Avenir Next',
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
if (widget.subname != null)
|
if (widget.subname != null)
|
||||||
Text(
|
Text(
|
||||||
widget.subname,
|
widget.subname,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context)
|
color: PaletteDark.darkCyanBlue,
|
||||||
.primaryTextTheme
|
fontWeight: FontWeight.w500,
|
||||||
.caption
|
|
||||||
.color,
|
|
||||||
decoration: TextDecoration.none,
|
|
||||||
fontFamily: 'Avenir Next',
|
|
||||||
fontSize: 12),
|
fontSize: 12),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -158,35 +137,37 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}
|
Container(
|
||||||
|
height: 1,
|
||||||
|
color: PaletteDark.lightOceanBlue,
|
||||||
|
),
|
||||||
|
ListView.separated(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
|
||||||
index -= 1;
|
|
||||||
final item = walletMenu.items[index];
|
final item = walletMenu.items[index];
|
||||||
final image = walletMenu.images[index] ?? Offstage();
|
final image = walletMenu.images[index] ?? Offstage();
|
||||||
|
final isLastTile = index == itemCount - 1;
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
walletMenu.action(index);
|
walletMenu.action(index);
|
||||||
},
|
},
|
||||||
child: index == itemCount - 1
|
child: Container(
|
||||||
? Container(
|
height: isLastTile
|
||||||
height: headerHeight,
|
? headerHeight
|
||||||
padding: EdgeInsets.only(
|
: tileHeight,
|
||||||
|
padding: isLastTile
|
||||||
|
? EdgeInsets.only(
|
||||||
left: 24,
|
left: 24,
|
||||||
right: 24,
|
right: 24,
|
||||||
top: fromBottomEdge,
|
top: fromBottomEdge,
|
||||||
bottom: fromTopEdge),
|
bottom: fromTopEdge)
|
||||||
alignment: Alignment.topLeft,
|
: EdgeInsets.only(left: 24, right: 24),
|
||||||
decoration: BoxDecoration(
|
alignment: isLastTile ? Alignment.topLeft : null,
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
bottomLeft: Radius.circular(24)),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.primaryTextTheme
|
|
||||||
.display1
|
|
||||||
.color,
|
|
||||||
),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
@ -197,58 +178,28 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||||
child: Text(
|
child: Text(
|
||||||
item,
|
item,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
decoration: TextDecoration.none,
|
color: Colors.white,
|
||||||
color: Theme.of(context)
|
fontSize: 16,
|
||||||
.primaryTextTheme
|
|
||||||
.title
|
|
||||||
.color,
|
|
||||||
fontFamily: 'Avenir Next',
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
|
||||||
height: tileHeight,
|
|
||||||
padding: EdgeInsets.only(left: 24, right: 24),
|
|
||||||
color: Theme.of(context)
|
|
||||||
.primaryTextTheme
|
|
||||||
.display1
|
|
||||||
.color,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
image,
|
|
||||||
SizedBox(width: 16),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
item,
|
|
||||||
style: TextStyle(
|
|
||||||
decoration: TextDecoration.none,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.primaryTextTheme
|
|
||||||
.title
|
|
||||||
.color,
|
|
||||||
fontFamily: 'Avenir Next',
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, index) => Container(
|
separatorBuilder: (_, index) => Container(
|
||||||
height: 1,
|
height: 1,
|
||||||
color: Theme.of(context).dividerColor,
|
color: PaletteDark.lightOceanBlue,
|
||||||
),
|
),
|
||||||
itemCount: itemCount + 1),
|
itemCount: itemCount)
|
||||||
),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,66 +1,40 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:cake_wallet/palette.dart';
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
|
||||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
||||||
import 'package:cake_wallet/src/widgets/trail_button.dart';
|
import 'package:cake_wallet/src/widgets/trail_button.dart';
|
||||||
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
|
|
||||||
class ExchangePage extends BasePage {
|
class ExchangePage extends BasePage {
|
||||||
|
ExchangePage(this.exchangeViewModel);
|
||||||
|
|
||||||
|
final ExchangeViewModel exchangeViewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => S.current.exchange;
|
String get title => S.current.exchange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get backgroundLightColor => Palette.darkLavender;
|
Color get backgroundLightColor => PaletteDark.wildVioletBlue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get backgroundDarkColor => PaletteDark.moderateBlue;
|
Color get backgroundDarkColor => PaletteDark.wildVioletBlue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget middle(BuildContext context) {
|
Widget middle(BuildContext context) =>
|
||||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
PresentProviderPicker(exchangeViewModel: exchangeViewModel);
|
||||||
|
|
||||||
return PresentProviderPicker(exchangeStore: exchangeStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget trailing(BuildContext context) {
|
Widget trailing(BuildContext context) =>
|
||||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
TrailButton(
|
||||||
|
|
||||||
return TrailButton(
|
|
||||||
caption: S.of(context).reset,
|
caption: S.of(context).reset,
|
||||||
onPressed: () => exchangeStore.reset()
|
onPressed: () => exchangeViewModel.reset()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) => ExchangeForm();
|
Widget body(BuildContext context) =>
|
||||||
}
|
BaseExchangeWidget(exchangeViewModel: exchangeViewModel);
|
||||||
|
|
||||||
class ExchangeForm extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => ExchangeFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExchangeFormState extends State<ExchangeForm> {
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
|
||||||
final walletStore = Provider.of<WalletStore>(context);
|
|
||||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
|
||||||
|
|
||||||
return BaseExchangeWidget(
|
|
||||||
exchangeStore: exchangeStore,
|
|
||||||
walletStore: walletStore,
|
|
||||||
exchangeTemplateStore: exchangeTemplateStore,
|
|
||||||
isTemplate: false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,32 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:cake_wallet/palette.dart';
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
|
||||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
|
|
||||||
class ExchangeTemplatePage extends BasePage {
|
class ExchangeTemplatePage extends BasePage {
|
||||||
|
ExchangeTemplatePage(this.exchangeViewModel);
|
||||||
|
|
||||||
|
final ExchangeViewModel exchangeViewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => S.current.exchange_new_template;
|
String get title => S.current.exchange_new_template;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get backgroundLightColor => Palette.darkLavender;
|
Color get backgroundLightColor => PaletteDark.wildVioletBlue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color get backgroundDarkColor => PaletteDark.moderateBlue;
|
Color get backgroundDarkColor => PaletteDark.wildVioletBlue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget trailing(BuildContext context) {
|
Widget trailing(BuildContext context) =>
|
||||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
PresentProviderPicker(exchangeViewModel: exchangeViewModel);
|
||||||
|
|
||||||
return PresentProviderPicker(exchangeStore: exchangeStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) => ExchangeTemplateForm();
|
Widget body(BuildContext context) =>
|
||||||
}
|
BaseExchangeWidget(exchangeViewModel: exchangeViewModel, isTemplate: true);
|
||||||
|
|
||||||
class ExchangeTemplateForm extends StatefulWidget{
|
|
||||||
@override
|
|
||||||
ExchangeTemplateFormState createState() => ExchangeTemplateFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExchangeTemplateFormState extends State<ExchangeTemplateForm> {
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
|
||||||
final walletStore = Provider.of<WalletStore>(context);
|
|
||||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
|
||||||
|
|
||||||
return BaseExchangeWidget(
|
|
||||||
exchangeStore: exchangeStore,
|
|
||||||
walletStore: walletStore,
|
|
||||||
exchangeTemplateStore: exchangeTemplateStore,
|
|
||||||
isTemplate: true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||||
import 'package:dotted_border/dotted_border.dart';
|
import 'package:dotted_border/dotted_border.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
@ -12,49 +14,37 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_exchange_provider.dart';
|
import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_exchange_provider.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange/exchange_trade_state.dart';
|
import 'package:cake_wallet/src/stores/exchange/exchange_trade_state.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange/limits_state.dart';
|
import 'package:cake_wallet/src/stores/exchange/limits_state.dart';
|
||||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
|
||||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.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/primary_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
import 'package:cake_wallet/src/widgets/top_panel.dart';
|
import 'package:cake_wallet/src/widgets/top_panel.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||||
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
|
|
||||||
class BaseExchangeWidget extends StatefulWidget {
|
class BaseExchangeWidget extends StatefulWidget {
|
||||||
BaseExchangeWidget({
|
BaseExchangeWidget({
|
||||||
@ required this.exchangeStore,
|
@ required this.exchangeViewModel,
|
||||||
@ required this.walletStore,
|
this.isTemplate = false,
|
||||||
@ required this.exchangeTemplateStore,
|
|
||||||
@ required this.isTemplate,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final ExchangeStore exchangeStore;
|
final ExchangeViewModel exchangeViewModel;
|
||||||
final WalletStore walletStore;
|
|
||||||
final ExchangeTemplateStore exchangeTemplateStore;
|
|
||||||
final bool isTemplate;
|
final bool isTemplate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BaseExchangeWidgetState createState() =>
|
BaseExchangeWidgetState createState() =>
|
||||||
BaseExchangeWidgetState(
|
BaseExchangeWidgetState(
|
||||||
exchangeStore: exchangeStore,
|
exchangeViewModel: exchangeViewModel,
|
||||||
walletStore: walletStore,
|
|
||||||
exchangeTemplateStore: exchangeTemplateStore,
|
|
||||||
isTemplate: isTemplate
|
isTemplate: isTemplate
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
BaseExchangeWidgetState({
|
BaseExchangeWidgetState({
|
||||||
@ required this.exchangeStore,
|
@ required this.exchangeViewModel,
|
||||||
@ required this.walletStore,
|
|
||||||
@ required this.exchangeTemplateStore,
|
|
||||||
@ required this.isTemplate,
|
@ required this.isTemplate,
|
||||||
});
|
});
|
||||||
|
|
||||||
final ExchangeStore exchangeStore;
|
final ExchangeViewModel exchangeViewModel;
|
||||||
final WalletStore walletStore;
|
|
||||||
final ExchangeTemplateStore exchangeTemplateStore;
|
|
||||||
final bool isTemplate;
|
final bool isTemplate;
|
||||||
|
|
||||||
final depositKey = GlobalKey<ExchangeCardState>();
|
final depositKey = GlobalKey<ExchangeCardState>();
|
||||||
|
@ -64,31 +54,31 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Image arrowBottomPurple = Image.asset(
|
final arrowBottomPurple = Image.asset(
|
||||||
'assets/images/arrow_bottom_purple_icon.png',
|
'assets/images/arrow_bottom_purple_icon.png',
|
||||||
color: Theme.of(context).primaryTextTheme.title.color,
|
color: Colors.white,
|
||||||
height: 8,
|
height: 8,
|
||||||
);
|
);
|
||||||
final Image arrowBottomCakeGreen = Image.asset(
|
final arrowBottomCakeGreen = Image.asset(
|
||||||
'assets/images/arrow_bottom_cake_green.png',
|
'assets/images/arrow_bottom_cake_green.png',
|
||||||
color: Theme.of(context).primaryTextTheme.title.color,
|
color: Colors.white,
|
||||||
height: 8,
|
height: 8,
|
||||||
);
|
);
|
||||||
|
|
||||||
final depositWalletName =
|
final depositWalletName =
|
||||||
exchangeStore.depositCurrency == CryptoCurrency.xmr
|
exchangeViewModel.depositCurrency == CryptoCurrency.xmr
|
||||||
? walletStore.name
|
? exchangeViewModel.wallet.name
|
||||||
: null;
|
: null;
|
||||||
final receiveWalletName =
|
final receiveWalletName =
|
||||||
exchangeStore.receiveCurrency == CryptoCurrency.xmr
|
exchangeViewModel.receiveCurrency == CryptoCurrency.xmr
|
||||||
? walletStore.name
|
? exchangeViewModel.wallet.name
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback(
|
WidgetsBinding.instance.addPostFrameCallback(
|
||||||
(_) => _setReactions(context, exchangeStore, walletStore));
|
(_) => _setReactions(context, exchangeViewModel));
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
color: Theme.of(context).backgroundColor,
|
color: PaletteDark.backgroundColor,
|
||||||
child: Form(
|
child: Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: ScrollableWithBottomSection(
|
child: ScrollableWithBottomSection(
|
||||||
|
@ -96,73 +86,60 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
content: Column(
|
content: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TopPanel(
|
TopPanel(
|
||||||
color: Theme.of(context).accentTextTheme.title.backgroundColor,
|
color: PaletteDark.darkNightBlue,
|
||||||
edgeInsets: EdgeInsets.only(bottom: 24),
|
edgeInsets: EdgeInsets.only(bottom: 32),
|
||||||
widget: Column(
|
widget: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TopPanel(
|
TopPanel(
|
||||||
color: Theme.of(context).accentTextTheme.title.color,
|
edgeInsets: EdgeInsets.fromLTRB(24, 29, 24, 32),
|
||||||
|
color: PaletteDark.wildVioletBlue,
|
||||||
widget: Observer(
|
widget: Observer(
|
||||||
builder: (_) => ExchangeCard(
|
builder: (_) => ExchangeCard(
|
||||||
key: depositKey,
|
key: depositKey,
|
||||||
title: S.of(context).you_will_send,
|
title: S.of(context).you_will_send,
|
||||||
initialCurrency: exchangeStore.depositCurrency,
|
initialCurrency: exchangeViewModel.depositCurrency,
|
||||||
initialWalletName: depositWalletName,
|
initialWalletName: depositWalletName,
|
||||||
initialAddress:
|
initialAddress:
|
||||||
exchangeStore.depositCurrency == walletStore.type
|
exchangeViewModel.depositCurrency == exchangeViewModel.wallet.currency
|
||||||
? walletStore.address
|
? exchangeViewModel.wallet.address
|
||||||
: exchangeStore.depositAddress,
|
: exchangeViewModel.depositAddress,
|
||||||
initialIsAmountEditable: true,
|
initialIsAmountEditable: true,
|
||||||
initialIsAddressEditable: exchangeStore.isDepositAddressEnabled,
|
initialIsAddressEditable: exchangeViewModel.isDepositAddressEnabled,
|
||||||
isAmountEstimated: false,
|
isAmountEstimated: false,
|
||||||
currencies: CryptoCurrency.all,
|
currencies: CryptoCurrency.all,
|
||||||
onCurrencySelected: (currency) =>
|
onCurrencySelected: (currency) =>
|
||||||
exchangeStore.changeDepositCurrency(currency: currency),
|
exchangeViewModel.changeDepositCurrency(currency: currency),
|
||||||
imageArrow: arrowBottomPurple,
|
imageArrow: arrowBottomPurple,
|
||||||
currencyButtonColor: Theme.of(context).accentTextTheme.title.color,
|
currencyButtonColor: PaletteDark.wildVioletBlue,
|
||||||
addressButtonsColor: Theme.of(context).accentTextTheme.title.backgroundColor,
|
addressButtonsColor: PaletteDark.moderateBlue,
|
||||||
currencyValueValidator: (value) {
|
currencyValueValidator: exchangeViewModel.amountValidator,
|
||||||
exchangeStore.validateCryptoCurrency(value);
|
addressTextFieldValidator: exchangeViewModel.addressValidator,
|
||||||
return exchangeStore.errorMessage;
|
|
||||||
},
|
|
||||||
addressTextFieldValidator: (value) {
|
|
||||||
exchangeStore.validateAddress(value,
|
|
||||||
cryptoCurrency: exchangeStore.depositCurrency);
|
|
||||||
return exchangeStore.errorMessage;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 32, left: 24, right: 24),
|
padding: EdgeInsets.only(top: 29, left: 24, right: 24),
|
||||||
child: Observer(
|
child: Observer(
|
||||||
builder: (_) => ExchangeCard(
|
builder: (_) => ExchangeCard(
|
||||||
key: receiveKey,
|
key: receiveKey,
|
||||||
title: S.of(context).you_will_get,
|
title: S.of(context).you_will_get,
|
||||||
initialCurrency: exchangeStore.receiveCurrency,
|
initialCurrency: exchangeViewModel.receiveCurrency,
|
||||||
initialWalletName: receiveWalletName,
|
initialWalletName: receiveWalletName,
|
||||||
initialAddress:
|
initialAddress:
|
||||||
exchangeStore.receiveCurrency == walletStore.type
|
exchangeViewModel.receiveCurrency == exchangeViewModel.wallet.currency
|
||||||
? walletStore.address
|
? exchangeViewModel.wallet.address
|
||||||
: exchangeStore.receiveAddress,
|
: exchangeViewModel.receiveAddress,
|
||||||
initialIsAmountEditable: false,
|
initialIsAmountEditable: false,
|
||||||
initialIsAddressEditable: exchangeStore.isReceiveAddressEnabled,
|
initialIsAddressEditable: exchangeViewModel.isReceiveAddressEnabled,
|
||||||
isAmountEstimated: true,
|
isAmountEstimated: true,
|
||||||
currencies: CryptoCurrency.all,
|
currencies: CryptoCurrency.all,
|
||||||
onCurrencySelected: (currency) => exchangeStore
|
onCurrencySelected: (currency) => exchangeViewModel
|
||||||
.changeReceiveCurrency(currency: currency),
|
.changeReceiveCurrency(currency: currency),
|
||||||
imageArrow: arrowBottomCakeGreen,
|
imageArrow: arrowBottomCakeGreen,
|
||||||
currencyButtonColor: Theme.of(context).accentTextTheme.title.backgroundColor,
|
currencyButtonColor: PaletteDark.darkNightBlue,
|
||||||
addressButtonsColor: Theme.of(context).accentTextTheme.title.color,
|
addressButtonsColor: PaletteDark.moderateBlue,
|
||||||
currencyValueValidator: (value) {
|
currencyValueValidator: exchangeViewModel.amountValidator,
|
||||||
exchangeStore.validateCryptoCurrency(value);
|
addressTextFieldValidator: exchangeViewModel.addressValidator,
|
||||||
return exchangeStore.errorMessage;
|
|
||||||
},
|
|
||||||
addressTextFieldValidator: (value) {
|
|
||||||
exchangeStore.validateAddress(value,
|
|
||||||
cryptoCurrency: exchangeStore.receiveCurrency);
|
|
||||||
return exchangeStore.errorMessage;
|
|
||||||
},
|
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -172,7 +149,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
? Offstage()
|
? Offstage()
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
top: 32,
|
top: 30,
|
||||||
left: 24,
|
left: 24,
|
||||||
bottom: 24
|
bottom: 24
|
||||||
),
|
),
|
||||||
|
@ -184,7 +161,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color
|
color: PaletteDark.darkCyanBlue
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -196,29 +173,23 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
height: 40,
|
height: 40,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: EdgeInsets.only(left: 24),
|
padding: EdgeInsets.only(left: 24),
|
||||||
child: Observer(
|
child: SingleChildScrollView(
|
||||||
builder: (_) {
|
|
||||||
final itemCount = exchangeTemplateStore.templates.length + 1;
|
|
||||||
|
|
||||||
return ListView.builder(
|
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: itemCount,
|
child: Row(
|
||||||
itemBuilder: (context, index) {
|
children: <Widget>[
|
||||||
|
GestureDetector(
|
||||||
if (index == 0) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: () => Navigator.of(context)
|
onTap: () => Navigator.of(context)
|
||||||
.pushNamed(Routes.exchangeTemplate),
|
.pushNamed(Routes.exchangeTemplate),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.only(right: 10),
|
padding: EdgeInsets.only(left: 1, right: 10),
|
||||||
child: DottedBorder(
|
child: DottedBorder(
|
||||||
borderType: BorderType.RRect,
|
borderType: BorderType.RRect,
|
||||||
dashPattern: [8, 4],
|
dashPattern: [6, 4],
|
||||||
color: Theme.of(context).accentTextTheme.title.backgroundColor,
|
color: PaletteDark.darkCyanBlue,
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
radius: Radius.circular(20),
|
radius: Radius.circular(20),
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 40,
|
height: 34,
|
||||||
width: 75,
|
width: 75,
|
||||||
padding: EdgeInsets.only(left: 10, right: 10),
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
@ -231,31 +202,61 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color
|
color: PaletteDark.darkCyanBlue
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}
|
Observer(
|
||||||
|
builder: (_) {
|
||||||
|
final templates = exchangeViewModel.templates;
|
||||||
|
final itemCount = exchangeViewModel.templates.length;
|
||||||
|
|
||||||
index -= 1;
|
return ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
final template = exchangeTemplateStore.templates[index];
|
shrinkWrap: true,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
|
itemCount: itemCount,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final template = templates[index];
|
||||||
|
|
||||||
return TemplateTile(
|
return TemplateTile(
|
||||||
|
key: UniqueKey(),
|
||||||
amount: template.amount,
|
amount: template.amount,
|
||||||
from: template.depositCurrency,
|
from: template.depositCurrency,
|
||||||
to: template.receiveCurrency,
|
to: template.receiveCurrency,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
applyTemplate(exchangeStore, template);
|
applyTemplate(exchangeViewModel, template);
|
||||||
|
},
|
||||||
|
onRemove: () {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (dialogContext) {
|
||||||
|
return AlertWithTwoActions(
|
||||||
|
alertTitle: S.of(context).template,
|
||||||
|
alertContent: S.of(context).confirm_delete_template,
|
||||||
|
leftButtonText: S.of(context).delete,
|
||||||
|
rightButtonText: S.of(context).cancel,
|
||||||
|
actionLeftButton: () {
|
||||||
|
Navigator.of(dialogContext).pop();
|
||||||
|
exchangeViewModel.exchangeTemplateStore.remove(template: template);
|
||||||
|
exchangeViewModel.exchangeTemplateStore.update();
|
||||||
|
},
|
||||||
|
actionRightButton: () => Navigator.of(dialogContext).pop()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -265,14 +266,15 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
padding: EdgeInsets.only(bottom: 15),
|
padding: EdgeInsets.only(bottom: 15),
|
||||||
child: Observer(builder: (_) {
|
child: Observer(builder: (_) {
|
||||||
final description =
|
final description =
|
||||||
exchangeStore.provider is XMRTOExchangeProvider
|
exchangeViewModel.provider is XMRTOExchangeProvider
|
||||||
? S.of(context).amount_is_guaranteed
|
? S.of(context).amount_is_guaranteed
|
||||||
: S.of(context).amount_is_estimate;
|
: S.of(context).amount_is_estimate;
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
description,
|
description,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
color: PaletteDark.darkCyanBlue,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
fontSize: 12
|
fontSize: 12
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -283,15 +285,15 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
? PrimaryButton(
|
? PrimaryButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_formKey.currentState.validate()) {
|
if (_formKey.currentState.validate()) {
|
||||||
exchangeTemplateStore.addTemplate(
|
exchangeViewModel.exchangeTemplateStore.addTemplate(
|
||||||
amount: exchangeStore.depositAmount,
|
amount: exchangeViewModel.depositAmount,
|
||||||
depositCurrency: exchangeStore.depositCurrency.toString(),
|
depositCurrency: exchangeViewModel.depositCurrency.toString(),
|
||||||
receiveCurrency: exchangeStore.receiveCurrency.toString(),
|
receiveCurrency: exchangeViewModel.receiveCurrency.toString(),
|
||||||
provider: exchangeStore.provider.toString(),
|
provider: exchangeViewModel.provider.toString(),
|
||||||
depositAddress: exchangeStore.depositAddress,
|
depositAddress: exchangeViewModel.depositAddress,
|
||||||
receiveAddress: exchangeStore.receiveAddress
|
receiveAddress: exchangeViewModel.receiveAddress
|
||||||
);
|
);
|
||||||
exchangeTemplateStore.update();
|
exchangeViewModel.exchangeTemplateStore.update();
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -304,41 +306,47 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
text: S.of(context).exchange,
|
text: S.of(context).exchange,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_formKey.currentState.validate()) {
|
if (_formKey.currentState.validate()) {
|
||||||
exchangeStore.createTrade();
|
exchangeViewModel.createTrade();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
isLoading: exchangeStore.tradeState is TradeIsCreating,
|
isLoading: exchangeViewModel.tradeState is TradeIsCreating,
|
||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyTemplate(ExchangeStore store, ExchangeTemplate template) {
|
void applyTemplate(ExchangeViewModel exchangeViewModel,
|
||||||
store.changeDepositCurrency(currency: CryptoCurrency.fromString(template.depositCurrency));
|
ExchangeTemplate template) {
|
||||||
store.changeReceiveCurrency(currency: CryptoCurrency.fromString(template.receiveCurrency));
|
exchangeViewModel.changeDepositCurrency(
|
||||||
|
currency: CryptoCurrency.fromString(template.depositCurrency));
|
||||||
|
exchangeViewModel.changeReceiveCurrency(
|
||||||
|
currency: CryptoCurrency.fromString(template.receiveCurrency));
|
||||||
|
|
||||||
switch (template.provider) {
|
switch (template.provider) {
|
||||||
case 'XMR.TO':
|
case 'XMR.TO':
|
||||||
store.changeProvider(provider: store.providerList[0]);
|
exchangeViewModel.changeProvider(
|
||||||
|
provider: exchangeViewModel.providerList[0]);
|
||||||
break;
|
break;
|
||||||
case 'ChangeNOW':
|
case 'ChangeNOW':
|
||||||
store.changeProvider(provider: store.providerList[1]);
|
exchangeViewModel.changeProvider(
|
||||||
|
provider: exchangeViewModel.providerList[1]);
|
||||||
break;
|
break;
|
||||||
case 'MorphToken':
|
case 'MorphToken':
|
||||||
store.changeProvider(provider: store.providerList[2]);
|
exchangeViewModel.changeProvider(
|
||||||
|
provider: exchangeViewModel.providerList[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
store.changeDepositAmount(amount: template.amount);
|
exchangeViewModel.changeDepositAmount(amount: template.amount);
|
||||||
store.depositAddress = template.depositAddress;
|
exchangeViewModel.depositAddress = template.depositAddress;
|
||||||
store.receiveAddress = template.receiveAddress;
|
exchangeViewModel.receiveAddress = template.receiveAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setReactions(
|
void _setReactions(
|
||||||
BuildContext context, ExchangeStore store, WalletStore walletStore) {
|
BuildContext context, ExchangeViewModel exchangeViewModel) {
|
||||||
if (_isReactionsSet) {
|
if (_isReactionsSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +355,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
final depositAmountController = depositKey.currentState.amountController;
|
final depositAmountController = depositKey.currentState.amountController;
|
||||||
final receiveAddressController = receiveKey.currentState.addressController;
|
final receiveAddressController = receiveKey.currentState.addressController;
|
||||||
final receiveAmountController = receiveKey.currentState.amountController;
|
final receiveAmountController = receiveKey.currentState.amountController;
|
||||||
final limitsState = store.limitsState;
|
final limitsState = exchangeViewModel.limitsState;
|
||||||
|
|
||||||
if (limitsState is LimitsLoadedSuccessfully) {
|
if (limitsState is LimitsLoadedSuccessfully) {
|
||||||
final min = limitsState.limits.min != null
|
final min = limitsState.limits.min != null
|
||||||
|
@ -360,63 +368,62 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
key.currentState.changeLimits(min: min, max: max);
|
key.currentState.changeLimits(min: min, max: max);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCurrencyChange(store.receiveCurrency, walletStore, receiveKey);
|
_onCurrencyChange(exchangeViewModel.receiveCurrency, exchangeViewModel, receiveKey);
|
||||||
_onCurrencyChange(store.depositCurrency, walletStore, depositKey);
|
_onCurrencyChange(exchangeViewModel.depositCurrency, exchangeViewModel, depositKey);
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => walletStore.name,
|
(_) => exchangeViewModel.wallet.name,
|
||||||
(String _) => _onWalletNameChange(
|
(String _) => _onWalletNameChange(
|
||||||
walletStore, store.receiveCurrency, receiveKey));
|
exchangeViewModel, exchangeViewModel.receiveCurrency, receiveKey));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => walletStore.name,
|
(_) => exchangeViewModel.wallet.name,
|
||||||
(String _) => _onWalletNameChange(
|
(String _) => _onWalletNameChange(
|
||||||
walletStore, store.depositCurrency, depositKey));
|
exchangeViewModel, exchangeViewModel.depositCurrency, depositKey));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => store.receiveCurrency,
|
(_) => exchangeViewModel.receiveCurrency,
|
||||||
(CryptoCurrency currency) =>
|
(CryptoCurrency currency) =>
|
||||||
_onCurrencyChange(currency, walletStore, receiveKey));
|
_onCurrencyChange(currency, exchangeViewModel, receiveKey));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => store.depositCurrency,
|
(_) => exchangeViewModel.depositCurrency,
|
||||||
(CryptoCurrency currency) =>
|
(CryptoCurrency currency) =>
|
||||||
_onCurrencyChange(currency, walletStore, depositKey));
|
_onCurrencyChange(currency, exchangeViewModel, depositKey));
|
||||||
|
|
||||||
reaction((_) => store.depositAmount, (String amount) {
|
reaction((_) => exchangeViewModel.depositAmount, (String amount) {
|
||||||
if (depositKey.currentState.amountController.text != amount) {
|
if (depositKey.currentState.amountController.text != amount) {
|
||||||
depositKey.currentState.amountController.text = amount;
|
depositKey.currentState.amountController.text = amount;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.depositAddress, (String address) {
|
reaction((_) => exchangeViewModel.depositAddress, (String address) {
|
||||||
if (depositKey.currentState.addressController.text != address) {
|
if (depositKey.currentState.addressController.text != address) {
|
||||||
depositKey.currentState.addressController.text = address;
|
depositKey.currentState.addressController.text = address;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.isDepositAddressEnabled, (bool isEnabled) {
|
reaction((_) => exchangeViewModel.isDepositAddressEnabled, (bool isEnabled) {
|
||||||
depositKey.currentState.isAddressEditable(isEditable: isEnabled);
|
depositKey.currentState.isAddressEditable(isEditable: isEnabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.receiveAmount, (String amount) {
|
reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
|
||||||
if (receiveKey.currentState.amountController.text !=
|
if (receiveKey.currentState.amountController.text != amount) {
|
||||||
store.receiveAmount) {
|
|
||||||
receiveKey.currentState.amountController.text = amount;
|
receiveKey.currentState.amountController.text = amount;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.receiveAddress, (String address) {
|
reaction((_) => exchangeViewModel.receiveAddress, (String address) {
|
||||||
if (receiveKey.currentState.addressController.text != address) {
|
if (receiveKey.currentState.addressController.text != address) {
|
||||||
receiveKey.currentState.addressController.text = address;
|
receiveKey.currentState.addressController.text = address;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.isReceiveAddressEnabled, (bool isEnabled) {
|
reaction((_) => exchangeViewModel.isReceiveAddressEnabled, (bool isEnabled) {
|
||||||
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
|
receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.tradeState, (ExchangeTradeState state) {
|
reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) {
|
||||||
if (state is TradeIsCreatedFailure) {
|
if (state is TradeIsCreatedFailure) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
showDialog<void>(
|
showDialog<void>(
|
||||||
|
@ -437,7 +444,7 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => store.limitsState, (LimitsState state) {
|
reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
|
||||||
String min;
|
String min;
|
||||||
String max;
|
String max;
|
||||||
|
|
||||||
|
@ -461,29 +468,29 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
});
|
});
|
||||||
|
|
||||||
depositAddressController.addListener(
|
depositAddressController.addListener(
|
||||||
() => store.depositAddress = depositAddressController.text);
|
() => exchangeViewModel.depositAddress = depositAddressController.text);
|
||||||
|
|
||||||
depositAmountController.addListener(() {
|
depositAmountController.addListener(() {
|
||||||
if (depositAmountController.text != store.depositAmount) {
|
if (depositAmountController.text != exchangeViewModel.depositAmount) {
|
||||||
store.changeDepositAmount(amount: depositAmountController.text);
|
exchangeViewModel.changeDepositAmount(amount: depositAmountController.text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
receiveAddressController.addListener(
|
receiveAddressController.addListener(
|
||||||
() => store.receiveAddress = receiveAddressController.text);
|
() => exchangeViewModel.receiveAddress = receiveAddressController.text);
|
||||||
|
|
||||||
receiveAmountController.addListener(() {
|
receiveAmountController.addListener(() {
|
||||||
if (receiveAmountController.text != store.receiveAmount) {
|
if (receiveAmountController.text != exchangeViewModel.receiveAmount) {
|
||||||
store.changeReceiveAmount(amount: receiveAmountController.text);
|
exchangeViewModel.changeReceiveAmount(amount: receiveAmountController.text);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reaction((_) => walletStore.address, (String address) {
|
reaction((_) => exchangeViewModel.wallet.address, (String address) {
|
||||||
if (store.depositCurrency == CryptoCurrency.xmr) {
|
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||||
depositKey.currentState.changeAddress(address: address);
|
depositKey.currentState.changeAddress(address: address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (store.receiveCurrency == CryptoCurrency.xmr) {
|
if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
|
||||||
receiveKey.currentState.changeAddress(address: address);
|
receiveKey.currentState.changeAddress(address: address);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -491,28 +498,33 @@ class BaseExchangeWidgetState extends State<BaseExchangeWidget> {
|
||||||
_isReactionsSet = true;
|
_isReactionsSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCurrencyChange(CryptoCurrency currency, WalletStore walletStore,
|
void _onCurrencyChange(CryptoCurrency currency,
|
||||||
|
ExchangeViewModel exchangeViewModel,
|
||||||
GlobalKey<ExchangeCardState> key) {
|
GlobalKey<ExchangeCardState> key) {
|
||||||
final isCurrentTypeWallet = currency == walletStore.type;
|
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
|
||||||
|
|
||||||
key.currentState.changeSelectedCurrency(currency);
|
key.currentState.changeSelectedCurrency(currency);
|
||||||
key.currentState
|
key.currentState
|
||||||
.changeWalletName(isCurrentTypeWallet ? walletStore.name : null);
|
.changeWalletName(isCurrentTypeWallet
|
||||||
|
? exchangeViewModel.wallet.name : null);
|
||||||
|
|
||||||
key.currentState
|
key.currentState
|
||||||
.changeAddress(address: isCurrentTypeWallet ? walletStore.address : '');
|
.changeAddress(address: isCurrentTypeWallet
|
||||||
|
? exchangeViewModel.wallet.address : '');
|
||||||
|
|
||||||
key.currentState.changeAmount(amount: '');
|
key.currentState.changeAmount(amount: '');
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onWalletNameChange(WalletStore walletStore, CryptoCurrency currency,
|
void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
|
||||||
|
CryptoCurrency currency,
|
||||||
GlobalKey<ExchangeCardState> key) {
|
GlobalKey<ExchangeCardState> key) {
|
||||||
final isCurrentTypeWallet = currency == walletStore.type;
|
final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
|
||||||
|
|
||||||
if (isCurrentTypeWallet) {
|
if (isCurrentTypeWallet) {
|
||||||
key.currentState.changeWalletName(walletStore.name);
|
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||||
key.currentState.addressController.text = walletStore.address;
|
key.currentState.addressController.text = exchangeViewModel.wallet.address;
|
||||||
} else if (key.currentState.addressController.text == walletStore.address) {
|
} else if (key.currentState.addressController.text ==
|
||||||
|
exchangeViewModel.wallet.address) {
|
||||||
key.currentState.changeWalletName(null);
|
key.currentState.changeWalletName(null);
|
||||||
key.currentState.addressController.text = null;
|
key.currentState.addressController.text = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
|
||||||
class ExchangeCard extends StatefulWidget {
|
class ExchangeCard extends StatefulWidget {
|
||||||
ExchangeCard(
|
ExchangeCard(
|
||||||
|
@ -57,6 +58,10 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
bool _isAddressEditable;
|
bool _isAddressEditable;
|
||||||
bool _isAmountEstimated;
|
bool _isAmountEstimated;
|
||||||
|
|
||||||
|
final copyImage = Image.asset('assets/images/copy_content.png',
|
||||||
|
height: 16, width: 16,
|
||||||
|
color: Colors.white);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_title = widget.title;
|
_title = widget.title;
|
||||||
|
@ -114,6 +119,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
@ -123,13 +129,13 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color
|
color: PaletteDark.lightBlueGrey
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 10),
|
padding: EdgeInsets.only(top: 20),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
BaseTextFormField(
|
BaseTextFormField(
|
||||||
|
@ -143,7 +149,20 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
RegExp('[\\-|\\ |\\,]'))
|
RegExp('[\\-|\\ |\\,]'))
|
||||||
],
|
],
|
||||||
hintText: '0.0000',
|
hintText: '0.0000',
|
||||||
validator: widget.currencyValueValidator
|
borderColor: PaletteDark.blueGrey,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white
|
||||||
|
),
|
||||||
|
placeholderTextStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: PaletteDark.lightBlueGrey
|
||||||
|
),
|
||||||
|
validator: _isAmountEditable
|
||||||
|
? widget.currencyValueValidator
|
||||||
|
: null
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 8,
|
top: 8,
|
||||||
|
@ -163,7 +182,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Theme.of(context).primaryTextTheme.title.color)),
|
color: Colors.white)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(left: 5),
|
padding: EdgeInsets.only(left: 5),
|
||||||
child: widget.imageArrow,
|
child: widget.imageArrow,
|
||||||
|
@ -187,7 +206,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
height: 1.2,
|
height: 1.2,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color),
|
color: PaletteDark.lightBlueGrey),
|
||||||
)
|
)
|
||||||
: Offstage(),
|
: Offstage(),
|
||||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||||
|
@ -198,28 +217,79 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
height: 1.2,
|
height: 1.2,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color))
|
color: PaletteDark.lightBlueGrey))
|
||||||
: Offstage(),
|
: Offstage(),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 10),
|
padding: EdgeInsets.only(top: 20),
|
||||||
child: AddressTextField(
|
child: Text(
|
||||||
controller: addressController,
|
_isAddressEditable
|
||||||
isActive: _isAddressEditable,
|
? S.of(context).widgets_address
|
||||||
options: _isAddressEditable
|
: S.of(context).refund_address,
|
||||||
? _walletName != null
|
style: TextStyle(
|
||||||
? []
|
fontSize: 14,
|
||||||
: [
|
fontWeight: FontWeight.w500,
|
||||||
AddressTextFieldOption.qrCode,
|
color: PaletteDark.lightBlueGrey
|
||||||
AddressTextFieldOption.addressBook,
|
|
||||||
]
|
|
||||||
: [],
|
|
||||||
isBorderExist: false,
|
|
||||||
buttonColor: widget.addressButtonsColor,
|
|
||||||
validator: widget.addressTextFieldValidator,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
_isAddressEditable
|
||||||
|
? AddressTextField(
|
||||||
|
controller: addressController,
|
||||||
|
options: [
|
||||||
|
AddressTextFieldOption.paste,
|
||||||
|
AddressTextFieldOption.qrCode,
|
||||||
|
AddressTextFieldOption.addressBook,
|
||||||
|
],
|
||||||
|
placeholder: '',
|
||||||
|
isBorderExist: false,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
|
buttonColor: widget.addressButtonsColor,
|
||||||
|
validator: widget.addressTextFieldValidator,
|
||||||
|
)
|
||||||
|
: Padding(
|
||||||
|
padding: EdgeInsets.only(top: 10),
|
||||||
|
child: Builder(
|
||||||
|
builder: (context) => GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Clipboard.setData(ClipboardData(
|
||||||
|
text: addressController.text));
|
||||||
|
Scaffold.of(context).showSnackBar(SnackBar(
|
||||||
|
content: Text(
|
||||||
|
S.of(context).copied_to_clipboard,
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.green,
|
||||||
|
duration: Duration(milliseconds: 500),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
addressController.text,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 16),
|
||||||
|
child: copyImage,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/src/stores/exchange/exchange_store.dart';
|
|
||||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
|
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
|
||||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
|
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
|
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
|
||||||
class PresentProviderPicker extends StatelessWidget {
|
class PresentProviderPicker extends StatelessWidget {
|
||||||
PresentProviderPicker({@required this.exchangeStore});
|
PresentProviderPicker({@required this.exchangeViewModel});
|
||||||
|
|
||||||
final ExchangeStore exchangeStore;
|
final ExchangeViewModel exchangeViewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final Image arrowBottom =
|
final arrowBottom =
|
||||||
Image.asset('assets/images/arrow_bottom_purple_icon.png',
|
Image.asset('assets/images/arrow_bottom_purple_icon.png',
|
||||||
color: Theme.of(context).primaryTextTheme.title.color,
|
color: Colors.white,
|
||||||
height: 6);
|
height: 6);
|
||||||
|
|
||||||
return FlatButton(
|
return FlatButton(
|
||||||
|
@ -33,19 +34,19 @@ class PresentProviderPicker extends StatelessWidget {
|
||||||
Text(S.of(context).exchange,
|
Text(S.of(context).exchange,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16.0,
|
fontSize: 16.0,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).primaryTextTheme.title.color)),
|
color: Colors.white)),
|
||||||
Observer(
|
Observer(
|
||||||
builder: (_) => Text('${exchangeStore.provider.title}',
|
builder: (_) => Text('${exchangeViewModel.provider.title}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 10.0,
|
fontSize: 10.0,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color)))
|
color: PaletteDark.lightBlueGrey)))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(width: 5),
|
SizedBox(width: 5),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 8),
|
padding: EdgeInsets.only(top: 12),
|
||||||
child: arrowBottom,
|
child: arrowBottom,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -54,11 +55,11 @@ class PresentProviderPicker extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _presentProviderPicker(BuildContext context) {
|
void _presentProviderPicker(BuildContext context) {
|
||||||
final items = exchangeStore.providersForCurrentPair();
|
final items = exchangeViewModel.providersForCurrentPair();
|
||||||
final selectedItem = items.indexOf(exchangeStore.provider);
|
final selectedItem = items.indexOf(exchangeViewModel.provider);
|
||||||
final images = List<Image>();
|
final images = <Image>[];
|
||||||
|
|
||||||
for (ExchangeProvider provider in items) {
|
for (var provider in items) {
|
||||||
switch (provider.description) {
|
switch (provider.description) {
|
||||||
case ExchangeProviderDescription.xmrto:
|
case ExchangeProviderDescription.xmrto:
|
||||||
images.add(Image.asset('assets/images/xmr_btc.png'));
|
images.add(Image.asset('assets/images/xmr_btc.png'));
|
||||||
|
@ -79,7 +80,7 @@ class PresentProviderPicker extends StatelessWidget {
|
||||||
selectedAtIndex: selectedItem,
|
selectedAtIndex: selectedItem,
|
||||||
title: S.of(context).change_exchange_provider,
|
title: S.of(context).change_exchange_provider,
|
||||||
onItemSelected: (ExchangeProvider provider) =>
|
onItemSelected: (ExchangeProvider provider) =>
|
||||||
exchangeStore.changeProvider(provider: provider)),
|
exchangeViewModel.changeProvider(provider: provider)),
|
||||||
context: context);
|
context: context);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -125,7 +125,7 @@ class ReceivePage extends BasePage {
|
||||||
.headline5
|
.headline5
|
||||||
.color
|
.color
|
||||||
.withOpacity(0.4),
|
.withOpacity(0.4),
|
||||||
validator: AmountValidator(),
|
validator: AmountValidator(isAutovalidate: true),
|
||||||
autovalidate: true,
|
autovalidate: true,
|
||||||
placeholderTextStyle: TextStyle(
|
placeholderTextStyle: TextStyle(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
|
|
|
@ -72,6 +72,10 @@ class BaseTextFormField extends StatelessWidget {
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: borderColor ?? Theme.of(context).dividerColor,
|
color: borderColor ?? Theme.of(context).dividerColor,
|
||||||
width: 1.0)),
|
width: 1.0)),
|
||||||
|
disabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: borderColor ?? Theme.of(context).dividerColor,
|
||||||
|
width: 1.0)),
|
||||||
enabledBorder: UnderlineInputBorder(
|
enabledBorder: UnderlineInputBorder(
|
||||||
borderSide: BorderSide(
|
borderSide: BorderSide(
|
||||||
color: borderColor ?? Theme.of(context).dividerColor,
|
color: borderColor ?? Theme.of(context).dividerColor,
|
||||||
|
|
|
@ -71,6 +71,8 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
|
||||||
EdgeInsetsDirectional.only(bottom: _paddingBottom, top: paddingTop),
|
EdgeInsetsDirectional.only(bottom: _paddingBottom, top: paddingTop),
|
||||||
child: CupertinoNavigationBar(
|
child: CupertinoNavigationBar(
|
||||||
leading: leading,
|
leading: leading,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
automaticallyImplyMiddle: false,
|
||||||
middle: middle,
|
middle: middle,
|
||||||
trailing: trailing,
|
trailing: trailing,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:cake_wallet/palette.dart';
|
||||||
|
|
||||||
class TrailButton extends StatelessWidget {
|
class TrailButton extends StatelessWidget {
|
||||||
TrailButton({
|
TrailButton({
|
||||||
|
@ -21,7 +22,7 @@ class TrailButton extends StatelessWidget {
|
||||||
child: Text(
|
child: Text(
|
||||||
caption,
|
caption,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryTextTheme.caption.color,
|
color: PaletteDark.lightBlueGrey,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
|
|
306
lib/view_model/exchange/exchange_view_model.dart
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
import 'package:cake_wallet/core/address_validator.dart';
|
||||||
|
import 'package:cake_wallet/core/amount_validator.dart';
|
||||||
|
import 'package:cake_wallet/core/template_validator.dart';
|
||||||
|
import 'package:cake_wallet/core/validator.dart';
|
||||||
|
import 'package:cake_wallet/core/wallet_base.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/limits.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/trade.dart';
|
||||||
|
import 'package:cake_wallet/src/stores/exchange/limits_state.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:cake_wallet/src/stores/exchange/exchange_trade_state.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/changenow/changenow_exchange_provider.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/changenow/changenow_request.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/trade_request.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_exchange_provider.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_trade_request.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/morphtoken/morphtoken_exchange_provider.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/morphtoken/morphtoken_request.dart';
|
||||||
|
import 'package:cake_wallet/store/templates/exchange_template_store.dart';
|
||||||
|
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||||
|
|
||||||
|
part 'exchange_view_model.g.dart';
|
||||||
|
|
||||||
|
class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
|
||||||
|
|
||||||
|
abstract class ExchangeViewModelBase with Store {
|
||||||
|
ExchangeViewModelBase({this.wallet, this.trades, this.exchangeTemplateStore}) {
|
||||||
|
providerList = [
|
||||||
|
XMRTOExchangeProvider(),
|
||||||
|
ChangeNowExchangeProvider(),
|
||||||
|
MorphTokenExchangeProvider(trades: trades)
|
||||||
|
];
|
||||||
|
|
||||||
|
provider = providerList[ 0 ];
|
||||||
|
|
||||||
|
depositCurrency = CryptoCurrency.xmr;
|
||||||
|
receiveCurrency = CryptoCurrency.btc;
|
||||||
|
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||||
|
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
depositAddress = '';
|
||||||
|
receiveAddress = '';
|
||||||
|
limitsState = LimitsInitialState();
|
||||||
|
tradeState = ExchangeTradeStateInitial();
|
||||||
|
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
|
||||||
|
loadLimits();
|
||||||
|
}
|
||||||
|
|
||||||
|
final WalletBase wallet;
|
||||||
|
final Box<Trade> trades;
|
||||||
|
final ExchangeTemplateStore exchangeTemplateStore;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
ExchangeProvider provider;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
List<ExchangeProvider> providerList;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
CryptoCurrency depositCurrency;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
CryptoCurrency receiveCurrency;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
LimitsState limitsState;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
ExchangeTradeState tradeState;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String depositAmount;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String receiveAmount;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String depositAddress;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String receiveAddress;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isDepositAddressEnabled;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isReceiveAddressEnabled;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
bool isValid;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String errorMessage;
|
||||||
|
|
||||||
|
Limits limits;
|
||||||
|
|
||||||
|
NumberFormat _cryptoNumberFormat;
|
||||||
|
|
||||||
|
Validator get amountValidator => AmountValidator(type: wallet.type);
|
||||||
|
|
||||||
|
Validator get addressValidator => AddressValidator(type: wallet.currency);
|
||||||
|
|
||||||
|
Validator get templateValidator => TemplateValidator();
|
||||||
|
|
||||||
|
@computed
|
||||||
|
ObservableList<ExchangeTemplate> get templates =>
|
||||||
|
exchangeTemplateStore.templates;
|
||||||
|
|
||||||
|
@action
|
||||||
|
void changeProvider({ExchangeProvider provider}) {
|
||||||
|
this.provider = provider;
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
loadLimits();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void changeDepositCurrency({CryptoCurrency currency}) {
|
||||||
|
depositCurrency = currency;
|
||||||
|
_onPairChange();
|
||||||
|
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||||
|
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void changeReceiveCurrency({CryptoCurrency currency}) {
|
||||||
|
receiveCurrency = currency;
|
||||||
|
_onPairChange();
|
||||||
|
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||||
|
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void changeReceiveAmount({String amount}) {
|
||||||
|
receiveAmount = amount;
|
||||||
|
|
||||||
|
if (amount == null || amount.isEmpty) {
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final _amount = double.parse(amount) ?? 0;
|
||||||
|
|
||||||
|
provider
|
||||||
|
.calculateAmount(
|
||||||
|
from: depositCurrency, to: receiveCurrency, amount: _amount)
|
||||||
|
.then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), ""))
|
||||||
|
.then((amount) => depositAmount = amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void changeDepositAmount({String amount}) {
|
||||||
|
depositAmount = amount;
|
||||||
|
|
||||||
|
if (amount == null || amount.isEmpty) {
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final _amount = double.parse(amount);
|
||||||
|
provider
|
||||||
|
.calculateAmount(
|
||||||
|
from: depositCurrency, to: receiveCurrency, amount: _amount)
|
||||||
|
.then((amount) => _cryptoNumberFormat.format(amount).toString().replaceAll(RegExp("\\,"), ""))
|
||||||
|
.then((amount) => receiveAmount = amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future loadLimits() async {
|
||||||
|
limitsState = LimitsIsLoading();
|
||||||
|
|
||||||
|
try {
|
||||||
|
limits = await provider.fetchLimits(
|
||||||
|
from: depositCurrency, to: receiveCurrency);
|
||||||
|
limitsState = LimitsLoadedSuccessfully(limits: limits);
|
||||||
|
} catch (e) {
|
||||||
|
limitsState = LimitsLoadedFailure(error: e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
Future createTrade() async {
|
||||||
|
TradeRequest request;
|
||||||
|
String amount;
|
||||||
|
CryptoCurrency currency;
|
||||||
|
|
||||||
|
if (provider is XMRTOExchangeProvider) {
|
||||||
|
request = XMRTOTradeRequest(
|
||||||
|
from: depositCurrency,
|
||||||
|
to: receiveCurrency,
|
||||||
|
amount: depositAmount,
|
||||||
|
address: receiveAddress,
|
||||||
|
refundAddress: depositAddress);
|
||||||
|
amount = depositAmount;
|
||||||
|
currency = depositCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider is ChangeNowExchangeProvider) {
|
||||||
|
request = ChangeNowRequest(
|
||||||
|
from: depositCurrency,
|
||||||
|
to: receiveCurrency,
|
||||||
|
amount: depositAmount,
|
||||||
|
refundAddress: depositAddress,
|
||||||
|
address: receiveAddress);
|
||||||
|
amount = depositAmount;
|
||||||
|
currency = depositCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider is MorphTokenExchangeProvider) {
|
||||||
|
request = MorphTokenRequest(
|
||||||
|
from: depositCurrency,
|
||||||
|
to: receiveCurrency,
|
||||||
|
amount: depositAmount,
|
||||||
|
refundAddress: depositAddress,
|
||||||
|
address: receiveAddress);
|
||||||
|
amount = depositAmount;
|
||||||
|
currency = depositCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limitsState is LimitsLoadedSuccessfully && amount != null) {
|
||||||
|
if (double.parse(amount) < limits.min) {
|
||||||
|
tradeState = TradeIsCreatedFailure(error: S.current.error_text_minimal_limit('${provider.description}',
|
||||||
|
'${limits.min}', currency.toString()));
|
||||||
|
} else if (limits.max != null && double.parse(amount) > limits.max) {
|
||||||
|
tradeState = TradeIsCreatedFailure(error: S.current.error_text_maximum_limit('${provider.description}',
|
||||||
|
'${limits.max}', currency.toString()));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
tradeState = TradeIsCreating();
|
||||||
|
final trade = await provider.createTrade(request: request);
|
||||||
|
trade.walletId = wallet.id;
|
||||||
|
await trades.add(trade);
|
||||||
|
tradeState = TradeIsCreatedSuccessfully(trade: trade);
|
||||||
|
} catch (e) {
|
||||||
|
tradeState = TradeIsCreatedFailure(error: e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tradeState = TradeIsCreatedFailure(error: S.current.error_text_limits_loading_failed("${provider.description}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
void reset() {
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
depositCurrency = CryptoCurrency.xmr;
|
||||||
|
receiveCurrency = CryptoCurrency.btc;
|
||||||
|
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
|
||||||
|
receiveAddress = receiveCurrency == wallet.currency ? wallet.address : '';
|
||||||
|
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||||
|
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||||
|
_onPairChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ExchangeProvider> providersForCurrentPair() {
|
||||||
|
return _providersForPair(from: depositCurrency, to: receiveCurrency);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ExchangeProvider> _providersForPair(
|
||||||
|
{CryptoCurrency from, CryptoCurrency to}) {
|
||||||
|
final providers = providerList
|
||||||
|
.where((provider) => provider.pairList
|
||||||
|
.where((pair) =>
|
||||||
|
pair.from == depositCurrency && pair.to == receiveCurrency)
|
||||||
|
.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onPairChange() {
|
||||||
|
final isPairExist = provider.pairList
|
||||||
|
.where((pair) =>
|
||||||
|
pair.from == depositCurrency && pair.to == receiveCurrency)
|
||||||
|
.isNotEmpty;
|
||||||
|
|
||||||
|
if (!isPairExist) {
|
||||||
|
final provider =
|
||||||
|
_providerForPair(from: depositCurrency, to: receiveCurrency);
|
||||||
|
|
||||||
|
if (provider != null) {
|
||||||
|
changeProvider(provider: provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
depositAmount = '';
|
||||||
|
receiveAmount = '';
|
||||||
|
|
||||||
|
loadLimits();
|
||||||
|
}
|
||||||
|
|
||||||
|
ExchangeProvider _providerForPair({CryptoCurrency from, CryptoCurrency to}) {
|
||||||
|
final providers = _providersForPair(from: from, to: to);
|
||||||
|
return providers.isNotEmpty ? providers[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Austausch",
|
"exchange" : "Austausch",
|
||||||
"clear" : "klar",
|
"clear" : "klar",
|
||||||
|
"refund_address" : "Rückerstattungsadresse",
|
||||||
"change_exchange_provider" : "Wechseln Sie den Exchange-Anbieter",
|
"change_exchange_provider" : "Wechseln Sie den Exchange-Anbieter",
|
||||||
"you_will_send" : "Du wirst senden",
|
"you_will_send" : "Du wirst senden",
|
||||||
"you_will_get" : "Sie erhalten",
|
"you_will_get" : "Sie erhalten",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Exchange",
|
"exchange" : "Exchange",
|
||||||
"clear" : "Clear",
|
"clear" : "Clear",
|
||||||
|
"refund_address" : "Refund address",
|
||||||
"change_exchange_provider" : "Change Exchange Provider",
|
"change_exchange_provider" : "Change Exchange Provider",
|
||||||
"you_will_send" : "You will send",
|
"you_will_send" : "You will send",
|
||||||
"you_will_get" : "You will get",
|
"you_will_get" : "You will get",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Intercambiar",
|
"exchange" : "Intercambiar",
|
||||||
"clear" : "Claro",
|
"clear" : "Claro",
|
||||||
|
"refund_address" : "Dirección de reembolso",
|
||||||
"change_exchange_provider" : "Cambiar proveedor de intercambio",
|
"change_exchange_provider" : "Cambiar proveedor de intercambio",
|
||||||
"you_will_send" : "Enviarás",
|
"you_will_send" : "Enviarás",
|
||||||
"you_will_get" : "Conseguirás",
|
"you_will_get" : "Conseguirás",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "अदला बदली",
|
"exchange" : "अदला बदली",
|
||||||
"clear" : "स्पष्ट",
|
"clear" : "स्पष्ट",
|
||||||
|
"refund_address" : "वापसी का पता",
|
||||||
"change_exchange_provider" : "एक्सचेंज प्रदाता बदलें",
|
"change_exchange_provider" : "एक्सचेंज प्रदाता बदलें",
|
||||||
"you_will_send" : "तुम भेजोगे",
|
"you_will_send" : "तुम भेजोगे",
|
||||||
"you_will_get" : "आपको मिल जायेगा",
|
"you_will_get" : "आपको मिल जायेगा",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "交換する",
|
"exchange" : "交換する",
|
||||||
"clear" : "クリア",
|
"clear" : "クリア",
|
||||||
|
"refund_address" : "払い戻し住所",
|
||||||
"change_exchange_provider" : "Exchangeプロバイダーの変更",
|
"change_exchange_provider" : "Exchangeプロバイダーの変更",
|
||||||
"you_will_send" : "送ります",
|
"you_will_send" : "送ります",
|
||||||
"you_will_get" : "あなたが取得します",
|
"you_will_get" : "あなたが取得します",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "교환",
|
"exchange" : "교환",
|
||||||
"clear" : "명확한",
|
"clear" : "명확한",
|
||||||
|
"refund_address" : "환불 주소",
|
||||||
"change_exchange_provider" : "교환 공급자 변경",
|
"change_exchange_provider" : "교환 공급자 변경",
|
||||||
"you_will_send" : "보내드립니다",
|
"you_will_send" : "보내드립니다",
|
||||||
"you_will_get" : "당신은 얻을 것이다",
|
"you_will_get" : "당신은 얻을 것이다",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Uitwisseling",
|
"exchange" : "Uitwisseling",
|
||||||
"clear" : "Duidelijk",
|
"clear" : "Duidelijk",
|
||||||
|
"refund_address" : "Adres voor terugbetaling",
|
||||||
"change_exchange_provider" : "Wijzig Exchange Provider",
|
"change_exchange_provider" : "Wijzig Exchange Provider",
|
||||||
"you_will_send" : "Je zal versturen",
|
"you_will_send" : "Je zal versturen",
|
||||||
"you_will_get" : "Je zult krijgen",
|
"you_will_get" : "Je zult krijgen",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Wymieniać się",
|
"exchange" : "Wymieniać się",
|
||||||
"clear" : "Wyczyść",
|
"clear" : "Wyczyść",
|
||||||
|
"refund_address" : "Adres zwrotu",
|
||||||
"change_exchange_provider" : "Zmień dostawcę programu Exchange",
|
"change_exchange_provider" : "Zmień dostawcę programu Exchange",
|
||||||
"you_will_send" : "Wyślesz",
|
"you_will_send" : "Wyślesz",
|
||||||
"you_will_get" : "Dostaniesz",
|
"you_will_get" : "Dostaniesz",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Trocar",
|
"exchange" : "Trocar",
|
||||||
"clear" : "Limpar",
|
"clear" : "Limpar",
|
||||||
|
"refund_address" : "Endereço de reembolso",
|
||||||
"change_exchange_provider" : "Alterar o provedor de troca",
|
"change_exchange_provider" : "Alterar o provedor de troca",
|
||||||
"you_will_send" : "Você enviará",
|
"you_will_send" : "Você enviará",
|
||||||
"you_will_get" : "Você receberá",
|
"you_will_get" : "Você receberá",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Обмен",
|
"exchange" : "Обмен",
|
||||||
"clear" : "Очистить",
|
"clear" : "Очистить",
|
||||||
|
"refund_address" : "Адрес возврата",
|
||||||
"change_exchange_provider" : "Изменить провайдера обмена",
|
"change_exchange_provider" : "Изменить провайдера обмена",
|
||||||
"you_will_send" : "Вы отправите",
|
"you_will_send" : "Вы отправите",
|
||||||
"you_will_get" : "Вы получите",
|
"you_will_get" : "Вы получите",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "Обмін",
|
"exchange" : "Обмін",
|
||||||
"clear" : "Очистити",
|
"clear" : "Очистити",
|
||||||
|
"refund_address" : "Адреса повернення коштів",
|
||||||
"change_exchange_provider" : "Змінити провайдера обміну",
|
"change_exchange_provider" : "Змінити провайдера обміну",
|
||||||
"you_will_send" : "Ви відправите",
|
"you_will_send" : "Ви відправите",
|
||||||
"you_will_get" : "Ви отримаєте",
|
"you_will_get" : "Ви отримаєте",
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
"exchange" : "交换",
|
"exchange" : "交换",
|
||||||
"clear" : "明确",
|
"clear" : "明确",
|
||||||
|
"refund_address" : "退款地址",
|
||||||
"change_exchange_provider" : "更改交易所提供商",
|
"change_exchange_provider" : "更改交易所提供商",
|
||||||
"you_will_send" : "您将发送",
|
"you_will_send" : "您将发送",
|
||||||
"you_will_get" : "你会得到",
|
"you_will_get" : "你会得到",
|
||||||
|
|