diff --git a/lib/di.dart b/lib/di.dart index 0043c4e04..821f51130 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -1569,10 +1569,10 @@ Future setup({ unspentCoinsListViewModel: getIt.get(param1: coinTypeToSpendFrom))); - getIt.registerFactoryParam( - (coinTypeToSpendFrom, _) => NewCoinControlPage( + getIt.registerFactoryParam( + (coinTypeToSpendFrom, canEdit) => NewCoinControlPage( unspentCoinsListViewModel: - getIt.get(param1: coinTypeToSpendFrom)) + getIt.get(param1: coinTypeToSpendFrom), canEdit: canEdit ?? true,) ); diff --git a/lib/new-ui/pages/coin_control_page.dart b/lib/new-ui/pages/coin_control_page.dart index 2cf3f7e11..656b608ad 100644 --- a/lib/new-ui/pages/coin_control_page.dart +++ b/lib/new-ui/pages/coin_control_page.dart @@ -4,15 +4,25 @@ import 'package:cake_wallet/new-ui/widgets/modal_header.dart'; import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart'; +import 'package:cw_core/unspent_coin_type.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import "package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart"; +class CoinControlPageArgs { + final bool canEdit; + final UnspentCoinType? coinTypeToSpendFrom; + + const CoinControlPageArgs({required this.canEdit, this.coinTypeToSpendFrom}); +} + class NewCoinControlPage extends StatefulWidget { - const NewCoinControlPage({super.key, required this.unspentCoinsListViewModel}); + const NewCoinControlPage( + {super.key, required this.unspentCoinsListViewModel, required this.canEdit}); final UnspentCoinsListViewModel unspentCoinsListViewModel; + final bool canEdit; @override State createState() => _NewCoinControlPageState(); @@ -31,9 +41,9 @@ class _NewCoinControlPageState extends State { Widget build(BuildContext context) { return PopScope( canPop: !widget.unspentCoinsListViewModel.isSavingItems, - onPopInvokedWithResult: (didPop, result) async{ + onPopInvokedWithResult: (didPop, result) async { await widget.unspentCoinsListViewModel.dispose(); - if(!didPop && mounted) Navigator.of(context).pop(); + if (!didPop && mounted) Navigator.of(context).pop(); }, child: Material( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), @@ -94,9 +104,9 @@ class _NewCoinControlPageState extends State { child: ModalHeader( iconPath: "assets/new-ui/settings_row_icons/coin-control.svg", title: "Coin Control", - message: S.of(context).coin_control_desc), + message: widget.canEdit ? S.of(context).coin_control_desc : S.of(context).coin_control_desc_no_edit), ), - if (widget.unspentCoinsListViewModel.items.isNotEmpty) + if (widget.unspentCoinsListViewModel.items.isNotEmpty && widget.canEdit) Padding( padding: const EdgeInsets.all(12.0), child: Row( @@ -124,7 +134,7 @@ class _NewCoinControlPageState extends State { ) ], ), - ), + ) else SizedBox(height: 24,), if (widget.unspentCoinsListViewModel.nonFrozenItems.isEmpty && widget.unspentCoinsListViewModel.frozenItems.isEmpty) ...[ SizedBox(height: 12), @@ -144,6 +154,7 @@ class _NewCoinControlPageState extends State { : Padding( padding: const EdgeInsets.symmetric(horizontal: 18.0), child: CoinControlListSection( + canEdit: widget.canEdit, items: widget.unspentCoinsListViewModel.nonFrozenItems, unspentCoinsListViewModel: widget.unspentCoinsListViewModel), @@ -170,6 +181,7 @@ class _NewCoinControlPageState extends State { .onSurfaceVariant), ), CoinControlListSection( + canEdit: widget.canEdit, items: widget .unspentCoinsListViewModel.frozenItems, unspentCoinsListViewModel: @@ -194,9 +206,10 @@ class _NewCoinControlPageState extends State { class CoinControlListSection extends StatelessWidget { const CoinControlListSection( - {super.key, required this.items, required this.unspentCoinsListViewModel}); + {super.key, required this.items, required this.unspentCoinsListViewModel, required this.canEdit}); final List items; + final bool canEdit; final UnspentCoinsListViewModel unspentCoinsListViewModel; @override @@ -231,6 +244,7 @@ class CoinControlListSection extends StatelessWidget { isLoading: item.isBeingSaved, isFirst: index == 0, isLast: index == items.length - 1, + hasCheckbox: canEdit, onCheckBoxTap: item.isFrozen ? null : () async { diff --git a/lib/new-ui/pages/send_page.dart b/lib/new-ui/pages/send_page.dart index fec5e06f5..fd0b69699 100644 --- a/lib/new-ui/pages/send_page.dart +++ b/lib/new-ui/pages/send_page.dart @@ -524,7 +524,7 @@ class _NewSendPageState extends State { label: "Coin Control", onTap: () { showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){ - return NewCoinControlPage(unspentCoinsListViewModel: widget.sendViewModel.unspentCoinsListViewModel,); + return NewCoinControlPage(unspentCoinsListViewModel: widget.sendViewModel.unspentCoinsListViewModel,canEdit: true); }); } ), diff --git a/lib/new-ui/widgets/coin_control_page/coin_control_list_item.dart b/lib/new-ui/widgets/coin_control_page/coin_control_list_item.dart index ab58ea240..3254498d1 100644 --- a/lib/new-ui/widgets/coin_control_page/coin_control_list_item.dart +++ b/lib/new-ui/widgets/coin_control_page/coin_control_list_item.dart @@ -17,7 +17,7 @@ class CoinControlListItem extends StatelessWidget { required this.isFirst, required this.isLast, required this.isLoading, - this.onCheckBoxTap, + this.onCheckBoxTap, required this.hasCheckbox, }); final String note; @@ -31,6 +31,7 @@ class CoinControlListItem extends StatelessWidget { final bool isFirst; final bool isLast; final bool isLoading; + final bool hasCheckbox; final Function()? onCheckBoxTap; @override @@ -123,6 +124,10 @@ class CoinControlListItem extends StatelessWidget { return CakeImageWidget(imageUrl:"assets/new-ui/frozen.svg"); } + if(!hasCheckbox) { + return SizedBox.shrink(); + } + return NewSimpleCheckbox(value: isSending, onChanged: (value){onCheckBoxTap?.call();}); } diff --git a/lib/new-ui/widgets/swap_page/swap_options_page.dart b/lib/new-ui/widgets/swap_page/swap_options_page.dart index 917537db0..6bd8a643f 100644 --- a/lib/new-ui/widgets/swap_page/swap_options_page.dart +++ b/lib/new-ui/widgets/swap_page/swap_options_page.dart @@ -102,7 +102,7 @@ class SwapOptionsPage extends StatelessWidget { label: "Coin Control", onTap: () { showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){ - return NewCoinControlPage(unspentCoinsListViewModel: exchangeViewModel.unspentCoinsListViewModel,); + return NewCoinControlPage(unspentCoinsListViewModel: exchangeViewModel.unspentCoinsListViewModel,canEdit: true,); }); }), ListItemSelector( diff --git a/lib/router.dart b/lib/router.dart index a08f78e4d..638329ae8 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -759,12 +759,9 @@ Route createRoute(RouteSettings settings) { ); case Routes.unspentCoinsList: - final coinTypeToSpendFrom = settings.arguments as UnspentCoinType?; - return handleRouteWithPlatformAwareness( - (context) => FeatureFlag.hasNewUi - ? getIt.get(param1: coinTypeToSpendFrom) - : getIt.get(param1: coinTypeToSpendFrom), - ); + final args = settings.arguments as CoinControlPageArgs?; + return handleRouteWithPlatformAwareness((context) => + getIt.get(param1: args?.coinTypeToSpendFrom, param2: args?.canEdit)); case Routes.unspentCoinsDetails: final args = settings.arguments as List; diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart index 2a8c537e8..883814617 100644 --- a/lib/src/screens/settings/privacy_page.dart +++ b/lib/src/screens/settings/privacy_page.dart @@ -1,6 +1,7 @@ import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_regular_row.dart'; import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item_toggle.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/new-ui/pages/coin_control_page.dart'; import 'package:cake_wallet/new-ui/widgets/modal_header.dart'; import 'package:cake_wallet/new-ui/widgets/modal_page_wrapper.dart'; import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; @@ -95,7 +96,7 @@ class PrivacyPage extends BasePage { keyValue: "coin_control", label: "Coin Control", onTap: () => - Navigator.of(context).pushNamed(Routes.unspentCoinsList)), + Navigator.of(context).pushNamed(Routes.unspentCoinsList, arguments: CoinControlPageArgs(canEdit: false, coinTypeToSpendFrom: null))), ], } ), diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 964255cac..b7f1832fd 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -208,6 +208,7 @@ "close": "Close", "coin_control": "Coin Control (optional)", "coin_control_desc": "Filter outputs for this transaction. The changes you make here will only reflect on the current transaction.", + "coin_control_desc_no_edit": "Freeze outputs if needed. The changes will be persistent across all transactions. You can also filter outputs for one transaction on the Send or Swap screens.", "coin_control_load_failed": "Failed to load unspent coins", "cold_or_recover_wallet": "Add an air-gapped cold wallet or recover a paper wallet.", "collection_address": "Collection Address",