mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Merge pull request #59 from cake-tech/CWA-212-update-exchange-screen
Cwa 212 update exchange screen
This commit is contained in:
commit
9bace0cd3c
35 changed files with 1662 additions and 739 deletions
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 895 B After Width: | Height: | Size: 752 B |
|
@ -237,6 +237,7 @@ class S implements WidgetsLocalizations {
|
|||
String get trade_details_state => "State";
|
||||
String get trade_details_title => "Trade Details";
|
||||
String get trade_history_title => "Trade history";
|
||||
String get trade_id => "Trade ID:";
|
||||
String get trade_not_created => "Trade not created.";
|
||||
String get trade_not_found => "Trade not found.";
|
||||
String get trade_state_btc_sent => "Btc sent";
|
||||
|
@ -313,7 +314,6 @@ class S implements WidgetsLocalizations {
|
|||
String time(String minutes, String seconds) => "${minutes}m ${seconds}s";
|
||||
String trade_details_copied(String title) => "${title} copied to Clipboard";
|
||||
String trade_for_not_created(String title) => "Trade for ${title} is not created.";
|
||||
String trade_id(String id) => "Trade ID:\n${id}";
|
||||
String trade_id_not_found(String tradeId, String title) => "Trade ${tradeId} of ${title} not found.";
|
||||
String trade_is_powered_by(String provider) => "This trade is powered by ${provider}";
|
||||
String transaction_details_copied(String title) => "${title} copied to Clipboard";
|
||||
|
@ -357,6 +357,8 @@ class $de extends S {
|
|||
@override
|
||||
String get you_will_get => "Sie erhalten";
|
||||
@override
|
||||
String get trade_id => "Handel-ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Stellen Sie Ihr Wallet aus den 25 Wörtern wieder her oder 13-Wort-Kombinationscode";
|
||||
@override
|
||||
String get trade_state_underpaid => "Unterbezahlt";
|
||||
|
@ -879,8 +881,6 @@ class $de extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Möchten Sie den aktuellen Knoten wirklich auf ändern? ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "Handel-ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Wird geladen ${wallet_name} Wallet";
|
||||
@override
|
||||
String version(String currentVersion) => "Ausführung ${currentVersion}";
|
||||
|
@ -967,6 +967,8 @@ class $hi extends S {
|
|||
@override
|
||||
String get you_will_get => "आपको मिल जायेगा";
|
||||
@override
|
||||
String get trade_id => "व्यापार ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "या तो 25 शब्द से अपने वॉलेट को पुनर्स्थापित करें या 13 शब्द संयोजन कोड";
|
||||
@override
|
||||
String get trade_state_underpaid => "के तहत भुगतान किया";
|
||||
|
@ -1489,8 +1491,6 @@ class $hi extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "क्या आप वर्तमान नोड को बदलना सुनिश्चित करते हैं ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "व्यापार ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "लोड हो रहा है ${wallet_name} बटुआ";
|
||||
@override
|
||||
String version(String currentVersion) => "संस्करण ${currentVersion}";
|
||||
|
@ -1577,6 +1577,8 @@ class $ru extends S {
|
|||
@override
|
||||
String get you_will_get => "Вы получите";
|
||||
@override
|
||||
String get trade_id => "ID сделки:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Вы можете восстановить кошелёк используя 25-ти значную мнемоническую фразу";
|
||||
@override
|
||||
String get trade_state_underpaid => "Недоплаченная";
|
||||
|
@ -2099,8 +2101,6 @@ class $ru extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Вы уверены, что хотите изменить текущую ноду на ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "ID сделки:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Загрузка ${wallet_name} кошелька";
|
||||
@override
|
||||
String version(String currentVersion) => "Версия ${currentVersion}";
|
||||
|
@ -2187,6 +2187,8 @@ class $ko extends S {
|
|||
@override
|
||||
String get you_will_get => "당신은 얻을 것이다";
|
||||
@override
|
||||
String get trade_id => "무역 ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "25 단어 또는 13 단어 조합 코드에서 지갑을 복원하십시오.";
|
||||
@override
|
||||
String get trade_state_underpaid => "미지급";
|
||||
|
@ -2709,8 +2711,6 @@ class $ko extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "현재 노드를 다음으로 변경 하시겠습니까 ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "무역 ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "로딩 ${wallet_name} 지갑";
|
||||
@override
|
||||
String version(String currentVersion) => "버전 ${currentVersion}";
|
||||
|
@ -2797,6 +2797,8 @@ class $pt extends S {
|
|||
@override
|
||||
String get you_will_get => "Você receberá";
|
||||
@override
|
||||
String get trade_id => "ID da troca:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Restaure sua carteira a partir de semente com 25 palavras ou 13 palavras";
|
||||
@override
|
||||
String get trade_state_underpaid => "Parcialmente paga";
|
||||
|
@ -3319,8 +3321,6 @@ class $pt extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Você realmente deseja alterar o nó atual para ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "ID da troca:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Abrindo a carteira ${wallet_name}";
|
||||
@override
|
||||
String version(String currentVersion) => "Versão ${currentVersion}";
|
||||
|
@ -3407,6 +3407,8 @@ class $uk extends S {
|
|||
@override
|
||||
String get you_will_get => "Ви отримаєте";
|
||||
@override
|
||||
String get trade_id => "ID операції:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Ви можете відновити гаманець використовуючи 25-ти слівну мнемонічну фразу";
|
||||
@override
|
||||
String get trade_state_underpaid => "Недоплачена";
|
||||
|
@ -3929,8 +3931,6 @@ class $uk extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Ви впевнені, що хочете змінити поточний вузол на ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "ID операції:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Завантаження ${wallet_name} гаманця";
|
||||
@override
|
||||
String version(String currentVersion) => "Версія ${currentVersion}";
|
||||
|
@ -4017,6 +4017,8 @@ class $ja extends S {
|
|||
@override
|
||||
String get you_will_get => "あなたが取得します";
|
||||
@override
|
||||
String get trade_id => "取引ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "25ワードからウォレットを復元しますまたは13ワードの組み合わせコード";
|
||||
@override
|
||||
String get trade_state_underpaid => "支払不足";
|
||||
|
@ -4539,8 +4541,6 @@ class $ja extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "現在のノードを変更してよろしいですか ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "取引ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "読み込み中 ${wallet_name} 財布";
|
||||
@override
|
||||
String version(String currentVersion) => "バージョン ${currentVersion}";
|
||||
|
@ -4631,6 +4631,8 @@ class $pl extends S {
|
|||
@override
|
||||
String get you_will_get => "Dostaniesz";
|
||||
@override
|
||||
String get trade_id => "Identyfikator handlu:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Przywróć swój portfel z 25 słów lub 13-słowny kod kombinacji";
|
||||
@override
|
||||
String get trade_state_underpaid => "Niedopłacone";
|
||||
|
@ -5153,8 +5155,6 @@ class $pl extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Czy na pewno chcesz przywrócić ustawienia domyślne? ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "Identyfikator handlu:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Ładuję ${wallet_name} portfel";
|
||||
@override
|
||||
String version(String currentVersion) => "Wersja ${currentVersion}";
|
||||
|
@ -5241,6 +5241,8 @@ class $es extends S {
|
|||
@override
|
||||
String get you_will_get => "Conseguirás";
|
||||
@override
|
||||
String get trade_id => "Comercial ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Restaure su billetera desde el código de combinación de 25 palabras i de 13 palabras";
|
||||
@override
|
||||
String get trade_state_underpaid => "Poco pagado";
|
||||
|
@ -5763,8 +5765,6 @@ class $es extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "¿Está seguro de cambiar el nodo actual a ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "Comercial ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Billetera ${wallet_name} de carga";
|
||||
@override
|
||||
String version(String currentVersion) => "Versión ${currentVersion}";
|
||||
|
@ -5851,6 +5851,8 @@ class $nl extends S {
|
|||
@override
|
||||
String get you_will_get => "Je zult krijgen";
|
||||
@override
|
||||
String get trade_id => "Trade ID:";
|
||||
@override
|
||||
String get restore_description_from_seed => "Herstel uw portemonnee van het 25 woord of 13 woord combinatiecode";
|
||||
@override
|
||||
String get trade_state_underpaid => "Slecht betaald";
|
||||
|
@ -6373,8 +6375,6 @@ class $nl extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "Weet u zeker dat u het huidige knooppunt wilt wijzigen in ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "Trade ID:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "Bezig met laden ${wallet_name} portemonnee";
|
||||
@override
|
||||
String version(String currentVersion) => "Versie ${currentVersion}";
|
||||
|
@ -6461,6 +6461,8 @@ class $zh extends S {
|
|||
@override
|
||||
String get you_will_get => "你会得到";
|
||||
@override
|
||||
String get trade_id => "贸易编号:";
|
||||
@override
|
||||
String get restore_description_from_seed => "从25个字中恢复您的钱包或13个字的组合码";
|
||||
@override
|
||||
String get trade_state_underpaid => "支付不足";
|
||||
|
@ -6983,8 +6985,6 @@ class $zh extends S {
|
|||
@override
|
||||
String change_current_node(String node) => "您确定将当前节点更改为 ${node}?";
|
||||
@override
|
||||
String trade_id(String id) => "贸易编号:\n${id}";
|
||||
@override
|
||||
String wallet_list_loading_wallet(String wallet_name) => "载入中 ${wallet_name} 钱包";
|
||||
@override
|
||||
String version(String currentVersion) => "版 ${currentVersion}";
|
||||
|
|
|
@ -22,6 +22,7 @@ import 'package:cake_wallet/src/stores/balance/balance_store.dart';
|
|||
import 'package:cake_wallet/src/stores/sync/sync_store.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:cake_wallet/src/stores/send_template/send_template_store.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/src/screens/root/root.dart';
|
||||
import 'package:cake_wallet/src/stores/authentication/authentication_store.dart';
|
||||
import 'package:cake_wallet/src/stores/settings/settings_store.dart';
|
||||
|
@ -34,6 +35,7 @@ import 'package:cake_wallet/src/domain/common/fiat_currency.dart';
|
|||
import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
|
||||
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/domain/common/template.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||
import 'package:cake_wallet/src/domain/services/wallet_service.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/domain/common/language.dart';
|
||||
|
@ -51,6 +53,7 @@ void main() async {
|
|||
Hive.registerAdapter(WalletInfoAdapter(), 4);
|
||||
Hive.registerAdapter(WalletTypeAdapter(), 5);
|
||||
Hive.registerAdapter(TemplateAdapter(), 6);
|
||||
Hive.registerAdapter(ExchangeTemplateAdapter(), 7);
|
||||
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
final transactionDescriptionsBoxKey = await getEncryptionKey(
|
||||
|
@ -69,6 +72,7 @@ void main() async {
|
|||
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
|
||||
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
final templates = await Hive.openBox<Template>(Template.boxName);
|
||||
final exchangeTemplates = await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
|
||||
|
||||
final sharedPreferences = await SharedPreferences.getInstance();
|
||||
final walletService = WalletService();
|
||||
|
@ -106,6 +110,7 @@ void main() async {
|
|||
sharedPreferences: sharedPreferences, walletsService: walletListService);
|
||||
final seedLanguageStore = SeedLanguageStore();
|
||||
final sendTemplateStore = SendTemplateStore(templateSource: templates);
|
||||
final exchangeTemplateStore = ExchangeTemplateStore(templateSource: exchangeTemplates);
|
||||
|
||||
setReactions(
|
||||
settingsStore: settingsStore,
|
||||
|
@ -133,6 +138,7 @@ void main() async {
|
|||
Provider(create: (_) => trades),
|
||||
Provider(create: (_) => seedLanguageStore),
|
||||
Provider(create: (_) => sendTemplateStore),
|
||||
Provider(create: (_) => exchangeTemplateStore),
|
||||
], child: CakeWalletApp()));
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ import 'package:cake_wallet/src/screens/dashboard/create_dashboard_page.dart';
|
|||
import 'package:cake_wallet/src/screens/welcome/create_welcome_page.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
|
||||
import 'package:cake_wallet/src/screens/send/send_template_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
|
||||
|
||||
class Router {
|
||||
static Route<dynamic> generateRoute(
|
||||
|
@ -470,6 +471,25 @@ class Router {
|
|||
}),
|
||||
], child: ExchangePage()));
|
||||
|
||||
case Routes.exchangeTemplate:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => 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: ExchangeTemplatePage(),)
|
||||
);
|
||||
|
||||
case Routes.settings:
|
||||
return MaterialPageRoute<void>(
|
||||
builder: (_) => Provider(
|
||||
|
|
|
@ -45,4 +45,5 @@ class Routes {
|
|||
static const changeLanguage = '/change_language';
|
||||
static const newWalletType = '/new_wallet_type';
|
||||
static const sendTemplate = '/send_template';
|
||||
static const exchangeTemplate = '/exchange_template';
|
||||
}
|
35
lib/src/domain/exchange/exchange_template.dart
Normal file
35
lib/src/domain/exchange/exchange_template.dart
Normal file
|
@ -0,0 +1,35 @@
|
|||
import 'package:hive/hive.dart';
|
||||
|
||||
part 'exchange_template.g.dart';
|
||||
|
||||
@HiveType()
|
||||
class ExchangeTemplate extends HiveObject {
|
||||
ExchangeTemplate({
|
||||
this.amount,
|
||||
this.depositCurrency,
|
||||
this.receiveCurrency,
|
||||
this.provider,
|
||||
this.depositAddress,
|
||||
this.receiveAddress
|
||||
});
|
||||
|
||||
static const boxName = 'ExchangeTemplate';
|
||||
|
||||
@HiveField(0)
|
||||
String amount;
|
||||
|
||||
@HiveField(1)
|
||||
String depositCurrency;
|
||||
|
||||
@HiveField(2)
|
||||
String receiveCurrency;
|
||||
|
||||
@HiveField(3)
|
||||
String provider;
|
||||
|
||||
@HiveField(4)
|
||||
String depositAddress;
|
||||
|
||||
@HiveField(5)
|
||||
String receiveAddress;
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
import 'dart:ui';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -8,7 +13,6 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/generated/i18n.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/exchange_provider_description.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/limits_state.dart';
|
||||
|
@ -17,18 +21,21 @@ 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/exchange/widgets/exchange_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.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/screens/exchange/widgets/provider_picker.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
|
||||
class ExchangePage extends BasePage {
|
||||
@override
|
||||
String get title => S.current.exchange;
|
||||
|
||||
@override
|
||||
bool get isModalBackButton => true;
|
||||
Color get backgroundColor => PaletteDark.walletCardSubAddressField;
|
||||
|
||||
final Image arrowBottomPurple =
|
||||
Image.asset('assets/images/arrow_bottom_purple_icon.png', height: 8);
|
||||
final Image arrowBottom =
|
||||
Image.asset('assets/images/arrow_bottom_purple_icon.png', color: Colors.white, height: 6);
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
|
@ -38,31 +45,34 @@ class ExchangePage extends BasePage {
|
|||
onPressed: () => _presentProviderPicker(context),
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(S.of(context).exchange,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).primaryTextTheme.title.color)),
|
||||
SizedBox(width: 5),
|
||||
arrowBottomPurple
|
||||
]),
|
||||
Observer(
|
||||
builder: (_) => Text('${exchangeStore.provider.title}',
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(S.of(context).exchange,
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme.headline.color)))
|
||||
color: Colors.white)),
|
||||
Observer(
|
||||
builder: (_) => Text('${exchangeStore.provider.title}',
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color:PaletteDark.walletCardText)))
|
||||
],
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
child: arrowBottom,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -72,14 +82,16 @@ class ExchangePage extends BasePage {
|
|||
|
||||
return ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
child: FlatButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(
|
||||
S.of(context).clear,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).accentTextTheme.caption.color,
|
||||
color: PaletteDark.walletCardText,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 16),
|
||||
fontSize: 14),
|
||||
),
|
||||
onPressed: () => exchangeStore.reset()),
|
||||
);
|
||||
|
@ -92,10 +104,26 @@ class ExchangePage extends BasePage {
|
|||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final items = exchangeStore.providersForCurrentPair();
|
||||
final selectedItem = items.indexOf(exchangeStore.provider);
|
||||
final images = List<Image>();
|
||||
|
||||
for (ExchangeProvider provider in items) {
|
||||
switch (provider.description) {
|
||||
case ExchangeProviderDescription.xmrto:
|
||||
images.add(Image.asset('assets/images/xmr_btc.png'));
|
||||
break;
|
||||
case ExchangeProviderDescription.changeNow:
|
||||
images.add(Image.asset('assets/images/change_now.png'));
|
||||
break;
|
||||
case ExchangeProviderDescription.morphToken:
|
||||
images.add(Image.asset('assets/images/morph_icon.png'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
showDialog<void>(
|
||||
builder: (_) => Picker(
|
||||
builder: (_) => ProviderPicker(
|
||||
items: items,
|
||||
images: images,
|
||||
selectedAtIndex: selectedItem,
|
||||
title: S.of(context).change_exchange_provider,
|
||||
onItemSelected: (ExchangeProvider provider) =>
|
||||
|
@ -117,10 +145,12 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
|
||||
final Image arrowBottomPurple = Image.asset(
|
||||
'assets/images/arrow_bottom_purple_icon.png',
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
final Image arrowBottomCakeGreen = Image.asset(
|
||||
'assets/images/arrow_bottom_cake_green.png',
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
|
||||
|
@ -128,6 +158,7 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
Widget build(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
||||
|
||||
final depositWalletName =
|
||||
exchangeStore.depositCurrency == CryptoCurrency.xmr
|
||||
|
@ -141,156 +172,229 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => _setReactions(context, exchangeStore, walletStore));
|
||||
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(left: 20, right: 20),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
return Container(
|
||||
color: PaletteDark.historyPanel,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: PaletteDark.menuList,
|
||||
edgeInsets: EdgeInsets.only(bottom: 24),
|
||||
widget: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
widget: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: depositKey,
|
||||
title: S.of(context).you_will_send,
|
||||
initialCurrency: exchangeStore.depositCurrency,
|
||||
initialWalletName: depositWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.depositCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: exchangeStore.depositAddress,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: false,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) =>
|
||||
exchangeStore.changeDepositCurrency(currency: currency),
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: PaletteDark.walletCardSubAddressField,
|
||||
addressButtonsColor: PaletteDark.menuList,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.depositCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 32, left: 24, right: 24),
|
||||
child: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: receiveKey,
|
||||
title: S.of(context).you_will_get,
|
||||
initialCurrency: exchangeStore.receiveCurrency,
|
||||
initialWalletName: receiveWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.receiveCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: exchangeStore.receiveAddress,
|
||||
initialIsAmountEditable: false,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: true,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) => exchangeStore
|
||||
.changeReceiveCurrency(currency: currency),
|
||||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyButtonColor: PaletteDark.menuList,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.receiveCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
)),
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10, bottom: 20),
|
||||
child: Text(
|
||||
S.of(context).you_will_send,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
height: 1.1,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
padding: EdgeInsets.only(
|
||||
top: 32,
|
||||
left: 24,
|
||||
bottom: 24
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).send_templates,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: PaletteDark.walletCardText
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
ExchangeCard(
|
||||
key: depositKey,
|
||||
initialCurrency: exchangeStore.depositCurrency,
|
||||
initialWalletName: depositWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.depositCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: null,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: false,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) =>
|
||||
exchangeStore.changeDepositCurrency(currency: currency),
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.depositCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
),
|
||||
SizedBox(height: 35),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 20),
|
||||
child: Text(
|
||||
S.of(context).you_will_get,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
height: 1.1,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme.title.color),
|
||||
)),
|
||||
Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: receiveKey,
|
||||
initialCurrency: exchangeStore.receiveCurrency,
|
||||
initialWalletName: receiveWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.receiveCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: null,
|
||||
initialIsAmountEditable: false,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: true,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) => exchangeStore
|
||||
.changeReceiveCurrency(currency: currency),
|
||||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.receiveCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
)),
|
||||
Container(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
final itemCount = exchangeTemplateStore.templates.length + 1;
|
||||
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: itemCount,
|
||||
itemBuilder: (context, index) {
|
||||
|
||||
if (index == 0) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.exchangeTemplate),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: DottedBorder(
|
||||
borderType: BorderType.RRect,
|
||||
dashPattern: [8, 4],
|
||||
color: PaletteDark.menuList,
|
||||
strokeWidth: 2,
|
||||
radius: Radius.circular(20),
|
||||
child: Container(
|
||||
height: 40,
|
||||
width: 75,
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).send_new,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: PaletteDark.walletCardText
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
index -= 1;
|
||||
|
||||
final template = exchangeTemplateStore.templates[index];
|
||||
|
||||
return TemplateTile(
|
||||
amount: template.amount,
|
||||
from: template.depositCurrency,
|
||||
to: template.receiveCurrency,
|
||||
onTap: () {
|
||||
applyTemplate(exchangeStore, template);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(top: 35, left: 20, right: 20),
|
||||
bottomSection: Column(children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 15),
|
||||
child: Observer(builder: (_) {
|
||||
final description =
|
||||
exchangeStore.provider is XMRTOExchangeProvider
|
||||
? S.of(context).amount_is_guaranteed
|
||||
: S.of(context).amount_is_estimate;
|
||||
return Center(
|
||||
child: Text(
|
||||
description,
|
||||
style: TextStyle(color: Palette.blueGrey, fontSize: 12),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
exchangeStore.createTrade();
|
||||
}
|
||||
},
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.backgroundColor,
|
||||
textColor: Theme.of(context).primaryTextTheme.button.color,
|
||||
isLoading: exchangeStore.tradeState is TradeIsCreating,
|
||||
)),
|
||||
Observer(builder: (_) {
|
||||
final title = exchangeStore.provider.description.title;
|
||||
var imageSrc = '';
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Column(children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 15),
|
||||
child: Observer(builder: (_) {
|
||||
final description =
|
||||
exchangeStore.provider is XMRTOExchangeProvider
|
||||
? S.of(context).amount_is_guaranteed
|
||||
: S.of(context).amount_is_estimate;
|
||||
return Center(
|
||||
child: Text(
|
||||
description,
|
||||
style: TextStyle(
|
||||
color: PaletteDark.walletCardText,
|
||||
fontSize: 12
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
exchangeStore.createTrade();
|
||||
}
|
||||
},
|
||||
color: Colors.blue,
|
||||
textColor: Colors.white,
|
||||
isLoading: exchangeStore.tradeState is TradeIsCreating,
|
||||
)),
|
||||
]),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
switch (exchangeStore.provider.description) {
|
||||
case ExchangeProviderDescription.xmrto:
|
||||
imageSrc = 'assets/images/xmr_btc.png';
|
||||
break;
|
||||
case ExchangeProviderDescription.changeNow:
|
||||
imageSrc = 'assets/images/change_now.png';
|
||||
break;
|
||||
case ExchangeProviderDescription.morphToken:
|
||||
imageSrc = 'assets/images/morph_icon.png';
|
||||
break;
|
||||
}
|
||||
void applyTemplate(ExchangeStore store, ExchangeTemplate template) {
|
||||
store.changeDepositCurrency(currency: CryptoCurrency.fromString(template.depositCurrency));
|
||||
store.changeReceiveCurrency(currency: CryptoCurrency.fromString(template.receiveCurrency));
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Image.asset(imageSrc),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
S.of(context).powered_by(title),
|
||||
style: TextStyle(fontSize: 14, color: Palette.powered),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
})
|
||||
]),
|
||||
));
|
||||
switch (template.provider) {
|
||||
case 'XMR.TO':
|
||||
store.changeProvider(provider: store.providerList[0]);
|
||||
break;
|
||||
case 'ChangeNOW':
|
||||
store.changeProvider(provider: store.providerList[1]);
|
||||
break;
|
||||
case 'MorphToken':
|
||||
store.changeProvider(provider: store.providerList[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
store.changeDepositAmount(amount: template.amount);
|
||||
store.depositAddress = template.depositAddress;
|
||||
store.receiveAddress = template.receiveAddress;
|
||||
}
|
||||
|
||||
void _setReactions(
|
||||
|
@ -345,6 +449,12 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.depositAddress, (String address) {
|
||||
if (depositKey.currentState.addressController.text != address) {
|
||||
depositKey.currentState.addressController.text = address;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.receiveAmount, (String amount) {
|
||||
if (receiveKey.currentState.amountController.text !=
|
||||
store.receiveAmount) {
|
||||
|
@ -352,6 +462,12 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.receiveAddress, (String address) {
|
||||
if (receiveKey.currentState.addressController.text != address) {
|
||||
receiveKey.currentState.addressController.text = address;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.provider, (ExchangeProvider provider) {
|
||||
receiveKey.currentState.isAddressEditable(isEditable: true);
|
||||
receiveKey.currentState.isAmountEditable(isEditable: false);
|
||||
|
@ -367,14 +483,11 @@ class ExchangeFormState extends State<ExchangeForm> {
|
|||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(S.of(context).error),
|
||||
content: Text(state.error),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () => Navigator.of(context).pop())
|
||||
],
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).error,
|
||||
alertContent: state.error,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
448
lib/src/screens/exchange/exchange_template_page.dart
Normal file
448
lib/src/screens/exchange/exchange_template_page.dart
Normal file
|
@ -0,0 +1,448 @@
|
|||
import 'dart:ui';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/generated/i18n.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/xmrto/xmrto_exchange_provider.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/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/exchange/widgets/exchange_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/top_panel.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/provider_picker.dart';
|
||||
import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
|
||||
|
||||
class ExchangeTemplatePage extends BasePage {
|
||||
@override
|
||||
String get title => 'New template';
|
||||
|
||||
@override
|
||||
Color get backgroundColor => PaletteDark.walletCardSubAddressField;
|
||||
|
||||
final Image arrowBottom =
|
||||
Image.asset('assets/images/arrow_bottom_purple_icon.png', color: Colors.white, height: 6);
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
|
||||
return FlatButton(
|
||||
onPressed: () => _presentProviderPicker(context),
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(S.of(context).exchange,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.white)),
|
||||
Observer(
|
||||
builder: (_) => Text('${exchangeStore.provider.title}',
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
fontWeight: FontWeight.w400,
|
||||
color:PaletteDark.walletCardText)))
|
||||
],
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
child: arrowBottom,
|
||||
)
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void _presentProviderPicker(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final items = exchangeStore.providersForCurrentPair();
|
||||
final selectedItem = items.indexOf(exchangeStore.provider);
|
||||
final images = List<Image>();
|
||||
|
||||
for (ExchangeProvider provider in items) {
|
||||
switch (provider.description) {
|
||||
case ExchangeProviderDescription.xmrto:
|
||||
images.add(Image.asset('assets/images/xmr_btc.png'));
|
||||
break;
|
||||
case ExchangeProviderDescription.changeNow:
|
||||
images.add(Image.asset('assets/images/change_now.png'));
|
||||
break;
|
||||
case ExchangeProviderDescription.morphToken:
|
||||
images.add(Image.asset('assets/images/morph_icon.png'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
showDialog<void>(
|
||||
builder: (_) => ProviderPicker(
|
||||
items: items,
|
||||
images: images,
|
||||
selectedAtIndex: selectedItem,
|
||||
title: S.of(context).change_exchange_provider,
|
||||
onItemSelected: (ExchangeProvider provider) =>
|
||||
exchangeStore.changeProvider(provider: provider)),
|
||||
context: context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => ExchangeTemplateForm();
|
||||
}
|
||||
|
||||
class ExchangeTemplateForm extends StatefulWidget{
|
||||
@override
|
||||
ExchangeTemplateFormState createState() => ExchangeTemplateFormState();
|
||||
}
|
||||
|
||||
class ExchangeTemplateFormState extends State<ExchangeTemplateForm> {
|
||||
final depositKey = GlobalKey<ExchangeCardState>();
|
||||
final receiveKey = GlobalKey<ExchangeCardState>();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
var _isReactionsSet = false;
|
||||
|
||||
final Image arrowBottomPurple = Image.asset(
|
||||
'assets/images/arrow_bottom_purple_icon.png',
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
final Image arrowBottomCakeGreen = Image.asset(
|
||||
'assets/images/arrow_bottom_cake_green.png',
|
||||
color: Colors.white,
|
||||
height: 8,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final exchangeStore = Provider.of<ExchangeStore>(context);
|
||||
final walletStore = Provider.of<WalletStore>(context);
|
||||
final exchangeTemplateStore = Provider.of<ExchangeTemplateStore>(context);
|
||||
|
||||
final depositWalletName =
|
||||
exchangeStore.depositCurrency == CryptoCurrency.xmr
|
||||
? walletStore.name
|
||||
: null;
|
||||
final receiveWalletName =
|
||||
exchangeStore.receiveCurrency == CryptoCurrency.xmr
|
||||
? walletStore.name
|
||||
: null;
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => _setReactions(context, exchangeStore, walletStore));
|
||||
|
||||
return Container(
|
||||
color: PaletteDark.historyPanel,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(bottom: 24),
|
||||
content: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: PaletteDark.menuList,
|
||||
edgeInsets: EdgeInsets.only(bottom: 24),
|
||||
widget: Column(
|
||||
children: <Widget>[
|
||||
TopPanel(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
widget: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: depositKey,
|
||||
title: S.of(context).you_will_send,
|
||||
initialCurrency: exchangeStore.depositCurrency,
|
||||
initialWalletName: depositWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.depositCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: null,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: false,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) =>
|
||||
exchangeStore.changeDepositCurrency(currency: currency),
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: PaletteDark.walletCardSubAddressField,
|
||||
addressButtonsColor: PaletteDark.menuList,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.depositCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 32, left: 24, right: 24),
|
||||
child: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
key: receiveKey,
|
||||
title: S.of(context).you_will_get,
|
||||
initialCurrency: exchangeStore.receiveCurrency,
|
||||
initialWalletName: receiveWalletName,
|
||||
initialAddress:
|
||||
exchangeStore.receiveCurrency == walletStore.type
|
||||
? walletStore.address
|
||||
: null,
|
||||
initialIsAmountEditable: false,
|
||||
initialIsAddressEditable: true,
|
||||
isAmountEstimated: true,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) => exchangeStore
|
||||
.changeReceiveCurrency(currency: currency),
|
||||
imageArrow: arrowBottomCakeGreen,
|
||||
currencyButtonColor: PaletteDark.menuList,
|
||||
currencyValueValidator: (value) {
|
||||
exchangeStore.validateCryptoCurrency(value);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
addressTextFieldValidator: (value) {
|
||||
exchangeStore.validateAddress(value,
|
||||
cryptoCurrency: exchangeStore.receiveCurrency);
|
||||
return exchangeStore.errorMessage;
|
||||
},
|
||||
)),
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Column(children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 15),
|
||||
child: Observer(builder: (_) {
|
||||
final description =
|
||||
exchangeStore.provider is XMRTOExchangeProvider
|
||||
? S.of(context).amount_is_guaranteed
|
||||
: S.of(context).amount_is_estimate;
|
||||
return Center(
|
||||
child: Text(
|
||||
description,
|
||||
style: TextStyle(
|
||||
color: PaletteDark.walletCardText,
|
||||
fontSize: 12
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
PrimaryButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
exchangeTemplateStore.addTemplate(
|
||||
amount: exchangeStore.depositAmount,
|
||||
depositCurrency: exchangeStore.depositCurrency.toString(),
|
||||
receiveCurrency: exchangeStore.receiveCurrency.toString(),
|
||||
provider: exchangeStore.provider.toString(),
|
||||
depositAddress: exchangeStore.depositAddress,
|
||||
receiveAddress: exchangeStore.receiveAddress
|
||||
);
|
||||
exchangeTemplateStore.update();
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
},
|
||||
text: S.of(context).save,
|
||||
color: Colors.green,
|
||||
textColor: Colors.white
|
||||
),
|
||||
]),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
void _setReactions(
|
||||
BuildContext context, ExchangeStore store, WalletStore walletStore) {
|
||||
if (_isReactionsSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
final depositAddressController = depositKey.currentState.addressController;
|
||||
final depositAmountController = depositKey.currentState.amountController;
|
||||
final receiveAddressController = receiveKey.currentState.addressController;
|
||||
final receiveAmountController = receiveKey.currentState.amountController;
|
||||
final limitsState = store.limitsState;
|
||||
|
||||
if (limitsState is LimitsLoadedSuccessfully) {
|
||||
final min = limitsState.limits.min != null
|
||||
? limitsState.limits.min.toString()
|
||||
: null;
|
||||
final max = limitsState.limits.max != null
|
||||
? limitsState.limits.max.toString()
|
||||
: null;
|
||||
final key = depositKey;
|
||||
key.currentState.changeLimits(min: min, max: max);
|
||||
}
|
||||
|
||||
_onCurrencyChange(store.receiveCurrency, walletStore, receiveKey);
|
||||
_onCurrencyChange(store.depositCurrency, walletStore, depositKey);
|
||||
|
||||
reaction(
|
||||
(_) => walletStore.name,
|
||||
(String _) => _onWalletNameChange(
|
||||
walletStore, store.receiveCurrency, receiveKey));
|
||||
|
||||
reaction(
|
||||
(_) => walletStore.name,
|
||||
(String _) => _onWalletNameChange(
|
||||
walletStore, store.depositCurrency, depositKey));
|
||||
|
||||
reaction(
|
||||
(_) => store.receiveCurrency,
|
||||
(CryptoCurrency currency) =>
|
||||
_onCurrencyChange(currency, walletStore, receiveKey));
|
||||
|
||||
reaction(
|
||||
(_) => store.depositCurrency,
|
||||
(CryptoCurrency currency) =>
|
||||
_onCurrencyChange(currency, walletStore, depositKey));
|
||||
|
||||
reaction((_) => store.depositAmount, (String amount) {
|
||||
if (depositKey.currentState.amountController.text != amount) {
|
||||
depositKey.currentState.amountController.text = amount;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.receiveAmount, (String amount) {
|
||||
if (receiveKey.currentState.amountController.text !=
|
||||
store.receiveAmount) {
|
||||
receiveKey.currentState.amountController.text = amount;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.provider, (ExchangeProvider provider) {
|
||||
receiveKey.currentState.isAddressEditable(isEditable: true);
|
||||
receiveKey.currentState.isAmountEditable(isEditable: false);
|
||||
depositKey.currentState.isAddressEditable(isEditable: true);
|
||||
depositKey.currentState.isAmountEditable(isEditable: true);
|
||||
|
||||
receiveKey.currentState.changeIsAmountEstimated(true);
|
||||
});
|
||||
|
||||
reaction((_) => store.tradeState, (ExchangeTradeState state) {
|
||||
if (state is TradeIsCreatedFailure) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(S.of(context).error),
|
||||
content: Text(state.error),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () => Navigator.of(context).pop())
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
if (state is TradeIsCreatedSuccessfully) {
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.exchangeConfirm, arguments: state.trade);
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => store.limitsState, (LimitsState state) {
|
||||
String min;
|
||||
String max;
|
||||
|
||||
if (state is LimitsLoadedSuccessfully) {
|
||||
min = state.limits.min != null ? state.limits.min.toString() : null;
|
||||
max = state.limits.max != null ? state.limits.max.toString() : null;
|
||||
}
|
||||
|
||||
if (state is LimitsLoadedFailure) {
|
||||
min = '0';
|
||||
max = '0';
|
||||
}
|
||||
|
||||
if (state is LimitsIsLoading) {
|
||||
min = '...';
|
||||
max = '...';
|
||||
}
|
||||
|
||||
depositKey.currentState.changeLimits(min: min, max: max);
|
||||
receiveKey.currentState.changeLimits(min: null, max: null);
|
||||
});
|
||||
|
||||
depositAddressController.addListener(
|
||||
() => store.depositAddress = depositAddressController.text);
|
||||
|
||||
depositAmountController.addListener(() {
|
||||
if (depositAmountController.text != store.depositAmount) {
|
||||
store.changeDepositAmount(amount: depositAmountController.text);
|
||||
}
|
||||
});
|
||||
|
||||
receiveAddressController.addListener(
|
||||
() => store.receiveAddress = receiveAddressController.text);
|
||||
|
||||
receiveAmountController.addListener(() {
|
||||
if (receiveAmountController.text != store.receiveAmount) {
|
||||
store.changeReceiveAmount(amount: receiveAmountController.text);
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => walletStore.address, (String address) {
|
||||
if (store.depositCurrency == CryptoCurrency.xmr) {
|
||||
depositKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
|
||||
if (store.receiveCurrency == CryptoCurrency.xmr) {
|
||||
receiveKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
});
|
||||
|
||||
_isReactionsSet = true;
|
||||
}
|
||||
|
||||
void _onCurrencyChange(CryptoCurrency currency, WalletStore walletStore,
|
||||
GlobalKey<ExchangeCardState> key) {
|
||||
final isCurrentTypeWallet = currency == walletStore.type;
|
||||
|
||||
key.currentState.changeSelectedCurrency(currency);
|
||||
key.currentState
|
||||
.changeWalletName(isCurrentTypeWallet ? walletStore.name : null);
|
||||
|
||||
key.currentState
|
||||
.changeAddress(address: isCurrentTypeWallet ? walletStore.address : '');
|
||||
|
||||
key.currentState.changeAmount(amount: '');
|
||||
}
|
||||
|
||||
void _onWalletNameChange(WalletStore walletStore, CryptoCurrency currency,
|
||||
GlobalKey<ExchangeCardState> key) {
|
||||
final isCurrentTypeWallet = currency == walletStore.type;
|
||||
|
||||
if (isCurrentTypeWallet) {
|
||||
key.currentState.changeWalletName(walletStore.name);
|
||||
key.currentState.addressController.text = walletStore.address;
|
||||
} else if (key.currentState.addressController.text == walletStore.address) {
|
||||
key.currentState.changeWalletName(null);
|
||||
key.currentState.addressController.text = null;
|
||||
}
|
||||
}
|
||||
}
|
119
lib/src/screens/exchange/widgets/currency_picker.dart
Normal file
119
lib/src/screens/exchange/widgets/currency_picker.dart
Normal file
|
@ -0,0 +1,119 @@
|
|||
import 'dart:ui';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||
|
||||
class CurrencyPicker extends StatelessWidget {
|
||||
CurrencyPicker({
|
||||
@required this.selectedAtIndex,
|
||||
@required this.items,
|
||||
@required this.title,
|
||||
@required this.onItemSelected,
|
||||
});
|
||||
|
||||
final int selectedAtIndex;
|
||||
final List<CryptoCurrency> items;
|
||||
final String title;
|
||||
final Function(CryptoCurrency) onItemSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: PaletteDark.historyPanel.withOpacity(0.75)),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||
child: Container(
|
||||
height: 400,
|
||||
width: 300,
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
child: GridView.count(
|
||||
shrinkWrap: true,
|
||||
crossAxisCount: 3,
|
||||
childAspectRatio: 1.25,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
crossAxisSpacing: 1,
|
||||
mainAxisSpacing: 1,
|
||||
children: List.generate(15, (index) {
|
||||
|
||||
if (index == 14) {
|
||||
return Container(
|
||||
color: PaletteDark.menuList,
|
||||
);
|
||||
}
|
||||
|
||||
final item = items[index];
|
||||
final isItemSelected = index == selectedAtIndex;
|
||||
|
||||
final color = isItemSelected
|
||||
? PaletteDark.historyPanel
|
||||
: PaletteDark.menuList;
|
||||
final textColor = isItemSelected
|
||||
? Colors.blue
|
||||
: Colors.white;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (onItemSelected == null) {
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
onItemSelected(item);
|
||||
},
|
||||
child: Container(
|
||||
color: color,
|
||||
child: Center(
|
||||
child: Text(
|
||||
item.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: textColor
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
})
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,12 +3,14 @@ import 'package:flutter/material.dart';
|
|||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.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/screens/exchange/widgets/currency_picker.dart';
|
||||
|
||||
class ExchangeCard extends StatefulWidget {
|
||||
ExchangeCard(
|
||||
{Key key,
|
||||
this.title = '',
|
||||
this.initialCurrency,
|
||||
this.initialAddress,
|
||||
this.initialWalletName,
|
||||
|
@ -18,12 +20,15 @@ class ExchangeCard extends StatefulWidget {
|
|||
this.currencies,
|
||||
this.onCurrencySelected,
|
||||
this.imageArrow,
|
||||
this.currencyButtonColor = Colors.transparent,
|
||||
this.addressButtonsColor = PaletteDark.walletCardSubAddressField,
|
||||
this.currencyValueValidator,
|
||||
this.addressTextFieldValidator})
|
||||
: super(key: key);
|
||||
|
||||
final List<CryptoCurrency> currencies;
|
||||
final Function(CryptoCurrency) onCurrencySelected;
|
||||
final String title;
|
||||
final CryptoCurrency initialCurrency;
|
||||
final String initialWalletName;
|
||||
final String initialAddress;
|
||||
|
@ -31,6 +36,8 @@ class ExchangeCard extends StatefulWidget {
|
|||
final bool initialIsAddressEditable;
|
||||
final bool isAmountEstimated;
|
||||
final Image imageArrow;
|
||||
final Color currencyButtonColor;
|
||||
final Color addressButtonsColor;
|
||||
final FormFieldValidator<String> currencyValueValidator;
|
||||
final FormFieldValidator<String> addressTextFieldValidator;
|
||||
|
||||
|
@ -42,6 +49,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
final addressController = TextEditingController();
|
||||
final amountController = TextEditingController();
|
||||
|
||||
String _title;
|
||||
String _min;
|
||||
String _max;
|
||||
CryptoCurrency _selectedCurrency;
|
||||
|
@ -52,6 +60,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_title = widget.title;
|
||||
_isAmountEditable = widget.initialIsAmountEditable;
|
||||
_isAddressEditable = widget.initialIsAddressEditable;
|
||||
_walletName = widget.initialWalletName;
|
||||
|
@ -103,157 +112,115 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(22, 15, 22, 30),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
child: Column(children: <Widget>[
|
||||
_isAmountEstimated != null && _isAmountEstimated
|
||||
? Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
|
||||
SizedBox(
|
||||
height: 30,
|
||||
child: Container(
|
||||
padding: EdgeInsets.fromLTRB(10, 5, 10, 5),
|
||||
decoration: BoxDecoration(
|
||||
color: Palette.lightGrey,
|
||||
borderRadius: BorderRadius.circular(10.0)),
|
||||
child: Text(
|
||||
S.of(context).estimated,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Palette.wildDarkBlue,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
])
|
||||
: Container(),
|
||||
Container(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 52,
|
||||
width: 90,
|
||||
color: Colors.transparent,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
_title,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: PaletteDark.walletCardText
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
BaseTextFormField(
|
||||
controller: amountController,
|
||||
enabled: _isAmountEditable,
|
||||
textAlign: TextAlign.left,
|
||||
keyboardType: TextInputType.numberWithOptions(
|
||||
signed: false, decimal: true),
|
||||
inputFormatters: [
|
||||
BlacklistingTextInputFormatter(
|
||||
RegExp('[\\-|\\ |\\,]'))
|
||||
],
|
||||
hintText: '0.0000',
|
||||
borderColor: PaletteDark.borderCardColor,
|
||||
validator: widget.currencyValueValidator
|
||||
),
|
||||
Positioned(
|
||||
top: 8,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
color: widget.currencyButtonColor,
|
||||
child: InkWell(
|
||||
onTap: () => _presentPicker(context),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(_selectedCurrency.toString(),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 24,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color)),
|
||||
widget.imageArrow
|
||||
]),
|
||||
_walletName != null
|
||||
? Text(_walletName,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Palette.wildDarkBlue))
|
||||
: SizedBox(),
|
||||
Text(
|
||||
_selectedCurrency.toString(),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16,
|
||||
color: Colors.white)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: widget.imageArrow,
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
style: TextStyle(fontSize: 23, height: 1.21),
|
||||
controller: amountController,
|
||||
enabled: _isAmountEditable,
|
||||
textAlign: TextAlign.right,
|
||||
keyboardType: TextInputType.numberWithOptions(
|
||||
signed: false, decimal: true),
|
||||
inputFormatters: [
|
||||
BlacklistingTextInputFormatter(
|
||||
RegExp('[\\-|\\ |\\,]'))
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
hintStyle: TextStyle(
|
||||
color: Theme.of(context).cardTheme.color,
|
||||
fontSize: 23,
|
||||
height: 1.21),
|
||||
hintText: '0.00000000',
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Palette.cakeGreen, width: 2.0)),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: _isAmountEditable
|
||||
? Palette.deepPurple
|
||||
: Theme.of(context).focusColor,
|
||||
width: 1.0))),
|
||||
validator: widget.currencyValueValidator),
|
||||
SizedBox(height: 5),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
width: double.infinity,
|
||||
child: Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
_min != null
|
||||
? Text(
|
||||
S.of(context).min_value(
|
||||
_min, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color),
|
||||
)
|
||||
: SizedBox(),
|
||||
_min != null ? SizedBox(width: 10) : SizedBox(),
|
||||
_max != null
|
||||
? Text(
|
||||
S.of(context).max_value(
|
||||
_max, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color))
|
||||
: SizedBox(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_min != null
|
||||
? Text(
|
||||
S.of(context).min_value(
|
||||
_min, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: PaletteDark.walletCardText),
|
||||
)
|
||||
: Offstage(),
|
||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||
_max != null
|
||||
? Text(
|
||||
S.of(context).max_value(
|
||||
_max, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: PaletteDark.walletCardText))
|
||||
: Offstage(),
|
||||
]),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
AddressTextField(
|
||||
controller: addressController,
|
||||
isActive: _isAddressEditable,
|
||||
options: _isAddressEditable
|
||||
? _walletName != null
|
||||
? [
|
||||
AddressTextFieldOption.qrCode,
|
||||
AddressTextFieldOption.addressBook,
|
||||
AddressTextFieldOption.subaddressList
|
||||
]
|
||||
: [
|
||||
AddressTextFieldOption.qrCode,
|
||||
AddressTextFieldOption.addressBook,
|
||||
]
|
||||
: [],
|
||||
validator: widget.addressTextFieldValidator,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: AddressTextField(
|
||||
controller: addressController,
|
||||
isActive: _isAddressEditable,
|
||||
options: _isAddressEditable
|
||||
? _walletName != null
|
||||
? []
|
||||
: [
|
||||
AddressTextFieldOption.qrCode,
|
||||
AddressTextFieldOption.addressBook,
|
||||
]
|
||||
: [],
|
||||
isBorderExist: false,
|
||||
buttonColor: widget.addressButtonsColor,
|
||||
validator: widget.addressTextFieldValidator,
|
||||
),
|
||||
)
|
||||
]),
|
||||
);
|
||||
|
@ -261,14 +228,14 @@ class ExchangeCardState extends State<ExchangeCard> {
|
|||
|
||||
void _presentPicker(BuildContext context) {
|
||||
showDialog<void>(
|
||||
builder: (_) => Picker(
|
||||
items: widget.currencies,
|
||||
builder: (_) => CurrencyPicker(
|
||||
selectedAtIndex: widget.currencies.indexOf(_selectedCurrency),
|
||||
items: widget.currencies,
|
||||
title: S.of(context).change_currency,
|
||||
onItemSelected: (CryptoCurrency item) =>
|
||||
widget.onCurrencySelected != null
|
||||
? widget.onCurrencySelected(item)
|
||||
: null),
|
||||
widget.onCurrencySelected != null
|
||||
? widget.onCurrencySelected(item)
|
||||
: null),
|
||||
context: context);
|
||||
}
|
||||
}
|
||||
|
|
124
lib/src/screens/exchange/widgets/provider_picker.dart
Normal file
124
lib/src/screens/exchange/widgets/provider_picker.dart
Normal file
|
@ -0,0 +1,124 @@
|
|||
import 'dart:ui';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_provider.dart';
|
||||
|
||||
class ProviderPicker extends StatelessWidget {
|
||||
ProviderPicker({
|
||||
@required this.selectedAtIndex,
|
||||
@required this.items,
|
||||
@required this.images,
|
||||
@required this.title,
|
||||
@required this.onItemSelected,
|
||||
});
|
||||
|
||||
final int selectedAtIndex;
|
||||
final List<ExchangeProvider> items;
|
||||
final List<Image> images;
|
||||
final String title;
|
||||
final Function(ExchangeProvider) onItemSelected;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: PaletteDark.historyPanel.withOpacity(0.75)),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.none,
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
child: GestureDetector(
|
||||
onTap: () => null,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(14)),
|
||||
child: Container(
|
||||
height: 233,
|
||||
color: PaletteDark.menuList,
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: PaletteDark.mainBackgroundColor,
|
||||
height: 1,
|
||||
),
|
||||
itemCount: items == null ? 0 : items.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
final image = images[index];
|
||||
final isItemSelected = index == selectedAtIndex;
|
||||
|
||||
final color = isItemSelected
|
||||
? PaletteDark.menuHeader
|
||||
: Colors.transparent;
|
||||
final textColor = isItemSelected
|
||||
? Colors.blue
|
||||
: Colors.white;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (onItemSelected == null) {
|
||||
return;
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
onItemSelected(item);
|
||||
},
|
||||
child: Container(
|
||||
height: 77,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
color: color,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: Text(
|
||||
item.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: textColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,54 +6,56 @@ import 'package:cake_wallet/generated/i18n.dart';
|
|||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/trade.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
|
||||
class ExchangeConfirmPage extends BasePage {
|
||||
ExchangeConfirmPage({@required this.trade});
|
||||
|
||||
final Trade trade;
|
||||
final copyImage = Image.asset('assets/images/copy_content.png', color: Colors.white);
|
||||
|
||||
@override
|
||||
String get title => S.current.copy_id;
|
||||
|
||||
@override
|
||||
Color get backgroundColor => PaletteDark.historyPanel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 80.0, right: 80.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).exchange_result_write_down_trade_id,
|
||||
return Container(
|
||||
color: PaletteDark.historyPanel,
|
||||
padding: EdgeInsets.all(24),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).exchange_result_write_down_trade_id,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 60),
|
||||
child: Text(
|
||||
S.of(context).trade_id,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white),
|
||||
),
|
||||
SizedBox(
|
||||
height: 70.0,
|
||||
),
|
||||
Text(
|
||||
S.of(context).trade_id(trade.id),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
),
|
||||
SizedBox(
|
||||
height: 70.0,
|
||||
),
|
||||
PrimaryButton(
|
||||
onPressed: () {
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: Builder(
|
||||
builder: (context) => GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: trade.id));
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
|
@ -62,31 +64,52 @@ class ExchangeConfirmPage extends BasePage {
|
|||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
duration: Duration(milliseconds: 1500),
|
||||
));
|
||||
},
|
||||
text: S.of(context).copy_id,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.caption
|
||||
.backgroundColor,
|
||||
textColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color)
|
||||
],
|
||||
),
|
||||
))),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 20.0, right: 20.0, bottom: 40.0),
|
||||
child: PrimaryButton(
|
||||
child: Container(
|
||||
height: 60,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(30)),
|
||||
color: PaletteDark.menuList
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(
|
||||
trade.id,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: copyImage,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)),
|
||||
PrimaryButton(
|
||||
onPressed: () => Navigator.of(context)
|
||||
.pushReplacementNamed(Routes.exchangeTrade, arguments: trade),
|
||||
text: S.of(context).saved_the_trade_id,
|
||||
color: Theme.of(context).primaryTextTheme.button.backgroundColor,
|
||||
textColor:
|
||||
Theme.of(context).primaryTextTheme.button.color),
|
||||
)
|
||||
],
|
||||
color: Colors.green,
|
||||
textColor: Colors.white)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,17 +12,21 @@ import 'package:cake_wallet/src/stores/exchange_trade/exchange_trade_store.dart'
|
|||
import 'package:cake_wallet/src/stores/send/send_store.dart';
|
||||
import 'package:cake_wallet/src/stores/send/sending_state.dart';
|
||||
import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange_trade/widgets/copy_button.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange_trade/widgets/timer_widget.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
|
||||
class ExchangeTradePage extends BasePage {
|
||||
@override
|
||||
String get title => S.current.exchange;
|
||||
|
||||
@override
|
||||
Color get backgroundColor => PaletteDark.historyPanel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => ExchangeTradeForm();
|
||||
}
|
||||
|
@ -46,278 +50,273 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
|
||||
_setEffects(context);
|
||||
|
||||
return ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(left: 20, right: 20, top: 20),
|
||||
content: Observer(builder: (_) {
|
||||
final trade = tradeStore.trade;
|
||||
final walletName = walletStore.name;
|
||||
return Container(
|
||||
color: PaletteDark.historyPanel,
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(left: 24, right: 24, top: 24),
|
||||
content: Observer(builder: (_) {
|
||||
final trade = tradeStore.trade;
|
||||
final walletName = walletStore.name;
|
||||
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).id,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
),
|
||||
Text(
|
||||
'${trade.id ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).amount,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
),
|
||||
Text(
|
||||
'${trade.amount ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color),
|
||||
)
|
||||
],
|
||||
),
|
||||
trade.extraId != null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).payment_id,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
),
|
||||
Text(
|
||||
'${trade.extraId ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color),
|
||||
)
|
||||
],
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).id,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
Text(
|
||||
'${trade.id ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: PaletteDark.walletCardText),
|
||||
)
|
||||
: Container(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).status,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color,
|
||||
height: 2),
|
||||
),
|
||||
Text(
|
||||
'${trade.state ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color),
|
||||
)
|
||||
],
|
||||
),
|
||||
trade.expiredAt != null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).offer_expires_in,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.color),
|
||||
),
|
||||
TimerWidget(trade.expiredAt,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle
|
||||
.color)
|
||||
],
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).amount,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
Text(
|
||||
'${trade.amount ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: PaletteDark.walletCardText),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Container(
|
||||
padding: EdgeInsets.all(5),
|
||||
color: Colors.white,
|
||||
constraints: BoxConstraints(minWidth: 65, maxWidth: 105),
|
||||
child: QrImage(
|
||||
data: trade.inputAddress ?? fetchingLabel,
|
||||
backgroundColor: Colors.white))
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20.0,
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
S.of(context).trade_is_powered_by(trade.provider != null
|
||||
? trade.provider.title
|
||||
: fetchingLabel),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context).primaryTextTheme.headline.color),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Center(
|
||||
child: Text(
|
||||
trade.inputAddress ?? fetchingLabel,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 14.0, color: Palette.lightViolet),
|
||||
],
|
||||
),
|
||||
trade.extraId != null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).payment_id,
|
||||
style: TextStyle(
|
||||
height: 2,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
Text(
|
||||
'${trade.extraId ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: PaletteDark.walletCardText),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).status,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
height: 2),
|
||||
),
|
||||
Text(
|
||||
'${trade.state ?? fetchingLabel}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
height: 2,
|
||||
color: PaletteDark.walletCardText),
|
||||
)
|
||||
],
|
||||
),
|
||||
trade.expiredAt != null
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).offer_expires_in,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
TimerWidget(trade.expiredAt,
|
||||
color: PaletteDark.walletCardText)
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 50.0, right: 50.0),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
child: CopyButton(
|
||||
onPressed: () => Clipboard.setData(
|
||||
ClipboardData(text: trade.inputAddress)),
|
||||
text: S.of(context).copy_address,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.button
|
||||
.backgroundColor,
|
||||
borderColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.button
|
||||
.decorationColor),
|
||||
)),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 5.0),
|
||||
child: CopyButton(
|
||||
onPressed: () =>
|
||||
Clipboard.setData(ClipboardData(text: trade.id)),
|
||||
text: S.of(context).copy_id,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.button
|
||||
.backgroundColor,
|
||||
borderColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.button
|
||||
.decorationColor),
|
||||
))
|
||||
],
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Spacer(
|
||||
flex: 1,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: AspectRatio(
|
||||
aspectRatio: 1.0,
|
||||
child: QrImage(
|
||||
data: trade.inputAddress ?? fetchingLabel,
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: PaletteDark.walletCardText,
|
||||
),
|
||||
),
|
||||
)),
|
||||
Spacer(
|
||||
flex: 1,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
tradeStore.isSendable
|
||||
? S.of(context).exchange_result_confirm(
|
||||
trade.amount ?? fetchingLabel,
|
||||
trade.from.toString(),
|
||||
walletName)
|
||||
: S.of(context).exchange_result_description(
|
||||
trade.amount ?? fetchingLabel, trade.from.toString()),
|
||||
SizedBox(
|
||||
height: 20.0,
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
S.of(context).trade_is_powered_by(trade.provider != null
|
||||
? trade.provider.title
|
||||
: fetchingLabel),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
child: Center(
|
||||
child: Text(
|
||||
trade.inputAddress ?? fetchingLabel,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 14.0, color: PaletteDark.walletCardText),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 5.0),
|
||||
child: Builder(
|
||||
builder: (context) => PrimaryButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: trade.inputAddress));
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
S.of(context).copied_to_clipboard,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
duration: Duration(milliseconds: 1500),
|
||||
));
|
||||
},
|
||||
text: S.of(context).copy_address,
|
||||
color: PaletteDark.menuList,
|
||||
textColor: Colors.white)
|
||||
),
|
||||
)),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 5.0),
|
||||
child: Builder(
|
||||
builder: (context) => PrimaryButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: trade.id));
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
S.of(context).copied_to_clipboard,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.white),
|
||||
),
|
||||
backgroundColor: Colors.green,
|
||||
duration: Duration(milliseconds: 1500),
|
||||
));
|
||||
},
|
||||
text: S.of(context).copy_id,
|
||||
color: PaletteDark.menuList,
|
||||
textColor: Colors.white)
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
tradeStore.isSendable
|
||||
? S.of(context).exchange_result_confirm(
|
||||
trade.amount ?? fetchingLabel,
|
||||
trade.from.toString(),
|
||||
walletName)
|
||||
: S.of(context).exchange_result_description(
|
||||
trade.amount ?? fetchingLabel, trade.from.toString()),
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Colors.white),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
S.of(context).exchange_result_write_down_ID,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
S.of(context).exchange_result_write_down_ID,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Theme.of(context).accentTextTheme.title.color),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
bottomSection: Observer(
|
||||
builder: (_) => tradeStore.trade.from == CryptoCurrency.xmr &&
|
||||
!(sendStore.state is TransactionCommitted)
|
||||
? Container(
|
||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
||||
child: LoadingPrimaryButton(
|
||||
isDisabled: tradeStore.trade.inputAddress == null ||
|
||||
tradeStore.trade.inputAddress.isEmpty,
|
||||
isLoading: sendStore.state is CreatingTransaction ||
|
||||
sendStore.state is TransactionCommitted,
|
||||
onPressed: () => sendStore.createTransaction(
|
||||
address: tradeStore.trade.inputAddress,
|
||||
amount: tradeStore.trade.amount),
|
||||
text: tradeStore.trade.provider ==
|
||||
ExchangeProviderDescription.xmrto
|
||||
? S.of(context).confirm
|
||||
: S.of(context).send_xmr,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.button
|
||||
.backgroundColor,
|
||||
textColor: Theme.of(context).primaryTextTheme.button.color),
|
||||
)
|
||||
: Offstage()),
|
||||
color: Colors.white),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
bottomSectionPadding: EdgeInsets.all(24),
|
||||
bottomSection: Observer(
|
||||
builder: (_) => tradeStore.trade.from == CryptoCurrency.xmr &&
|
||||
!(sendStore.state is TransactionCommitted)
|
||||
? LoadingPrimaryButton(
|
||||
isDisabled: tradeStore.trade.inputAddress == null ||
|
||||
tradeStore.trade.inputAddress.isEmpty,
|
||||
isLoading: sendStore.state is CreatingTransaction ||
|
||||
sendStore.state is TransactionCommitted,
|
||||
onPressed: () => sendStore.createTransaction(
|
||||
address: tradeStore.trade.inputAddress,
|
||||
amount: tradeStore.trade.amount),
|
||||
text: tradeStore.trade.provider ==
|
||||
ExchangeProviderDescription.xmrto
|
||||
? S.of(context).confirm
|
||||
: S.of(context).send_xmr,
|
||||
color: Colors.blue,
|
||||
textColor: Colors.white)
|
||||
: Offstage()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -334,14 +333,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(S.of(context).error),
|
||||
content: Text(state.error),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () => Navigator.of(context).pop())
|
||||
],
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).error,
|
||||
alertContent: state.error,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -352,23 +348,18 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(S.of(context).confirm_sending),
|
||||
content: Text(S.of(context).commit_transaction_amount_fee(
|
||||
sendStore.pendingTransaction.amount,
|
||||
sendStore.pendingTransaction.fee)),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
sendStore.commitTransaction();
|
||||
}),
|
||||
FlatButton(
|
||||
child: Text(S.of(context).cancel),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
)
|
||||
],
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).confirm_sending,
|
||||
alertContent: S.of(context).commit_transaction_amount_fee(
|
||||
sendStore.pendingTransaction.amount,
|
||||
sendStore.pendingTransaction.fee),
|
||||
leftButtonText: S.of(context).ok,
|
||||
rightButtonText: S.of(context).cancel,
|
||||
actionLeftButton: () {
|
||||
Navigator.of(context).pop();
|
||||
sendStore.commitTransaction();
|
||||
},
|
||||
actionRightButton: () => Navigator.of(context).pop()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -379,14 +370,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
|||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(S.of(context).sending),
|
||||
content: Text(S.of(context).transaction_sent),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(S.of(context).ok),
|
||||
onPressed: () => Navigator.of(context).pop())
|
||||
],
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).sending,
|
||||
alertContent: S.of(context).transaction_sent,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -170,7 +170,7 @@ class ReceiveBodyState extends State<ReceiveBody> {
|
|||
height: 48,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(27)),
|
||||
borderRadius: BorderRadius.all(Radius.circular(24)),
|
||||
color: PaletteDark.walletCardSubAddressField
|
||||
),
|
||||
child: Row(
|
||||
|
|
|
@ -27,7 +27,7 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
|||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/sending_alert.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/src/stores/send_template/send_template_store.dart';
|
||||
|
||||
class SendPage extends BasePage {
|
||||
|
@ -357,7 +357,7 @@ class SendFormState extends State<SendForm> {
|
|||
if (index == 0) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.of(context)
|
||||
.pushNamed(Routes.sendTemplate, arguments: sendStore),
|
||||
.pushNamed(Routes.sendTemplate),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(right: 10),
|
||||
child: DottedBorder(
|
||||
|
@ -394,9 +394,9 @@ class SendFormState extends State<SendForm> {
|
|||
final template = sendTemplateStore.templates[index];
|
||||
|
||||
return TemplateTile(
|
||||
name: template.name,
|
||||
to: template.name,
|
||||
amount: template.amount,
|
||||
cryptoCurrency: template.cryptoCurrency,
|
||||
from: template.cryptoCurrency,
|
||||
onTap: () {
|
||||
_addressController.text = template.address;
|
||||
_cryptoAmountController.text = template.amount;
|
||||
|
|
|
@ -33,6 +33,10 @@ abstract class ExchangeStoreBase with Store {
|
|||
provider = initialProvider;
|
||||
depositCurrency = initialDepositCurrency;
|
||||
receiveCurrency = initialReceiveCurrency;
|
||||
depositAmount = '';
|
||||
receiveAmount = '';
|
||||
depositAddress = '';
|
||||
receiveAddress = '';
|
||||
limitsState = LimitsInitialState();
|
||||
tradeState = ExchangeTradeStateInitial();
|
||||
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
|
||||
|
@ -63,6 +67,12 @@ abstract class ExchangeStoreBase with Store {
|
|||
@observable
|
||||
String receiveAmount;
|
||||
|
||||
@observable
|
||||
String depositAddress;
|
||||
|
||||
@observable
|
||||
String receiveAddress;
|
||||
|
||||
@observable
|
||||
bool isValid;
|
||||
|
||||
|
@ -71,10 +81,6 @@ abstract class ExchangeStoreBase with Store {
|
|||
|
||||
Box<Trade> trades;
|
||||
|
||||
String depositAddress;
|
||||
|
||||
String receiveAddress;
|
||||
|
||||
WalletStore walletStore;
|
||||
|
||||
Limits limits;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import 'dart:async';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cake_wallet/src/domain/exchange/exchange_template.dart';
|
||||
|
||||
part 'exchange_template_store.g.dart';
|
||||
|
||||
class ExchangeTemplateStore = ExchangeTemplateBase with _$ExchangeTemplateStore;
|
||||
|
||||
abstract class ExchangeTemplateBase with Store {
|
||||
ExchangeTemplateBase({this.templateSource}) {
|
||||
templates = ObservableList<ExchangeTemplate>();
|
||||
update();
|
||||
}
|
||||
|
||||
@observable
|
||||
ObservableList<ExchangeTemplate> templates;
|
||||
|
||||
Box<ExchangeTemplate> templateSource;
|
||||
|
||||
@action
|
||||
void update() =>
|
||||
templates.replaceRange(0, templates.length, templateSource.values.toList());
|
||||
|
||||
@action
|
||||
Future addTemplate({String amount, String depositCurrency, String receiveCurrency,
|
||||
String provider, String depositAddress, String receiveAddress}) async {
|
||||
final template = ExchangeTemplate(
|
||||
amount: amount,
|
||||
depositCurrency: depositCurrency,
|
||||
receiveCurrency: receiveCurrency,
|
||||
provider: provider,
|
||||
depositAddress: depositAddress,
|
||||
receiveAddress: receiveAddress);
|
||||
await templateSource.add(template);
|
||||
}
|
||||
|
||||
@action
|
||||
Future remove({ExchangeTemplate template}) async => await template.delete();
|
||||
}
|
|
@ -19,6 +19,8 @@ class AddressTextField extends StatelessWidget {
|
|||
],
|
||||
this.onURIScanned,
|
||||
this.focusNode,
|
||||
this.isBorderExist = true,
|
||||
this.buttonColor = PaletteDark.walletCardSubAddressField,
|
||||
this.validator});
|
||||
|
||||
static const prefixIconWidth = 34.0;
|
||||
|
@ -31,6 +33,8 @@ class AddressTextField extends StatelessWidget {
|
|||
final Function(Uri) onURIScanned;
|
||||
final List<AddressTextFieldOption> options;
|
||||
final FormFieldValidator<String> validator;
|
||||
final bool isBorderExist;
|
||||
final Color buttonColor;
|
||||
FocusNode focusNode;
|
||||
|
||||
@override
|
||||
|
@ -62,7 +66,7 @@ class AddressTextField extends StatelessWidget {
|
|||
child: Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
color: buttonColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(6))),
|
||||
child: Image.asset('assets/images/qr_code_icon.png')),
|
||||
|
@ -80,7 +84,7 @@ class AddressTextField extends StatelessWidget {
|
|||
child: Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
color: buttonColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(6))),
|
||||
child: Image.asset(
|
||||
|
@ -99,7 +103,7 @@ class AddressTextField extends StatelessWidget {
|
|||
child: Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
color: buttonColor,
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(6))),
|
||||
child: Image.asset(
|
||||
|
@ -114,13 +118,17 @@ class AddressTextField extends StatelessWidget {
|
|||
color: PaletteDark.walletCardText
|
||||
),
|
||||
hintText: placeholder ?? S.current.widgets_address,
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
focusedBorder: isBorderExist
|
||||
? UnderlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: PaletteDark.walletCardSubAddressField,
|
||||
width: 1.0)),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
width: 1.0))
|
||||
: InputBorder.none,
|
||||
enabledBorder: isBorderExist
|
||||
? UnderlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(color: PaletteDark.walletCardSubAddressField, width: 1.0)),
|
||||
BorderSide(color: PaletteDark.walletCardSubAddressField, width: 1.0))
|
||||
: InputBorder.none,
|
||||
),
|
||||
validator: validator,
|
||||
);
|
||||
|
|
|
@ -15,6 +15,9 @@ class BaseTextFormField extends StatelessWidget {
|
|||
this.textColor = Colors.white,
|
||||
this.hintColor = PaletteDark.walletCardText,
|
||||
this.borderColor = PaletteDark.menuList,
|
||||
this.prefix,
|
||||
this.suffix,
|
||||
this.enabled = true,
|
||||
this.validator
|
||||
});
|
||||
|
||||
|
@ -29,6 +32,9 @@ class BaseTextFormField extends StatelessWidget {
|
|||
final Color textColor;
|
||||
final Color hintColor;
|
||||
final Color borderColor;
|
||||
final Widget prefix;
|
||||
final Widget suffix;
|
||||
final bool enabled;
|
||||
final FormFieldValidator<String> validator;
|
||||
|
||||
@override
|
||||
|
@ -41,11 +47,14 @@ class BaseTextFormField extends StatelessWidget {
|
|||
autovalidate: autovalidate,
|
||||
maxLines: maxLines,
|
||||
inputFormatters: inputFormatters,
|
||||
enabled: enabled,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: textColor
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
prefix: prefix,
|
||||
suffix: suffix,
|
||||
hintStyle: TextStyle(
|
||||
color: hintColor,
|
||||
fontSize: 16
|
||||
|
|
|
@ -3,15 +3,15 @@ import 'package:cake_wallet/palette.dart';
|
|||
|
||||
class TemplateTile extends StatelessWidget {
|
||||
TemplateTile({
|
||||
@required this.name,
|
||||
@required this.to,
|
||||
@required this.amount,
|
||||
@required this.cryptoCurrency,
|
||||
@required this.from,
|
||||
@required this.onTap
|
||||
});
|
||||
|
||||
final String name;
|
||||
final String to;
|
||||
final String amount;
|
||||
final String cryptoCurrency;
|
||||
final String from;
|
||||
final VoidCallback onTap;
|
||||
|
||||
final toIcon = Image.asset('assets/images/to_icon.png');
|
||||
|
@ -44,7 +44,7 @@ class TemplateTile extends StatelessWidget {
|
|||
Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: Text(
|
||||
cryptoCurrency,
|
||||
from,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
|
@ -59,7 +59,7 @@ class TemplateTile extends StatelessWidget {
|
|||
Padding(
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
child: Text(
|
||||
name,
|
||||
to,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
|
@ -1,24 +1,40 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class TopPanel extends StatelessWidget {
|
||||
TopPanel({@required this.color, @required this.widget});
|
||||
class TopPanel extends StatefulWidget {
|
||||
TopPanel({
|
||||
@required this.color,
|
||||
@required this.widget,
|
||||
this.edgeInsets = const EdgeInsets.all(24)
|
||||
});
|
||||
|
||||
final Color color;
|
||||
final Widget widget;
|
||||
final EdgeInsets edgeInsets;
|
||||
|
||||
@override
|
||||
TopPanelState createState() => TopPanelState(color, widget, edgeInsets);
|
||||
}
|
||||
|
||||
class TopPanelState extends State<TopPanel> {
|
||||
TopPanelState(this._color, this._widget, this._edgeInsets);
|
||||
|
||||
final Color _color;
|
||||
final Widget _widget;
|
||||
final EdgeInsets _edgeInsets;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.all(24),
|
||||
padding: _edgeInsets,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24)
|
||||
),
|
||||
color: color
|
||||
color: _color
|
||||
),
|
||||
child: widget,
|
||||
child: _widget,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "ID kopieren",
|
||||
"exchange_result_write_down_trade_id" : "Bitte kopieren oder notieren Sie die Handel-ID, um fortzufahren.",
|
||||
"trade_id" : "Handel-ID:\n${id}",
|
||||
"trade_id" : "Handel-ID:",
|
||||
"copied_to_clipboard" : "In die Zwischenablage kopiert",
|
||||
"saved_the_trade_id" : "Ich habe die Geschäfts-ID gespeichert",
|
||||
"fetching" : "holen",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "Copy ID",
|
||||
"exchange_result_write_down_trade_id" : "Please copy or write down the trade ID to continue.",
|
||||
"trade_id" : "Trade ID:\n${id}",
|
||||
"trade_id" : "Trade ID:",
|
||||
"copied_to_clipboard" : "Copied to Clipboard",
|
||||
"saved_the_trade_id" : "I've saved the trade ID",
|
||||
"fetching" : "Fetching",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "Copiar ID",
|
||||
"exchange_result_write_down_trade_id" : "Por favor, copia o escribe el ID.",
|
||||
"trade_id" : "Comercial ID:\n${id}",
|
||||
"trade_id" : "Comercial ID:",
|
||||
"copied_to_clipboard" : "Copiado al portapapeles",
|
||||
"saved_the_trade_id" : "He salvado comercial ID",
|
||||
"fetching" : "Cargando",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "प्रतिलिपि ID",
|
||||
"exchange_result_write_down_trade_id" : "जारी रखने के लिए कृपया ट्रेड ID की प्रतिलिपि बनाएँ या लिखें.",
|
||||
"trade_id" : "व्यापार ID:\n${id}",
|
||||
"trade_id" : "व्यापार ID:",
|
||||
"copied_to_clipboard" : "क्लिपबोर्ड पर नकल",
|
||||
"saved_the_trade_id" : "मैंने व्यापार बचा लिया है ID",
|
||||
"fetching" : "ला रहा है",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "IDをコピー",
|
||||
"exchange_result_write_down_trade_id" : "続行するには、取引IDをコピーまたは書き留めてください.",
|
||||
"trade_id" : "取引ID:\n${id}",
|
||||
"trade_id" : "取引ID:",
|
||||
"copied_to_clipboard" : "クリップボードにコピーしました",
|
||||
"saved_the_trade_id" : "取引IDを保存しました",
|
||||
"fetching" : "フェッチング",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "부 ID",
|
||||
"exchange_result_write_down_trade_id" : "계속하려면 거래 ID를 복사하거나 적어 두십시오..",
|
||||
"trade_id" : "무역 ID:\n${id}",
|
||||
"trade_id" : "무역 ID:",
|
||||
"copied_to_clipboard" : "클립 보드에 복사",
|
||||
"saved_the_trade_id" : "거래 ID를 저장했습니다",
|
||||
"fetching" : "가져 오는 중",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "ID kopiëren",
|
||||
"exchange_result_write_down_trade_id" : "Kopieer of noteer de handels-ID om door te gaan.",
|
||||
"trade_id" : "Trade ID:\n${id}",
|
||||
"trade_id" : "Trade ID:",
|
||||
"copied_to_clipboard" : "Gekopieerd naar het klembord",
|
||||
"saved_the_trade_id" : "Ik heb de ruil-ID opgeslagen",
|
||||
"fetching" : "Ophalen",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "ID kopii",
|
||||
"exchange_result_write_down_trade_id" : "Skopiuj lub zanotuj identyfikator transakcji, aby kontynuować.",
|
||||
"trade_id" : "Identyfikator handlu:\n${id}",
|
||||
"trade_id" : "Identyfikator handlu:",
|
||||
"copied_to_clipboard" : "Skopiowane do schowka",
|
||||
"saved_the_trade_id" : "Zapisałem ID",
|
||||
"fetching" : "Ujmujący",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "Copiar ID",
|
||||
"exchange_result_write_down_trade_id" : "Copie ou anote o ID da troca para continuar.",
|
||||
"trade_id" : "ID da troca:\n${id}",
|
||||
"trade_id" : "ID da troca:",
|
||||
"copied_to_clipboard" : "Copiado para a área de transferência",
|
||||
"saved_the_trade_id" : "ID da troca salvo",
|
||||
"fetching" : "Buscando",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "Скопировать ID",
|
||||
"exchange_result_write_down_trade_id" : "Пожалуйста, скопируйте или запишите ID сделки.",
|
||||
"trade_id" : "ID сделки:\n${id}",
|
||||
"trade_id" : "ID сделки:",
|
||||
"copied_to_clipboard" : "Скопировано в буфер обмена",
|
||||
"saved_the_trade_id" : "Я сохранил ID сделки",
|
||||
"fetching" : "Загрузка",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "Скопіювати ID",
|
||||
"exchange_result_write_down_trade_id" : "Будь ласка, скопіюйте або запишіть ID операції.",
|
||||
"trade_id" : "ID операції:\n${id}",
|
||||
"trade_id" : "ID операції:",
|
||||
"copied_to_clipboard" : "Скопійовано в буфер обміну",
|
||||
"saved_the_trade_id" : "Я зберіг ID операції",
|
||||
"fetching" : "Завантаження",
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
"copy_id" : "复印ID",
|
||||
"exchange_result_write_down_trade_id" : "请复制或写下交易编号以继续.",
|
||||
"trade_id" : "贸易编号:\n${id}",
|
||||
"trade_id" : "贸易编号:",
|
||||
"copied_to_clipboard" : "复制到剪贴板",
|
||||
"saved_the_trade_id" : "我已经保存了交易ID",
|
||||
"fetching" : "正在取得",
|
||||
|
|
Loading…
Reference in a new issue