dev
dart 243 lines 7.65 KB
Raw
1 import "package:cake_wallet/generated/i18n.dart";
2 import "package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart";
3 import "package:cake_wallet/src/widgets/cake_image_widget.dart";
4 import "package:cw_core/currency_for_wallet_type.dart";
5 import "package:flutter/material.dart";
6
7 class RecipientNetworkItem {
8 const RecipientNetworkItem({
9 required this.chainId,
10 required this.name,
11 required this.iconPath,
12 this.chainBadgeIconPath,
13 });
14
15 final int chainId;
16 final String name;
17 final String iconPath;
18 final String? chainBadgeIconPath;
19 }
20
21 class SelectRecipientNetworkSheet extends StatelessWidget {
22 const SelectRecipientNetworkSheet({
23 super.key,
24 required this.networks,
25 required this.currentChainId,
26 });
27
28 final List<RecipientNetworkItem> networks;
29 final int currentChainId;
30
31 static Future<int?> show({
32 required BuildContext context,
33 required List<RecipientNetworkItem> networks,
34 required int currentChainId,
35 }) {
36 return showModalBottomSheet<int>(
37 context: context,
38 isScrollControlled: true,
39 useSafeArea: true,
40 enableDrag: false,
41 isDismissible: false,
42 backgroundColor: Colors.transparent,
43 builder: (_) => SelectRecipientNetworkSheet(
44 networks: networks,
45 currentChainId: currentChainId,
46 ),
47 );
48 }
49
50 @override
51 Widget build(BuildContext context) {
52 final colors = Theme.of(context).colorScheme;
53
54 RecipientNetworkItem? current;
55 final compatible = <RecipientNetworkItem>[];
56 for (final network in networks) {
57 if (network.chainId == currentChainId && current == null) {
58 current = network;
59 } else {
60 compatible.add(network);
61 }
62 }
63
64 return Container(
65 decoration: BoxDecoration(
66 borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
67 color: colors.surface,
68 ),
69 child: SafeArea(
70 top: false,
71 child: Column(
72 children: [
73 ModalTopBar(
74 title: "",
75 trailingIcon: const Icon(Icons.close),
76 onTrailingPressed: () => Navigator.of(context).maybePop(),
77 ),
78 const SizedBox(height: 32),
79 CakeImageWidget(
80 imageUrl: "assets/new-ui/network_cube.svg",
81 width: 75,
82 height: 75,
83 colorFilter: ColorFilter.mode(colors.onSurfaceVariant, BlendMode.srcIn),
84 ),
85 const SizedBox(height: 24),
86 Text(
87 S.of(context).select_recipient_network,
88 textAlign: TextAlign.center,
89 style: Theme.of(context)
90 .textTheme
91 .titleLarge
92 ?.copyWith(fontSize: 20, fontWeight: FontWeight.w500, letterSpacing: -0.1),
93 ),
94 const SizedBox(height: 24),
95 Padding(
96 padding: const EdgeInsets.symmetric(horizontal: 32),
97 child: Text(
98 S.of(context).select_recipient_network_description,
99 textAlign: TextAlign.center,
100 style: Theme.of(context)
101 .textTheme
102 .bodyMedium
103 ?.copyWith(color: colors.onSurfaceVariant, letterSpacing: -0.07),
104 ),
105 ),
106 const SizedBox(height: 32),
107 Flexible(
108 child: SingleChildScrollView(
109 padding: const EdgeInsets.symmetric(horizontal: 16),
110 child: Column(
111 crossAxisAlignment: CrossAxisAlignment.start,
112 children: [
113 if (current != null) ...[
114 NetworkListCard(
115 rows: [
116 RecipientNetworkListRow(
117 item: current,
118 subtitle: S.of(context).current_network,
119 onTap: () => Navigator.of(context).pop(current!.chainId),
120 ),
121 ],
122 ),
123 const SizedBox(height: 24),
124 ],
125 if (compatible.isNotEmpty) ...[
126 Text(
127 S.of(context).compatible_networks,
128 style: Theme.of(context)
129 .textTheme
130 .bodySmall
131 ?.copyWith(color: colors.onSurfaceVariant, letterSpacing: -0.06),
132 ),
133 const SizedBox(height: 12),
134 NetworkListCard(
135 rows: [
136 for (final network in compatible)
137 RecipientNetworkListRow(
138 item: network,
139 onTap: () => Navigator.of(context).pop(network.chainId),
140 ),
141 ],
142 ),
143 ],
144 const SizedBox(height: 16),
145 ],
146 ),
147 ),
148 ),
149 ],
150 ),
151 ),
152 );
153 }
154 }
155
156 class NetworkListCard extends StatelessWidget {
157 const NetworkListCard({required this.rows});
158
159 final List<Widget> rows;
160
161 @override
162 Widget build(BuildContext context) {
163 final colors = Theme.of(context).colorScheme;
164 return Container(
165 decoration: BoxDecoration(
166 color: colors.surfaceContainer,
167 borderRadius: BorderRadius.circular(20),
168 ),
169 clipBehavior: Clip.antiAlias,
170 child: Column(
171 mainAxisSize: MainAxisSize.min,
172 children: [
173 for (var i = 0; i < rows.length; i++) ...[
174 rows[i],
175 if (i != rows.length - 1)
176 Divider(
177 height: 1,
178 thickness: 1,
179 color: colors.surfaceContainerHigh,
180 indent: 48,
181 endIndent: 12,
182 ),
183 ],
184 ],
185 ),
186 );
187 }
188 }
189
190 class RecipientNetworkListRow extends StatelessWidget {
191 const RecipientNetworkListRow(
192 {super.key, required this.item, required this.onTap, this.subtitle, this.imageOverride});
193
194 final String? subtitle;
195 final String? imageOverride;
196 final VoidCallback onTap;
197 final RecipientNetworkItem item;
198
199 @override
200 Widget build(BuildContext context) {
201 final colors = Theme.of(context).colorScheme;
202 return InkWell(
203 onTap: onTap,
204 child: Padding(
205 padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
206 child: Row(
207 children: [
208 CakeImageWidget(
209 imageUrl: imageOverride ?? item.iconPath,
210 width: 24,
211 height: 24,
212 fit: BoxFit.cover,
213 color: isMonochromeSymbolIcon(imageOverride ?? item.iconPath) ? colors.primary : null,
214 ),
215 const SizedBox(width: 12),
216 Expanded(
217 child: Column(
218 crossAxisAlignment: CrossAxisAlignment.start,
219 spacing: 4,
220 children: [
221 Text(
222 item.name,
223 style: Theme.of(context)
224 .textTheme
225 .bodyMedium
226 ?.copyWith(fontWeight: FontWeight.w400, letterSpacing: -0.07),
227 ),
228 if (subtitle != null)
229 Text(
230 subtitle!,
231 style: Theme.of(context).textTheme.bodySmall?.copyWith(
232 color: colors.onSurfaceVariant, letterSpacing: -0.06, fontSize: 12),
233 ),
234 ],
235 ),
236 ),
237 Icon(Icons.chevron_right, size: 16, color: colors.onSurfaceVariant),
238 ],
239 ),
240 ),
241 );
242 }
243 }