fix lag on saving frozen coin status (#3164)

* fix lag on saving frozen coin status * wrap saveUnspentCoinInfo in @action * revert fix + safeguard coin control page

malik1004x committed Apr 15, 2026 at 14:31 UTC fb14d07fc712c51745464f35fbaa4bb943986390
4 files changed +35 -11
lib/new-ui/pages/coin_control_page.dart
+23 -5
@@ -4,7 +4,6 @@ import 'package:cake_wallet/new-ui/widgets/modal_header.dart';
4 import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
5 import 'package:cake_wallet/routes.dart';
6 import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
7 -import 'package:cw_core/utils/print_verbose.dart';
7 import 'package:flutter/cupertino.dart';
8 import 'package:flutter/material.dart';
9 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -32,6 +31,10 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
31 Widget build(BuildContext context) {
32 return PopScope(
33 canPop: !widget.unspentCoinsListViewModel.isSavingItems,
34 + onPopInvokedWithResult: (didPop, result) async{
35 + await widget.unspentCoinsListViewModel.dispose();
36 + if(!didPop && mounted) Navigator.of(context).pop();
37 + },
38 child: Material(
39 borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
40 color: Colors.transparent,
@@ -42,10 +45,25 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
45 child: Column(
46 children: [
47 ModalTopBar(
45 - title: "",
46 - onLeadingPressed: Navigator.of(context).pop,
47 - leadingIcon: Icon(Icons.arrow_back_ios_new),
48 - onTrailingPressed: () {}),
48 + title: "",
49 + trailingWidget: GestureDetector(
50 + onTap: Navigator.of(context).pop,
51 + child: Container(
52 + decoration: BoxDecoration(
53 + color: Theme.of(context).colorScheme.surfaceContainer,
54 + borderRadius: BorderRadius.circular(99999)),
55 + child: Padding(
56 + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
57 + child: Text(
58 + S.of(context).done,
59 + style: TextStyle(
60 + color: Theme.of(context).colorScheme.primary,
61 + fontWeight: FontWeight.w600),
62 + ),
63 + ),
64 + ),
65 + ),
66 + ),
67 FutureBuilder(
68 future: _initialization,
69 builder: (context, asyncSnapshot) {
lib/new-ui/pages/send_page.dart
+6 -2
@@ -11,6 +11,7 @@ import 'package:cake_wallet/exchange/trade.dart';
11 import 'package:cake_wallet/generated/i18n.dart';
12 import 'package:cake_wallet/monero/monero.dart';
13 import 'package:cake_wallet/new-ui/modal_navigator.dart';
14 +import 'package:cake_wallet/new-ui/pages/coin_control_page.dart';
15 import 'package:cake_wallet/new-ui/widgets/animated_dropdown.dart';
16 import 'package:cake_wallet/new-ui/widgets/keyboard_hide_overlay.dart';
17 import 'package:cake_wallet/new-ui/widgets/picker.dart';
@@ -513,8 +514,11 @@ class _NewSendPageState extends State<NewSendPage> {
514 ListItemRegularRowWidget(
515 keyValue: "",
516 label: "Coin Control",
516 - onTap: () => Navigator.of(context)
517 - .pushNamed(Routes.unspentCoinsList),
517 + onTap: () {
518 + showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){
519 + return NewCoinControlPage(unspentCoinsListViewModel: widget.sendViewModel.unspentCoinsListViewModel,);
520 + });
521 + }
522 ),
523 ]),
524 )
lib/new-ui/widgets/swap_page/swap_options_page.dart
+5 -2
@@ -2,15 +2,16 @@ import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular
2 import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_selector.dart';
3 import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart';
4 import 'package:cake_wallet/generated/i18n.dart';
5 +import 'package:cake_wallet/new-ui/pages/coin_control_page.dart';
6 import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
7 import 'package:cake_wallet/new-ui/widgets/swap_page/provider_options_page.dart';
8 import 'package:cake_wallet/new-ui/widgets/swap_page/refund_address_modal.dart';
8 -import 'package:cake_wallet/routes.dart';
9 import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart';
10 import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
11 import 'package:flutter/cupertino.dart';
12 import 'package:flutter/material.dart';
13 import 'package:flutter_mobx/flutter_mobx.dart';
14 +import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
15
16 class SwapOptionsPage extends StatelessWidget {
17 const SwapOptionsPage({super.key, required this.exchangeViewModel});
@@ -100,7 +101,9 @@ class SwapOptionsPage extends StatelessWidget {
101 keyValue: "coin control",
102 label: "Coin Control",
103 onTap: () {
103 - Navigator.of(context).pushNamed(Routes.unspentCoinsList);
104 + showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){
105 + return NewCoinControlPage(unspentCoinsListViewModel: exchangeViewModel.unspentCoinsListViewModel,);
106 + });
107 }),
108 ListItemSelector(
109 keyValue: "curr",
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+1 -2
@@ -116,6 +116,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
116
117 bool get hasAdjustableFieldChanged => items.any(_hasAdjustableFieldChanged);
118
119 + @action
120 Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
121 try {
122 item.isBeingSaved = true;
@@ -129,8 +130,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
130 existingInfo.note = item.note;
131
132 await existingInfo.save();
132 - await _updateUnspents();
133 - await wallet.updateBalance();
133 item.isBeingSaved = false;
134 isSavingItems = false;
135 } catch (e) {