Merge branch 'CAKE-29-remake-node-screen-and-contact-book' of github.com:cake-tech/cake_wallet_private into btc

wownero
M 4 years ago
commit 2627945e00

@ -9,6 +9,7 @@ import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
class ContactListPage extends BasePage {
ContactListPage(this.contactListViewModel, {this.isEditable = true});
@ -30,7 +31,7 @@ class ContactListPage extends BasePage {
height: 32.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).accentTextTheme.title.backgroundColor),
color: Theme.of(context).accentTextTheme.caption.color),
child: Stack(
alignment: Alignment.center,
children: <Widget>[
@ -54,30 +55,30 @@ class ContactListPage extends BasePage {
@override
Widget body(BuildContext context) {
final shortDivider = Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: Theme.of(context).backgroundColor,
child: Container(
height: 1,
color: Theme.of(context).primaryTextTheme.title.backgroundColor,
),
);
return Container(
color: Theme.of(context).backgroundColor,
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
child: Observer(
builder: (_) {
return contactListViewModel.contacts.isNotEmpty
? ListView.separated(
separatorBuilder: (_, __) => Container(
height: 1,
padding: EdgeInsets.only(left: 24),
color: Theme.of(context)
.accentTextTheme
.title
.backgroundColor,
child: Container(
height: 1,
color: Theme.of(context).dividerColor,
),
),
itemCount: contactListViewModel.contacts.length,
itemBuilder: (BuildContext context, int index) {
final contact = contactListViewModel.contacts[index];
final image = _getCurrencyImage(contact.type);
final content = GestureDetector(
? 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 = Builder(
builder: (context) => GestureDetector(
onTap: () async {
if (!isEditable) {
Navigator.of(context).pop(contact);
@ -106,10 +107,6 @@ class ContactListPage extends BasePage {
children: <Widget>[
Container(
width: double.infinity,
color: Theme.of(context)
.accentTextTheme
.title
.backgroundColor,
child: Padding(
padding: const EdgeInsets.only(
left: 24, top: 16, bottom: 16, right: 24),
@ -117,7 +114,7 @@ class ContactListPage extends BasePage {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.center,
CrossAxisAlignment.center,
children: <Widget>[
image ?? Offstage(),
Padding(
@ -128,6 +125,7 @@ class ContactListPage extends BasePage {
contact.name,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
color: Theme.of(context)
.primaryTextTheme
.title
@ -139,57 +137,55 @@ class ContactListPage extends BasePage {
),
],
),
);
)
);
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;
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);
}
},
),
],
dismissal: SlidableDismissal(
child: SlidableDrawerDismissal(),
onDismissed: (actionType) async =>
await contactListViewModel.delete(contact),
onWillDismiss: (actionType) async =>
showAlertDialog(context),
),
);
})
if (isDelete) {
await contactListViewModel
.delete(contact);
}
},
),
],
dismissal: SlidableDismissal(
child: SlidableDrawerDismissal(),
onDismissed: (actionType) async =>
await contactListViewModel.delete(contact),
onWillDismiss: (actionType) async =>
showAlertDialog(context),
),
);
},
)
: Center(
child: Text(
S.of(context).placeholder_contacts,
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.caption
.color
.withOpacity(0.5),
color: Colors.grey,
fontSize: 14),
),
);

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -30,7 +31,7 @@ class ContactPage extends BasePage {
.addListener(() => contactViewModel.address = _addressController.text);
autorun((_) =>
_currencyTypeController.text = contactViewModel.currency.toString());
_currencyTypeController.text = contactViewModel.currency?.toString()??'');
}
@override
@ -45,7 +46,7 @@ class ContactPage extends BasePage {
@override
Widget body(BuildContext context) {
final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png',
color: Theme.of(context).dividerColor, height: 8);
color: Theme.of(context).primaryTextTheme.overline.color, height: 8);
reaction((_) => contactViewModel.state, (ContactViewModelState state) {
if (state is ContactCreationFailure) {
@ -57,79 +58,83 @@ class ContactPage extends BasePage {
}
});
return Container(
color: Theme.of(context).backgroundColor,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
BaseTextFormField(
controller: _nameController,
hintText: S.of(context).contact_name,
validator: ContactNameValidator()),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
child: InkWell(
onTap: () => _presentCurrencyPicker(context),
child: IgnorePointer(
child: BaseTextFormField(
controller: _currencyTypeController,
hintText: S.of(context).settings_currency,
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[downArrow],
),
)),
),
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
BaseTextFormField(
controller: _nameController,
hintText: S.of(context).contact_name,
validator: ContactNameValidator()),
Padding(
padding: EdgeInsets.only(top: 20),
child: Container(
child: InkWell(
onTap: () => _presentCurrencyPicker(context),
child: IgnorePointer(
child: BaseTextFormField(
controller: _currencyTypeController,
hintText: S.of(context).settings_currency,
suffixIcon: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[downArrow],
),
)),
),
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Observer(
builder: (_) => AddressTextField(
controller: _addressController,
options: [AddressTextFieldOption.qrCode],
validator: AddressValidator(
type: contactViewModel.currency),
)),
)
],
),
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Row(
children: <Widget>[
Expanded(
child: PrimaryButton(
onPressed: () => contactViewModel.reset(),
text: S.of(context).reset,
color: Colors.red,
textColor: Colors.white),
),
SizedBox(width: 20),
Expanded(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
return;
}
await contactViewModel.save();
},
text: S.of(context).save,
color: Colors.green,
textColor: Colors.white,
isDisabled: !contactViewModel.isReady)))
Padding(
padding: EdgeInsets.only(top: 20),
child: Observer(
builder: (_) => AddressTextField(
controller: _addressController,
options: [AddressTextFieldOption.qrCode],
buttonColor: Theme.of(context).accentTextTheme.display2.color,
iconColor: PaletteDark.gray,
borderColor: Theme.of(context).primaryTextTheme.title.backgroundColor,
validator: AddressValidator(
type: contactViewModel.currency),
)),
)
],
)),
);
),
),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Row(
children: <Widget>[
Expanded(
child: PrimaryButton(
onPressed: () {
contactViewModel.reset();
_nameController.text = '';
_addressController.text = '';
},
text: S.of(context).reset,
color: Colors.red,
textColor: Colors.white),
),
SizedBox(width: 20),
Expanded(
child: Observer(
builder: (_) => PrimaryButton(
onPressed: () async {
if (!_formKey.currentState.validate()) {
return;
}
await contactViewModel.save();
},
text: S.of(context).save,
color: Palette.blueCraiola,
textColor: Colors.white,
isDisabled: !contactViewModel.isReady)))
],
));
}
void _presentCurrencyPicker(BuildContext context) {

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -6,6 +7,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/node_address_validator.dart';
import 'package:cake_wallet/core/node_port_validator.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.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/view_model/node_list/node_create_or_edit_view_model.dart';
@ -77,32 +79,11 @@ class NodeCreateOrEditPage extends BasePage {
Row(
children: <Widget>[
Expanded(
child: TextFormField(
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
fontSize: 16),
hintText: S.of(context).node_address,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0))),
child: BaseTextFormField(
controller: _addressController,
hintText: S.of(context).node_address,
validator: NodeAddressValidator(),
),
)
)
],
),
@ -110,34 +91,13 @@ class NodeCreateOrEditPage extends BasePage {
Row(
children: <Widget>[
Expanded(
child: TextFormField(
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
child: BaseTextFormField(
controller: _portController,
hintText: S.of(context).node_port,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
fontSize: 16),
hintText: S.of(context).node_port,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0))),
controller: _portController,
validator: NodePortValidator(),
),
)
)
],
),
@ -146,32 +106,10 @@ class NodeCreateOrEditPage extends BasePage {
Row(
children: <Widget>[
Expanded(
child: TextFormField(
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
fontSize: 16),
hintText: S.of(context).login,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0))),
child: BaseTextFormField(
controller: _loginController,
validator: (value) => null,
),
hintText: S.of(context).login,
)
)
],
),
@ -179,32 +117,10 @@ class NodeCreateOrEditPage extends BasePage {
Row(
children: <Widget>[
Expanded(
child: TextFormField(
style: TextStyle(
fontSize: 16.0,
color: Theme.of(context)
.primaryTextTheme
.title
.color),
decoration: InputDecoration(
hintStyle: TextStyle(
color: Theme.of(context)
.primaryTextTheme
.caption
.color,
fontSize: 16),
hintText: S.of(context).password,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).dividerColor,
width: 1.0))),
child: BaseTextFormField(
controller: _passwordController,
validator: (value) => null,
),
hintText: S.of(context).password,
)
)
],
)
@ -237,7 +153,7 @@ class NodeCreateOrEditPage extends BasePage {
Navigator.of(context).pop();
},
text: S.of(context).save,
color: Colors.green,
color: Palette.blueCraiola,
textColor: Colors.white,
isDisabled: !nodeCreateOrEditViewModel.isReady,
),

