Cw 231 display balance in send and transaction screens when long pressing and when show balance is disabled (#926)

* feat: allow reversing displayMode by long pressing on transactions page * feat: allow reversing displayMode by long pressing on send page * revert: revert transaction_list_item.dart but keep BalanceDisplayMode get displayMode => balanceViewModel.displayMode

Rafael Saes committed Jun 9, 2023 at 19:29 UTC b16cfaaff5ac7e318dba9557b3eba6c5af6d30d7
3 files changed +396 -342
lib/src/screens/dashboard/widgets/transactions_page.dart
+109 -90
@@ -25,107 +25,126 @@ class TransactionsPage extends StatelessWidget {
25
26 @override
27 Widget build(BuildContext context) {
28 - return Container(
29 - color: ResponsiveLayoutUtil.instance.isMobile(context)
30 - ? null
31 - : Theme.of(context).colorScheme.background,
32 - padding: EdgeInsets.only(top: 24, bottom: 24),
33 - child: Column(
34 - children: <Widget>[
35 - HeaderRow(dashboardViewModel: dashboardViewModel),
36 - Expanded(child: Observer(builder: (_) {
37 - final items = dashboardViewModel.items;
28 + return GestureDetector(
29 + onLongPress: () => dashboardViewModel.balanceViewModel.isReversing =
30 + !dashboardViewModel.balanceViewModel.isReversing,
31 + onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing =
32 + !dashboardViewModel.balanceViewModel.isReversing,
33 + child: Container(
34 + color: ResponsiveLayoutUtil.instance.isMobile(context)
35 + ? null
36 + : Theme.of(context).colorScheme.background,
37 + padding: EdgeInsets.only(top: 24, bottom: 24),
38 + child: Column(
39 + children: <Widget>[
40 + HeaderRow(dashboardViewModel: dashboardViewModel),
41 + Expanded(child: Observer(builder: (_) {
42 + final items = dashboardViewModel.items;
43
39 - return items.isNotEmpty
40 - ? ListView.builder(
41 - itemCount: items.length,
42 - itemBuilder: (context, index) {
43 - final item = items[index];
44 + return items.isNotEmpty
45 + ? ListView.builder(
46 + itemCount: items.length,
47 + itemBuilder: (context, index) {
48 + final item = items[index];
49
45 - if (item is DateSectionItem) {
46 - return DateSectionRaw(date: item.date);
47 - }
50 + if (item is DateSectionItem) {
51 + return DateSectionRaw(date: item.date);
52 + }
53
49 - if (item is TransactionListItem) {
50 - final transaction = item.transaction;
54 + if (item is TransactionListItem) {
55 + final transaction = item.transaction;
56
52 - return Observer(
53 - builder: (_) => TransactionRow(
54 - onTap: () => Navigator.of(context)
55 - .pushNamed(Routes.transactionDetails, arguments: transaction),
56 - direction: transaction.direction,
57 - formattedDate: DateFormat('HH:mm').format(transaction.date),
58 - formattedAmount: item.formattedCryptoAmount,
59 - formattedFiatAmount:
60 - dashboardViewModel.balanceViewModel.isFiatDisabled
61 - ? ''
62 - : item.formattedFiatAmount,
63 - isPending: transaction.isPending,
64 - title: item.formattedTitle + item.formattedStatus));
65 - }
57 + return Observer(
58 + builder: (_) => TransactionRow(
59 + onTap: () => Navigator.of(context).pushNamed(
60 + Routes.transactionDetails,
61 + arguments: transaction),
62 + direction: transaction.direction,
63 + formattedDate: DateFormat('HH:mm')
64 + .format(transaction.date),
65 + formattedAmount: item.formattedCryptoAmount,
66 + formattedFiatAmount: dashboardViewModel
67 + .balanceViewModel.isFiatDisabled
68 + ? ''
69 + : item.formattedFiatAmount,
70 + isPending: transaction.isPending,
71 + title: item.formattedTitle +
72 + item.formattedStatus));
73 + }
74
67 - if (item is AnonpayTransactionListItem) {
68 - final transactionInfo = item.transaction;
75 + if (item is AnonpayTransactionListItem) {
76 + final transactionInfo = item.transaction;
77
70 - return AnonpayTransactionRow(
71 - onTap: () => Navigator.of(context)
72 - .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
73 - currency: transactionInfo.fiatAmount != null
74 - ? transactionInfo.fiatEquiv ?? ''
75 - : CryptoCurrency.fromFullName(transactionInfo.coinTo)
76 - .name
77 - .toUpperCase(),
78 - provider: transactionInfo.provider,
79 - amount: transactionInfo.fiatAmount?.toString() ??
80 - (transactionInfo.amountTo?.toString() ?? ''),
81 - createdAt: DateFormat('HH:mm').format(transactionInfo.createdAt),
82 - );
83 - }
78 + return AnonpayTransactionRow(
79 + onTap: () => Navigator.of(context).pushNamed(
80 + Routes.anonPayDetailsPage,
81 + arguments: transactionInfo),
82 + currency: transactionInfo.fiatAmount != null
83 + ? transactionInfo.fiatEquiv ?? ''
84 + : CryptoCurrency.fromFullName(
85 + transactionInfo.coinTo)
86 + .name
87 + .toUpperCase(),
88 + provider: transactionInfo.provider,
89 + amount: transactionInfo.fiatAmount?.toString() ??
90 + (transactionInfo.amountTo?.toString() ?? ''),
91 + createdAt: DateFormat('HH:mm')
92 + .format(transactionInfo.createdAt),
93 + );
94 + }
95
85 - if (item is TradeListItem) {
86 - final trade = item.trade;
96 + if (item is TradeListItem) {
97 + final trade = item.trade;
98
88 - return Observer(
89 - builder: (_) => TradeRow(
90 - onTap: () => Navigator.of(context)
91 - .pushNamed(Routes.tradeDetails, arguments: trade),
92 - provider: trade.provider,
93 - from: trade.from,
94 - to: trade.to,
95 - createdAtFormattedDate: trade.createdAt != null
96 - ? DateFormat('HH:mm').format(trade.createdAt!)
97 - : null,
98 - formattedAmount: item.tradeFormattedAmount));
99 - }
99 + return Observer(
100 + builder: (_) => TradeRow(
101 + onTap: () => Navigator.of(context).pushNamed(
102 + Routes.tradeDetails,
103 + arguments: trade),
104 + provider: trade.provider,
105 + from: trade.from,
106 + to: trade.to,
107 + createdAtFormattedDate:
108 + trade.createdAt != null
109 + ? DateFormat('HH:mm')
110 + .format(trade.createdAt!)
111 + : null,
112 + formattedAmount: item.tradeFormattedAmount));
113 + }
114
101 - if (item is OrderListItem) {
102 - final order = item.order;
115 + if (item is OrderListItem) {
116 + final order = item.order;
117
104 - return Observer(
105 - builder: (_) => OrderRow(
106 - onTap: () => Navigator.of(context)
107 - .pushNamed(Routes.orderDetails, arguments: order),
108 - provider: order.provider,
109 - from: order.from!,
110 - to: order.to!,
111 - createdAtFormattedDate:
112 - DateFormat('HH:mm').format(order.createdAt),
113 - formattedAmount: item.orderFormattedAmount,
114 - ));
115 - }
118 + return Observer(
119 + builder: (_) => OrderRow(
120 + onTap: () => Navigator.of(context)
121 + .pushNamed(Routes.orderDetails,
122 + arguments: order),
123 + provider: order.provider,
124 + from: order.from!,
125 + to: order.to!,
126 + createdAtFormattedDate: DateFormat('HH:mm')
127 + .format(order.createdAt),
128 + formattedAmount: item.orderFormattedAmount,
129 + ));
130 + }
131
117 - return Container(color: Colors.transparent, height: 1);
118 - })
119 - : Center(
120 - child: Text(
121 - S.of(context).placeholder_transactions,
122 - style: TextStyle(
123 - fontSize: 14,
124 - color: Theme.of(context).primaryTextTheme!.labelSmall!.decorationColor!),
125 - ),
126 - );
127 - }))
128 - ],
132 + return Container(color: Colors.transparent, height: 1);
133 + })
134 + : Center(
135 + child: Text(
136 + S.of(context).placeholder_transactions,
137 + style: TextStyle(
138 + fontSize: 14,
139 + color: Theme.of(context)
140 + .primaryTextTheme
141 + .labelSmall!
142 + .decorationColor!),
143 + ),
144 + );
145 + }))
146 + ],
147 + ),
148 ),
149 );
150 }
lib/src/screens/send/send_page.dart
+286 -250
@@ -145,216 +145,247 @@ class SendPage extends BasePage {
145 Widget body(BuildContext context) {
146 _setEffects(context);
147
148 - return Form(
149 - key: _formKey,
150 - child: ScrollableWithBottomSection(
151 - contentPadding: EdgeInsets.only(bottom: 24),
152 - content: FocusTraversalGroup(
153 - policy: OrderedTraversalPolicy(),
154 - child: Column(
155 - children: <Widget>[
156 - Container(
157 - height: _sendCardHeight(context),
158 - child: Observer(
159 - builder: (_) {
160 - return PageView.builder(
161 - scrollDirection: Axis.horizontal,
162 - controller: controller,
163 - itemCount: sendViewModel.outputs.length,
164 - itemBuilder: (context, index) {
165 - final output = sendViewModel.outputs[index];
166 -
167 - return SendCard(
168 - key: output.key,
169 - output: output,
170 - sendViewModel: sendViewModel,
171 - initialPaymentRequest: initialPaymentRequest,
172 - );
173 - });
174 - },
175 - )),
176 - Padding(
177 - padding:
178 - EdgeInsets.only(top: 10, left: 24, right: 24, bottom: 10),
179 - child: Container(
180 - height: 10,
181 - child: Observer(
182 - builder: (_) {
183 - final count = sendViewModel.outputs.length;
184 -
185 - return count > 1
186 - ? SmoothPageIndicator(
187 - controller: controller,
188 - count: count,
189 - effect: ScrollingDotsEffect(
190 - spacing: 6.0,
191 - radius: 6.0,
192 - dotWidth: 6.0,
193 - dotHeight: 6.0,
194 - dotColor: Theme.of(context)
195 - .primaryTextTheme!.displaySmall!
196 - .backgroundColor!,
197 - activeDotColor: Theme.of(context)
198 - .primaryTextTheme!.displayMedium!
199 - .backgroundColor!),
200 - )
201 - : Offstage();
202 - },
203 - ),
204 - ),
205 - ),
206 - if (sendViewModel.hasMultiRecipient)
207 - Container(
208 - height: 40,
209 - width: double.infinity,
210 - padding: EdgeInsets.only(left: 24),
211 - child: SingleChildScrollView(
212 - scrollDirection: Axis.horizontal,
213 - child: Observer(
214 - builder: (_) {
215 - final templates = sendViewModel.templates;
216 - final itemCount = templates.length;
217 -
218 - return Row(
219 - children: <Widget>[
220 - AddTemplateButton(
221 - onTap: () => Navigator.of(context).pushNamed(Routes.sendTemplate),
222 - currentTemplatesLength: templates.length,
223 - ),
224 - ListView.builder(
148 + return GestureDetector(
149 + onLongPress: () => sendViewModel.balanceViewModel.isReversing =
150 + !sendViewModel.balanceViewModel.isReversing,
151 + onLongPressUp: () => sendViewModel.balanceViewModel.isReversing =
152 + !sendViewModel.balanceViewModel.isReversing,
153 + child: Form(
154 + key: _formKey,
155 + child: ScrollableWithBottomSection(
156 + contentPadding: EdgeInsets.only(bottom: 24),
157 + content: FocusTraversalGroup(
158 + policy: OrderedTraversalPolicy(),
159 + child: Column(
160 + children: <Widget>[
161 + Container(
162 + height: _sendCardHeight(context),
163 + child: Observer(
164 + builder: (_) {
165 + return PageView.builder(
166 scrollDirection: Axis.horizontal,
226 - shrinkWrap: true,
227 - physics: NeverScrollableScrollPhysics(),
228 - itemCount: itemCount,
167 + controller: controller,
168 + itemCount: sendViewModel.outputs.length,
169 itemBuilder: (context, index) {
230 - final template = templates[index];
231 - return TemplateTile(
232 - key: UniqueKey(),
233 - to: template.name,
234 - amount: template.isCurrencySelected ? template.amount : template.amountFiat,
235 - from: template.isCurrencySelected ? template.cryptoCurrency : template.fiatCurrency,
236 - onTap: () async {
237 - final fiatFromTemplate = FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency);
238 - final output = _defineCurrentOutput();
239 - output.address = template.address;
240 - if(template.isCurrencySelected){
241 - output.setCryptoAmount(template.amount);
242 - }else{
243 - sendViewModel.setFiatCurrency(fiatFromTemplate);
244 - output.setFiatAmount(template.amountFiat);
245 - }
246 - output.resetParsedAddress();
247 - await output.fetchParsedAddress(context);
248 - },
249 - onRemove: () {
250 - showPopUp<void>(
251 - context: context,
252 - builder: (dialogContext) {
253 - return AlertWithTwoActions(
254 - alertTitle: S.of(context).template,
255 - alertContent: S
256 - .of(context)
257 - .confirm_delete_template,
258 - rightButtonText: S.of(context).delete,
259 - leftButtonText: S.of(context).cancel,
260 - actionRightButton: () {
261 - Navigator.of(dialogContext).pop();
262 - sendViewModel.sendTemplateViewModel
263 - .removeTemplate(
264 - template: template);
265 - },
266 - actionLeftButton: () =>
267 - Navigator.of(dialogContext)
268 - .pop());
269 - },
270 - );
271 - },
170 + final output = sendViewModel.outputs[index];
171 +
172 + return SendCard(
173 + key: output.key,
174 + output: output,
175 + sendViewModel: sendViewModel,
176 + initialPaymentRequest: initialPaymentRequest,
177 );
273 - },
274 - ),
275 - ],
276 - );
277 - },
178 + });
179 + },
180 + )),
181 + Padding(
182 + padding: EdgeInsets.only(
183 + top: 10, left: 24, right: 24, bottom: 10),
184 + child: Container(
185 + height: 10,
186 + child: Observer(
187 + builder: (_) {
188 + final count = sendViewModel.outputs.length;
189 +
190 + return count > 1
191 + ? SmoothPageIndicator(
192 + controller: controller,
193 + count: count,
194 + effect: ScrollingDotsEffect(
195 + spacing: 6.0,
196 + radius: 6.0,
197 + dotWidth: 6.0,
198 + dotHeight: 6.0,
199 + dotColor: Theme.of(context)
200 + .primaryTextTheme
201 + !.displaySmall!
202 + .backgroundColor!,
203 + activeDotColor: Theme.of(context)
204 + .primaryTextTheme
205 + !.displayMedium!
206 + .backgroundColor!),
207 + )
208 + : Offstage();
209 + },
210 + ),
211 ),
212 ),
280 - )
281 - ],
213 + if (sendViewModel.hasMultiRecipient)
214 + Container(
215 + height: 40,
216 + width: double.infinity,
217 + padding: EdgeInsets.only(left: 24),
218 + child: SingleChildScrollView(
219 + scrollDirection: Axis.horizontal,
220 + child: Observer(
221 + builder: (_) {
222 + final templates = sendViewModel.templates;
223 + final itemCount = templates.length;
224 +
225 + return Row(
226 + children: <Widget>[
227 + AddTemplateButton(
228 + onTap: () => Navigator.of(context)
229 + .pushNamed(Routes.sendTemplate),
230 + currentTemplatesLength: templates.length,
231 + ),
232 + ListView.builder(
233 + scrollDirection: Axis.horizontal,
234 + shrinkWrap: true,
235 + physics: NeverScrollableScrollPhysics(),
236 + itemCount: itemCount,
237 + itemBuilder: (context, index) {
238 + final template = templates[index];
239 + return TemplateTile(
240 + key: UniqueKey(),
241 + to: template.name,
242 + amount: template.isCurrencySelected
243 + ? template.amount
244 + : template.amountFiat,
245 + from: template.isCurrencySelected
246 + ? template.cryptoCurrency
247 + : template.fiatCurrency,
248 + onTap: () async {
249 + final fiatFromTemplate = FiatCurrency
250 + .all
251 + .singleWhere((element) =>
252 + element.title ==
253 + template.fiatCurrency);
254 + final output = _defineCurrentOutput();
255 + output.address = template.address;
256 + if (template.isCurrencySelected) {
257 + output
258 + .setCryptoAmount(template.amount);
259 + } else {
260 + sendViewModel.setFiatCurrency(
261 + fiatFromTemplate);
262 + output.setFiatAmount(
263 + template.amountFiat);
264 + }
265 + output.resetParsedAddress();
266 + await output
267 + .fetchParsedAddress(context);
268 + },
269 + onRemove: () {
270 + showPopUp<void>(
271 + context: context,
272 + builder: (dialogContext) {
273 + return AlertWithTwoActions(
274 + alertTitle:
275 + S.of(context).template,
276 + alertContent: S
277 + .of(context)
278 + .confirm_delete_template,
279 + rightButtonText:
280 + S.of(context).delete,
281 + leftButtonText:
282 + S.of(context).cancel,
283 + actionRightButton: () {
284 + Navigator.of(dialogContext)
285 + .pop();
286 + sendViewModel
287 + .sendTemplateViewModel
288 + .removeTemplate(
289 + template: template);
290 + },
291 + actionLeftButton: () =>
292 + Navigator.of(dialogContext)
293 + .pop());
294 + },
295 + );
296 + },
297 + );
298 + },
299 + ),
300 + ],
301 + );
302 + },
303 + ),
304 + ),
305 + )
306 + ],
307 + ),
308 ),
283 - ),
284 - bottomSectionPadding:
285 - EdgeInsets.only(left: 24, right: 24, bottom: 24),
286 - bottomSection: Column(
287 - children: [
288 - if (sendViewModel.hasCurrecyChanger)
289 - Observer(builder: (_) =>
309 + bottomSectionPadding:
310 + EdgeInsets.only(left: 24, right: 24, bottom: 24),
311 + bottomSection: Column(
312 + children: [
313 + if (sendViewModel.hasCurrecyChanger)
314 + Observer(
315 + builder: (_) => Padding(
316 + padding: EdgeInsets.only(bottom: 12),
317 + child: PrimaryButton(
318 + onPressed: () => presentCurrencyPicker(context),
319 + text:
320 + 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
321 + color: Colors.transparent,
322 + textColor: Theme.of(context)
323 + .accentTextTheme
324 + !.displaySmall!
325 + .decorationColor!,
326 + ))),
327 + if (sendViewModel.hasMultiRecipient)
328 Padding(
291 - padding: EdgeInsets.only(bottom: 12),
292 - child: PrimaryButton(
293 - onPressed: () => presentCurrencyPicker(context),
294 - text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
295 - color: Colors.transparent,
296 - textColor: Theme.of(context)
297 - .accentTextTheme!.displaySmall!
298 - .decorationColor!,
299 - )
300 - )
301 - ),
302 - if (sendViewModel.hasMultiRecipient)
303 - Padding(
304 - padding: EdgeInsets.only(bottom: 12),
305 - child: PrimaryButton(
306 - onPressed: () {
307 - sendViewModel.addOutput();
308 - Future.delayed(const Duration(milliseconds: 250), () {
309 - controller.jumpToPage(sendViewModel.outputs.length - 1);
310 - });
311 - },
312 - text: S.of(context).add_receiver,
313 - color: Colors.transparent,
314 - textColor: Theme.of(context)
315 - .accentTextTheme!.displaySmall!
316 - .decorationColor!,
317 - isDottedBorder: true,
318 - borderColor: Theme.of(context)
319 - .primaryTextTheme!.displaySmall!
320 - .decorationColor!,
321 - )),
322 - Observer(
323 - builder: (_) {
324 - return LoadingPrimaryButton(
325 - onPressed: () async {
326 - if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
327 - if (sendViewModel.outputs.length > 1) {
329 + padding: EdgeInsets.only(bottom: 12),
330 + child: PrimaryButton(
331 + onPressed: () {
332 + sendViewModel.addOutput();
333 + Future.delayed(const Duration(milliseconds: 250), () {
334 + controller
335 + .jumpToPage(sendViewModel.outputs.length - 1);
336 + });
337 + },
338 + text: S.of(context).add_receiver,
339 + color: Colors.transparent,
340 + textColor: Theme.of(context)
341 + .accentTextTheme
342 + !.displaySmall!
343 + .decorationColor!,
344 + isDottedBorder: true,
345 + borderColor: Theme.of(context)
346 + .primaryTextTheme
347 + !.displaySmall!
348 + .decorationColor!,
349 + )),
350 + Observer(
351 + builder: (_) {
352 + return LoadingPrimaryButton(
353 + onPressed: () async {
354 + if (_formKey.currentState != null &&
355 + !_formKey.currentState!.validate()) {
356 + if (sendViewModel.outputs.length > 1) {
357 + showErrorValidationAlert(context);
358 + }
359 +
360 + return;
361 + }
362 +
363 + final notValidItems = sendViewModel.outputs
364 + .where((item) =>
365 + item.address.isEmpty ||
366 + item.cryptoAmount.isEmpty)
367 + .toList();
368 +
369 + if (notValidItems.isNotEmpty ?? false) {
370 showErrorValidationAlert(context);
371 + return;
372 }
373
331 - return;
332 - }
333 -
334 - final notValidItems = sendViewModel.outputs
335 - .where((item) =>
336 - item.address.isEmpty || item.cryptoAmount.isEmpty)
337 - .toList();
338 -
339 - if (notValidItems.isNotEmpty ?? false) {
340 - showErrorValidationAlert(context);
341 - return;
342 - }
343 -
344 - await sendViewModel.createTransaction();
345 -
346 - },
347 - text: S.of(context).send,
348 - color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
349 - textColor: Colors.white,
350 - isLoading: sendViewModel.state is IsExecutingState ||
351 - sendViewModel.state is TransactionCommitting,
352 - isDisabled: !sendViewModel.isReadyForSend,
353 - );
354 - },
355 - )
356 - ],
357 - )),
374 + await sendViewModel.createTransaction();
375 + },
376 + text: S.of(context).send,
377 + color:
378 + Theme.of(context).accentTextTheme!.bodyLarge!.color!,
379 + textColor: Colors.white,
380 + isLoading: sendViewModel.state is IsExecutingState ||
381 + sendViewModel.state is TransactionCommitting,
382 + isDisabled: !sendViewModel.isReadyForSend,
383 + );
384 + },
385 + )
386 + ],
387 + )),
388 + ),
389 );
390 }
391
@@ -382,51 +413,54 @@ class SendPage extends BasePage {
413 WidgetsBinding.instance.addPostFrameCallback((_) {
414 if (context.mounted) {
415 showPopUp<void>(
385 - context: context,
386 - builder: (BuildContext context) {
387 - return ConfirmSendingAlert(
388 - alertTitle: S.of(context).confirm_sending,
389 - amount: S.of(context).send_amount,
390 - amountValue:
391 - sendViewModel.pendingTransaction!.amountFormatted,
392 - fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
393 - fee: S.of(context).send_fee,
394 - feeValue: sendViewModel.pendingTransaction!.feeFormatted,
395 - feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
396 - outputs: sendViewModel.outputs,
397 - rightButtonText: S.of(context).ok,
398 - leftButtonText: S.of(context).cancel,
399 - actionRightButton: () {
400 - Navigator.of(context).pop();
401 - sendViewModel.commitTransaction();
402 - showPopUp<void>(
403 - context: context,
404 - builder: (BuildContext context) {
405 - return Observer(builder: (_) {
406 - final state = sendViewModel.state;
407 -
408 - if (state is FailureState) {
409 - Navigator.of(context).pop();
410 - }
411 -
412 - if (state is TransactionCommitted) {
413 - return AlertWithOneAction(
414 - alertTitle: '',
415 - alertContent: S.of(context).send_success(
416 - sendViewModel.selectedCryptoCurrency.toString()),
417 - buttonText: S.of(context).ok,
418 - buttonAction: () {
419 - Navigator.of(context).pop();
420 - RequestReviewHandler.requestReview();
421 - });
416 + context: context,
417 + builder: (BuildContext context) {
418 + return ConfirmSendingAlert(
419 + alertTitle: S.of(context).confirm_sending,
420 + amount: S.of(context).send_amount,
421 + amountValue:
422 + sendViewModel.pendingTransaction!.amountFormatted,
423 + fiatAmountValue:
424 + sendViewModel.pendingTransactionFiatAmountFormatted,
425 + fee: S.of(context).send_fee,
426 + feeValue: sendViewModel.pendingTransaction!.feeFormatted,
427 + feeFiatAmount: sendViewModel
428 + .pendingTransactionFeeFiatAmountFormatted,
429 + outputs: sendViewModel.outputs,
430 + rightButtonText: S.of(context).ok,
431 + leftButtonText: S.of(context).cancel,
432 + actionRightButton: () {
433 + Navigator.of(context).pop();
434 + sendViewModel.commitTransaction();
435 + showPopUp<void>(
436 + context: context,
437 + builder: (BuildContext context) {
438 + return Observer(builder: (_) {
439 + final state = sendViewModel.state;
440 +
441 + if (state is FailureState) {
442 + Navigator.of(context).pop();
443 }
444
424 - return Offstage();
445 + if (state is TransactionCommitted) {
446 + return AlertWithOneAction(
447 + alertTitle: '',
448 + alertContent: S.of(context).send_success(
449 + sendViewModel.selectedCryptoCurrency
450 + .toString()),
451 + buttonText: S.of(context).ok,
452 + buttonAction: () {
453 + Navigator.of(context).pop();
454 + RequestReviewHandler.requestReview();
455 + });
456 + }
457 +
458 + return Offstage();
459 + });
460 });
426 - });
427 - },
428 - actionLeftButton: () => Navigator.of(context).pop());
429 - });
461 + },
462 + actionLeftButton: () => Navigator.of(context).pop());
463 + });
464 }
465 });
466 }
@@ -461,16 +495,18 @@ class SendPage extends BasePage {
495 });
496 }
497
464 - void presentCurrencyPicker(BuildContext context) async {
498 + void presentCurrencyPicker(BuildContext context) async {
499 await showPopUp<CryptoCurrency>(
500 builder: (_) => Picker(
467 - items: sendViewModel.currencies,
468 - displayItem: (Object item) => item.toString(),
469 - selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
470 - title: S.of(context).please_select,
471 - mainAxisAlignment: MainAxisAlignment.center,
472 - onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
473 - ),
501 + items: sendViewModel.currencies,
502 + displayItem: (Object item) => item.toString(),
503 + selectedAtIndex: sendViewModel.currencies
504 + .indexOf(sendViewModel.selectedCryptoCurrency),
505 + title: S.of(context).please_select,
506 + mainAxisAlignment: MainAxisAlignment.center,
507 + onItemSelected: (CryptoCurrency cur) =>
508 + sendViewModel.selectedCryptoCurrency = cur,
509 + ),
510 context: context);
511 }
512 }
lib/view_model/dashboard/transaction_list_item.dart
+1 -2
@@ -13,7 +13,6 @@ import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
13 import 'package:cw_core/keyable.dart';
14 import 'package:cw_core/wallet_type.dart';
15
16 -
16 class TransactionListItem extends ActionListItem with Keyable {
17 TransactionListItem(
18 {required this.transaction,
@@ -28,7 +27,7 @@ class TransactionListItem extends ActionListItem with Keyable {
27
28 FiatCurrency get fiatCurrency => settingsStore.fiatCurrency;
29
31 - BalanceDisplayMode get displayMode => settingsStore.balanceDisplayMode;
30 + BalanceDisplayMode get displayMode => balanceViewModel.displayMode;
31
32 @override
33 dynamic get keyIndex => transaction.id;