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;