CAKE-28 | created filter tile, filter widget, checkbox widget and filter item; applied filter items to filter widget, also applied filter widget to dashboard page; reworked wallet list page and menu widget; applied light and dark themes to filter widget and wallet list age; fixed filtered method in the trade filter store

Oleksandr Sobol committed Aug 28, 2020 at 23:04 UTC 4ed7f6ec1825f577278013eba55123872846b168
18 files changed +531 -289
assets/images/2.0x/back_vector.png
Binary files /dev/null and b/assets/images/2.0x/back_vector.png differ
assets/images/3.0x/back_vector.png
Binary files /dev/null and b/assets/images/3.0x/back_vector.png differ
assets/images/back_vector.png
Binary files /dev/null and b/assets/images/back_vector.png differ
lib/palette.dart
+10 -1
@@ -9,11 +9,20 @@ class Palette {
9 static const Color lavender = Color.fromRGBO(237, 245, 252, 1.0);
10 static const Color oceanBlue = Color.fromRGBO(30, 52, 78, 1.0);
11 static const Color lightBlueGrey = Color.fromRGBO(118, 131, 169, 1.0);
12 - static const Color periwinkle = Color.fromRGBO(197, 208, 230, 1.0);
12 + static const Color periwinkle = Color.fromRGBO(195, 210, 227, 1.0);
13 static const Color blue = Color.fromRGBO(88, 143, 252, 1.0);
14 static const Color darkLavender = Color.fromRGBO(229, 238, 250, 1.0);
15 static const Color nightBlue = Color.fromRGBO(46, 57, 96, 1.0);
16
17 + static const Color moderateOrangeYellow = Color.fromRGBO(245, 134, 82, 1.0);
18 + static const Color moderateOrange = Color.fromRGBO(235, 117, 63, 1.0);
19 + static const Color shineGreen = Color.fromRGBO(76, 189, 87, 1.0);
20 + static const Color moderateGreen = Color.fromRGBO(45, 158, 56, 1.0);
21 + static const Color cornflower = Color.fromRGBO(85, 147, 240, 1.0);
22 + static const Color royalBlue = Color.fromRGBO(43, 114, 221, 1.0);
23 + static const Color lightRed = Color.fromRGBO(227, 87, 87, 1.0);
24 + static const Color persianRed = Color.fromRGBO(206, 55, 55, 1.0);
25 +
26 // NEW DESIGN
27 static const Color blueCraiola = Color.fromRGBO(69, 110, 255, 1.0);
28 static const Color darkBlueCraiola = Color.fromRGBO(53, 86, 136, 1.0);
lib/src/screens/dashboard/widgets/filter_tile.dart new
+21
@@ -0,0 +1,21 @@
1 +import 'package:flutter/material.dart';
2 +
3 +class FilterTile extends StatelessWidget {
4 + FilterTile({@required this.child});
5 +
6 + final Widget child;
7 +
8 + @override
9 + Widget build(BuildContext context) {
10 + return Container(
11 + width: double.infinity,
12 + padding: EdgeInsets.only(
13 + top: 18,
14 + bottom: 18,
15 + left: 24,
16 + right: 24
17 + ),
18 + child: child,
19 + );
20 + }
21 +}
\ No newline at end of file
lib/src/screens/dashboard/widgets/filter_widget.dart new
+155
@@ -0,0 +1,155 @@
1 +import 'dart:ui';
2 +import 'package:cake_wallet/palette.dart';
3 +import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
4 +import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
5 +import 'package:flutter/cupertino.dart';
6 +import 'package:flutter/material.dart';
7 +import 'package:cake_wallet/src/widgets/alert_background.dart';
8 +import 'package:cake_wallet/src/widgets/alert_close_button.dart';
9 +import 'package:cake_wallet/src/widgets/checkbox_widget.dart';
10 +import 'package:cake_wallet/generated/i18n.dart';
11 +import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
12 +
13 +class FilterWidget extends StatelessWidget {
14 + FilterWidget({@required this.dashboardViewModel});
15 +
16 + final DashboardViewModel dashboardViewModel;
17 + final backVector = Image.asset('assets/images/back_vector.png',
18 + color: Palette.darkBlueCraiola
19 + );
20 +
21 + @override
22 + Widget build(BuildContext context) {
23 + return AlertBackground(
24 + child: Stack(
25 + alignment: Alignment.center,
26 + children: <Widget>[
27 + Column(
28 + mainAxisSize: MainAxisSize.min,
29 + children: <Widget>[
30 + Text(
31 + S.of(context).filters,
32 + style: TextStyle(
33 + color: Colors.white,
34 + fontSize: 18,
35 + fontWeight: FontWeight.bold,
36 + fontFamily: 'Poppins',
37 + decoration: TextDecoration.none,
38 + ),
39 + ),
40 + Padding(
41 + padding: EdgeInsets.only(
42 + left: 24,
43 + right: 24,
44 + top: 24
45 + ),
46 + child: ClipRRect(
47 + borderRadius: BorderRadius.all(Radius.circular(14)),
48 + child: Container(
49 + color: Theme.of(context).textTheme.body2.decorationColor,
50 + child: ListView.separated(
51 + shrinkWrap: true,
52 + physics: const NeverScrollableScrollPhysics(),
53 + itemCount: dashboardViewModel.filterItems.length,
54 + separatorBuilder: (context, _) => Container(
55 + height: 1,
56 + color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
57 + ),
58 + itemBuilder: (_, index1) {
59 + final title = dashboardViewModel.filterItems.keys.elementAt(index1);
60 + final section = dashboardViewModel.filterItems.values.elementAt(index1);
61 +
62 + return Column(
63 + crossAxisAlignment: CrossAxisAlignment.start,
64 + children: <Widget>[
65 + Padding(
66 + padding: EdgeInsets.only(
67 + top: 20,
68 + left: 24,
69 + right: 24
70 + ),
71 + child: Text(
72 + title,
73 + style: TextStyle(
74 + color: Theme.of(context).accentTextTheme.subhead.color,
75 + fontSize: 16,
76 + fontWeight: FontWeight.w500,
77 + fontFamily: 'Poppins',
78 + decoration: TextDecoration.none
79 + ),
80 + ),
81 + ),
82 + ListView.separated(
83 + shrinkWrap: true,
84 + physics: const NeverScrollableScrollPhysics(),
85 + itemCount: section.length,
86 + separatorBuilder: (context, _) => Container(
87 + height: 1,
88 + padding: EdgeInsets.only(left: 24),
89 + color: Theme.of(context).textTheme.body2.decorationColor,
90 + child: Container(
91 + height: 1,
92 + color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
93 + ),
94 + ),
95 + itemBuilder: (_, index2) {
96 +
97 + final item = section[index2];
98 + final content = item.onChanged != null
99 + ? CheckboxWidget(
100 + value: item.value,
101 + caption: item.caption,
102 + onChanged: item.onChanged
103 + )
104 + : GestureDetector(
105 + onTap: () async {
106 + final List<DateTime> picked =
107 + await date_rage_picker.showDatePicker(
108 + context: context,
109 + initialFirstDate: DateTime.now()
110 + .subtract(Duration(days: 1)),
111 + initialLastDate: (DateTime.now()),
112 + firstDate: DateTime(2015),
113 + lastDate: DateTime.now()
114 + .add(Duration(days: 1)));
115 +
116 + if (picked != null && picked.length == 2) {
117 + dashboardViewModel.transactionFilterStore
118 + .changeStartDate(picked.first);
119 + dashboardViewModel.transactionFilterStore
120 + .changeEndDate(picked.last);
121 + }
122 + },
123 + child: Padding(
124 + padding: EdgeInsets.only(left: 32),
125 + child: Text(
126 + item.caption,
127 + style: TextStyle(
128 + color: Theme.of(context).primaryTextTheme.title.color,
129 + fontSize: 18,
130 + fontFamily: 'Poppins',
131 + fontWeight: FontWeight.w500,
132 + decoration: TextDecoration.none
133 + ),
134 + ),
135 + ),
136 + );
137 +
138 + return FilterTile(child: content);
139 + },
140 + )
141 + ],
142 + );
143 + },
144 + ),
145 + ),
146 + ),
147 + ),
148 + ],
149 + ),
150 + AlertCloseButton(image: backVector)
151 + ],
152 + ),
153 + );
154 + }
155 +}
\ No newline at end of file
lib/src/screens/dashboard/widgets/header_row.dart
+9 -166
@@ -1,9 +1,7 @@
1 +import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
2 import 'package:flutter/material.dart';
3 import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
4 -import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
5 -import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
6 -import 'package:flutter_mobx/flutter_mobx.dart';
5
6 class HeaderRow extends StatelessWidget {
7 HeaderRow({this.dashboardViewModel});
@@ -31,148 +29,13 @@ class HeaderRow extends StatelessWidget {
29 color: Colors.white
30 ),
31 ),
34 - PopupMenuButton<int>(
35 - itemBuilder: (context) => [
36 - PopupMenuItem(
37 - enabled: false,
38 - value: -1,
39 - child: Text(S.of(context).transactions,
40 - style: TextStyle(
41 - fontWeight: FontWeight.bold,
42 - color: Theme.of(context).primaryTextTheme.title.color))),
43 - PopupMenuItem(
44 - value: 0,
45 - child: Observer(
46 - builder: (_) => Row(
47 - mainAxisAlignment:
48 - MainAxisAlignment
49 - .spaceBetween,
50 - children: [
51 - Text(S.of(context).incoming,
52 - style: TextStyle(
53 - color: Theme.of(context).primaryTextTheme.title.color
54 - ),
55 - ),
56 - Checkbox(
57 - value: dashboardViewModel
58 - .transactionFilterStore
59 - .displayIncoming,
60 - onChanged: (value) => dashboardViewModel
61 - .transactionFilterStore
62 - .toggleIncoming()
63 - )
64 - ]))),
65 - PopupMenuItem(
66 - value: 1,
67 - child: Observer(
68 - builder: (_) => Row(
69 - mainAxisAlignment:
70 - MainAxisAlignment
71 - .spaceBetween,
72 - children: [
73 - Text(S.of(context).outgoing,
74 - style: TextStyle(
75 - color: Theme.of(context).primaryTextTheme.title.color
76 - )
77 - ),
78 - Checkbox(
79 - value: dashboardViewModel
80 - .transactionFilterStore
81 - .displayOutgoing,
82 - onChanged: (value) => dashboardViewModel
83 - .transactionFilterStore
84 - .toggleOutgoing(),
85 - )
86 - ]))),
87 - PopupMenuItem(
88 - value: 2,
89 - child:
90 - Text(S.of(context).transactions_by_date,
91 - style: TextStyle(
92 - color: Theme.of(context).primaryTextTheme.title.color
93 - )
94 - )),
95 - PopupMenuDivider(),
96 - PopupMenuItem(
97 - enabled: false,
98 - value: -1,
99 - child: Text(S.of(context).trades,
100 - style: TextStyle(
101 - fontWeight: FontWeight.bold,
102 - color: Theme.of(context).primaryTextTheme.title.color))),
103 - PopupMenuItem(
104 - value: 3,
105 - child: Observer(
106 - builder: (_) => Row(
107 - mainAxisAlignment:
108 - MainAxisAlignment
109 - .spaceBetween,
110 - children: [
111 - Text('XMR.TO',
112 - style: TextStyle(
113 - color: Theme.of(context).primaryTextTheme.title.color
114 - )
115 - ),
116 - Checkbox(
117 - value: dashboardViewModel
118 - .tradeFilterStore
119 - .displayXMRTO,
120 - onChanged: (value) => dashboardViewModel
121 - .tradeFilterStore
122 - .toggleDisplayExchange(
123 - ExchangeProviderDescription
124 - .xmrto),
125 - )
126 - ]))),
127 - PopupMenuItem(
128 - value: 4,
129 - child: Observer(
130 - builder: (_) => Row(
131 - mainAxisAlignment:
132 - MainAxisAlignment
133 - .spaceBetween,
134 - children: [
135 - Text('Change.NOW',
136 - style: TextStyle(
137 - color: Theme.of(context).primaryTextTheme.title.color
138 - )
139 - ),
140 - Checkbox(
141 - value: dashboardViewModel
142 - .tradeFilterStore
143 - .displayChangeNow,
144 - onChanged: (value) => dashboardViewModel
145 - .tradeFilterStore
146 - .toggleDisplayExchange(
147 - ExchangeProviderDescription
148 - .changeNow),
149 - )
150 - ]))),
151 - PopupMenuItem(
152 - value: 5,
153 - child: Observer(
154 - builder: (_) => Row(
155 - mainAxisAlignment:
156 - MainAxisAlignment
157 - .spaceBetween,
158 - children: [
159 - Text('MorphToken',
160 - style: TextStyle(
161 - color: Theme.of(context).primaryTextTheme.title.color
162 - )
163 - ),
164 - Checkbox(
165 - value: dashboardViewModel
166 - .tradeFilterStore
167 - .displayMorphToken,
168 - onChanged: (value) => dashboardViewModel
169 - .tradeFilterStore
170 - .toggleDisplayExchange(
171 - ExchangeProviderDescription
172 - .morphToken),
173 - )
174 - ])))
175 - ],
32 + GestureDetector(
33 + onTap: () {
34 + showDialog<void>(
35 + context: context,
36 + builder: (context) => FilterWidget(dashboardViewModel: dashboardViewModel)
37 + );
38 + },
39 child: Container(
40 height: 36,
41 width: 36,
@@ -182,27 +45,7 @@ class HeaderRow extends StatelessWidget {
45 ),
46 child: filterIcon,
47 ),
185 - onSelected: (item) async {
186 - if (item == 2) {
187 - final picked =
188 - await date_rage_picker.showDatePicker(
189 - context: context,
190 - initialFirstDate: DateTime.now()
191 - .subtract(Duration(days: 1)),
192 - initialLastDate: (DateTime.now()),
193 - firstDate: DateTime(2015),
194 - lastDate: DateTime.now()
195 - .add(Duration(days: 1)));
196 -
197 - if (picked != null && picked.length == 2) {
198 - dashboardViewModel.transactionFilterStore
199 - .changeStartDate(picked.first);
200 - dashboardViewModel.transactionFilterStore
201 - .changeEndDate(picked.last);
202 - }
203 - }
204 - },
205 - ),
48 + )
49 ],
50 ),
51 );
lib/src/screens/dashboard/widgets/menu_widget.dart
+28 -15
@@ -17,8 +17,8 @@ class MenuWidget extends StatefulWidget {
17 }
18
19 class MenuWidgetState extends State<MenuWidget> {
20 - final moneroIcon = Image.asset('assets/images/monero_menu.png');
21 - final bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png');
20 + Image moneroIcon;
21 + Image bitcoinIcon;
22 final largeScreen = 731;
23
24 double menuWidth;
@@ -36,10 +36,10 @@ class MenuWidgetState extends State<MenuWidget> {
36 screenWidth = 0;
37 screenHeight = 0;
38
39 - headerHeight = 125;
39 + headerHeight = 137;
40 tileHeight = 75;
41 - fromTopEdge = 30;
42 - fromBottomEdge = 21;
41 + fromTopEdge = 50;
42 + fromBottomEdge = 30;
43
44 super.initState();
45 WidgetsBinding.instance.addPostFrameCallback(afterLayout);
@@ -67,6 +67,15 @@ class MenuWidgetState extends State<MenuWidget> {
67 final walletMenu = WalletMenu(context);
68 final itemCount = walletMenu.items.length;
69
70 + moneroIcon = Image.asset('assets/images/monero_menu.png',
71 + color: Theme.of(context)
72 + .accentTextTheme
73 + .overline.decorationColor);
74 + bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
75 + color: Theme.of(context)
76 + .accentTextTheme
77 + .overline.decorationColor);
78 +
79 return Row(
80 mainAxisSize: MainAxisSize.max,
81 crossAxisAlignment: CrossAxisAlignment.center,
@@ -87,17 +96,22 @@ class MenuWidgetState extends State<MenuWidget> {
96 topLeft: Radius.circular(24),
97 bottomLeft: Radius.circular(24)),
98 child: Container(
90 - width: menuWidth,
91 - height: double.infinity,
92 - color: Theme.of(context).textTheme.body2.color,
93 - alignment: Alignment.topCenter,
99 + color: Theme.of(context).textTheme.body2.decorationColor,
100 child: ListView.separated(
101 + padding: EdgeInsets.only(top: 0),
102 itemBuilder: (_, index) {
103
104 if (index == 0) {
105 return Container(
106 height: headerHeight,
100 - color: Theme.of(context).textTheme.body2.color,
107 + decoration: BoxDecoration(
108 + gradient: LinearGradient(colors: [
109 + Theme.of(context).accentTextTheme.display1.color,
110 + Theme.of(context).accentTextTheme.display1.decorationColor,
111 + ],
112 + begin: Alignment.topLeft,
113 + end: Alignment.bottomRight),
114 + ),
115 padding: EdgeInsets.only(
116 left: 24,
117 top: fromTopEdge,
@@ -121,8 +135,7 @@ class MenuWidgetState extends State<MenuWidget> {
135 Text(
136 widget.name,
137 style: TextStyle(
124 - color: Theme.of(context).textTheme
125 - .display2.color,
138 + color: Colors.white,
139 fontSize: 16,
140 fontWeight: FontWeight.bold),
141 ),
@@ -131,8 +144,8 @@ class MenuWidgetState extends State<MenuWidget> {
144 widget.subname,
145 style: TextStyle(
146 color: Theme.of(context)
134 - .primaryTextTheme
135 - .caption.color,
147 + .accentTextTheme
148 + .overline.decorationColor,
149 fontWeight: FontWeight.w500,
150 fontSize: 12),
151 )
@@ -194,7 +207,7 @@ class MenuWidgetState extends State<MenuWidget> {
207 color: Theme.of(context).primaryTextTheme.caption.decorationColor,
208 ),
209 itemCount: itemCount + 1),
197 - ),
210 + )
211 )
212 )
213 ],
lib/src/screens/send/widgets/base_send_widget.dart
+38 -20
@@ -247,26 +247,44 @@ class BaseSendWidget extends StatelessWidget {
247 ),
248 isTemplate
249 ? Offstage()
250 - : Padding(
251 - padding: const EdgeInsets.only(top: 24),
252 - child: Row(
253 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
254 - children: <Widget>[
255 - Text(S.of(context).send_estimated_fee,
256 - style: TextStyle(
257 - fontSize: 12,
258 - fontWeight: FontWeight.w500,
259 - color: Theme.of(context).primaryTextTheme.display2.color,
260 - )),
261 - Text(
262 - sendViewModel.estimatedFee.toString() + ' '
263 - + sendViewModel.currency.title,
264 - style: TextStyle(
265 - fontSize: 12,
266 - fontWeight: FontWeight.w600,
267 - color: Theme.of(context).primaryTextTheme.display2.color,
268 - ))
269 - ],
250 + : GestureDetector(
251 + onTap: () {},
252 + child: Container(
253 + padding: EdgeInsets.only(top: 24),
254 + child: Row(
255 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
256 + children: <Widget>[
257 + Text(S.of(context).send_estimated_fee,
258 + style: TextStyle(
259 + fontSize: 12,
260 + fontWeight: FontWeight.w500,
261 + //color: Theme.of(context).primaryTextTheme.display2.color,
262 + color: Colors.white
263 + )),
264 + Container(
265 + child: Row(
266 + children: <Widget>[
267 + Text(
268 + sendViewModel.estimatedFee.toString() + ' '
269 + + sendViewModel.currency.title,
270 + style: TextStyle(
271 + fontSize: 12,
272 + fontWeight: FontWeight.w600,
273 + //color: Theme.of(context).primaryTextTheme.display2.color,
274 + color: Colors.white
275 + )),
276 + Padding(
277 + padding: EdgeInsets.only(left: 5),
278 + child: Icon(
279 + Icons.arrow_forward_ios,
280 + size: 12,
281 + color: Colors.white,),
282 + )
283 + ],
284 + ),
285 + )
286 + ],
287 + ),
288 ),
289 )
290 ],
lib/src/screens/wallet_list/wallet_list_page.dart
+27 -15
@@ -37,11 +37,14 @@ class WalletListBodyState extends State<WalletListBody> {
37 final bitcoinIcon =
38 Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
39 final scrollController = ScrollController();
40 + final double tileHeight = 60;
41
42 @override
43 Widget build(BuildContext context) {
44 final newWalletImage = Image.asset('assets/images/new_wallet.png',
44 - height: 12, width: 12, color: Palette.oceanBlue);
45 + height: 12,
46 + width: 12,
47 + color: Theme.of(context).accentTextTheme.headline.decorationColor);
48 final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
49 height: 12,
50 width: 12,
@@ -58,7 +61,7 @@ class WalletListBodyState extends State<WalletListBody> {
61 shrinkWrap: true,
62 physics: const NeverScrollableScrollPhysics(),
63 separatorBuilder: (_, index) => Divider(
61 - color: Theme.of(context).backgroundColor, height: 16),
64 + color: Theme.of(context).backgroundColor, height: 32),
65 itemCount: widget.walletListViewModel.wallets.length,
66 itemBuilder: (__, index) {
67 final wallet = widget.walletListViewModel.wallets[index];
@@ -80,7 +83,7 @@ class WalletListBodyState extends State<WalletListBody> {
83 .generateImagesForWalletMenu(wallet.isCurrent);
84
85 return Container(
83 - height: 108,
86 + height: tileHeight,
87 width: double.infinity,
88 child: CustomScrollView(
89 scrollDirection: Axis.horizontal,
@@ -90,7 +93,7 @@ class WalletListBodyState extends State<WalletListBody> {
93 pinned: false,
94 floating: true,
95 delegate: WalletTile(
93 - min: screenWidth - 228,
96 + min: screenWidth - 170,
97 max: screenWidth,
98 image: _imageFor(type: wallet.type),
99 walletName: wallet.name,
@@ -101,10 +104,11 @@ class WalletListBodyState extends State<WalletListBody> {
104 delegate:
105 SliverChildBuilderDelegate((context, index) {
106 final item = items[index];
104 - final color = colors[index];
107 final image = images[index];
108 + final firstColor = colors[index*2];
109 + final secondColor = colors[index*2 + 1];
110
107 - final radius = index == 0 ? 12.0 : 0.0;
111 + final radius = index == 0 ? 10.0 : 0.0;
112
113 return GestureDetector(
114 onTap: () {
@@ -117,8 +121,8 @@ class WalletListBodyState extends State<WalletListBody> {
121 wallet.isCurrent);
122 },
123 child: Container(
120 - height: 108,
121 - width: 108,
124 + height: tileHeight,
125 + width: 80,
126 color: Theme.of(context).backgroundColor,
127 child: Container(
128 padding: EdgeInsets.only(left: 5, right: 5),
@@ -126,18 +130,27 @@ class WalletListBodyState extends State<WalletListBody> {
130 borderRadius: BorderRadius.only(
131 topLeft: Radius.circular(radius),
132 bottomLeft: Radius.circular(radius)),
129 - color: color),
133 + gradient: LinearGradient(
134 + begin: Alignment.topCenter,
135 + end: Alignment.bottomCenter,
136 + colors: [
137 + firstColor,
138 + secondColor
139 + ]
140 + )
141 + ),
142 child: Center(
143 child: Column(
144 mainAxisSize: MainAxisSize.min,
145 children: <Widget>[
146 image,
135 - SizedBox(height: 5),
147 + SizedBox(height: 2),
148 Text(
149 item,
150 textAlign: TextAlign.center,
151 style: TextStyle(
140 - fontSize: 12,
152 + fontSize: 7,
153 + fontWeight: FontWeight.w500,
154 color: Colors.white),
155 )
156 ],
@@ -159,9 +172,8 @@ class WalletListBodyState extends State<WalletListBody> {
172 Navigator.of(context).pushNamed(Routes.newWalletType),
173 image: newWalletImage,
174 text: S.of(context).wallet_list_create_new_wallet,
162 - color: Colors.white,
163 - textColor: Palette.oceanBlue,
164 - borderColor: Palette.oceanBlue,
175 + color: Theme.of(context).accentTextTheme.subtitle.decorationColor,
176 + textColor: Theme.of(context).accentTextTheme.headline.decorationColor,
177 ),
178 SizedBox(height: 10.0),
179 PrimaryImageButton(
@@ -169,7 +181,7 @@ class WalletListBodyState extends State<WalletListBody> {
181 .pushNamed(Routes.restoreWalletType),
182 image: restoreWalletImage,
183 text: S.of(context).wallet_list_restore_wallet,
172 - color: Theme.of(context).primaryTextTheme.overline.color,
184 + color: Theme.of(context).accentTextTheme.caption.color,
185 textColor: Theme.of(context).primaryTextTheme.title.color)
186 ])),
187 ));
lib/src/screens/wallet_list/wallet_menu.dart
+35 -15
@@ -6,6 +6,7 @@ import 'package:cake_wallet/generated/i18n.dart';
6 import 'package:cake_wallet/src/stores/wallet_list/wallet_list_store.dart';
7 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
8 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
9 +import 'package:cake_wallet/palette.dart';
10
11 class WalletMenu {
12 WalletMenu(this.context, this.walletListViewModel);
@@ -20,18 +21,25 @@ class WalletMenu {
21 S.current.rescan
22 ];
23
23 - final List<Color> listColors = [
24 - Colors.blue,
25 - Colors.orange,
26 - Colors.red,
27 - Colors.green
24 + final List<Color> firstColors = [
25 + Palette.cornflower,
26 + Palette.moderateOrangeYellow,
27 + Palette.lightRed,
28 + Palette.shineGreen
29 + ];
30 +
31 + final List<Color> secondColors = [
32 + Palette.royalBlue,
33 + Palette.moderateOrange,
34 + Palette.persianRed,
35 + Palette.moderateGreen
36 ];
37
38 final List<Image> listImages = [
31 - Image.asset('assets/images/load.png', height: 32, width: 32, color: Colors.white),
32 - Image.asset('assets/images/eye_action.png', height: 32, width: 32, color: Colors.white),
33 - Image.asset('assets/images/trash.png', height: 32, width: 32, color: Colors.white),
34 - Image.asset('assets/images/scanner.png', height: 32, width: 32, color: Colors.white)
39 + Image.asset('assets/images/load.png', height: 24, width: 24, color: Colors.white),
40 + Image.asset('assets/images/eye_action.png', height: 24, width: 24, color: Colors.white),
41 + Image.asset('assets/images/trash.png', height: 24, width: 24, color: Colors.white),
42 + Image.asset('assets/images/scanner.png', height: 24, width: 24, color: Colors.white)
43 ];
44
45 List<String> generateItemsForWalletMenu(bool isCurrentWallet) {
@@ -46,18 +54,30 @@ class WalletMenu {
54 }
55
56 List<Color> generateColorsForWalletMenu(bool isCurrentWallet) {
49 - final colors = List<Color>();
57 + final colors = <Color>[];
58
51 - if (!isCurrentWallet) colors.add(listColors[0]);
52 - if (isCurrentWallet) colors.add(listColors[1]);
53 - if (!isCurrentWallet) colors.add(listColors[2]);
54 - if (isCurrentWallet) colors.add(listColors[3]);
59 + if (!isCurrentWallet) {
60 + colors.add(firstColors[0]);
61 + colors.add(secondColors[0]);
62 + }
63 + if (isCurrentWallet) {
64 + colors.add(firstColors[1]);
65 + colors.add(secondColors[1]);
66 + }
67 + if (!isCurrentWallet) {
68 + colors.add(firstColors[2]);
69 + colors.add(secondColors[2]);
70 + }
71 + if (isCurrentWallet) {
72 + colors.add(firstColors[3]);
73 + colors.add(secondColors[3]);
74 + }
75
76 return colors;
77 }
78
79 List<Image> generateImagesForWalletMenu(bool isCurrentWallet) {
60 - final images = List<Image>();
80 + final images = <Image>[];
81
82 if (!isCurrentWallet) images.add(listImages[0]);
83 if (isCurrentWallet) images.add(listImages[1]);
lib/src/screens/wallet_list/widgets/wallet_tile.dart
+37 -30
@@ -17,17 +17,18 @@ class WalletTile extends SliverPersistentHeaderDelegate {
17 final String walletName;
18 final String walletAddress;
19 final bool isCurrent;
20 + final double tileHeight = 60;
21
22 @override
23 Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
24 var opacity = 1 - shrinkOffset / (max - min);
25 opacity = opacity >= 0 ? opacity : 0;
26
26 - var panelWidth = 12 * opacity;
27 - panelWidth = panelWidth < 12 ? 0 : 12;
27 + var panelWidth = 10 * opacity;
28 + panelWidth = panelWidth < 10 ? 0 : 10;
29
30 final currentColor = isCurrent
30 - ? Theme.of(context).accentTextTheme.caption.color
31 + ? Theme.of(context).accentTextTheme.subtitle.decorationColor
32 : Theme.of(context).backgroundColor;
33
34 return Stack(
@@ -38,7 +39,7 @@ class WalletTile extends SliverPersistentHeaderDelegate {
39 top: 0,
40 right: max - 4,
41 child: Container(
41 - height: 108,
42 + height: tileHeight,
43 width: 4,
44 decoration: BoxDecoration(
45 borderRadius: BorderRadius.only(topRight: Radius.circular(4), bottomRight: Radius.circular(4)),
@@ -48,13 +49,30 @@ class WalletTile extends SliverPersistentHeaderDelegate {
49 ),
50 Positioned(
51 top: 0,
51 - right: 12,
52 + right: 10,
53 child: Container(
53 - height: 108,
54 - width: max - 16,
54 + height: tileHeight,
55 + width: max - 14,
56 padding: EdgeInsets.only(left: 20, right: 20),
57 color: Theme.of(context).backgroundColor,
57 - child: Column(
58 + alignment: Alignment.centerLeft,
59 + child: Row(
60 + //mainAxisAlignment: MainAxisAlignment.start,
61 + crossAxisAlignment: CrossAxisAlignment.center,
62 + children: <Widget>[
63 + image,
64 + SizedBox(width: 10),
65 + Text(
66 + walletName,
67 + style: TextStyle(
68 + fontSize: 22,
69 + fontWeight: FontWeight.w600,
70 + color: Theme.of(context).primaryTextTheme.title.color
71 + ),
72 + )
73 + ],
74 + ),
75 + /*Column(
76 mainAxisSize: MainAxisSize.max,
77 mainAxisAlignment: MainAxisAlignment.center,
78 children: <Widget>[
@@ -92,7 +110,7 @@ class WalletTile extends SliverPersistentHeaderDelegate {
110 )
111 : Offstage()
112 ],
95 - ),
113 + ),*/
114 ),
115 ),
116 Positioned(
@@ -101,29 +119,18 @@ class WalletTile extends SliverPersistentHeaderDelegate {
119 child: Opacity(
120 opacity: opacity,
121 child: Container(
104 - height: 108,
122 + height: tileHeight,
123 width: panelWidth,
106 - padding: EdgeInsets.only(
107 - top: 1,
108 - left: 1,
109 - bottom: 1
110 - ),
124 decoration: BoxDecoration(
112 - borderRadius: BorderRadius.only(topLeft: Radius.circular(12), bottomLeft: Radius.circular(12)),
113 - color: Theme.of(context).accentTextTheme.subtitle.color
114 - ),
115 - child: Container(
116 - decoration: BoxDecoration(
117 - borderRadius: BorderRadius.only(topLeft: Radius.circular(12), bottomLeft: Radius.circular(12)),
118 - gradient: LinearGradient(
119 - begin: Alignment.topCenter,
120 - end: Alignment.bottomCenter,
121 - colors: [
122 - Theme.of(context).accentTextTheme.caption.backgroundColor,
123 - Theme.of(context).accentTextTheme.caption.decorationColor
124 - ]
125 - )
126 - ),
125 + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)),
126 + gradient: LinearGradient(
127 + begin: Alignment.topCenter,
128 + end: Alignment.bottomCenter,
129 + colors: [
130 + Theme.of(context).accentTextTheme.headline.color,
131 + Theme.of(context).accentTextTheme.headline.backgroundColor
132 + ]
133 + )
134 ),
135 ),
136 )
lib/src/widgets/checkbox_widget.dart new
+81
@@ -0,0 +1,81 @@
1 +import 'dart:ui';
2 +import 'package:cake_wallet/palette.dart';
3 +import 'package:flutter/cupertino.dart';
4 +import 'package:flutter/material.dart';
5 +
6 +class CheckboxWidget extends StatefulWidget {
7 + CheckboxWidget({
8 + @required this.value,
9 + @required this.caption,
10 + @required this.onChanged});
11 +
12 + final bool value;
13 + final String caption;
14 + final Function(bool) onChanged;
15 +
16 + @override
17 + CheckboxWidgetState createState() => CheckboxWidgetState(value, caption, onChanged);
18 +}
19 +
20 +class CheckboxWidgetState extends State<CheckboxWidget> {
21 + CheckboxWidgetState(this.value, this.caption, this.onChanged);
22 +
23 + bool value;
24 + String caption;
25 + Function(bool) onChanged;
26 +
27 + @override
28 + Widget build(BuildContext context) {
29 + return GestureDetector(
30 + onTap: () {
31 + value = !value;
32 + onChanged(value);
33 + setState(() {});
34 + },
35 + child: Row(
36 + mainAxisSize: MainAxisSize.min,
37 + mainAxisAlignment: MainAxisAlignment.start,
38 + children: <Widget>[
39 + Container(
40 + height: 16,
41 + width: 16,
42 + decoration: BoxDecoration(
43 + color: value
44 + ? Palette.blueCraiola
45 + : Theme.of(context).accentTextTheme.subhead.decorationColor,
46 + borderRadius: BorderRadius.all(Radius.circular(2)),
47 + border: Border.all(
48 + color: value
49 + ? Palette.blueCraiola
50 + : Theme.of(context).accentTextTheme.overline.color,
51 + width: 1
52 + )
53 + ),
54 + child: value
55 + ? Center(
56 + child: Icon(
57 + Icons.done,
58 + color: Colors.white,
59 + size: 14,
60 + ),
61 + )
62 + : Offstage(),
63 + ),
64 + Padding(
65 + padding: EdgeInsets.only(left: 16),
66 + child: Text(
67 + caption,
68 + style: TextStyle(
69 + color: Theme.of(context).primaryTextTheme.title.color,
70 + fontSize: 18,
71 + fontFamily: 'Poppins',
72 + fontWeight: FontWeight.w500,
73 + decoration: TextDecoration.none
74 + ),
75 + ),
76 + )
77 + ],
78 + ),
79 + );
80 + }
81 +}
\ No newline at end of file
lib/store/dashboard/trade_filter_store.dart
+1 -1
@@ -43,7 +43,7 @@ abstract class TradeFilterStoreBase with Store {
43 final needToFilter = !displayChangeNow || !displayXMRTO || !displayMorphToken;
44
45 return needToFilter
46 - ? trades
46 + ? _trades
47 .where((item) =>
48 (displayXMRTO &&
49 item.trade.provider == ExchangeProviderDescription.xmrto) ||
lib/themes.dart
+38 -24
@@ -132,19 +132,26 @@ class Themes {
132 subtitle: TextStyle(
133 color: Palette.darkBlueCraiola, // QR code (exchange trade page)
134 backgroundColor: Palette.wildPeriwinkle, // divider (exchange trade page)
135 -
136 -
137 -
138 - decorationColor: Palette.darkLavender // selected item
135 + decorationColor: Palette.blueCraiola // crete new wallet button background (wallet list page)
136 + ),
137 + headline: TextStyle(
138 + color: Palette.moderateLavender, // first gradient color of wallet action buttons (wallet list page)
139 + backgroundColor: Palette.moderateLavender, // second gradient color of wallet action buttons (wallet list page)
140 + decorationColor: Colors.white // restore wallet button text color (wallet list page)
141 + ),
142 + subhead: TextStyle(
143 + color: Palette.darkGray, // titles color (filter widget)
144 + backgroundColor: Palette.periwinkle, // divider color (filter widget)
145 + decorationColor: Colors.white // checkbox background (filter widget)
146 + ),
147 + overline: TextStyle(
148 + color: Palette.wildPeriwinkle, // checkbox bounds (filter widget)
149 + decorationColor: Colors.white, // menu subname
150 + ),
151 + display1: TextStyle(
152 + color: Palette.blueCraiola, // first gradient color (menu header)
153 + decorationColor: Palette.pinkFlamingo // second gradient color(menu header)
154 ),
140 -
141 -
142 -
143 -
144 - headline: TextStyle(
145 - color: Palette.darkLavender, // faq background
146 - backgroundColor: Palette.lavender // faq extension
147 - )
155 ),
156
157
@@ -288,19 +295,26 @@ class Themes {
295 subtitle: TextStyle(
296 color: PaletteDark.lightBlueGrey, // QR code (exchange trade page)
297 backgroundColor: PaletteDark.deepVioletBlue, // divider (exchange trade page)
291 -
292 -
293 -
294 - decorationColor: PaletteDark.headerNightBlue // selected item
298 + decorationColor: Colors.white // crete new wallet button background (wallet list page)
299 + ),
300 + headline: TextStyle(
301 + color: PaletteDark.distantBlue, // first gradient color of wallet action buttons (wallet list page)
302 + backgroundColor: PaletteDark.distantNightBlue, // second gradient color of wallet action buttons (wallet list page)
303 + decorationColor: Palette.darkBlueCraiola // restore wallet button text color (wallet list page)
304 + ),
305 + subhead: TextStyle(
306 + color: Colors.white, // titles color (filter widget)
307 + backgroundColor: PaletteDark.darkOceanBlue, // divider color (filter widget)
308 + decorationColor: PaletteDark.wildVioletBlue.withOpacity(0.3) // checkbox background (filter widget)
309 + ),
310 + overline: TextStyle(
311 + color: PaletteDark.wildVioletBlue, // checkbox bounds (filter widget)
312 + decorationColor: PaletteDark.darkCyanBlue, // menu subname
313 + ),
314 + display1: TextStyle(
315 + color: PaletteDark.deepPurpleBlue, // first gradient color (menu header)
316 + decorationColor: PaletteDark.deepPurpleBlue // second gradient color(menu header)
317 ),
296 -
297 -
298 -
299 -
300 - headline: TextStyle(
301 - color: PaletteDark.lightNightBlue, // faq background
302 - backgroundColor: PaletteDark.headerNightBlue // faq extension
303 - )
318 ),
319
320
lib/view_model/dashboard/dashboard_view_model.dart
+41
@@ -8,6 +8,7 @@ import 'package:cake_wallet/src/domain/common/transaction_info.dart';
8 import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
9 import 'package:cake_wallet/src/domain/exchange/trade.dart';
10 import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
11 +import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
12 import 'package:cake_wallet/view_model/dashboard/trade_list_item.dart';
13 import 'package:cake_wallet/view_model/dashboard/transaction_list_item.dart';
14 import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
@@ -35,6 +36,44 @@ abstract class DashboardViewModelBase with Store {
36 this.tradeFilterStore,
37 this.transactionFilterStore}) {
38
39 + filterItems = {S.current.transactions : [
40 + FilterItem(
41 + value: transactionFilterStore.displayIncoming,
42 + caption: S.current.incoming,
43 + onChanged: (value) => transactionFilterStore.toggleIncoming()
44 + ),
45 + FilterItem(
46 + value: transactionFilterStore.displayOutgoing,
47 + caption: S.current.outgoing,
48 + onChanged: (value) => transactionFilterStore.toggleOutgoing()
49 + ),
50 + FilterItem(
51 + value: false,
52 + caption: S.current.transactions_by_date,
53 + onChanged: null
54 + ),
55 + ],
56 + S.current.trades : [
57 + FilterItem(
58 + value: tradeFilterStore.displayXMRTO,
59 + caption: 'XMR.TO',
60 + onChanged: (value) => tradeFilterStore
61 + .toggleDisplayExchange(ExchangeProviderDescription.xmrto)
62 + ),
63 + FilterItem(
64 + value: tradeFilterStore.displayChangeNow,
65 + caption: 'Change.NOW',
66 + onChanged: (value) => tradeFilterStore
67 + .toggleDisplayExchange(ExchangeProviderDescription.changeNow)
68 + ),
69 + FilterItem(
70 + value: tradeFilterStore.displayMorphToken,
71 + caption: 'MorphToken',
72 + onChanged: (value) => tradeFilterStore
73 + .toggleDisplayExchange(ExchangeProviderDescription.morphToken)
74 + ),
75 + ]};
76 +
77 name = appStore.wallet?.name;
78 wallet ??= appStore.wallet;
79 type = wallet.type;
@@ -125,6 +164,8 @@ abstract class DashboardViewModelBase with Store {
164
165 TransactionFilterStore transactionFilterStore;
166
167 + Map<String, List<FilterItem>> filterItems;
168 +
169 ReactionDisposer _reaction;
170
171 void _onWalletChange(WalletBase wallet) {
lib/view_model/dashboard/filter_item.dart new
+7
@@ -0,0 +1,7 @@
1 +class FilterItem {
2 + FilterItem({this.value, this.caption, this.onChanged});
3 +
4 + bool value;
5 + String caption;
6 + Function(bool) onChanged;
7 +}
\ No newline at end of file
lib/view_model/exchange/exchange_trade_view_model.dart
+3 -2
@@ -35,7 +35,8 @@ abstract class ExchangeTradeViewModelBase with Store {
35 break;
36 }
37
38 - items = ObservableList.of([
38 + items = ObservableList<ExchangeTradeItem>();
39 + items.addAll([
40 ExchangeTradeItem(
41 title: S.current.id,
42 data: '${trade.id}',
@@ -69,7 +70,7 @@ abstract class ExchangeTradeViewModelBase with Store {
70 bool isSendable;
71
72 @observable
72 - ObservableList<ExchangeTradeItem> items;// = ObservableList();
73 + ObservableList<ExchangeTradeItem> items;
74
75 ExchangeProvider _provider;
76