show token row in receive infobox (#3211)
* show token row in receive infobox * fix showing currencies w/o image
malik1004x committed
May 6, 2026 at 21:48 UTC
cfb5da012eedbaaa4aa11a9f96b4be7fd4407498
2 files changed
+114
-16
lib/new-ui/pages/receive_page.dart
+4
-2
@@ -165,8 +165,10 @@ class _NewReceivePageState extends State<NewReceivePage> {
165
final hasLabel = _addressItemWithLabel?.name != null && _addressItemWithLabel!.name!.isNotEmpty;
166
final infoboxDismissed = widget.addressListViewModel.wallet.walletInfo.receiveInfoboxDismissed;
167
final infobox = ReceiveInfoBox.forWalletType(widget.addressListViewModel.type,
168
- onDismissed: () {
169
- widget.addressListViewModel.dismissInfobox();
168
+ supportedCurrencies: widget.addressListViewModel.tokenCurrencies
169
+ .whereType<CryptoCurrency>()
170
+ .toList(), onDismissed: () {
171
+ widget.addressListViewModel.dismissInfobox();
172
setState(() {});
173
}, autoGenerateSubaddressStatus: widget.lightningMode ? AutoGenerateSubaddressStatus.disabled : widget.dashboardViewModel.settingsStore.autoGenerateSubaddressStatus);
174
lib/new-ui/widgets/receive_page/receive_info_box.dart
+110
-14
@@ -1,15 +1,17 @@
1
+import 'dart:math';
2
+
3
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
4
import 'package:cake_wallet/generated/i18n.dart';
5
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
6
+import 'package:cw_core/crypto_currency.dart';
7
import 'package:cw_core/wallet_type.dart';
8
import 'package:flutter/material.dart';
6
-import 'package:flutter_svg/svg.dart';
9
10
class ReceiveInfoBox extends StatelessWidget {
11
ReceiveInfoBox(
10
- {super.key, required this.iconPath, required this.message, required this.onDismissed});
12
+ {super.key, required this.iconPath, required this.message, required this.onDismissed, this.bottomWidget});
13
12
- static ReceiveInfoBox? forWalletType(WalletType type, {required VoidCallback onDismissed, required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus}) {
14
+ static ReceiveInfoBox? forWalletType(WalletType type, {required VoidCallback onDismissed, required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus, List<CryptoCurrency>? supportedCurrencies}) {
15
switch (type) {
16
case WalletType.nano:
17
return null;
@@ -24,11 +26,15 @@ class ReceiveInfoBox extends StatelessWidget {
26
if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled)
27
return null;
28
return ReceiveInfoBox(
27
- iconPath: "assets/new-ui/chain_badges/${walletTypeToString(type).toLowerCase()}.svg",
29
+ iconPath: "",
30
message:
31
"${S.current.infobox_multichain} ${walletTypeToString(type)}",
32
onDismissed: onDismissed,
31
- );
33
+ bottomWidget: InfoboxCurrencyRow(
34
+ currencies: supportedCurrencies ?? [],
35
+ chainIconPath:
36
+ "assets/new-ui/chain_badges/${walletTypeToString(type).toLowerCase()}.svg",
37
+ ));
38
default:
39
if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled)
40
return null;
@@ -42,6 +48,7 @@ class ReceiveInfoBox extends StatelessWidget {
48
49
late final String iconPath;
50
late final String message;
51
+ final Widget? bottomWidget;
52
final VoidCallback onDismissed;
53
54
@override
@@ -58,6 +65,7 @@ class ReceiveInfoBox extends StatelessWidget {
65
crossAxisAlignment: CrossAxisAlignment.start,
66
spacing: 10,
67
children: [
68
+ if(iconPath.isNotEmpty)
69
CakeImageWidget(imageUrl:
70
iconPath,
71
width: 16,
@@ -79,15 +87,21 @@ class ReceiveInfoBox extends StatelessWidget {
87
fontSize: 12,
88
fontWeight: FontWeight.w300),
89
),
82
- GestureDetector(
83
- onTap: onDismissed,
84
- child: Text(
85
- S.of(context).dismiss,
86
- style: TextStyle(
87
- color: Theme.of(context).colorScheme.primary,
88
- fontSize: 12,
89
- fontWeight: FontWeight.w300),
90
- ))
90
+ Row(
91
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
92
+ children: [
93
+ if (bottomWidget != null) bottomWidget!,
94
+ GestureDetector(
95
+ onTap: onDismissed,
96
+ child: Text(
97
+ S.of(context).dismiss,
98
+ style: TextStyle(
99
+ color: Theme.of(context).colorScheme.primary,
100
+ fontSize: 12,
101
+ fontWeight: FontWeight.w300),
102
+ )),
103
+ ],
104
+ )
105
]),
106
)
107
],
@@ -97,3 +111,85 @@ class ReceiveInfoBox extends StatelessWidget {
111
);
112
}
113
}
114
+
115
+class InfoboxCurrencyRow extends StatelessWidget {
116
+ const InfoboxCurrencyRow({super.key, required this.currencies, required this.chainIconPath});
117
+
118
+ final String chainIconPath;
119
+ final List<CryptoCurrency> currencies;
120
+
121
+ static const overlap = 16.0;
122
+ static const iconSize = 24.0;
123
+ static const maxCurrencies = 4;
124
+ static const iconBorder = 1.5;
125
+
126
+ @override
127
+ Widget build(BuildContext context) {
128
+ final currenciesWithImage = currencies.where((item)=>item.iconPath != null).toList();
129
+ final currenciesLimited = currenciesWithImage.sublist(0, min(currenciesWithImage.length, maxCurrencies));
130
+
131
+ final double stackWidth = iconSize + (overlap * (currenciesLimited.length));
132
+
133
+ return Row(
134
+ spacing: 8,
135
+ children: [
136
+ CakeImageWidget(
137
+ imageUrl: chainIconPath,
138
+ width: 20,
139
+ height: 20,
140
+ colorFilter:
141
+ ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
142
+ ),
143
+ Container(
144
+ height: 28,
145
+ width: 1,
146
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
147
+ ),
148
+ SizedBox(
149
+ height: iconSize + iconBorder * 2,
150
+ width: stackWidth,
151
+ child: Stack(
152
+ children: [
153
+ Positioned(
154
+ top: iconBorder,
155
+ left: overlap * currenciesLimited.length,
156
+ child: Container(
157
+ width: 24,
158
+ height: 24,
159
+ decoration: BoxDecoration(
160
+ color: Colors.white.withAlpha(25),
161
+ borderRadius: BorderRadius.circular(9999999)),
162
+ child: Icon(
163
+ Icons.add,
164
+ size: 16,
165
+ color: Colors.white.withAlpha(128),
166
+ ),
167
+ ),
168
+ ),
169
+ ...currenciesLimited
170
+ .asMap()
171
+ .entries
172
+ .map((entry) => Positioned(
173
+ left: 16.0 * entry.key,
174
+ child: Container(
175
+ decoration: BoxDecoration(
176
+ border: Border.all(
177
+ color: Theme.of(context).colorScheme.surfaceContainer,
178
+ width: iconBorder),
179
+ borderRadius: BorderRadius.circular(9999999)),
180
+ child: CakeImageWidget(
181
+ imageUrl: entry.value.iconPath,
182
+ width: 24,
183
+ height: 24,
184
+ ),
185
+ ),
186
+ ))
187
+ .toList()
188
+ .reversed,
189
+ ],
190
+ ),
191
+ )
192
+ ],
193
+ );
194
+ }
195
+}