mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-18 05:51:34 +02:00
@@ -224,6 +224,9 @@ class ContactListPage extends BasePage {
|
||||
case CryptoCurrency.xrp:
|
||||
image = Image.asset('assets/images/xrp.png', height: 24, width: 24);
|
||||
break;
|
||||
case CryptoCurrency.xhv:
|
||||
image = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
break;
|
||||
default:
|
||||
image = null;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class DashboardPage extends BasePage {
|
||||
|
||||
final DashboardViewModel walletViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
final controller = PageController(initialPage: 1);
|
||||
final controller = PageController(initialPage: 0);
|
||||
|
||||
var pages = <Widget>[];
|
||||
bool _isEffectsInstalled = false;
|
||||
@@ -101,21 +101,10 @@ class DashboardPage extends BasePage {
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final exchangeImage = Image.asset('assets/images/transfer.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final buyImage = Image.asset('assets/images/buy.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final sellImage = Image.asset('assets/images/sell.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
_setEffects(context);
|
||||
|
||||
return SafeArea(
|
||||
minimum: EdgeInsets.only(bottom: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
@@ -125,7 +114,7 @@ class DashboardPage extends BasePage {
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) => pages[index])),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 24),
|
||||
padding: EdgeInsets.only(bottom: 24, top: 10),
|
||||
child: SmoothPageIndicator(
|
||||
controller: controller,
|
||||
count: pages.length,
|
||||
@@ -140,48 +129,89 @@ class DashboardPage extends BasePage {
|
||||
.display1
|
||||
.backgroundColor),
|
||||
)),
|
||||
|
||||
ClipRect(
|
||||
child:Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 38),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32, bottom: 14, top: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
if (!isMoneroOnly)
|
||||
Observer(builder: (_) {
|
||||
return ClipRect(
|
||||
child:Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
if (walletViewModel.hasBuyAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/buy.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledBuyAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).buy,
|
||||
onClick: () async => await _onClickBuyButton(context),
|
||||
textColor: !walletViewModel.isEnabledBuyAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
ActionButton(
|
||||
image: buyImage,
|
||||
title: S.of(context).buy,
|
||||
onClick: () async => await _onClickBuyButton(context),
|
||||
),
|
||||
ActionButton(
|
||||
image: receiveImage,
|
||||
title: S.of(context).receive,
|
||||
route: Routes.receive),
|
||||
ActionButton(
|
||||
image: exchangeImage,
|
||||
title: S.of(context).exchange,
|
||||
route: Routes.exchange),
|
||||
ActionButton(
|
||||
image: sendImage,
|
||||
title: S.of(context).send,
|
||||
route: Routes.send),
|
||||
if (!isMoneroOnly)
|
||||
image: receiveImage,
|
||||
title: S.of(context).receive,
|
||||
route: Routes.addressPage),
|
||||
if (walletViewModel.hasExchangeAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/transfer.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledExchangeAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).exchange,
|
||||
onClick: () async => _onClickExchangeButton(context),
|
||||
textColor: !walletViewModel.isEnabledExchangeAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
ActionButton(
|
||||
image: sellImage,
|
||||
title: S.of(context).sell,
|
||||
onClick: () async => await _onClickSellButton(context),
|
||||
),
|
||||
],
|
||||
),),
|
||||
),),),
|
||||
image: sendImage,
|
||||
title: S.of(context).send,
|
||||
route: Routes.send),
|
||||
if (walletViewModel.hasSellAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/sell.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledSellAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).sell,
|
||||
onClick: () async => await _onClickSellButton(context),
|
||||
textColor: !walletViewModel.isEnabledSellAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
],
|
||||
),),
|
||||
),),);
|
||||
}),
|
||||
|
||||
],
|
||||
));
|
||||
@@ -192,9 +222,6 @@ class DashboardPage extends BasePage {
|
||||
return;
|
||||
}
|
||||
|
||||
pages.add(AddressPage(
|
||||
addressListViewModel: addressListViewModel,
|
||||
walletViewModel: walletViewModel));
|
||||
pages.add(balancePage);
|
||||
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
|
||||
_isEffectsInstalled = true;
|
||||
@@ -289,4 +316,24 @@ class DashboardPage extends BasePage {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onClickExchangeButton(BuildContext context) async {
|
||||
final walletType = walletViewModel.type;
|
||||
|
||||
switch (walletType) {
|
||||
case WalletType.haven:
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'Exchange',
|
||||
alertContent: 'Exchange for this asset is not supported yet.',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
break;
|
||||
default:
|
||||
await Navigator.of(context).pushNamed(Routes.exchange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,25 @@ class ActionButton extends StatelessWidget {
|
||||
@required this.title,
|
||||
this.route,
|
||||
this.onClick,
|
||||
this.alignment = Alignment.center});
|
||||
this.alignment = Alignment.center,
|
||||
this.textColor});
|
||||
|
||||
final Image image;
|
||||
final String title;
|
||||
final String route;
|
||||
final Alignment alignment;
|
||||
final void Function() onClick;
|
||||
final Color textColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var _textColor = textColor ?? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 14, bottom: 16, left: 10, right: 10),
|
||||
alignment: alignment,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -42,8 +50,7 @@ class ActionButton extends StatelessWidget {
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Theme.of(context).accentTextTheme.display3
|
||||
.backgroundColor),
|
||||
color: _textColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
@@ -15,7 +16,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class AddressPage extends StatelessWidget {
|
||||
class AddressPage extends BasePage {
|
||||
AddressPage({@required this.addressListViewModel,
|
||||
this.walletViewModel})
|
||||
: _cryptoAmountFocus = FocusNode();
|
||||
@@ -26,7 +27,64 @@ class AddressPage extends StatelessWidget {
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String get title => S.current.receive;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => currentTheme.type == ThemeType.bright
|
||||
? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
||||
@override
|
||||
Widget leading(BuildContext context) {
|
||||
final _backButton = Icon(Icons.arrow_back_ios,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
|
||||
size: 16,);
|
||||
|
||||
return SizedBox(
|
||||
height: 37,
|
||||
width: 37,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => onClose(context),
|
||||
child: _backButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||
(BuildContext context, Widget scaffold) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).accentColor,
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
Theme.of(context).primaryColor,
|
||||
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
|
||||
child: scaffold);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
autorun((_) async {
|
||||
if (!walletViewModel.isOutdatedElectrumWallet
|
||||
|| !walletViewModel.settingsStore.shouldShowReceiveWarning) {
|
||||
@@ -66,7 +124,6 @@ class AddressPage extends StatelessWidget {
|
||||
)
|
||||
]),
|
||||
child: Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -15,23 +16,21 @@ class BalancePage extends StatelessWidget{
|
||||
|
||||
Color get backgroundLightColor =>
|
||||
settingsStore.currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onLongPress: () =>
|
||||
dashboardViewModel.balanceViewModel.isReversing =
|
||||
!dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPressUp: () =>
|
||||
dashboardViewModel.balanceViewModel.isReversing =
|
||||
!dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPress: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 56),
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
margin: const EdgeInsets.only(left: 24, bottom: 16),
|
||||
child: Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.asset,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
@@ -44,162 +43,140 @@ class BalancePage extends StatelessWidget{
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
})),
|
||||
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 24, left: 24, right: 24, bottom: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 8,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 8,),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.availableBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 4,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.availableFiatBalance.toString()}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 26),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 8),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.additionalBalance
|
||||
.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 4,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.additionalFiatBalance.toString()}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.currency.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
})),
|
||||
Observer(builder: (_) {
|
||||
return ListView.separated(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
|
||||
itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
|
||||
itemBuilder: (__, index) {
|
||||
final balance = dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
|
||||
return buildBalanceRow(context,
|
||||
availableBalanceLabel: '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
|
||||
availableBalance: balance.availableBalance,
|
||||
availableFiatBalance: balance.fiatAvailableBalance,
|
||||
additionalBalanceLabel: '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
|
||||
additionalBalance: balance.additionalBalance,
|
||||
additionalFiatBalance: balance.fiatAdditionalBalance,
|
||||
currency: balance.formattedAssetTitle);
|
||||
});
|
||||
})
|
||||
])));
|
||||
}
|
||||
|
||||
Widget buildBalanceRow(BuildContext context,
|
||||
{String availableBalanceLabel,
|
||||
String availableBalance,
|
||||
String availableFiatBalance,
|
||||
String additionalBalanceLabel,
|
||||
String additionalBalance,
|
||||
String additionalFiatBalance,
|
||||
String currency}) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 4,),
|
||||
Text('${availableBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
AutoSizeText(
|
||||
availableBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center),
|
||||
Text(currency,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
]),
|
||||
SizedBox(height: 4,),
|
||||
Text('${availableFiatBalance}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 26),
|
||||
Text('${additionalBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 8),
|
||||
AutoSizeText(
|
||||
additionalBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center),
|
||||
SizedBox(height: 4,),
|
||||
Text('${additionalFiatBalance}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
])),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
Image moneroIcon;
|
||||
Image bitcoinIcon;
|
||||
Image litecoinIcon;
|
||||
Image havenIcon;
|
||||
final largeScreen = 731;
|
||||
|
||||
double menuWidth;
|
||||
@@ -78,6 +79,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
|
||||
color: Theme.of(context).accentTextTheme.overline.decorationColor);
|
||||
litecoinIcon = Image.asset('assets/images/litecoin_menu.png');
|
||||
havenIcon = Image.asset('assets/images/haven_menu.png');
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -242,6 +244,8 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
return bitcoinIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
|
||||
final walletTypeLightImage =
|
||||
Image.asset('assets/images/wallet_type_light.png');
|
||||
final havenIcon =
|
||||
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
|
||||
WalletType selected;
|
||||
List<WalletType> types;
|
||||
@@ -129,6 +131,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
return bitcoinIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class ReceivePage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return addressListViewModel.type == WalletType.monero
|
||||
return (addressListViewModel.type == WalletType.monero || addressListViewModel.type == WalletType.haven)
|
||||
? KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
|
||||
@@ -133,54 +133,7 @@ class QRWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
))),
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return addressListViewModel.emoji.isNotEmpty
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(bottom: 10),
|
||||
child: Builder(
|
||||
builder: (context) => GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: addressListViewModel.emoji));
|
||||
showBar<void>(
|
||||
context, S.of(context).copied_to_clipboard);
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).yat,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(child:Text(
|
||||
addressListViewModel.emoji,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 26))),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: copyImage,
|
||||
)]
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
)),
|
||||
)
|
||||
: Container();
|
||||
})
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||
BlockchainHeightWidget(
|
||||
focusNode: widget.blockHeightFocusNode,
|
||||
key: blockchainHeightKey,
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered)
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered,
|
||||
hasDatePicker: widget.type == WalletType.monero)
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ class WalletRestorePage extends BasePage {
|
||||
.text
|
||||
.split(' ');
|
||||
|
||||
if (walletRestoreViewModel.type == WalletType.monero &&
|
||||
if ((walletRestoreViewModel.type == WalletType.monero || walletRestoreViewModel.type == WalletType.haven) &&
|
||||
seedWords.length != WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:ui';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -22,6 +23,7 @@ import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
class SendPage extends BasePage {
|
||||
SendPage({@required this.sendViewModel}) : _formKey = GlobalKey<FormState>();
|
||||
@@ -140,6 +142,7 @@ class SendPage extends BasePage {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (sendViewModel.hasMultiRecipient)
|
||||
Container(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
@@ -256,27 +259,43 @@ class SendPage extends BasePage {
|
||||
EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
sendViewModel.addOutput();
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
controller.jumpToPage(sendViewModel.outputs.length - 1);
|
||||
});
|
||||
},
|
||||
text: S.of(context).add_receiver,
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
isDottedBorder: true,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)),
|
||||
if (sendViewModel.hasCurrecyChanger)
|
||||
Observer(builder: (_) =>
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () => presentCurrencyPicker(context),
|
||||
text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)
|
||||
)
|
||||
),
|
||||
if (sendViewModel.hasMultiRecipient)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
sendViewModel.addOutput();
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
controller.jumpToPage(sendViewModel.outputs.length - 1);
|
||||
});
|
||||
},
|
||||
text: S.of(context).add_receiver,
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
isDottedBorder: true,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
return LoadingPrimaryButton(
|
||||
@@ -298,7 +317,7 @@ class SendPage extends BasePage {
|
||||
showErrorValidationAlert(context);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await sendViewModel.createTransaction();
|
||||
|
||||
},
|
||||
@@ -377,7 +396,7 @@ class SendPage extends BasePage {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: S.of(context).send_success(
|
||||
sendViewModel.currency.toString()),
|
||||
sendViewModel.selectedCryptoCurrency.toString()),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () =>
|
||||
Navigator.of(context).pop());
|
||||
@@ -418,4 +437,17 @@ class SendPage extends BasePage {
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
|
||||
void presentCurrencyPicker(BuildContext context) async {
|
||||
await showPopUp<CryptoCurrency>(
|
||||
builder: (_) => Picker(
|
||||
items: sendViewModel.currencies,
|
||||
displayItem: (Object item) => item.toString(),
|
||||
selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
|
||||
title: S.of(context).please_select,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
|
||||
),
|
||||
context: context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class SendCardState extends State<SendCard>
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
sendViewModel.currency.title +
|
||||
sendViewModel.selectedCryptoCurrency.title +
|
||||
':',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@@ -391,7 +391,7 @@ class SendCardState extends State<SendCard>
|
||||
.toString() +
|
||||
' ' +
|
||||
sendViewModel
|
||||
.currency.title,
|
||||
.selectedCryptoCurrency.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight:
|
||||
|
||||
@@ -45,6 +45,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
|
||||
final nonWalletTypeIcon =
|
||||
Image.asset('assets/images/close.png', height: 24, width: 24);
|
||||
final havenIcon =
|
||||
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
final scrollController = ScrollController();
|
||||
final double tileHeight = 60;
|
||||
Flushbar<void> _progressBar;
|
||||
@@ -176,12 +178,12 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
bottomSection: Column(children: <Widget>[
|
||||
PrimaryImageButton(
|
||||
onPressed: () {
|
||||
if (isMoneroOnly) {
|
||||
Navigator.of(context).pushNamed(Routes.newWallet, arguments: WalletType.monero);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
},
|
||||
if (isSingleCoin) {
|
||||
Navigator.of(context).pushNamed(Routes.newWallet, arguments: widget.walletListViewModel.currentWalletType);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
},
|
||||
image: newWalletImage,
|
||||
text: S.of(context).wallet_list_create_new_wallet,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
@@ -190,7 +192,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
SizedBox(height: 10.0),
|
||||
PrimaryImageButton(
|
||||
onPressed: () {
|
||||
if (isMoneroOnly) {
|
||||
if (isSingleCoin) {
|
||||
Navigator
|
||||
.of(context)
|
||||
.pushNamed(
|
||||
@@ -216,6 +218,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
return moneroIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return nonWalletTypeIcon;
|
||||
}
|
||||
@@ -264,18 +268,6 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _generateNewWallet() async {
|
||||
try {
|
||||
changeProcessText(S.of(context).creating_new_wallet);
|
||||
await widget.walletListViewModel.walletNewVM
|
||||
.create(options: 'English'); // FIXME: Unnamed constant
|
||||
hideProgressText();
|
||||
await Navigator.of(context).pushNamed(Routes.preSeed);
|
||||
} catch (e) {
|
||||
changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void changeProcessText(String text) {
|
||||
_progressBar = createBar<void>(text, duration: null)..show(context);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,30 @@ class WelcomePage extends BasePage {
|
||||
final welcomeImageLight = Image.asset('assets/images/welcome_light.png');
|
||||
final welcomeImageDark = Image.asset('assets/images/welcome.png');
|
||||
|
||||
String appTitle(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app;
|
||||
}
|
||||
|
||||
return S.of(context).cake_wallet;
|
||||
}
|
||||
|
||||
String appDescription(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com_wallet_text;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app_wallet_text;
|
||||
}
|
||||
|
||||
return S.of(context).first_wallet_text;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -83,9 +107,7 @@ class WelcomePage extends BasePage {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
isMoneroOnly
|
||||
? S.of(context).monero_com
|
||||
: S.of(context).cake_wallet,
|
||||
appTitle(context),
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -101,9 +123,7 @@ class WelcomePage extends BasePage {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
isMoneroOnly
|
||||
? S.of(context).monero_com_wallet_text
|
||||
: S.of(context).first_wallet_text,
|
||||
appDescription(context),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
@@ -7,12 +7,13 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
|
||||
class BlockchainHeightWidget extends StatefulWidget {
|
||||
BlockchainHeightWidget({GlobalKey key, this.onHeightChange, this.focusNode,
|
||||
this.onHeightOrDateEntered})
|
||||
this.onHeightOrDateEntered, this.hasDatePicker})
|
||||
: super(key: key);
|
||||
|
||||
final Function(int) onHeightChange;
|
||||
final Function(bool) onHeightOrDateEntered;
|
||||
final FocusNode focusNode;
|
||||
final bool hasDatePicker;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => BlockchainHeightState();
|
||||
@@ -67,43 +68,45 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
|
||||
)))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Text(
|
||||
S.of(context).widgets_or,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: InkWell(
|
||||
onTap: () => _selectDate(context),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: dateController,
|
||||
hintText: S.of(context).widgets_restore_from_date,
|
||||
)),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
||||
child: Text(
|
||||
S.of(context).restore_from_date_or_blockheight,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).hintColor
|
||||
if (widget.hasDatePicker) ...[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Text(
|
||||
S.of(context).widgets_or,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
),
|
||||
)
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: InkWell(
|
||||
onTap: () => _selectDate(context),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: dateController,
|
||||
hintText: S.of(context).widgets_restore_from_date,
|
||||
)),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
||||
child: Text(
|
||||
S.of(context).restore_from_date_or_blockheight,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).hintColor
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user