CAKE-134. CAKE-139. FIXES.

M committed Oct 30, 2020 at 18:32 UTC 9f498f30a283d0a7096fb23827f1eda0dea6f48c
8 files changed +356 -233
lib/di.dart
+3 -1
@@ -1,3 +1,4 @@
1 +
2 import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart';
3 import 'package:cake_wallet/core/wallet_service.dart';
4 import 'package:cake_wallet/entities/biometric_auth.dart';
@@ -332,7 +333,8 @@ Future setup(
333 getIt.registerFactory(() => ExchangeTradeViewModel(
334 wallet: getIt.get<AppStore>().wallet,
335 trades: tradesSource,
335 - tradesStore: getIt.get<TradesStore>()));
336 + tradesStore: getIt.get<TradesStore>(),
337 + sendViewModel: getIt.get<SendViewModel>()));
338
339 getIt.registerFactory(() => ExchangePage(getIt.get<ExchangeViewModel>()));
340
lib/src/screens/exchange/widgets/currency_picker.dart
+1
@@ -95,6 +95,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
95 alignment: Alignment.center,
96 children: <Widget>[
97 GridView.count(
98 + padding: EdgeInsets.all(0),
99 controller: controller,
100 crossAxisCount: crossAxisCount,
101 childAspectRatio: 1.25,
lib/src/screens/exchange_trade/exchange_trade_page.dart
+137 -67
@@ -1,31 +1,26 @@
1 -import 'package:cake_wallet/palette.dart';
1 +import 'dart:ui';
2 +import 'package:mobx/mobx.dart';
3 +import 'package:flutter_mobx/flutter_mobx.dart';
4 +import 'package:flutter/material.dart';
5 +import 'package:flutter/cupertino.dart';
6 +import 'package:flutter/services.dart';
7 +import 'package:cake_wallet/generated/i18n.dart';
8 +import 'package:cake_wallet/core/execution_state.dart';
9 import 'package:cake_wallet/entities/crypto_currency.dart';
10 import 'package:cake_wallet/exchange/exchange_provider_description.dart';
4 -import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart';
11 import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
12 +import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
13 import 'package:cake_wallet/src/widgets/standart_list_row.dart';
14 import 'package:cake_wallet/utils/show_bar.dart';
15 import 'package:cake_wallet/utils/show_pop_up.dart';
16 import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
10 -import 'package:mobx/mobx.dart';
11 -import 'package:provider/provider.dart';
12 -import 'package:flutter_mobx/flutter_mobx.dart';
13 -import 'package:flutter/material.dart';
14 -import 'package:flutter/cupertino.dart';
15 -import 'package:flutter/services.dart';
16 -import 'package:cake_wallet/generated/i18n.dart';
17 -
18 -// import 'package:cake_wallet/src/stores/exchange_trade/exchange_trade_store.dart';
19 -// import 'package:cake_wallet/src/stores/send/send_store.dart';
20 -// import 'package:cake_wallet/src/stores/send/sending_state.dart';
21 -// import 'package:cake_wallet/src/stores/wallet/wallet_store.dart';
17 +import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
18 import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart';
19 import 'package:cake_wallet/src/screens/base_page.dart';
20 import 'package:cake_wallet/src/screens/exchange_trade/widgets/timer_widget.dart';
21 import 'package:cake_wallet/src/widgets/primary_button.dart';
22 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
23 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
28 -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
24
25 void showInformation(
26 ExchangeTradeViewModel exchangeTradeViewModel, BuildContext context) {
@@ -110,7 +105,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
105 width: 16,
106 color: Theme.of(context).primaryTextTheme.overline.color);
107
113 - //_setEffects(context);
108 + _setEffects(context);
109
110 return Container(
111 child: ScrollableWithBottomSection(
@@ -227,44 +222,25 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
222 );
223 }),
224 bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
230 - bottomSection:
231 - /*Observer(
232 - builder: (_) => tradeStore.trade.from == CryptoCurrency.xmr &&
233 - !(sendStore.state is TransactionCommitted)
225 + bottomSection: Observer(builder: (_) {
226 + final trade = widget.exchangeTradeViewModel.trade;
227 + final sendingState =
228 + widget.exchangeTradeViewModel.sendViewModel.state;
229 +
230 + return trade.from == CryptoCurrency.xmr && !(sendingState is TransactionCommitted)
231 ? LoadingPrimaryButton(
235 - isDisabled: tradeStore.trade.inputAddress == null ||
236 - tradeStore.trade.inputAddress.isEmpty,
237 - isLoading: sendStore.state is CreatingTransaction ||
238 - sendStore.state is TransactionCommitted,
239 - onPressed: () => sendStore.createTransaction(
240 - address: tradeStore.trade.inputAddress,
241 - amount: tradeStore.trade.amount),
242 - text: tradeStore.trade.provider ==
243 - ExchangeProviderDescription.xmrto
244 - ? S.of(context).confirm
245 - : S.of(context).send_xmr,
246 - color: Colors.blue,
247 - textColor: Colors.white)
248 - : Offstage()),*/
249 - Observer(
250 - builder: (_) {
251 - final trade = widget.exchangeTradeViewModel.trade;
252 -
253 - return trade.from == CryptoCurrency.xmr
254 - ? LoadingPrimaryButton(
232 isDisabled: trade.inputAddress == null ||
233 trade.inputAddress.isEmpty,
257 - isLoading: false, // FIXME
258 - onPressed: () {}, // FIXME
259 - text: trade.provider ==
260 - ExchangeProviderDescription.xmrto
234 + isLoading: sendingState is IsExecutingState,
235 + onPressed: () =>
236 + widget.exchangeTradeViewModel.confirmSending(),
237 + text: trade.provider == ExchangeProviderDescription.xmrto
238 ? S.of(context).confirm
239 : S.of(context).send_xmr,
240 color: Theme.of(context).accentTextTheme.body2.color,
241 textColor: Colors.white)
265 - : Offstage();
266 - })
267 - ),
242 + : Offstage();
243 + })),
244 );
245 }
246
@@ -273,10 +249,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
249 return;
250 }
251
276 - /*final sendStore = Provider.of<SendStore>(context);
277 -
278 - reaction((_) => sendStore.state, (SendingState state) {
279 - if (state is SendingFailed) {
252 + reaction((_) => this.widget.exchangeTradeViewModel.sendViewModel.state,
253 + (ExecutionState state) {
254 + if (state is FailureState) {
255 WidgetsBinding.instance.addPostFrameCallback((_) {
256 showPopUp<void>(
257 context: context,
@@ -285,30 +260,126 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
260 alertTitle: S.of(context).error,
261 alertContent: state.error,
262 buttonText: S.of(context).ok,
288 - buttonAction: () => Navigator.of(context).pop()
289 - );
263 + buttonAction: () => Navigator.of(context).pop());
264 });
265 });
266 }
267
294 - if (state is TransactionCreatedSuccessfully) {
268 + if (state is ExecutedSuccessfullyState) {
269 WidgetsBinding.instance.addPostFrameCallback((_) {
270 showPopUp<void>(
271 context: context,
272 builder: (BuildContext context) {
299 - return AlertWithTwoActions(
273 + return ConfirmSendingAlert(
274 alertTitle: S.of(context).confirm_sending,
301 - alertContent: S.of(context).commit_transaction_amount_fee(
302 - sendStore.pendingTransaction.amount,
303 - sendStore.pendingTransaction.fee),
304 - leftButtonText: S.of(context).ok,
305 - rightButtonText: S.of(context).cancel,
306 - actionLeftButton: () {
275 + amount: S.of(context).send_amount,
276 + amountValue: widget.exchangeTradeViewModel.sendViewModel
277 + .pendingTransaction.amountFormatted,
278 + fee: S.of(context).send_fee,
279 + feeValue: widget.exchangeTradeViewModel.sendViewModel
280 + .pendingTransaction.feeFormatted,
281 + rightButtonText: S.of(context).ok,
282 + leftButtonText: S.of(context).cancel,
283 + actionRightButton: () {
284 Navigator.of(context).pop();
308 - sendStore.commitTransaction();
285 + widget.exchangeTradeViewModel.sendViewModel
286 + .commitTransaction();
287 + showPopUp<void>(
288 + context: context,
289 + builder: (BuildContext context) {
290 + return Observer(builder: (_) {
291 + final state = widget
292 + .exchangeTradeViewModel.sendViewModel.state;
293 +
294 + if (state is TransactionCommitted) {
295 + return Stack(
296 + children: <Widget>[
297 + Container(
298 + color: Theme.of(context).backgroundColor,
299 + child: Center(
300 + child: Image.asset(
301 + 'assets/images/birthday_cake.png'),
302 + ),
303 + ),
304 + Center(
305 + child: Padding(
306 + padding: EdgeInsets.only(
307 + top: 220, left: 24, right: 24),
308 + child: Text(
309 + S.of(context).send_success,
310 + textAlign: TextAlign.center,
311 + style: TextStyle(
312 + fontSize: 22,
313 + fontWeight: FontWeight.bold,
314 + color: Theme.of(context)
315 + .primaryTextTheme
316 + .title
317 + .color,
318 + decoration: TextDecoration.none,
319 + ),
320 + ),
321 + ),
322 + ),
323 + Positioned(
324 + left: 24,
325 + right: 24,
326 + bottom: 24,
327 + child: PrimaryButton(
328 + onPressed: () =>
329 + Navigator.of(context).pop(),
330 + text: S.of(context).send_got_it,
331 + color: Theme.of(context)
332 + .accentTextTheme
333 + .body2
334 + .color,
335 + textColor: Colors.white))
336 + ],
337 + );
338 + }
339 +
340 + return Stack(
341 + children: <Widget>[
342 + Container(
343 + color: Theme.of(context).backgroundColor,
344 + child: Center(
345 + child: Image.asset(
346 + 'assets/images/birthday_cake.png'),
347 + ),
348 + ),
349 + BackdropFilter(
350 + filter: ImageFilter.blur(
351 + sigmaX: 3.0, sigmaY: 3.0),
352 + child: Container(
353 + decoration: BoxDecoration(
354 + color: Theme.of(context)
355 + .backgroundColor
356 + .withOpacity(0.25)),
357 + child: Center(
358 + child: Padding(
359 + padding: EdgeInsets.only(top: 220),
360 + child: Text(
361 + S.of(context).send_sending,
362 + textAlign: TextAlign.center,
363 + style: TextStyle(
364 + fontSize: 22,
365 + fontWeight: FontWeight.bold,
366 + color: Theme.of(context)
367 + .primaryTextTheme
368 + .title
369 + .color,
370 + decoration: TextDecoration.none,
371 + ),
372 + ),
373 + ),
374 + ),
375 + ),
376 + )
377 + ],
378 + );
379 + });
380 + });
381 },
310 - actionRightButton: () => Navigator.of(context).pop()
311 - );
382 + actionLeftButton: () => Navigator.of(context).pop());
383 });
384 });
385 }
@@ -322,12 +393,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
393 alertTitle: S.of(context).sending,
394 alertContent: S.of(context).transaction_sent,
395 buttonText: S.of(context).ok,
325 - buttonAction: () => Navigator.of(context).pop()
326 - );
396 + buttonAction: () => Navigator.of(context).pop());
397 });
398 });
399 }
330 - });*/
400 + });
401
402 _effectsInstalled = true;
403 }
lib/src/screens/send/send_page.dart
+10 -2
@@ -483,8 +483,16 @@ class SendPage extends BasePage {
483 }
484 },
485 text: S.of(context).send,
486 - color: Theme.of(context).accentTextTheme.body2.color,
487 - textColor: Colors.white,
486 + color: Theme
487 + .of(context)
488 + .accentTextTheme
489 + .subtitle
490 + .decorationColor,
491 + textColor: Theme
492 + .of(context)
493 + .accentTextTheme
494 + .headline
495 + .decorationColor,
496 isLoading: sendViewModel.state is IsExecutingState ||
497 sendViewModel.state is TransactionCommitting,
498 isDisabled:
lib/src/screens/send/send_template_page.dart
+183 -155
@@ -1,15 +1,17 @@
1 -import 'package:cake_wallet/src/widgets/address_text_field.dart';
2 -import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
3 -import 'package:cake_wallet/src/widgets/primary_button.dart';
4 -import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
1 +import 'package:mobx/mobx.dart';
2 import 'package:flutter/cupertino.dart';
3 import 'package:flutter/material.dart';
4 +import 'package:flutter/services.dart';
5 +import 'package:flutter_mobx/flutter_mobx.dart';
6 +import 'package:keyboard_actions/keyboard_actions.dart';
7 import 'package:cake_wallet/src/screens/base_page.dart';
8 import 'package:cake_wallet/generated/i18n.dart';
9 import 'package:cake_wallet/view_model/send/send_view_model.dart';
10 -import 'package:flutter/services.dart';
11 -import 'package:flutter_mobx/flutter_mobx.dart';
12 -import 'package:mobx/mobx.dart';
10 +import 'package:cake_wallet/src/widgets/address_text_field.dart';
11 +import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
12 +import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
13 +import 'package:cake_wallet/src/widgets/primary_button.dart';
14 +import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
15
16 class SendTemplatePage extends BasePage {
17 SendTemplatePage({@required this.sendViewModel});
@@ -20,6 +22,8 @@ class SendTemplatePage extends BasePage {
22 final _fiatAmountController = TextEditingController();
23 final _nameController = TextEditingController();
24 final _formKey = GlobalKey<FormState>();
25 + final FocusNode _cryptoAmountFocus = FocusNode();
26 + final FocusNode _fiatAmountFocus = FocusNode();
27
28 bool _effectsInstalled = false;
29
@@ -42,94 +46,153 @@ class SendTemplatePage extends BasePage {
46 Widget body(BuildContext context) {
47 _setEffects(context);
48
45 - return Container(
46 - color: Theme.of(context).backgroundColor,
47 - child: ScrollableWithBottomSection(
48 - contentPadding: EdgeInsets.only(bottom: 24),
49 - content: Container(
50 - decoration: BoxDecoration(
51 - borderRadius: BorderRadius.only(
52 - bottomLeft: Radius.circular(24),
53 - bottomRight: Radius.circular(24)
54 - ),
55 - gradient: LinearGradient(colors: [
56 - Theme.of(context).primaryTextTheme.subhead.color,
57 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
58 - ], begin: Alignment.topLeft, end: Alignment.bottomRight),
59 - ),
60 - child: Form(
61 - key: _formKey,
62 - child: Column(children: <Widget>[
63 - Padding(
64 - padding: EdgeInsets.fromLTRB(24, 90, 24, 32),
65 - child: Column(
66 - children: <Widget>[
67 - BaseTextFormField(
68 - controller: _nameController,
69 - hintText: S.of(context).send_name,
70 - borderColor: Theme.of(context)
71 - .primaryTextTheme
72 - .headline
73 - .color,
74 - textStyle: TextStyle(
75 - fontSize: 14,
76 - fontWeight: FontWeight.w500,
77 - color: Colors.white),
78 - placeholderTextStyle: TextStyle(
79 - color: Theme.of(context)
80 - .primaryTextTheme
81 - .headline
82 - .decorationColor,
83 - fontWeight: FontWeight.w500,
84 - fontSize: 14),
85 - validator: sendViewModel.templateValidator,
86 - ),
87 - Padding(
88 - padding: EdgeInsets.only(top: 20),
89 - child: AddressTextField(
90 - controller: _addressController,
91 - onURIScanned: (uri) {
92 - var address = '';
93 - var amount = '';
49 + return KeyboardActions(
50 + config: KeyboardActionsConfig(
51 + keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
52 + keyboardBarColor: isDarkTheme
53 + ? Color.fromRGBO(48, 51, 60, 1.0)
54 + : Color.fromRGBO(98, 98, 98, 1.0),
55 + nextFocus: false,
56 + actions: [
57 + KeyboardActionsItem(
58 + focusNode: _cryptoAmountFocus,
59 + toolbarButtons: [(_) => KeyboardDoneButton()],
60 + ),
61 + KeyboardActionsItem(
62 + focusNode: _fiatAmountFocus,
63 + toolbarButtons: [(_) => KeyboardDoneButton()],
64 + )
65 + ]),
66 + child: Container(
67 + height: 0,
68 + color: Theme.of(context).backgroundColor,
69 + child: ScrollableWithBottomSection(
70 + contentPadding: EdgeInsets.only(bottom: 24),
71 + content: Container(
72 + decoration: BoxDecoration(
73 + borderRadius: BorderRadius.only(
74 + bottomLeft: Radius.circular(24),
75 + bottomRight: Radius.circular(24)),
76 + gradient: LinearGradient(colors: [
77 + Theme.of(context).primaryTextTheme.subhead.color,
78 + Theme.of(context).primaryTextTheme.subhead.decorationColor,
79 + ], begin: Alignment.topLeft, end: Alignment.bottomRight),
80 + ),
81 + child: Form(
82 + key: _formKey,
83 + child: Column(children: <Widget>[
84 + Padding(
85 + padding: EdgeInsets.fromLTRB(24, 90, 24, 32),
86 + child: Column(
87 + children: <Widget>[
88 + BaseTextFormField(
89 + controller: _nameController,
90 + hintText: S.of(context).send_name,
91 + borderColor:
92 + Theme.of(context).primaryTextTheme.headline.color,
93 + textStyle: TextStyle(
94 + fontSize: 14,
95 + fontWeight: FontWeight.w500,
96 + color: Colors.white),
97 + placeholderTextStyle: TextStyle(
98 + color: Theme.of(context)
99 + .primaryTextTheme
100 + .headline
101 + .decorationColor,
102 + fontWeight: FontWeight.w500,
103 + fontSize: 14),
104 + validator: sendViewModel.templateValidator,
105 + ),
106 + Padding(
107 + padding: EdgeInsets.only(top: 20),
108 + child: AddressTextField(
109 + controller: _addressController,
110 + onURIScanned: (uri) {
111 + var address = '';
112 + var amount = '';
113
95 - if (uri != null) {
96 - address = uri.path;
97 - amount = uri.queryParameters['tx_amount'];
98 - } else {
99 - address = uri.toString();
100 - }
114 + if (uri != null) {
115 + address = uri.path;
116 + amount = uri.queryParameters['tx_amount'];
117 + } else {
118 + address = uri.toString();
119 + }
120
102 - _addressController.text = address;
103 - _cryptoAmountController.text = amount;
104 - },
105 - options: [
106 - AddressTextFieldOption.paste,
107 - AddressTextFieldOption.qrCode,
108 - AddressTextFieldOption.addressBook
109 - ],
110 - buttonColor:
111 - Theme.of(context).primaryTextTheme.display1.color,
112 - borderColor:
113 - Theme.of(context).primaryTextTheme.headline.color,
114 - textStyle: TextStyle(
115 - fontSize: 14,
116 - fontWeight: FontWeight.w500,
117 - color: Colors.white),
118 - hintStyle: TextStyle(
119 - fontSize: 14,
120 - fontWeight: FontWeight.w500,
121 - color: Theme.of(context)
121 + _addressController.text = address;
122 + _cryptoAmountController.text = amount;
123 + },
124 + options: [
125 + AddressTextFieldOption.paste,
126 + AddressTextFieldOption.qrCode,
127 + AddressTextFieldOption.addressBook
128 + ],
129 + buttonColor: Theme.of(context)
130 + .primaryTextTheme
131 + .display1
132 + .color,
133 + borderColor: Theme.of(context)
134 .primaryTextTheme
135 .headline
124 - .decorationColor),
125 - validator: sendViewModel.addressValidator,
126 - ),
127 - ),
128 - Observer(builder: (_) {
129 - return Padding(
130 - padding: const EdgeInsets.only(top: 20),
131 - child: BaseTextFormField(
132 - controller: _cryptoAmountController,
136 + .color,
137 + textStyle: TextStyle(
138 + fontSize: 14,
139 + fontWeight: FontWeight.w500,
140 + color: Colors.white),
141 + hintStyle: TextStyle(
142 + fontSize: 14,
143 + fontWeight: FontWeight.w500,
144 + color: Theme.of(context)
145 + .primaryTextTheme
146 + .headline
147 + .decorationColor),
148 + validator: sendViewModel.addressValidator,
149 + ),
150 + ),
151 + Observer(builder: (_) {
152 + return Padding(
153 + padding: const EdgeInsets.only(top: 20),
154 + child: BaseTextFormField(
155 + focusNode: _cryptoAmountFocus,
156 + controller: _cryptoAmountController,
157 + keyboardType: TextInputType.numberWithOptions(
158 + signed: false, decimal: true),
159 + inputFormatters: [
160 + BlacklistingTextInputFormatter(
161 + RegExp('[\\-|\\ ]'))
162 + ],
163 + prefixIcon: Padding(
164 + padding: EdgeInsets.only(top: 9),
165 + child:
166 + Text(sendViewModel.currency.title + ':',
167 + style: TextStyle(
168 + fontSize: 16,
169 + fontWeight: FontWeight.w600,
170 + color: Colors.white,
171 + )),
172 + ),
173 + hintText: '0.0000',
174 + borderColor: Theme.of(context)
175 + .primaryTextTheme
176 + .headline
177 + .color,
178 + textStyle: TextStyle(
179 + fontSize: 14,
180 + fontWeight: FontWeight.w500,
181 + color: Colors.white),
182 + placeholderTextStyle: TextStyle(
183 + color: Theme.of(context)
184 + .primaryTextTheme
185 + .headline
186 + .decorationColor,
187 + fontWeight: FontWeight.w500,
188 + fontSize: 14),
189 + validator: sendViewModel.amountValidator));
190 + }),
191 + Padding(
192 + padding: const EdgeInsets.only(top: 20),
193 + child: BaseTextFormField(
194 + focusNode: _fiatAmountFocus,
195 + controller: _fiatAmountController,
196 keyboardType: TextInputType.numberWithOptions(
197 signed: false, decimal: true),
198 inputFormatters: [
@@ -138,15 +201,14 @@ class SendTemplatePage extends BasePage {
201 ],
202 prefixIcon: Padding(
203 padding: EdgeInsets.only(top: 9),
141 - child:
142 - Text(sendViewModel.currency.title + ':',
204 + child: Text(sendViewModel.fiat.title + ':',
205 style: TextStyle(
206 fontSize: 16,
207 fontWeight: FontWeight.w600,
208 color: Colors.white,
209 )),
210 ),
149 - hintText: '0.0000',
211 + hintText: '0.00',
212 borderColor: Theme.of(context)
213 .primaryTextTheme
214 .headline
@@ -162,68 +224,34 @@ class SendTemplatePage extends BasePage {
224 .decorationColor,
225 fontWeight: FontWeight.w500,
226 fontSize: 14),
165 - validator: sendViewModel.amountValidator));
166 - }),
167 - Padding(
168 - padding: const EdgeInsets.only(top: 20),
169 - child: BaseTextFormField(
170 - controller: _fiatAmountController,
171 - keyboardType: TextInputType.numberWithOptions(
172 - signed: false, decimal: true),
173 - inputFormatters: [
174 - BlacklistingTextInputFormatter(
175 - RegExp('[\\-|\\ ]'))
176 - ],
177 - prefixIcon: Padding(
178 - padding: EdgeInsets.only(top: 9),
179 - child: Text(sendViewModel.fiat.title + ':',
180 - style: TextStyle(
181 - fontSize: 16,
182 - fontWeight: FontWeight.w600,
183 - color: Colors.white,
184 - )),
185 - ),
186 - hintText: '0.00',
187 - borderColor: Theme.of(context)
188 - .primaryTextTheme
189 - .headline
190 - .color,
191 - textStyle: TextStyle(
192 - fontSize: 14,
193 - fontWeight: FontWeight.w500,
194 - color: Colors.white),
195 - placeholderTextStyle: TextStyle(
196 - color: Theme.of(context)
197 - .primaryTextTheme
198 - .headline
199 - .decorationColor,
200 - fontWeight: FontWeight.w500,
201 - fontSize: 14),
202 - )),
203 - ],
204 - ),
205 - )
206 - ]),
227 + )),
228 + ],
229 + ),
230 + )
231 + ]),
232 + ),
233 + ),
234 + bottomSectionPadding:
235 + EdgeInsets.only(left: 24, right: 24, bottom: 24),
236 + bottomSection: PrimaryButton(
237 + onPressed: () {
238 + if (_formKey.currentState.validate()) {
239 + sendViewModel.addTemplate(
240 + name: _nameController.text,
241 + address: _addressController.text,
242 + cryptoCurrency: sendViewModel.currency.title,
243 + amount: _cryptoAmountController.text);
244 + sendViewModel.updateTemplate();
245 + Navigator.of(context).pop();
246 + }
247 + },
248 + text: S.of(context).save,
249 + color: Theme.of(context).accentTextTheme.subtitle.decorationColor,
250 + textColor:
251 + Theme.of(context).accentTextTheme.headline.decorationColor,
252 + ),
253 ),
208 - ),
209 - bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
210 - bottomSection: PrimaryButton(
211 - onPressed: () {
212 - if (_formKey.currentState.validate()) {
213 - sendViewModel.addTemplate(
214 - name: _nameController.text,
215 - address: _addressController.text,
216 - cryptoCurrency: sendViewModel.currency.title,
217 - amount: _cryptoAmountController.text);
218 - sendViewModel.updateTemplate();
219 - Navigator.of(context).pop();
220 - }
221 - },
222 - text: S.of(context).save,
223 - color: Colors.green,
224 - textColor: Colors.white),
225 - ),
226 - );
254 + ));
255 }
256
257 void _setEffects(BuildContext context) {
lib/src/screens/trade_details/trade_details_page.dart
+5 -5
@@ -13,29 +13,29 @@ import 'package:cake_wallet/src/widgets/standart_list_row.dart';
13 class TradeDetailsPage extends BasePage {
14 TradeDetailsPage(this.trade) : _items = [] {
15 final dateFormat = DateFormatter.withCurrentLocal();
16 - final items = [
16 + _items.addAll([
17 StandartListItem(title: S.current.trade_details_id, value: trade.id),
18 StandartListItem(
19 title: S.current.trade_details_state,
20 value: trade.state != null
21 ? trade.state.toString()
22 : S.current.trade_details_fetching)
23 - ];
23 + ]);
24
25 if (trade.provider != null) {
26 - items.add(StandartListItem(
26 + _items.add(StandartListItem(
27 title: S.current.trade_details_provider,
28 value: trade.provider.toString()));
29 }
30
31 if (trade.createdAt != null) {
32 - items.add(StandartListItem(
32 + _items.add(StandartListItem(
33 title: S.current.trade_details_created_at,
34 value: dateFormat.format(trade.createdAt).toString()));
35 }
36
37 if (trade.from != null && trade.to != null) {
38 - items.add(StandartListItem(
38 + _items.add(StandartListItem(
39 title: S.current.trade_details_pair,
40 value: '${trade.from.toString()} → ${trade.to.toString()}'));
41 }
lib/view_model/exchange/exchange_trade_view_model.dart
+15 -1
@@ -7,6 +7,7 @@ import 'package:cake_wallet/exchange/morphtoken/morphtoken_exchange_provider.dar
7 import 'package:cake_wallet/exchange/trade.dart';
8 import 'package:cake_wallet/exchange/xmrto/xmrto_exchange_provider.dart';
9 import 'package:cake_wallet/store/dashboard/trades_store.dart';
10 +import 'package:cake_wallet/view_model/send/send_view_model.dart';
11 import 'package:hive/hive.dart';
12 import 'package:mobx/mobx.dart';
13 import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart';
@@ -18,7 +19,8 @@ class ExchangeTradeViewModel = ExchangeTradeViewModelBase
19 with _$ExchangeTradeViewModel;
20
21 abstract class ExchangeTradeViewModelBase with Store {
21 - ExchangeTradeViewModelBase({this.wallet, this.trades, this.tradesStore}) {
22 + ExchangeTradeViewModelBase(
23 + {this.wallet, this.trades, this.tradesStore, this.sendViewModel}) {
24 trade = tradesStore.trade;
25
26 isSendable = trade.from == wallet.currency ||
@@ -57,6 +59,7 @@ abstract class ExchangeTradeViewModelBase with Store {
59 final WalletBase wallet;
60 final Box<Trade> trades;
61 final TradesStore tradesStore;
62 + final SendViewModel sendViewModel;
63
64 @observable
65 Trade trade;
@@ -71,6 +74,17 @@ abstract class ExchangeTradeViewModelBase with Store {
74
75 Timer _timer;
76
77 + @action
78 + Future confirmSending() async {
79 + if (!isSendable) {
80 + return;
81 + }
82 +
83 + sendViewModel.address = trade.inputAddress;
84 + sendViewModel.setCryptoAmount(trade.amount);
85 + await sendViewModel.createTransaction();
86 + }
87 +
88 @action
89 Future<void> _updateTrade() async {
90 try {
lib/view_model/send/send_view_model.dart
+2 -2
@@ -1,8 +1,8 @@
1 +import 'package:intl/intl.dart';
2 +import 'package:mobx/mobx.dart';
3 import 'package:cake_wallet/entities/openalias_record.dart';
4 import 'package:cake_wallet/entities/template.dart';
5 import 'package:cake_wallet/store/templates/send_template_store.dart';
4 -import 'package:intl/intl.dart';
5 -import 'package:mobx/mobx.dart';
6 import 'package:cake_wallet/core/template_validator.dart';
7 import 'package:cake_wallet/core/address_validator.dart';
8 import 'package:cake_wallet/core/amount_validator.dart';