CWA-210 | applied new design to send page; created sending alert and confirm sending alert

Oleksandr Sobol committed May 7, 2020 at 20:10 UTC 722efa2f89c02b69d39c6382ab854c329ab57a2c
13 files changed +506 -339
assets/images/2.0x/qr_code_icon.png
Binary files a/assets/images/2.0x/qr_code_icon.png and b/assets/images/2.0x/qr_code_icon.png differ
assets/images/3.0x/qr_code_icon.png
Binary files a/assets/images/3.0x/qr_code_icon.png and b/assets/images/3.0x/qr_code_icon.png differ
assets/images/birthday_cake.png
Binary files /dev/null and b/assets/images/birthday_cake.png differ
assets/images/qr_code_icon.png
Binary files a/assets/images/qr_code_icon.png and b/assets/images/qr_code_icon.png differ
lib/src/screens/send/send_page.dart
+258 -324
@@ -17,18 +17,23 @@ import 'package:cake_wallet/src/stores/send/send_store.dart';
17 import 'package:cake_wallet/src/stores/send/sending_state.dart';
18 import 'package:cake_wallet/src/screens/base_page.dart';
19 import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
20 -import 'package:cake_wallet/src/domain/common/balance_display_mode.dart';
20 import 'package:cake_wallet/src/domain/common/calculate_estimated_fee.dart';
21 import 'package:cake_wallet/generated/i18n.dart';
22 import 'package:cake_wallet/src/domain/common/sync_status.dart';
23 import 'package:cake_wallet/src/stores/sync/sync_store.dart';
24 +import 'package:cake_wallet/src/widgets/top_panel.dart';
25 +import 'package:dotted_border/dotted_border.dart';
26 +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
27 +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
28 +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
31 class SendPage extends BasePage {
32 @override
33 String get title => S.current.send_title;
34
35 @override
31 - bool get isModalBackButton => true;
36 + Color get backgroundColor => PaletteDark.menuList;
37
38 @override
39 bool get resizeToAvoidBottomPadding => false;
@@ -44,7 +49,6 @@ class SendForm extends StatefulWidget {
49
50 class SendFormState extends State<SendForm> {
51 final _addressController = TextEditingController();
47 - final _paymentIdController = TextEditingController();
52 final _cryptoAmountController = TextEditingController();
53 final _fiatAmountController = TextEditingController();
54
@@ -75,14 +79,11 @@ class SendFormState extends State<SendForm> {
79 await showDialog<void>(
80 context: context,
81 builder: (BuildContext context) {
78 - return AlertDialog(
79 - title: Text(S.of(context).openalias_alert_title),
80 - content: Text(S.of(context).openalias_alert_content(sendStore.recordName)),
81 - actions: <Widget>[
82 - FlatButton(
83 - child: Text(S.of(context).ok),
84 - onPressed: () => Navigator.of(context).pop())
85 - ],
82 + return AlertWithOneAction(
83 + alertTitle: S.of(context).openalias_alert_title,
84 + alertContent: S.of(context).openalias_alert_content(sendStore.recordName),
85 + buttonText: S.of(context).ok,
86 + buttonAction: () => Navigator.of(context).pop()
87 );
88 });
89 }
@@ -99,89 +100,16 @@ class SendFormState extends State<SendForm> {
100
101 _setEffects(context);
102
102 - return ScrollableWithBottomSection(
103 - contentPadding: EdgeInsets.all(0),
103 + return Container(
104 + color: PaletteDark.historyPanel,
105 + child: ScrollableWithBottomSection(
106 + contentPadding: EdgeInsets.only(bottom: 24),
107 content: Column(
105 - children: [
106 - Container(
107 - padding: EdgeInsets.only(left: 38, right: 30),
108 - decoration: BoxDecoration(
109 - color: Theme.of(context).backgroundColor,
110 - boxShadow: [
111 - BoxShadow(
112 - color: Palette.shadowGrey,
113 - blurRadius: 10,
114 - offset: Offset(0, 12),
115 - )
116 - ],
117 - border: Border(
118 - top: BorderSide(
119 - width: 1,
120 - color: Theme.of(context)
121 - .accentTextTheme
122 - .subtitle
123 - .backgroundColor))),
124 - child: SizedBox(
125 - height: 56,
126 - width: double.infinity,
127 - child: Row(
128 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
129 - children: <Widget>[
130 - Observer(builder: (_) {
131 - return Column(
132 - crossAxisAlignment: CrossAxisAlignment.start,
133 - mainAxisAlignment: MainAxisAlignment.center,
134 - children: <Widget>[
135 - Text(S.of(context).send_your_wallet,
136 - style: TextStyle(
137 - fontSize: 12, color: Palette.lightViolet)),
138 - Text(walletStore.name,
139 - style: TextStyle(
140 - fontSize: 18,
141 - color: Theme.of(context)
142 - .accentTextTheme
143 - .overline
144 - .color,
145 - height: 1.25)),
146 - ]);
147 - }),
148 - Observer(builder: (context) {
149 - final savedDisplayMode = settingsStore.balanceDisplayMode;
150 - final availableBalance =
151 - savedDisplayMode == BalanceDisplayMode.hiddenBalance
152 - ? '---'
153 - : balanceStore.unlockedBalance;
154 -
155 - return Column(
156 - mainAxisAlignment: MainAxisAlignment.center,
157 - children: <Widget>[
158 - Text(S.of(context).xmr_available_balance,
159 - style: TextStyle(
160 - fontSize: 12,
161 - color: Theme.of(context)
162 - .accentTextTheme
163 - .overline
164 - .backgroundColor,
165 - )),
166 - Text(availableBalance,
167 - style: TextStyle(
168 - fontSize: 22,
169 - color: Theme.of(context)
170 - .accentTextTheme
171 - .overline
172 - .color,
173 - height: 1.1)),
174 - ]);
175 - })
176 - ],
177 - ),
178 - ),
179 - ),
180 - Form(
181 - key: _formKey,
182 - child: Container(
183 - padding:
184 - EdgeInsets.only(left: 38, right: 33, top: 10, bottom: 30),
108 + children: <Widget>[
109 + TopPanel(
110 + color: PaletteDark.menuList,
111 + widget: Form(
112 + key: _formKey,
113 child: Column(children: <Widget>[
114 AddressTextField(
115 controller: _addressController,
@@ -190,19 +118,16 @@ class SendFormState extends State<SendForm> {
118 onURIScanned: (uri) {
119 var address = '';
120 var amount = '';
193 - var paymentId = '';
121
122 if (uri != null) {
123 address = uri.path;
124 amount = uri.queryParameters['tx_amount'];
198 - paymentId = uri.queryParameters['tx_payment_id'];
125 } else {
126 address = uri.toString();
127 }
128
129 _addressController.text = address;
130 _cryptoAmountController.text = amount;
205 - _paymentIdController.text = paymentId;
131 },
132 options: [
133 AddressTextFieldOption.qrCode,
@@ -214,102 +139,103 @@ class SendFormState extends State<SendForm> {
139 return sendStore.errorMessage;
140 },
141 ),
217 - Padding(
218 - padding: const EdgeInsets.only(top: 20),
219 - child: TextFormField(
220 - style: TextStyle(
221 - fontSize: 14.0,
222 - color: Theme.of(context)
223 - .accentTextTheme
224 - .overline
225 - .backgroundColor),
226 - controller: _paymentIdController,
227 - decoration: InputDecoration(
228 - hintStyle: TextStyle(
229 - fontSize: 14.0,
230 - color: Theme.of(context).hintColor),
231 - hintText: S.of(context).send_payment_id,
232 - focusedBorder: UnderlineInputBorder(
233 - borderSide: BorderSide(
234 - color: Palette.cakeGreen, width: 2.0)),
235 - enabledBorder: UnderlineInputBorder(
236 - borderSide: BorderSide(
237 - color: Theme.of(context).focusColor,
238 - width: 1.0))),
239 - validator: (value) {
240 - sendStore.validatePaymentID(value);
241 - return sendStore.errorMessage;
242 - }),
243 - ),
244 - Padding(
245 - padding: const EdgeInsets.only(top: 20),
246 - child: TextFormField(
247 - style: TextStyle(
248 - fontSize: 18.0,
249 - color: Theme.of(context)
250 - .accentTextTheme
251 - .overline
252 - .color),
253 - controller: _cryptoAmountController,
254 - keyboardType: TextInputType.numberWithOptions(
255 - signed: false, decimal: true),
256 - inputFormatters: [
257 - BlacklistingTextInputFormatter(
258 - RegExp('[\\-|\\ |\\,]'))
259 - ],
260 - decoration: InputDecoration(
261 - prefixIcon: Padding(
262 - padding: EdgeInsets.only(top: 12),
263 - child: Text('XMR:',
264 - style: TextStyle(
265 - fontSize: 18,
266 - color: Theme.of(context)
267 - .accentTextTheme
268 - .overline
269 - .color,
270 - )),
271 - ),
272 - suffixIcon: Container(
273 - width: 1,
274 - padding: EdgeInsets.only(top: 0),
275 - child: Center(
276 - child: InkWell(
277 - onTap: () => sendStore.setSendAll(),
278 - child: Text(S.of(context).all,
279 - style: TextStyle(
280 - fontSize: 10,
281 - color: Theme.of(context)
282 - .accentTextTheme
283 - .overline
284 - .decorationColor))),
285 - ),
142 + Observer(
143 + builder: (_) {
144 + return Padding(
145 + padding: const EdgeInsets.only(top: 20),
146 + child: TextFormField(
147 + style: TextStyle(
148 + fontSize: 16.0,
149 + color: Colors.white
150 ),
287 - hintStyle: TextStyle(
288 - fontSize: 18.0,
289 - color: Theme.of(context).hintColor),
290 - hintText: '0.0000',
291 - focusedBorder: UnderlineInputBorder(
292 - borderSide: BorderSide(
293 - color: Palette.cakeGreen, width: 2.0)),
294 - enabledBorder: UnderlineInputBorder(
295 - borderSide: BorderSide(
296 - color: Theme.of(context).focusColor,
297 - width: 1.0))),
298 - validator: (value) {
299 - sendStore.validateXMR(
300 - value, balanceStore.unlockedBalance);
301 - return sendStore.errorMessage;
302 - }),
151 + controller: _cryptoAmountController,
152 + keyboardType: TextInputType.numberWithOptions(
153 + signed: false, decimal: true),
154 + inputFormatters: [
155 + BlacklistingTextInputFormatter(
156 + RegExp('[\\-|\\ |\\,]'))
157 + ],
158 + decoration: InputDecoration(
159 + prefixIcon: Padding(
160 + padding: EdgeInsets.only(top: 12),
161 + child: Text('XMR:',
162 + style: TextStyle(
163 + fontSize: 16,
164 + fontWeight: FontWeight.bold,
165 + color: Colors.white,
166 + )),
167 + ),
168 + suffixIcon: Padding(
169 + padding: EdgeInsets.only(
170 + bottom: 5
171 + ),
172 + child: Row(
173 + mainAxisSize: MainAxisSize.min,
174 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
175 + children: <Widget>[
176 + Container(
177 + width: MediaQuery.of(context).size.width/2,
178 + alignment: Alignment.centerLeft,
179 + child: Text(
180 + ' / ' + balanceStore.unlockedBalance,
181 + maxLines: 1,
182 + overflow: TextOverflow.ellipsis,
183 + style: TextStyle(
184 + fontSize: 16,
185 + color: PaletteDark.walletCardText
186 + )
187 + ),
188 + ),
189 + Container(
190 + height: 32,
191 + width: 32,
192 + margin: EdgeInsets.only(left: 12, bottom: 7, top: 4),
193 + decoration: BoxDecoration(
194 + color: PaletteDark.walletCardSubAddressField,
195 + borderRadius: BorderRadius.all(Radius.circular(6))
196 + ),
197 + child: InkWell(
198 + onTap: () => sendStore.setSendAll(),
199 + child: Center(
200 + child: Text(S.of(context).all,
201 + style: TextStyle(
202 + fontSize: 9,
203 + fontWeight: FontWeight.bold,
204 + color: PaletteDark.walletCardText
205 + )
206 + ),
207 + ),
208 + ),
209 + )
210 + ],
211 + ),
212 + ),
213 + hintStyle: TextStyle(
214 + fontSize: 16.0,
215 + color: Colors.white),
216 + hintText: '0.0000',
217 + focusedBorder: UnderlineInputBorder(
218 + borderSide: BorderSide(
219 + color: PaletteDark.walletCardSubAddressField,
220 + width: 1.0)),
221 + enabledBorder: UnderlineInputBorder(
222 + borderSide: BorderSide(
223 + color: PaletteDark.walletCardSubAddressField,
224 + width: 1.0))),
225 + validator: (value) {
226 + sendStore.validateXMR(
227 + value, balanceStore.unlockedBalance);
228 + return sendStore.errorMessage;
229 + }),
230 + );
231 + }
232 ),
233 Padding(
234 padding: const EdgeInsets.only(top: 20),
235 child: TextFormField(
236 style: TextStyle(
308 - fontSize: 18.0,
309 - color: Theme.of(context)
310 - .accentTextTheme
311 - .overline
312 - .color),
237 + fontSize: 16.0,
238 + color: Colors.white),
239 controller: _fiatAmountController,
240 keyboardType: TextInputType.numberWithOptions(
241 signed: false, decimal: true),
@@ -323,123 +249,147 @@ class SendFormState extends State<SendForm> {
249 child: Text(
250 '${settingsStore.fiatCurrency.toString()}:',
251 style: TextStyle(
326 - fontSize: 18,
327 - color: Theme.of(context)
328 - .accentTextTheme
329 - .overline
330 - .color,
252 + fontSize: 16,
253 + fontWeight: FontWeight.bold,
254 + color: Colors.white,
255 )),
256 ),
257 hintStyle: TextStyle(
334 - fontSize: 18.0,
335 - color: Theme.of(context).hintColor),
258 + fontSize: 16.0,
259 + color: PaletteDark.walletCardText),
260 hintText: '0.00',
261 focusedBorder: UnderlineInputBorder(
262 borderSide: BorderSide(
339 - color: Palette.cakeGreen, width: 2.0)),
263 + color: PaletteDark.walletCardSubAddressField,
264 + width: 1.0)),
265 enabledBorder: UnderlineInputBorder(
266 borderSide: BorderSide(
342 - color: Theme.of(context).focusColor,
267 + color: PaletteDark.walletCardSubAddressField,
268 width: 1.0)))),
269 ),
345 - Padding(
346 - padding: const EdgeInsets.only(top: 12.0, bottom: 10),
347 - child: Row(
348 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
349 - children: <Widget>[
350 - Text(S.of(context).send_estimated_fee,
351 - style: TextStyle(
352 - fontSize: 14,
353 - fontWeight: FontWeight.w500,
354 - color: Theme.of(context)
355 - .accentTextTheme
356 - .overline
357 - .backgroundColor,
358 - )),
359 - Text(
360 - '${calculateEstimatedFee(priority: settingsStore.transactionPriority)} XMR',
361 - style: TextStyle(
362 - fontSize: 14,
363 - fontWeight: FontWeight.w500,
364 - color: Theme.of(context)
365 - .primaryTextTheme
366 - .overline
367 - .backgroundColor,
368 - ))
369 - ],
370 - ),
371 - ),
372 - SizedBox(
373 - width: double.infinity,
374 - child: Text(
375 - S.of(context).send_priority(
376 - settingsStore.transactionPriority.toString()),
377 - style: TextStyle(
378 - fontSize: 12,
379 - fontWeight: FontWeight.w500,
380 - color: Theme.of(context)
381 - .primaryTextTheme
382 - .subtitle
383 - .color,
384 - height: 1.3)),
385 - ),
270 ]),
271 ),
272 + ),
273 + Padding(
274 + padding: EdgeInsets.only(
275 + top: 32,
276 + left: 24,
277 + bottom: 24
278 + ),
279 + child: Row(
280 + mainAxisAlignment: MainAxisAlignment.start,
281 + children: <Widget>[
282 + Text(
283 + 'Templates',
284 + style: TextStyle(
285 + fontSize: 18,
286 + fontWeight: FontWeight.w600,
287 + color: PaletteDark.walletCardText
288 + ),
289 + )
290 + ],
291 + ),
292 + ),
293 + Container(
294 + height: 40,
295 + width: double.infinity,
296 + padding: EdgeInsets.only(left: 24),
297 + child: ListView.builder(
298 + scrollDirection: Axis.horizontal,
299 + itemCount: 1,
300 + itemBuilder: (context, index) {
301 +
302 + if (index == 0) {
303 + return GestureDetector(
304 + onTap: () {},
305 + child: Container(
306 + padding: EdgeInsets.only(right: 10),
307 + child: DottedBorder(
308 + borderType: BorderType.RRect,
309 + dashPattern: [8, 4],
310 + color: PaletteDark.menuList,
311 + strokeWidth: 2,
312 + radius: Radius.circular(20),
313 + child: Container(
314 + height: 40,
315 + width: 75,
316 + padding: EdgeInsets.only(left: 10, right: 10),
317 + alignment: Alignment.center,
318 + decoration: BoxDecoration(
319 + borderRadius: BorderRadius.all(Radius.circular(20)),
320 + color: Colors.transparent,
321 + ),
322 + child: Text(
323 + 'New',
324 + style: TextStyle(
325 + fontSize: 14,
326 + fontWeight: FontWeight.w600,
327 + color: PaletteDark.walletCardText
328 + ),
329 + ),
330 + )
331 + ),
332 + ),
333 + );
334 + }
335 +
336 + return Container();
337 + }
338 + ),
339 )
340 ],
341 ),
342 + bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
343 bottomSection: Observer(builder: (_) {
344 return LoadingPrimaryButton(
345 onPressed: syncStore.status is SyncedSyncStatus
346 ? () async {
395 - // Hack. Don't ask me.
396 - FocusScope.of(context).requestFocus(FocusNode());
397 -
398 - if (_formKey.currentState.validate()) {
399 - await showDialog<void>(
400 - context: context,
401 - builder: (dialogContext) {
402 - return AlertDialog(
403 - title: Text(
404 - S.of(context).send_creating_transaction),
405 - content: Text(S.of(context).confirm_sending),
406 - actions: <Widget>[
407 - FlatButton(
408 - child: Text(S.of(context).send),
409 - onPressed: () async {
410 - await Navigator.of(dialogContext)
411 - .popAndPushNamed(Routes.auth,
412 - arguments: (bool
413 - isAuthenticatedSuccessfully,
414 - AuthPageState auth) {
415 - if (!isAuthenticatedSuccessfully) {
416 - return;
417 - }
418 -
419 - Navigator.of(auth.context).pop();
420 -
421 - sendStore.createTransaction(
422 - address: _addressController.text,
423 - paymentId:
424 - _paymentIdController.text);
425 - });
426 - }),
427 - FlatButton(
428 - child: Text(S.of(context).cancel),
429 - onPressed: () =>
430 - Navigator.of(context).pop())
431 - ],
432 - );
433 - });
434 - }
435 - }
436 - : null,
347 + // Hack. Don't ask me.
348 + FocusScope.of(context).requestFocus(FocusNode());
349 +
350 + if (_formKey.currentState.validate()) {
351 + await showDialog<void>(
352 + context: context,
353 + builder: (dialogContext) {
354 + return AlertWithTwoActions(
355 + alertTitle: S.of(context).send_creating_transaction,
356 + alertContent: S.of(context).confirm_sending,
357 + leftButtonText: S.of(context).send,
358 + rightButtonText: S.of(context).cancel,
359 + actionLeftButton: () async {
360 + await Navigator.of(dialogContext)
361 + .popAndPushNamed(Routes.auth,
362 + arguments: (bool
363 + isAuthenticatedSuccessfully,
364 + AuthPageState auth) {
365 + if (!isAuthenticatedSuccessfully) {
366 + return;
367 + }
368 +
369 + Navigator.of(auth.context).pop();
370 +
371 + sendStore.createTransaction(
372 + address: _addressController.text,
373 + paymentId: '');
374 + });
375 + },
376 + actionRightButton: () =>
377 + Navigator.of(context).pop()
378 + );
379 + });
380 + }
381 + }
382 + : null,
383 text: S.of(context).send,
438 - color: Theme.of(context).accentTextTheme.button.backgroundColor,
439 - textColor: Theme.of(context).primaryTextTheme.button.color,
384 + color: Colors.blue,
385 + textColor: Colors.white,
386 isLoading: sendStore.state is CreatingTransaction ||
441 - sendStore.state is TransactionCommiting);
442 - }));
387 + sendStore.state is TransactionCommiting,
388 + isDisabled: !(syncStore.status is SyncedSyncStatus),
389 + );
390 + }),
391 + ),
392 + );
393 }
394
395 void _setEffects(BuildContext context) {
@@ -483,14 +433,11 @@ class SendFormState extends State<SendForm> {
433 showDialog<void>(
434 context: context,
435 builder: (BuildContext context) {
486 - return AlertDialog(
487 - title: Text(S.of(context).error),
488 - content: Text(state.error),
489 - actions: <Widget>[
490 - FlatButton(
491 - child: Text(S.of(context).ok),
492 - onPressed: () => Navigator.of(context).pop())
493 - ],
436 + return AlertWithOneAction(
437 + alertTitle: S.of(context).error,
438 + alertContent: state.error,
439 + buttonText: S.of(context).ok,
440 + buttonAction: () => Navigator.of(context).pop()
441 );
442 });
443 });
@@ -501,23 +448,25 @@ class SendFormState extends State<SendForm> {
448 showDialog<void>(
449 context: context,
450 builder: (BuildContext context) {
504 - return AlertDialog(
505 - title: Text(S.of(context).confirm_sending),
506 - content: Text(S.of(context).commit_transaction_amount_fee(
507 - sendStore.pendingTransaction.amount,
508 - sendStore.pendingTransaction.fee)),
509 - actions: <Widget>[
510 - FlatButton(
511 - child: Text(S.of(context).ok),
512 - onPressed: () {
513 - Navigator.of(context).pop();
514 - sendStore.commitTransaction();
515 - }),
516 - FlatButton(
517 - child: Text(S.of(context).cancel),
518 - onPressed: () => Navigator.of(context).pop(),
519 - )
520 - ],
451 + return ConfirmSendingAlert(
452 + alertTitle: S.of(context).confirm_sending,
453 + amount: 'Amount:',
454 + amountValue: sendStore.pendingTransaction.amount,
455 + fee: 'Fee:',
456 + feeValue: sendStore.pendingTransaction.fee,
457 + leftButtonText: S.of(context).ok,
458 + rightButtonText: S.of(context).cancel,
459 + actionLeftButton: () {
460 + Navigator.of(context).pop();
461 + sendStore.commitTransaction();
462 + showDialog<void>(
463 + context: context,
464 + builder: (BuildContext context) {
465 + return SendingAlert(sendStore: sendStore);
466 + }
467 + );
468 + },
469 + actionRightButton: () => Navigator.of(context).pop()
470 );
471 });
472 });
@@ -525,23 +474,8 @@ class SendFormState extends State<SendForm> {
474
475 if (state is TransactionCommitted) {
476 WidgetsBinding.instance.addPostFrameCallback((_) {
528 - showDialog<void>(
529 - context: context,
530 - builder: (BuildContext context) {
531 - return AlertDialog(
532 - title: Text(S.of(context).sending),
533 - content: Text(S.of(context).transaction_sent),
534 - actions: <Widget>[
535 - FlatButton(
536 - child: Text(S.of(context).ok),
537 - onPressed: () {
538 - _addressController.text = '';
539 - _cryptoAmountController.text = '';
540 - Navigator.of(context)..pop()..pop();
541 - })
542 - ],
543 - );
544 - });
477 + _addressController.text = '';
478 + _cryptoAmountController.text = '';
479 });
480 }
481 });
lib/src/screens/send/widgets/confirm_sending_alert.dart new
+100
@@ -0,0 +1,100 @@
1 +import 'package:flutter/material.dart';
2 +import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
3 +
4 +class ConfirmSendingAlert extends BaseAlertDialog {
5 + ConfirmSendingAlert({
6 + @required this.alertTitle,
7 + @required this.amount,
8 + @required this.amountValue,
9 + @required this.fee,
10 + @required this.feeValue,
11 + @required this.leftButtonText,
12 + @required this.rightButtonText,
13 + @required this.actionLeftButton,
14 + @required this.actionRightButton,
15 + this.alertBarrierDismissible = true
16 + });
17 +
18 + final String alertTitle;
19 + final String amount;
20 + final String amountValue;
21 + final String fee;
22 + final String feeValue;
23 + final String leftButtonText;
24 + final String rightButtonText;
25 + final VoidCallback actionLeftButton;
26 + final VoidCallback actionRightButton;
27 + final bool alertBarrierDismissible;
28 +
29 + @override
30 + String get titleText => alertTitle;
31 +
32 + @override
33 + String get leftActionButtonText => leftButtonText;
34 + @override
35 + String get rightActionButtonText => rightButtonText;
36 + @override
37 + VoidCallback get actionLeft => actionLeftButton;
38 + @override
39 + VoidCallback get actionRight => actionRightButton;
40 + @override
41 + bool get barrierDismissible => alertBarrierDismissible;
42 +
43 + @override
44 + Widget content(BuildContext context) {
45 + return Column(
46 + mainAxisSize: MainAxisSize.max,
47 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
48 + children: <Widget>[
49 + Row(
50 + mainAxisSize: MainAxisSize.max,
51 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
52 + children: <Widget>[
53 + Text(
54 + amount,
55 + style: TextStyle(
56 + fontSize: 16,
57 + fontWeight: FontWeight.w600,
58 + color: Colors.white,
59 + decoration: TextDecoration.none,
60 + ),
61 + ),
62 + Text(
63 + amountValue,
64 + style: TextStyle(
65 + fontSize: 16,
66 + fontWeight: FontWeight.w600,
67 + color: Colors.white,
68 + decoration: TextDecoration.none,
69 + ),
70 + )
71 + ],
72 + ),
73 + Row(
74 + mainAxisSize: MainAxisSize.max,
75 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
76 + children: <Widget>[
77 + Text(
78 + fee,
79 + style: TextStyle(
80 + fontSize: 16,
81 + fontWeight: FontWeight.w600,
82 + color: Colors.white,
83 + decoration: TextDecoration.none,
84 + ),
85 + ),
86 + Text(
87 + feeValue,
88 + style: TextStyle(
89 + fontSize: 16,
90 + fontWeight: FontWeight.w600,
91 + color: Colors.white,
92 + decoration: TextDecoration.none,
93 + ),
94 + )
95 + ],
96 + )
97 + ],
98 + );
99 + }
100 +}
\ No newline at end of file
lib/src/screens/send/widgets/sending_alert.dart new
+105
@@ -0,0 +1,105 @@
1 +import 'dart:ui';
2 +import 'package:cake_wallet/palette.dart';
3 +import 'package:cake_wallet/src/stores/send/sending_state.dart';
4 +import 'package:flutter/material.dart';
5 +import 'package:cake_wallet/src/widgets/primary_button.dart';
6 +import 'package:cake_wallet/src/stores/send/send_store.dart';
7 +import 'package:cake_wallet/generated/i18n.dart';
8 +import 'package:flutter_mobx/flutter_mobx.dart';
9 +
10 +class SendingAlert extends StatefulWidget {
11 + SendingAlert({@required this.sendStore});
12 +
13 + final SendStore sendStore;
14 +
15 + @override
16 + SendingAlertState createState() => SendingAlertState(sendStore);
17 +}
18 +
19 +class SendingAlertState extends State<SendingAlert> {
20 + SendingAlertState(this.sendStore);
21 +
22 + final SendStore sendStore;
23 +
24 + @override
25 + Widget build(BuildContext context) {
26 + return Observer(
27 + builder: (_) {
28 + final state = sendStore.state;
29 +
30 + if (state is TransactionCommitted) {
31 + return Stack(
32 + children: <Widget>[
33 + Container(
34 + color: PaletteDark.historyPanel,
35 + child: Center(
36 + child: Image.asset(
37 + 'assets/images/birthday_cake.png'),
38 + ),
39 + ),
40 + Center(
41 + child: Padding(
42 + padding: EdgeInsets.only(top: 220, left: 24, right: 24),
43 + child: Text(
44 + 'Your Monero was successfully sent',
45 + textAlign: TextAlign.center,
46 + style: TextStyle(
47 + fontSize: 22,
48 + fontWeight: FontWeight.bold,
49 + color: Colors.white,
50 + decoration: TextDecoration.none,
51 + ),
52 + ),
53 + ),
54 + ),
55 + Positioned(
56 + left: 24,
57 + right: 24,
58 + bottom: 24,
59 + child: PrimaryButton(
60 + onPressed: () => Navigator.of(context).pop(),
61 + text: 'Got it',
62 + color: Colors.blue,
63 + textColor: Colors.white
64 + )
65 + )
66 + ],
67 + );
68 + }
69 +
70 + return Stack(
71 + children: <Widget>[
72 + Container(
73 + color: PaletteDark.historyPanel,
74 + child: Center(
75 + child: Image.asset(
76 + 'assets/images/birthday_cake.png'),
77 + ),
78 + ),
79 + BackdropFilter(
80 + filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
81 + child: Container(
82 + decoration: BoxDecoration(color: PaletteDark.historyPanel.withOpacity(0.25)),
83 + child: Center(
84 + child: Padding(
85 + padding: EdgeInsets.only(top: 220),
86 + child: Text(
87 + 'Sending...',
88 + textAlign: TextAlign.center,
89 + style: TextStyle(
90 + fontSize: 22,
91 + fontWeight: FontWeight.bold,
92 + color: Colors.white,
93 + decoration: TextDecoration.none,
94 + ),
95 + ),
96 + ),
97 + ),
98 + ),
99 + )
100 + ],
101 + );
102 + }
103 + );
104 + }
105 +}
\ No newline at end of file
lib/src/widgets/address_text_field.dart
+19 -10
@@ -40,6 +40,10 @@ class AddressTextField extends StatelessWidget {
40 enabled: isActive,
41 controller: controller,
42 focusNode: focusNode,
43 + style: TextStyle(
44 + fontSize: 16,
45 + color: Colors.white
46 + ),
47 decoration: InputDecoration(
48 suffixIcon: SizedBox(
49 width: prefixIconWidth * options.length +
@@ -58,9 +62,9 @@ class AddressTextField extends StatelessWidget {
62 child: Container(
63 padding: EdgeInsets.all(8),
64 decoration: BoxDecoration(
61 - color: Palette.wildDarkBlueWithOpacity,
65 + color: PaletteDark.walletCardSubAddressField,
66 borderRadius:
63 - BorderRadius.all(Radius.circular(8))),
67 + BorderRadius.all(Radius.circular(6))),
68 child: Image.asset('assets/images/qr_code_icon.png')),
69 ))
70 ],
@@ -76,11 +80,11 @@ class AddressTextField extends StatelessWidget {
80 child: Container(
81 padding: EdgeInsets.all(8),
82 decoration: BoxDecoration(
79 - color: Palette.wildDarkBlueWithOpacity,
83 + color: PaletteDark.walletCardSubAddressField,
84 borderRadius:
81 - BorderRadius.all(Radius.circular(8))),
85 + BorderRadius.all(Radius.circular(6))),
86 child: Image.asset(
83 - 'assets/images/address_book_icon.png')),
87 + 'assets/images/open_book.png')),
88 ))
89 ],
90 if (this
@@ -95,9 +99,9 @@ class AddressTextField extends StatelessWidget {
99 child: Container(
100 padding: EdgeInsets.all(8),
101 decoration: BoxDecoration(
98 - color: Palette.wildDarkBlueWithOpacity,
102 + color: PaletteDark.walletCardSubAddressField,
103 borderRadius:
100 - BorderRadius.all(Radius.circular(8))),
104 + BorderRadius.all(Radius.circular(6))),
105 child: Image.asset(
106 'assets/images/receive_icon_raw.png')),
107 ))
@@ -105,13 +109,18 @@ class AddressTextField extends StatelessWidget {
109 ],
110 ),
111 ),
108 - hintStyle: TextStyle(color: Theme.of(context).hintColor),
112 + hintStyle: TextStyle(
113 + fontSize: 16,
114 + color: PaletteDark.walletCardText
115 + ),
116 hintText: placeholder ?? S.current.widgets_address,
117 focusedBorder: UnderlineInputBorder(
111 - borderSide: BorderSide(color: Palette.cakeGreen, width: 2.0)),
118 + borderSide: BorderSide(
119 + color: PaletteDark.walletCardSubAddressField,
120 + width: 1.0)),
121 enabledBorder: UnderlineInputBorder(
122 borderSide:
114 - BorderSide(color: Theme.of(context).focusColor, width: 1.0)),
123 + BorderSide(color: PaletteDark.walletCardSubAddressField, width: 1.0)),
124 ),
125 validator: validator,
126 );
lib/src/widgets/base_alert_dialog.dart
+1 -1
@@ -138,7 +138,7 @@ class BaseAlertDialog extends StatelessWidget {
138 Container(
139 width: 300,
140 height: 77,
141 - padding: EdgeInsets.all(24),
141 + padding: EdgeInsets.only(left: 24, right: 24),
142 decoration: BoxDecoration(
143 borderRadius: BorderRadius.only(
144 topLeft: Radius.circular(24),
lib/src/widgets/seed_widget.dart
-1
@@ -238,7 +238,6 @@ class SeedWidgetState extends State<SeedWidget> {
238 fit: FlexFit.tight,
239 flex: 1,
240 child: TopPanel(
241 - height: null,
241 color: PaletteDark.menuList,
242 widget: SingleChildScrollView(
243 child: Column(
lib/src/widgets/top_panel.dart
+1 -3
@@ -1,9 +1,8 @@
1 import 'package:flutter/material.dart';
2
3 class TopPanel extends StatelessWidget {
4 - TopPanel({@required this.height, @required this.color, @required this.widget});
4 + TopPanel({@required this.color, @required this.widget});
5
6 - final double height;
6 final Color color;
7 final Widget widget;
8
@@ -11,7 +10,6 @@ class TopPanel extends StatelessWidget {
10 Widget build(BuildContext context) {
11 return Container(
12 width: double.infinity,
14 - height: height ?? double.infinity,
13 padding: EdgeInsets.all(24),
14 decoration: BoxDecoration(
15 borderRadius: BorderRadius.only(
pubspec.lock
+21
@@ -232,6 +232,13 @@ packages:
232 url: "https://pub.dartlang.org"
233 source: hosted
234 version: "3.0.7"
235 + dotted_border:
236 + dependency: "direct main"
237 + description:
238 + name: dotted_border
239 + url: "https://pub.dartlang.org"
240 + source: hosted
241 + version: "1.0.5"
242 encrypt:
243 dependency: "direct main"
244 description:
@@ -525,6 +532,20 @@ packages:
532 url: "https://pub.dartlang.org"
533 source: hosted
534 version: "1.6.4"
535 + path_drawing:
536 + dependency: transitive
537 + description:
538 + name: path_drawing
539 + url: "https://pub.dartlang.org"
540 + source: hosted
541 + version: "0.4.1"
542 + path_parsing:
543 + dependency: transitive
544 + description:
545 + name: path_parsing
546 + url: "https://pub.dartlang.org"
547 + source: hosted
548 + version: "0.1.4"
549 path_provider:
550 dependency: "direct main"
551 description:
pubspec.yaml
+1
@@ -49,6 +49,7 @@ dependencies:
49 package_info: ^0.4.0+13
50 devicelocale: ^0.2.1
51 auto_size_text: ^2.1.0
52 + dotted_border: ^1.0.5
53
54 # The following adds the Cupertino Icons font to your application.
55 # Use with the CupertinoIcons class for iOS style icons.