diff --git a/assets/images/2.0x/coins.png b/assets/images/2.0x/coins.png new file mode 100644 index 000000000..c96e6e48c Binary files /dev/null and b/assets/images/2.0x/coins.png differ diff --git a/assets/images/2.0x/down_arrow.png b/assets/images/2.0x/down_arrow.png new file mode 100644 index 000000000..2033ba4e5 Binary files /dev/null and b/assets/images/2.0x/down_arrow.png differ diff --git a/assets/images/2.0x/exchange.png b/assets/images/2.0x/exchange.png new file mode 100644 index 000000000..a13680225 Binary files /dev/null and b/assets/images/2.0x/exchange.png differ diff --git a/assets/images/2.0x/filter_button.png b/assets/images/2.0x/filter_button.png new file mode 100644 index 000000000..767e4e561 Binary files /dev/null and b/assets/images/2.0x/filter_button.png differ diff --git a/assets/images/2.0x/menu_button.png b/assets/images/2.0x/menu_button.png new file mode 100644 index 000000000..a0f391b9c Binary files /dev/null and b/assets/images/2.0x/menu_button.png differ diff --git a/assets/images/2.0x/send.png b/assets/images/2.0x/send.png new file mode 100644 index 000000000..055ee615a Binary files /dev/null and b/assets/images/2.0x/send.png differ diff --git a/assets/images/2.0x/up_arrow.png b/assets/images/2.0x/up_arrow.png new file mode 100644 index 000000000..ad2427e7a Binary files /dev/null and b/assets/images/2.0x/up_arrow.png differ diff --git a/assets/images/3.0x/coins.png b/assets/images/3.0x/coins.png new file mode 100644 index 000000000..86ea55ae9 Binary files /dev/null and b/assets/images/3.0x/coins.png differ diff --git a/assets/images/3.0x/down_arrow.png b/assets/images/3.0x/down_arrow.png new file mode 100644 index 000000000..8a6312136 Binary files /dev/null and b/assets/images/3.0x/down_arrow.png differ diff --git a/assets/images/3.0x/exchange.png b/assets/images/3.0x/exchange.png new file mode 100644 index 000000000..52d78d21e Binary files /dev/null and b/assets/images/3.0x/exchange.png differ diff --git a/assets/images/3.0x/filter_button.png b/assets/images/3.0x/filter_button.png new file mode 100644 index 000000000..29ba46c3b Binary files /dev/null and b/assets/images/3.0x/filter_button.png differ diff --git a/assets/images/3.0x/menu_button.png b/assets/images/3.0x/menu_button.png new file mode 100644 index 000000000..97f28ae94 Binary files /dev/null and b/assets/images/3.0x/menu_button.png differ diff --git a/assets/images/3.0x/send.png b/assets/images/3.0x/send.png new file mode 100644 index 000000000..f77c93aed Binary files /dev/null and b/assets/images/3.0x/send.png differ diff --git a/assets/images/3.0x/up_arrow.png b/assets/images/3.0x/up_arrow.png new file mode 100644 index 000000000..9d84ebecc Binary files /dev/null and b/assets/images/3.0x/up_arrow.png differ diff --git a/assets/images/coins.png b/assets/images/coins.png new file mode 100644 index 000000000..8541ee942 Binary files /dev/null and b/assets/images/coins.png differ diff --git a/assets/images/down_arrow.png b/assets/images/down_arrow.png new file mode 100644 index 000000000..3d6607611 Binary files /dev/null and b/assets/images/down_arrow.png differ diff --git a/assets/images/exchange.png b/assets/images/exchange.png new file mode 100644 index 000000000..ce2d3928f Binary files /dev/null and b/assets/images/exchange.png differ diff --git a/assets/images/filter_button.png b/assets/images/filter_button.png new file mode 100644 index 000000000..5aff5d41d Binary files /dev/null and b/assets/images/filter_button.png differ diff --git a/assets/images/menu_button.png b/assets/images/menu_button.png new file mode 100644 index 000000000..33a3e5c94 Binary files /dev/null and b/assets/images/menu_button.png differ diff --git a/assets/images/send.png b/assets/images/send.png new file mode 100644 index 000000000..aef504999 Binary files /dev/null and b/assets/images/send.png differ diff --git a/assets/images/up_arrow.png b/assets/images/up_arrow.png new file mode 100644 index 000000000..353240176 Binary files /dev/null and b/assets/images/up_arrow.png differ diff --git a/lib/palette.dart b/lib/palette.dart index 06d889b16..ce7d9e28b 100644 --- a/lib/palette.dart +++ b/lib/palette.dart @@ -82,4 +82,7 @@ class PaletteDark { static const Color walletCardAddressField = Color.fromRGBO(51, 63, 104, 1.0); static const Color walletCardAddressText = Color.fromRGBO(183, 197, 242, 1.0); static const Color walletCardSubAddressField = Color.fromRGBO(63, 77, 122, 1.0); + static const Color historyPanel = Color.fromRGBO(33, 43, 73, 1.0); + static const Color historyPanelText = Color.fromRGBO(91, 112, 146, 1.0); + static const Color historyPanelButton = Color.fromRGBO(39, 53, 96, 1.0); } \ No newline at end of file diff --git a/lib/src/domain/common/transaction_info.dart b/lib/src/domain/common/transaction_info.dart index e2daaec7a..f7b55937a 100644 --- a/lib/src/domain/common/transaction_info.dart +++ b/lib/src/domain/common/transaction_info.dart @@ -43,7 +43,7 @@ class TransactionInfo { String amountFormatted() => '${formatAmount(moneroAmountToString(amount: amount))} XMR'; - String fiatAmount() => _fiatAmount ?? ''; + String fiatAmount(String symbol) => _fiatAmount != null ? symbol + ' ' + _fiatAmount : ''; void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount); } diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index fa7819f2f..a379d22ed 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -18,14 +18,15 @@ import 'package:cake_wallet/src/stores/action_list/date_section_item.dart'; import 'package:cake_wallet/src/stores/action_list/trade_list_item.dart'; import 'package:cake_wallet/src/stores/action_list/transaction_list_item.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/dashboard/date_section_raw.dart'; -import 'package:cake_wallet/src/screens/dashboard/trade_row.dart'; -import 'package:cake_wallet/src/screens/dashboard/transaction_raw.dart'; +import 'package:cake_wallet/src/screens/dashboard/widgets/date_section_raw.dart'; +import 'package:cake_wallet/src/screens/dashboard/widgets/trade_row.dart'; +import 'package:cake_wallet/src/screens/dashboard/widgets/transaction_raw.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/wallet_card.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/buttons_widget.dart'; +import 'package:cake_wallet/src/screens/dashboard/widgets/trade_history_panel.dart'; class DashboardPage extends BasePage { final _bodyKey = GlobalKey(); @@ -115,6 +116,7 @@ class DashboardPageBody extends StatefulWidget { } class DashboardPageBodyState extends State { + final menuButton = Image.asset('assets/images/menu_button.png'); /*final _connectionStatusObserverKey = GlobalKey(); final _balanceObserverKey = GlobalKey(); final _balanceTitleObserverKey = GlobalKey(); @@ -136,7 +138,27 @@ class DashboardPageBodyState extends State { child: Column( children: [ Padding( - padding: EdgeInsets.only(left: 20, top: 78), + padding: EdgeInsets.only(top: 14), + child: Container( + width: double.infinity, + alignment: Alignment.centerRight, + child: SizedBox( + height: 37, + width: 37, + child: ButtonTheme( + minWidth: double.minPositive, + child: FlatButton( + highlightColor: Colors.transparent, + splashColor: Colors.transparent, + padding: EdgeInsets.all(0), + onPressed: () {}, + child: menuButton), + ), + ), + ) + ), + Padding( + padding: EdgeInsets.only(left: 20, top: 23), child: WalletCard(), ), Padding( @@ -144,8 +166,7 @@ class DashboardPageBodyState extends State { child: ButtonsWidget(), ), Expanded( - child: Container( - ) + child: TradeHistoryPanel() ) ], ), diff --git a/lib/src/screens/dashboard/date_section_raw.dart b/lib/src/screens/dashboard/widgets/date_section_raw.dart similarity index 89% rename from lib/src/screens/dashboard/date_section_raw.dart rename to lib/src/screens/dashboard/widgets/date_section_raw.dart index 86fc3ff06..edbc5c854 100644 --- a/lib/src/screens/dashboard/date_section_raw.dart +++ b/lib/src/screens/dashboard/widgets/date_section_raw.dart @@ -20,8 +20,8 @@ class DateSectionRaw extends StatelessWidget { final settingsStore = Provider.of(context); final currentLanguage = settingsStore.languageCode; final dateSectionDateFormat = settingsStore.getCurrentDateFormat( - formatUSA: "MMM d", - formatDefault: "d MMM"); + formatUSA: "yyyy MMM d", + formatDefault: "d MMM yyyy"); var title = ""; if (isToday) { @@ -39,7 +39,7 @@ class DateSectionRaw extends StatelessWidget { padding: const EdgeInsets.only(top: 10, bottom: 10), child: Center( child: Text(title, - style: TextStyle(fontSize: 16, color: Palette.wildDarkBlue))), + style: TextStyle(fontSize: 12, color: PaletteDark.historyPanelText))), ); } } diff --git a/lib/src/screens/dashboard/widgets/trade_history_panel.dart b/lib/src/screens/dashboard/widgets/trade_history_panel.dart new file mode 100644 index 000000000..2f4fad150 --- /dev/null +++ b/lib/src/screens/dashboard/widgets/trade_history_panel.dart @@ -0,0 +1,179 @@ +import 'dart:async'; +import 'package:cake_wallet/src/domain/common/balance_display_mode.dart'; +import 'package:cake_wallet/src/stores/action_list/action_list_store.dart'; +import 'package:cake_wallet/src/stores/action_list/date_section_item.dart'; +import 'package:cake_wallet/src/stores/action_list/trade_list_item.dart'; +import 'package:cake_wallet/src/stores/action_list/transaction_list_item.dart'; +import 'package:cake_wallet/src/stores/settings/settings_store.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:cake_wallet/routes.dart'; +import 'date_section_raw.dart'; +import 'trade_row.dart'; +import 'transaction_raw.dart'; + +class TradeHistoryPanel extends StatefulWidget { + @override + TradeHistoryPanelState createState() => TradeHistoryPanelState(); +} + +class TradeHistoryPanelState extends State { + final _listObserverKey = GlobalKey(); + final _listKey = GlobalKey(); + + double panelHeight; + double screenHeight; + double opacity; + bool isDraw; + + @override + void initState() { + panelHeight = 0; + screenHeight = 0; + opacity = 0; + isDraw = false; + super.initState(); + WidgetsBinding.instance.addPostFrameCallback(afterLayout); + } + + void afterLayout(dynamic _) { + screenHeight = MediaQuery.of(context).size.height; + setState(() { + panelHeight = screenHeight; + opacity = 1; + }); + Timer(Duration(milliseconds: 350), () => + setState(() => isDraw = true) + ); + } + + @override + Widget build(BuildContext context) { + final actionListStore = Provider.of(context); + final settingsStore = Provider.of(context); + final transactionDateFormat = DateFormat("HH:mm"); + final filterButton = Image.asset('assets/images/filter_button.png'); + + return Container( + width: double.infinity, + alignment: Alignment.bottomCenter, + child: AnimatedContainer( + width: double.infinity, + height: panelHeight, + duration: Duration(milliseconds: 1000), + curve: Curves.fastOutSlowIn, + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), + color: PaletteDark.historyPanel.withOpacity(opacity), + ), + child: isDraw + ? Container( + padding: EdgeInsets.only(top: 20, left: 20, right: 20), + child: Column( + children: [ + Container( + width: double.infinity, + height: 36, + margin: EdgeInsets.only(bottom: 10), + child: Stack( + alignment: Alignment.center, + children: [ + Text( + S.of(context).trade_history_title, + style: TextStyle( + fontSize: 20 + ), + ), + Positioned( + right: 0, + child: GestureDetector( + onTap: () {}, + child: filterButton, + ) + ) + ], + ), + ), + Observer( + key: _listObserverKey, + builder: (_) { + final items = actionListStore.items == null + ? [] + : actionListStore.items; + final itemsCount = items.length; + final symbol = settingsStore.fiatCurrency.toString(); + + return Expanded( + child: ListView.builder( + key: _listKey, + padding: EdgeInsets.only(bottom: 15), + itemCount: itemsCount, + itemBuilder: (context, index) { + + final item = items[index]; + + if (item is DateSectionItem) { + return DateSectionRaw(date: item.date); + } + + if (item is TransactionListItem) { + final transaction = item.transaction; + final savedDisplayMode = settingsStore.balanceDisplayMode; + final formattedAmount = + savedDisplayMode == BalanceDisplayMode.hiddenBalance + ? '---' + : transaction.amountFormatted(); + final formattedFiatAmount = + savedDisplayMode == BalanceDisplayMode.hiddenBalance + ? '---' + : transaction.fiatAmount(symbol); + + return TransactionRow( + onTap: () => Navigator.of(context).pushNamed( + Routes.transactionDetails, + arguments: transaction), + direction: transaction.direction, + formattedDate: + transactionDateFormat.format(transaction.date), + formattedAmount: formattedAmount, + formattedFiatAmount: formattedFiatAmount, + isPending: transaction.isPending); + } + + if (item is TradeListItem) { + final trade = item.trade; + final savedDisplayMode = settingsStore.balanceDisplayMode; + final formattedAmount = trade.amount != null + ? savedDisplayMode == BalanceDisplayMode.hiddenBalance + ? '---' + : trade.amountFormatted() + : trade.amount; + + return TradeRow( + onTap: () => Navigator.of(context) + .pushNamed(Routes.tradeDetails, arguments: trade), + provider: trade.provider, + from: trade.from, + to: trade.to, + createdAtFormattedDate: + transactionDateFormat.format(trade.createdAt), + formattedAmount: formattedAmount); + } + + return Container(); + } + ) + ); + }) + ], + ), + ) + : Offstage() + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/screens/dashboard/trade_row.dart b/lib/src/screens/dashboard/widgets/trade_row.dart similarity index 71% rename from lib/src/screens/dashboard/trade_row.dart rename to lib/src/screens/dashboard/widgets/trade_row.dart index 75a3371bd..ce603c359 100644 --- a/lib/src/screens/dashboard/trade_row.dart +++ b/lib/src/screens/dashboard/widgets/trade_row.dart @@ -21,25 +21,25 @@ class TradeRow extends StatelessWidget { @override Widget build(BuildContext context) { - final amountCrypto = provider == ExchangeProviderDescription.xmrto - ? to.toString() - : from.toString(); + final amountCrypto = from.toString(); return InkWell( onTap: onTap, child: Container( - padding: EdgeInsets.only(top: 14, bottom: 14, left: 20, right: 20), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: PaletteDark.darkGrey, - width: 0.5, - style: BorderStyle.solid))), + padding: EdgeInsets.only(top: 5, bottom: 5), child: Row(children: [ - _getPoweredImage(provider), + Container( + height: 36, + width: 36, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: PaletteDark.historyPanelButton + ), + child: _getPoweredImage(provider), + ), Expanded( child: Padding( - padding: const EdgeInsets.only(left: 10, right: 10), + padding: const EdgeInsets.only(left: 10), child: Column( children: [ Row( @@ -48,23 +48,20 @@ class TradeRow extends StatelessWidget { Text('${from.toString()} → ${to.toString()}', style: TextStyle( fontSize: 16, - color: Theme.of(context) - .primaryTextTheme - .subhead - .color)), + )), formattedAmount != null ? Text(formattedAmount + ' ' + amountCrypto, style: const TextStyle( - fontSize: 16, color: Palette.purpleBlue)) + fontSize: 16)) : Container() ]), - SizedBox(height: 6), + SizedBox(height: 5), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(createdAtFormattedDate, style: const TextStyle( - fontSize: 13, color: Palette.blueGrey)) + fontSize: 14, color: PaletteDark.historyPanelText)) ]), ], ), diff --git a/lib/src/screens/dashboard/transaction_raw.dart b/lib/src/screens/dashboard/widgets/transaction_raw.dart similarity index 60% rename from lib/src/screens/dashboard/transaction_raw.dart rename to lib/src/screens/dashboard/widgets/transaction_raw.dart index 383db5218..bf970cd27 100644 --- a/lib/src/screens/dashboard/transaction_raw.dart +++ b/lib/src/screens/dashboard/widgets/transaction_raw.dart @@ -24,24 +24,25 @@ class TransactionRow extends StatelessWidget { return InkWell( onTap: onTap, child: Container( - padding: EdgeInsets.only(top: 14, bottom: 14, left: 20, right: 20), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: PaletteDark.darkGrey, - width: 0.5, - style: BorderStyle.solid))), + padding: EdgeInsets.only(top: 5, bottom: 5), child: Row(children: [ - Image.asset( - direction == TransactionDirection.incoming - ? 'assets/images/transaction_incoming.png' - : 'assets/images/transaction_outgoing.png', - height: 25, - width: 25), + Container( + height: 36, + width: 36, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: PaletteDark.historyPanelButton + ), + child: Image.asset( + direction == TransactionDirection.incoming + ? 'assets/images/down_arrow.png' + : 'assets/images/up_arrow.png'), + ), Expanded( child: Padding( - padding: const EdgeInsets.only(left: 10, right: 10), + padding: const EdgeInsets.only(left: 10), child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -53,24 +54,25 @@ class TransactionRow extends StatelessWidget { (isPending ? S.of(context).pending : ''), style: TextStyle( fontSize: 16, - color: Theme.of(context) - .primaryTextTheme - .subhead - .color)), - Text(formattedAmount, + )), + Text(direction == TransactionDirection.incoming + ? formattedAmount + : '- ' + formattedAmount, style: const TextStyle( - fontSize: 16, color: Palette.purpleBlue)) + fontSize: 16)) ]), - SizedBox(height: 6), + SizedBox(height: 5,), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(formattedDate, style: const TextStyle( - fontSize: 13, color: Palette.blueGrey)), - Text(formattedFiatAmount, + fontSize: 14, color: PaletteDark.historyPanelText)), + Text(direction == TransactionDirection.incoming + ? formattedFiatAmount + : '- ' + formattedFiatAmount, style: const TextStyle( - fontSize: 14, color: Palette.blueGrey)) + fontSize: 14, color: PaletteDark.historyPanelText)) ]), ], ),