CWA-219 | created clear button and fiat currency picker; changed clear button in the send page; fiat and crypto balance aligned to baseline on wallet card; added placeholders to trade_history_panel and address_book_page; keyboard doesn't appear when buttons in the address text field are pressed

Oleksandr Sobol committed Jun 2, 2020 at 21:03 UTC bc88fa9758f63784545d7b337385b1e6f44a88bd
22 files changed +514 -277
lib/generated/i18n.dart
+46
@@ -121,6 +121,8 @@ class S implements WidgetsLocalizations {
121 String get payment_id => "Payment ID: ";
122 String get pending => " (pending)";
123 String get pin_is_incorrect => "PIN is incorrect";
124 + String get placeholder_contacts => "Your contacts will be displayed here";
125 + String get placeholder_transactions => "Your transactions will be displayed here";
126 String get please_make_selection => "Please make selection below to create or recover your wallet.";
127 String get please_select => "Please select:";
128 String get please_try_to_connect_to_another_node => "Please try to connect to another node";
@@ -392,6 +394,8 @@ class $de extends S {
394 @override
395 String get wallet_list_create_new_wallet => "Neue Wallet erstellen";
396 @override
397 + String get placeholder_contacts => "Ihre Kontakte werden hier angezeigt";
398 + @override
399 String get card_address => "Adresse:";
400 @override
401 String get seed_language_portuguese => "Portugiesisch";
@@ -462,6 +466,8 @@ class $de extends S {
466 @override
467 String get settings_display_balance_as => "Kontostand anzeigen als";
468 @override
469 + String get placeholder_transactions => "Ihre Transaktionen werden hier angezeigt";
470 + @override
471 String get trade_details_provider => "Anbieter";
472 @override
473 String get seed_language_japanese => "Japanisch";
@@ -1008,6 +1014,8 @@ class $hi extends S {
1014 @override
1015 String get wallet_list_create_new_wallet => "नया बटुआ बनाएँ";
1016 @override
1017 + String get placeholder_contacts => "आपके संपर्क यहां प्रदर्शित होंगे";
1018 + @override
1019 String get card_address => "पता:";
1020 @override
1021 String get seed_language_portuguese => "पुर्तगाली";
@@ -1078,6 +1086,8 @@ class $hi extends S {
1086 @override
1087 String get settings_display_balance_as => "के रूप में संतुलन प्रदर्शित करें";
1088 @override
1089 + String get placeholder_transactions => "आपके लेनदेन यहां प्रदर्शित होंगे";
1090 + @override
1091 String get trade_details_provider => "प्रदाता";
1092 @override
1093 String get seed_language_japanese => "जापानी";
@@ -1624,6 +1634,8 @@ class $ru extends S {
1634 @override
1635 String get wallet_list_create_new_wallet => "Создать новый кошелёк";
1636 @override
1637 + String get placeholder_contacts => "Ваши контакты будут отображаться здесь";
1638 + @override
1639 String get card_address => "Адрес:";
1640 @override
1641 String get seed_language_portuguese => "Португальский";
@@ -1694,6 +1706,8 @@ class $ru extends S {
1706 @override
1707 String get settings_display_balance_as => "Отображать баланс как";
1708 @override
1709 + String get placeholder_transactions => "Ваши транзакции будут отображаться здесь";
1710 + @override
1711 String get trade_details_provider => "Провайдер";
1712 @override
1713 String get seed_language_japanese => "Японский";
@@ -2240,6 +2254,8 @@ class $ko extends S {
2254 @override
2255 String get wallet_list_create_new_wallet => "새 월렛 만들기";
2256 @override
2257 + String get placeholder_contacts => "연락처가 여기에 표시됩니다";
2258 + @override
2259 String get card_address => "주소:";
2260 @override
2261 String get seed_language_portuguese => "포르투갈 인";
@@ -2310,6 +2326,8 @@ class $ko extends S {
2326 @override
2327 String get settings_display_balance_as => "잔액 표시";
2328 @override
2329 + String get placeholder_transactions => "거래가 여기에 표시됩니다";
2330 + @override
2331 String get trade_details_provider => "공급자";
2332 @override
2333 String get seed_language_japanese => "일본어";
@@ -2856,6 +2874,8 @@ class $pt extends S {
2874 @override
2875 String get wallet_list_create_new_wallet => "Criar nova carteira";
2876 @override
2877 + String get placeholder_contacts => "Seus contatos serão exibidos aqui";
2878 + @override
2879 String get card_address => "Endereço:";
2880 @override
2881 String get seed_language_portuguese => "Português";
@@ -2926,6 +2946,8 @@ class $pt extends S {
2946 @override
2947 String get settings_display_balance_as => "Saldo a exibir";
2948 @override
2949 + String get placeholder_transactions => "Suas transações serão exibidas aqui";
2950 + @override
2951 String get trade_details_provider => "Provedor";
2952 @override
2953 String get seed_language_japanese => "Japonês";
@@ -3472,6 +3494,8 @@ class $uk extends S {
3494 @override
3495 String get wallet_list_create_new_wallet => "Створити новий гаманець";
3496 @override
3497 + String get placeholder_contacts => "Тут будуть показані ваші контакти";
3498 + @override
3499 String get card_address => "Адреса:";
3500 @override
3501 String get seed_language_portuguese => "Португальська";
@@ -3542,6 +3566,8 @@ class $uk extends S {
3566 @override
3567 String get settings_display_balance_as => "Відображати баланс як";
3568 @override
3569 + String get placeholder_transactions => "Тут відображатимуться ваші транзакції";
3570 + @override
3571 String get trade_details_provider => "Провайдер";
3572 @override
3573 String get seed_language_japanese => "Японська";
@@ -4088,6 +4114,8 @@ class $ja extends S {
4114 @override
4115 String get wallet_list_create_new_wallet => "新しいウォレットを作成";
4116 @override
4117 + String get placeholder_contacts => "連絡先はここに表示されます";
4118 + @override
4119 String get card_address => "住所:";
4120 @override
4121 String get seed_language_portuguese => "ポルトガル語";
@@ -4158,6 +4186,8 @@ class $ja extends S {
4186 @override
4187 String get settings_display_balance_as => "残高を表示";
4188 @override
4189 + String get placeholder_transactions => "あなたの取引はここに表示されます";
4190 + @override
4191 String get trade_details_provider => "プロバイダー";
4192 @override
4193 String get seed_language_japanese => "日本語";
@@ -4708,6 +4738,8 @@ class $pl extends S {
4738 @override
4739 String get wallet_list_create_new_wallet => "Utwórz nowy portfel";
4740 @override
4741 + String get placeholder_contacts => "Twoje kontakty zostaną wyświetlone tutaj";
4742 + @override
4743 String get card_address => "Adres:";
4744 @override
4745 String get seed_language_portuguese => "Portugalski";
@@ -4778,6 +4810,8 @@ class $pl extends S {
4810 @override
4811 String get settings_display_balance_as => "Wyświetl saldo jako";
4812 @override
4813 + String get placeholder_transactions => "Twoje transakcje zostaną wyświetlone tutaj";
4814 + @override
4815 String get trade_details_provider => "Dostawca";
4816 @override
4817 String get seed_language_japanese => "Japoński";
@@ -5324,6 +5358,8 @@ class $es extends S {
5358 @override
5359 String get wallet_list_create_new_wallet => "Crear nueva billetera";
5360 @override
5361 + String get placeholder_contacts => "Tus contactos se mostrarán aquí";
5362 + @override
5363 String get card_address => "Dirección:";
5364 @override
5365 String get seed_language_portuguese => "Portugués";
@@ -5394,6 +5430,8 @@ class $es extends S {
5430 @override
5431 String get settings_display_balance_as => "Mostrar saldo como";
5432 @override
5433 + String get placeholder_transactions => "Sus transacciones se mostrarán aquí";
5434 + @override
5435 String get trade_details_provider => "Proveedor";
5436 @override
5437 String get seed_language_japanese => "Japonés";
@@ -5940,6 +5978,8 @@ class $nl extends S {
5978 @override
5979 String get wallet_list_create_new_wallet => "Maak een nieuwe portemonnee";
5980 @override
5981 + String get placeholder_contacts => "Je contacten worden hier weergegeven";
5982 + @override
5983 String get card_address => "Adres:";
5984 @override
5985 String get seed_language_portuguese => "Portugees";
@@ -6010,6 +6050,8 @@ class $nl extends S {
6050 @override
6051 String get settings_display_balance_as => "Toon saldo als";
6052 @override
6053 + String get placeholder_transactions => "Uw transacties worden hier weergegeven";
6054 + @override
6055 String get trade_details_provider => "Leverancier";
6056 @override
6057 String get seed_language_japanese => "Japans";
@@ -6556,6 +6598,8 @@ class $zh extends S {
6598 @override
6599 String get wallet_list_create_new_wallet => "创建新钱包";
6600 @override
6601 + String get placeholder_contacts => "您的聯繫人將顯示在這裡";
6602 + @override
6603 String get card_address => "地址:";
6604 @override
6605 String get seed_language_portuguese => "葡萄牙語";
@@ -6626,6 +6670,8 @@ class $zh extends S {
6670 @override
6671 String get settings_display_balance_as => "将余额显示为";
6672 @override
6673 + String get placeholder_transactions => "您的交易將顯示在這裡";
6674 + @override
6675 String get trade_details_provider => "提供者";
6676 @override
6677 String get seed_language_japanese => "日本";
lib/src/screens/address_book/address_book_page.dart
+145 -130
@@ -64,148 +64,163 @@ class AddressBookPage extends BasePage {
64 color: Theme.of(context).backgroundColor,
65 padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
66 child: Observer(
67 - builder: (_) => ListView.separated(
68 - separatorBuilder: (_, __) => Container(
69 - height: 1,
70 - padding: EdgeInsets.only(left: 24),
71 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
72 - child: Container(
67 + builder: (_) {
68 + final count = addressBookStore.contactList == null
69 + ? 0
70 + : addressBookStore.contactList.length;
71 +
72 + return count > 0
73 + ? ListView.separated(
74 + separatorBuilder: (_, __) => Container(
75 height: 1,
74 - color: Theme.of(context).dividerColor,
76 + padding: EdgeInsets.only(left: 24),
77 + color: Theme.of(context).accentTextTheme.title.backgroundColor,
78 + child: Container(
79 + height: 1,
80 + color: Theme.of(context).dividerColor,
81 + ),
82 ),
76 - ),
77 - itemCount: addressBookStore.contactList == null
78 - ? 0
79 - : addressBookStore.contactList.length,
80 - itemBuilder: (BuildContext context, int index) {
81 - final contact = addressBookStore.contactList[index];
82 - final image = _getCurrencyImage(contact.type);
83 + itemCount: count,
84 + itemBuilder: (BuildContext context, int index) {
85 + final contact = addressBookStore.contactList[index];
86 + final image = _getCurrencyImage(contact.type);
87
84 - final isDrawTop = index == 0 ? true : false;
85 - final isDrawBottom = index == addressBookStore.contactList.length - 1 ? true : false;
88 + final isDrawTop = index == 0 ? true : false;
89 + final isDrawBottom = index == addressBookStore.contactList.length - 1 ? true : false;
90
87 - final content = GestureDetector(
88 - onTap: () async {
89 - if (!isEditable) {
90 - Navigator.of(context).pop(contact);
91 - return;
92 - }
91 + final content = GestureDetector(
92 + onTap: () async {
93 + if (!isEditable) {
94 + Navigator.of(context).pop(contact);
95 + return;
96 + }
97
94 - final isCopied = await showNameAndAddressDialog(
95 - context, contact.name, contact.address);
98 + final isCopied = await showNameAndAddressDialog(
99 + context, contact.name, contact.address);
100
97 - if (isCopied != null && isCopied) {
98 - await Clipboard.setData(
99 - ClipboardData(text: contact.address));
100 - Scaffold.of(context).showSnackBar(
101 - SnackBar(
102 - content: Text(
103 - S.of(context).copied_to_clipboard,
104 - style: TextStyle(
105 - color: Colors.white
101 + if (isCopied != null && isCopied) {
102 + await Clipboard.setData(
103 + ClipboardData(text: contact.address));
104 + Scaffold.of(context).showSnackBar(
105 + SnackBar(
106 + content: Text(
107 + S.of(context).copied_to_clipboard,
108 + style: TextStyle(
109 + color: Colors.white
110 + ),
111 ),
112 + backgroundColor: Colors.green,
113 + duration: Duration(milliseconds: 1500),
114 ),
108 - backgroundColor: Colors.green,
109 - duration: Duration(milliseconds: 1500),
110 - ),
111 - );
112 - }
113 - },
114 - child: Column(
115 - children: <Widget>[
116 - isDrawTop
117 - ? Container(
118 - width: double.infinity,
119 - height: 1,
120 - color: Theme.of(context).dividerColor,
121 - )
122 - : Offstage(),
123 - Container(
124 - width: double.infinity,
125 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
126 - child: Padding(
127 - padding: const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
128 - child: Row(
129 - mainAxisSize: MainAxisSize.min,
130 - mainAxisAlignment: MainAxisAlignment.start,
131 - crossAxisAlignment: CrossAxisAlignment.center,
132 - children: <Widget>[
133 - image != null
134 - ? image
135 - : Offstage(),
136 - Padding(
137 - padding: image != null
138 - ? EdgeInsets.only(left: 12)
139 - : EdgeInsets.only(left: 0),
140 - child: Text(
141 - contact.name,
142 - style: TextStyle(
143 - fontSize: 14,
144 - color: Theme.of(context).primaryTextTheme.title.color
145 - ),
146 - ),
115 + );
116 + }
117 + },
118 + child: Column(
119 + children: <Widget>[
120 + isDrawTop
121 + ? Container(
122 + width: double.infinity,
123 + height: 1,
124 + color: Theme.of(context).dividerColor,
125 + )
126 + : Offstage(),
127 + Container(
128 + width: double.infinity,
129 + color: Theme.of(context).accentTextTheme.title.backgroundColor,
130 + child: Padding(
131 + padding: const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
132 + child: Row(
133 + mainAxisSize: MainAxisSize.min,
134 + mainAxisAlignment: MainAxisAlignment.start,
135 + crossAxisAlignment: CrossAxisAlignment.center,
136 + children: <Widget>[
137 + image != null
138 + ? image
139 + : Offstage(),
140 + Padding(
141 + padding: image != null
142 + ? EdgeInsets.only(left: 12)
143 + : EdgeInsets.only(left: 0),
144 + child: Text(
145 + contact.name,
146 + style: TextStyle(
147 + fontSize: 14,
148 + color: Theme.of(context).primaryTextTheme.title.color
149 + ),
150 + ),
151 + )
152 + ],
153 )
148 - ],
149 - )
154 + ),
155 ),
151 - ),
152 - isDrawBottom
153 - ? Container(
154 - width: double.infinity,
155 - height: 1,
156 - color: Theme.of(context).dividerColor,
157 - )
158 - : Offstage(),
159 - ],
160 - ),
161 - );
156 + isDrawBottom
157 + ? Container(
158 + width: double.infinity,
159 + height: 1,
160 + color: Theme.of(context).dividerColor,
161 + )
162 + : Offstage(),
163 + ],
164 + ),
165 + );
166
163 - return !isEditable
164 - ? content
165 - : Slidable(
166 - key: Key('${contact.key}'),
167 - actionPane: SlidableDrawerActionPane(),
168 - child: content,
169 - secondaryActions: <Widget>[
170 - IconSlideAction(
171 - caption: S.of(context).edit,
172 - color: Colors.blue,
173 - icon: Icons.edit,
174 - onTap: () async {
175 - await Navigator.of(context).pushNamed(
176 - Routes.addressBookAddContact,
177 - arguments: contact);
167 + return !isEditable
168 + ? content
169 + : Slidable(
170 + key: Key('${contact.key}'),
171 + actionPane: SlidableDrawerActionPane(),
172 + child: content,
173 + secondaryActions: <Widget>[
174 + IconSlideAction(
175 + caption: S.of(context).edit,
176 + color: Colors.blue,
177 + icon: Icons.edit,
178 + onTap: () async {
179 + await Navigator.of(context).pushNamed(
180 + Routes.addressBookAddContact,
181 + arguments: contact);
182 + await addressBookStore.updateContactList();
183 + },
184 + ),
185 + IconSlideAction(
186 + caption: S.of(context).delete,
187 + color: Colors.red,
188 + icon: CupertinoIcons.delete,
189 + onTap: () async {
190 + await showAlertDialog(context)
191 + .then((isDelete) async {
192 + if (isDelete != null && isDelete) {
193 + await addressBookStore.delete(
194 + contact: contact);
195 await addressBookStore.updateContactList();
179 - },
180 - ),
181 - IconSlideAction(
182 - caption: S.of(context).delete,
183 - color: Colors.red,
184 - icon: CupertinoIcons.delete,
185 - onTap: () async {
186 - await showAlertDialog(context)
187 - .then((isDelete) async {
188 - if (isDelete != null && isDelete) {
189 - await addressBookStore.delete(
190 - contact: contact);
191 - await addressBookStore.updateContactList();
192 - }
193 - });
194 - },
195 - ),
196 - ],
197 - dismissal: SlidableDismissal(
198 - child: SlidableDrawerDismissal(),
199 - onDismissed: (actionType) async {
200 - await addressBookStore.delete(contact: contact);
201 - await addressBookStore.updateContactList();
202 - },
203 - onWillDismiss: (actionType) async {
204 - return await showAlertDialog(context);
205 - },
206 - ),
207 - );
208 - }),
196 + }
197 + });
198 + },
199 + ),
200 + ],
201 + dismissal: SlidableDismissal(
202 + child: SlidableDrawerDismissal(),
203 + onDismissed: (actionType) async {
204 + await addressBookStore.delete(contact: contact);
205 + await addressBookStore.updateContactList();
206 + },
207 + onWillDismiss: (actionType) async {
208 + return await showAlertDialog(context);
209 + },
210 + ),
211 + );
212 + })
213 + : Center(
214 + child: Text(
215 + S.of(context).placeholder_contacts,
216 + textAlign: TextAlign.center,
217 + style: TextStyle(
218 + color: Theme.of(context).primaryTextTheme.caption.color.withOpacity(0.5),
219 + fontSize: 12
220 + ),
221 + ),
222 + );
223 + },
224 ));
225 }
226
lib/src/screens/dashboard/widgets/trade_history_panel.dart
+13
@@ -14,6 +14,7 @@ import 'date_section_raw.dart';
14 import 'trade_row.dart';
15 import 'transaction_raw.dart';
16 import 'button_header.dart';
17 +import 'package:cake_wallet/generated/i18n.dart';
18
19 class TradeHistoryPanel extends StatefulWidget {
20 @override
@@ -88,6 +89,18 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
89 height: freeSpaceHeight,
90 width: MediaQuery.of(context).size.width,
91 color: Theme.of(context).backgroundColor,
92 + child: itemsCount > 1
93 + ? Offstage()
94 + : Center(
95 + child: Text(
96 + S.of(context).placeholder_transactions,
97 + textAlign: TextAlign.center,
98 + style: TextStyle(
99 + color: Theme.of(context).primaryTextTheme.caption.color.withOpacity(0.5),
100 + fontSize: 12
101 + ),
102 + ),
103 + ),
104 );
105 }
106
lib/src/screens/dashboard/widgets/wallet_card.dart
+2
@@ -279,6 +279,7 @@ class WalletCardState extends State<WalletCard> {
279 balance,
280 style: TextStyle(
281 fontSize: 28,
282 + height: 1,
283 color: Theme.of(context).primaryTextTheme.title.color
284 ),
285 )
@@ -288,6 +289,7 @@ class WalletCardState extends State<WalletCard> {
289 fiatBalance,
290 style: TextStyle(
291 fontSize: 14,
292 + height: 2,
293 color: Theme.of(context).primaryTextTheme.title.color
294 ),
295 )
lib/src/screens/exchange/exchange_page.dart
+3 -14
@@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
10 import 'package:cake_wallet/src/stores/exchange_template/exchange_template_store.dart';
11 import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker.dart';
12 import 'package:cake_wallet/src/screens/exchange/widgets/base_exchange_widget.dart';
13 +import 'package:cake_wallet/src/widgets/clear_button.dart';
14
15 class ExchangePage extends BasePage {
16 @override
@@ -32,20 +33,8 @@ class ExchangePage extends BasePage {
33 Widget trailing(BuildContext context) {
34 final exchangeStore = Provider.of<ExchangeStore>(context);
35
35 - return ButtonTheme(
36 - minWidth: double.minPositive,
37 - highlightColor: Colors.transparent,
38 - splashColor: Colors.transparent,
39 - child: FlatButton(
40 - padding: EdgeInsets.all(0),
41 - child: Text(
42 - S.of(context).clear,
43 - style: TextStyle(
44 - color: Theme.of(context).primaryTextTheme.caption.color,
45 - fontWeight: FontWeight.w500,
46 - fontSize: 14),
47 - ),
48 - onPressed: () => exchangeStore.reset()),
36 + return ClearButton(
37 + onPressed: () => exchangeStore.reset()
38 );
39 }
40
lib/src/screens/send/send_page.dart
+3 -19
@@ -29,6 +29,7 @@ import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart'
29 import 'package:cake_wallet/src/screens/send/widgets/sending_alert.dart';
30 import 'package:cake_wallet/src/widgets/template_tile.dart';
31 import 'package:cake_wallet/src/stores/send_template/send_template_store.dart';
32 +import 'package:cake_wallet/src/widgets/clear_button.dart';
33
34 class SendPage extends BasePage {
35 @override
@@ -47,25 +48,8 @@ class SendPage extends BasePage {
48 Widget trailing(context) {
49 final sendStore = Provider.of<SendStore>(context);
50
50 - return Container(
51 - height: 32,
52 - width: 82,
53 - decoration: BoxDecoration(
54 - borderRadius: BorderRadius.all(Radius.circular(16)),
55 - color: Theme.of(context).accentTextTheme.title.color
56 - ),
57 - child: ButtonTheme(
58 - minWidth: double.minPositive,
59 - child: FlatButton(
60 - onPressed: () => sendStore.clear(),
61 - child: Text(
62 - S.of(context).clear,
63 - textAlign: TextAlign.center,
64 - style: TextStyle(
65 - fontSize: 10.0,
66 - color: Colors.blue),
67 - )),
68 - ),
51 + return ClearButton(
52 + onPressed: () => sendStore.clear()
53 );
54 }
55
lib/src/screens/settings/settings.dart
+8 -7
@@ -24,6 +24,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_link_list_row.
24 import 'package:cake_wallet/src/screens/settings/widgets/settings_switch_list_row.dart';
25 import 'package:cake_wallet/src/screens/settings/widgets/settings_text_list_row.dart';
26 import 'package:cake_wallet/src/screens/settings/widgets/settings_raw_widget_list_row.dart';
27 +import 'package:cake_wallet/src/screens/settings/widgets/fiat_currency_picker.dart';
28
29 class SettingsPage extends BasePage {
30 @override
@@ -409,13 +410,13 @@ class SettingsFormState extends State<SettingsForm> {
410 final selectedItem = items.indexOf(settingsStore.fiatCurrency);
411
412 await showDialog<void>(
412 - builder: (_) => Picker(
413 - items: items,
414 - selectedAtIndex: selectedItem,
415 - title: S.of(context).please_select,
416 - mainAxisAlignment: MainAxisAlignment.center,
417 - onItemSelected: (FiatCurrency currency) async =>
418 - await settingsStore.setCurrentFiatCurrency(currency: currency)),
413 + builder: (_) => FiatCurrencyPicker(
414 + selectedAtIndex: selectedItem,
415 + items: items,
416 + title: S.of(context).please_select,
417 + onItemSelected: (currency) async =>
418 + await settingsStore.setCurrentFiatCurrency(currency: currency)
419 + ),
420 context: context);
421 }
422
lib/src/screens/settings/widgets/fiat_currency_picker.dart new
+111
@@ -0,0 +1,111 @@
1 +import 'dart:ui';
2 +import 'package:flutter/cupertino.dart';
3 +import 'package:flutter/material.dart';
4 +import 'package:cake_wallet/palette.dart';
5 +import 'package:cake_wallet/src/domain/common/fiat_currency.dart';
6 +
7 +class FiatCurrencyPicker extends StatelessWidget {
8 + FiatCurrencyPicker({
9 + @required this.selectedAtIndex,
10 + @required this.items,
11 + @required this.title,
12 + @required this.onItemSelected,
13 + });
14 +
15 + final int selectedAtIndex;
16 + final List<FiatCurrency> items;
17 + final String title;
18 + final Function(FiatCurrency) onItemSelected;
19 +
20 + @override
21 + Widget build(BuildContext context) {
22 + return GestureDetector(
23 + onTap: () => Navigator.of(context).pop(),
24 + child: Container(
25 + color: Colors.transparent,
26 + child: BackdropFilter(
27 + filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
28 + child: Container(
29 + decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)),
30 + child: Center(
31 + child: Column(
32 + mainAxisSize: MainAxisSize.min,
33 + children: <Widget>[
34 + Container(
35 + padding: EdgeInsets.only(left: 24, right: 24),
36 + child: Text(
37 + title,
38 + textAlign: TextAlign.center,
39 + style: TextStyle(
40 + fontSize: 18,
41 + fontWeight: FontWeight.bold,
42 + decoration: TextDecoration.none,
43 + color: Colors.white
44 + ),
45 + ),
46 + ),
47 + Padding(
48 + padding: EdgeInsets.only(top: 24),
49 + child: GestureDetector(
50 + onTap: () => null,
51 + child: ClipRRect(
52 + borderRadius: BorderRadius.all(Radius.circular(14)),
53 + child: Container(
54 + height: 400,
55 + width: 300,
56 + color: Theme.of(context).dividerColor,
57 + child: GridView.count(
58 + crossAxisCount: 3,
59 + childAspectRatio: 1.25,
60 + crossAxisSpacing: 1,
61 + mainAxisSpacing: 1,
62 + children: List.generate(items.length, (index) {
63 +
64 + final item = items[index];
65 + final isItemSelected = index == selectedAtIndex;
66 +
67 + final color = isItemSelected
68 + ? Theme.of(context).accentTextTheme.subtitle.decorationColor
69 + : Theme.of(context).primaryTextTheme.display1.color;
70 + final textColor = isItemSelected
71 + ? Colors.blue
72 + : Theme.of(context).primaryTextTheme.title.color;
73 +
74 + return GestureDetector(
75 + onTap: () {
76 + if (onItemSelected == null) {
77 + return;
78 + }
79 + Navigator.of(context).pop();
80 + onItemSelected(item);
81 + },
82 + child: Container(
83 + color: color,
84 + child: Center(
85 + child: Text(
86 + item.toString(),
87 + style: TextStyle(
88 + fontSize: 18,
89 + fontWeight: FontWeight.bold,
90 + decoration: TextDecoration.none,
91 + color: textColor
92 + ),
93 + ),
94 + ),
95 + ),
96 + );
97 + })
98 + ),
99 + ),
100 + ),
101 + ),
102 + )
103 + ],
104 + ),
105 + )
106 + ),
107 + ),
108 + ),
109 + );
110 + }
111 +}
\ No newline at end of file
lib/src/widgets/address_text_field.dart
+107 -95
@@ -38,103 +38,115 @@ class AddressTextField extends StatelessWidget {
38
39 @override
40 Widget build(BuildContext context) {
41 - return TextFormField(
42 - onFieldSubmitted: (_) => FocusScope.of(context).unfocus(),
43 - enabled: isActive,
44 - controller: controller,
45 - focusNode: focusNode,
46 - style: TextStyle(
47 - fontSize: 16,
48 - color: Theme.of(context).primaryTextTheme.title.color
49 - ),
50 - decoration: InputDecoration(
51 - suffixIcon: SizedBox(
52 - width: prefixIconWidth * options.length +
53 - (spaceBetweenPrefixIcons * options.length),
54 - child: Row(
55 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
56 - children: [
57 - SizedBox(width: 5),
58 - if (this.options.contains(AddressTextFieldOption.qrCode)) ...[
59 - Container(
60 - width: prefixIconWidth,
61 - height: prefixIconHeight,
62 - padding: EdgeInsets.only(top: 0),
63 - child: InkWell(
64 - onTap: () async => _presentQRScanner(context),
65 - child: Container(
66 - padding: EdgeInsets.all(8),
67 - decoration: BoxDecoration(
68 - color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
69 - borderRadius:
70 - BorderRadius.all(Radius.circular(6))),
71 - child: Image.asset('assets/images/qr_code_icon.png')),
72 - ))
73 - ],
74 - if (this
75 - .options
76 - .contains(AddressTextFieldOption.addressBook)) ...[
77 - Container(
78 - width: prefixIconWidth,
79 - height: prefixIconHeight,
80 - padding: EdgeInsets.only(top: 0),
81 - child: InkWell(
82 - onTap: () async => _presetAddressBookPicker(context),
83 - child: Container(
84 - padding: EdgeInsets.all(8),
85 - decoration: BoxDecoration(
86 - color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
87 - borderRadius:
88 - BorderRadius.all(Radius.circular(6))),
89 - child: Image.asset(
90 - 'assets/images/open_book.png')),
91 - ))
92 - ],
93 - if (this
94 - .options
95 - .contains(AddressTextFieldOption.subaddressList)) ...[
96 - Container(
97 - width: prefixIconWidth,
98 - height: prefixIconHeight,
99 - padding: EdgeInsets.only(top: 0),
100 - child: InkWell(
101 - onTap: () async => _presetSubaddressListPicker(context),
102 - child: Container(
103 - padding: EdgeInsets.all(8),
104 - decoration: BoxDecoration(
105 - color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
106 - borderRadius:
107 - BorderRadius.all(Radius.circular(6))),
108 - child: Image.asset(
109 - 'assets/images/receive_icon_raw.png')),
110 - ))
111 - ],
112 - ],
41 + return Stack(
42 + children: <Widget>[
43 + TextFormField(
44 + onFieldSubmitted: (_) => FocusScope.of(context).unfocus(),
45 + enabled: isActive,
46 + controller: controller,
47 + focusNode: focusNode,
48 + style: TextStyle(
49 + fontSize: 16,
50 + color: Theme.of(context).primaryTextTheme.title.color
51 ),
114 - ),
115 - hintStyle: TextStyle(
116 - fontSize: 16,
117 - color: Theme.of(context).primaryTextTheme.caption.color
118 - ),
119 - hintText: placeholder ?? S.current.widgets_address,
120 - focusedBorder: isBorderExist
121 - ? UnderlineInputBorder(
122 - borderSide: BorderSide(
123 - color: Theme.of(context).dividerColor,
124 - width: 1.0))
125 - : InputBorder.none,
126 - disabledBorder: isBorderExist
127 - ? UnderlineInputBorder(
128 - borderSide:
129 - BorderSide(color: Theme.of(context).dividerColor, width: 1.0))
130 - : InputBorder.none,
131 - enabledBorder: isBorderExist
132 - ? UnderlineInputBorder(
133 - borderSide:
52 + decoration: InputDecoration(
53 + suffixIcon: SizedBox(
54 + width: prefixIconWidth * options.length +
55 + (spaceBetweenPrefixIcons * options.length),
56 + ),
57 + hintStyle: TextStyle(
58 + fontSize: 16,
59 + color: Theme.of(context).primaryTextTheme.caption.color
60 + ),
61 + hintText: placeholder ?? S.current.widgets_address,
62 + focusedBorder: isBorderExist
63 + ? UnderlineInputBorder(
64 + borderSide: BorderSide(
65 + color: Theme.of(context).dividerColor,
66 + width: 1.0))
67 + : InputBorder.none,
68 + disabledBorder: isBorderExist
69 + ? UnderlineInputBorder(
70 + borderSide:
71 BorderSide(color: Theme.of(context).dividerColor, width: 1.0))
135 - : InputBorder.none,
136 - ),
137 - validator: validator,
72 + : InputBorder.none,
73 + enabledBorder: isBorderExist
74 + ? UnderlineInputBorder(
75 + borderSide:
76 + BorderSide(color: Theme.of(context).dividerColor, width: 1.0))
77 + : InputBorder.none,
78 + ),
79 + validator: validator,
80 + ),
81 + Positioned(
82 + bottom: 10,
83 + right: 0,
84 + child: SizedBox(
85 + width: prefixIconWidth * options.length +
86 + (spaceBetweenPrefixIcons * options.length),
87 + child: Row(
88 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
89 + children: [
90 + SizedBox(width: 5),
91 + if (this.options.contains(AddressTextFieldOption.qrCode)) ...[
92 + Container(
93 + width: prefixIconWidth,
94 + height: prefixIconHeight,
95 + padding: EdgeInsets.only(top: 0),
96 + child: InkWell(
97 + onTap: () async => _presentQRScanner(context),
98 + child: Container(
99 + padding: EdgeInsets.all(8),
100 + decoration: BoxDecoration(
101 + color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
102 + borderRadius:
103 + BorderRadius.all(Radius.circular(6))),
104 + child: Image.asset('assets/images/qr_code_icon.png')),
105 + ))
106 + ],
107 + if (this
108 + .options
109 + .contains(AddressTextFieldOption.addressBook)) ...[
110 + Container(
111 + width: prefixIconWidth,
112 + height: prefixIconHeight,
113 + padding: EdgeInsets.only(top: 0),
114 + child: InkWell(
115 + onTap: () async => _presetAddressBookPicker(context),
116 + child: Container(
117 + padding: EdgeInsets.all(8),
118 + decoration: BoxDecoration(
119 + color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
120 + borderRadius:
121 + BorderRadius.all(Radius.circular(6))),
122 + child: Image.asset(
123 + 'assets/images/open_book.png')),
124 + ))
125 + ],
126 + if (this
127 + .options
128 + .contains(AddressTextFieldOption.subaddressList)) ...[
129 + Container(
130 + width: prefixIconWidth,
131 + height: prefixIconHeight,
132 + padding: EdgeInsets.only(top: 0),
133 + child: InkWell(
134 + onTap: () async => _presetSubaddressListPicker(context),
135 + child: Container(
136 + padding: EdgeInsets.all(8),
137 + decoration: BoxDecoration(
138 + color: buttonColor ?? Theme.of(context).accentTextTheme.title.color,
139 + borderRadius:
140 + BorderRadius.all(Radius.circular(6))),
141 + child: Image.asset(
142 + 'assets/images/receive_icon_raw.png')),
143 + ))
144 + ],
145 + ],
146 + ),
147 + )
148 + )
149 + ],
150 );
151 }
152
lib/src/widgets/clear_button.dart new
+28
@@ -0,0 +1,28 @@
1 +import 'package:flutter/material.dart';
2 +import 'package:cake_wallet/generated/i18n.dart';
3 +
4 +class ClearButton extends StatelessWidget {
5 + ClearButton({@required this.onPressed});
6 +
7 + final VoidCallback onPressed;
8 +
9 + @override
10 + Widget build(BuildContext context) {
11 +
12 + return ButtonTheme(
13 + minWidth: double.minPositive,
14 + highlightColor: Colors.transparent,
15 + splashColor: Colors.transparent,
16 + child: FlatButton(
17 + padding: EdgeInsets.all(0),
18 + child: Text(
19 + S.of(context).clear,
20 + style: TextStyle(
21 + color: Theme.of(context).primaryTextTheme.caption.color,
22 + fontWeight: FontWeight.w500,
23 + fontSize: 14),
24 + ),
25 + onPressed: onPressed),
26 + );
27 + }
28 +}
\ No newline at end of file
res/values/strings_de.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Sie senden Geld an\n${recipient_name}",
375
376 "card_address" : "Adresse:",
377 - "buy" : "Kaufen"
377 + "buy" : "Kaufen",
378 +
379 + "placeholder_transactions" : "Ihre Transaktionen werden hier angezeigt",
380 + "placeholder_contacts" : "Ihre Kontakte werden hier angezeigt"
381 }
\ No newline at end of file
res/values/strings_en.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "You will be sending funds to\n${recipient_name}",
375
376 "card_address" : "Address:",
377 - "buy" : "Buy"
377 + "buy" : "Buy",
378 +
379 + "placeholder_transactions" : "Your transactions will be displayed here",
380 + "placeholder_contacts" : "Your contacts will be displayed here"
381 }
\ No newline at end of file
res/values/strings_es.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Enviará fondos a\n${recipient_name}",
375
376 "card_address" : "Dirección:",
377 - "buy" : "Comprar"
377 + "buy" : "Comprar",
378 +
379 + "placeholder_transactions" : "Sus transacciones se mostrarán aquí",
380 + "placeholder_contacts" : "Tus contactos se mostrarán aquí"
381 }
\ No newline at end of file
res/values/strings_hi.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}",
375
376 "card_address" : "पता:",
377 - "buy" : "खरीदें"
377 + "buy" : "खरीदें",
378 +
379 + "placeholder_transactions" : "आपके लेनदेन यहां प्रदर्शित होंगे",
380 + "placeholder_contacts" : "आपके संपर्क यहां प्रदर्शित होंगे"
381 }
\ No newline at end of file
res/values/strings_ja.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "に送金します\n${recipient_name}",
375
376 "card_address" : "住所:",
377 - "buy" : "購入"
377 + "buy" : "購入",
378 +
379 + "placeholder_transactions" : "あなたの取引はここに表示されます",
380 + "placeholder_contacts" : "連絡先はここに表示されます"
381 }
\ No newline at end of file
res/values/strings_ko.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}",
375
376 "card_address" : "주소:",
377 - "buy" : "구입"
377 + "buy" : "구입",
378 +
379 + "placeholder_transactions" : "거래가 여기에 표시됩니다",
380 + "placeholder_contacts" : "연락처가 여기에 표시됩니다"
381 }
\ No newline at end of file
res/values/strings_nl.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "U stuurt geld naar\n${recipient_name}",
375
376 "card_address" : "Adres:",
377 - "buy" : "Kopen"
377 + "buy" : "Kopen",
378 +
379 + "placeholder_transactions" : "Uw transacties worden hier weergegeven",
380 + "placeholder_contacts" : "Je contacten worden hier weergegeven"
381 }
\ No newline at end of file
res/values/strings_pl.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Będziesz wysyłać środki na\n${recipient_name}",
375
376 "card_address" : "Adres:",
377 - "buy" : "Kup"
377 + "buy" : "Kup",
378 +
379 + "placeholder_transactions" : "Twoje transakcje zostaną wyświetlone tutaj",
380 + "placeholder_contacts" : "Twoje kontakty zostaną wyświetlone tutaj"
381 }
\ No newline at end of file
res/values/strings_pt.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Você enviará fundos para\n${recipient_name}",
375
376 "card_address" : "Endereço:",
377 - "buy" : "Comprar"
377 + "buy" : "Comprar",
378 +
379 + "placeholder_transactions" : "Suas transações serão exibidas aqui",
380 + "placeholder_contacts" : "Seus contatos serão exibidos aqui"
381 }
res/values/strings_ru.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}",
375
376 "card_address" : "Адрес:",
377 - "buy" : "Купить"
377 + "buy" : "Купить",
378 +
379 + "placeholder_transactions" : "Ваши транзакции будут отображаться здесь",
380 + "placeholder_contacts" : "Ваши контакты будут отображаться здесь"
381 }
\ No newline at end of file
res/values/strings_uk.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "Ви будете відправляти кошти\n${recipient_name}",
375
376 "card_address" : "Адреса:",
377 - "buy" : "Купити"
377 + "buy" : "Купити",
378 +
379 + "placeholder_transactions" : "Тут відображатимуться ваші транзакції",
380 + "placeholder_contacts" : "Тут будуть показані ваші контакти"
381 }
\ No newline at end of file
res/values/strings_zh.arb
+4 -1
@@ -374,5 +374,8 @@
374 "openalias_alert_content" : "您將匯款至\n${recipient_name}",
375
376 "card_address" : "地址:",
377 - "buy" : "購買"
377 + "buy" : "購買",
378 +
379 + "placeholder_transactions" : "您的交易將顯示在這裡",
380 + "placeholder_contacts" : "您的聯繫人將顯示在這裡"
381 }
\ No newline at end of file