CAKE-28 | reworked standart_list_row (added image); applied new design, light and dark themes to exchange trade page
Oleksandr Sobol committed
Aug 27, 2020 at 22:42 UTC
56519bbe8607e3e4e12582ae9559e3bed5b66e7e
7 files changed
+182
-285
lib/src/screens/exchange_trade/exchange_trade_item.dart
+3
-3
@@ -7,7 +7,7 @@ class ExchangeTradeItem {
7
@required this.isCopied,
8
});
9
10
- final String title;
11
- final String data;
12
- final bool isCopied;
10
+ String title;
11
+ String data;
12
+ bool isCopied;
13
}
\ No newline at end of file
lib/src/screens/exchange_trade/exchange_trade_page.dart
+97
-252
@@ -3,6 +3,7 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
3
import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart';
4
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart';
5
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
6
+import 'package:cake_wallet/src/widgets/standart_list_row.dart';
7
import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
8
import 'package:mobx/mobx.dart';
9
import 'package:provider/provider.dart';
@@ -86,7 +87,6 @@ class ExchangeTradeForm extends StatefulWidget {
87
class ExchangeTradeState extends State<ExchangeTradeForm> {
88
final fetchingLabel = S.current.fetching;
89
String get title => S.current.exchange;
89
- List<ExchangeTradeItem> items;
90
91
bool _effectsInstalled = false;
92
@@ -94,25 +94,6 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
94
void initState() {
95
super.initState();
96
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
97
-
98
- items = [
99
- ExchangeTradeItem(
100
- title: S.current.id,
101
- data: '${widget.exchangeTradeViewModel.trade.id ?? fetchingLabel}',
102
- isCopied: true),
103
- ExchangeTradeItem(
104
- title: S.current.amount,
105
- data: '${widget.exchangeTradeViewModel.trade.amount ?? fetchingLabel}',
106
- isCopied: false),
107
- ExchangeTradeItem(
108
- title: S.current.status,
109
- data: '${widget.exchangeTradeViewModel.trade.state ?? fetchingLabel}',
110
- isCopied: false),
111
- ExchangeTradeItem(
112
- title: S.current.widgets_address,
113
- data: widget.exchangeTradeViewModel.trade.inputAddress ?? fetchingLabel,
114
- isCopied: true),
115
- ];
97
}
98
99
void afterLayout(dynamic _) {
@@ -121,257 +102,121 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
102
103
@override
104
Widget build(BuildContext context) {
105
+ final copyImage = Image.asset('assets/images/copy_content.png',
106
+ height: 16, width: 16,
107
+ color: Theme.of(context).primaryTextTheme.overline.color);
108
109
//_setEffects(context);
110
111
return Container(
112
child: ScrollableWithBottomSection(
129
- contentPadding: EdgeInsets.only(left: 24, right: 24, top: 24),
113
+ contentPadding: EdgeInsets.only(top: 10, bottom: 16),
114
content: Observer(builder: (_) {
115
final trade = widget.exchangeTradeViewModel.trade;
116
117
return Column(
134
- mainAxisAlignment: MainAxisAlignment.start,
135
- crossAxisAlignment: CrossAxisAlignment.start,
118
children: <Widget>[
137
- Container(
138
- child: Row(
139
- crossAxisAlignment: CrossAxisAlignment.start,
140
- children: [
141
- Column(
142
- crossAxisAlignment: CrossAxisAlignment.start,
143
- children: <Widget>[
144
- Row(
145
- mainAxisAlignment: MainAxisAlignment.start,
146
- children: <Widget>[
147
- Text(
148
- S.of(context).id,
149
- style: TextStyle(
150
- height: 2,
151
- fontWeight: FontWeight.bold,
152
- fontSize: 14.0,
153
- color: Theme.of(context).primaryTextTheme.title.color),
154
- ),
155
- Text(
156
- '${trade.id ?? fetchingLabel}',
157
- style: TextStyle(
158
- fontSize: 14.0,
159
- height: 2,
160
- color: Theme.of(context).primaryTextTheme.caption.color),
161
- )
162
- ],
163
- ),
164
- Row(
165
- mainAxisAlignment: MainAxisAlignment.start,
166
- children: <Widget>[
167
- Text(
168
- S.of(context).amount,
169
- style: TextStyle(
170
- height: 2,
171
- fontWeight: FontWeight.bold,
172
- fontSize: 14.0,
173
- color: Theme.of(context).primaryTextTheme.title.color),
174
- ),
175
- Text(
176
- '${trade.amount ?? fetchingLabel}',
177
- style: TextStyle(
178
- fontSize: 14.0,
179
- height: 2,
180
- color: Theme.of(context).primaryTextTheme.caption.color),
181
- )
182
- ],
183
- ),
184
- trade.extraId != null
185
- ? Row(
186
- mainAxisAlignment: MainAxisAlignment.start,
187
- children: <Widget>[
188
- Text(
189
- S.of(context).payment_id,
190
- style: TextStyle(
191
- height: 2,
192
- fontWeight: FontWeight.bold,
193
- fontSize: 14.0,
194
- color: Theme.of(context).primaryTextTheme.title.color),
195
- ),
196
- Text(
197
- '${trade.extraId ?? fetchingLabel}',
198
- style: TextStyle(
199
- fontSize: 14.0,
200
- height: 2,
201
- color: Theme.of(context).primaryTextTheme.caption.color),
202
- )
203
- ],
204
- )
205
- : Container(),
206
- Row(
207
- mainAxisAlignment: MainAxisAlignment.start,
208
- children: <Widget>[
209
- Text(
210
- S.of(context).status,
211
- style: TextStyle(
212
- fontSize: 14.0,
213
- fontWeight: FontWeight.bold,
214
- color: Theme.of(context).primaryTextTheme.title.color,
215
- height: 2),
216
- ),
217
- Text(
218
- '${trade.state ?? fetchingLabel}',
219
- style: TextStyle(
220
- fontSize: 14.0,
221
- height: 2,
222
- color: Theme.of(context).primaryTextTheme.caption.color),
223
- )
224
- ],
225
- ),
226
- trade.expiredAt != null
227
- ? Row(
228
- mainAxisAlignment: MainAxisAlignment.start,
229
- children: <Widget>[
230
- Text(
231
- S.of(context).offer_expires_in,
232
- style: TextStyle(
233
- fontSize: 14.0,
234
- color: Theme.of(context).primaryTextTheme.title.color),
235
- ),
236
- TimerWidget(trade.expiredAt,
237
- color: Theme.of(context).primaryTextTheme.caption.color)
238
- ],
239
- )
240
- : Container(),
241
- ],
242
- ),
243
- ],
244
- ),
245
- ),
246
- Padding(
247
- padding: EdgeInsets.only(top: 20),
248
- child: Row(
119
+ trade.expiredAt != null
120
+ ? Row(
121
+ mainAxisSize: MainAxisSize.max,
122
+ mainAxisAlignment: MainAxisAlignment.center,
123
children: <Widget>[
250
- Spacer(
251
- flex: 1,
252
- ),
253
- Flexible(
254
- flex: 1,
255
- child: Center(
256
- child: AspectRatio(
257
- aspectRatio: 1.0,
258
- child: QrImage(
259
- data: trade.inputAddress ?? fetchingLabel,
260
- backgroundColor: Colors.transparent,
261
- foregroundColor: Theme.of(context).primaryTextTheme.display4.color,
262
- ),
263
- ),
264
- )),
265
- Spacer(
266
- flex: 1,
267
- )
268
- ],
269
- ),
270
- ),
271
- SizedBox(
272
- height: 20.0,
273
- ),
274
- Center(
275
- child: Text(
276
- S.of(context).trade_is_powered_by(trade.provider != null
277
- ? trade.provider.title
278
- : fetchingLabel),
279
- textAlign: TextAlign.center,
280
- style: TextStyle(
281
- fontSize: 14.0,
282
- fontWeight: FontWeight.bold,
283
- color: Theme.of(context).primaryTextTheme.title.color),
284
- ),
285
- ),
286
- Container(
287
- padding: EdgeInsets.only(top: 20, bottom: 20),
288
- child: Center(
289
- child: Text(
290
- trade.inputAddress ?? fetchingLabel,
291
- textAlign: TextAlign.center,
124
+ Text(
125
+ S.of(context).offer_expires_in,
126
style: TextStyle(
293
- fontSize: 14.0,
294
- color: Theme.of(context).primaryTextTheme.caption.color),
127
+ fontSize: 14.0,
128
+ fontWeight: FontWeight.w500,
129
+ color: Theme.of(context).primaryTextTheme.overline.color),
130
),
296
- ),
131
+ TimerWidget(trade.expiredAt,
132
+ color: Theme.of(context).primaryTextTheme.title.color)
133
+ ])
134
+ : Offstage(),
135
+ Padding(
136
+ padding: EdgeInsets.only(top: 32),
137
+ child: Row(children: <Widget>[
138
+ Spacer(flex: 3),
139
+ Flexible(
140
+ flex: 4,
141
+ child: Center(
142
+ child: AspectRatio(
143
+ aspectRatio: 1.0,
144
+ child: QrImage(
145
+ data: trade.inputAddress ?? fetchingLabel,
146
+ backgroundColor: Colors.transparent,
147
+ foregroundColor: Theme.of(context)
148
+ .accentTextTheme.subtitle.color,
149
+ )))),
150
+ Spacer(flex: 3)
151
+ ]),
152
),
298
- Container(
299
- child: Row(
300
- children: <Widget>[
301
- Flexible(
302
- child: Container(
303
- padding: EdgeInsets.only(right: 5.0),
304
- child: Builder(
305
- builder: (context) => PrimaryButton(
306
- onPressed: () {
307
- Clipboard.setData(ClipboardData(text: trade.inputAddress));
308
- Scaffold.of(context).showSnackBar(SnackBar(
309
- content: Text(
310
- S.of(context).copied_to_clipboard,
311
- textAlign: TextAlign.center,
312
- style: TextStyle(color: Colors.white),
313
- ),
314
- backgroundColor: Colors.green,
315
- duration: Duration(milliseconds: 1500),
316
- ));
317
- },
318
- text: S.of(context).copy_address,
319
- color: Theme.of(context).accentTextTheme.title.backgroundColor,
320
- textColor: Theme.of(context).primaryTextTheme.title.color)
321
- ),
322
- )),
323
- Flexible(
324
- child: Container(
325
- padding: EdgeInsets.only(left: 5.0),
326
- child: Builder(
327
- builder: (context) => PrimaryButton(
328
- onPressed: () {
329
- Clipboard.setData(ClipboardData(text: trade.id));
330
- Scaffold.of(context).showSnackBar(SnackBar(
331
- content: Text(
332
- S.of(context).copied_to_clipboard,
333
- textAlign: TextAlign.center,
334
- style: TextStyle(color: Colors.white),
335
- ),
336
- backgroundColor: Colors.green,
337
- duration: Duration(milliseconds: 1500),
338
- ));
339
- },
340
- text: S.of(context).copy_id,
341
- color: Theme.of(context).accentTextTheme.title.backgroundColor,
342
- textColor: Theme.of(context).primaryTextTheme.title.color)
343
- ),
344
- ))
345
- ],
153
+ Padding(
154
+ padding: EdgeInsets.only(top: 16),
155
+ child: ListView.separated(
156
+ shrinkWrap: true,
157
+ physics: NeverScrollableScrollPhysics(),
158
+ itemCount: widget.exchangeTradeViewModel.items.length,
159
+ separatorBuilder: (context, index) => Container(
160
+ height: 1,
161
+ color: Theme.of(context).accentTextTheme.subtitle.backgroundColor,
162
+ ),
163
+ itemBuilder: (context, index) {
164
+ final item = widget.exchangeTradeViewModel.items[index];
165
+ String value;
166
+
167
+ final content = Observer(
168
+ builder: (_) {
169
+ switch (index) {
170
+ case 0:
171
+ value = '${widget.exchangeTradeViewModel.trade.id ?? fetchingLabel}';
172
+ break;
173
+ case 1:
174
+ value = '${widget.exchangeTradeViewModel.trade.amount ?? fetchingLabel}';
175
+ break;
176
+ case 2:
177
+ value = '${widget.exchangeTradeViewModel.trade.state ?? fetchingLabel}';
178
+ break;
179
+ case 3:
180
+ value = widget.exchangeTradeViewModel.trade.inputAddress ?? fetchingLabel;
181
+ break;
182
+ }
183
+
184
+ return StandartListRow(
185
+ title: item.title,
186
+ value: value,
187
+ valueFontSize: 14,
188
+ image: item.isCopied ? copyImage : null,
189
+ );
190
+ }
191
+ );
192
+
193
+ return item.isCopied
194
+ ? Builder(
195
+ builder: (context) =>
196
+ GestureDetector(
197
+ onTap: () {
198
+ Clipboard.setData(ClipboardData(text: value));
199
+ Scaffold.of(context).showSnackBar(SnackBar(
200
+ content: Text(
201
+ S.of(context).copied_to_clipboard,
202
+ textAlign: TextAlign.center,
203
+ style: TextStyle(color: Colors.white),
204
+ ),
205
+ backgroundColor: Colors.green,
206
+ duration: Duration(milliseconds: 1500),
207
+ ));
208
+ },
209
+ child: content,
210
+ )
211
+ )
212
+ : content;
213
+ },
214
),
215
),
348
- /*Container(
349
- padding: EdgeInsets.only(top: 20),
350
- child: Text(
351
- widget.exchangeTradeViewModel.isSendable
352
- ? S.of(context).exchange_result_confirm(
353
- trade.amount ?? fetchingLabel,
354
- trade.from.toString(),
355
- walletName)
356
- : S.of(context).exchange_result_description(
357
- trade.amount ?? fetchingLabel, trade.from.toString()),
358
- textAlign: TextAlign.left,
359
- style: TextStyle(
360
- fontSize: 13.0,
361
- color: Theme.of(context).primaryTextTheme.title.color),
362
- ),
363
- ),*/
364
- Text(
365
- S.of(context).exchange_result_write_down_ID,
366
- textAlign: TextAlign.left,
367
- style: TextStyle(
368
- fontSize: 13.0,
369
- color: Theme.of(context).primaryTextTheme.title.color),
370
- )
216
],
217
);
218
}),
374
- bottomSectionPadding: EdgeInsets.all(24),
219
+ bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
220
bottomSection: PrimaryButton(
221
onPressed: () {},
222
text: S.of(context).confirm,
lib/src/screens/exchange_trade/widgets/exchange_trade_row.dart
deleted
-8
@@ -1,8 +0,0 @@
1
-import 'package:flutter/material.dart';
2
-
3
-class ExchangeTradeRow extends StatelessWidget {
4
- @override
5
- Widget build(BuildContext context) {
6
- return Container();
7
- }
8
-}
\ No newline at end of file
lib/src/screens/exchange_trade/widgets/timer_widget.dart
+8
-2
@@ -53,10 +53,16 @@ class TimerWidgetState extends State<TimerWidget> {
53
Widget build(BuildContext context) {
54
return _isExpired
55
? Text(S.of(context).expired,
56
- style: TextStyle(fontSize: 14.0, color: Colors.red))
56
+ style: TextStyle(
57
+ fontSize: 14.0,
58
+ fontWeight: FontWeight.w500,
59
+ color: Colors.red))
60
: Text(
61
S.of(context).time(_minutes.toString(), _seconds.toString()),
59
- style: TextStyle(fontSize: 14.0, color: widget.color),
62
+ style: TextStyle(
63
+ fontSize: 14.0,
64
+ fontWeight: FontWeight.w500,
65
+ color: widget.color),
66
);
67
}
68
lib/src/widgets/standart_list_row.dart
+32
-10
@@ -1,13 +1,20 @@
1
+import 'package:flutter/cupertino.dart';
2
import 'package:flutter/material.dart';
3
4
class StandartListRow extends StatelessWidget {
5
StandartListRow(
6
{this.title,
7
this.value,
8
+ this.titleFontSize = 14,
9
+ this.valueFontSize = 16,
10
+ this.image,
11
this.isDrawBottom = false});
12
13
final String title;
14
final String value;
15
+ final double titleFontSize;
16
+ final double valueFontSize;
17
+ final Image image;
18
final bool isDrawBottom;
19
20
@override
@@ -19,27 +26,42 @@ class StandartListRow extends StatelessWidget {
26
color: Theme.of(context).backgroundColor,
27
child: Padding(
28
padding:
22
- const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
29
+ const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
30
child: Column(
31
crossAxisAlignment: CrossAxisAlignment.start,
32
children: <Widget>[
33
Text(title,
34
style: TextStyle(
28
- fontSize: 14,
35
+ fontSize: titleFontSize,
36
fontWeight: FontWeight.w500,
37
color:
38
Theme.of(context).primaryTextTheme.overline.color),
39
textAlign: TextAlign.left),
40
Padding(
41
padding: const EdgeInsets.only(top: 12),
35
- child: Text(value,
36
- style: TextStyle(
37
- fontSize: 16,
38
- fontWeight: FontWeight.w500,
39
- color: Theme.of(context)
40
- .primaryTextTheme
41
- .title
42
- .color)),
42
+ child: Row(
43
+ mainAxisSize: MainAxisSize.max,
44
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
45
+ crossAxisAlignment: CrossAxisAlignment.start,
46
+ children: <Widget>[
47
+ Expanded(
48
+ child: Text(value,
49
+ style: TextStyle(
50
+ fontSize: valueFontSize,
51
+ fontWeight: FontWeight.w500,
52
+ color: Theme.of(context)
53
+ .primaryTextTheme
54
+ .title
55
+ .color)),
56
+ ),
57
+ image != null
58
+ ? Padding(
59
+ padding: EdgeInsets.only(left: 24),
60
+ child: image,
61
+ )
62
+ : Offstage()
63
+ ],
64
+ ),
65
)
66
]),
67
),
lib/themes.dart
+18
-10
@@ -129,14 +129,18 @@ class Themes {
129
backgroundColor: Palette.moderateLavender, // button background (confirm exchange)
130
decorationColor: Palette.darkBlueCraiola, // text color (information page)
131
),
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
139
+ ),
140
+
141
142
143
135
- subtitle: TextStyle(
136
- color: Palette.lightBlueGrey, // border color, wallet label
137
- backgroundColor: Palette.lavender, // address field, wallet card
138
- decorationColor: Palette.darkLavender // selected item
139
- ),
144
headline: TextStyle(
145
color: Palette.darkLavender, // faq background
146
backgroundColor: Palette.lavender // faq extension
@@ -281,14 +285,18 @@ class Themes {
285
backgroundColor: PaletteDark.deepVioletBlue, // button background (confirm exchange)
286
decorationColor: Palette.darkLavender, // text color (information page)
287
),
288
+ subtitle: TextStyle(
289
+ color: PaletteDark.lightBlueGrey, // QR code (exchange trade page)
290
+ backgroundColor: PaletteDark.deepVioletBlue, // divider (exchange trade page)
291
+
292
+
293
+
294
+ decorationColor: PaletteDark.headerNightBlue // selected item
295
+ ),
296
+
297
298
299
287
- subtitle: TextStyle(
288
- color: PaletteDark.darkNightBlue, // border color, wallet label
289
- backgroundColor: PaletteDark.violetBlue, // address field, wallet card
290
- decorationColor: PaletteDark.headerNightBlue // selected item
291
- ),
300
headline: TextStyle(
301
color: PaletteDark.lightNightBlue, // faq background
302
backgroundColor: PaletteDark.headerNightBlue // faq extension
lib/view_model/exchange/exchange_trade_view_model.dart
+24
@@ -9,6 +9,8 @@ import 'package:cake_wallet/src/domain/exchange/xmrto/xmrto_exchange_provider.da
9
import 'package:cake_wallet/store/dashboard/trades_store.dart';
10
import 'package:hive/hive.dart';
11
import 'package:mobx/mobx.dart';
12
+import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart';
13
+import 'package:cake_wallet/generated/i18n.dart';
14
15
part 'exchange_trade_view_model.g.dart';
16
@@ -33,6 +35,25 @@ abstract class ExchangeTradeViewModelBase with Store {
35
break;
36
}
37
38
+ items = ObservableList.of([
39
+ ExchangeTradeItem(
40
+ title: S.current.id,
41
+ data: '${trade.id}',
42
+ isCopied: true),
43
+ ExchangeTradeItem(
44
+ title: S.current.amount,
45
+ data: '${trade.amount}',
46
+ isCopied: false),
47
+ ExchangeTradeItem(
48
+ title: S.current.status,
49
+ data: '${trade.state}',
50
+ isCopied: false),
51
+ ExchangeTradeItem(
52
+ title: S.current.widgets_address + ':',
53
+ data: trade.inputAddress,
54
+ isCopied: true),
55
+ ]);
56
+
57
_updateTrade();
58
_timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
59
}
@@ -47,6 +68,9 @@ abstract class ExchangeTradeViewModelBase with Store {
68
@observable
69
bool isSendable;
70
71
+ @observable
72
+ ObservableList<ExchangeTradeItem> items;// = ObservableList();
73
+
74
ExchangeProvider _provider;
75
76
Timer _timer;