diff --git a/lib/new-ui/pages/receive_page.dart b/lib/new-ui/pages/receive_page.dart index 1f6655701..764393e3b 100644 --- a/lib/new-ui/pages/receive_page.dart +++ b/lib/new-ui/pages/receive_page.dart @@ -165,8 +165,10 @@ class _NewReceivePageState extends State { final hasLabel = _addressItemWithLabel?.name != null && _addressItemWithLabel!.name!.isNotEmpty; final infoboxDismissed = widget.addressListViewModel.wallet.walletInfo.receiveInfoboxDismissed; final infobox = ReceiveInfoBox.forWalletType(widget.addressListViewModel.type, - onDismissed: () { - widget.addressListViewModel.dismissInfobox(); + supportedCurrencies: widget.addressListViewModel.tokenCurrencies + .whereType() + .toList(), onDismissed: () { + widget.addressListViewModel.dismissInfobox(); setState(() {}); }, autoGenerateSubaddressStatus: widget.lightningMode ? AutoGenerateSubaddressStatus.disabled : widget.dashboardViewModel.settingsStore.autoGenerateSubaddressStatus); diff --git a/lib/new-ui/widgets/receive_page/receive_info_box.dart b/lib/new-ui/widgets/receive_page/receive_info_box.dart index 9b6b65dfd..0b9bc6959 100644 --- a/lib/new-ui/widgets/receive_page/receive_info_box.dart +++ b/lib/new-ui/widgets/receive_page/receive_info_box.dart @@ -1,15 +1,17 @@ +import 'dart:math'; + import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/widgets/cake_image_widget.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; class ReceiveInfoBox extends StatelessWidget { ReceiveInfoBox( - {super.key, required this.iconPath, required this.message, required this.onDismissed}); + {super.key, required this.iconPath, required this.message, required this.onDismissed, this.bottomWidget}); - static ReceiveInfoBox? forWalletType(WalletType type, {required VoidCallback onDismissed, required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus}) { + static ReceiveInfoBox? forWalletType(WalletType type, {required VoidCallback onDismissed, required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus, List? supportedCurrencies}) { switch (type) { case WalletType.nano: return null; @@ -24,11 +26,15 @@ class ReceiveInfoBox extends StatelessWidget { if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled) return null; return ReceiveInfoBox( - iconPath: "assets/new-ui/chain_badges/${walletTypeToString(type).toLowerCase()}.svg", + iconPath: "", message: "${S.current.infobox_multichain} ${walletTypeToString(type)}", onDismissed: onDismissed, - ); + bottomWidget: InfoboxCurrencyRow( + currencies: supportedCurrencies ?? [], + chainIconPath: + "assets/new-ui/chain_badges/${walletTypeToString(type).toLowerCase()}.svg", + )); default: if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled) return null; @@ -42,6 +48,7 @@ class ReceiveInfoBox extends StatelessWidget { late final String iconPath; late final String message; + final Widget? bottomWidget; final VoidCallback onDismissed; @override @@ -58,6 +65,7 @@ class ReceiveInfoBox extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 10, children: [ + if(iconPath.isNotEmpty) CakeImageWidget(imageUrl: iconPath, width: 16, @@ -79,15 +87,21 @@ class ReceiveInfoBox extends StatelessWidget { fontSize: 12, fontWeight: FontWeight.w300), ), - GestureDetector( - onTap: onDismissed, - child: Text( - S.of(context).dismiss, - style: TextStyle( - color: Theme.of(context).colorScheme.primary, - fontSize: 12, - fontWeight: FontWeight.w300), - )) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (bottomWidget != null) bottomWidget!, + GestureDetector( + onTap: onDismissed, + child: Text( + S.of(context).dismiss, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontSize: 12, + fontWeight: FontWeight.w300), + )), + ], + ) ]), ) ], @@ -97,3 +111,85 @@ class ReceiveInfoBox extends StatelessWidget { ); } } + +class InfoboxCurrencyRow extends StatelessWidget { + const InfoboxCurrencyRow({super.key, required this.currencies, required this.chainIconPath}); + + final String chainIconPath; + final List currencies; + + static const overlap = 16.0; + static const iconSize = 24.0; + static const maxCurrencies = 4; + static const iconBorder = 1.5; + + @override + Widget build(BuildContext context) { + final currenciesWithImage = currencies.where((item)=>item.iconPath != null).toList(); + final currenciesLimited = currenciesWithImage.sublist(0, min(currenciesWithImage.length, maxCurrencies)); + + final double stackWidth = iconSize + (overlap * (currenciesLimited.length)); + + return Row( + spacing: 8, + children: [ + CakeImageWidget( + imageUrl: chainIconPath, + width: 20, + height: 20, + colorFilter: + ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn), + ), + Container( + height: 28, + width: 1, + color: Theme.of(context).colorScheme.surfaceContainerHigh, + ), + SizedBox( + height: iconSize + iconBorder * 2, + width: stackWidth, + child: Stack( + children: [ + Positioned( + top: iconBorder, + left: overlap * currenciesLimited.length, + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.white.withAlpha(25), + borderRadius: BorderRadius.circular(9999999)), + child: Icon( + Icons.add, + size: 16, + color: Colors.white.withAlpha(128), + ), + ), + ), + ...currenciesLimited + .asMap() + .entries + .map((entry) => Positioned( + left: 16.0 * entry.key, + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.surfaceContainer, + width: iconBorder), + borderRadius: BorderRadius.circular(9999999)), + child: CakeImageWidget( + imageUrl: entry.value.iconPath, + width: 24, + height: 24, + ), + ), + )) + .toList() + .reversed, + ], + ), + ) + ], + ); + } +}