CWA-198 | removed buttons_widget, fixed wallet_card, trade_history_panel, date_section_raw, trade_raw, transaction_raw and dashboard_page

This commit is contained in:
Oleksandr Sobol 2020-04-17 22:40:11 +03:00
parent 823030403a
commit 2a18f4a1e4
20 changed files with 474 additions and 832 deletions

View file

@ -39,6 +39,7 @@ 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";
@ -439,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";
@ -1009,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 => "सेटिंग्स";
@ -1579,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 => "Настройки";
@ -2149,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 => "설정";
@ -2719,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";
@ -3289,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 => "Налаштування";
@ -3859,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 => "設定";
@ -4433,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";
@ -5003,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";
@ -5573,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";
@ -6143,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 => "设定值";

View file

@ -1,111 +1,18 @@
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/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();
/*@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<WalletStore>(context);
return Observer(builder: (_) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
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),
),
]);
});
}
@override
Widget trailing(BuildContext context) {
return SizedBox(
width: 20,
child: FlatButton(
padding: EdgeInsets.all(0),
onPressed: () => Navigator.of(context).pushNamed(Routes.settings),
child: Image.asset('assets/images/settings_icon.png',
color: Colors.grey, height: 20)),
);
}*/
@override
ObstructingPreferredSizeWidget appBar(BuildContext context) => null;
@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<void>(
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 {
@ -117,12 +24,6 @@ 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();
final _syncingObserverKey = GlobalKey();
final _listObserverKey = GlobalKey();
final _listKey = GlobalKey();*/
@override
Widget build(BuildContext context) {
@ -161,491 +62,22 @@ class DashboardPageBodyState extends State<DashboardPageBody> {
padding: EdgeInsets.only(left: 20, top: 23),
child: WalletCard(),
),
Padding(
padding: EdgeInsets.only(top: 28),
child: ButtonsWidget(),
),
Expanded(
child: TradeHistoryPanel()
child: Stack(
alignment: Alignment.topCenter,
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 28,
left: 0,
child: TradeHistoryPanel()
),
],
)
)
],
),
),
);
/*final balanceStore = Provider.of<BalanceStore>(context);
final actionListStore = Provider.of<ActionListStore>(context);
final syncStore = Provider.of<SyncStore>(context);
final settingsStore = Provider.of<SettingsStore>(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
? <String>[]
: 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: <Widget>[
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<Color>(
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: <Widget>[
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: <Widget>[
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: <Widget>[
PopupMenuButton<int>(
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<DateTime> 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();
});
});*/
}
}

View file

@ -1,118 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
class ButtonsWidget extends StatefulWidget {
@override
ButtonsWidgetState createState() => ButtonsWidgetState();
}
class ButtonsWidgetState extends State<ButtonsWidget> {
final sendImage = Image.asset('assets/images/send.png');
final exchangeImage = Image.asset('assets/images/exchange.png');
final buyImage = Image.asset('assets/images/coins.png');
double height;
bool isDraw;
@override
void initState() {
height = 0;
isDraw = false;
super.initState();
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
}
void afterLayout(dynamic _) {
setState(() => height = 108);
Timer(Duration(milliseconds: 250), () =>
setState(() => isDraw = true)
);
}
@override
Widget build(BuildContext context) {
return Container(
height: 108,
padding: EdgeInsets.only(left: 44, right: 44),
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
height: height,
duration: Duration(milliseconds: 500),
curve: Curves.fastOutSlowIn,
child: isDraw
? Row(
children: <Widget>[
Flexible(
child: actionButton(
image: sendImage,
title: S.of(context).send,
route: Routes.send
)
),
Flexible(
child: actionButton(
image: exchangeImage,
title: S.of(context).exchange,
route: Routes.exchange
)
),
Flexible(
child: actionButton(
image: buyImage,
title: 'Buy',
route: ''
)
)
],
)
: Offstage(),
),
);
}
Widget actionButton({
@required Image image,
@required String title,
@required String route}) {
return Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GestureDetector(
onTap: () {
if (route.isNotEmpty) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
}
},
child: Container(
height: 48,
width: 48,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle
),
child: image,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Text(
title,
style: TextStyle(
fontSize: 16,
color: PaletteDark.walletCardText
),
),
)
],
),
);
}
}

