CWA-198 | added transaction history panel to dashboard page; added fiat currency symbol to transaction_info; changed date_section_raw, trade_row and transaction_raw
BIN
assets/images/2.0x/coins.png
Normal file
After Width: | Height: | Size: 971 B |
BIN
assets/images/2.0x/down_arrow.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
assets/images/2.0x/exchange.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/2.0x/filter_button.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/2.0x/menu_button.png
Normal file
After Width: | Height: | Size: 226 B |
BIN
assets/images/2.0x/send.png
Normal file
After Width: | Height: | Size: 582 B |
BIN
assets/images/2.0x/up_arrow.png
Normal file
After Width: | Height: | Size: 429 B |
BIN
assets/images/3.0x/coins.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/images/3.0x/down_arrow.png
Normal file
After Width: | Height: | Size: 559 B |
BIN
assets/images/3.0x/exchange.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/3.0x/filter_button.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/images/3.0x/menu_button.png
Normal file
After Width: | Height: | Size: 293 B |
BIN
assets/images/3.0x/send.png
Normal file
After Width: | Height: | Size: 836 B |
BIN
assets/images/3.0x/up_arrow.png
Normal file
After Width: | Height: | Size: 479 B |
BIN
assets/images/coins.png
Normal file
After Width: | Height: | Size: 600 B |
BIN
assets/images/down_arrow.png
Normal file
After Width: | Height: | Size: 287 B |
BIN
assets/images/exchange.png
Normal file
After Width: | Height: | Size: 588 B |
BIN
assets/images/filter_button.png
Normal file
After Width: | Height: | Size: 693 B |
BIN
assets/images/menu_button.png
Normal file
After Width: | Height: | Size: 165 B |
BIN
assets/images/send.png
Normal file
After Width: | Height: | Size: 378 B |
BIN
assets/images/up_arrow.png
Normal file
After Width: | Height: | Size: 292 B |
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<DashboardPageBody> {
|
||||
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<DashboardPageBody> {
|
|||
child: Column(
|
||||
children: <Widget>[
|
||||
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<DashboardPageBody> {
|
|||
child: ButtonsWidget(),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
)
|
||||
child: TradeHistoryPanel()
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
|
@ -20,8 +20,8 @@ class DateSectionRaw extends StatelessWidget {
|
|||
final settingsStore = Provider.of<SettingsStore>(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))),
|
||||
);
|
||||
}
|
||||
}
|
179
lib/src/screens/dashboard/widgets/trade_history_panel.dart
Normal file
|
@ -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<TradeHistoryPanel> {
|
||||
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<ActionListStore>(context);
|
||||
final settingsStore = Provider.of<SettingsStore>(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: <Widget>[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 36,
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
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
|
||||
? <String>[]
|
||||
: 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()
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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: <Widget>[
|
||||
_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: <Widget>[
|
||||
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: <Widget>[
|
||||
Text(createdAtFormattedDate,
|
||||
style: const TextStyle(
|
||||
fontSize: 13, color: Palette.blueGrey))
|
||||
fontSize: 14, color: PaletteDark.historyPanelText))
|
||||
]),
|
||||
],
|
||||
),
|
|
@ -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: <Widget>[
|
||||
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: <Widget>[
|
||||
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: <Widget>[
|
||||
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))
|
||||
]),
|
||||
],
|
||||
),
|