dev
dart 280 lines 10 KB
Raw
1 import 'package:cake_wallet/generated/i18n.dart';
2 import 'package:cake_wallet/src/widgets/setting_action_button.dart';
3 import 'package:cake_wallet/src/widgets/setting_actions.dart';
4 import 'package:flutter/material.dart';
5 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
6 import 'package:cw_core/wallet_type.dart';
7 import 'package:flutter_mobx/flutter_mobx.dart';
8
9 class MenuWidget extends StatefulWidget {
10 MenuWidget(this.dashboardViewModel, Key? key);
11
12 final DashboardViewModel dashboardViewModel;
13
14 @override
15 MenuWidgetState createState() => MenuWidgetState();
16 }
17
18 class MenuWidgetState extends State<MenuWidget> {
19 MenuWidgetState()
20 : this.menuWidth = 0,
21 this.screenWidth = 0,
22 this.screenHeight = 0,
23 this.headerHeight = 120,
24 this.tileHeight = 60,
25 this.fromTopEdge = 50,
26 this.fromBottomEdge = 25,
27 this.moneroIcon = Image.asset('assets/new-ui/crypto_full_icons/monero.svg'),
28 this.bitcoinIcon = Image.asset('assets/new-ui/crypto_full_icons/bitcoin.svg'),
29 this.litecoinIcon = Image.asset('assets/new-ui/crypto_full_icons/litecoin.svg'),
30 this.havenIcon = Image.asset('assets/images/haven_menu.webp'),
31 this.ethereumIcon = Image.asset('assets/new-ui/crypto_full_icons/ethereum.svg'),
32 this.nanoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg'),
33 this.bananoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg'),
34 this.bitcoinCashIcon = Image.asset('assets/new-ui/crypto_full_icons/bitcoin-cash.svg'),
35 this.polygonIcon = Image.asset('assets/new-ui/crypto_full_icons/polygon.svg'),
36 this.baseIcon = Image.asset('assets/new-ui/crypto_full_icons/base.svg'),
37 this.arbitrumIcon = Image.asset('assets/new-ui/crypto_full_icons/arbitrum.svg'),
38 this.bscIcon = Image.asset('assets/new-ui/crypto_full_icons/bnb.svg'),
39 this.solanaIcon = Image.asset('assets/new-ui/crypto_full_icons/solana.svg'),
40 this.tronIcon = Image.asset('assets/new-ui/crypto_full_icons/tron.svg'),
41 this.wowneroIcon = Image.asset('assets/new-ui/crypto_full_icons/wownero.svg'),
42 this.zanoIcon = Image.asset('assets/new-ui/crypto_full_icons/zano.svg'),
43 this.decredIcon = Image.asset('assets/new-ui/crypto_full_icons/decred.svg'),
44 this.dogecoinIcon = Image.asset('assets/new-ui/crypto_full_icons/dogecoin.svg'),
45 this.zcashIcon = Image.asset('assets/new-ui/crypto_full_icons/zcash.svg');
46
47 final largeScreen = 731;
48
49 double menuWidth;
50 double screenWidth;
51 double screenHeight;
52
53 double headerHeight;
54 double tileHeight;
55 double fromTopEdge;
56 double fromBottomEdge;
57
58 Image moneroIcon;
59 Image bitcoinIcon;
60 Image litecoinIcon;
61 Image havenIcon;
62 Image ethereumIcon;
63 Image bitcoinCashIcon;
64 Image nanoIcon;
65 Image bananoIcon;
66 Image polygonIcon;
67 Image baseIcon;
68 Image arbitrumIcon;
69 Image bscIcon;
70 Image solanaIcon;
71 Image tronIcon;
72 Image wowneroIcon;
73 Image zanoIcon;
74 Image decredIcon;
75 Image dogecoinIcon;
76 Image zcashIcon;
77
78 @override
79 void initState() {
80 menuWidth = 0;
81 screenWidth = 0;
82 screenHeight = 0;
83
84 headerHeight = 120;
85 tileHeight = 60;
86 fromTopEdge = 50;
87 fromBottomEdge = 25;
88
89 super.initState();
90 WidgetsBinding.instance.addPostFrameCallback(afterLayout);
91 }
92
93 void afterLayout(dynamic _) {
94 screenWidth = MediaQuery.of(context).size.width;
95 screenHeight = MediaQuery.of(context).size.height;
96
97 setState(() {
98 menuWidth = screenWidth;
99
100 if (screenHeight > largeScreen) {
101 final scale = screenHeight / largeScreen;
102 tileHeight *= scale;
103 headerHeight *= scale;
104 fromTopEdge *= scale;
105 fromBottomEdge *= scale;
106 }
107 });
108 }
109
110 @override
111 Widget build(BuildContext context) {
112 List<SettingActions> items = List.of(SettingActions.all);
113 if (!widget.dashboardViewModel.hasSilentPayments) {
114 items.removeWhere(
115 (element) => element.name(context) == S.of(context).silent_payments_settings);
116 }
117 if (!widget.dashboardViewModel.isMoneroViewOnly) {
118 items.removeWhere((element) => element.name(context) == S.of(context).export_outputs);
119 }
120 if (!widget.dashboardViewModel.hasMweb) {
121 items.removeWhere((element) => element.name(context) == S.of(context).litecoin_mweb_settings);
122 }
123 int itemCount = items.length;
124
125 moneroIcon = Image.asset('assets/new-ui/crypto_full_icons/monero.svg');
126 bitcoinIcon = Image.asset('assets/new-ui/crypto_full_icons/bitcoin.svg');
127
128 return Row(
129 mainAxisSize: MainAxisSize.max,
130 crossAxisAlignment: CrossAxisAlignment.center,
131 children: <Widget>[
132 Padding(
133 padding: EdgeInsets.only(left: 24),
134 child: Container(
135 height: 60,
136 width: 4,
137 decoration: BoxDecoration(
138 borderRadius: BorderRadius.all(Radius.circular(2)),
139 color: Theme.of(context).colorScheme.outline,
140 ),
141 ),
142 ),
143 SizedBox(width: 12),
144 Expanded(
145 child: ClipRRect(
146 borderRadius: BorderRadius.only(
147 topLeft: Radius.circular(24),
148 bottomLeft: Radius.circular(24),
149 ),
150 child: Container(
151 color: Theme.of(context).colorScheme.surface,
152 child: ListView.separated(
153 padding: EdgeInsets.only(top: 0),
154 itemBuilder: (_, index) {
155 if (index == 0) {
156 return Container(
157 height: headerHeight,
158 decoration: BoxDecoration(
159 borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24)),
160 color: Theme.of(context).colorScheme.surface,
161 ),
162 padding: EdgeInsets.only(
163 left: 24,
164 top: fromTopEdge,
165 right: 24,
166 bottom: fromBottomEdge,
167 ),
168 child: Row(
169 mainAxisAlignment: MainAxisAlignment.start,
170 children: <Widget>[
171 _iconFor(type: widget.dashboardViewModel.type),
172 SizedBox(width: 12),
173 SingleChildScrollView(
174 child: Container(
175 child: Column(
176 crossAxisAlignment: CrossAxisAlignment.start,
177 mainAxisAlignment: widget.dashboardViewModel.subname.isNotEmpty
178 ? MainAxisAlignment.spaceBetween
179 : MainAxisAlignment.center,
180 children: <Widget>[
181 Text(
182 widget.dashboardViewModel.name,
183 style: Theme.of(context).textTheme.bodyLarge?.copyWith(
184 fontWeight: FontWeight.w700,
185 ),
186 ),
187 if (widget.dashboardViewModel.subname.isNotEmpty)
188 Observer(
189 builder: (_) => Text(
190 widget.dashboardViewModel.subname,
191 style: Theme.of(context).textTheme.bodySmall?.copyWith(
192 color: Theme.of(context).colorScheme.onSurfaceVariant,
193 fontWeight: FontWeight.w500,
194 ),
195 ),
196 ),
197 ],
198 ),
199 ),
200 ),
201 ],
202 ),
203 );
204 }
205
206 index--;
207
208 final item = items[index];
209 final isLastTile = index == itemCount - 1;
210
211 return SettingActionButton(
212 key: item.key,
213 isLastTile: isLastTile,
214 tileHeight: tileHeight,
215 selectionActive: false,
216 fromBottomEdge: fromBottomEdge,
217 fromTopEdge: fromTopEdge,
218 onTap: () => item.onTap.call(context),
219 image: item.image,
220 title: item.name.call(context),
221 );
222 },
223 separatorBuilder: (_, index) => Container(
224 height: 0,
225 color: Theme.of(context).colorScheme.outline,
226 ),
227 itemCount: itemCount + 1,
228 ),
229 ),
230 ),
231 ),
232 ],
233 );
234 }
235
236 Widget _iconFor({required WalletType type}) {
237 switch (type) {
238 case WalletType.monero:
239 return moneroIcon;
240 case WalletType.bitcoin:
241 return bitcoinIcon;
242 case WalletType.litecoin:
243 return litecoinIcon;
244 case WalletType.haven:
245 return havenIcon;
246 case WalletType.ethereum:
247 return ethereumIcon;
248 case WalletType.bitcoinCash:
249 return bitcoinCashIcon;
250 case WalletType.nano:
251 return nanoIcon;
252 case WalletType.banano:
253 return bananoIcon;
254 case WalletType.polygon:
255 return polygonIcon;
256 case WalletType.solana:
257 return solanaIcon;
258 case WalletType.base:
259 return baseIcon;
260 case WalletType.arbitrum:
261 return arbitrumIcon;
262 case WalletType.bsc:
263 return bscIcon;
264 case WalletType.tron:
265 return tronIcon;
266 case WalletType.wownero:
267 return wowneroIcon;
268 case WalletType.zano:
269 return zanoIcon;
270 case WalletType.decred:
271 return decredIcon;
272 case WalletType.dogecoin:
273 return dogecoinIcon;
274 case WalletType.zcash:
275 return zcashIcon;
276 default:
277 throw Exception('No icon for ${type.toString()}');
278 }
279 }
280 }