View file

@ -35,11 +35,12 @@ 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: 12, color: PaletteDark.historyPanelText))),
return Container(
padding: EdgeInsets.only(top: 10, bottom: 10, left: 20, right: 20),
alignment: Alignment.center,
color: PaletteDark.historyPanel,
child: Text(title,
style: TextStyle(fontSize: 12, color: PaletteDark.historyPanelText))
);
}
}

View file

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:cake_wallet/src/domain/common/balance_display_mode.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/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:cake_wallet/generated/i18n.dart';
@ -15,6 +16,7 @@ import 'package:cake_wallet/routes.dart';
import 'date_section_raw.dart';
import 'trade_row.dart';
import 'transaction_raw.dart';
import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
class TradeHistoryPanel extends StatefulWidget {
@override
@ -27,15 +29,11 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
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);
}
@ -44,11 +42,7 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
screenHeight = MediaQuery.of(context).size.height;
setState(() {
panelHeight = screenHeight;
opacity = 1;
});
Timer(Duration(milliseconds: 350), () =>
setState(() => isDraw = true)
);
}
@override
@ -56,123 +50,399 @@ class TradeHistoryPanelState extends State<TradeHistoryPanel> {
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,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
alignment: Alignment.bottomCenter,
child: AnimatedContainer(
width: double.infinity,
width: MediaQuery.of(context).size.width,
height: panelHeight,
duration: Duration(milliseconds: 1000),
duration: Duration(milliseconds: 500),
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(
child: CustomScrollView(
slivers: <Widget>[
SliverPersistentHeader(
delegate: ButtonHeader(),
pinned: true,
floating: false,
),
Observer(
key: _listObserverKey,
builder: (_) {
final items = actionListStore.items == null
? <String>[]
: actionListStore.items;
final itemsCount = items.length;
final itemsCount = items.length + 1;
final symbol = settingsStore.fiatCurrency.toString();
double freeSpaceHeight = MediaQuery.of(context).size.height - 496; // FIXME
return Expanded(
child: ListView.builder(
key: _listKey,
padding: EdgeInsets.only(bottom: 15),
itemCount: itemsCount,
itemBuilder: (context, index) {
return SliverList(
key: _listKey,
delegate: SliverChildBuilderDelegate(
(context, index) {
final item = items[index];
if (index == itemsCount - 1) {
freeSpaceHeight = freeSpaceHeight >= 0 ? freeSpaceHeight : 0;
if (item is DateSectionItem) {
return DateSectionRaw(date: item.date);
}
return Container(
height: freeSpaceHeight,
width: MediaQuery.of(context).size.width,
color: PaletteDark.historyPanel,
);
}
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);
final item = items[index];
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 DateSectionItem) {
freeSpaceHeight -= 32; // FIXME
return DateSectionRaw(date: item.date);
}
if (item is TradeListItem) {
final trade = item.trade;
final savedDisplayMode = settingsStore.balanceDisplayMode;
final formattedAmount = trade.amount != null
? savedDisplayMode == BalanceDisplayMode.hiddenBalance
? '---'
: trade.amountFormatted()
: trade.amount;
if (item is TransactionListItem) {
freeSpaceHeight -= 45; // FIXME
final transaction = item.transaction;
final savedDisplayMode = settingsStore.balanceDisplayMode;
final formattedAmount =
savedDisplayMode == BalanceDisplayMode.hiddenBalance
? '---'
: transaction.amountFormatted();
final formattedFiatAmount =
savedDisplayMode == BalanceDisplayMode.hiddenBalance
? '---'
: transaction.fiatAmount(symbol);
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 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);
}
return Container();
}
)
if (item is TradeListItem) {
freeSpaceHeight -= 45; // FIXME
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
)
);
})
],
),
],
)
: Offstage()
),
);
}
}
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<ActionListStore>(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: <Widget>[
Opacity(
opacity: buttonsOpacity,
child: Container(
height: buttonsHeight,
padding: EdgeInsets.only(left: 44, right: 44),
child: Row(
children: <Widget>[
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: <Widget>[
Text(
S.of(context).trade_history_title,
style: TextStyle(
fontSize: 20,
color: Colors.white
),
),
Positioned(
right: 0,
child: PopupMenuButton<int>(
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<DateTime> 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: <Widget>[
GestureDetector(
onTap: () {
if (route.isNotEmpty) {
Navigator.of(context, rootNavigator: true).pushNamed(route);
}
},
child: Container(
height: 48,
width: 48,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle
),
child: image,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Text(
title,
style: TextStyle(
fontSize: 16,
color: PaletteDark.walletCardText
),
),
)
],
),
);
}

View file

@ -26,7 +26,8 @@ class TradeRow extends StatelessWidget {
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.only(top: 5, bottom: 5),
color: PaletteDark.historyPanel,
padding: EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20),
child: Row(children: <Widget>[
Container(
height: 36,
@ -48,11 +49,14 @@ class TradeRow extends StatelessWidget {
Text('${from.toString()}${to.toString()}',
style: TextStyle(
fontSize: 16,
color: Colors.white
)),
formattedAmount != null
? Text(formattedAmount + ' ' + amountCrypto,
style: const TextStyle(
fontSize: 16))
fontSize: 16,
color: Colors.white
))
: Container()
]),
SizedBox(height: 5),

View file

@ -24,7 +24,8 @@ class TransactionRow extends StatelessWidget {
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.only(top: 5, bottom: 5),
color: PaletteDark.historyPanel,
padding: EdgeInsets.only(top: 5, bottom: 5, left: 20, right: 20),
child: Row(children: <Widget>[
Container(
height: 36,
@ -54,12 +55,15 @@ class TransactionRow extends StatelessWidget {
(isPending ? S.of(context).pending : ''),
style: TextStyle(
fontSize: 16,
color: Colors.white
)),
Text(direction == TransactionDirection.incoming
? formattedAmount
: '- ' + formattedAmount,
style: const TextStyle(
fontSize: 16))
fontSize: 16,
color: Colors.white
))
]),
SizedBox(height: 5,),
Row(

View file

@ -159,7 +159,8 @@ class WalletCardState extends State<WalletCard> {
walletStore.name,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold
fontWeight: FontWeight.bold,
color: Colors.white
),
),
SizedBox(width: 10),
@ -243,7 +244,8 @@ class WalletCardState extends State<WalletCard> {
Text(
balance,
style: TextStyle(
fontSize: 28
fontSize: 28,
color: Colors.white
),
)
],
@ -251,7 +253,8 @@ class WalletCardState extends State<WalletCard> {
Text(
fiatBalance,
style: TextStyle(
fontSize: 14
fontSize: 14,
color: Colors.white
),
)
],
@ -276,7 +279,8 @@ class WalletCardState extends State<WalletCard> {
Text(
descriptionText,
style: TextStyle(
fontSize: 14
fontSize: 14,
color: Colors.white
),
)
],
@ -299,6 +303,7 @@ class WalletCardState extends State<WalletCard> {
final walletStore = Provider.of<WalletStore>(context);
final rightArrow = Image.asset('assets/images/right_arrow.png');
double messageBoxHeight = 0;
double messageBoxWidth = cardWidth - 30;
return Observer(
key: _addressObserverKey,
@ -308,6 +313,7 @@ class WalletCardState extends State<WalletCard> {
height: cardHeight,
alignment: Alignment.topCenter,
child: Stack(
alignment: Alignment.topRight,
children: <Widget>[
Container(
width: cardWidth,
@ -328,7 +334,7 @@ class WalletCardState extends State<WalletCard> {
children: <Widget>[
Expanded(
child: Container(
height: 72,
height: 84,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
@ -344,10 +350,16 @@ class WalletCardState extends State<WalletCard> {
onTap: () {
Clipboard.setData(ClipboardData(
text: walletStore.subaddress.address));
_addressObserverKey.currentState.setState(() => messageBoxHeight = 20);
_addressObserverKey.currentState.setState(() {
messageBoxHeight = 20;
messageBoxWidth = cardWidth;
});
Timer(Duration(milliseconds: 1000), () {
try {
_addressObserverKey.currentState.setState(() => messageBoxHeight = 0);
_addressObserverKey.currentState.setState(() {
messageBoxHeight = 0;
messageBoxWidth = cardWidth - 30;
});
} catch(e) {
print('${e.toString()}');
}
@ -357,6 +369,7 @@ class WalletCardState extends State<WalletCard> {
walletStore.subaddress.address,
style: TextStyle(
fontSize: 14,
color: Colors.white
),
),
)
@ -364,10 +377,10 @@ class WalletCardState extends State<WalletCard> {
),
)
),
SizedBox(width: 20),
SizedBox(width: 10),
Container(
width: 72,
height: 72,
width: 84,
height: 84,
child: QrImage(
data: walletStore.subaddress.address,
backgroundColor: Colors.transparent,
@ -393,6 +406,7 @@ class WalletCardState extends State<WalletCard> {
S.current.subaddresses,
style: TextStyle(
fontSize: 14,
color: Colors.white
),
),
rightArrow
@ -404,7 +418,7 @@ class WalletCardState extends State<WalletCard> {
),
),
AnimatedContainer(
width: cardWidth,
width: messageBoxWidth,
height: messageBoxHeight,
alignment: Alignment.center,
duration: Duration(milliseconds: 500),

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR-Empfänger erkannt",
"openalias_alert_content" : "Sie senden Geld an\n${recipient_name}",
"card_address" : "Adresse:"
"card_address" : "Adresse:",
"buy" : "Kaufen"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR Recipient Detected",
"openalias_alert_content" : "You will be sending funds to\n${recipient_name}",
"card_address" : "Address:"
"card_address" : "Address:",
"buy" : "Buy"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "Destinatario XMR detectado",
"openalias_alert_content" : "Enviará fondos a\n${recipient_name}",
"card_address" : "Dirección:"
"card_address" : "Dirección:",
"buy" : "Comprar"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR प्राप्तकर्ता का पता लगाया",
"openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}",
"card_address" : "पता:"
"card_address" : "पता:",
"buy" : "खरीदें"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR受信者が検出されました",
"openalias_alert_content" : "に送金します\n${recipient_name}",
"card_address" : "住所:"
"card_address" : "住所:",
"buy" : "購入"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR 수신자 감지",
"openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}",
"card_address" : "주소:"
"card_address" : "주소:",
"buy" : "구입"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "XMR-ontvanger gedetecteerd",
"openalias_alert_content" : "U stuurt geld naar\n${recipient_name}",
"card_address" : "Adres:"
"card_address" : "Adres:",
"buy" : "Kopen"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "Wykryto odbiorcę XMR",
"openalias_alert_content" : "Będziesz wysyłać środki na\n${recipient_name}",
"card_address" : "Adres:"
"card_address" : "Adres:",
"buy" : "Kup"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "Destinatário XMR detectado",
"openalias_alert_content" : "Você enviará fundos para\n${recipient_name}",
"card_address" : "Endereço:"
"card_address" : "Endereço:",
"buy" : "Comprar"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "Получатель XMR обнаружен",
"openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}",
"card_address" : "Адрес:"
"card_address" : "Адрес:",
"buy" : "Купить"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "Отримувача XMR виявлено",
"openalias_alert_content" : "Ви будете відправляти кошти\n${recipient_name}",
"card_address" : "Адреса:"
"card_address" : "Адреса:",
"buy" : "Купити"
}

View file

@ -351,5 +351,6 @@
"openalias_alert_title" : "檢測到XMR收件人",
"openalias_alert_content" : "您將匯款至\n${recipient_name}",
"card_address" : "地址:"
"card_address" : "地址:",
"buy" : "購買"
}