@ -24,7 +24,7 @@ class NodeListPage extends BasePage {
height: 32,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(16)),
color: Theme.of(context).accentTextTheme.title.backgroundColor),
color: Theme.of(context).accentTextTheme.caption.color),
child: ButtonTheme(
minWidth: double.minPositive,
child: FlatButton(
@ -51,7 +51,7 @@ class NodeListPage extends BasePage {
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
color: Colors.blue),
color: Palette.blueCraiola),
)),
),
);

@ -23,9 +23,9 @@ class NodeListRow extends StandardListRow {
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
return NodeIndicator(isLive: snapshot.data as bool);
return NodeIndicator(isLive: (snapshot.data as bool)??false);
default:
return NodeIndicator();
return NodeIndicator(isLive: false);
}
});
}
@ -38,6 +38,6 @@ class NodeHeaderListRow extends StandardListRow {
@override
Widget buildTrailing(BuildContext context) {
return Icon(Icons.add,
color: Theme.of(context).primaryTextTheme.title.color, size: 24.0);
color: Theme.of(context).accentTextTheme.subhead.color, size: 24.0);
}
}

@ -1,4 +1,3 @@
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/routes.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
@ -23,6 +22,7 @@ class AddressTextField extends StatelessWidget {
this.isBorderExist = true,
this.buttonColor,
this.borderColor,
this.iconColor,
this.textStyle,
this.hintStyle,
this.validator});
@ -40,6 +40,7 @@ class AddressTextField extends StatelessWidget {
final bool isBorderExist;
final Color buttonColor;
final Color borderColor;
final Color iconColor;
final TextStyle textStyle;
final TextStyle hintStyle;
FocusNode focusNode;
@ -55,7 +56,7 @@ class AddressTextField extends StatelessWidget {
focusNode: focusNode,
style: textStyle ?? TextStyle(
fontSize: 16,
color: Colors.white
color: Theme.of(context).primaryTextTheme.title.color
),
decoration: InputDecoration(
suffixIcon: SizedBox(
@ -64,7 +65,7 @@ class AddressTextField extends StatelessWidget {
),
hintStyle: hintStyle ?? TextStyle(
fontSize: 16,
color: PaletteDark.darkCyanBlue
color: Theme.of(context).hintColor
),
hintText: placeholder ?? S.current.widgets_address,
focusedBorder: isBorderExist
@ -113,7 +114,7 @@ class AddressTextField extends StatelessWidget {
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/duplicate.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
color: iconColor ?? Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)),
],
@ -131,7 +132,7 @@ class AddressTextField extends StatelessWidget {
borderRadius:
BorderRadius.all(Radius.circular(6))),
child: Image.asset('assets/images/qr_code_icon.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
color: iconColor ?? Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
))
],
@ -152,7 +153,7 @@ class AddressTextField extends StatelessWidget {
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/open_book.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
color: iconColor ?? Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
))
],
@ -173,7 +174,7 @@ class AddressTextField extends StatelessWidget {
BorderRadius.all(Radius.circular(6))),
child: Image.asset(
'assets/images/receive_icon_raw.png',
color: Theme.of(context).primaryTextTheme.display1.decorationColor,
color: iconColor ?? Theme.of(context).primaryTextTheme.display1.decorationColor,
)),
)),
],

