From 7c321faf2fd5b21c86b5813c0aee73e3a88093b8 Mon Sep 17 00:00:00 2001 From: David Adegoke <64401859+Blazebrain@users.noreply.github.com> Date: Sat, 6 Jun 2026 13:34:56 +0100 Subject: [PATCH] Release fixes (#3301) * fix: Solana GMT token showing the wrong decimal place * add badge icon to swap confirm sheet, also address book chain icons display correctly * missing mask icon for mweb --- .../list_item/list_item_regular_row.dart | 4 + .../send_page/l2_action_wallet_selector.dart | 19 ++-- .../widgets/swap_page/swap_confirm_sheet.dart | 23 ++++ .../list_item_regular_row_widget.dart | 107 +++++++++++------- .../new_list_row/new_list_section.dart | 2 + 5 files changed, 105 insertions(+), 50 deletions(-) diff --git a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart index b86632124..4660199ff 100644 --- a/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart +++ b/lib/entities/new_ui_entities/list_item/list_item_regular_row.dart @@ -8,6 +8,7 @@ class ListItemRegularRow extends ListItem { this.subtitle, this.trailingText, this.iconPath, + this.badgeIconPath, this.onTap, this.trailingIconPath, this.showArrow = true, @@ -19,6 +20,7 @@ class ListItemRegularRow extends ListItem { this.copyableText, this.leadingIconErrorWidget, this.leadingIconSize, + this.badgeIconSize, this.iconColor, }); @@ -26,6 +28,7 @@ class ListItemRegularRow extends ListItem { final String? trailingText; final String? iconPath; final String? trailingIconPath; + final String? badgeIconPath; final String? copyableText; final VoidCallback? onTap; final bool showArrow; @@ -36,5 +39,6 @@ class ListItemRegularRow extends ListItem { final double? trailingIconSize; final Widget? leadingIconErrorWidget; final double? leadingIconSize; + final double? badgeIconSize; final Color? iconColor; } diff --git a/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart b/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart index 6a9aa35c8..94e8c1909 100644 --- a/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart +++ b/lib/new-ui/widgets/send_page/l2_action_wallet_selector.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/main.dart'; +import 'package:cake_wallet/new-ui/widgets/coins_page/token_image_widget.dart'; import 'package:cake_wallet/new-ui/widgets/new_primary_button.dart'; import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart'; import 'package:cake_wallet/new-ui/widgets/send_page/l2_send_external_modal.dart'; @@ -56,8 +57,8 @@ class _L2ActionWalletSelectorState extends State { super.initState(); if (widget.showOtherWallets) { () async { - items.addAll((await WalletInfo.getAll()) - .where((item) => item.type == widget.sendViewModel.walletType && item.hardwareWalletType == null)); + items.addAll((await WalletInfo.getAll()).where((item) => + item.type == widget.sendViewModel.walletType && item.hardwareWalletType == null)); items.sort((a, b) { if (a.name == widget.sendViewModel.wallet.name) return -1; @@ -125,8 +126,7 @@ class _L2ActionWalletSelectorState extends State { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: WalletRow( - currencyIconPath: - getCryptoCurrencyIconForWalletListItem(item.type), + currencyIconPath: getCryptoCurrencyIconForWalletListItem(item.type), walletName: item.name, isCurrent: item.name == widget.sendViewModel.wallet.name, isSelected: _selectedWalletIndex == index && !textEntered, @@ -252,8 +252,8 @@ class _L2ActionWalletSelectorState extends State { mainAxisAlignment: MainAxisAlignment.center, spacing: 10, children: [ - CakeImageWidget(imageUrl: - "assets/new-ui/send_from_external.svg", + CakeImageWidget( + imageUrl: "assets/new-ui/send_from_external.svg", colorFilter: ColorFilter.mode( Theme.of(context).colorScheme.primary, BlendMode.srcIn), ), @@ -378,10 +378,9 @@ class WalletRow extends StatelessWidget { Row( spacing: 12, children: [ - Image.asset( - currencyIconPath, - height: 24, - width: 24, + TokenImageWidget( + imageUrl: currencyIconPath, + size: 24, ), Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/new-ui/widgets/swap_page/swap_confirm_sheet.dart b/lib/new-ui/widgets/swap_page/swap_confirm_sheet.dart index 3676cd6e4..ede917cee 100644 --- a/lib/new-ui/widgets/swap_page/swap_confirm_sheet.dart +++ b/lib/new-ui/widgets/swap_page/swap_confirm_sheet.dart @@ -14,7 +14,10 @@ import 'package:cake_wallet/src/widgets/new_list_row/new_list_section.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/currencies_with_memo.dart'; +import 'package:cw_core/currency_for_wallet_type.dart'; +import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -160,6 +163,7 @@ class SwapTransactionDetails extends StatelessWidget { keyValue: "send value", label: exchangeViewModel.depositCurrency.fullName ?? "", iconPath: exchangeViewModel.depositCurrency.iconPath ?? "", + badgeIconPath: _resolveChainBadgePath(exchangeViewModel.depositCurrency), trailingText: exchangeTradeViewModel.trade.amountFormatted() + " " + (exchangeViewModel.depositCurrency.title)), @@ -184,6 +188,7 @@ class SwapTransactionDetails extends StatelessWidget { keyValue: "receive value", label: exchangeViewModel.receiveCurrency.fullName ?? "", iconPath: exchangeViewModel.receiveCurrency.iconPath ?? "", + badgeIconPath: _resolveChainBadgePath(exchangeViewModel.receiveCurrency), trailingText: (receiveAmount) + " " + (exchangeViewModel.receiveCurrency.title)), ListItemRegularRow( @@ -272,3 +277,21 @@ class SwapTransactionDetails extends StatelessWidget { } } } + +String? _resolveChainBadgePath(CryptoCurrency currency) { + try { + if (currency.chainIconPath != null) return currency.chainIconPath; + + final tag = currency.tag; + if (tag != null && tag.isNotEmpty) { + final byTag = CryptoCurrency.fromString(tag); + if (byTag.chainIconPath != null) return byTag.chainIconPath; + } + + final walletType = cryptoCurrencyOrTokenToWalletType(currency); + if (walletType != null) { + return walletTypeToCryptoCurrency(walletType).chainIconPath; + } + } catch (_) {} + return null; +} diff --git a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart index 962cb87d1..b2301b881 100644 --- a/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart +++ b/lib/src/widgets/new_list_row/list_item_regular_row_widget.dart @@ -6,34 +6,36 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class ListItemRegularRowWidget extends StatelessWidget { - const ListItemRegularRowWidget({ - super.key, - required this.keyValue, - required this.label, - this.subtitle, - this.trailingText, - this.iconPath, - this.onTap, - this.isFirstInSection = false, - this.isLastInSection = false, - this.showArrow = true, - this.trailingIconPath, - this.truncateTrailingText = false, - this.foregroundColor, - this.trailingIconSize, - this.bottomWidget, - this.trailingWidget, - this.copyableText, - this.leadingIconErrorWidget, - this.leadingIconSize, - this.iconColor - }); + const ListItemRegularRowWidget( + {super.key, + required this.keyValue, + required this.label, + this.subtitle, + this.trailingText, + this.iconPath, + this.badgeIconPath, + this.onTap, + this.isFirstInSection = false, + this.isLastInSection = false, + this.showArrow = true, + this.trailingIconPath, + this.truncateTrailingText = false, + this.foregroundColor, + this.trailingIconSize, + this.bottomWidget, + this.trailingWidget, + this.copyableText, + this.leadingIconErrorWidget, + this.leadingIconSize, + this.badgeIconSize, + this.iconColor}); final String keyValue; final String label; final String? subtitle; final String? trailingText; final String? iconPath; + final String? badgeIconPath; final VoidCallback? onTap; final bool isFirstInSection; final bool isLastInSection; @@ -47,6 +49,7 @@ class ListItemRegularRowWidget extends StatelessWidget { final String? copyableText; final Widget? leadingIconErrorWidget; final double? leadingIconSize; + final double? badgeIconSize; final Color? iconColor; @override @@ -69,6 +72,38 @@ class ListItemRegularRowWidget extends StatelessWidget { isFirstInSection: isFirstInSection, isLastInSection: isLastInSection, builder: (context, textStyle, labelStyle) { + final leadingIcon = iconPath != null + ? CakeImageWidget( + imageUrl: iconPath!, + width: leadingIconSize ?? 24, + height: leadingIconSize ?? 24, + errorWidget: leadingIconErrorWidget, + colorFilter: + iconColor == null ? null : ColorFilter.mode(iconColor!, BlendMode.srcIn), + ) + : null; + + final imageWidget = badgeIconPath != null + ? Stack( + clipBehavior: Clip.none, + children: [ + leadingIcon!, + Positioned( + right: -3, + bottom: -3, + child: CakeImageWidget( + imageUrl: badgeIconPath!, + width: badgeIconSize ?? 10, + height: badgeIconSize ?? 10, + errorWidget: leadingIconErrorWidget, + colorFilter: iconColor == null + ? null + : ColorFilter.mode(iconColor!, BlendMode.srcIn), + ), + ), + ], + ) + : leadingIcon; return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, @@ -81,16 +116,9 @@ class ListItemRegularRowWidget extends StatelessWidget { children: [ if (iconPath != null) Padding( - padding: const EdgeInsets.only(right: 12.0), - child: CakeImageWidget( - imageUrl: iconPath!, - width: leadingIconSize ?? 24, - height: leadingIconSize ?? 24, - errorWidget: leadingIconErrorWidget, - colorFilter: iconColor == null - ? null - : ColorFilter.mode(iconColor!, BlendMode.srcIn), - )), + padding: const EdgeInsets.only(right: 12.0), + child: imageWidget ?? SizedBox(), + ), Flexible( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -140,14 +168,13 @@ class ListItemRegularRowWidget extends StatelessWidget { BlendMode.srcIn), ) else if (showArrow) - Padding( - padding: const EdgeInsets.symmetric(vertical: 7.0), - child: CakeImageWidget(imageUrl: - "assets/new-ui/arrow_forward.svg", - height: 14, - color: theme.colorScheme.onSurfaceVariant - ), - ) + Padding( + padding: const EdgeInsets.symmetric(vertical: 7.0), + child: CakeImageWidget( + imageUrl: "assets/new-ui/arrow_forward.svg", + height: 14, + color: theme.colorScheme.onSurfaceVariant), + ) ], ), ], diff --git a/lib/src/widgets/new_list_row/new_list_section.dart b/lib/src/widgets/new_list_row/new_list_section.dart index edc0b4eba..8abef379d 100644 --- a/lib/src/widgets/new_list_row/new_list_section.dart +++ b/lib/src/widgets/new_list_row/new_list_section.dart @@ -96,6 +96,7 @@ class NewListSections extends StatelessWidget { subtitle: item.subtitle, trailingText: item.trailingText, iconPath: item.iconPath, + badgeIconPath: item.badgeIconPath, trailingIconPath: item.trailingIconPath, onTap: tapHandlers[item.keyValue] ?? item.onTap, isFirstInSection: isFirst, @@ -109,6 +110,7 @@ class NewListSections extends StatelessWidget { bottomWidget: item.bottomWidget, leadingIconErrorWidget: item.leadingIconErrorWidget, leadingIconSize: item.leadingIconSize, + badgeIconSize: item.badgeIconSize, iconColor: item.iconColor, ); }