CWA-201 | added wallet tiles to wallet list page; added colors and images to wallet menu
Oleksandr Sobol committed
Apr 23, 2020 at 21:36 UTC
07aaf7716711eecd1025b3a34ff1a09477caf582
11 files changed
+286
-84
assets/images/2.0x/load.png
Binary files /dev/null and b/assets/images/2.0x/load.png differ
assets/images/2.0x/scanner.png
Binary files /dev/null and b/assets/images/2.0x/scanner.png differ
assets/images/2.0x/trash.png
Binary files /dev/null and b/assets/images/2.0x/trash.png differ
assets/images/3.0x/load.png
Binary files /dev/null and b/assets/images/3.0x/load.png differ
assets/images/3.0x/scanner.png
Binary files /dev/null and b/assets/images/3.0x/scanner.png differ
assets/images/3.0x/trash.png
Binary files /dev/null and b/assets/images/3.0x/trash.png differ
assets/images/load.png
Binary files /dev/null and b/assets/images/load.png differ
assets/images/scanner.png
Binary files /dev/null and b/assets/images/scanner.png differ
assets/images/trash.png
Binary files /dev/null and b/assets/images/trash.png differ
lib/src/screens/wallet_list/wallet_list_page.dart
+250
-84
@@ -6,22 +6,15 @@ import 'package:cake_wallet/routes.dart';
6
import 'package:cake_wallet/palette.dart';
7
import 'package:cake_wallet/generated/i18n.dart';
8
import 'package:cake_wallet/src/widgets/primary_button.dart';
9
-import 'package:cake_wallet/src/domain/common/wallet_description.dart';
9
import 'package:cake_wallet/src/screens/base_page.dart';
10
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
11
import 'package:cake_wallet/src/stores/wallet_list/wallet_list_store.dart';
12
import 'package:cake_wallet/src/screens/wallet_list/wallet_menu.dart';
14
-import 'package:cake_wallet/src/widgets/picker.dart';
13
14
class WalletListPage extends BasePage {
17
- @override
18
- bool get isModalBackButton => true;
19
-
20
- @override
21
- String get title => S.current.wallet_list_title;
15
16
@override
24
- AppBarStyle get appBarStyle => AppBarStyle.withShadow;
17
+ ObstructingPreferredSizeWidget appBar(BuildContext context) => null;
18
19
@override
20
Widget body(BuildContext context) => WalletListBody();
@@ -33,92 +26,265 @@ class WalletListBody extends StatefulWidget {
26
}
27
28
class WalletListBodyState extends State<WalletListBody> {
29
+ final moneroIcon = Image.asset('assets/images/monero.png', height: 24, width: 24);
30
WalletListStore _walletListStore;
31
38
- void presetMenuForWallet(WalletDescription wallet, bool isCurrentWallet,
39
- BuildContext bodyContext) {
40
- final walletMenu = WalletMenu(bodyContext);
41
- final items = walletMenu.generateItemsForWalletMenu(isCurrentWallet);
42
-
43
- showDialog<void>(
44
- context: bodyContext,
45
- builder: (_) => Picker(
46
- items: items,
47
- selectedAtIndex: -1,
48
- title: S.of(context).wallet_menu,
49
- onItemSelected: (String item) => walletMenu.action(
50
- walletMenu.listItems.indexOf(item), wallet, isCurrentWallet)),
51
- );
52
- }
53
-
32
@override
33
Widget build(BuildContext context) {
34
_walletListStore = Provider.of<WalletListStore>(context);
35
58
- return ScrollableWithBottomSection(
59
- content: Container(
60
- padding: EdgeInsets.all(20),
61
- child: Observer(
62
- builder: (_) => ListView.separated(
63
- shrinkWrap: true,
64
- physics: const NeverScrollableScrollPhysics(),
65
- separatorBuilder: (_, index) => Divider(
66
- color: Theme.of(context).dividerTheme.color, height: 1.0),
67
- itemCount: _walletListStore.wallets.length,
68
- itemBuilder: (__, index) {
69
- final wallet = _walletListStore.wallets[index];
70
- final isCurrentWallet =
36
+ return SafeArea(
37
+ child: Container(
38
+ padding: EdgeInsets.only(top: 32),
39
+ color: PaletteDark.menuHeader,
40
+ child: ScrollableWithBottomSection(
41
+ contentPadding: EdgeInsets.only(bottom: 20),
42
+ content: Container(
43
+ child: Observer(
44
+ builder: (_) => ListView.separated(
45
+ shrinkWrap: true,
46
+ physics: const NeverScrollableScrollPhysics(),
47
+ separatorBuilder: (_, index) => Divider(
48
+ color: PaletteDark.menuHeader, height: 16),
49
+ itemCount: _walletListStore.wallets.length,
50
+ itemBuilder: (__, index) {
51
+ final wallet = _walletListStore.wallets[index];
52
+ final screenWidth = MediaQuery.of(context).size.width;
53
+
54
+ final isCurrentWallet =
55
_walletListStore.isCurrentWallet(wallet);
56
73
- return InkWell(
74
- onTap: () =>
75
- presetMenuForWallet(wallet, isCurrentWallet, context),
76
- child: Container(
77
- padding: EdgeInsets.only(left: 10.0, right: 10.0),
78
- child: ListTile(
79
- title: Text(
80
- wallet.name,
81
- style: TextStyle(
82
- color: isCurrentWallet
83
- ? Palette.cakeGreen
84
- : Theme.of(context)
85
- .primaryTextTheme
86
- .headline
87
- .color,
88
- fontSize: 18.0,
89
- fontWeight: FontWeight.w600),
57
+ final walletMenu = WalletMenu(context);
58
+ final items = walletMenu.generateItemsForWalletMenu(isCurrentWallet);
59
+ final colors = walletMenu.generateColorsForWalletMenu(isCurrentWallet);
60
+ final images = walletMenu.generateImagesForWalletMenu(isCurrentWallet);
61
+
62
+ return Container(
63
+ height: 108,
64
+ width: double.infinity,
65
+ child: CustomScrollView(
66
+ scrollDirection: Axis.horizontal,
67
+ slivers: <Widget>[
68
+ SliverPersistentHeader(
69
+ pinned: false,
70
+ floating: true,
71
+ delegate: WalletTile(
72
+ min: screenWidth - 228,
73
+ max: screenWidth,
74
+ image: moneroIcon,
75
+ walletName: wallet.name,
76
+ walletAddress: '',
77
+ isCurrent: isCurrentWallet
78
),
91
- trailing: isCurrentWallet
92
- ? Icon(
93
- Icons.check,
94
- color: Palette.cakeGreen,
95
- size: 20.0,
96
- )
97
- : null)));
98
- }),
99
- ),
100
- ),
101
- bottomSection: Column(children: <Widget>[
102
- PrimaryIconButton(
103
- onPressed: () => Navigator.of(context).pushNamed(Routes.newWallet),
104
- iconData: Icons.add,
105
- color: Theme.of(context).primaryTextTheme.button.backgroundColor,
106
- borderColor:
79
+ ),
80
+ SliverList(
81
+ delegate: SliverChildBuilderDelegate(
82
+ (context, index) {
83
+
84
+ final item = items[index];
85
+ final color = colors[index];
86
+ final image = images[index];
87
+
88
+ final content = Center(
89
+ child: Column(
90
+ mainAxisSize: MainAxisSize.min,
91
+ children: <Widget>[
92
+ image,
93
+ SizedBox(height: 5),
94
+ Text(
95
+ item,
96
+ textAlign: TextAlign.center,
97
+ style: TextStyle(
98
+ fontSize: 12,
99
+ color: Colors.white
100
+ ),
101
+ )
102
+ ],
103
+ ),
104
+ );
105
+
106
+ if (index == 0) {
107
+ return GestureDetector(
108
+ onTap: () => walletMenu.action(
109
+ walletMenu.listItems.indexOf(item), wallet, isCurrentWallet),
110
+ child: Container(
111
+ height: 108,
112
+ width: 108,
113
+ color: PaletteDark.menuHeader,
114
+ child: Container(
115
+ padding: EdgeInsets.only(left: 5, right: 5),
116
+ decoration: BoxDecoration(
117
+ borderRadius: BorderRadius.only(
118
+ topLeft: Radius.circular(12),
119
+ bottomLeft: Radius.circular(12)
120
+ ),
121
+ color: color
122
+ ),
123
+ child: content,
124
+ ),
125
+ ),
126
+ );
127
+ }
128
+
129
+ return GestureDetector(
130
+ onTap: () => walletMenu.action(
131
+ walletMenu.listItems.indexOf(item), wallet, isCurrentWallet),
132
+ child: Container(
133
+ height: 108,
134
+ width: 108,
135
+ padding: EdgeInsets.only(left: 5, right: 5),
136
+ color: color,
137
+ child: content,
138
+ ),
139
+ );
140
+ },
141
+ childCount: items.length
142
+ )
143
+ )
144
+ ],
145
+ ),
146
+ );
147
+ }),
148
+ ),
149
+ ),
150
+ bottomSection: Column(children: <Widget>[
151
+ PrimaryIconButton(
152
+ onPressed: () => Navigator.of(context).pushNamed(Routes.newWallet),
153
+ iconData: Icons.add,
154
+ color: Theme.of(context).primaryTextTheme.button.backgroundColor,
155
+ borderColor:
156
Theme.of(context).primaryTextTheme.button.decorationColor,
108
- iconColor: Palette.violet,
109
- iconBackgroundColor: Theme.of(context).primaryIconTheme.color,
110
- text: S.of(context).wallet_list_create_new_wallet),
111
- SizedBox(height: 10.0),
112
- PrimaryIconButton(
113
- onPressed: () =>
114
- Navigator.of(context).pushNamed(Routes.restoreWalletOptions),
115
- iconData: Icons.refresh,
116
- text: S.of(context).wallet_list_restore_wallet,
117
- color: Theme.of(context).accentTextTheme.button.backgroundColor,
118
- borderColor:
157
+ iconColor: Palette.violet,
158
+ iconBackgroundColor: Theme.of(context).primaryIconTheme.color,
159
+ text: S.of(context).wallet_list_create_new_wallet),
160
+ SizedBox(height: 10.0),
161
+ PrimaryIconButton(
162
+ onPressed: () =>
163
+ Navigator.of(context).pushNamed(Routes.restoreWalletOptions),
164
+ iconData: Icons.refresh,
165
+ text: S.of(context).wallet_list_restore_wallet,
166
+ color: Theme.of(context).accentTextTheme.button.backgroundColor,
167
+ borderColor:
168
Theme.of(context).accentTextTheme.button.decorationColor,
120
- iconColor: Theme.of(context).primaryTextTheme.caption.color,
121
- iconBackgroundColor: Theme.of(context).accentIconTheme.color)
122
- ]));
169
+ iconColor: Theme.of(context).primaryTextTheme.caption.color,
170
+ iconBackgroundColor: Theme.of(context).accentIconTheme.color)
171
+ ])),
172
+ )
173
+ );
174
+ }
175
+}
176
+
177
+class WalletTile extends SliverPersistentHeaderDelegate {
178
+ WalletTile({
179
+ @required this.min,
180
+ @required this.max,
181
+ @required this.image,
182
+ @required this.walletName,
183
+ @required this.walletAddress,
184
+ @required this.isCurrent
185
+ });
186
+
187
+ final double min;
188
+ final double max;
189
+ final Image image;
190
+ final String walletName;
191
+ final String walletAddress;
192
+ final bool isCurrent;
193
+
194
+ @override
195
+ Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
196
+
197
+ double opacity = 1 - shrinkOffset / (max - min);
198
+ opacity = opacity >= 0 ? opacity : 0;
199
+
200
+ double panelWidth = 12 * opacity;
201
+ panelWidth = panelWidth < 12 ? 0 : 12;
202
+
203
+ final currentColor = isCurrent
204
+ ? Colors.white
205
+ : PaletteDark.menuHeader;
206
+
207
+ return Stack(
208
+ fit: StackFit.expand,
209
+ overflow: Overflow.visible,
210
+ children: <Widget>[
211
+ Positioned(
212
+ top: 0,
213
+ right: max - 4,
214
+ child: Container(
215
+ height: 108,
216
+ width: 4,
217
+ decoration: BoxDecoration(
218
+ borderRadius: BorderRadius.only(topRight: Radius.circular(4), bottomRight: Radius.circular(4)),
219
+ color: currentColor
220
+ ),
221
+ ),
222
+ ),
223
+ Positioned(
224
+ top: 0,
225
+ right: 12,
226
+ child: Container(
227
+ height: 108,
228
+ width: max - 16,
229
+ padding: EdgeInsets.only(left: 20, right: 20),
230
+ color: PaletteDark.menuHeader,
231
+ child: Column(
232
+ mainAxisSize: MainAxisSize.max,
233
+ mainAxisAlignment: MainAxisAlignment.center,
234
+ children: <Widget>[
235
+ Row(
236
+ mainAxisAlignment: MainAxisAlignment.start,
237
+ crossAxisAlignment: CrossAxisAlignment.center,
238
+ children: <Widget>[
239
+ image,
240
+ SizedBox(width: 10),
241
+ Text(
242
+ walletName,
243
+ style: TextStyle(
244
+ fontSize: 22,
245
+ fontWeight: FontWeight.bold,
246
+ color: Colors.white
247
+ ),
248
+ )
249
+ ],
250
+ )
251
+ ],
252
+ ),
253
+ ),
254
+ ),
255
+ Positioned(
256
+ top: 0,
257
+ right: 0,
258
+ child: Opacity(
259
+ opacity: opacity,
260
+ child: Container(
261
+ height: 108,
262
+ width: panelWidth,
263
+ decoration: BoxDecoration(
264
+ borderRadius: BorderRadius.only(topLeft: Radius.circular(12), bottomLeft: Radius.circular(12)),
265
+ gradient: LinearGradient(
266
+ begin: Alignment.topCenter,
267
+ end: Alignment.bottomCenter,
268
+ colors: [
269
+ PaletteDark.walletCardTopEndSync,
270
+ PaletteDark.walletCardBottomEndSync
271
+ ]
272
+ )
273
+ ),
274
+ ),
275
+ )
276
+ ),
277
+ ],
278
+ );
279
}
280
+
281
+ @override
282
+ double get maxExtent => max;
283
+
284
+ @override
285
+ double get minExtent => min;
286
+
287
+ @override
288
+ bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
289
+
290
}
lib/src/screens/wallet_list/wallet_menu.dart
+36
@@ -18,6 +18,20 @@ class WalletMenu {
18
S.current.rescan
19
];
20
21
+ final List<Color> listColors = [
22
+ Colors.blue,
23
+ Colors.orange,
24
+ Colors.red,
25
+ Colors.green
26
+ ];
27
+
28
+ final List<Image> listImages = [
29
+ Image.asset('assets/images/load.png', height: 32, width: 32, color: Colors.white),
30
+ Image.asset('assets/images/eye.png', height: 32, width: 32, color: Colors.white),
31
+ Image.asset('assets/images/trash.png', height: 32, width: 32, color: Colors.white),
32
+ Image.asset('assets/images/scanner.png', height: 32, width: 32, color: Colors.white)
33
+ ];
34
+
35
List<String> generateItemsForWalletMenu(bool isCurrentWallet) {
36
final items = List<String>();
37
@@ -29,6 +43,28 @@ class WalletMenu {
43
return items;
44
}
45
46
+ List<Color> generateColorsForWalletMenu(bool isCurrentWallet) {
47
+ final colors = List<Color>();
48
+
49
+ if (!isCurrentWallet) colors.add(listColors[0]);
50
+ if (isCurrentWallet) colors.add(listColors[1]);
51
+ if (!isCurrentWallet) colors.add(listColors[2]);
52
+ if (isCurrentWallet) colors.add(listColors[3]);
53
+
54
+ return colors;
55
+ }
56
+
57
+ List<Image> generateImagesForWalletMenu(bool isCurrentWallet) {
58
+ final images = List<Image>();
59
+
60
+ if (!isCurrentWallet) images.add(listImages[0]);
61
+ if (isCurrentWallet) images.add(listImages[1]);
62
+ if (!isCurrentWallet) images.add(listImages[2]);
63
+ if (isCurrentWallet) images.add(listImages[3]);
64
+
65
+ return images;
66
+ }
67
+
68
void action(int index, WalletDescription wallet, bool isCurrentWallet) {
69
final _walletListStore = Provider.of<WalletListStore>(context);
70