dev
dart 209 lines 7.63 KB
Raw
1 import 'package:cake_wallet/di.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/routes.dart';
4 import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart';
5 import 'package:cake_wallet/src/screens/nano_accounts/nano_account_list_page.dart';
6 import 'package:cake_wallet/src/screens/receive/widgets/address_cell.dart';
7 import 'package:cake_wallet/src/screens/receive/widgets/header_tile.dart';
8 import 'package:cake_wallet/src/widgets/section_divider.dart';
9 import 'package:cake_wallet/themes/core/material_base_theme.dart';
10 import 'package:cake_wallet/utils/list_item.dart';
11 import 'package:cake_wallet/utils/show_pop_up.dart';
12 import 'package:cake_wallet/view_model/wallet_address_list/wallet_account_list_header.dart';
13 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_hidden_list_header.dart';
14 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_header.dart';
15 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
16 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
17 import 'package:cw_core/wallet_type.dart';
18 import 'package:flutter/material.dart';
19 import 'package:flutter_mobx/flutter_mobx.dart';
20
21 class AddressList extends StatefulWidget {
22 const AddressList({super.key, required this.addressListViewModel, this.onSelect});
23
24 final WalletAddressListViewModel addressListViewModel;
25 final Function(String)? onSelect;
26
27 @override
28 State<AddressList> createState() => _AddressListState();
29 }
30
31 class _AddressListState extends State<AddressList> {
32 bool showHiddenAddresses = false;
33
34 void _toggleHiddenAddresses() {
35 setState(() {
36 showHiddenAddresses = !showHiddenAddresses;
37 });
38 updateItems();
39 }
40
41 List<ListItem> getItems(List<ListItem> list, bool showHidden) {
42 return list.where((element) {
43 if (element is WalletAddressListItem) {
44 if (showHidden && element.isHidden) return true;
45 if (!showHidden && !element.isHidden) return true;
46 return false;
47 }
48 return true;
49 }).toList();
50 }
51
52 List<ListItem> items = [];
53
54 void updateItems() {
55 setState(() {
56 items = getItems(widget.addressListViewModel.forceRecomputeItems, showHiddenAddresses);
57 });
58 }
59
60 @override
61 void initState() {
62 super.initState();
63
64 items = getItems(widget.addressListViewModel.items, showHiddenAddresses);
65 }
66
67 @override
68 Widget build(BuildContext context) {
69 bool editable = widget.onSelect == null;
70 return ListView.separated(
71 padding: EdgeInsets.all(0),
72 separatorBuilder: (context, _) => const HorizontalSectionDivider(),
73 shrinkWrap: true,
74 physics: NeverScrollableScrollPhysics(),
75 itemCount: items.length,
76 itemBuilder: (context, index) {
77 final item = items[index];
78 Widget cell = Container();
79
80 if (item is WalletAccountListHeader) {
81 cell = HeaderTile(
82 showTrailingButton: true,
83 walletAddressListViewModel: widget.addressListViewModel,
84 trailingButtonTap: () async {
85 if (widget.addressListViewModel.type == WalletType.monero ||
86 widget.addressListViewModel.type == WalletType.wownero ||
87 widget.addressListViewModel.type == WalletType.haven) {
88 await showPopUp<void>(
89 context: context,
90 builder: (_) => getIt.get<MoneroAccountListPage>(),
91 );
92 updateItems();
93 } else {
94 await showPopUp<void>(
95 context: context,
96 builder: (_) => getIt.get<NanoAccountListPage>(),
97 );
98 updateItems();
99 }
100 },
101 title: S.of(context).accounts,
102 trailingIcon: Icon(
103 Icons.arrow_forward_ios,
104 size: 14,
105 color: Theme.of(context).colorScheme.onSurfaceVariant,
106 ),
107 );
108 }
109
110 if (item is WalletAddressHiddenListHeader) {
111 cell = HeaderTile(
112 title: S.of(context).hidden_addresses,
113 walletAddressListViewModel: widget.addressListViewModel,
114 showTrailingButton: true,
115 showSearchButton: false,
116 trailingButtonTap: _toggleHiddenAddresses,
117 trailingIcon: Icon(
118 showHiddenAddresses ? Icons.toggle_on : Icons.toggle_off,
119 size: 20,
120 color: Theme.of(context).colorScheme.onSurfaceVariant,
121 ),
122 );
123 }
124
125 if (item is WalletAddressListHeader) {
126 cell = HeaderTile(
127 title: S.of(context).addresses,
128 walletAddressListViewModel: widget.addressListViewModel,
129 showTrailingButton: widget.addressListViewModel.showAddManualAddresses,
130 showSearchButton: true,
131 onSearchCallback: updateItems,
132 trailingButtonTap: () =>
133 Navigator.of(context).pushNamed(Routes.newSubaddress).then((value) {
134 updateItems(); // refresh the new address
135 }),
136 trailingIcon: Icon(
137 Icons.add,
138 size: 20,
139 color: Theme.of(context).colorScheme.onSurfaceVariant,
140 ),
141 );
142 }
143
144 if (item is WalletAddressListItem) {
145 if (item.isHidden && !showHiddenAddresses) {
146 cell = Container();
147 } else if (!item.isHidden && showHiddenAddresses) {
148 cell = Container();
149 } else {
150 cell = Observer(
151 builder: (_) {
152 final isCurrent =
153 item.address == widget.addressListViewModel.address.address && editable;
154 final backgroundColor = isCurrent
155 ? Theme.of(context).colorScheme.primary
156 : Theme.of(context).colorScheme.surface;
157 final textColor = isCurrent
158 ? Theme.of(context).colorScheme.onPrimary
159 : Theme.of(context).colorScheme.onSurface;
160
161 return AddressCell.fromItem(
162 item,
163 isCurrent: isCurrent,
164 walletType: widget.addressListViewModel.type,
165 hasBalance: widget.addressListViewModel.isBalanceAvailable,
166 hasReceived: widget.addressListViewModel.isReceivedAvailable,
167 // hasReceived:
168 backgroundColor: backgroundColor,
169 textColor: textColor,
170 onTap: (_) {
171 if (widget.onSelect != null) {
172 widget.onSelect!(item.address);
173 return;
174 }
175 widget.addressListViewModel.setAddress(item);
176 },
177 onEdit: editable
178 ? () => Navigator.of(context)
179 .pushNamed(Routes.newSubaddress, arguments: item)
180 .then((value) {
181 updateItems(); // refresh the new address
182 })
183 : null,
184 isHidden: item.isHidden,
185 onHide: () => _hideAddress(item),
186 );
187 },
188 );
189 }
190 }
191
192 return index != 0
193 ? cell
194 : ClipRRect(
195 borderRadius: BorderRadius.only(
196 topLeft: Radius.circular(30),
197 topRight: Radius.circular(30),
198 ),
199 child: cell,
200 );
201 },
202 );
203 }
204
205 void _hideAddress(WalletAddressListItem item) async {
206 await widget.addressListViewModel.toggleHideAddress(item);
207 updateItems();
208 }
209 }