Fixes and improvments.

This commit is contained in:
M 2020-10-02 20:28:29 +03:00
parent b506f9c953
commit 04e7c18841
13 changed files with 246 additions and 240 deletions

View file

@ -354,7 +354,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = 32J6BB6VUS; DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -493,7 +493,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = 32J6BB6VUS; DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -526,7 +526,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = 32J6BB6VUS; DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (

View file

@ -180,9 +180,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
@override @override
Future<void> save() async { Future<void> save() async {
print('SAVE CALLED');
await monero_wallet.store(); await monero_wallet.store();
print('SAVE FINISHED');
} }
Future<int> getNodeHeight() async => monero_wallet.getNodeHeight(); Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();

View file

@ -14,8 +14,6 @@ void startAuthenticationStateChange(AuthenticationStore authenticationStore,
if (state == AuthenticationState.installed) { if (state == AuthenticationState.installed) {
await loadCurrentWallet(); await loadCurrentWallet();
// await navigatorKey.currentState
// .pushNamedAndRemoveUntil(Routes.login, (_) => false);
} }
if (state == AuthenticationState.allowed) { if (state == AuthenticationState.allowed) {

View file

@ -63,14 +63,14 @@ class ContactListPage extends BasePage {
builder: (_) { builder: (_) {
return contactListViewModel.contacts.isNotEmpty return contactListViewModel.contacts.isNotEmpty
? SectionStandardList( ? SectionStandardList(
sectionCount: 1, sectionCount: 1,
context: context, context: context,
itemCounter: (int sectionIndex) => contactListViewModel.contacts.length, itemCounter: (int sectionIndex) =>
itemBuilder: (_, sectionIndex, index) { contactListViewModel.contacts.length,
final contact = contactListViewModel.contacts[index]; itemBuilder: (_, sectionIndex, index) {
final image = _getCurrencyImage(contact.type); final contact = contactListViewModel.contacts[index];
final content = Builder( final image = _getCurrencyImage(contact.type);
builder: (context) => GestureDetector( final content = GestureDetector(
onTap: () async { onTap: () async {
if (!isEditable) { if (!isEditable) {
Navigator.of(context).pop(contact); Navigator.of(context).pop(contact);
@ -83,94 +83,79 @@ class ContactListPage extends BasePage {
if (isCopied != null && isCopied) { if (isCopied != null && isCopied) {
await Clipboard.setData( await Clipboard.setData(
ClipboardData(text: contact.address)); ClipboardData(text: contact.address));
await showBar<void>(context, await showBar<void>(
S.of(context).copied_to_clipboard); context, S.of(context).copied_to_clipboard);
} }
}, },
child: Column( child: Container(
children: <Widget>[ color: Colors.transparent,
Container( padding: const EdgeInsets.only(
width: double.infinity, left: 24, top: 16, bottom: 16, right: 24),
child: Padding( child: Row(
padding: const EdgeInsets.only( mainAxisSize: MainAxisSize.min,
left: 24, top: 16, bottom: 16, right: 24), mainAxisAlignment: MainAxisAlignment.start,
child: Row( crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, children: <Widget>[
mainAxisAlignment: MainAxisAlignment.start, image ?? Offstage(),
crossAxisAlignment: Padding(
CrossAxisAlignment.center, padding: image != null
children: <Widget>[ ? EdgeInsets.only(left: 12)
image ?? Offstage(), : EdgeInsets.only(left: 0),
Padding( child: Text(
padding: image != null contact.name,
? EdgeInsets.only(left: 12) style: TextStyle(
: EdgeInsets.only(left: 0), fontSize: 14,
child: Text( fontWeight: FontWeight.normal,
contact.name, color: Theme.of(context)
style: TextStyle( .primaryTextTheme
fontSize: 14, .title
fontWeight: FontWeight.normal, .color),
color: Theme.of(context) ),
.primaryTextTheme )
.title ],
.color), ),
),
)
],
)),
),
],
), ),
) );
);
return !isEditable return !isEditable
? content ? content
: Slidable( : Slidable(
key: Key('${contact.key}'), key: Key('${contact.key}'),
actionPane: SlidableDrawerActionPane(), actionPane: SlidableDrawerActionPane(),
child: content, child: content,
secondaryActions: <Widget>[ secondaryActions: <Widget>[
IconSlideAction( IconSlideAction(
caption: S.of(context).edit, caption: S.of(context).edit,
color: Colors.blue, color: Colors.blue,
icon: Icons.edit, icon: Icons.edit,
onTap: () async => await Navigator.of(context) onTap: () async =>
.pushNamed(Routes.addressBookAddContact, await Navigator.of(context).pushNamed(
arguments: contact), Routes.addressBookAddContact,
), arguments: contact),
IconSlideAction( ),
caption: S.of(context).delete, IconSlideAction(
color: Colors.red, caption: S.of(context).delete,
icon: CupertinoIcons.delete, color: Colors.red,
onTap: () async { icon: CupertinoIcons.delete,
final isDelete = onTap: () async {
await showAlertDialog(context) ?? false; final isDelete =
await showAlertDialog(context) ??
false;
if (isDelete) { if (isDelete) {
await contactListViewModel await contactListViewModel
.delete(contact); .delete(contact);
} }
}, },
), ),
], ]);
dismissal: SlidableDismissal( },
child: SlidableDrawerDismissal(), )
onDismissed: (actionType) async => null,
// await contactListViewModel.delete(contact),
onWillDismiss: (actionType) async =>
showAlertDialog(context),
),
);
},
)
: Center( : Center(
child: Text( child: Text(
S.of(context).placeholder_contacts, S.of(context).placeholder_contacts,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(color: Colors.grey, fontSize: 14),
color: Colors.grey,
fontSize: 14),
), ),
); );
}, },
@ -181,7 +166,8 @@ class ContactListPage extends BasePage {
Image image; Image image;
switch (currency) { switch (currency) {
case CryptoCurrency.xmr: case CryptoCurrency.xmr:
image = Image.asset('assets/images/monero_logo.png', height: 24, width: 24); image =
Image.asset('assets/images/monero_logo.png', height: 24, width: 24);
break; break;
case CryptoCurrency.ada: case CryptoCurrency.ada:
image = Image.asset('assets/images/ada.png', height: 24, width: 24); image = Image.asset('assets/images/ada.png', height: 24, width: 24);

View file

@ -29,8 +29,21 @@ class TransactionRow extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ 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'),
),
Expanded( Expanded(
child: Container( child: Container(
padding: const EdgeInsets.only(left: 12),
height: 56, height: 56,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -48,25 +61,11 @@ class TransactionRow extends StatelessWidget {
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.white)), color: Colors.white)),
Container( Text(formattedAmount,
decoration: BoxDecoration( style: TextStyle(
borderRadius: fontSize: 16,
BorderRadius.all(Radius.circular(10)), fontWeight: FontWeight.w500,
color: (direction == color: Colors.white))
TransactionDirection.incoming
? Colors.green.withOpacity(0.8)
: Theme.of(context)
.accentTextTheme
.body2
.decorationColor
.withOpacity(0.8))),
padding: EdgeInsets.only(
top: 3, bottom: 3, left: 10, right: 10),
child: Text(formattedAmount,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white)))
]), ]),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,

View file

@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class NodeListPage extends BasePage { class NodeListPage extends BasePage {
NodeListPage(this.nodeListViewModel); NodeListPage(this.nodeListViewModel);
@ -59,102 +60,104 @@ class NodeListPage extends BasePage {
} }
@override @override
Widget body(context) { Widget body(BuildContext context) {
return Container( return Container(
padding: EdgeInsets.only(top: 10), padding: EdgeInsets.only(top: 10),
child: Observer( child: Observer(
builder: (_) => SectionStandardList( builder: (BuildContext context) {
sectionCount: 2, return nodeListViewModel.nodes.isNotEmpty
context: context, ? SectionStandardList(
itemBuilder: (_, sectionIndex, index) { sectionCount: 2,
return Observer(builder: (_) { context: context,
if (sectionIndex == 0) { itemCounter: (int sectionIndex) {
return NodeHeaderListRow( if (sectionIndex == 0) {
title: S.of(context).add_new_node, return 1;
onTap: (_) async => await Navigator.of(context) }
.pushNamed(Routes.newNode));
}
final node = nodeListViewModel.nodes[index]; return nodeListViewModel.nodes.length;
final isSelected = node.keyIndex == },
nodeListViewModel.settingsStore.currentNode.keyIndex; itemBuilder: (_, sectionIndex, index) {
final nodeListRow = NodeListRow( if (sectionIndex == 0) {
title: node.uri, return NodeHeaderListRow(
isSelected: isSelected, title: S.of(context).add_new_node,
isAlive: node.requestNode(), onTap: (_) async => await Navigator.of(context)
onTap: (_) async { .pushNamed(Routes.newNode));
if (isSelected) { }
return;
}
await showPopUp<void>( final node = nodeListViewModel.nodes[index];
context: context, final isSelected = node.keyIndex ==
builder: (BuildContext context) { nodeListViewModel.settingsStore.currentNode.keyIndex;
// FIXME: Add translation. final nodeListRow = NodeListRow(
return AlertWithTwoActions( title: node.uri,
alertTitle: 'Change current node', isSelected: isSelected,
alertContent: isAlive: node.requestNode(),
S.of(context).change_current_node(node.uri), onTap: (_) async {
leftButtonText: S.of(context).cancel, if (isSelected) {
rightButtonText: S.of(context).change, return;
actionLeftButton: () => }
Navigator.of(context).pop(),
actionRightButton: () async {
await nodeListViewModel.setAsCurrent(node);
Navigator.of(context).pop();
});
});
});
final dismissibleRow = Dismissible( await showPopUp<void>(
key: Key('${node.keyIndex}'), context: context,
confirmDismiss: (direction) async { builder: (BuildContext context) {
return await showPopUp( // FIXME: Add translation.
context: context, return AlertWithTwoActions(
builder: (BuildContext context) { alertTitle: 'Change current node',
return AlertWithTwoActions( alertContent: S
alertTitle: S.of(context).remove_node, .of(context)
alertContent: S.of(context).remove_node_message, .change_current_node(node.uri),
rightButtonText: S.of(context).remove, leftButtonText: S.of(context).cancel,
leftButtonText: S.of(context).cancel, rightButtonText: S.of(context).change,
actionRightButton: () => actionLeftButton: () =>
Navigator.pop(context, true), Navigator.of(context).pop(),
actionLeftButton: () => actionRightButton: () async {
Navigator.pop(context, false)); await nodeListViewModel
}); .setAsCurrent(node);
}, Navigator.of(context).pop();
onDismissed: (direction) async => });
nodeListViewModel.delete(node), });
direction: DismissDirection.endToStart, });
background: Container(
padding: EdgeInsets.only(right: 10.0),
alignment: AlignmentDirectional.centerEnd,
color: Palette.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
const Icon(
CupertinoIcons.delete,
color: Colors.white,
),
Text(
S.of(context).delete,
style: TextStyle(color: Colors.white),
)
],
)),
child: nodeListRow);
return isSelected ? nodeListRow : dismissibleRow; final dismissibleRow = Slidable(
}); key: Key('${node.keyIndex}'),
}, actionPane: SlidableDrawerActionPane(),
itemCounter: (int sectionIndex) { child: nodeListRow,
if (sectionIndex == 0) { secondaryActions: <Widget>[
return 1; 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;
return nodeListViewModel.nodes.length; if (confirmed) {
}), await nodeListViewModel.delete(node);
}
},
),
]);
return isSelected ? nodeListRow : dismissibleRow;
})
: Container();
},
), ),
); );
} }

View file

@ -81,8 +81,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
} }
@override @override
Widget build(BuildContext context) => Widget build(BuildContext context) => Scaffold(
Scaffold(key: _key, body: body(context)); key: _key, body: body(context), resizeToAvoidBottomPadding: false);
Widget body(BuildContext context) { Widget body(BuildContext context) {
final deleteIconImage = Image.asset( final deleteIconImage = Image.asset(

View file

@ -25,15 +25,29 @@ import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart'
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
class SendPage extends BasePage { class SendPage extends BasePage {
SendPage({@required this.sendViewModel}); SendPage({@required this.sendViewModel})
: _addressController = TextEditingController(),
_cryptoAmountController = TextEditingController(),
_fiatAmountController = TextEditingController(),
_formKey = GlobalKey<FormState>(),
_cryptoAmountFocus = FocusNode(),
_fiatAmountFocus = FocusNode(),
_addressFocusNode = FocusNode() {
_addressFocusNode.addListener(() {
if (!_addressFocusNode.hasFocus && _addressController.text.isNotEmpty) {
getOpenaliasRecord(_addressFocusNode.context);
}
});
}
final SendViewModel sendViewModel; final SendViewModel sendViewModel;
final _addressController = TextEditingController(); final TextEditingController _addressController;
final _cryptoAmountController = TextEditingController(); final TextEditingController _cryptoAmountController;
final _fiatAmountController = TextEditingController(); final TextEditingController _fiatAmountController;
final _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey;
final _cryptoAmountFocus = FocusNode(); final FocusNode _cryptoAmountFocus;
final _fiatAmountFocus = FocusNode(); final FocusNode _fiatAmountFocus;
final FocusNode _addressFocusNode;
bool _effectsInstalled = false; bool _effectsInstalled = false;
@ -105,6 +119,7 @@ class SendPage extends BasePage {
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
AddressTextField( AddressTextField(
focusNode: _addressFocusNode,
controller: _addressController, controller: _addressController,
onURIScanned: (uri) { onURIScanned: (uri) {
var address = ''; var address = '';
@ -672,24 +687,23 @@ class SendPage extends BasePage {
} }
Future<void> getOpenaliasRecord(BuildContext context) async { Future<void> getOpenaliasRecord(BuildContext context) async {
// final isOpenalias = final record =
// await sendViewModel.isOpenaliasRecord(_addressController.text); await sendViewModel.decodeOpenaliasRecord(_addressController.text);
// if (isOpenalias) { if (record != null) {
// _addressController.text = sendViewModel.recordAddress; _addressController.text = record.address;
// await showPopUp<void>( await showPopUp<void>(
// context: context, context: context,
// builder: (BuildContext context) { builder: (BuildContext context) {
// return AlertWithOneAction( return AlertWithOneAction(
// alertTitle: S.of(context).openalias_alert_title, alertTitle: S.of(context).openalias_alert_title,
// alertContent: S alertContent:
// .of(context) S.of(context).openalias_alert_content(record.name),
// .openalias_alert_content(sendViewModel.recordName), buttonText: S.of(context).ok,
// buttonText: S.of(context).ok, buttonAction: () => Navigator.of(context).pop());
// buttonAction: () => Navigator.of(context).pop()); });
// }); }
// }
} }
Future<void> _setTransactionPriority(BuildContext context) async { Future<void> _setTransactionPriority(BuildContext context) async {

View file

@ -131,7 +131,7 @@ class WalletListBodyState extends State<WalletListBody> {
wallet.name, wallet.name,
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w500,
color: Theme.of(context) color: Theme.of(context)
.primaryTextTheme .primaryTextTheme
.title .title

View file

@ -61,7 +61,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
} }
return watch().listen((event) { return watch().listen((event) {
if (filter != null && !filter(event.value as T)) { if (filter != null && event.value != null && !filter(event.value as T)) {
return; return;
} }
@ -80,7 +80,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
} }
return watch().listen((event) { return watch().listen((event) {
if (filter != null && !filter(event.value as T)) { if (filter != null && event.value != null && !filter(event.value as T)) {
return; return;
} }
@ -124,15 +124,13 @@ extension HiveBindable<T extends Keyable> on ObservableList<T> {
listen().listen((event) => dest.acceptEntityChange(event)); listen().listen((event) => dest.acceptEntityChange(event));
void acceptBoxChange(BoxEvent event, {T transformed}) { void acceptBoxChange(BoxEvent event, {T transformed}) {
print('---------------------');
print('event.key: ${event.key}; event.deleted: ${event.deleted};');
if (event.deleted) { if (event.deleted) {
removeWhere((el) { removeWhere((el) {
print('el.keyIndex ${el.keyIndex}'); return el.keyIndex == event.key;
return el.keyIndex == event.key; }); });
}
print('---------------------'); return;
}
final dynamic value = transformed ?? event.value; final dynamic value = transformed ?? event.value;
@ -150,6 +148,7 @@ extension HiveBindable<T extends Keyable> on ObservableList<T> {
void acceptEntityChange(EntityChange<T> event) { void acceptEntityChange(EntityChange<T> event) {
if (event.type == ChangeType.delete) { if (event.type == ChangeType.delete) {
removeWhere((el) => el.keyIndex == event.key); removeWhere((el) => el.keyIndex == event.key);
return;
} }
final dynamic value = event.value; final dynamic value = event.value;

View file

@ -14,8 +14,8 @@ Future<T> showPopUp<T>({
context: context, context: context,
builder: builder, builder: builder,
barrierDismissible: barrierDismissible, barrierDismissible: barrierDismissible,
//barrierColor: barrierColor, barrierColor: barrierColor,
//useSafeArea: useSafeArea, useSafeArea: useSafeArea,
useRootNavigator: useRootNavigator, useRootNavigator: useRootNavigator,
routeSettings: routeSettings, routeSettings: routeSettings,
child: child); child: child);

View file

@ -16,7 +16,7 @@ abstract class NodeListViewModelBase with Store {
NodeListViewModelBase(this._nodeSource, this._wallet, this.settingsStore) NodeListViewModelBase(this._nodeSource, this._wallet, this.settingsStore)
: nodes = ObservableList<Node>() { : nodes = ObservableList<Node>() {
_nodeSource.bindToList(nodes, _nodeSource.bindToList(nodes,
filter: (Node val) => val.type == _wallet.type, initialFire: true); filter: (Node val) => val?.type == _wallet.type, initialFire: true);
} }
final ObservableList<Node> nodes; final ObservableList<Node> nodes;
@ -46,7 +46,8 @@ abstract class NodeListViewModelBase with Store {
await setAsCurrent(node); await setAsCurrent(node);
} }
Future<void> delete(Node node) async => _nodeSource.delete(node.key); @action
Future<void> delete(Node node) async => node.delete();
Future<void> setAsCurrent(Node node) async => Future<void> setAsCurrent(Node node) async =>
settingsStore.currentNode = node; settingsStore.currentNode = node;

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/openalias_record.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/template_validator.dart'; import 'package:cake_wallet/core/template_validator.dart';
@ -144,6 +145,13 @@ abstract class SendViewModelBase with Store {
void setTransactionPriority(TransactionPriority priority) => void setTransactionPriority(TransactionPriority priority) =>
_settingsStore.transactionPriority = priority; _settingsStore.transactionPriority = priority;
Future<OpenaliasRecord> decodeOpenaliasRecord(String name) async {
final record = await OpenaliasRecord
.fetchAddressAndName(OpenaliasRecord.formatDomainName(name));
return record.name != name ? record : null;
}
@action @action
void _updateFiatAmount() { void _updateFiatAmount() {
try { try {