@ -45,7 +45,7 @@ class BaseAlertDialog extends StatelessWidget {
Flexible(
child: Container(
height: 52,
padding: EdgeInsets.only(left: 12, right: 12),
padding: EdgeInsets.only(left: 6, right: 6),
color: Palette.blueCraiola,
child: ButtonTheme(
minWidth: double.infinity,
@ -70,7 +70,7 @@ class BaseAlertDialog extends StatelessWidget {
Flexible(
child: Container(
height: 52,
padding: EdgeInsets.only(left: 12, right: 12),
padding: EdgeInsets.only(left: 6, right: 6),
color: Palette.alizarinRed,
child: ButtonTheme(
minWidth: double.infinity,

@ -1,3 +1,4 @@
import 'package:cake_wallet/palette.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -39,7 +40,7 @@ class StandardListRow extends StatelessWidget {
Text(title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.normal,
color: _titleColor(context)))
]));
}
@ -47,21 +48,24 @@ class StandardListRow extends StatelessWidget {
Widget buildTrailing(BuildContext context) => null;
Color _titleColor(BuildContext context) => isSelected
? Color.fromRGBO(20, 200, 71, 1)
? Palette.blueCraiola
: Theme.of(context).primaryTextTheme.title.color;
Color _backgroundColor(BuildContext context) {
// return Theme.of(context).accentTextTheme.subtitle.decorationColor;
return Theme.of(context).accentTextTheme.title.backgroundColor;
return Theme.of(context).backgroundColor;
}
}
class SectionHeaderListRow extends StatelessWidget {
@override
Widget build(BuildContext context) => Column(children: [
StandardListSeparator(),
Container(width: double.infinity, height: 40, color: Colors.white),
StandardListSeparator()
StandardListSeparator(padding: EdgeInsets.only(left: 24)),
Container(
width: double.infinity,
height: 40,
color: Theme.of(context).backgroundColor),
//StandardListSeparator(padding: EdgeInsets.only(left: 24))
]);
}
@ -75,8 +79,10 @@ class StandardListSeparator extends StatelessWidget {
return Container(
height: 1,
padding: padding,
color: Theme.of(context).accentTextTheme.title.backgroundColor,
child: Container(height: 1, color: Color.fromRGBO(219, 227, 243, 1)));
color: Theme.of(context).backgroundColor,
child: Container(
height: 1,
color: Theme.of(context).primaryTextTheme.title.backgroundColor));
}
}
@ -126,9 +132,9 @@ class SectionStandardList extends StatelessWidget {
final items = <Widget>[];
for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
if (sectionIndex == 0) {
/*if (sectionIndex == 0) {
items.add(StandardListSeparator());
}
}*/
final itemCount = itemCounter(sectionIndex);
@ -140,7 +146,7 @@ class SectionStandardList extends StatelessWidget {
items.add(sectionIndex + 1 != sectionCount
? SectionHeaderListRow()
: StandardListSeparator());
: StandardListSeparator(padding: EdgeInsets.only(left: 24)));
}
return items;

@ -152,6 +152,9 @@ class Themes {
color: Palette.blueCraiola, // first gradient color (menu header)
decorationColor: Palette.pinkFlamingo // second gradient color(menu header)
),
display2: TextStyle(
color: Palette.shadowWhite, // action button color (address text field)
),
),
@ -315,6 +318,9 @@ class Themes {
color: PaletteDark.deepPurpleBlue, // first gradient color (menu header)
decorationColor: PaletteDark.deepPurpleBlue // second gradient color(menu header)
),
display2: TextStyle(
color: PaletteDark.nightBlue, // action button color (address text field)
),
),

@ -16,7 +16,7 @@ abstract class ContactViewModelBase with Store {
_contact = contact {
name = _contact?.name;
address = _contact?.address;
currency = _contact?.type ?? _wallet.currency;
currency = _contact?.type; //_wallet.currency;
}
@observable
@ -33,7 +33,8 @@ abstract class ContactViewModelBase with Store {
@computed
bool get isReady =>
(name?.isNotEmpty ?? false) && (address?.isNotEmpty ?? false);
(name?.isNotEmpty ?? false) && (currency?.toString()?.isNotEmpty ?? false)
&& (address?.isNotEmpty ?? false);
final List<CryptoCurrency> currencies;
final ContactService _contactService;
@ -44,7 +45,8 @@ abstract class ContactViewModelBase with Store {
void reset() {
address = '';
name = '';
currency = _wallet.currency;
//currency = _wallet.currency;
currency = null;
}
Future save() async {

Loading…
Cancel
Save