mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-19 05:58:50 +02:00
Merged 4.1.0
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
@@ -9,13 +10,13 @@ enum AppBarStyle { regular, withShadow, transparent }
|
||||
|
||||
abstract class BasePage extends StatelessWidget {
|
||||
BasePage()
|
||||
: _scaffoldKey = GlobalKey<ScaffoldState>(),
|
||||
_closeButtonImage = Image.asset('assets/images/close_button.png'),
|
||||
_closeButtonImageDarkTheme =
|
||||
Image.asset('assets/images/close_button_dark_theme.png');
|
||||
: _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey;
|
||||
final Image _closeButtonImage;
|
||||
final Image _closeButtonImageDarkTheme;
|
||||
|
||||
final Image closeButtonImage =
|
||||
Image.asset('assets/images/close_button.png');
|
||||
final Image closeButtonImageDarkTheme =
|
||||
Image.asset('assets/images/close_button_dark_theme.png');
|
||||
|
||||
String get title => null;
|
||||
|
||||
@@ -37,7 +38,7 @@ abstract class BasePage extends StatelessWidget {
|
||||
|
||||
Widget Function(BuildContext, Widget) get rootWrapper => null;
|
||||
|
||||
bool get isDarkTheme => getIt.get<SettingsStore>().isDarkTheme;
|
||||
ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme;
|
||||
|
||||
void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer();
|
||||
|
||||
@@ -51,8 +52,8 @@ abstract class BasePage extends StatelessWidget {
|
||||
final _backButton = Icon(Icons.arrow_back_ios,
|
||||
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color,
|
||||
size: 16,);
|
||||
final _closeButton =
|
||||
isDarkTheme ? _closeButtonImageDarkTheme : _closeButtonImage;
|
||||
final _closeButton = currentTheme.type == ThemeType.dark
|
||||
? closeButtonImageDarkTheme : closeButtonImage;
|
||||
|
||||
return SizedBox(
|
||||
height: 37,
|
||||
@@ -88,8 +89,8 @@ abstract class BasePage extends StatelessWidget {
|
||||
Widget floatingActionButton(BuildContext context) => null;
|
||||
|
||||
ObstructingPreferredSizeWidget appBar(BuildContext context) {
|
||||
final appBarColor =
|
||||
isDarkTheme ? backgroundDarkColor : backgroundLightColor;
|
||||
final appBarColor = currentTheme.type == ThemeType.dark
|
||||
? backgroundDarkColor : backgroundLightColor;
|
||||
|
||||
switch (appBarStyle) {
|
||||
case AppBarStyle.regular:
|
||||
@@ -131,10 +132,12 @@ abstract class BasePage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final _backgroundColor = currentTheme.type == ThemeType.dark
|
||||
? backgroundDarkColor : backgroundLightColor;
|
||||
|
||||
final root = Scaffold(
|
||||
key: _scaffoldKey,
|
||||
backgroundColor:
|
||||
isDarkTheme ? backgroundDarkColor : backgroundLightColor,
|
||||
backgroundColor: _backgroundColor,
|
||||
resizeToAvoidBottomPadding: resizeToAvoidBottomPadding,
|
||||
extendBodyBehindAppBar: extendBodyBehindAppBar,
|
||||
endDrawer: endDrawer,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -61,107 +62,113 @@ class ContactListPage extends BasePage {
|
||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
||||
child: Observer(
|
||||
builder: (_) {
|
||||
return contactListViewModel.contacts.isNotEmpty
|
||||
? SectionStandardList(
|
||||
sectionCount: 1,
|
||||
context: context,
|
||||
itemCounter: (int sectionIndex) =>
|
||||
contactListViewModel.contacts.length,
|
||||
itemBuilder: (_, sectionIndex, index) {
|
||||
final contact = contactListViewModel.contacts[index];
|
||||
final image = _getCurrencyImage(contact.type);
|
||||
final content = GestureDetector(
|
||||
onTap: () async {
|
||||
if (!isEditable) {
|
||||
Navigator.of(context).pop(contact);
|
||||
return;
|
||||
}
|
||||
return SectionStandardList(
|
||||
context: context,
|
||||
sectionCount: 2,
|
||||
sectionTitleBuilder: (_, int sectionIndex) {
|
||||
var title = 'Contacts';
|
||||
|
||||
final isCopied = await showNameAndAddressDialog(
|
||||
context, contact.name, contact.address);
|
||||
if (sectionIndex == 0) {
|
||||
title = 'My wallets';
|
||||
}
|
||||
|
||||
if (isCopied != null && isCopied) {
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: contact.address));
|
||||
await showBar<void>(
|
||||
context, S.of(context).copied_to_clipboard);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image ?? Offstage(),
|
||||
Padding(
|
||||
padding: image != null
|
||||
? EdgeInsets.only(left: 12)
|
||||
: EdgeInsets.only(left: 0),
|
||||
child: Text(
|
||||
contact.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 24, bottom: 20),
|
||||
child: Text(title, style: TextStyle(fontSize: 36)));
|
||||
},
|
||||
itemCounter: (int sectionIndex) => sectionIndex == 0
|
||||
? contactListViewModel.walletContacts.length
|
||||
: contactListViewModel.contacts.length,
|
||||
itemBuilder: (_, sectionIndex, index) {
|
||||
if (sectionIndex == 0) {
|
||||
final walletInfo = contactListViewModel.walletContacts[index];
|
||||
return generateRaw(context, walletInfo);
|
||||
}
|
||||
|
||||
return !isEditable
|
||||
? content
|
||||
: Slidable(
|
||||
key: Key('${contact.key}'),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: content,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).edit,
|
||||
color: Colors.blue,
|
||||
icon: Icons.edit,
|
||||
onTap: () async =>
|
||||
await Navigator.of(context).pushNamed(
|
||||
Routes.addressBookAddContact,
|
||||
arguments: contact),
|
||||
),
|
||||
IconSlideAction(
|
||||
caption: S.of(context).delete,
|
||||
color: Colors.red,
|
||||
icon: CupertinoIcons.delete,
|
||||
onTap: () async {
|
||||
final isDelete =
|
||||
await showAlertDialog(context) ??
|
||||
false;
|
||||
final contact = contactListViewModel.contacts[index];
|
||||
final content = generateRaw(context, contact);
|
||||
|
||||
if (isDelete) {
|
||||
await contactListViewModel
|
||||
.delete(contact);
|
||||
}
|
||||
},
|
||||
),
|
||||
]);
|
||||
},
|
||||
)
|
||||
: Center(
|
||||
child: Text(
|
||||
S.of(context).placeholder_contacts,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.grey, fontSize: 14),
|
||||
),
|
||||
);
|
||||
return !isEditable
|
||||
? content
|
||||
: Slidable(
|
||||
key: Key('${contact.key}'),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: content,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).edit,
|
||||
color: Colors.blue,
|
||||
icon: Icons.edit,
|
||||
onTap: () async => await Navigator.of(context)
|
||||
.pushNamed(Routes.addressBookAddContact,
|
||||
arguments: contact),
|
||||
),
|
||||
IconSlideAction(
|
||||
caption: S.of(context).delete,
|
||||
color: Colors.red,
|
||||
icon: CupertinoIcons.delete,
|
||||
onTap: () async {
|
||||
final isDelete =
|
||||
await showAlertDialog(context) ?? false;
|
||||
|
||||
if (isDelete) {
|
||||
await contactListViewModel.delete(contact);
|
||||
}
|
||||
},
|
||||
),
|
||||
]);
|
||||
},
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
Widget generateRaw(BuildContext context, ContactBase contact) {
|
||||
final image = _getCurrencyImage(contact.type);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
if (!isEditable) {
|
||||
Navigator.of(context).pop(contact);
|
||||
return;
|
||||
}
|
||||
|
||||
final isCopied = await showNameAndAddressDialog(
|
||||
context, contact.name, contact.address);
|
||||
|
||||
if (isCopied != null && isCopied) {
|
||||
await Clipboard.setData(ClipboardData(text: contact.address));
|
||||
await showBar<void>(context, S.of(context).copied_to_clipboard);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding:
|
||||
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image ?? Offstage(),
|
||||
Padding(
|
||||
padding: image != null
|
||||
? EdgeInsets.only(left: 12)
|
||||
: EdgeInsets.only(left: 0),
|
||||
child: Text(
|
||||
contact.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Image _getCurrencyImage(CryptoCurrency currency) {
|
||||
Image image;
|
||||
switch (currency) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
@@ -20,7 +21,8 @@ class DashboardPage extends BasePage {
|
||||
});
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => Colors.transparent;
|
||||
Color get backgroundLightColor => currentTheme.type == ThemeType.bright
|
||||
? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
@@ -50,7 +52,8 @@ class DashboardPage extends BasePage {
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final menuButton =
|
||||
Image.asset('assets/images/menu.png', color: Colors.white);
|
||||
Image.asset('assets/images/menu.png',
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
|
||||
return Container(
|
||||
alignment: Alignment.centerRight,
|
||||
@@ -65,12 +68,6 @@ class DashboardPage extends BasePage {
|
||||
|
||||
final DashboardViewModel walletViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
final sendImage = Image.asset('assets/images/upload.png',
|
||||
height: 22.24, width: 24, color: Colors.white);
|
||||
final exchangeImage = Image.asset('assets/images/transfer.png',
|
||||
height: 24.27, width: 22.25, color: Colors.white);
|
||||
final receiveImage = Image.asset('assets/images/download.png',
|
||||
height: 22.24, width: 24, color: Colors.white);
|
||||
final controller = PageController(initialPage: 1);
|
||||
|
||||
var pages = <Widget>[];
|
||||
@@ -78,6 +75,15 @@ class DashboardPage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final sendImage = Image.asset('assets/images/upload.png',
|
||||
height: 22.24, width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final exchangeImage = Image.asset('assets/images/transfer.png',
|
||||
height: 24.27, width: 22.25,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final receiveImage = Image.asset('assets/images/download.png',
|
||||
height: 22.24, width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
_setEffects();
|
||||
|
||||
return SafeArea(
|
||||
@@ -100,7 +106,8 @@ class DashboardPage extends BasePage {
|
||||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context).indicatorColor,
|
||||
activeDotColor: Colors.white),
|
||||
activeDotColor: Theme.of(context).accentTextTheme.display1
|
||||
.backgroundColor),
|
||||
)),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 45, right: 45, bottom: 24),
|
||||
|
||||
@@ -9,44 +9,53 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
// FIXME: terrible design
|
||||
|
||||
class WalletMenu {
|
||||
WalletMenu(this.context, this.reconnect);
|
||||
|
||||
final List<WalletMenuItem> items = [
|
||||
WalletMenuItem(
|
||||
title: S.current.reconnect,
|
||||
image: Image.asset('assets/images/reconnect_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.rescan,
|
||||
image: Image.asset('assets/images/filter_icon.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.wallets,
|
||||
image: Image.asset('assets/images/wallet_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.nodes,
|
||||
image:
|
||||
Image.asset('assets/images/nodes_menu.png', height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.show_keys,
|
||||
image:
|
||||
Image.asset('assets/images/key_menu.png', height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.address_book_menu,
|
||||
image: Image.asset('assets/images/open_book_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.settings_title,
|
||||
image: Image.asset('assets/images/settings_menu.png',
|
||||
height: 16, width: 16)),
|
||||
];
|
||||
WalletMenu(this.context, this.reconnect, this.hasRescan) : items = [] {
|
||||
items.addAll([
|
||||
WalletMenuItem(
|
||||
title: S.current.reconnect,
|
||||
image: Image.asset('assets/images/reconnect_menu.png',
|
||||
height: 16, width: 16)),
|
||||
if (hasRescan)
|
||||
WalletMenuItem(
|
||||
title: S.current.rescan,
|
||||
image: Image.asset('assets/images/filter_icon.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.wallets,
|
||||
image: Image.asset('assets/images/wallet_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.nodes,
|
||||
image: Image.asset('assets/images/nodes_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.show_keys,
|
||||
image:
|
||||
Image.asset('assets/images/key_menu.png', height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.address_book_menu,
|
||||
image: Image.asset('assets/images/open_book_menu.png',
|
||||
height: 16, width: 16)),
|
||||
WalletMenuItem(
|
||||
title: S.current.settings_title,
|
||||
image: Image.asset('assets/images/settings_menu.png',
|
||||
height: 16, width: 16)),
|
||||
]);
|
||||
}
|
||||
|
||||
final List<WalletMenuItem> items;
|
||||
final BuildContext context;
|
||||
final Future<void> Function() reconnect;
|
||||
final bool hasRescan;
|
||||
|
||||
void action(int index) {
|
||||
switch (index) {
|
||||
var indx = index;
|
||||
|
||||
if (index > 0 && !hasRescan) {
|
||||
indx += 1;
|
||||
}
|
||||
|
||||
switch (indx) {
|
||||
case 0:
|
||||
_presentReconnectAlert(context);
|
||||
break;
|
||||
|
||||
@@ -39,7 +39,10 @@ class ActionButton extends StatelessWidget {
|
||||
SizedBox(height: 15),
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontSize: 14, color: Colors.white),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).accentTextTheme.display3
|
||||
.backgroundColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,62 +1,109 @@
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
|
||||
import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
|
||||
class AddressPage extends StatelessWidget {
|
||||
AddressPage({@required this.addressListViewModel});
|
||||
AddressPage({@required this.addressListViewModel})
|
||||
: _cryptoAmountFocus = FocusNode();
|
||||
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: QRWidget(addressListViewModel: addressListViewModel),
|
||||
)
|
||||
return KeyboardActions(
|
||||
autoScroll: false,
|
||||
disableScroll: true,
|
||||
tapOutsideToDismiss: true,
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor:
|
||||
Theme.of(context).accentTextTheme.body2.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
focusNode: _cryptoAmountFocus,
|
||||
toolbarButtons: [(_) => KeyboardDoneButton()],
|
||||
)
|
||||
]),
|
||||
child: Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: QRWidget(
|
||||
addressListViewModel: addressListViewModel,
|
||||
amountTextFieldFocusNode: _cryptoAmountFocus,
|
||||
isAmountFieldShow: !addressListViewModel.hasAccounts),
|
||||
)),
|
||||
Observer(builder: (_) {
|
||||
return addressListViewModel.hasAddressList
|
||||
? GestureDetector(
|
||||
onTap: () =>
|
||||
Navigator.of(context).pushNamed(Routes.receive),
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.only(left: 24, right: 12),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.all(Radius.circular(25)),
|
||||
border: Border.all(
|
||||
color:
|
||||
Theme.of(context).textTheme.subhead.color,
|
||||
width: 1),
|
||||
color: Theme.of(context).buttonColor),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Observer(
|
||||
builder: (_) => Text(
|
||||
addressListViewModel.hasAccounts
|
||||
? S
|
||||
.of(context)
|
||||
.accounts_subaddresses
|
||||
: S.of(context).addresses,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor),
|
||||
)),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: PrimaryButton(
|
||||
onPressed: () => addressListViewModel.nextAddress(),
|
||||
text: 'Next address',
|
||||
color: Theme.of(context).buttonColor,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor);
|
||||
})
|
||||
],
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.receive),
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.only(left: 24, right: 12),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(25)),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).textTheme.subhead.color,
|
||||
width: 1
|
||||
),
|
||||
color: Theme.of(context).buttonColor
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S.of(context).accounts_subaddresses,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 14,
|
||||
color: Colors.white,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
@@ -11,58 +12,86 @@ class BalancePage extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.all(24),
|
||||
child: GestureDetector(
|
||||
onTapUp: (_) => dashboardViewModel.balanceViewModel.isReversing = false,
|
||||
onTapDown: (_) => dashboardViewModel.balanceViewModel.isReversing = true,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.currency.toString(),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.currency.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 40,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
'${dashboardViewModel.balanceViewModel.availableBalanceLabel} (${dashboardViewModel.balanceViewModel.availableFiatBalance.toString()})',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.availableBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 40,
|
||||
fontSize: 54,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context).indicatorColor,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.displayMode.toString(),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
'${dashboardViewModel.balanceViewModel.additionalBalanceLabel} (${dashboardViewModel.balanceViewModel.additionalFiatBalance.toString()})',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.additionalBalance
|
||||
.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).indicatorColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(dashboardViewModel.balanceViewModel.cryptoBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 54,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 10),
|
||||
Observer(builder: (_) {
|
||||
return Text(dashboardViewModel.balanceViewModel.fiatBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).indicatorColor,
|
||||
height: 1),
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
],
|
||||
),
|
||||
)
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,15 @@ class HeaderRow extends StatelessWidget {
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (context) => FilterWidget(dashboardViewModel: dashboardViewModel)
|
||||
builder: (context) =>
|
||||
FilterWidget(dashboardViewModel: dashboardViewModel)
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
|
||||
@@ -66,8 +66,10 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletMenu =
|
||||
WalletMenu(context, () async => widget.dashboardViewModel.reconnect());
|
||||
final walletMenu = WalletMenu(
|
||||
context,
|
||||
() async => widget.dashboardViewModel.reconnect(),
|
||||
widget.dashboardViewModel.hasRescan);
|
||||
final itemCount = walletMenu.items.length;
|
||||
|
||||
moneroIcon = Image.asset('assets/images/monero_menu.png',
|
||||
@@ -148,16 +150,19 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
),
|
||||
if (widget.dashboardViewModel.subname !=
|
||||
null)
|
||||
Observer(builder: (_) => Text(
|
||||
widget.dashboardViewModel.subname,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.overline
|
||||
.decorationColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 12),
|
||||
))
|
||||
Observer(
|
||||
builder: (_) => Text(
|
||||
widget.dashboardViewModel
|
||||
.subname,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.overline
|
||||
.decorationColor,
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
fontSize: 12),
|
||||
))
|
||||
],
|
||||
),
|
||||
))
|
||||
|
||||
@@ -25,54 +25,53 @@ class TradeRow extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: 52,
|
||||
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
_getPoweredImage(provider),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
child: Container(
|
||||
height: 46,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_getPoweredImage(provider),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text('${from.toString()} → ${to.toString()}',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white
|
||||
)),
|
||||
formattedAmount != null
|
||||
? Text(formattedAmount + ' ' + amountCrypto,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white
|
||||
))
|
||||
: Container()
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(createdAtFormattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).textTheme
|
||||
.overline.backgroundColor))
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
))
|
||||
]),
|
||||
Text('${from.toString()} → ${to.toString()}',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor
|
||||
)),
|
||||
formattedAmount != null
|
||||
? Text(formattedAmount + ' ' + amountCrypto,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor
|
||||
))
|
||||
: Container()
|
||||
]),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(createdAtFormattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context).textTheme
|
||||
.overline.backgroundColor))
|
||||
])
|
||||
],
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,73 +23,73 @@ class TransactionRow extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: 62,
|
||||
padding: EdgeInsets.fromLTRB(24, 8, 24, 8),
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.only(left: 24, right: 24),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 36,
|
||||
width: 36,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).textTheme.overline.decorationColor
|
||||
),
|
||||
child: Image.asset(
|
||||
direction == TransactionDirection.incoming
|
||||
? 'assets/images/down_arrow.png'
|
||||
: 'assets/images/up_arrow.png'),
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 36,
|
||||
width: 36,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Theme.of(context).textTheme.overline.decorationColor
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 12),
|
||||
height: 56,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(direction == TransactionDirection.incoming
|
||||
? S.of(context).received
|
||||
: S.of(context).sent) +
|
||||
(isPending ? S.of(context).pending : ''),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white)),
|
||||
Text(formattedAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white))
|
||||
]),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(formattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.overline
|
||||
.backgroundColor)),
|
||||
Text(formattedFiatAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.overline
|
||||
.backgroundColor))
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
]),
|
||||
child: Image.asset(
|
||||
direction == TransactionDirection.incoming
|
||||
? 'assets/images/down_arrow.png'
|
||||
: 'assets/images/up_arrow.png'),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(direction == TransactionDirection.incoming
|
||||
? S.of(context).received
|
||||
: S.of(context).sent) +
|
||||
(isPending ? S.of(context).pending : ''),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor)),
|
||||
Text(formattedAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor))
|
||||
]),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(formattedDate,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.overline
|
||||
.backgroundColor)),
|
||||
Text(formattedFiatAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.overline
|
||||
.backgroundColor))
|
||||
])
|
||||
],
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ class TransactionsPage extends StatelessWidget {
|
||||
if (item is TransactionListItem) {
|
||||
final transaction = item.transaction;
|
||||
|
||||
return TransactionRow(
|
||||
return Observer(
|
||||
builder: (_) => TransactionRow(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.transactionDetails,
|
||||
arguments: transaction),
|
||||
@@ -55,7 +56,7 @@ class TransactionsPage extends StatelessWidget {
|
||||
.format(transaction.date),
|
||||
formattedAmount: item.formattedCryptoAmount,
|
||||
formattedFiatAmount: item.formattedFiatAmount,
|
||||
isPending: transaction.isPending);
|
||||
isPending: transaction.isPending));
|
||||
}
|
||||
|
||||
if (item is TradeListItem) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/entities/sync_status.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -62,10 +63,11 @@ class ExchangePage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) => TrailButton(
|
||||
caption: S.of(context).reset, onPressed: () {
|
||||
caption: S.of(context).reset,
|
||||
onPressed: () {
|
||||
_formKey.currentState.reset();
|
||||
exchangeViewModel.reset();
|
||||
});
|
||||
});
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
@@ -95,9 +97,8 @@ class ExchangePage extends BasePage {
|
||||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: isDarkTheme
|
||||
? Color.fromRGBO(48, 51, 60, 1.0)
|
||||
: Color.fromRGBO(98, 98, 98, 1.0),
|
||||
keyboardBarColor:
|
||||
Theme.of(context).accentTextTheme.body2.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
@@ -161,6 +162,11 @@ class ExchangePage extends BasePage {
|
||||
padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
|
||||
child: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
hasAllAmount: exchangeViewModel.hasAllAmount,
|
||||
allAmount: exchangeViewModel.hasAllAmount
|
||||
? () => exchangeViewModel
|
||||
.calculateDepositAllAmount()
|
||||
: null,
|
||||
amountFocusNode: _depositAmountFocus,
|
||||
key: depositKey,
|
||||
title: S.of(context).you_will_send,
|
||||
@@ -178,9 +184,30 @@ class ExchangePage extends BasePage {
|
||||
isAmountEstimated: false,
|
||||
hasRefundAddress: true,
|
||||
currencies: CryptoCurrency.all,
|
||||
onCurrencySelected: (currency) =>
|
||||
exchangeViewModel.changeDepositCurrency(
|
||||
currency: currency),
|
||||
onCurrencySelected: (currency) {
|
||||
// FIXME: need to move it into view model
|
||||
if (currency == CryptoCurrency.xmr &&
|
||||
exchangeViewModel.wallet.type ==
|
||||
WalletType.bitcoin) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (dialogContext) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).error,
|
||||
alertContent: S
|
||||
.of(context)
|
||||
.exchange_incorrect_current_wallet_for_xmr,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () =>
|
||||
Navigator.of(dialogContext)
|
||||
.pop());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
exchangeViewModel.changeDepositCurrency(
|
||||
currency: currency);
|
||||
},
|
||||
imageArrow: arrowBottomPurple,
|
||||
currencyButtonColor: Colors.transparent,
|
||||
addressButtonsColor:
|
||||
@@ -395,30 +422,35 @@ class ExchangePage extends BasePage {
|
||||
}),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
if ((exchangeViewModel.depositCurrency == CryptoCurrency.xmr)
|
||||
&&(!(exchangeViewModel.status is SyncedSyncStatus))) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).exchange,
|
||||
alertContent: S.of(context).exchange_sync_alert_content,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
} else {
|
||||
exchangeViewModel.createTrade();
|
||||
}
|
||||
}
|
||||
},
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading: exchangeViewModel.tradeState
|
||||
is TradeIsCreating)),
|
||||
builder: (_) => LoadingPrimaryButton(
|
||||
text: S.of(context).exchange,
|
||||
onPressed: () {
|
||||
if (_formKey.currentState.validate()) {
|
||||
if ((exchangeViewModel.depositCurrency ==
|
||||
CryptoCurrency.xmr) &&
|
||||
(!(exchangeViewModel.status
|
||||
is SyncedSyncStatus))) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).exchange,
|
||||
alertContent: S
|
||||
.of(context)
|
||||
.exchange_sync_alert_content,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () =>
|
||||
Navigator.of(context).pop());
|
||||
});
|
||||
} else {
|
||||
exchangeViewModel.createTrade();
|
||||
}
|
||||
}
|
||||
},
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading:
|
||||
exchangeViewModel.tradeState is TradeIsCreating)),
|
||||
]),
|
||||
)),
|
||||
));
|
||||
|
||||
@@ -27,7 +27,9 @@ class ExchangeCard extends StatefulWidget {
|
||||
this.borderColor = Colors.transparent,
|
||||
this.currencyValueValidator,
|
||||
this.addressTextFieldValidator,
|
||||
this.amountFocusNode})
|
||||
this.amountFocusNode,
|
||||
this.hasAllAmount = false,
|
||||
this.allAmount})
|
||||
: super(key: key);
|
||||
|
||||
final List<CryptoCurrency> currencies;
|
||||
@@ -47,6 +49,8 @@ class ExchangeCard extends StatefulWidget {
|
||||
final FormFieldValidator<String> currencyValueValidator;
|
||||
final FormFieldValidator<String> addressTextFieldValidator;
|
||||
final FocusNode amountFocusNode;
|
||||
final bool hasAllAmount;
|
||||
Function allAmount;
|
||||
|
||||
@override
|
||||
ExchangeCardState createState() => ExchangeCardState();
|
||||
@@ -166,8 +170,8 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.subhead
|
||||
.accentTextTheme
|
||||
.display4
|
||||
.decorationColor),
|
||||
validator: _isAmountEditable
|
||||
? widget.currencyValueValidator
|
||||
@@ -197,50 +201,88 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
]),
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
if (widget.hasAllAmount)
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 55,
|
||||
child: Container(
|
||||
height: 32,
|
||||
width: 32,
|
||||
margin: EdgeInsets.only(left: 14, top: 4, bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.color,
|
||||
borderRadius: BorderRadius.all(Radius.circular(6))),
|
||||
child: InkWell(
|
||||
onTap: () => widget.allAmount?.call(),
|
||||
child: Center(
|
||||
child: Text(S.of(context).all,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display1
|
||||
.decorationColor)),
|
||||
),
|
||||
),
|
||||
))
|
||||
],
|
||||
)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: <
|
||||
Widget>[
|
||||
_min != null
|
||||
? Text(
|
||||
S.of(context).min_value(_min, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.subhead
|
||||
.decorationColor),
|
||||
)
|
||||
: Offstage(),
|
||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||
_max != null
|
||||
? Text(
|
||||
S.of(context).max_value(_max, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.subhead
|
||||
.decorationColor))
|
||||
: Offstage(),
|
||||
]),
|
||||
child: Container(
|
||||
height: 15,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
_min != null
|
||||
? Text(
|
||||
S
|
||||
.of(context)
|
||||
.min_value(_min, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display4
|
||||
.decorationColor),
|
||||
)
|
||||
: Offstage(),
|
||||
_min != null ? SizedBox(width: 10) : Offstage(),
|
||||
_max != null
|
||||
? Text(
|
||||
S
|
||||
.of(context)
|
||||
.max_value(_max, _selectedCurrency.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
height: 1.2,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display4
|
||||
.decorationColor))
|
||||
: Offstage(),
|
||||
])),
|
||||
),
|
||||
!_isAddressEditable && widget.hasRefundAddress
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
S.of(context).refund_address,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color:
|
||||
Theme.of(context).textTheme.subhead.decorationColor),
|
||||
))
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
S.of(context).refund_address,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display4
|
||||
.decorationColor),
|
||||
))
|
||||
: Offstage(),
|
||||
_isAddressEditable
|
||||
? Padding(
|
||||
@@ -248,7 +290,8 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
child: AddressTextField(
|
||||
controller: addressController,
|
||||
placeholder: widget.hasRefundAddress
|
||||
? S.of(context).refund_address : null,
|
||||
? S.of(context).refund_address
|
||||
: null,
|
||||
options: [
|
||||
AddressTextFieldOption.paste,
|
||||
AddressTextFieldOption.qrCode,
|
||||
@@ -262,8 +305,10 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color:
|
||||
Theme.of(context).textTheme.subhead.decorationColor),
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display4
|
||||
.decorationColor),
|
||||
buttonColor: widget.addressButtonsColor,
|
||||
validator: widget.addressTextFieldValidator,
|
||||
),
|
||||
@@ -275,8 +320,8 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: addressController.text));
|
||||
showBar<void>(context,
|
||||
S.of(context).copied_to_clipboard);
|
||||
showBar<void>(
|
||||
context, S.of(context).copied_to_clipboard);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
||||
@@ -6,8 +6,6 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
|
||||
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
|
||||
@@ -172,36 +170,14 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
||||
),
|
||||
itemBuilder: (context, index) {
|
||||
final item = widget.exchangeTradeViewModel.items[index];
|
||||
String value;
|
||||
final value = item.data ?? fetchingLabel;
|
||||
|
||||
final content = Observer(builder: (_) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
value =
|
||||
'${widget.exchangeTradeViewModel.trade.id ?? fetchingLabel}';
|
||||
break;
|
||||
case 1:
|
||||
value =
|
||||
'${widget.exchangeTradeViewModel.trade.amount ?? fetchingLabel}';
|
||||
break;
|
||||
case 2:
|
||||
value =
|
||||
'${widget.exchangeTradeViewModel.trade.state ?? fetchingLabel}';
|
||||
break;
|
||||
case 3:
|
||||
value = widget.exchangeTradeViewModel.trade
|
||||
.inputAddress ??
|
||||
fetchingLabel;
|
||||
break;
|
||||
}
|
||||
|
||||
return StandartListRow(
|
||||
title: item.title,
|
||||
value: value,
|
||||
valueFontSize: 14,
|
||||
image: item.isCopied ? copyImage : null,
|
||||
);
|
||||
});
|
||||
final content = StandartListRow(
|
||||
title: item.title,
|
||||
value: value,
|
||||
valueFontSize: 14,
|
||||
image: item.isCopied ? copyImage : null,
|
||||
);
|
||||
|
||||
return item.isCopied
|
||||
? Builder(
|
||||
@@ -227,16 +203,15 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
||||
final sendingState =
|
||||
widget.exchangeTradeViewModel.sendViewModel.state;
|
||||
|
||||
return trade.from == CryptoCurrency.xmr && !(sendingState is TransactionCommitted)
|
||||
return widget.exchangeTradeViewModel.isSendable &&
|
||||
!(sendingState is TransactionCommitted)
|
||||
? LoadingPrimaryButton(
|
||||
isDisabled: trade.inputAddress == null ||
|
||||
trade.inputAddress.isEmpty,
|
||||
isLoading: sendingState is IsExecutingState,
|
||||
onPressed: () =>
|
||||
widget.exchangeTradeViewModel.confirmSending(),
|
||||
text: trade.provider == ExchangeProviderDescription.xmrto
|
||||
? S.of(context).confirm
|
||||
: S.of(context).send_xmr,
|
||||
text: S.of(context).confirm,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white)
|
||||
: Offstage();
|
||||
@@ -306,7 +281,11 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
||||
padding: EdgeInsets.only(
|
||||
top: 220, left: 24, right: 24),
|
||||
child: Text(
|
||||
S.of(context).send_success,
|
||||
S.of(context).send_success(widget
|
||||
.exchangeTradeViewModel
|
||||
.wallet
|
||||
.currency
|
||||
.toString()),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
@@ -379,7 +358,16 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
|
||||
});
|
||||
});
|
||||
},
|
||||
actionLeftButton: () => Navigator.of(context).pop());
|
||||
actionLeftButton: () => Navigator.of(context).pop(),
|
||||
feeFiatAmount: widget.exchangeTradeViewModel.sendViewModel
|
||||
.pendingTransaction.feeFormatted,
|
||||
fiatAmountValue: widget.exchangeTradeViewModel.sendViewModel
|
||||
.pendingTransactionFeeFiatAmount +
|
||||
' ' +
|
||||
widget.exchangeTradeViewModel.sendViewModel.fiat.title,
|
||||
recipientTitle: S.of(context).recipient_address,
|
||||
recipientAddress:
|
||||
widget.exchangeTradeViewModel.sendViewModel.address);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
@@ -22,17 +21,24 @@ class NewWalletPage extends BasePage {
|
||||
|
||||
final WalletNewVM _walletNewVM;
|
||||
|
||||
final walletNameImage = Image.asset('assets/images/wallet_name.png');
|
||||
final walletNameLightImage =
|
||||
Image.asset('assets/images/wallet_name_light.png');
|
||||
|
||||
@override
|
||||
String get title => S.current.new_wallet;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => WalletNameForm(_walletNewVM);
|
||||
Widget body(BuildContext context) => WalletNameForm(_walletNewVM,
|
||||
currentTheme.type == ThemeType.dark
|
||||
? walletNameImage : walletNameLightImage);
|
||||
}
|
||||
|
||||
class WalletNameForm extends StatefulWidget {
|
||||
WalletNameForm(this._walletNewVM);
|
||||
WalletNameForm(this._walletNewVM, this.walletImage);
|
||||
|
||||
final WalletNewVM _walletNewVM;
|
||||
final Image walletImage;
|
||||
|
||||
@override
|
||||
_WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
|
||||
@@ -43,9 +49,6 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||
|
||||
static const aspectRatioImage = 1.22;
|
||||
|
||||
final walletNameImage = Image.asset('assets/images/wallet_name.png');
|
||||
final walletNameLightImage =
|
||||
Image.asset('assets/images/wallet_name_light.png');
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
|
||||
ReactionDisposer _stateReaction;
|
||||
@@ -78,10 +81,6 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletImage = getIt.get<SettingsStore>().isDarkTheme
|
||||
? walletNameImage
|
||||
: walletNameLightImage;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: ScrollableWithBottomSection(
|
||||
@@ -92,7 +91,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||
padding: EdgeInsets.only(left: 12, right: 12),
|
||||
child: AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: walletImage, fit: BoxFit.fill)),
|
||||
child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
||||
import 'package:flushbar/flushbar.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
@@ -10,25 +17,36 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
|
||||
|
||||
class NewWalletTypePage extends BasePage {
|
||||
NewWalletTypePage({this.onTypeSelected, this.isNewWallet = true});
|
||||
NewWalletTypePage(this.walletNewVM, {this.onTypeSelected, this.isNewWallet});
|
||||
|
||||
final void Function(BuildContext, WalletType) onTypeSelected;
|
||||
final bool isNewWallet;
|
||||
final WalletNewVM walletNewVM;
|
||||
|
||||
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
|
||||
final walletTypeLightImage =
|
||||
Image.asset('assets/images/wallet_type_light.png');
|
||||
|
||||
@override
|
||||
String get title => isNewWallet
|
||||
? S.current.new_wallet
|
||||
: S.current.wallet_list_restore_wallet;
|
||||
String get title =>
|
||||
isNewWallet ? S.current.new_wallet : S.current.wallet_list_restore_wallet;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) =>
|
||||
WalletTypeForm(onTypeSelected: onTypeSelected);
|
||||
Widget body(BuildContext context) => WalletTypeForm(walletNewVM, isNewWallet,
|
||||
onTypeSelected: onTypeSelected,
|
||||
walletImage: currentTheme.type == ThemeType.dark
|
||||
? walletTypeImage
|
||||
: walletTypeLightImage);
|
||||
}
|
||||
|
||||
class WalletTypeForm extends StatefulWidget {
|
||||
WalletTypeForm({this.onTypeSelected});
|
||||
WalletTypeForm(this.walletNewVM, this.isNewWallet,
|
||||
{this.onTypeSelected, this.walletImage});
|
||||
|
||||
final void Function(BuildContext, WalletType) onTypeSelected;
|
||||
final WalletNewVM walletNewVM;
|
||||
final bool isNewWallet;
|
||||
final Image walletImage;
|
||||
|
||||
@override
|
||||
WalletTypeFormState createState() => WalletTypeFormState();
|
||||
@@ -42,10 +60,12 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
final bitcoinIcon =
|
||||
Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
|
||||
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
|
||||
final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
|
||||
final walletTypeLightImage =
|
||||
Image.asset('assets/images/wallet_type_light.png');
|
||||
|
||||
WalletType selected;
|
||||
List<WalletType> types;
|
||||
Flushbar<void> _progressBar;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -55,11 +75,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletImage = getIt.get<SettingsStore>().isDarkTheme
|
||||
? walletTypeImage : walletTypeLightImage;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
padding: EdgeInsets.only(top: 24, bottom: 24),
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
content: Column(
|
||||
@@ -69,7 +86,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
padding: EdgeInsets.only(left: 12, right: 12),
|
||||
child: AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: walletImage, fit: BoxFit.fill)),
|
||||
child:
|
||||
FittedBox(child: widget.walletImage, fit: BoxFit.fill)),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 48),
|
||||
@@ -86,7 +104,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: SelectButton(
|
||||
image: _iconFor(type),
|
||||
text: walletTypeToString(type),
|
||||
text: walletTypeToDisplayName(type),
|
||||
isSelected: selected == type,
|
||||
onTap: () => setState(() => selected = type)),
|
||||
))
|
||||
@@ -94,9 +112,9 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: PrimaryButton(
|
||||
onPressed: () => widget.onTypeSelected(context, selected),
|
||||
onPressed: () => onTypeSelected(),
|
||||
text: S.of(context).seed_language_next,
|
||||
color: Colors.green,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isDisabled: selected == null,
|
||||
),
|
||||
@@ -114,4 +132,35 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onTypeSelected() async {
|
||||
if (!widget.isNewWallet) {
|
||||
widget.onTypeSelected(context, selected);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_changeProcessText(S.of(context).creating_new_wallet);
|
||||
widget.walletNewVM.type = selected;
|
||||
await widget.walletNewVM
|
||||
.create(options: 'English'); // FIXME: Unnamed constant
|
||||
await _progressBar?.dismiss();
|
||||
final state = widget.walletNewVM.state;
|
||||
|
||||
if (state is ExecutedSuccessfullyState) {
|
||||
widget.onTypeSelected(context, selected);
|
||||
}
|
||||
|
||||
if (state is FailureState) {
|
||||
_changeProcessText(
|
||||
S.of(context).creating_new_wallet_error(state.error));
|
||||
}
|
||||
} catch (e) {
|
||||
_changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void _changeProcessText(String text) {
|
||||
_progressBar = createBar<void>(text, duration: null)..show(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class SelectButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = isSelected
|
||||
? Theme.of(context).accentTextTheme.subtitle.decorationColor
|
||||
? Colors.green
|
||||
: Theme.of(context).accentTextTheme.caption.color;
|
||||
final textColor = isSelected
|
||||
? Theme.of(context).accentTextTheme.headline.decorationColor
|
||||
|
||||
@@ -65,98 +65,90 @@ class NodeListPage extends BasePage {
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Observer(
|
||||
builder: (BuildContext context) {
|
||||
return nodeListViewModel.nodes.isNotEmpty
|
||||
? SectionStandardList(
|
||||
sectionCount: 2,
|
||||
context: context,
|
||||
itemCounter: (int sectionIndex) {
|
||||
if (sectionIndex == 0) {
|
||||
return 1;
|
||||
}
|
||||
return SectionStandardList(
|
||||
sectionCount: 2,
|
||||
context: context,
|
||||
itemCounter: (int sectionIndex) {
|
||||
if (sectionIndex == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return nodeListViewModel.nodes.length;
|
||||
},
|
||||
itemBuilder: (_, sectionIndex, index) {
|
||||
if (sectionIndex == 0) {
|
||||
return NodeHeaderListRow(
|
||||
title: S.of(context).add_new_node,
|
||||
onTap: (_) async => await Navigator.of(context)
|
||||
.pushNamed(Routes.newNode));
|
||||
}
|
||||
return nodeListViewModel.nodes.length;
|
||||
},
|
||||
itemBuilder: (_, sectionIndex, index) {
|
||||
if (sectionIndex == 0) {
|
||||
return NodeHeaderListRow(
|
||||
title: S.of(context).add_new_node,
|
||||
onTap: (_) async => await Navigator.of(context)
|
||||
.pushNamed(Routes.newNode));
|
||||
}
|
||||
|
||||
final node = nodeListViewModel.nodes[index];
|
||||
final isSelected = node.keyIndex ==
|
||||
nodeListViewModel.settingsStore.currentNode.keyIndex;
|
||||
final nodeListRow = NodeListRow(
|
||||
title: node.uri,
|
||||
isSelected: isSelected,
|
||||
isAlive: node.requestNode(),
|
||||
onTap: (_) async {
|
||||
if (isSelected) {
|
||||
return;
|
||||
final node = nodeListViewModel.nodes[index];
|
||||
final isSelected =
|
||||
node.keyIndex == nodeListViewModel.currentNode?.keyIndex;
|
||||
final nodeListRow = NodeListRow(
|
||||
title: node.uri,
|
||||
isSelected: isSelected,
|
||||
isAlive: node.requestNode(),
|
||||
onTap: (_) async {
|
||||
if (isSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle:
|
||||
S.of(context).change_current_node_title,
|
||||
alertContent:
|
||||
S.of(context).change_current_node(node.uri),
|
||||
leftButtonText: S.of(context).cancel,
|
||||
rightButtonText: S.of(context).change,
|
||||
actionLeftButton: () =>
|
||||
Navigator.of(context).pop(),
|
||||
actionRightButton: () async {
|
||||
await nodeListViewModel.setAsCurrent(node);
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
final dismissibleRow = Slidable(
|
||||
key: Key('${node.keyIndex}'),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: nodeListRow,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).delete,
|
||||
color: Colors.red,
|
||||
icon: CupertinoIcons.delete,
|
||||
onTap: () async {
|
||||
final confirmed = await showPopUp<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context).remove_node,
|
||||
alertContent:
|
||||
S.of(context).remove_node_message,
|
||||
rightButtonText: S.of(context).remove,
|
||||
leftButtonText: S.of(context).cancel,
|
||||
actionRightButton: () =>
|
||||
Navigator.pop(context, true),
|
||||
actionLeftButton: () =>
|
||||
Navigator.pop(context, false));
|
||||
}) ??
|
||||
false;
|
||||
|
||||
if (confirmed) {
|
||||
await nodeListViewModel.delete(node);
|
||||
}
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle: S.of(context)
|
||||
.change_current_node_title,
|
||||
alertContent: S
|
||||
.of(context)
|
||||
.change_current_node(node.uri),
|
||||
leftButtonText: S.of(context).cancel,
|
||||
rightButtonText: S.of(context).change,
|
||||
actionLeftButton: () =>
|
||||
Navigator.of(context).pop(),
|
||||
actionRightButton: () async {
|
||||
await nodeListViewModel
|
||||
.setAsCurrent(node);
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
final dismissibleRow = Slidable(
|
||||
key: Key('${node.keyIndex}'),
|
||||
actionPane: SlidableDrawerActionPane(),
|
||||
child: nodeListRow,
|
||||
secondaryActions: <Widget>[
|
||||
IconSlideAction(
|
||||
caption: S.of(context).delete,
|
||||
color: Colors.red,
|
||||
icon: CupertinoIcons.delete,
|
||||
onTap: () async {
|
||||
final confirmed = await showPopUp<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
alertTitle:
|
||||
S.of(context).remove_node,
|
||||
alertContent: S
|
||||
.of(context)
|
||||
.remove_node_message,
|
||||
rightButtonText:
|
||||
S.of(context).remove,
|
||||
leftButtonText:
|
||||
S.of(context).cancel,
|
||||
actionRightButton: () =>
|
||||
Navigator.pop(context, true),
|
||||
actionLeftButton: () =>
|
||||
Navigator.pop(context, false));
|
||||
}) ??
|
||||
false;
|
||||
|
||||
if (confirmed) {
|
||||
await nodeListViewModel.delete(node);
|
||||
}
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
return isSelected ? nodeListRow : dismissibleRow;
|
||||
})
|
||||
: Container();
|
||||
return isSelected ? nodeListRow : dismissibleRow;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -27,16 +28,47 @@ class ReceivePage extends BasePage {
|
||||
String get title => S.current.receive;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => Colors.transparent;
|
||||
Color get backgroundLightColor => currentTheme.type == ThemeType.bright
|
||||
? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
|
||||
@override
|
||||
Color get titleColor => Colors.white;
|
||||
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
@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(
|
||||
@@ -51,7 +83,8 @@ class ReceivePage extends BasePage {
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final shareImage =
|
||||
Image.asset('assets/images/share.png', color: Colors.white);
|
||||
Image.asset('assets/images/share.png',
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
|
||||
return SizedBox(
|
||||
height: 20.0,
|
||||
@@ -74,9 +107,8 @@ class ReceivePage extends BasePage {
|
||||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: isDarkTheme
|
||||
? Color.fromRGBO(48, 51, 60, 1.0)
|
||||
: Color.fromRGBO(98, 98, 98, 1.0),
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.body2
|
||||
.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
|
||||
@@ -47,14 +47,14 @@ class QRWidget extends StatelessWidget {
|
||||
child: QrImage(
|
||||
data: addressListViewModel.uri.toString(),
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.white,
|
||||
//Theme.of(context).textTheme.headline.color,
|
||||
foregroundColor: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor,
|
||||
))))),
|
||||
Spacer(flex: 3)
|
||||
]),
|
||||
isAmountFieldShow
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(top: 60),
|
||||
padding: EdgeInsets.only(top: 40),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
@@ -67,11 +67,12 @@ class QRWidget extends StatelessWidget {
|
||||
decimal: true),
|
||||
inputFormatters: [
|
||||
BlacklistingTextInputFormatter(
|
||||
RegExp('[\\-|\\ |\\,]'))
|
||||
RegExp('[\\-|\\ ]'))
|
||||
],
|
||||
textAlign: TextAlign.center,
|
||||
hintText: S.of(context).receive_amount,
|
||||
textColor: Colors.white,
|
||||
textColor: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor,
|
||||
borderColor: Theme.of(context)
|
||||
.textTheme
|
||||
.headline
|
||||
@@ -108,9 +109,10 @@ class QRWidget extends StatelessWidget {
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white),
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
@@ -7,12 +9,20 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
||||
|
||||
class WalletRestoreFromSeedForm extends StatefulWidget {
|
||||
WalletRestoreFromSeedForm({Key key, this.blockHeightFocusNode,
|
||||
this.onHeightOrDateEntered})
|
||||
WalletRestoreFromSeedForm(
|
||||
{Key key,
|
||||
@required this.displayLanguageSelector,
|
||||
@required this.displayBlockHeightSelector,
|
||||
@required this.type,
|
||||
this.blockHeightFocusNode,
|
||||
this.onHeightOrDateEntered})
|
||||
: super(key: key);
|
||||
|
||||
final WalletType type;
|
||||
final bool displayLanguageSelector;
|
||||
final bool displayBlockHeightSelector;
|
||||
final FocusNode blockHeightFocusNode;
|
||||
final Function (bool) onHeightOrDateEntered;
|
||||
final Function(bool) onHeightOrDateEntered;
|
||||
|
||||
@override
|
||||
WalletRestoreFromSeedFormState createState() =>
|
||||
@@ -41,32 +51,35 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 25, right: 25),
|
||||
child: Column(children: [
|
||||
SeedWidget(key: seedWidgetStateKey, language: language),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final selected = await showPopUp<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
SeedLanguagePicker(selected: language));
|
||||
SeedWidget(
|
||||
key: seedWidgetStateKey, language: language, type: widget.type),
|
||||
if (widget.displayLanguageSelector)
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final selected = await showPopUp<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
SeedLanguagePicker(selected: language));
|
||||
|
||||
if (selected == null || selected.isEmpty) {
|
||||
return;
|
||||
}
|
||||
if (selected == null || selected.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
_changeLanguage(selected);
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: languageController,
|
||||
enableInteractiveSelection: false,
|
||||
readOnly: true)))),
|
||||
BlockchainHeightWidget(
|
||||
focusNode: widget.blockHeightFocusNode,
|
||||
key: blockchainHeightKey,
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered)
|
||||
_changeLanguage(selected);
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.only(top: 20.0),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: languageController,
|
||||
enableInteractiveSelection: false,
|
||||
readOnly: true)))),
|
||||
if (widget.displayBlockHeightSelector)
|
||||
BlockchainHeightWidget(
|
||||
focusNode: widget.blockHeightFocusNode,
|
||||
key: blockchainHeightKey,
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered)
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,16 +25,30 @@ class WalletRestorePage extends BasePage {
|
||||
_pages = [],
|
||||
_blockHeightFocusNode = FocusNode(),
|
||||
_controller = PageController(initialPage: 0) {
|
||||
_pages.addAll([
|
||||
WalletRestoreFromSeedForm(
|
||||
key: walletRestoreFromSeedFormKey,
|
||||
blockHeightFocusNode: _blockHeightFocusNode,
|
||||
onHeightOrDateEntered: (value)
|
||||
=> walletRestoreViewModel.isButtonEnabled = value),
|
||||
WalletRestoreFromKeysFrom(key: walletRestoreFromKeysFormKey,
|
||||
onHeightOrDateEntered: (value)
|
||||
=> walletRestoreViewModel.isButtonEnabled = value)
|
||||
]);
|
||||
walletRestoreViewModel.availableModes.forEach((mode) {
|
||||
switch (mode) {
|
||||
case WalletRestoreMode.seed:
|
||||
_pages.add(WalletRestoreFromSeedForm(
|
||||
displayBlockHeightSelector:
|
||||
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
|
||||
displayLanguageSelector:
|
||||
walletRestoreViewModel.hasSeedLanguageSelector,
|
||||
type: walletRestoreViewModel.type,
|
||||
key: walletRestoreFromSeedFormKey,
|
||||
blockHeightFocusNode: _blockHeightFocusNode,
|
||||
onHeightOrDateEntered: (value) =>
|
||||
walletRestoreViewModel.isButtonEnabled = value));
|
||||
break;
|
||||
case WalletRestoreMode.keys:
|
||||
_pages.add(WalletRestoreFromKeysFrom(
|
||||
key: walletRestoreFromKeysFormKey,
|
||||
onHeightOrDateEntered: (value) =>
|
||||
walletRestoreViewModel.isButtonEnabled = value));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -76,20 +90,19 @@ class WalletRestorePage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode)
|
||||
{
|
||||
walletRestoreViewModel.isButtonEnabled = false;
|
||||
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
|
||||
walletRestoreViewModel.isButtonEnabled = false;
|
||||
|
||||
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey
|
||||
.currentState.restoreHeightController.text = '';
|
||||
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey
|
||||
.currentState.dateController.text = '';
|
||||
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
|
||||
.restoreHeightController.text = '';
|
||||
walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
|
||||
.dateController.text = '';
|
||||
|
||||
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey
|
||||
.currentState.restoreHeightController.text = '';
|
||||
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey
|
||||
.currentState.dateController.text = '';
|
||||
});
|
||||
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
|
||||
.restoreHeightController.text = '';
|
||||
walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
|
||||
.dateController.text = '';
|
||||
});
|
||||
|
||||
return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Expanded(
|
||||
@@ -100,40 +113,37 @@ class WalletRestorePage extends BasePage {
|
||||
},
|
||||
controller: _controller,
|
||||
itemCount: _pages.length,
|
||||
itemBuilder: (_, index) => SingleChildScrollView(child: _pages[index]))),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: SmoothPageIndicator(
|
||||
controller: _controller,
|
||||
count: _pages.length,
|
||||
effect: ColorTransitionEffect(
|
||||
spacing: 6.0,
|
||||
radius: 6.0,
|
||||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context).hintColor.withOpacity(0.5),
|
||||
activeDotColor: Theme.of(context).hintColor),
|
||||
)),
|
||||
itemBuilder: (_, index) =>
|
||||
SingleChildScrollView(child: _pages[index]))),
|
||||
if (_pages.length > 1)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: SmoothPageIndicator(
|
||||
controller: _controller,
|
||||
count: _pages.length,
|
||||
effect: ColorTransitionEffect(
|
||||
spacing: 6.0,
|
||||
radius: 6.0,
|
||||
dotWidth: 6.0,
|
||||
dotHeight: 6.0,
|
||||
dotColor: Theme.of(context).hintColor.withOpacity(0.5),
|
||||
activeDotColor: Theme.of(context).hintColor),
|
||||
)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 40, left: 25, right: 25),
|
||||
child: Observer(
|
||||
builder: (context) {
|
||||
return LoadingPrimaryButton(
|
||||
onPressed: () =>
|
||||
walletRestoreViewModel.create(options: _credentials()),
|
||||
text: S.of(context).restore_recover,
|
||||
color: Theme
|
||||
.of(context)
|
||||
.accentTextTheme
|
||||
.subtitle
|
||||
.decorationColor,
|
||||
textColor: Theme
|
||||
.of(context)
|
||||
.accentTextTheme
|
||||
.headline
|
||||
.decorationColor,
|
||||
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
||||
isDisabled: !walletRestoreViewModel.isButtonEnabled,);
|
||||
onPressed: () =>
|
||||
walletRestoreViewModel.create(options: _credentials()),
|
||||
text: S.of(context).restore_recover,
|
||||
color:
|
||||
Theme.of(context).accentTextTheme.subtitle.decorationColor,
|
||||
textColor:
|
||||
Theme.of(context).accentTextTheme.headline.decorationColor,
|
||||
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
||||
isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
||||
);
|
||||
},
|
||||
))
|
||||
]);
|
||||
@@ -145,8 +155,11 @@ class WalletRestorePage extends BasePage {
|
||||
if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
|
||||
credentials['seed'] = walletRestoreFromSeedFormKey
|
||||
.currentState.seedWidgetStateKey.currentState.text;
|
||||
credentials['height'] = walletRestoreFromSeedFormKey
|
||||
.currentState.blockchainHeightKey.currentState.height;
|
||||
|
||||
if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
|
||||
credentials['height'] = walletRestoreFromSeedFormKey
|
||||
.currentState.blockchainHeightKey.currentState.height;
|
||||
}
|
||||
} else {
|
||||
credentials['address'] =
|
||||
walletRestoreFromKeysFormKey.currentState.addressController.text;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
@@ -8,8 +8,17 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
|
||||
class PreSeedPage extends BasePage {
|
||||
static final imageLight = Image.asset('assets/images/pre_seed_light.png');
|
||||
static final imageDark = Image.asset('assets/images/pre_seed_dark.png');
|
||||
PreSeedPage(this.type)
|
||||
: imageLight = Image.asset('assets/images/pre_seed_light.png'),
|
||||
imageDark = Image.asset('assets/images/pre_seed_dark.png'),
|
||||
wordsCount = type == WalletType.monero
|
||||
? 25
|
||||
: 12; // FIXME: Stupid fast implementation
|
||||
|
||||
final Image imageDark;
|
||||
final Image imageLight;
|
||||
final WalletType type;
|
||||
final int wordsCount;
|
||||
|
||||
@override
|
||||
Widget leading(BuildContext context) => null;
|
||||
@@ -19,8 +28,7 @@ class PreSeedPage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final image =
|
||||
getIt.get<SettingsStore>().isDarkTheme ? imageDark : imageLight;
|
||||
final image = currentTheme.type == ThemeType.dark ? imageDark : imageLight;
|
||||
|
||||
return WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
@@ -41,7 +49,7 @@ class PreSeedPage extends BasePage {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 70, left: 16, right: 16),
|
||||
child: Text(
|
||||
S.of(context).pre_seed_description,
|
||||
S.of(context).pre_seed_description(wordsCount.toString()),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -17,8 +16,8 @@ import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
|
||||
class WalletSeedPage extends BasePage {
|
||||
WalletSeedPage(this.walletSeedViewModel, {@required this.isNewWalletCreated});
|
||||
|
||||
static final imageLight = Image.asset('assets/images/crypto_lock_light.png');
|
||||
static final imageDark = Image.asset('assets/images/crypto_lock.png');
|
||||
final imageLight = Image.asset('assets/images/crypto_lock_light.png');
|
||||
final imageDark = Image.asset('assets/images/crypto_lock.png');
|
||||
|
||||
@override
|
||||
String get title => S.current.seed_title;
|
||||
@@ -83,8 +82,7 @@ class WalletSeedPage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final image =
|
||||
getIt.get<SettingsStore>().isDarkTheme ? imageDark : imageLight;
|
||||
final image = currentTheme.type == ThemeType.dark ? imageDark : imageLight;
|
||||
|
||||
return WillPopScope(onWillPop: () async => false, child: Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -15,17 +14,26 @@ class SeedLanguage extends BasePage {
|
||||
|
||||
final Function(BuildContext, String) onConfirm;
|
||||
|
||||
final walletNameImage = Image.asset('assets/images/wallet_name.png');
|
||||
final walletNameLightImage =
|
||||
Image.asset('assets/images/wallet_name_light.png');
|
||||
|
||||
@override
|
||||
String get title => S.current.wallet_list_restore_wallet;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) => SeedLanguageForm(onConfirm: onConfirm);
|
||||
Widget body(BuildContext context) =>
|
||||
SeedLanguageForm(
|
||||
onConfirm: onConfirm,
|
||||
walletImage: currentTheme.type == ThemeType.dark
|
||||
? walletNameImage : walletNameLightImage);
|
||||
}
|
||||
|
||||
class SeedLanguageForm extends StatefulWidget {
|
||||
SeedLanguageForm({this.onConfirm});
|
||||
SeedLanguageForm({this.onConfirm, this.walletImage});
|
||||
|
||||
final Function(BuildContext, String) onConfirm;
|
||||
final Image walletImage;
|
||||
|
||||
@override
|
||||
SeedLanguageFormState createState() => SeedLanguageFormState();
|
||||
@@ -33,18 +41,10 @@ class SeedLanguageForm extends StatefulWidget {
|
||||
|
||||
class SeedLanguageFormState extends State<SeedLanguageForm> {
|
||||
static const aspectRatioImage = 1.22;
|
||||
|
||||
final walletNameImage = Image.asset('assets/images/wallet_name.png');
|
||||
final walletNameLightImage =
|
||||
Image.asset('assets/images/wallet_name_light.png');
|
||||
final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final walletImage = getIt.get<SettingsStore>().isDarkTheme
|
||||
? walletNameImage
|
||||
: walletNameLightImage;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: ScrollableWithBottomSection(
|
||||
@@ -55,7 +55,8 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
|
||||
padding: EdgeInsets.only(left: 12, right: 12),
|
||||
child: AspectRatio(
|
||||
aspectRatio: aspectRatioImage,
|
||||
child: FittedBox(child: walletImage, fit: BoxFit.fill)),
|
||||
child: FittedBox(child: widget.walletImage,
|
||||
fit: BoxFit.fill)),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 40),
|
||||
|
||||
+100
-109
@@ -31,6 +31,7 @@ class SendPage extends BasePage {
|
||||
: _addressController = TextEditingController(),
|
||||
_cryptoAmountController = TextEditingController(),
|
||||
_fiatAmountController = TextEditingController(),
|
||||
_noteController = TextEditingController(),
|
||||
_formKey = GlobalKey<FormState>(),
|
||||
_cryptoAmountFocus = FocusNode(),
|
||||
_fiatAmountFocus = FocusNode(),
|
||||
@@ -46,6 +47,7 @@ class SendPage extends BasePage {
|
||||
final TextEditingController _addressController;
|
||||
final TextEditingController _cryptoAmountController;
|
||||
final TextEditingController _fiatAmountController;
|
||||
final TextEditingController _noteController;
|
||||
final GlobalKey<FormState> _formKey;
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
final FocusNode _fiatAmountFocus;
|
||||
@@ -83,9 +85,8 @@ class SendPage extends BasePage {
|
||||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: isDarkTheme
|
||||
? Color.fromRGBO(48, 51, 60, 1.0)
|
||||
: Color.fromRGBO(98, 98, 98, 1.0),
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.body2
|
||||
.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
@@ -133,7 +134,8 @@ class SendPage extends BasePage {
|
||||
|
||||
if (uri != null) {
|
||||
address = uri.path;
|
||||
amount = uri.queryParameters['tx_amount'];
|
||||
amount = uri.queryParameters['tx_amount'] ??
|
||||
uri.queryParameters['amount'];
|
||||
} else {
|
||||
address = uri.toString();
|
||||
}
|
||||
@@ -304,6 +306,30 @@ class SendPage extends BasePage {
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14),
|
||||
)),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: BaseTextFormField(
|
||||
controller: _noteController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: null,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.color,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white),
|
||||
hintText: S.of(context).note_optional,
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.decorationColor),
|
||||
),
|
||||
),
|
||||
Observer(
|
||||
builder: (_) => GestureDetector(
|
||||
onTap: () =>
|
||||
@@ -313,6 +339,7 @@ class SendPage extends BasePage {
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
S
|
||||
@@ -326,23 +353,50 @@ class SendPage extends BasePage {
|
||||
color: Colors.white)),
|
||||
Container(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
sendViewModel
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
sendViewModel
|
||||
.estimatedFee
|
||||
.toString() +
|
||||
' ' +
|
||||
sendViewModel
|
||||
' ' +
|
||||
sendViewModel
|
||||
.currency.title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight:
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight:
|
||||
FontWeight.w600,
|
||||
//color: Theme.of(context).primaryTextTheme.display2.color,
|
||||
color:
|
||||
//color: Theme.of(context).primaryTextTheme.display2.color,
|
||||
color:
|
||||
Colors.white)),
|
||||
Padding(
|
||||
padding:
|
||||
EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
sendViewModel
|
||||
.estimatedFeeFiatAmount
|
||||
+ ' ' +
|
||||
sendViewModel
|
||||
.fiat.title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight:
|
||||
FontWeight.w600,
|
||||
color: Theme
|
||||
.of(context)
|
||||
.primaryTextTheme
|
||||
.headline
|
||||
.decorationColor))
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 2,
|
||||
left: 5),
|
||||
child: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
@@ -497,14 +551,8 @@ class SendPage extends BasePage {
|
||||
}
|
||||
},
|
||||
text: S.of(context).send,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.subtitle
|
||||
.decorationColor,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.headline
|
||||
.decorationColor,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading: sendViewModel.state is IsExecutingState ||
|
||||
sendViewModel.state is TransactionCommitting,
|
||||
isDisabled:
|
||||
@@ -540,6 +588,14 @@ class SendPage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
_noteController.addListener(() {
|
||||
final note = _noteController.text ?? '';
|
||||
|
||||
if (note != sendViewModel.note) {
|
||||
sendViewModel.note = note;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => sendViewModel.sendAll, (bool all) {
|
||||
if (all) {
|
||||
_cryptoAmountController.text = S.current.all;
|
||||
@@ -577,6 +633,12 @@ class SendPage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => sendViewModel.note, (String note) {
|
||||
if (note != _noteController.text) {
|
||||
_noteController.text = note;
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => sendViewModel.state, (ExecutionState state) {
|
||||
if (state is FailureState) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -602,8 +664,14 @@ class SendPage extends BasePage {
|
||||
amount: S.of(context).send_amount,
|
||||
amountValue:
|
||||
sendViewModel.pendingTransaction.amountFormatted,
|
||||
fiatAmountValue: sendViewModel.pendingTransactionFiatAmount
|
||||
+ ' ' + sendViewModel.fiat.title,
|
||||
fee: S.of(context).send_fee,
|
||||
feeValue: sendViewModel.pendingTransaction.feeFormatted,
|
||||
feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmount
|
||||
+ ' ' + sendViewModel.fiat.title,
|
||||
recipientTitle: S.of(context).recipient_address,
|
||||
recipientAddress: sendViewModel.address,
|
||||
rightButtonText: S.of(context).ok,
|
||||
leftButtonText: S.of(context).cancel,
|
||||
actionRightButton: () {
|
||||
@@ -620,94 +688,17 @@ class SendPage extends BasePage {
|
||||
}
|
||||
|
||||
if (state is TransactionCommitted) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
'assets/images/birthday_cake.png'),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 220, left: 24, right: 24),
|
||||
child: Text(
|
||||
S.of(context).send_success,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 24,
|
||||
right: 24,
|
||||
bottom: 24,
|
||||
child: PrimaryButton(
|
||||
onPressed: () =>
|
||||
Navigator.of(context).pop(),
|
||||
text: S.of(context).send_got_it,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.body2
|
||||
.color,
|
||||
textColor: Colors.white))
|
||||
],
|
||||
);
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: S.of(context).send_success(
|
||||
sendViewModel.currency
|
||||
.toString()),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () =>
|
||||
Navigator.of(context).pop());
|
||||
}
|
||||
|
||||
if (state is TransactionCommitting) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
'assets/images/birthday_cake.png'),
|
||||
),
|
||||
),
|
||||
BackdropFilter(
|
||||
filter: ImageFilter.blur(
|
||||
sigmaX: 3.0, sigmaY: 3.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.backgroundColor
|
||||
.withOpacity(0.25)),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 220),
|
||||
child: Text(
|
||||
S.of(context).send_sending,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Container();
|
||||
return Offstage();
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -748,8 +739,9 @@ class SendPage extends BasePage {
|
||||
}
|
||||
|
||||
Future<void> _setTransactionPriority(BuildContext context) async {
|
||||
final items = TransactionPriority.all;
|
||||
final items = TransactionPriority.forWalletType(sendViewModel.walletType);
|
||||
final selectedItem = items.indexOf(sendViewModel.transactionPriority);
|
||||
final isShowScrollThumb = items.length > 3;
|
||||
|
||||
await showPopUp<void>(
|
||||
builder: (_) => Picker(
|
||||
@@ -759,7 +751,6 @@ class SendPage extends BasePage {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
onItemSelected: (TransactionPriority priority) =>
|
||||
sendViewModel.setTransactionPriority(priority),
|
||||
isAlwaysShowScrollThumb: true,
|
||||
),
|
||||
context: context);
|
||||
}
|
||||
|
||||
@@ -49,9 +49,8 @@ class SendTemplatePage extends BasePage {
|
||||
return KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
keyboardBarColor: isDarkTheme
|
||||
? Color.fromRGBO(48, 51, 60, 1.0)
|
||||
: Color.fromRGBO(98, 98, 98, 1.0),
|
||||
keyboardBarColor: Theme.of(context).accentTextTheme.body2
|
||||
.backgroundColor,
|
||||
nextFocus: false,
|
||||
actions: [
|
||||
KeyboardActionsItem(
|
||||
@@ -113,7 +112,8 @@ class SendTemplatePage extends BasePage {
|
||||
|
||||
if (uri != null) {
|
||||
address = uri.path;
|
||||
amount = uri.queryParameters['tx_amount'];
|
||||
amount = uri.queryParameters['tx_amount'] ??
|
||||
uri.queryParameters['amount'];
|
||||
} else {
|
||||
address = uri.toString();
|
||||
}
|
||||
@@ -246,9 +246,8 @@ class SendTemplatePage extends BasePage {
|
||||
}
|
||||
},
|
||||
text: S.of(context).save,
|
||||
color: Theme.of(context).accentTextTheme.subtitle.decorationColor,
|
||||
textColor:
|
||||
Theme.of(context).accentTextTheme.headline.decorationColor,
|
||||
color: Colors.green,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
|
||||
|
||||
@@ -6,8 +7,12 @@ class ConfirmSendingAlert extends BaseAlertDialog {
|
||||
@required this.alertTitle,
|
||||
@required this.amount,
|
||||
@required this.amountValue,
|
||||
@required this.fiatAmountValue,
|
||||
@required this.fee,
|
||||
@required this.feeValue,
|
||||
@required this.feeFiatAmount,
|
||||
@required this.recipientTitle,
|
||||
@required this.recipientAddress,
|
||||
@required this.leftButtonText,
|
||||
@required this.rightButtonText,
|
||||
@required this.actionLeftButton,
|
||||
@@ -18,8 +23,12 @@ class ConfirmSendingAlert extends BaseAlertDialog {
|
||||
final String alertTitle;
|
||||
final String amount;
|
||||
final String amountValue;
|
||||
final String fiatAmountValue;
|
||||
final String fee;
|
||||
final String feeValue;
|
||||
final String feeFiatAmount;
|
||||
final String recipientTitle;
|
||||
final String recipientAddress;
|
||||
final String leftButtonText;
|
||||
final String rightButtonText;
|
||||
final VoidCallback actionLeftButton;
|
||||
@@ -29,74 +38,145 @@ class ConfirmSendingAlert extends BaseAlertDialog {
|
||||
@override
|
||||
String get titleText => alertTitle;
|
||||
|
||||
@override
|
||||
bool get isDividerExists => true;
|
||||
|
||||
@override
|
||||
String get leftActionButtonText => leftButtonText;
|
||||
|
||||
@override
|
||||
String get rightActionButtonText => rightButtonText;
|
||||
|
||||
@override
|
||||
VoidCallback get actionLeft => actionLeftButton;
|
||||
|
||||
@override
|
||||
VoidCallback get actionRight => actionRightButton;
|
||||
|
||||
@override
|
||||
bool get barrierDismissible => alertBarrierDismissible;
|
||||
|
||||
@override
|
||||
Widget content(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
amount,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
amountValue,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
amountValue,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
fiatAmountValue,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: PaletteDark.pigeonBlue,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
fee,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 16),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
fee,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
feeValue,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
feeValue,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
feeFiatAmount,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: PaletteDark.pigeonBlue,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(0, 16, 0, 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'$recipientTitle:',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
recipientAddress,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: 'Lato',
|
||||
color: PaletteDark.pigeonBlue,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
|
||||
@@ -43,7 +43,6 @@ class SettingsPage extends BasePage {
|
||||
return SettingsPickerCell<dynamic>(
|
||||
title: item.title,
|
||||
selectedItem: item.selectedItem(),
|
||||
isAlwaysShowScrollThumb: item.isAlwaysShowScrollThumb,
|
||||
items: item.items,
|
||||
onItemSelected: (dynamic value) => item.onItemSelected(value),
|
||||
);
|
||||
|
||||
@@ -9,8 +9,7 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
|
||||
{@required String title,
|
||||
this.selectedItem,
|
||||
this.items,
|
||||
this.onItemSelected,
|
||||
this.isAlwaysShowScrollThumb})
|
||||
this.onItemSelected})
|
||||
: super(
|
||||
title: title,
|
||||
isSelected: false,
|
||||
@@ -24,7 +23,6 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
|
||||
selectedAtIndex: selectedAtIndex,
|
||||
title: S.current.please_select,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
isAlwaysShowScrollThumb: isAlwaysShowScrollThumb,
|
||||
onItemSelected: (ItemType item) =>
|
||||
onItemSelected?.call(item)));
|
||||
});
|
||||
@@ -32,7 +30,6 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
|
||||
final ItemType selectedItem;
|
||||
final List<ItemType> items;
|
||||
final void Function(ItemType item) onItemSelected;
|
||||
final bool isAlwaysShowScrollThumb;
|
||||
|
||||
@override
|
||||
Widget buildTrailing(BuildContext context) {
|
||||
|
||||
@@ -1,82 +1,43 @@
|
||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/view_model/trade_details_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/exchange/trade.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
|
||||
|
||||
class TradeDetailsPage extends BasePage {
|
||||
TradeDetailsPage(this.trade) : _items = [] {
|
||||
final dateFormat = DateFormatter.withCurrentLocal();
|
||||
_items.addAll([
|
||||
StandartListItem(title: S.current.trade_details_id, value: trade.id),
|
||||
StandartListItem(
|
||||
title: S.current.trade_details_state,
|
||||
value: trade.state != null
|
||||
? trade.state.toString()
|
||||
: S.current.trade_details_fetching)
|
||||
]);
|
||||
|
||||
if (trade.provider != null) {
|
||||
_items.add(StandartListItem(
|
||||
title: S.current.trade_details_provider,
|
||||
value: trade.provider.toString()));
|
||||
}
|
||||
|
||||
if (trade.createdAt != null) {
|
||||
_items.add(StandartListItem(
|
||||
title: S.current.trade_details_created_at,
|
||||
value: dateFormat.format(trade.createdAt).toString()));
|
||||
}
|
||||
|
||||
if (trade.from != null && trade.to != null) {
|
||||
_items.add(StandartListItem(
|
||||
title: S.current.trade_details_pair,
|
||||
value: '${trade.from.toString()} → ${trade.to.toString()}'));
|
||||
}
|
||||
}
|
||||
TradeDetailsPage(this.tradeDetailsViewModel);
|
||||
|
||||
@override
|
||||
String get title => S.current.trade_details_title;
|
||||
|
||||
final Trade trade;
|
||||
final List<StandartListItem> _items;
|
||||
final TradeDetailsViewModel tradeDetailsViewModel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Container(child: Observer(builder: (_) {
|
||||
return ListView.separated(
|
||||
separatorBuilder: (_, __) => Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.backgroundColor)),
|
||||
itemCount: _items.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = _items[index];
|
||||
final isDrawBottom = index == _items.length - 1 ? true : false;
|
||||
return Observer(builder: (_) {
|
||||
return SectionStandardList(
|
||||
sectionCount: 1,
|
||||
itemCounter: (int _) => tradeDetailsViewModel.items.length,
|
||||
itemBuilder: (_, __, index) {
|
||||
final item = tradeDetailsViewModel.items[index];
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: '${item.value}'));
|
||||
showBar<void>(context, S.of(context).copied_to_clipboard);
|
||||
showBar<void>(context, S
|
||||
.of(context)
|
||||
.copied_to_clipboard);
|
||||
},
|
||||
child: StandartListRow(
|
||||
title: '${item.title}',
|
||||
value: '${item.value}',
|
||||
isDrawBottom: isDrawBottom,
|
||||
title: '${item.title}',
|
||||
value: '${item.value}'
|
||||
));
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
class StandartListItem {
|
||||
StandartListItem({this.title, this.value});
|
||||
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||
|
||||
final String title;
|
||||
final String value;
|
||||
class StandartListItem extends TransactionDetailsListItem {
|
||||
StandartListItem({String title, String value})
|
||||
: super(title: title, value: value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||
|
||||
class TextFieldListItem extends TransactionDetailsListItem {
|
||||
TextFieldListItem({String title, String value, this.onSubmitted})
|
||||
: super(title: title, value: value);
|
||||
|
||||
final Function(String value) onSubmitted;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
abstract class TransactionDetailsListItem {
|
||||
TransactionDetailsListItem({this.title, this.value});
|
||||
|
||||
final String title;
|
||||
final String value;
|
||||
}
|
||||
@@ -1,104 +1,32 @@
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/widgets/textfield_list_row.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/view_model/transaction_details_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
||||
import 'package:cake_wallet/monero/monero_transaction_info.dart';
|
||||
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
|
||||
class TransactionDetailsPage extends BasePage {
|
||||
TransactionDetailsPage(this.transactionInfo, bool showRecipientAddress, Box<TransactionDescription> transactionDescriptionBox)
|
||||
: _items = [] {
|
||||
final dateFormat = DateFormatter.withCurrentLocal();
|
||||
final tx = transactionInfo;
|
||||
|
||||
if (tx is MoneroTransactionInfo) {
|
||||
final items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
StandartListItem(
|
||||
title: S.current.send_fee,
|
||||
value: tx.feeFormatted())
|
||||
];
|
||||
|
||||
if (showRecipientAddress) {
|
||||
final recipientAddress = transactionDescriptionBox.values.firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)?.recipientAddress;
|
||||
|
||||
if (recipientAddress?.isNotEmpty ?? false) {
|
||||
items.add(StandartListItem(
|
||||
title: S.current.transaction_details_recipient_address,
|
||||
value: recipientAddress));
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.key?.isNotEmpty ?? null) {
|
||||
// FIXME: add translation
|
||||
items.add(StandartListItem(title: 'Transaction Key', value: tx.key));
|
||||
}
|
||||
|
||||
_items.addAll(items);
|
||||
}
|
||||
|
||||
if (tx is BitcoinTransactionInfo) {
|
||||
final items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: 'Confirmations', value: tx.confirmations?.toString()),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted())
|
||||
];
|
||||
|
||||
_items.addAll(items);
|
||||
}
|
||||
}
|
||||
TransactionDetailsPage({this.transactionDetailsViewModel});
|
||||
|
||||
@override
|
||||
String get title => S.current.transaction_details_title;
|
||||
|
||||
final TransactionInfo transactionInfo;
|
||||
|
||||
final List<StandartListItem> _items;
|
||||
final TransactionDetailsViewModel transactionDetailsViewModel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return Container(
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (context, index) => Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Container(
|
||||
height: 1,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme.title.backgroundColor,
|
||||
),
|
||||
),
|
||||
itemCount: _items.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = _items[index];
|
||||
final isDrawBottom = index == _items.length - 1 ? true : false;
|
||||
return SectionStandardList(
|
||||
sectionCount: 1,
|
||||
itemCounter: (int _) => transactionDetailsViewModel.items.length,
|
||||
itemBuilder: (_, __, index) {
|
||||
final item = transactionDetailsViewModel.items[index];
|
||||
|
||||
if (item is StandartListItem) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: item.value));
|
||||
@@ -107,10 +35,19 @@ class TransactionDetailsPage extends BasePage {
|
||||
},
|
||||
child: StandartListRow(
|
||||
title: '${item.title}:',
|
||||
value: item.value,
|
||||
isDrawBottom: isDrawBottom),
|
||||
value: item.value),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (item is TextFieldListItem) {
|
||||
return TextFieldListRow(
|
||||
title: item.title,
|
||||
value: item.value,
|
||||
onSubmitted: item.onSubmitted,
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class TextFieldListRow extends StatelessWidget {
|
||||
TextFieldListRow(
|
||||
{this.title,
|
||||
this.value,
|
||||
this.titleFontSize = 14,
|
||||
this.valueFontSize = 16,
|
||||
this.onSubmitted}) {
|
||||
|
||||
_textController = TextEditingController();
|
||||
_textController.text = value;
|
||||
}
|
||||
|
||||
final String title;
|
||||
final String value;
|
||||
final double titleFontSize;
|
||||
final double valueFontSize;
|
||||
final Function(String value) onSubmitted;
|
||||
|
||||
TextEditingController _textController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: titleFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme.overline.color),
|
||||
textAlign: TextAlign.left),
|
||||
TextField(
|
||||
controller: _textController,
|
||||
keyboardType: TextInputType.multiline,
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: null,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(
|
||||
fontSize: valueFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme.title.color),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.only(top: 12, bottom: 0),
|
||||
hintText: S.of(context).enter_your_note,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: valueFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme.overline.color),
|
||||
border: InputBorder.none
|
||||
),
|
||||
onSubmitted: (value) => onSubmitted.call(value),
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_list/widgets/wallet_menu_alert.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/utils/show_bar.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
@@ -15,7 +14,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_list/wallet_menu.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
|
||||
class WalletListPage extends BasePage {
|
||||
@@ -51,7 +49,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
final newWalletImage = Image.asset('assets/images/new_wallet.png',
|
||||
height: 12,
|
||||
width: 12,
|
||||
color: Theme.of(context).accentTextTheme.headline.decorationColor);
|
||||
color: Colors.white);
|
||||
final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
|
||||
height: 12,
|
||||
width: 12,
|
||||
@@ -165,17 +163,16 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
),
|
||||
bottomSection: Column(children: <Widget>[
|
||||
PrimaryImageButton(
|
||||
onPressed: () => _generateNewWallet(),
|
||||
onPressed: () => Navigator.of(context).pushNamed(Routes.newWalletType),
|
||||
image: newWalletImage,
|
||||
text: S.of(context).wallet_list_create_new_wallet,
|
||||
color: Theme.of(context).accentTextTheme.subtitle.decorationColor,
|
||||
textColor:
|
||||
Theme.of(context).accentTextTheme.headline.decorationColor,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
SizedBox(height: 10.0),
|
||||
PrimaryImageButton(
|
||||
onPressed: () =>
|
||||
Navigator.of(context).pushNamed(Routes.restoreWallet),
|
||||
Navigator.of(context).pushNamed(Routes.restoreWalletType),
|
||||
image: restoreWalletImage,
|
||||
text: S.of(context).wallet_list_restore_wallet,
|
||||
color: Theme.of(context).accentTextTheme.caption.color,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
@@ -23,9 +22,7 @@ class WelcomePage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final welcomeImage = getIt
|
||||
.get<SettingsStore>()
|
||||
.isDarkTheme
|
||||
final welcomeImage = currentTheme.type == ThemeType.dark
|
||||
? welcomeImageDark : welcomeImageLight;
|
||||
|
||||
final newWalletImage = Image.asset('assets/images/new_wallet.png',
|
||||
|
||||
@@ -2,8 +2,8 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/entities/contact_record.dart';
|
||||
import 'package:cake_wallet/entities/qr_scanner.dart';
|
||||
import 'package:cake_wallet/entities/contact_base.dart';
|
||||
|
||||
enum AddressTextFieldOption { paste, qrCode, addressBook }
|
||||
|
||||
@@ -42,7 +42,7 @@ class AddressTextField extends StatelessWidget {
|
||||
final Color iconColor;
|
||||
final TextStyle textStyle;
|
||||
final TextStyle hintStyle;
|
||||
FocusNode focusNode;
|
||||
final FocusNode focusNode;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -204,7 +204,7 @@ class AddressTextField extends StatelessWidget {
|
||||
onURIScanned(uri);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error $e');
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ class AddressTextField extends StatelessWidget {
|
||||
final contact = await Navigator.of(context, rootNavigator: true)
|
||||
.pushNamed(Routes.pickerAddressBook);
|
||||
|
||||
if (contact is ContactRecord && contact.address != null) {
|
||||
if (contact is ContactBase && contact.address != null) {
|
||||
controller.text = contact.address;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class AlertWithOneAction extends BaseAlertDialog {
|
||||
width: 300,
|
||||
height: 52,
|
||||
padding: EdgeInsets.only(left: 12, right: 12),
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
color: Theme.of(context).accentTextTheme.body1.backgroundColor,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.infinity,
|
||||
child: FlatButton(
|
||||
@@ -44,7 +44,8 @@ class AlertWithOneAction extends BaseAlertDialog {
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).primaryTextTheme.body1
|
||||
.backgroundColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)),
|
||||
|
||||
@@ -7,6 +7,7 @@ class BaseAlertDialog extends StatelessWidget {
|
||||
String get contentText => '';
|
||||
String get leftActionButtonText => '';
|
||||
String get rightActionButtonText => '';
|
||||
bool get isDividerExists => false;
|
||||
VoidCallback get actionLeft => () {};
|
||||
VoidCallback get actionRight => () {};
|
||||
bool get barrierDismissible => true;
|
||||
@@ -61,18 +62,24 @@ class BaseAlertDialog extends StatelessWidget {
|
||||
fontSize: 15,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).primaryTextTheme.body2
|
||||
.backgroundColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)),
|
||||
),
|
||||
)
|
||||
),
|
||||
Container(
|
||||
width: 1,
|
||||
height: 52,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
height: 52,
|
||||
padding: EdgeInsets.only(left: 6, right: 6),
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
color: Theme.of(context).accentTextTheme.body1.backgroundColor,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.infinity,
|
||||
child: FlatButton(
|
||||
@@ -86,7 +93,8 @@ class BaseAlertDialog extends StatelessWidget {
|
||||
fontSize: 15,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
color: Theme.of(context).primaryTextTheme.body1
|
||||
.backgroundColor,
|
||||
decoration: TextDecoration.none,
|
||||
),
|
||||
)),
|
||||
@@ -120,18 +128,31 @@ class BaseAlertDialog extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
|
||||
child: title(context),
|
||||
),
|
||||
isDividerExists
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(top: 16, bottom: 8),
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
)
|
||||
: Offstage(),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 8, 24, 32),
|
||||
child: content(context),
|
||||
)
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.fromLTRB(24, 32, 24, 32),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
title(context),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
child: content(context),
|
||||
)
|
||||
],
|
||||
),
|
||||
height: 1,
|
||||
color: Theme.of(context).dividerColor,
|
||||
),
|
||||
actionButtons(context)
|
||||
],
|
||||
|
||||
@@ -51,7 +51,7 @@ class BaseTextFormField extends StatelessWidget {
|
||||
final FocusNode focusNode;
|
||||
final bool readOnly;
|
||||
final bool enableInteractiveSelection;
|
||||
String initialValue;
|
||||
final String initialValue;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -15,7 +15,6 @@ class Picker<Item extends Object> extends StatefulWidget {
|
||||
this.description,
|
||||
@required this.onItemSelected,
|
||||
this.mainAxisAlignment = MainAxisAlignment.start,
|
||||
this.isAlwaysShowScrollThumb = false
|
||||
});
|
||||
|
||||
final int selectedAtIndex;
|
||||
@@ -25,7 +24,6 @@ class Picker<Item extends Object> extends StatefulWidget {
|
||||
final String description;
|
||||
final Function(Item) onItemSelected;
|
||||
final MainAxisAlignment mainAxisAlignment;
|
||||
final bool isAlwaysShowScrollThumb;
|
||||
|
||||
@override
|
||||
PickerState createState() => PickerState<Item>(items, images, onItemSelected);
|
||||
@@ -56,6 +54,8 @@ class PickerState<Item> extends State<Picker> {
|
||||
setState(() {});
|
||||
});
|
||||
|
||||
final isShowScrollThumb = items != null ? items.length > 3 : false;
|
||||
|
||||
return AlertBackground(
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
@@ -168,13 +168,13 @@ class PickerState<Item> extends State<Picker> {
|
||||
)
|
||||
)
|
||||
: Offstage(),
|
||||
widget.isAlwaysShowScrollThumb
|
||||
? CakeScrollbar(
|
||||
isShowScrollThumb
|
||||
? CakeScrollbar(
|
||||
backgroundHeight: backgroundHeight,
|
||||
thumbHeight: thumbHeight,
|
||||
fromTop: fromTop
|
||||
)
|
||||
: Offstage(),
|
||||
: Offstage(),
|
||||
],
|
||||
)
|
||||
),
|
||||
|
||||
@@ -12,20 +12,21 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class SeedWidget extends StatefulWidget {
|
||||
SeedWidget({Key key, this.language}) : super(key: key);
|
||||
SeedWidget({Key key, this.language, this.type}) : super(key: key);
|
||||
|
||||
final String language;
|
||||
final WalletType type;
|
||||
|
||||
@override
|
||||
SeedWidgetState createState() => SeedWidgetState(language);
|
||||
SeedWidgetState createState() => SeedWidgetState(language, type);
|
||||
}
|
||||
|
||||
class SeedWidgetState extends State<SeedWidget> {
|
||||
SeedWidgetState(String language)
|
||||
SeedWidgetState(String language, this.type)
|
||||
: controller = TextEditingController(),
|
||||
focusNode = FocusNode(),
|
||||
words = SeedValidator.getWordList(
|
||||
type: WalletType.monero, language: language) {
|
||||
type:type, language: language) {
|
||||
focusNode.addListener(() {
|
||||
setState(() {
|
||||
if (!focusNode.hasFocus && controller.text.isEmpty) {
|
||||
@@ -41,6 +42,7 @@ class SeedWidgetState extends State<SeedWidget> {
|
||||
|
||||
final TextEditingController controller;
|
||||
final FocusNode focusNode;
|
||||
final WalletType type;
|
||||
List<String> words;
|
||||
bool _showPlaceholder;
|
||||
|
||||
@@ -55,7 +57,7 @@ class SeedWidgetState extends State<SeedWidget> {
|
||||
void changeSeedLanguage(String language) {
|
||||
setState(() {
|
||||
words = SeedValidator.getWordList(
|
||||
type: WalletType.monero, language: language);
|
||||
type: type, language: language);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -113,16 +113,19 @@ class SectionStandardList extends StatelessWidget {
|
||||
{@required this.itemCounter,
|
||||
@required this.itemBuilder,
|
||||
@required this.sectionCount,
|
||||
this.sectionTitleBuilder,
|
||||
this.hasTopSeparator = false,
|
||||
BuildContext context})
|
||||
: totalRows = transform(hasTopSeparator, context, sectionCount,
|
||||
itemCounter, itemBuilder);
|
||||
itemCounter, itemBuilder, sectionTitleBuilder);
|
||||
|
||||
final int sectionCount;
|
||||
final bool hasTopSeparator;
|
||||
final int Function(int sectionIndex) itemCounter;
|
||||
final Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
||||
itemBuilder;
|
||||
final Widget Function(BuildContext context, int sectionIndex)
|
||||
sectionTitleBuilder;
|
||||
final List<Widget> totalRows;
|
||||
|
||||
static List<Widget> transform(
|
||||
@@ -131,14 +134,20 @@ class SectionStandardList extends StatelessWidget {
|
||||
int sectionCount,
|
||||
int Function(int sectionIndex) itemCounter,
|
||||
Widget Function(BuildContext context, int sectionIndex, int itemIndex)
|
||||
itemBuilder) {
|
||||
itemBuilder,
|
||||
Widget Function(BuildContext context, int sectionIndex)
|
||||
sectionTitleBuilder) {
|
||||
final items = <Widget>[];
|
||||
|
||||
for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
|
||||
if ((sectionIndex == 0)&&(hasTopSeparator)) {
|
||||
if ((sectionIndex == 0) && (hasTopSeparator)) {
|
||||
items.add(StandardListSeparator(padding: EdgeInsets.only(left: 24)));
|
||||
}
|
||||
|
||||
if (sectionTitleBuilder != null) {
|
||||
items.add(sectionTitleBuilder(context, sectionIndex));
|
||||
}
|
||||
|
||||
final itemCount = itemCounter(sectionIndex);
|
||||
|
||||
for (var itemIndex = 0; itemIndex < itemCount; itemIndex++) {
|
||||
|
||||
@@ -7,77 +7,60 @@ class StandartListRow extends StatelessWidget {
|
||||
this.value,
|
||||
this.titleFontSize = 14,
|
||||
this.valueFontSize = 16,
|
||||
this.image,
|
||||
this.isDrawBottom = false});
|
||||
this.image});
|
||||
|
||||
final String title;
|
||||
final String value;
|
||||
final double titleFontSize;
|
||||
final double valueFontSize;
|
||||
final Image image;
|
||||
final bool isDrawBottom;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: titleFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme.overline.color),
|
||||
textAlign: TextAlign.left),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(value,
|
||||
style: TextStyle(
|
||||
fontSize: valueFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color)),
|
||||
),
|
||||
image != null
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: image,
|
||||
)
|
||||
: Offstage()
|
||||
],
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: titleFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color:
|
||||
Theme.of(context).primaryTextTheme.overline.color),
|
||||
textAlign: TextAlign.left),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Text(value,
|
||||
style: TextStyle(
|
||||
fontSize: valueFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color)),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
isDrawBottom
|
||||
? Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).primaryTextTheme.title.backgroundColor,
|
||||
),
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
image != null
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(left: 24),
|
||||
child: image,
|
||||
)
|
||||
: Offstage()
|
||||
],
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TrailButton extends StatelessWidget {
|
||||
TrailButton({
|
||||
@required this.caption,
|
||||
@required this.onPressed
|
||||
});
|
||||
TrailButton({@required this.caption, @required this.onPressed});
|
||||
|
||||
final String caption;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
child: FlatButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(
|
||||
caption,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).textTheme.display1.color,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14),
|
||||
),
|
||||
onPressed: onPressed),
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Text(
|
||||
caption,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).accentTextTheme.display4.decorationColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14),
|
||||
),
|
||||
onPressed: onPressed),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user