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/header.png b/assets/images/2.0x/header.png new file mode 100644 index 000000000..192b343ff Binary files /dev/null and b/assets/images/2.0x/header.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/right_arrow.png b/assets/images/2.0x/right_arrow.png new file mode 100644 index 000000000..279cf0ccf Binary files /dev/null and b/assets/images/2.0x/right_arrow.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/triangle.png b/assets/images/2.0x/triangle.png new file mode 100644 index 000000000..1a7baf26d Binary files /dev/null and b/assets/images/2.0x/triangle.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/header.png b/assets/images/3.0x/header.png new file mode 100644 index 000000000..9a86d241a Binary files /dev/null and b/assets/images/3.0x/header.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/right_arrow.png b/assets/images/3.0x/right_arrow.png new file mode 100644 index 000000000..35eb86002 Binary files /dev/null and b/assets/images/3.0x/right_arrow.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/triangle.png b/assets/images/3.0x/triangle.png new file mode 100644 index 000000000..2813c9443 Binary files /dev/null and b/assets/images/3.0x/triangle.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/header.png b/assets/images/header.png new file mode 100644 index 000000000..a3e8169aa Binary files /dev/null and b/assets/images/header.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/right_arrow.png b/assets/images/right_arrow.png new file mode 100644 index 000000000..8864a49f8 Binary files /dev/null and b/assets/images/right_arrow.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/triangle.png b/assets/images/triangle.png new file mode 100644 index 000000000..0c48a2465 Binary files /dev/null and b/assets/images/triangle.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/generated/i18n.dart b/lib/generated/i18n.dart index 186ac1ddb..99ece7cc0 100644 --- a/lib/generated/i18n.dart +++ b/lib/generated/i18n.dart @@ -39,7 +39,9 @@ class S implements WidgetsLocalizations { String get authentication => "Authentication"; String get available_balance => "Available Balance"; String get biometric_auth_reason => "Scan your fingerprint to authenticate"; + String get buy => "Buy"; String get cancel => "Cancel"; + String get card_address => "Address:"; String get change => "Change"; String get change_currency => "Change Currency"; String get change_exchange_provider => "Change Exchange Provider"; @@ -362,6 +364,8 @@ class $de extends S { @override String get wallet_list_create_new_wallet => "Neue Wallet erstellen"; @override + String get card_address => "Adresse:"; + @override String get seed_language_portuguese => "Portugiesisch"; @override String get setup_pin => "PIN einrichten"; @@ -436,6 +440,8 @@ class $de extends S { @override String get trade_details_fetching => "Holen"; @override + String get buy => "Kaufen"; + @override String get confirm_sending => "Bestätigen Sie das Senden"; @override String get settings_title => "die Einstellungen"; @@ -930,6 +936,8 @@ class $hi extends S { @override String get wallet_list_create_new_wallet => "नया बटुआ बनाएँ"; @override + String get card_address => "पता:"; + @override String get seed_language_portuguese => "पुर्तगाली"; @override String get setup_pin => "पिन सेट करें"; @@ -1004,6 +1012,8 @@ class $hi extends S { @override String get trade_details_fetching => "ला रहा है"; @override + String get buy => "खरीदें"; + @override String get confirm_sending => "भेजने की पुष्टि करें"; @override String get settings_title => "सेटिंग्स"; @@ -1498,6 +1508,8 @@ class $ru extends S { @override String get wallet_list_create_new_wallet => "Создать новый кошелёк"; @override + String get card_address => "Адрес:"; + @override String get seed_language_portuguese => "Португальский"; @override String get setup_pin => "Настроить PIN"; @@ -1572,6 +1584,8 @@ class $ru extends S { @override String get trade_details_fetching => "Получение"; @override + String get buy => "Купить"; + @override String get confirm_sending => "Подтвердить отправку"; @override String get settings_title => "Настройки"; @@ -2066,6 +2080,8 @@ class $ko extends S { @override String get wallet_list_create_new_wallet => "새 월렛 만들기"; @override + String get card_address => "주소:"; + @override String get seed_language_portuguese => "포르투갈 인"; @override String get setup_pin => "설정 PIN"; @@ -2140,6 +2156,8 @@ class $ko extends S { @override String get trade_details_fetching => "가져 오는 중"; @override + String get buy => "구입"; + @override String get confirm_sending => "전송 확인"; @override String get settings_title => "설정"; @@ -2634,6 +2652,8 @@ class $pt extends S { @override String get wallet_list_create_new_wallet => "Criar nova carteira"; @override + String get card_address => "Endereço:"; + @override String get seed_language_portuguese => "Português"; @override String get setup_pin => "Configurar PIN"; @@ -2708,6 +2728,8 @@ class $pt extends S { @override String get trade_details_fetching => "Buscando"; @override + String get buy => "Comprar"; + @override String get confirm_sending => "Confirmar o envio"; @override String get settings_title => "Configurações"; @@ -3202,6 +3224,8 @@ class $uk extends S { @override String get wallet_list_create_new_wallet => "Створити новий гаманець"; @override + String get card_address => "Адреса:"; + @override String get seed_language_portuguese => "Португальська"; @override String get setup_pin => "Встановити PIN"; @@ -3276,6 +3300,8 @@ class $uk extends S { @override String get trade_details_fetching => "Отримання"; @override + String get buy => "Купити"; + @override String get confirm_sending => "Підтвердити відправлення"; @override String get settings_title => "Налаштування"; @@ -3770,6 +3796,8 @@ class $ja extends S { @override String get wallet_list_create_new_wallet => "新しいウォレットを作成"; @override + String get card_address => "住所:"; + @override String get seed_language_portuguese => "ポルトガル語"; @override String get setup_pin => "PINのセットアップ"; @@ -3844,6 +3872,8 @@ class $ja extends S { @override String get trade_details_fetching => "フェッチング"; @override + String get buy => "購入"; + @override String get confirm_sending => "送信を確認"; @override String get settings_title => "設定"; @@ -4342,6 +4372,8 @@ class $pl extends S { @override String get wallet_list_create_new_wallet => "Utwórz nowy portfel"; @override + String get card_address => "Adres:"; + @override String get seed_language_portuguese => "Portugalski"; @override String get setup_pin => "Ustaw PIN"; @@ -4416,6 +4448,8 @@ class $pl extends S { @override String get trade_details_fetching => "Ujmujący"; @override + String get buy => "Kup"; + @override String get confirm_sending => "Potwierdź wysłanie"; @override String get settings_title => "Ustawienia"; @@ -4910,6 +4944,8 @@ class $es extends S { @override String get wallet_list_create_new_wallet => "Crear nueva billetera"; @override + String get card_address => "Dirección:"; + @override String get seed_language_portuguese => "Portugués"; @override String get setup_pin => "PIN de configuración"; @@ -4984,6 +5020,8 @@ class $es extends S { @override String get trade_details_fetching => "Cargando"; @override + String get buy => "Comprar"; + @override String get confirm_sending => "Confirmar envío"; @override String get settings_title => "Configuraciones"; @@ -5478,6 +5516,8 @@ class $nl extends S { @override String get wallet_list_create_new_wallet => "Maak een nieuwe portemonnee"; @override + String get card_address => "Adres:"; + @override String get seed_language_portuguese => "Portugees"; @override String get setup_pin => "PIN instellen"; @@ -5552,6 +5592,8 @@ class $nl extends S { @override String get trade_details_fetching => "Ophalen"; @override + String get buy => "Kopen"; + @override String get confirm_sending => "Bevestig verzending"; @override String get settings_title => "Instellingen"; @@ -6046,6 +6088,8 @@ class $zh extends S { @override String get wallet_list_create_new_wallet => "创建新钱包"; @override + String get card_address => "地址:"; + @override String get seed_language_portuguese => "葡萄牙語"; @override String get setup_pin => "设定PIN码"; @@ -6120,6 +6164,8 @@ class $zh extends S { @override String get trade_details_fetching => "正在取得"; @override + String get buy => "購買"; + @override String get confirm_sending => "确认发送"; @override String get settings_title => "设定值"; diff --git a/lib/palette.dart b/lib/palette.dart index d4d915a02..cf8dab9c9 100644 --- a/lib/palette.dart +++ b/lib/palette.dart @@ -69,4 +69,22 @@ class PaletteDark { static const Color switchBackground = Color.fromRGBO(100, 115, 137, 0.4); static const Color wildDarkBlueWithOpacity = Color.fromRGBO(155, 172, 197, 0.4); static const Color wildDarkBlue = Color.fromRGBO(155, 172, 197, 0.8); + + // NEW + + static const Color backgroundStart = Color.fromRGBO(231, 240, 253, 1.0); + static const Color backgroundEnd = Color.fromRGBO(172, 203, 238, 1.0); + static const Color mainBackgroundColor = Color.fromRGBO(70, 85, 133, 1.0); + static const Color borderCardColor = Color.fromRGBO(81, 96, 147, 1.0); + static const Color walletCardTopStartSync = Color.fromRGBO(89, 104, 152, 1.0); + static const Color walletCardBottomStartSync = Color.fromRGBO(70, 85, 133, 1.0); + static const Color walletCardTopEndSync = Color.fromRGBO(70, 85, 133, 1.0); + static const Color walletCardBottomEndSync = Color.fromRGBO(45, 56, 95, 1.0); + static const Color walletCardText = Color.fromRGBO(140, 153, 201, 1.0); + 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/base_page.dart b/lib/src/screens/base_page.dart index 309f0fe50..54521b7fe 100644 --- a/lib/src/screens/base_page.dart +++ b/lib/src/screens/base_page.dart @@ -81,9 +81,10 @@ abstract class BasePage extends StatelessWidget { leading: leading(context), middle: middle(context), trailing: trailing(context), - backgroundColor: _isDarkTheme + backgroundColor: backgroundColor); + /*backgroundColor: _isDarkTheme ? Theme.of(context).backgroundColor - : backgroundColor); + : backgroundColor);*/ case AppBarStyle.withShadow: return NavBar.withShadow( @@ -91,9 +92,10 @@ abstract class BasePage extends StatelessWidget { leading: leading(context), middle: middle(context), trailing: trailing(context), - backgroundColor: _isDarkTheme + backgroundColor: backgroundColor); + /*backgroundColor: _isDarkTheme ? Theme.of(context).backgroundColor - : backgroundColor); + : backgroundColor);*/ default: return NavBar( @@ -101,9 +103,10 @@ abstract class BasePage extends StatelessWidget { leading: leading(context), middle: middle(context), trailing: trailing(context), - backgroundColor: _isDarkTheme + backgroundColor: backgroundColor); + /*backgroundColor: _isDarkTheme ? Theme.of(context).backgroundColor - : backgroundColor); + : backgroundColor);*/ } } diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index 5a54eb204..bd0cfb6db 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -1,106 +1,37 @@ -import 'package:provider/provider.dart'; -import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/palette.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/domain/common/balance_display_mode.dart'; -import 'package:cake_wallet/src/domain/common/sync_status.dart'; -import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart'; -import 'package:cake_wallet/src/stores/action_list/action_list_store.dart'; -import 'package:cake_wallet/src/stores/balance/balance_store.dart'; -import 'package:cake_wallet/src/stores/sync/sync_store.dart'; -import 'package:cake_wallet/src/stores/settings/settings_store.dart'; -import 'package:cake_wallet/src/stores/wallet/wallet_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/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/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/trade_history_panel.dart'; class DashboardPage extends BasePage { final _bodyKey = GlobalKey(); @override - Widget leading(BuildContext context) { - return SizedBox( - width: 30, - child: FlatButton( - padding: EdgeInsets.all(0), - onPressed: () => _presentWalletMenu(context), - child: Image.asset('assets/images/more.png', - color: Theme.of(context).primaryTextTheme.caption.color, - width: 30))); - } - - @override - Widget middle(BuildContext context) { - final walletStore = Provider.of(context); - - return Observer(builder: (_) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - walletStore.name, - style: TextStyle( - color: Theme.of(context).primaryTextTheme.title.color), - ), - SizedBox(height: 5), - Text( - walletStore.account != null ? '${walletStore.account.label}' : '', - style: TextStyle( - fontWeight: FontWeight.w400, - fontSize: 10, - color: Theme.of(context).primaryTextTheme.title.color), - ), - ]); - }); - } + Color get backgroundColor => PaletteDark.mainBackgroundColor; @override Widget trailing(BuildContext context) { + final menuButton = Image.asset('assets/images/header.png'); + return SizedBox( - width: 20, - child: FlatButton( + height: 37, + width: 37, + child: ButtonTheme( + minWidth: double.minPositive, + child: FlatButton( + highlightColor: Colors.transparent, + splashColor: Colors.transparent, padding: EdgeInsets.all(0), - onPressed: () => Navigator.of(context).pushNamed(Routes.settings), - child: Image.asset('assets/images/settings_icon.png', - color: Colors.grey, height: 20)), + onPressed: () {}, + child: menuButton), + ), ); } @override Widget body(BuildContext context) => DashboardPageBody(key: _bodyKey); - - @override - Widget floatingActionButton(BuildContext context) => FloatingActionButton( - child: Image.asset('assets/images/exchange_icon.png', - color: Colors.white, height: 26, width: 22), - backgroundColor: Palette.floatingActionButton, - onPressed: () async => await Navigator.of(context, rootNavigator: true) - .pushNamed(Routes.exchange)); - - void _presentWalletMenu(BuildContext bodyContext) { - final walletMenu = WalletMenu(bodyContext); - - showDialog( - builder: (_) => Picker( - items: walletMenu.items, - selectedAtIndex: -1, - title: S.of(bodyContext).wallet_menu, - pickerHeight: 510, - onItemSelected: (String item) => - walletMenu.action(walletMenu.items.indexOf(item))), - context: bodyContext); - } } class DashboardPageBody extends StatefulWidget { @@ -111,488 +42,26 @@ class DashboardPageBody extends StatefulWidget { } class DashboardPageBodyState extends State { - final _connectionStatusObserverKey = GlobalKey(); - final _balanceObserverKey = GlobalKey(); - final _balanceTitleObserverKey = GlobalKey(); - final _syncingObserverKey = GlobalKey(); - final _listObserverKey = GlobalKey(); - final _listKey = GlobalKey(); @override Widget build(BuildContext context) { - final balanceStore = Provider.of(context); - final actionListStore = Provider.of(context); - final syncStore = Provider.of(context); - final settingsStore = Provider.of(context); - final transactionDateFormat = settingsStore.getCurrentDateFormat( - formatUSA: "MMMM d, yyyy, HH:mm", - formatDefault: "d MMMM yyyy, HH:mm"); - return Observer( - key: _listObserverKey, - builder: (_) { - final items = actionListStore.items == null - ? [] - : actionListStore.items; - final itemsCount = items.length + 2; - - return ListView.builder( - key: _listKey, - padding: EdgeInsets.only(bottom: 15), - itemCount: itemsCount, - itemBuilder: (context, index) { - if (index == 0) { - return Container( - margin: EdgeInsets.only(bottom: 20), - decoration: BoxDecoration( - color: Theme.of(context).backgroundColor, - boxShadow: [ - BoxShadow( - color: Palette.shadowGreyWithOpacity, - blurRadius: 10, - offset: Offset(0, 12)) - ]), - child: Column( - children: [ - Observer( - key: _syncingObserverKey, - builder: (_) { - final status = syncStore.status; - final statusText = status.title(); - final progress = syncStore.status.progress(); - final isFialure = status is FailedSyncStatus; - - var descriptionText = ''; - - if (status is SyncingSyncStatus) { - descriptionText = S - .of(context) - .Blocks_remaining( - syncStore.status.toString()); - } - - if (status is FailedSyncStatus) { - descriptionText = S - .of(context) - .please_try_to_connect_to_another_node; - } - - return Container( - child: Column( - children: [ - SizedBox( - height: 3, - child: LinearProgressIndicator( - backgroundColor: Palette.separator, - valueColor: - AlwaysStoppedAnimation( - Palette.cakeGreen), - value: progress, - ), - ), - SizedBox(height: 10), - Text(statusText, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - color: isFialure - ? Palette.failure - : Palette.cakeGreen)), - Text(descriptionText, - style: TextStyle( - fontSize: 11, - color: Palette.wildDarkBlue, - height: 2.0)) - ], - ), - ); - }), - GestureDetector( - onTapUp: (_) => balanceStore.isReversing = false, - onTapDown: (_) => balanceStore.isReversing = true, - child: Container( - padding: EdgeInsets.only(top: 40, bottom: 40), - color: Colors.transparent, - child: Column( - children: [ - Container(width: double.infinity), - Observer( - key: _balanceTitleObserverKey, - builder: (_) { - final savedDisplayMode = - settingsStore.balanceDisplayMode; - final displayMode = balanceStore - .isReversing - ? (savedDisplayMode == - BalanceDisplayMode - .availableBalance - ? BalanceDisplayMode.fullBalance - : BalanceDisplayMode - .availableBalance) - : savedDisplayMode; - - return Text(displayMode.toString(), - style: TextStyle( - color: Palette.violet, - fontSize: 16)); - }), - Observer( - key: _connectionStatusObserverKey, - builder: (_) { - final savedDisplayMode = - settingsStore.balanceDisplayMode; - var balance = '---'; - final displayMode = balanceStore - .isReversing - ? (savedDisplayMode == - BalanceDisplayMode - .availableBalance - ? BalanceDisplayMode.fullBalance - : BalanceDisplayMode - .availableBalance) - : savedDisplayMode; - - if (displayMode == - BalanceDisplayMode.availableBalance) { - balance = - balanceStore.unlockedBalance ?? - '0.0'; - } - - if (displayMode == - BalanceDisplayMode.fullBalance) { - balance = - balanceStore.fullBalance ?? '0.0'; - } - - return Text( - balance, - style: TextStyle( - color: Theme.of(context) - .primaryTextTheme - .caption - .color, - fontSize: 42), - ); - }), - Padding( - padding: EdgeInsets.only(top: 7), - child: Observer( - key: _balanceObserverKey, - builder: (_) { - final savedDisplayMode = - settingsStore.balanceDisplayMode; - final displayMode = - balanceStore.isReversing - ? (savedDisplayMode == - BalanceDisplayMode - .availableBalance - ? BalanceDisplayMode - .fullBalance - : BalanceDisplayMode - .availableBalance) - : savedDisplayMode; - final symbol = settingsStore - .fiatCurrency - .toString(); - var balance = '---'; - - if (displayMode == - BalanceDisplayMode - .availableBalance) { - balance = - '${balanceStore.fiatUnlockedBalance} $symbol'; - } - - if (displayMode == - BalanceDisplayMode.fullBalance) { - balance = - '${balanceStore.fiatFullBalance} $symbol'; - } - - return Text(balance, - style: TextStyle( - color: Palette.wildDarkBlue, - fontSize: 16)); - })) - ], - ), - ), - ), - Padding( - padding: const EdgeInsets.only( - left: 20, right: 20, bottom: 30), - child: Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: PrimaryImageButton( - image: Image.asset( - 'assets/images/send_icon.png', - height: 25, - width: 25), - text: S.of(context).send, - onPressed: () => Navigator.of(context, - rootNavigator: true) - .pushNamed(Routes.send), - color: Theme.of(context) - .primaryTextTheme - .button - .backgroundColor, - borderColor: Theme.of(context) - .primaryTextTheme - .button - .decorationColor, - )), - SizedBox(width: 10), - Expanded( - child: PrimaryImageButton( - image: Image.asset( - 'assets/images/receive_icon.png', - height: 25, - width: 25), - text: S.of(context).receive, - onPressed: () => Navigator.of(context, - rootNavigator: true) - .pushNamed(Routes.receive), - color: Theme.of(context) - .accentTextTheme - .caption - .backgroundColor, - borderColor: Theme.of(context) - .accentTextTheme - .caption - .decorationColor, - )) - ], - ), - )), - ], - ), - ); - } - - if (index == 1 && actionListStore.totalCount > 0) { - return Padding( - padding: EdgeInsets.only(right: 20, top: 10, bottom: 20), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - PopupMenuButton( - itemBuilder: (context) => [ - PopupMenuItem( - enabled: false, - value: -1, - child: Text(S.of(context).transactions, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).primaryTextTheme.caption.color))), - PopupMenuItem( - value: 0, - child: Observer( - builder: (_) => Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text(S.of(context).incoming), - Checkbox( - value: actionListStore - .transactionFilterStore - .displayIncoming, - onChanged: (value) => - actionListStore - .transactionFilterStore - .toggleIncoming(), - ) - ]))), - PopupMenuItem( - value: 1, - child: Observer( - builder: (_) => Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text(S.of(context).outgoing), - Checkbox( - value: actionListStore - .transactionFilterStore - .displayOutgoing, - onChanged: (value) => - actionListStore - .transactionFilterStore - .toggleOutgoing(), - ) - ]))), - PopupMenuItem( - value: 2, - child: - Text(S.of(context).transactions_by_date)), - PopupMenuDivider(), - PopupMenuItem( - enabled: false, - value: -1, - child: Text(S.of(context).trades, - style: TextStyle( - fontWeight: FontWeight.bold, - color: Theme.of(context).primaryTextTheme.caption.color))), - PopupMenuItem( - value: 3, - child: Observer( - builder: (_) => Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text('XMR.TO'), - Checkbox( - value: actionListStore - .tradeFilterStore - .displayXMRTO, - onChanged: (value) => - actionListStore - .tradeFilterStore - .toggleDisplayExchange( - ExchangeProviderDescription - .xmrto), - ) - ]))), - PopupMenuItem( - value: 4, - child: Observer( - builder: (_) => Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text('Change.NOW'), - Checkbox( - value: actionListStore - .tradeFilterStore - .displayChangeNow, - onChanged: (value) => - actionListStore - .tradeFilterStore - .toggleDisplayExchange( - ExchangeProviderDescription - .changeNow), - ) - ]))), - PopupMenuItem( - value: 5, - child: Observer( - builder: (_) => Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text('MorphToken'), - Checkbox( - value: actionListStore - .tradeFilterStore - .displayMorphToken, - onChanged: (value) => - actionListStore - .tradeFilterStore - .toggleDisplayExchange( - ExchangeProviderDescription - .morphToken), - ) - ]))) - ], - child: Text(S.of(context).filters, - style: TextStyle( - fontSize: 16.0, - color: Theme.of(context) - .primaryTextTheme - .subtitle - .color)), - onSelected: (item) async { - if (item == 2) { - final List picked = - await date_rage_picker.showDatePicker( - context: context, - initialFirstDate: DateTime.now() - .subtract(Duration(days: 1)), - initialLastDate: (DateTime.now()), - firstDate: DateTime(2015), - lastDate: DateTime.now() - .add(Duration(days: 1))); - - if (picked != null && picked.length == 2) { - actionListStore.transactionFilterStore - .changeStartDate(picked.first); - actionListStore.transactionFilterStore - .changeEndDate(picked.last); - } - } - }, - ) - ]), - ); - } - - index -= 2; - - if (index < 0 || index >= items.length) { - return Container(); - } - - 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(); - - 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(); - }); - }); + return SafeArea( + child: Container( + color: PaletteDark.mainBackgroundColor, + child: Column( + children: [ + Padding( + padding: EdgeInsets.only(left: 20, top: 10), + child: WalletCard(), + ), + SizedBox( + height: 28, + ), + Expanded(child: TradeHistoryPanel()) + ], + ), + ), + ); } } diff --git a/lib/src/screens/dashboard/widgets/button_header.dart b/lib/src/screens/dashboard/widgets/button_header.dart new file mode 100644 index 000000000..71b8434e5 --- /dev/null +++ b/lib/src/screens/dashboard/widgets/button_header.dart @@ -0,0 +1,297 @@ +import 'package:cake_wallet/src/domain/exchange/exchange_provider_description.dart'; +import 'package:cake_wallet/src/stores/action_list/action_list_store.dart'; +import 'package:flutter/cupertino.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:provider/provider.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker; + +class ButtonHeader extends SliverPersistentHeaderDelegate { + final sendImage = Image.asset('assets/images/send.png'); + final exchangeImage = Image.asset('assets/images/exchange.png'); + final buyImage = Image.asset('assets/images/coins.png'); + final filterButton = Image.asset('assets/images/filter_button.png'); + + @override + Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { + final actionListStore = Provider.of(context); + final historyPanelWidth = MediaQuery.of(context).size.width; + + double buttonsOpacity = 1 - shrinkOffset / (maxExtent - minExtent); + double buttonsHeight = maxExtent - minExtent - shrinkOffset; + + buttonsOpacity = buttonsOpacity >= 0 ? buttonsOpacity : 0; + buttonsHeight = buttonsHeight >= 0 ? buttonsHeight : 0; + + return Stack( + fit: StackFit.expand, + overflow: Overflow.visible, + children: [ + Opacity( + opacity: buttonsOpacity, + child: Container( + height: buttonsHeight, + padding: EdgeInsets.only(left: 44, right: 44), + child: Row( + children: [ + Flexible( + child: actionButton( + context: context, + image: sendImage, + title: S.of(context).send, + route: Routes.send + ) + ), + Flexible( + child: actionButton( + context: context, + image: exchangeImage, + title: S.of(context).exchange, + route: Routes.exchange + ) + ), + Flexible( + child: actionButton( + context: context, + image: buyImage, + title: S.of(context).buy, + route: '' + ) + ) + ], + ), + ), + ), + Positioned( + top: buttonsHeight, + left: 0, + child: Container( + width: historyPanelWidth, + height: 66, + padding: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), + color: PaletteDark.historyPanel, + ), + child: Stack( + alignment: Alignment.center, + children: [ + Text( + S.of(context).trade_history_title, + style: TextStyle( + fontSize: 20, + color: Colors.white + ), + ), + Positioned( + right: 0, + child: PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + enabled: false, + value: -1, + child: Text(S.of(context).transactions, + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).primaryTextTheme.caption.color))), + PopupMenuItem( + value: 0, + child: Observer( + builder: (_) => Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text(S.of(context).incoming), + Checkbox( + value: actionListStore + .transactionFilterStore + .displayIncoming, + onChanged: (value) => + actionListStore + .transactionFilterStore + .toggleIncoming(), + ) + ]))), + PopupMenuItem( + value: 1, + child: Observer( + builder: (_) => Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text(S.of(context).outgoing), + Checkbox( + value: actionListStore + .transactionFilterStore + .displayOutgoing, + onChanged: (value) => + actionListStore + .transactionFilterStore + .toggleOutgoing(), + ) + ]))), + PopupMenuItem( + value: 2, + child: + Text(S.of(context).transactions_by_date)), + PopupMenuDivider(), + PopupMenuItem( + enabled: false, + value: -1, + child: Text(S.of(context).trades, + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).primaryTextTheme.caption.color))), + PopupMenuItem( + value: 3, + child: Observer( + builder: (_) => Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text('XMR.TO'), + Checkbox( + value: actionListStore + .tradeFilterStore + .displayXMRTO, + onChanged: (value) => + actionListStore + .tradeFilterStore + .toggleDisplayExchange( + ExchangeProviderDescription + .xmrto), + ) + ]))), + PopupMenuItem( + value: 4, + child: Observer( + builder: (_) => Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text('Change.NOW'), + Checkbox( + value: actionListStore + .tradeFilterStore + .displayChangeNow, + onChanged: (value) => + actionListStore + .tradeFilterStore + .toggleDisplayExchange( + ExchangeProviderDescription + .changeNow), + ) + ]))), + PopupMenuItem( + value: 5, + child: Observer( + builder: (_) => Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text('MorphToken'), + Checkbox( + value: actionListStore + .tradeFilterStore + .displayMorphToken, + onChanged: (value) => + actionListStore + .tradeFilterStore + .toggleDisplayExchange( + ExchangeProviderDescription + .morphToken), + ) + ]))) + ], + child: filterButton, + onSelected: (item) async { + if (item == 2) { + final List picked = + await date_rage_picker.showDatePicker( + context: context, + initialFirstDate: DateTime.now() + .subtract(Duration(days: 1)), + initialLastDate: (DateTime.now()), + firstDate: DateTime(2015), + lastDate: DateTime.now() + .add(Duration(days: 1))); + + if (picked != null && picked.length == 2) { + actionListStore.transactionFilterStore + .changeStartDate(picked.first); + actionListStore.transactionFilterStore + .changeEndDate(picked.last); + } + } + }, + ), + ) + ], + ), + ) + ) + ], + ); + } + + @override + double get maxExtent => 174; + + @override + double get minExtent => 66; + + @override + bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true; + + Widget actionButton({ + BuildContext context, + @required Image image, + @required String title, + @required String route}) { + + return Container( + width: MediaQuery.of(context).size.width, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + GestureDetector( + onTap: () { + if (route.isNotEmpty) { + Navigator.of(context, rootNavigator: true).pushNamed(route); + } + }, + child: Container( + height: 48, + width: 48, + alignment: Alignment.center, + decoration: BoxDecoration( + color: PaletteDark.borderCardColor, + shape: BoxShape.circle + ), + child: image, + ), + ), + Padding( + padding: EdgeInsets.only(top: 10), + child: Text( + title, + style: TextStyle( + fontSize: 16, + color: PaletteDark.walletCardText + ), + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/src/screens/dashboard/date_section_raw.dart b/lib/src/screens/dashboard/widgets/date_section_raw.dart similarity index 69% rename from lib/src/screens/dashboard/date_section_raw.dart rename to lib/src/screens/dashboard/widgets/date_section_raw.dart index 86fc3ff06..4ec9382fd 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) { @@ -35,11 +35,19 @@ class DateSectionRaw extends StatelessWidget { title = dateSectionDateFormat.format(date); } - return Padding( - padding: const EdgeInsets.only(top: 10, bottom: 10), - child: Center( - child: Text(title, - style: TextStyle(fontSize: 16, color: Palette.wildDarkBlue))), + return Container( + height: 36, + padding: EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20), + alignment: Alignment.center, + decoration: BoxDecoration( + color: PaletteDark.historyPanel, + border: Border.all( + width: 1, + color: PaletteDark.historyPanel + ), + ), + child: Text(title, + 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..99035a6d9 --- /dev/null +++ b/lib/src/screens/dashboard/widgets/trade_history_panel.dart @@ -0,0 +1,160 @@ +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/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/palette.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'; +import 'button_header.dart'; + +class TradeHistoryPanel extends StatefulWidget { + @override + TradeHistoryPanelState createState() => TradeHistoryPanelState(); +} + +class TradeHistoryPanelState extends State { + final _listObserverKey = GlobalKey(); + final _listKey = GlobalKey(); + + double panelHeight; + double screenHeight; + + @override + void initState() { + panelHeight = 0; + screenHeight = 0; + super.initState(); + WidgetsBinding.instance.addPostFrameCallback(afterLayout); + } + + void afterLayout(dynamic _) { + screenHeight = MediaQuery.of(context).size.height; + setState(() { + panelHeight = screenHeight; + }); + } + + @override + Widget build(BuildContext context) { + final actionListStore = Provider.of(context); + final settingsStore = Provider.of(context); + final transactionDateFormat = DateFormat("HH:mm"); + + return Container( + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + alignment: Alignment.bottomCenter, + child: AnimatedContainer( + width: MediaQuery.of(context).size.width, + height: panelHeight, + duration: Duration(milliseconds: 1000), + curve: Curves.fastOutSlowIn, + child: CustomScrollView( + slivers: [ + SliverPersistentHeader( + delegate: ButtonHeader(), + pinned: true, + floating: false, + ), + Observer( + key: _listObserverKey, + builder: (_) { + final items = actionListStore.items == null + ? [] + : actionListStore.items; + final itemsCount = items.length + 1; + final symbol = settingsStore.fiatCurrency.toString(); + double freeSpaceHeight = MediaQuery.of(context).size.height - 496; + + return SliverList( + key: _listKey, + delegate: SliverChildBuilderDelegate( + (context, index) { + + if (index == itemsCount - 1) { + freeSpaceHeight = freeSpaceHeight >= 0 ? freeSpaceHeight : 0; + + return Container( + height: freeSpaceHeight, + width: MediaQuery.of(context).size.width, + color: PaletteDark.historyPanel, + ); + } + + final item = items[index]; + + if (item is DateSectionItem) { + freeSpaceHeight -= 38; + return DateSectionRaw(date: item.date); + } + + if (item is TransactionListItem) { + freeSpaceHeight -= 58; + 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) { + freeSpaceHeight -= 58; + 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( + color: PaletteDark.historyPanel + ); + }, + + childCount: itemsCount + ) + ); + }) + ], + ) + ), + ); + } +} \ 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 70% rename from lib/src/screens/dashboard/trade_row.dart rename to lib/src/screens/dashboard/widgets/trade_row.dart index 75a3371bd..1ea5f098d 100644 --- a/lib/src/screens/dashboard/trade_row.dart +++ b/lib/src/screens/dashboard/widgets/trade_row.dart @@ -21,25 +21,33 @@ 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), + height: 56, decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: PaletteDark.darkGrey, - width: 0.5, - style: BorderStyle.solid))), + color: PaletteDark.historyPanel, + border: Border.all( + width: 1, + color: PaletteDark.historyPanel + ), + ), + padding: EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20), 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 +56,23 @@ class TradeRow extends StatelessWidget { Text('${from.toString()} → ${to.toString()}', style: TextStyle( fontSize: 16, - color: Theme.of(context) - .primaryTextTheme - .subhead - .color)), + color: Colors.white + )), formattedAmount != null ? Text(formattedAmount + ' ' + amountCrypto, style: const TextStyle( - fontSize: 16, color: Palette.purpleBlue)) + fontSize: 16, + color: Colors.white + )) : 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 54% rename from lib/src/screens/dashboard/transaction_raw.dart rename to lib/src/screens/dashboard/widgets/transaction_raw.dart index 383db5218..517318260 100644 --- a/lib/src/screens/dashboard/transaction_raw.dart +++ b/lib/src/screens/dashboard/widgets/transaction_raw.dart @@ -24,24 +24,33 @@ class TransactionRow extends StatelessWidget { return InkWell( onTap: onTap, child: Container( - padding: EdgeInsets.only(top: 14, bottom: 14, left: 20, right: 20), + height: 56, decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: PaletteDark.darkGrey, - width: 0.5, - style: BorderStyle.solid))), + color: PaletteDark.historyPanel, + border: Border.all( + width: 1, + color: PaletteDark.historyPanel + ), + ), + padding: EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20), 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 +62,28 @@ class TransactionRow extends StatelessWidget { (isPending ? S.of(context).pending : ''), style: TextStyle( fontSize: 16, - color: Theme.of(context) - .primaryTextTheme - .subhead - .color)), - Text(formattedAmount, + color: Colors.white + )), + Text(direction == TransactionDirection.incoming + ? formattedAmount + : '- ' + formattedAmount, style: const TextStyle( - fontSize: 16, color: Palette.purpleBlue)) + fontSize: 16, + color: Colors.white + )) ]), - 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)) ]), ], ), diff --git a/lib/src/screens/dashboard/widgets/wallet_card.dart b/lib/src/screens/dashboard/widgets/wallet_card.dart new file mode 100644 index 000000000..a4c2f4b48 --- /dev/null +++ b/lib/src/screens/dashboard/widgets/wallet_card.dart @@ -0,0 +1,471 @@ +import 'dart:async'; +import 'package:cake_wallet/src/domain/common/balance_display_mode.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:cake_wallet/src/stores/balance/balance_store.dart'; +import 'package:cake_wallet/src/stores/settings/settings_store.dart'; +import 'package:cake_wallet/src/stores/sync/sync_store.dart'; +import 'package:cake_wallet/src/stores/wallet/wallet_store.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:cake_wallet/palette.dart'; +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/domain/common/sync_status.dart'; +import 'package:cake_wallet/src/screens/receive/qr_image.dart'; + +class WalletCard extends StatefulWidget { + @override + WalletCardState createState() => WalletCardState(); +} + +class WalletCardState extends State { + final _syncingObserverKey = GlobalKey(); + final _balanceObserverKey = GlobalKey(); + final _addressObserverKey = GlobalKey(); + + final List colorsSync = [PaletteDark.walletCardSubAddressField, PaletteDark.walletCardBottomEndSync]; + double cardWidth; + double cardHeight; + double screenWidth; + double opacity; + bool isDraw; + bool isFrontSide; + + @override + void initState() { + cardWidth = 0; + cardHeight = 220; + screenWidth = 0; + opacity = 0; + isDraw = false; + isFrontSide = true; + super.initState(); + WidgetsBinding.instance.addPostFrameCallback(afterLayout); + } + + void afterLayout(dynamic _) { + screenWidth = MediaQuery.of(context).size.width - 20; + setState(() { + cardWidth = screenWidth; + opacity = 1; + }); + Timer(Duration(milliseconds: 500), () => + setState(() => isDraw = true) + ); + } + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + height: cardHeight, + alignment: Alignment.centerRight, + child: AnimatedContainer( + alignment: Alignment.centerLeft, + width: cardWidth, + height: cardHeight, + duration: Duration(milliseconds: 500), + curve: Curves.fastOutSlowIn, + padding: EdgeInsets.only( + top: 1, + left: 1, + bottom: 1 + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)), + color: PaletteDark.borderCardColor, + boxShadow: [ + BoxShadow( + color: PaletteDark.historyPanel.withOpacity(0.5), + blurRadius: 8, + offset: Offset(5, 5)) + ] + ), + child: Container( + width: cardWidth, + height: cardHeight, + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)), + color: PaletteDark.historyPanel + ), + child: InkWell( + onTap: () => setState(() => isFrontSide = !isFrontSide), + child: isFrontSide + ? frontSide() + : backSide() + ), + ), + ), + ); + } + + Widget frontSide() { + final syncStore = Provider.of(context); + final walletStore = Provider.of(context); + final settingsStore = Provider.of(context); + final balanceStore = Provider.of(context); + final triangleButton = Image.asset('assets/images/triangle.png'); + + return Observer( + key: _syncingObserverKey, + builder: (_) { + final status = syncStore.status; + final statusText = status.title(); + final progress = syncStore.status.progress(); + final indicatorWidth = progress * cardWidth; + + String shortAddress = walletStore.subaddress.address; + shortAddress = shortAddress.replaceRange(4, shortAddress.length - 4, '...'); + + var descriptionText = ''; + + if (status is SyncingSyncStatus) { + descriptionText = S + .of(context) + .Blocks_remaining( + syncStore.status.toString()); + } + + if (status is FailedSyncStatus) { + descriptionText = S + .of(context) + .please_try_to_connect_to_another_node; + } + + return Container( + width: cardWidth, + height: cardHeight, + child: Stack( + children: [ + Container( + height: cardHeight, + width: indicatorWidth, + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)), + gradient: LinearGradient( + colors: colorsSync, + begin: Alignment.topCenter, + end: Alignment.bottomCenter + ) + ), + ), + progress != 1 + ? Positioned( + left: indicatorWidth, + top: 0, + bottom: 0, + child: Container( + width: 1, + height: cardHeight, + color: PaletteDark.borderCardColor, + ) + ) + : Offstage(), + isDraw ? Positioned( + left: 20, + right: 20, + top: 30, + bottom: 30, + child: Container( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + InkWell( + onTap: () {print('TAP 2');}, + child: Row( + children: [ + Text( + walletStore.name, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white + ), + ), + SizedBox(width: 10), + triangleButton + ], + ), + ), + SizedBox( + height: 5, + ), + Text( + walletStore.account.label, + style: TextStyle( + fontSize: 12, + color: PaletteDark.walletCardText + ), + ) + ], + ), + Container( + width: 98, + height: 32, + alignment: Alignment.center, + decoration: BoxDecoration( + color: PaletteDark.walletCardAddressField, + borderRadius: BorderRadius.all(Radius.circular(16)) + ), + child: Text( + shortAddress, + style: TextStyle( + fontSize: 12, + color: PaletteDark.walletCardAddressText + ), + ), + ) + ], + ), + status is SyncedSyncStatus + ? Observer( + key: _balanceObserverKey, + builder: (_) { + final balanceDisplayMode = settingsStore.balanceDisplayMode; + final symbol = settingsStore + .fiatCurrency + .toString(); + var balance = '---'; + var fiatBalance = '---'; + + if (balanceDisplayMode == + BalanceDisplayMode.availableBalance) { + balance = + balanceStore.unlockedBalance ?? + '0.0'; + fiatBalance = + '$symbol ${balanceStore.fiatUnlockedBalance}'; + } + + if (balanceDisplayMode == + BalanceDisplayMode.fullBalance) { + balance = + balanceStore.fullBalance ?? '0.0'; + fiatBalance = + '$symbol ${balanceStore.fiatFullBalance}'; + } + + return Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + balanceDisplayMode.toString(), + style: TextStyle( + fontSize: 12, + color: PaletteDark.walletCardText + ), + ), + SizedBox(height: 5), + Text( + balance, + style: TextStyle( + fontSize: 28, + color: Colors.white + ), + ) + ], + ), + Text( + fiatBalance, + style: TextStyle( + fontSize: 14, + color: Colors.white + ), + ) + ], + ); + } + ) + : Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + statusText, + style: TextStyle( + fontSize: 12, + color: PaletteDark.walletCardText + ), + ), + SizedBox(height: 5), + Text( + descriptionText, + style: TextStyle( + fontSize: 14, + color: Colors.white + ), + ) + ], + ) + ], + ) + ], + ), + ) + ) + : Offstage() + ], + ), + ); + }, + ); + } + + Widget backSide() { + final walletStore = Provider.of(context); + final rightArrow = Image.asset('assets/images/right_arrow.png'); + double messageBoxHeight = 0; + double messageBoxWidth = cardWidth - 10; + + return Observer( + key: _addressObserverKey, + builder: (_) { + return Container( + width: cardWidth, + height: cardHeight, + alignment: Alignment.topCenter, + child: Stack( + alignment: Alignment.topRight, + children: [ + Container( + width: cardWidth, + height: cardHeight, + padding: EdgeInsets.only(left: 20, right: 20, top: 30, bottom: 30), + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10), bottomLeft: Radius.circular(10)), + gradient: LinearGradient( + colors: colorsSync, + begin: Alignment.topCenter, + end: Alignment.bottomCenter + ) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Expanded( + child: Container( + height: 84, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + S.current.card_address, + style: TextStyle( + fontSize: 12, + color: PaletteDark.walletCardText + ), + ), + GestureDetector( + onTap: () { + Clipboard.setData(ClipboardData( + text: walletStore.subaddress.address)); + _addressObserverKey.currentState.setState(() { + messageBoxHeight = 20; + messageBoxWidth = cardWidth; + }); + Timer(Duration(milliseconds: 1000), () { + try { + _addressObserverKey.currentState.setState(() { + messageBoxHeight = 0; + messageBoxWidth = cardWidth - 10; + }); + } catch(e) { + print('${e.toString()}'); + } + }); + }, + child: Text( + walletStore.subaddress.address, + style: TextStyle( + fontSize: 14, + color: Colors.white + ), + ), + ) + ], + ), + ) + ), + SizedBox(width: 10), + Container( + width: 84, + height: 84, + child: QrImage( + data: walletStore.subaddress.address, + backgroundColor: Colors.transparent, + foregroundColor: PaletteDark.walletCardText, + ), + ) + ], + ), + Container( + height: 44, + padding: EdgeInsets.only(left: 20, right: 20), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(22)), + color: PaletteDark.walletCardSubAddressField + ), + child: InkWell( + onTap: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + S.current.subaddresses, + style: TextStyle( + fontSize: 14, + color: Colors.white + ), + ), + rightArrow + ], + ), + ), + ) + ], + ), + ), + AnimatedContainer( + width: messageBoxWidth, + height: messageBoxHeight, + alignment: Alignment.center, + duration: Duration(milliseconds: 500), + curve: Curves.fastOutSlowIn, + decoration: BoxDecoration( + borderRadius: BorderRadius.only(topLeft: Radius.circular(10)), + color: Colors.green + ), + child: Text( + S.of(context).copied_to_clipboard, + style: TextStyle( + fontSize: 10, + color: Colors.white + ), + ), + ) + ], + ), + ); + } + ); + } +} \ No newline at end of file diff --git a/lib/src/widgets/nav_bar.dart b/lib/src/widgets/nav_bar.dart index 5e540a09f..a46072615 100644 --- a/lib/src/widgets/nav_bar.dart +++ b/lib/src/widgets/nav_bar.dart @@ -19,8 +19,9 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget { middle: middle, trailing: trailing, height: _height, - backgroundColor: - _isDarkTheme ? Theme.of(context).backgroundColor : backgroundColor); + backgroundColor: backgroundColor); + /*backgroundColor: + _isDarkTheme ? Theme.of(context).backgroundColor : backgroundColor);*/ } factory NavBar.withShadow( @@ -37,12 +38,14 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget { middle: middle, trailing: trailing, height: 80, - backgroundColor: - _isDarkTheme ? Theme.of(context).backgroundColor : backgroundColor, + backgroundColor: backgroundColor, + /*backgroundColor: + _isDarkTheme ? Theme.of(context).backgroundColor : backgroundColor,*/ decoration: BoxDecoration( - color: _isDarkTheme + color: backgroundColor, + /*_isDarkTheme ? Theme.of(context).backgroundColor - : backgroundColor, + : backgroundColor,*/ boxShadow: [ BoxShadow( color: Color.fromRGBO(132, 141, 198, 0.11), diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 58d26c54c..a7e82893f 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -349,5 +349,8 @@ "version" : "Ausführung ${currentVersion}", "openalias_alert_title" : "XMR-Empfänger erkannt", - "openalias_alert_content" : "Sie senden Geld an\n${recipient_name}" + "openalias_alert_content" : "Sie senden Geld an\n${recipient_name}", + + "card_address" : "Adresse:", + "buy" : "Kaufen" } \ No newline at end of file diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 2a019d3e7..5681dc513 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -349,5 +349,8 @@ "version" : "Version ${currentVersion}", "openalias_alert_title" : "XMR Recipient Detected", - "openalias_alert_content" : "You will be sending funds to\n${recipient_name}" + "openalias_alert_content" : "You will be sending funds to\n${recipient_name}", + + "card_address" : "Address:", + "buy" : "Buy" } \ No newline at end of file diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 6b15f9c95..260df0433 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -349,5 +349,8 @@ "version" : "Versión ${currentVersion}", "openalias_alert_title" : "Destinatario XMR detectado", - "openalias_alert_content" : "Enviará fondos a\n${recipient_name}" + "openalias_alert_content" : "Enviará fondos a\n${recipient_name}", + + "card_address" : "Dirección:", + "buy" : "Comprar" } \ No newline at end of file diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 6760af1ff..85b6f080e 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -349,5 +349,8 @@ "version" : "संस्करण ${currentVersion}", "openalias_alert_title" : "XMR प्राप्तकर्ता का पता लगाया", - "openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}" + "openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}", + + "card_address" : "पता:", + "buy" : "खरीदें" } \ No newline at end of file diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index ddac44e75..a291e6a12 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -349,5 +349,8 @@ "version" : "バージョン ${currentVersion}", "openalias_alert_title" : "XMR受信者が検出されました", - "openalias_alert_content" : "に送金します\n${recipient_name}" + "openalias_alert_content" : "に送金します\n${recipient_name}", + + "card_address" : "住所:", + "buy" : "購入" } \ No newline at end of file diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 644629554..50acfcbb1 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -349,5 +349,8 @@ "version" : "버전 ${currentVersion}", "openalias_alert_title" : "XMR 수신자 감지", - "openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}" + "openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}", + + "card_address" : "주소:", + "buy" : "구입" } \ No newline at end of file diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index cefa5284b..0268e8a0e 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -349,5 +349,8 @@ "version" : "Versie ${currentVersion}", "openalias_alert_title" : "XMR-ontvanger gedetecteerd", - "openalias_alert_content" : "U stuurt geld naar\n${recipient_name}" + "openalias_alert_content" : "U stuurt geld naar\n${recipient_name}", + + "card_address" : "Adres:", + "buy" : "Kopen" } \ No newline at end of file diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 5da641175..dec019a07 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -349,5 +349,8 @@ "version" : "Wersja ${currentVersion}", "openalias_alert_title" : "Wykryto odbiorcę XMR", - "openalias_alert_content" : "Będziesz wysyłać środki na\n${recipient_name}" + "openalias_alert_content" : "Będziesz wysyłać środki na\n${recipient_name}", + + "card_address" : "Adres:", + "buy" : "Kup" } \ No newline at end of file diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index c1ff1ca32..fe855e87f 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -349,5 +349,8 @@ "version" : "Versão ${currentVersion}", "openalias_alert_title" : "Destinatário XMR detectado", - "openalias_alert_content" : "Você enviará fundos para\n${recipient_name}" + "openalias_alert_content" : "Você enviará fundos para\n${recipient_name}", + + "card_address" : "Endereço:", + "buy" : "Comprar" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 947cc1cb5..5692f7421 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -349,5 +349,8 @@ "version" : "Версия ${currentVersion}", "openalias_alert_title" : "Получатель XMR обнаружен", - "openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}" + "openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}", + + "card_address" : "Адрес:", + "buy" : "Купить" } \ No newline at end of file diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 39ce4762c..e44a993f7 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -349,5 +349,8 @@ "version" : "Версія ${currentVersion}", "openalias_alert_title" : "Отримувача XMR виявлено", - "openalias_alert_content" : "Ви будете відправляти кошти\n${recipient_name}" + "openalias_alert_content" : "Ви будете відправляти кошти\n${recipient_name}", + + "card_address" : "Адреса:", + "buy" : "Купити" } \ No newline at end of file diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 61625661a..06a428fce 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -349,5 +349,8 @@ "version" : "版 ${currentVersion}", "openalias_alert_title" : "檢測到XMR收件人", - "openalias_alert_content" : "您將匯款至\n${recipient_name}" + "openalias_alert_content" : "您將匯款至\n${recipient_name}", + + "card_address" : "地址:", + "buy" : "購買" } \ No newline at end of file