dev
dart 202 lines 8.37 KB
Raw
1 import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cake_wallet/routes.dart';
4 import 'package:cake_wallet/src/screens/base_page.dart';
5 import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
6 import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
7 import 'package:cake_wallet/src/widgets/primary_button.dart';
8 import 'package:cake_wallet/themes/core/material_base_theme.dart';
9 import 'package:cake_wallet/view_model/wallet_groups_display_view_model.dart';
10 import 'package:cw_core/currency_for_wallet_type.dart';
11 import 'package:flutter/material.dart';
12 import 'package:flutter_mobx/flutter_mobx.dart';
13
14 class WalletGroupsDisplayPage extends BasePage {
15 WalletGroupsDisplayPage(this.walletGroupsDisplayViewModel);
16
17 final WalletGroupsDisplayViewModel walletGroupsDisplayViewModel;
18
19 @override
20 String get title => S.current.wallet_group;
21
22 @override
23 Widget body(BuildContext context) => WalletGroupsDisplayBody(
24 walletGroupsDisplayViewModel: walletGroupsDisplayViewModel,
25 currentTheme: currentTheme,
26 );
27 }
28
29 class WalletGroupsDisplayBody extends StatelessWidget {
30 WalletGroupsDisplayBody({
31 required this.walletGroupsDisplayViewModel,
32 required this.currentTheme,
33 });
34
35 final WalletGroupsDisplayViewModel walletGroupsDisplayViewModel;
36 final MaterialThemeBase currentTheme;
37
38 @override
39 Widget build(BuildContext context) {
40 return Center(
41 child: Padding(
42 padding: EdgeInsets.symmetric(horizontal: 20),
43 child: Column(
44 children: [
45 Expanded(
46 child: SingleChildScrollView(
47 child: Observer(
48 builder: (context) {
49 return Column(
50 children: [
51 SizedBox(height: 48),
52 if (walletGroupsDisplayViewModel.hasNoFilteredWallet) ...{
53 SizedBox(height: 16),
54 WalletGroupEmptyStateWidget(
55 currentTheme: currentTheme,
56 ),
57 },
58 ...walletGroupsDisplayViewModel.multiWalletGroups.map(
59 (walletGroup) {
60 return Observer(builder: (context) {
61 final index = walletGroupsDisplayViewModel.multiWalletGroups
62 .indexOf(walletGroup);
63 final group = walletGroupsDisplayViewModel.multiWalletGroups[index];
64 final groupName =
65 group.groupName ?? '${S.of(context).wallet_group} ${index + 1}';
66 return GroupedWalletExpansionTile(
67 shouldShowCurrentWalletPointer: false,
68 leadingWidget:
69 Icon(Icons.account_balance_wallet_outlined, size: 28),
70 borderRadius: BorderRadius.all(Radius.circular(16)),
71 title: groupName,
72 childWallets: group.wallets.map((walletInfo) {
73 return walletGroupsDisplayViewModel
74 .convertWalletInfoToWalletListItem(walletInfo);
75 }).toList(),
76 isSelected:
77 walletGroupsDisplayViewModel.selectedWalletGroup == group,
78 onTitleTapped: () =>
79 walletGroupsDisplayViewModel.selectWalletGroup(group),
80 onChildItemTapped: (_) =>
81 walletGroupsDisplayViewModel.selectWalletGroup(group),
82 );
83 });
84 },
85 ).toList(),
86 ...walletGroupsDisplayViewModel.singleWalletsList.map((singleWallet) {
87 return Observer(
88 builder: (context) {
89 final index = walletGroupsDisplayViewModel.singleWalletsList
90 .indexOf(singleWallet);
91 final wallet = walletGroupsDisplayViewModel.singleWalletsList[index];
92 return GroupedWalletExpansionTile(
93 borderRadius: BorderRadius.all(Radius.circular(16)),
94 title: wallet.name,
95 isSelected:
96 walletGroupsDisplayViewModel.selectedSingleWallet == wallet,
97 leadingWidget: CakeImageWidget(
98 imageUrl: getCryptoCurrencyIconForWalletListItem(wallet.type),
99 width: 32,
100 height: 32,
101 ),
102 onTitleTapped: () =>
103 walletGroupsDisplayViewModel.selectSingleWallet(wallet),
104 );
105 },
106 );
107 }).toList(),
108 ],
109 );
110 },
111 ),
112 ),
113 ),
114 Observer(
115 builder: (context) {
116 return LoadingPrimaryButton(
117 isLoading: walletGroupsDisplayViewModel.isFetchingMnemonic,
118 onPressed: () {
119 if (walletGroupsDisplayViewModel.hasNoFilteredWallet) {
120 Navigator.of(context).pushNamed(
121 Routes.newWallet,
122 arguments: NewWalletArguments(type: walletGroupsDisplayViewModel.type),
123 );
124 } else {
125 onTypeSelected(context);
126 }
127 },
128 text: walletGroupsDisplayViewModel.hasNoFilteredWallet
129 ? S.of(context).create_new_seed
130 : S.of(context).seed_language_next,
131 color: Theme.of(context).colorScheme.primary,
132 textColor: Theme.of(context).colorScheme.onPrimary,
133 isDisabled: !walletGroupsDisplayViewModel.hasNoFilteredWallet
134 ? (walletGroupsDisplayViewModel.selectedWalletGroup == null &&
135 walletGroupsDisplayViewModel.selectedSingleWallet == null)
136 : false,
137 );
138 },
139 ),
140 SizedBox(height: 24),
141 ],
142 ),
143 ),
144 );
145 }
146
147 Future<void> onTypeSelected(BuildContext context) async {
148 final mnemonic = await walletGroupsDisplayViewModel.getSelectedWalletMnemonic();
149 if (context.mounted) {
150 Navigator.of(context).pushNamed(
151 Routes.newWallet,
152 arguments: NewWalletArguments(
153 type: walletGroupsDisplayViewModel.type,
154 mnemonic: mnemonic,
155 isChildWallet: true,
156 ),
157 );
158 }
159 }
160 }
161
162 class WalletGroupEmptyStateWidget extends StatelessWidget {
163 const WalletGroupEmptyStateWidget({required this.currentTheme, super.key});
164
165 final MaterialThemeBase currentTheme;
166
167 @override
168 Widget build(BuildContext context) {
169 return Column(
170 children: [
171 CakeImageWidget(
172 imageUrl: currentTheme.isDark
173 ? 'assets/new-ui/hero/wallet_group_empty_dark.svg'
174 : 'assets/new-ui/hero/wallet_group_empty_light.svg',
175 height: 200,
176 ),
177 SizedBox(height: 60),
178 Text.rich(
179 TextSpan(
180 children: [
181 TextSpan(
182 text: '${S.of(context).wallet_group_empty_state_text_one} ',
183 ),
184 TextSpan(
185 text: '${S.of(context).create_new_seed} ',
186 style:
187 Theme.of(context).textTheme.bodyMedium!.copyWith(fontWeight: FontWeight.w700),
188 ),
189 TextSpan(text: S.of(context).wallet_group_empty_state_text_two),
190 ],
191 ),
192 textAlign: TextAlign.center,
193 style: Theme.of(context).textTheme.bodyMedium!.copyWith(
194 height: 1.5,
195 fontSize: 16,
196 color: Theme.of(context).colorScheme.onSurfaceVariant,
197 ),
198 ),
199 ],
200 );
201 }
202 }