CWA-198 | moved ButtonHeader class to button_header.dart, fixed containers and bounds height for date_section_raw, trade_raw and transaction_raw, changed animation time for trade_history panel
Oleksandr Sobol committed
Apr 21, 2020 at 17:31 UTC
52d5dedaf82b95f3a7cb12db4263c391d297325b
5 files changed
+308
-297
lib/src/screens/dashboard/widgets/button_header.dart
new
+297
@@ -0,0 +1,297 @@
1
+import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
2
+import 'package:cake_wallet/src/stores/action_list/action_list_store.dart';
3
+import 'package:flutter/cupertino.dart';
4
+import 'package:flutter/material.dart';
5
+import 'package:cake_wallet/palette.dart';
6
+import 'package:cake_wallet/generated/i18n.dart';
7
+import 'package:flutter_mobx/flutter_mobx.dart';
8
+import 'package:provider/provider.dart';
9
+import 'package:cake_wallet/routes.dart';
10
+import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
11
+
12
+class ButtonHeader extends SliverPersistentHeaderDelegate {
13
+ final sendImage = Image.asset('assets/images/send.png');
14
+ final exchangeImage = Image.asset('assets/images/exchange.png');
15
+ final buyImage = Image.asset('assets/images/coins.png');
16
+ final filterButton = Image.asset('assets/images/filter_button.png');
17
+
18
+ @override
19
+ Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
20
+ final actionListStore = Provider.of<ActionListStore>(context);
21
+ final historyPanelWidth = MediaQuery.of(context).size.width;
22
+
23
+ double buttonsOpacity = 1 - shrinkOffset / (maxExtent - minExtent);
24
+ double buttonsHeight = maxExtent - minExtent - shrinkOffset;
25
+
26
+ buttonsOpacity = buttonsOpacity >= 0 ? buttonsOpacity : 0;
27
+ buttonsHeight = buttonsHeight >= 0 ? buttonsHeight : 0;
28
+
29
+ return Stack(
30
+ fit: StackFit.expand,
31
+ overflow: Overflow.visible,
32
+ children: <Widget>[
33
+ Opacity(
34
+ opacity: buttonsOpacity,
35
+ child: Container(
36
+ height: buttonsHeight,
37
+ padding: EdgeInsets.only(left: 44, right: 44),
38
+ child: Row(
39
+ children: <Widget>[
40
+ Flexible(
41
+ child: actionButton(
42
+ context: context,
43
+ image: sendImage,
44
+ title: S.of(context).send,
45
+ route: Routes.send
46
+ )
47
+ ),
48
+ Flexible(
49
+ child: actionButton(
50
+ context: context,
51
+ image: exchangeImage,
52
+ title: S.of(context).exchange,
53
+ route: Routes.exchange
54
+ )
55
+ ),
56
+ Flexible(
57
+ child: actionButton(
58
+ context: context,
59
+ image: buyImage,
60
+ title: S.of(context).buy,
61
+ route: ''
62
+ )
63
+ )
64
+ ],
65
+ ),
66
+ ),
67
+ ),
68
+ Positioned(
69
+ top: buttonsHeight,
70
+ left: 0,
71
+ child: Container(
72
+ width: historyPanelWidth,
73
+ height: 66,
74
+ padding: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 10),
75
+ decoration: BoxDecoration(
76
+ borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
77
+ color: PaletteDark.historyPanel,
78
+ ),
79
+ child: Stack(
80
+ alignment: Alignment.center,
81
+ children: <Widget>[
82
+ Text(
83
+ S.of(context).trade_history_title,
84
+ style: TextStyle(
85
+ fontSize: 20,
86
+ color: Colors.white
87
+ ),
88
+ ),
89
+ Positioned(
90
+ right: 0,
91
+ child: PopupMenuButton<int>(
92
+ itemBuilder: (context) => [
93
+ PopupMenuItem(
94
+ enabled: false,
95
+ value: -1,
96
+ child: Text(S.of(context).transactions,
97
+ style: TextStyle(
98
+ fontWeight: FontWeight.bold,
99
+ color: Theme.of(context).primaryTextTheme.caption.color))),
100
+ PopupMenuItem(
101
+ value: 0,
102
+ child: Observer(
103
+ builder: (_) => Row(
104
+ mainAxisAlignment:
105
+ MainAxisAlignment
106
+ .spaceBetween,
107
+ children: [
108
+ Text(S.of(context).incoming),
109
+ Checkbox(
110
+ value: actionListStore
111
+ .transactionFilterStore
112
+ .displayIncoming,
113
+ onChanged: (value) =>
114
+ actionListStore
115
+ .transactionFilterStore
116
+ .toggleIncoming(),
117
+ )
118
+ ]))),
119
+ PopupMenuItem(
120
+ value: 1,
121
+ child: Observer(
122
+ builder: (_) => Row(
123
+ mainAxisAlignment:
124
+ MainAxisAlignment
125
+ .spaceBetween,
126
+ children: [
127
+ Text(S.of(context).outgoing),
128
+ Checkbox(
129
+ value: actionListStore
130
+ .transactionFilterStore
131
+ .displayOutgoing,
132
+ onChanged: (value) =>
133
+ actionListStore
134
+ .transactionFilterStore
135
+ .toggleOutgoing(),
136
+ )
137
+ ]))),
138
+ PopupMenuItem(
139
+ value: 2,
140
+ child:
141
+ Text(S.of(context).transactions_by_date)),
142
+ PopupMenuDivider(),
143
+ PopupMenuItem(
144
+ enabled: false,
145
+ value: -1,
146
+ child: Text(S.of(context).trades,
147
+ style: TextStyle(
148
+ fontWeight: FontWeight.bold,
149
+ color: Theme.of(context).primaryTextTheme.caption.color))),
150
+ PopupMenuItem(
151
+ value: 3,
152
+ child: Observer(
153
+ builder: (_) => Row(
154
+ mainAxisAlignment:
155
+ MainAxisAlignment
156
+ .spaceBetween,
157
+ children: [
158
+ Text('XMR.TO'),
159
+ Checkbox(
160
+ value: actionListStore
161
+ .tradeFilterStore
162
+ .displayXMRTO,
163
+ onChanged: (value) =>
164
+ actionListStore
165
+ .tradeFilterStore
166
+ .toggleDisplayExchange(
167
+ ExchangeProviderDescription
168
+ .xmrto),
169
+ )
170
+ ]))),
171
+ PopupMenuItem(
172
+ value: 4,
173
+ child: Observer(
174
+ builder: (_) => Row(
175
+ mainAxisAlignment:
176
+ MainAxisAlignment
177
+ .spaceBetween,
178
+ children: [
179
+ Text('Change.NOW'),
180
+ Checkbox(
181
+ value: actionListStore
182
+ .tradeFilterStore
183
+ .displayChangeNow,
184
+ onChanged: (value) =>
185
+ actionListStore
186
+ .tradeFilterStore
187
+ .toggleDisplayExchange(
188
+ ExchangeProviderDescription
189
+ .changeNow),
190
+ )
191
+ ]))),
192
+ PopupMenuItem(
193
+ value: 5,
194
+ child: Observer(
195
+ builder: (_) => Row(
196
+ mainAxisAlignment:
197
+ MainAxisAlignment
198
+ .spaceBetween,
199
+ children: [
200
+ Text('MorphToken'),
201
+ Checkbox(
202
+ value: actionListStore
203
+ .tradeFilterStore
204
+ .displayMorphToken,
205
+ onChanged: (value) =>
206
+ actionListStore
207
+ .tradeFilterStore
208
+ .toggleDisplayExchange(
209
+ ExchangeProviderDescription
210
+ .morphToken),
211
+ )
212
+ ])))
213
+ ],
214
+ child: filterButton,
215
+ onSelected: (item) async {
216
+ if (item == 2) {
217
+ final List<DateTime> picked =
218
+ await date_rage_picker.showDatePicker(
219
+ context: context,
220
+ initialFirstDate: DateTime.now()
221
+ .subtract(Duration(days: 1)),
222
+ initialLastDate: (DateTime.now()),
223
+ firstDate: DateTime(2015),
224
+ lastDate: DateTime.now()
225
+ .add(Duration(days: 1)));
226
+
227
+ if (picked != null && picked.length == 2) {
228
+ actionListStore.transactionFilterStore
229
+ .changeStartDate(picked.first);
230
+ actionListStore.transactionFilterStore
231
+ .changeEndDate(picked.last);
232
+ }
233
+ }
234
+ },
235
+ ),
236
+ )
237
+ ],
238
+ ),
239
+ )
240
+ )
241
+ ],
242
+ );
243
+ }
244
+
245
+ @override
246
+ double get maxExtent => 174;
247
+
248
+ @override
249
+ double get minExtent => 66;
250
+
251
+ @override
252
+ bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
253
+
254
+ Widget actionButton({
255
+ BuildContext context,
256
+ @required Image image,
257
+ @required String title,
258
+ @required String route}) {
259
+
260
+ return Container(
261
+ width: MediaQuery.of(context).size.width,
262
+ child: Column(
263
+ mainAxisAlignment: MainAxisAlignment.start,
264
+ crossAxisAlignment: CrossAxisAlignment.center,
265
+ children: <Widget>[
266
+ GestureDetector(
267
+ onTap: () {
268
+ if (route.isNotEmpty) {
269
+ Navigator.of(context, rootNavigator: true).pushNamed(route);
270
+ }
271
+ },
272
+ child: Container(
273
+ height: 48,
274
+ width: 48,
275
+ alignment: Alignment.center,
276
+ decoration: BoxDecoration(
277
+ color: Colors.white,
278
+ shape: BoxShape.circle
279
+ ),
280
+ child: image,
281
+ ),
282
+ ),
283
+ Padding(
284
+ padding: EdgeInsets.only(top: 10),
285
+ child: Text(
286
+ title,
287
+ style: TextStyle(
288
+ fontSize: 16,
289
+ color: PaletteDark.walletCardText
290
+ ),
291
+ ),
292
+ )
293
+ ],
294
+ ),
295
+ );
296
+ }
297
+}
\ No newline at end of file
lib/src/screens/dashboard/widgets/date_section_raw.dart
+1
@@ -36,6 +36,7 @@ class DateSectionRaw extends StatelessWidget {
36
}
37
38
return Container(
39
+ height: 36,
40
padding: EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20),
41
alignment: Alignment.center,
42
decoration: BoxDecoration(
lib/src/screens/dashboard/widgets/trade_history_panel.dart
+6
-295
@@ -1,5 +1,4 @@
1
import 'package:cake_wallet/src/domain/common/balance_display_mode.dart';
2
-import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
2
import 'package:cake_wallet/src/stores/action_list/action_list_store.dart';
3
import 'package:cake_wallet/src/stores/action_list/date_section_item.dart';
4
import 'package:cake_wallet/src/stores/action_list/trade_list_item.dart';
@@ -8,7 +7,6 @@ import 'package:cake_wallet/src/stores/settings/settings_store.dart';
7
import 'package:flutter/cupertino.dart';
8
import 'package:flutter/material.dart';
9
import 'package:cake_wallet/palette.dart';
11
-import 'package:cake_wallet/generated/i18n.dart';
10
import 'package:flutter_mobx/flutter_mobx.dart';
11
import 'package:intl/intl.dart';
12
import 'package:provider/provider.dart';
@@ -16,7 +14,7 @@ import 'package:cake_wallet/routes.dart';
14
import 'date_section_raw.dart';
15
import 'trade_row.dart';
16
import 'transaction_raw.dart';
19
-import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
17
+import 'button_header.dart';
18
19
class TradeHistoryPanel extends StatefulWidget {
20
@override
@@ -58,7 +56,7 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
56
child: AnimatedContainer(
57
width: MediaQuery.of(context).size.width,
58
height: panelHeight,
61
- duration: Duration(milliseconds: 500),
59
+ duration: Duration(milliseconds: 1000),
60
curve: Curves.fastOutSlowIn,
61
child: CustomScrollView(
62
slivers: <Widget>[
@@ -75,7 +73,7 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
73
: actionListStore.items;
74
final itemsCount = items.length + 1;
75
final symbol = settingsStore.fiatCurrency.toString();
78
- double freeSpaceHeight = MediaQuery.of(context).size.height - 496; // FIXME
76
+ double freeSpaceHeight = MediaQuery.of(context).size.height - 496;
77
78
return SliverList(
79
key: _listKey,
@@ -95,12 +93,12 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
93
final item = items[index];
94
95
if (item is DateSectionItem) {
98
- freeSpaceHeight -= 32; // FIXME
96
+ freeSpaceHeight -= 38;
97
return DateSectionRaw(date: item.date);
98
}
99
100
if (item is TransactionListItem) {
103
- freeSpaceHeight -= 45; // FIXME
101
+ freeSpaceHeight -= 58;
102
final transaction = item.transaction;
103
final savedDisplayMode = settingsStore.balanceDisplayMode;
104
final formattedAmount =
@@ -125,7 +123,7 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
123
}
124
125
if (item is TradeListItem) {
128
- freeSpaceHeight -= 45; // FIXME
126
+ freeSpaceHeight -= 58;
127
final trade = item.trade;
128
final savedDisplayMode = settingsStore.balanceDisplayMode;
129
final formattedAmount = trade.amount != null
@@ -159,291 +157,4 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
157
),
158
);
159
}
162
-}
163
-
164
-class ButtonHeader extends SliverPersistentHeaderDelegate {
165
- final sendImage = Image.asset('assets/images/send.png');
166
- final exchangeImage = Image.asset('assets/images/exchange.png');
167
- final buyImage = Image.asset('assets/images/coins.png');
168
- final filterButton = Image.asset('assets/images/filter_button.png');
169
-
170
- @override
171
- Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
172
- final actionListStore = Provider.of<ActionListStore>(context);
173
- final historyPanelWidth = MediaQuery.of(context).size.width;
174
-
175
- double buttonsOpacity = 1 - shrinkOffset / (maxExtent - minExtent);
176
- double buttonsHeight = maxExtent - minExtent - shrinkOffset;
177
-
178
- buttonsOpacity = buttonsOpacity >= 0 ? buttonsOpacity : 0;
179
- buttonsHeight = buttonsHeight >= 0 ? buttonsHeight : 0;
180
-
181
- return Stack(
182
- fit: StackFit.expand,
183
- overflow: Overflow.visible,
184
- children: <Widget>[
185
- Opacity(
186
- opacity: buttonsOpacity,
187
- child: Container(
188
- height: buttonsHeight,
189
- padding: EdgeInsets.only(left: 44, right: 44),
190
- child: Row(
191
- children: <Widget>[
192
- Flexible(
193
- child: actionButton(
194
- context: context,
195
- image: sendImage,
196
- title: S.of(context).send,
197
- route: Routes.send
198
- )
199
- ),
200
- Flexible(
201
- child: actionButton(
202
- context: context,
203
- image: exchangeImage,
204
- title: S.of(context).exchange,
205
- route: Routes.exchange
206
- )
207
- ),
208
- Flexible(
209
- child: actionButton(
210
- context: context,
211
- image: buyImage,
212
- title: S.of(context).buy,
213
- route: ''
214
- )
215
- )
216
- ],
217
- ),
218
- ),
219
- ),
220
- Positioned(
221
- top: buttonsHeight,
222
- left: 0,
223
- child: Container(
224
- width: historyPanelWidth,
225
- height: 66,
226
- padding: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 10),
227
- decoration: BoxDecoration(
228
- borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)),
229
- color: PaletteDark.historyPanel,
230
- ),
231
- child: Stack(
232
- alignment: Alignment.center,
233
- children: <Widget>[
234
- Text(
235
- S.of(context).trade_history_title,
236
- style: TextStyle(
237
- fontSize: 20,
238
- color: Colors.white
239
- ),
240
- ),
241
- Positioned(
242
- right: 0,
243
- child: PopupMenuButton<int>(
244
- itemBuilder: (context) => [
245
- PopupMenuItem(
246
- enabled: false,
247
- value: -1,
248
- child: Text(S.of(context).transactions,
249
- style: TextStyle(
250
- fontWeight: FontWeight.bold,
251
- color: Theme.of(context).primaryTextTheme.caption.color))),
252
- PopupMenuItem(
253
- value: 0,
254
- child: Observer(
255
- builder: (_) => Row(
256
- mainAxisAlignment:
257
- MainAxisAlignment
258
- .spaceBetween,
259
- children: [
260
- Text(S.of(context).incoming),
261
- Checkbox(
262
- value: actionListStore
263
- .transactionFilterStore
264
- .displayIncoming,
265
- onChanged: (value) =>
266
- actionListStore
267
- .transactionFilterStore
268
- .toggleIncoming(),
269
- )
270
- ]))),
271
- PopupMenuItem(
272
- value: 1,
273
- child: Observer(
274
- builder: (_) => Row(
275
- mainAxisAlignment:
276
- MainAxisAlignment
277
- .spaceBetween,
278
- children: [
279
- Text(S.of(context).outgoing),
280
- Checkbox(
281
- value: actionListStore
282
- .transactionFilterStore
283
- .displayOutgoing,
284
- onChanged: (value) =>
285
- actionListStore
286
- .transactionFilterStore
287
- .toggleOutgoing(),
288
- )
289
- ]))),
290
- PopupMenuItem(
291
- value: 2,
292
- child:
293
- Text(S.of(context).transactions_by_date)),
294
- PopupMenuDivider(),
295
- PopupMenuItem(
296
- enabled: false,
297
- value: -1,
298
- child: Text(S.of(context).trades,
299
- style: TextStyle(
300
- fontWeight: FontWeight.bold,
301
- color: Theme.of(context).primaryTextTheme.caption.color))),
302
- PopupMenuItem(
303
- value: 3,
304
- child: Observer(
305
- builder: (_) => Row(
306
- mainAxisAlignment:
307
- MainAxisAlignment
308
- .spaceBetween,
309
- children: [
310
- Text('XMR.TO'),
311
- Checkbox(
312
- value: actionListStore
313
- .tradeFilterStore
314
- .displayXMRTO,
315
- onChanged: (value) =>
316
- actionListStore
317
- .tradeFilterStore
318
- .toggleDisplayExchange(
319
- ExchangeProviderDescription
320
- .xmrto),
321
- )
322
- ]))),
323
- PopupMenuItem(
324
- value: 4,
325
- child: Observer(
326
- builder: (_) => Row(
327
- mainAxisAlignment:
328
- MainAxisAlignment
329
- .spaceBetween,
330
- children: [
331
- Text('Change.NOW'),
332
- Checkbox(
333
- value: actionListStore
334
- .tradeFilterStore
335
- .displayChangeNow,
336
- onChanged: (value) =>
337
- actionListStore
338
- .tradeFilterStore
339
- .toggleDisplayExchange(
340
- ExchangeProviderDescription
341
- .changeNow),
342
- )
343
- ]))),
344
- PopupMenuItem(
345
- value: 5,
346
- child: Observer(
347
- builder: (_) => Row(
348
- mainAxisAlignment:
349
- MainAxisAlignment
350
- .spaceBetween,
351
- children: [
352
- Text('MorphToken'),
353
- Checkbox(
354
- value: actionListStore
355
- .tradeFilterStore
356
- .displayMorphToken,
357
- onChanged: (value) =>
358
- actionListStore
359
- .tradeFilterStore
360
- .toggleDisplayExchange(
361
- ExchangeProviderDescription
362
- .morphToken),
363
- )
364
- ])))
365
- ],
366
- child: filterButton,
367
- onSelected: (item) async {
368
- if (item == 2) {
369
- final List<DateTime> picked =
370
- await date_rage_picker.showDatePicker(
371
- context: context,
372
- initialFirstDate: DateTime.now()
373
- .subtract(Duration(days: 1)),
374
- initialLastDate: (DateTime.now()),
375
- firstDate: DateTime(2015),
376
- lastDate: DateTime.now()
377
- .add(Duration(days: 1)));
378
-
379
- if (picked != null && picked.length == 2) {
380
- actionListStore.transactionFilterStore
381
- .changeStartDate(picked.first);
382
- actionListStore.transactionFilterStore
383
- .changeEndDate(picked.last);
384
- }
385
- }
386
- },
387
- ),
388
- )
389
- ],
390
- ),
391
- )
392
- )
393
- ],
394
- );
395
- }
396
-
397
- @override
398
- double get maxExtent => 174;
399
-
400
- @override
401
- double get minExtent => 66;
402
-
403
- @override
404
- bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
405
-
406
- Widget actionButton({
407
- BuildContext context,
408
- @required Image image,
409
- @required String title,
410
- @required String route}) {
411
-
412
- return Container(
413
- width: MediaQuery.of(context).size.width,
414
- child: Column(
415
- mainAxisAlignment: MainAxisAlignment.start,
416
- crossAxisAlignment: CrossAxisAlignment.center,
417
- children: <Widget>[
418
- GestureDetector(
419
- onTap: () {
420
- if (route.isNotEmpty) {
421
- Navigator.of(context, rootNavigator: true).pushNamed(route);
422
- }
423
- },
424
- child: Container(
425
- height: 48,
426
- width: 48,
427
- alignment: Alignment.center,
428
- decoration: BoxDecoration(
429
- color: Colors.white,
430
- shape: BoxShape.circle
431
- ),
432
- child: image,
433
- ),
434
- ),
435
- Padding(
436
- padding: EdgeInsets.only(top: 10),
437
- child: Text(
438
- title,
439
- style: TextStyle(
440
- fontSize: 16,
441
- color: PaletteDark.walletCardText
442
- ),
443
- ),
444
- )
445
- ],
446
- ),
447
- );
448
- }
160
}
\ No newline at end of file
lib/src/screens/dashboard/widgets/trade_row.dart
+2
-1
@@ -26,10 +26,11 @@ class TradeRow extends StatelessWidget {
26
return InkWell(
27
onTap: onTap,
28
child: Container(
29
+ height: 56,
30
decoration: BoxDecoration(
31
color: PaletteDark.historyPanel,
32
border: Border.all(
32
- width: 0.5,
33
+ width: 1,
34
color: PaletteDark.historyPanel
35
),
36
),
lib/src/screens/dashboard/widgets/transaction_raw.dart
+2
-1
@@ -24,10 +24,11 @@ class TransactionRow extends StatelessWidget {
24
return InkWell(
25
onTap: onTap,
26
child: Container(
27
+ height: 56,
28
decoration: BoxDecoration(
29
color: PaletteDark.historyPanel,
30
border: Border.all(
30
- width: 0.5,
31
+ width: 1,
32
color: PaletteDark.historyPanel
33
),
34
),