1
+import 'package:cake_wallet/core/new_wallet_arguments.dart';
2
+import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
3
import 'package:cake_wallet/entities/wallet_list_order_types.dart';
4
import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart';
5
+import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
6
+import 'package:cake_wallet/src/screens/wallet_list/edit_wallet_button_widget.dart';
7
import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart';
8
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
9
import 'package:cake_wallet/store/settings_store.dart';
11
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
12
import 'package:cake_wallet/core/auth_service.dart';
13
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
10
-import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
11
-import 'package:cake_wallet/utils/device_info.dart';
14
import 'package:cake_wallet/utils/responsive_layout_util.dart';
15
import 'package:cake_wallet/utils/show_bar.dart';
16
import 'package:cake_wallet/utils/show_pop_up.dart';
25
import 'package:cake_wallet/src/widgets/primary_button.dart';
26
import 'package:cake_wallet/src/screens/base_page.dart';
27
import 'package:cake_wallet/wallet_type_utils.dart';
26
-import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
28
29
class WalletListPage extends BasePage {
30
WalletListPage({required this.walletListViewModel, required this.authService});
129
child: Column(
130
children: [
131
Expanded(
131
- child: Container(
132
- child: Observer(
133
- builder: (_) => FilteredList(
134
- list: widget.walletListViewModel.wallets,
135
- updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
136
- itemBuilder: (__, index) {
137
- final wallet = widget.walletListViewModel.wallets[index];
138
- final currentColor = wallet.isCurrent
139
- ? Theme.of(context)
140
- .extension<WalletListTheme>()!
141
- .createNewWalletButtonBackgroundColor
142
- : Theme.of(context).colorScheme.background;
143
- final row = GestureDetector(
144
- key: ValueKey(wallet.name),
145
- onTap: () => wallet.isCurrent ? null : _loadWallet(wallet),
146
- child: Container(
147
- height: tileHeight,
148
- width: double.infinity,
149
- child: Row(
150
- children: <Widget>[
151
- Container(
152
- height: tileHeight,
153
- width: 4,
154
- decoration: BoxDecoration(
155
- borderRadius: BorderRadius.only(
156
- topRight: Radius.circular(4),
157
- bottomRight: Radius.circular(4)),
158
- color: currentColor),
159
- ),
160
- Expanded(
161
- child: Container(
162
- height: tileHeight,
163
- padding: EdgeInsets.only(left: 20, right: 20),
164
- color: Theme.of(context).colorScheme.background,
165
- alignment: Alignment.centerLeft,
166
- child: Row(
167
- crossAxisAlignment: CrossAxisAlignment.center,
168
- children: <Widget>[
169
- wallet.isEnabled
170
- ? _imageFor(
171
- type: wallet.type,
172
- isTestnet: wallet.isTestnet,
173
- )
174
- : nonWalletTypeIcon,
175
- SizedBox(width: 10),
176
- Flexible(
177
- child: Text(
178
- wallet.name,
179
- maxLines: null,
180
- softWrap: true,
181
- style: TextStyle(
182
- fontSize: DeviceInfo.instance.isDesktop ? 18 : 20,
183
- fontWeight: FontWeight.w500,
184
- color: Theme.of(context)
185
- .extension<CakeTextTheme>()!
186
- .titleColor,
187
- ),
188
- ),
132
+ child: SingleChildScrollView(
133
+ child: Column(
134
+ crossAxisAlignment: CrossAxisAlignment.start,
135
+ children: [
136
+ if (widget.walletListViewModel.multiWalletGroups.isNotEmpty) ...{
137
+ Padding(
138
+ padding: const EdgeInsets.only(left: 24),
139
+ child: Text(
140
+ S.current.shared_seed_wallet_groups,
141
+ style: TextStyle(
142
+ fontSize: 18,
143
+ fontWeight: FontWeight.w500,
144
+ color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
145
+ ),
146
+ ),
147
+ ),
148
+ SizedBox(height: 16),
149
+ Container(
150
+ child: Observer(
151
+ builder: (_) => FilteredList(
152
+ shrinkWrap: true,
153
+ list: widget.walletListViewModel.multiWalletGroups,
154
+ updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
155
+ itemBuilder: (context, index) {
156
+ final group = widget.walletListViewModel.multiWalletGroups[index];
157
+ final groupName = group.groupName ??
158
+ '${S.current.wallet_group} ${index + 1}';
159
+ return GroupedWalletExpansionTile(
160
+ borderRadius: BorderRadius.all(Radius.circular(16)),
161
+ margin: EdgeInsets.only(left: 20, right: 20, bottom: 12),
162
+ title: groupName,
163
+ tileKey: ValueKey('group_wallets_expansion_tile_widget_$index'),
164
+ leadingWidget: Icon(
165
+ Icons.account_balance_wallet_outlined,
166
+ size: 28,
167
+ ),
168
+ trailingWidget: EditWalletButtonWidget(
169
+ width: 74,
170
+ isGroup: true,
171
+ onTap: () {
172
+ final wallet = widget.walletListViewModel
173
+ .convertWalletInfoToWalletListItem(group.wallets.first);
174
+ Navigator.of(context).pushNamed(
175
+ Routes.walletEdit,
176
+ arguments: WalletEditPageArguments(
177
+ walletListViewModel: widget.walletListViewModel,
178
+ editingWallet: wallet,
179
+ isWalletGroup: true,
180
+ groupName: groupName,
181
+ parentAddress: group.parentAddress,
182
),
190
- ],
191
- ),
183
+ );
184
+ },
185
),
193
- ),
194
- ],
186
+ childWallets: group.wallets.map((walletInfo) {
187
+ return widget.walletListViewModel
188
+ .convertWalletInfoToWalletListItem(walletInfo);
189
+ }).toList(),
190
+ isSelected: false,
191
+ onChildItemTapped: (wallet) =>
192
+ wallet.isCurrent ? null : _loadWallet(wallet),
193
+ childTrailingWidget: (item) {
194
+ return item.isCurrent
195
+ ? SizedBox.shrink()
196
+ : EditWalletButtonWidget(
197
+ width: 44,
198
+ onTap: () => Navigator.of(context).pushNamed(
199
+ Routes.walletEdit,
200
+ arguments: WalletEditPageArguments(
201
+ walletListViewModel: widget.walletListViewModel,
202
+ editingWallet: item,
203
+ ),
204
+ ),
205
+ );
206
+ },
207
+ );
208
+ },
209
+ ),
210
+ ),
211
+ ),
212
+ SizedBox(height: 24),
213
+ },
214
+ if (widget.walletListViewModel.singleWalletsList.isNotEmpty) ...{
215
+ Padding(
216
+ padding: const EdgeInsets.only(left: 24),
217
+ child: Text(
218
+ S.current.single_seed_wallets_group,
219
+ style: TextStyle(
220
+ fontSize: 18,
221
+ fontWeight: FontWeight.w500,
222
+ color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
223
),
224
),
197
- );
225
+ ),
226
+ SizedBox(height: 16),
227
+ Container(
228
+ child: Observer(
229
+ builder: (_) => FilteredList(
230
+ shrinkWrap: true,
231
+ list: widget.walletListViewModel.singleWalletsList,
232
+ updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
233
+ itemBuilder: (context, index) {
234
+ final wallet = widget.walletListViewModel.singleWalletsList[index];
235
199
- return wallet.isCurrent
200
- ? row
201
- : Row(
202
- key: ValueKey(wallet.name),
203
- children: [
204
- Expanded(child: row),
205
- GestureDetector(
206
- onTap: () => Navigator.of(context).pushNamed(Routes.walletEdit,
207
- arguments: [widget.walletListViewModel, wallet]),
208
- child: Container(
209
- padding: EdgeInsets.only(
210
- right: DeviceInfo.instance.isMobile ? 20 : 40),
211
- child: Center(
212
- child: Container(
213
- height: 40,
236
+ return GroupedWalletExpansionTile(
237
+ tileKey: ValueKey('single_wallets_expansion_tile_widget_$index'),
238
+ leadingWidget: Image.asset(
239
+ walletTypeToCryptoCurrency(wallet.type).iconPath!,
240
+ width: 32,
241
+ height: 32,
242
+ ),
243
+ title: wallet.name,
244
+ isSelected: false,
245
+ borderRadius: BorderRadius.all(Radius.circular(16)),
246
+ margin: EdgeInsets.only(left: 20, right: 20, bottom: 12),
247
+ onTitleTapped: () => wallet.isCurrent ? null : _loadWallet(wallet),
248
+ trailingWidget: wallet.isCurrent
249
+ ? null
250
+ : EditWalletButtonWidget(
251
width: 44,
215
- padding: EdgeInsets.all(10),
216
- decoration: BoxDecoration(
217
- shape: BoxShape.circle,
218
- color: Theme.of(context)
219
- .extension<ReceivePageTheme>()!
220
- .iconsBackgroundColor,
221
- ),
222
- child: Icon(
223
- Icons.edit,
224
- size: 14,
225
- color: Theme.of(context)
226
- .extension<ReceivePageTheme>()!
227
- .iconsColor,
228
- ),
252
+ onTap: () {
253
+ Navigator.of(context).pushNamed(
254
+ Routes.walletEdit,
255
+ arguments: WalletEditPageArguments(
256
+ walletListViewModel: widget.walletListViewModel,
257
+ editingWallet: wallet,
258
+ ),
259
+ );
260
+ },
261
),
230
- ),
231
- ),
232
- ),
233
- ],
234
- );
262
+ );
263
+ },
264
+ ),
265
+ ),
266
+ ),
267
},
236
- ),
268
+ ],
269
),
270
),
271
),
281
widget.authService.authenticateAction(
282
context,
283
route: Routes.newWallet,
252
- arguments: widget.walletListViewModel.currentWalletType,
284
+ arguments: NewWalletArguments(
285
+ type: widget.walletListViewModel.currentWalletType,
286
+ ),
287
conditionToDetermineIfToUse2FA:
288
widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
289
);
290
} else {
291
Navigator.of(context).pushNamed(
292
Routes.newWallet,
259
- arguments: widget.walletListViewModel.currentWalletType,
293
+ arguments: NewWalletArguments(
294
+ type: widget.walletListViewModel.currentWalletType,
295
+ ),
296
);
297
}
298
} else {
376
377
Future<void> _loadWallet(WalletListItem wallet) async {
378
if (SettingsStoreBase.walletPasswordDirectInput) {
343
- Navigator.of(context).pushNamed(
344
- Routes.walletUnlockLoadable,
379
+ Navigator.of(context).pushNamed(Routes.walletUnlockLoadable,
380
arguments: WalletUnlockArguments(
381
callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
382
if (isAuthenticatedSuccessfully) {
383
auth.close();
384
setState(() {});
385
}
351
- }, walletName: wallet.name,
386
+ },
387
+ walletName: wallet.name,
388
walletType: wallet.type));
389
return;
390
}