Merge pull request #49 from cake-tech/CWA-198-implement-main-screen

Cwa 198 implement main screen
This commit is contained in:
Oleksandr Sobol 2020-05-01 22:09:36 +03:00 committed by GitHub
commit 069bef967a
54 changed files with 1168 additions and 636 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

BIN
assets/images/2.0x/send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
assets/images/3.0x/send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

BIN
assets/images/coins.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

BIN
assets/images/exchange.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

BIN
assets/images/header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

BIN
assets/images/send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

BIN
assets/images/triangle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

BIN
assets/images/up_arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

View file

@ -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 => "设定值";

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);*/
}
}

View file

@ -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<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),
),
]);
});
}
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<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 {
@ -111,488 +42,26 @@ class DashboardPageBody extends StatefulWidget {
}
class DashboardPageBodyState extends State<DashboardPageBody> {
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<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();
});
});
return SafeArea(
child: Container(
color: PaletteDark.mainBackgroundColor,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20, top: 10),
child: WalletCard(),
),
SizedBox(
height: 28,
),
Expanded(child: TradeHistoryPanel())
],
),
),
);
}
}

View file

@ -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<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: PaletteDark.borderCardColor,
shape: BoxShape.circle
),
child: image,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Text(
title,
style: TextStyle(
fontSize: 16,
color: PaletteDark.walletCardText
),
),
)
],
),
);
}
}

View file

@ -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) {
@ -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))
);
}
}

View file

@ -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<TradeHistoryPanel> {
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<ActionListStore>(context);
final settingsStore = Provider.of<SettingsStore>(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: <Widget>[
SliverPersistentHeader(
delegate: ButtonHeader(),
pinned: true,
floating: false,
),
Observer(
key: _listObserverKey,
builder: (_) {
final items = actionListStore.items == null
? <String>[]
: 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
)
);
})
],
)
),
);
}
}

View file

@ -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: <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 +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: <Widget>[
Text(createdAtFormattedDate,
style: const TextStyle(
fontSize: 13, color: Palette.blueGrey))
fontSize: 14, color: PaletteDark.historyPanelText))
]),
],
),

View file

@ -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: <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 +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: <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))
]),
],
),

View file

@ -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<WalletCard> {
final _syncingObserverKey = GlobalKey();
final _balanceObserverKey = GlobalKey();
final _addressObserverKey = GlobalKey();
final List<Color> 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<SyncStore>(context);
final walletStore = Provider.of<WalletStore>(context);
final settingsStore = Provider.of<SettingsStore>(context);
final balanceStore = Provider.of<BalanceStore>(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: <Widget>[
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: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
InkWell(
onTap: () {print('TAP 2');},
child: Row(
children: <Widget>[
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: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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<WalletStore>(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: <Widget>[
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: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(
height: 84,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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: <Widget>[
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
),
),
)
],
),
);
}
);
}
}

View file

@ -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),

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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" : "खरीदें"
}

View file

@ -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" : "購入"
}

View file

@ -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" : "구입"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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" : "Купить"
}

View file

@ -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" : "Купити"
}

View file

@ -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" : "購買"
}