mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-11-17 01:37:40 +00:00
CAKE-198 | applied ability to make a note with some details about transaction; added transactionNote property and note getter to transaction_description.dart; added multiline textfield for notes (send_page.dart); added transaction_details_list_item.dart, textfield_list_item.dart, textfield_list_row.dart, transaction_details_view_model.dart to the app
This commit is contained in:
parent
782de5d1d8
commit
023336d460
11 changed files with 312 additions and 95 deletions
13
lib/di.dart
13
lib/di.dart
|
@ -55,6 +55,7 @@ import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/rescan_view_model.dart';
|
import 'package:cake_wallet/view_model/rescan_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
|
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
|
||||||
|
import 'package:cake_wallet/view_model/transaction_details_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/auth_view_model.dart';
|
import 'package:cake_wallet/view_model/auth_view_model.dart';
|
||||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||||
|
@ -415,11 +416,17 @@ Future setup(
|
||||||
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
|
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
|
||||||
WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
|
WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
|
||||||
|
|
||||||
|
getIt.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>
|
||||||
|
((TransactionInfo transactionInfo, _) => TransactionDetailsViewModel(
|
||||||
|
transactionInfo: transactionInfo,
|
||||||
|
transactionDescriptionBox: transactionDescriptionBox,
|
||||||
|
settingsStore: getIt.get<SettingsStore>()
|
||||||
|
));
|
||||||
|
|
||||||
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
|
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
|
||||||
(TransactionInfo transactionInfo, _) => TransactionDetailsPage(
|
(TransactionInfo transactionInfo, _) => TransactionDetailsPage(
|
||||||
transactionInfo,
|
transactionDetailsViewModel: getIt
|
||||||
getIt.get<SettingsStore>().shouldSaveRecipientAddress,
|
.get<TransactionDetailsViewModel>(param1: transactionInfo)));
|
||||||
transactionDescriptionBox));
|
|
||||||
|
|
||||||
getIt.registerFactoryParam<NewWalletTypePage,
|
getIt.registerFactoryParam<NewWalletTypePage,
|
||||||
void Function(BuildContext, WalletType), bool>(
|
void Function(BuildContext, WalletType), bool>(
|
||||||
|
|
|
@ -4,7 +4,7 @@ part 'transaction_description.g.dart';
|
||||||
|
|
||||||
@HiveType(typeId: 2)
|
@HiveType(typeId: 2)
|
||||||
class TransactionDescription extends HiveObject {
|
class TransactionDescription extends HiveObject {
|
||||||
TransactionDescription({this.id, this.recipientAddress});
|
TransactionDescription({this.id, this.recipientAddress, this.transactionNote});
|
||||||
|
|
||||||
static const boxName = 'TransactionDescriptions';
|
static const boxName = 'TransactionDescriptions';
|
||||||
static const boxKey = 'transactionDescriptionsBoxKey';
|
static const boxKey = 'transactionDescriptionsBoxKey';
|
||||||
|
@ -14,4 +14,9 @@ class TransactionDescription extends HiveObject {
|
||||||
|
|
||||||
@HiveField(1)
|
@HiveField(1)
|
||||||
String recipientAddress;
|
String recipientAddress;
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
String transactionNote;
|
||||||
|
|
||||||
|
String get note => transactionNote ?? '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class SendPage extends BasePage {
|
||||||
: _addressController = TextEditingController(),
|
: _addressController = TextEditingController(),
|
||||||
_cryptoAmountController = TextEditingController(),
|
_cryptoAmountController = TextEditingController(),
|
||||||
_fiatAmountController = TextEditingController(),
|
_fiatAmountController = TextEditingController(),
|
||||||
|
_noteController = TextEditingController(),
|
||||||
_formKey = GlobalKey<FormState>(),
|
_formKey = GlobalKey<FormState>(),
|
||||||
_cryptoAmountFocus = FocusNode(),
|
_cryptoAmountFocus = FocusNode(),
|
||||||
_fiatAmountFocus = FocusNode(),
|
_fiatAmountFocus = FocusNode(),
|
||||||
|
@ -46,6 +47,7 @@ class SendPage extends BasePage {
|
||||||
final TextEditingController _addressController;
|
final TextEditingController _addressController;
|
||||||
final TextEditingController _cryptoAmountController;
|
final TextEditingController _cryptoAmountController;
|
||||||
final TextEditingController _fiatAmountController;
|
final TextEditingController _fiatAmountController;
|
||||||
|
final TextEditingController _noteController;
|
||||||
final GlobalKey<FormState> _formKey;
|
final GlobalKey<FormState> _formKey;
|
||||||
final FocusNode _cryptoAmountFocus;
|
final FocusNode _cryptoAmountFocus;
|
||||||
final FocusNode _fiatAmountFocus;
|
final FocusNode _fiatAmountFocus;
|
||||||
|
@ -304,6 +306,30 @@ class SendPage extends BasePage {
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
fontSize: 14),
|
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: 'Note (optional)',
|
||||||
|
placeholderTextStyle: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.headline
|
||||||
|
.decorationColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
Observer(
|
Observer(
|
||||||
builder: (_) => GestureDetector(
|
builder: (_) => GestureDetector(
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
|
@ -534,6 +560,14 @@ class SendPage extends BasePage {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_noteController.addListener(() {
|
||||||
|
final note = _noteController.text ?? '';
|
||||||
|
|
||||||
|
if (note != sendViewModel.note) {
|
||||||
|
sendViewModel.note = note;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
reaction((_) => sendViewModel.sendAll, (bool all) {
|
reaction((_) => sendViewModel.sendAll, (bool all) {
|
||||||
if (all) {
|
if (all) {
|
||||||
_cryptoAmountController.text = S.current.all;
|
_cryptoAmountController.text = S.current.all;
|
||||||
|
@ -571,6 +605,12 @@ class SendPage extends BasePage {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reaction((_) => sendViewModel.note, (String note) {
|
||||||
|
if (note != _noteController.text) {
|
||||||
|
_noteController.text = note;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
reaction((_) => sendViewModel.state, (ExecutionState state) {
|
reaction((_) => sendViewModel.state, (ExecutionState state) {
|
||||||
if (state is FailureState) {
|
if (state is FailureState) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
class StandartListItem {
|
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||||
StandartListItem({this.title, this.value});
|
|
||||||
|
|
||||||
final String title;
|
class StandartListItem extends TransactionDetailsListItem {
|
||||||
final String value;
|
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,87 +1,21 @@
|
||||||
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/utils/show_bar.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/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.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/widgets/standart_list_row.dart';
|
||||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.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/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/utils/date_formatter.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
|
|
||||||
class TransactionDetailsPage extends BasePage {
|
class TransactionDetailsPage extends BasePage {
|
||||||
TransactionDetailsPage(this.transactionInfo, bool showRecipientAddress,
|
TransactionDetailsPage({this.transactionDetailsViewModel});
|
||||||
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 (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()),
|
|
||||||
if (tx.feeFormatted()?.isNotEmpty)
|
|
||||||
StandartListItem(title: S.current.send_fee, value: tx.feeFormatted())
|
|
||||||
];
|
|
||||||
|
|
||||||
_items.addAll(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => S.current.transaction_details_title;
|
String get title => S.current.transaction_details_title;
|
||||||
|
|
||||||
final TransactionInfo transactionInfo;
|
final TransactionDetailsViewModel transactionDetailsViewModel;
|
||||||
|
|
||||||
final List<StandartListItem> _items;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) {
|
Widget body(BuildContext context) {
|
||||||
|
@ -97,22 +31,37 @@ class TransactionDetailsPage extends BasePage {
|
||||||
Theme.of(context).primaryTextTheme.title.backgroundColor,
|
Theme.of(context).primaryTextTheme.title.backgroundColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemCount: _items.length,
|
itemCount: transactionDetailsViewModel.items.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = _items[index];
|
final item = transactionDetailsViewModel.items[index];
|
||||||
final isDrawBottom = index == _items.length - 1 ? true : false;
|
final isDrawBottom =
|
||||||
|
index == transactionDetailsViewModel.items.length - 1
|
||||||
|
? true : false;
|
||||||
|
|
||||||
return GestureDetector(
|
if (item is StandartListItem) {
|
||||||
onTap: () {
|
return GestureDetector(
|
||||||
Clipboard.setData(ClipboardData(text: item.value));
|
onTap: () {
|
||||||
showBar<void>(context,
|
Clipboard.setData(ClipboardData(text: item.value));
|
||||||
S.of(context).transaction_details_copied(item.title));
|
showBar<void>(context,
|
||||||
},
|
S.of(context).transaction_details_copied(item.title));
|
||||||
child: StandartListRow(
|
},
|
||||||
title: '${item.title}:',
|
child: StandartListRow(
|
||||||
value: item.value,
|
title: '${item.title}:',
|
||||||
isDrawBottom: isDrawBottom),
|
value: item.value,
|
||||||
);
|
isDrawBottom: isDrawBottom),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item is TextFieldListItem) {
|
||||||
|
return TextFieldListRow(
|
||||||
|
title: item.title,
|
||||||
|
value: item.value,
|
||||||
|
onSubmitted: item.onSubmitted,
|
||||||
|
isDrawBottom: isDrawBottom,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TextFieldListRow extends StatelessWidget {
|
||||||
|
TextFieldListRow(
|
||||||
|
{this.title,
|
||||||
|
this.value,
|
||||||
|
this.titleFontSize = 14,
|
||||||
|
this.valueFontSize = 16,
|
||||||
|
this.onSubmitted,
|
||||||
|
this.isDrawBottom = false}) {
|
||||||
|
|
||||||
|
_textController = TextEditingController();
|
||||||
|
_textController.text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final String value;
|
||||||
|
final double titleFontSize;
|
||||||
|
final double valueFontSize;
|
||||||
|
final Function(String value) onSubmitted;
|
||||||
|
final bool isDrawBottom;
|
||||||
|
|
||||||
|
TextEditingController _textController;
|
||||||
|
|
||||||
|
@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),
|
||||||
|
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: 'Note',
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: valueFontSize,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.title
|
||||||
|
.color),
|
||||||
|
border: InputBorder.none
|
||||||
|
),
|
||||||
|
onSubmitted: (value) => onSubmitted.call(value),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ class BaseTextFormField extends StatelessWidget {
|
||||||
final FocusNode focusNode;
|
final FocusNode focusNode;
|
||||||
final bool readOnly;
|
final bool readOnly;
|
||||||
final bool enableInteractiveSelection;
|
final bool enableInteractiveSelection;
|
||||||
String initialValue;
|
final String initialValue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ abstract class SendViewModelBase with Store {
|
||||||
this._fiatConversationStore, this.transactionDescriptionBox)
|
this._fiatConversationStore, this.transactionDescriptionBox)
|
||||||
: state = InitialExecutionState(),
|
: state = InitialExecutionState(),
|
||||||
_cryptoNumberFormat = NumberFormat(),
|
_cryptoNumberFormat = NumberFormat(),
|
||||||
|
note = '',
|
||||||
sendAll = false {
|
sendAll = false {
|
||||||
_setCryptoNumMaximumFractionDigits();
|
_setCryptoNumMaximumFractionDigits();
|
||||||
}
|
}
|
||||||
|
@ -53,6 +54,9 @@ abstract class SendViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
String address;
|
String address;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String note;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
bool sendAll;
|
bool sendAll;
|
||||||
|
|
||||||
|
@ -105,6 +109,7 @@ abstract class SendViewModelBase with Store {
|
||||||
cryptoAmount = '';
|
cryptoAmount = '';
|
||||||
fiatAmount = '';
|
fiatAmount = '';
|
||||||
address = '';
|
address = '';
|
||||||
|
note = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -127,7 +132,8 @@ abstract class SendViewModelBase with Store {
|
||||||
if (_settingsStore.shouldSaveRecipientAddress &&
|
if (_settingsStore.shouldSaveRecipientAddress &&
|
||||||
(pendingTransaction.id?.isNotEmpty ?? false)) {
|
(pendingTransaction.id?.isNotEmpty ?? false)) {
|
||||||
await transactionDescriptionBox.add(TransactionDescription(
|
await transactionDescriptionBox.add(TransactionDescription(
|
||||||
id: pendingTransaction.id, recipientAddress: address));
|
id: pendingTransaction.id, recipientAddress: address,
|
||||||
|
transactionNote: note));
|
||||||
}
|
}
|
||||||
|
|
||||||
state = TransactionCommitted();
|
state = TransactionCommitted();
|
||||||
|
|
105
lib/view_model/transaction_details_view_model.dart
Normal file
105
lib/view_model/transaction_details_view_model.dart
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_info.dart';
|
||||||
|
import 'package:cake_wallet/monero/monero_transaction_info.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||||
|
import 'package:cake_wallet/utils/date_formatter.dart';
|
||||||
|
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
|
||||||
|
part 'transaction_details_view_model.g.dart';
|
||||||
|
|
||||||
|
class TransactionDetailsViewModel = TransactionDetailsViewModelBase with _$TransactionDetailsViewModel;
|
||||||
|
|
||||||
|
abstract class TransactionDetailsViewModelBase with Store {
|
||||||
|
TransactionDetailsViewModelBase({
|
||||||
|
this.transactionInfo,
|
||||||
|
this.transactionDescriptionBox,
|
||||||
|
this.settingsStore}) : items = [] {
|
||||||
|
|
||||||
|
showRecipientAddress = settingsStore?.shouldSaveRecipientAddress ?? false;
|
||||||
|
|
||||||
|
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 (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)),
|
||||||
|
// FIXME: add translation
|
||||||
|
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()),
|
||||||
|
if (tx.feeFormatted()?.isNotEmpty)
|
||||||
|
StandartListItem(title: S.current.send_fee, value: tx.feeFormatted())
|
||||||
|
];
|
||||||
|
|
||||||
|
items.addAll(_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final description = transactionDescriptionBox.values.firstWhere(
|
||||||
|
(val) => val.id == transactionInfo.id, orElse: () => null);
|
||||||
|
|
||||||
|
if (description != null) {
|
||||||
|
// FIXME: add translation
|
||||||
|
items.add(TextFieldListItem(title: 'Note (tap to change)',
|
||||||
|
value: description.note, onSubmitted: (value) {
|
||||||
|
description.transactionNote = value;
|
||||||
|
description.save();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final TransactionInfo transactionInfo;
|
||||||
|
final Box<TransactionDescription> transactionDescriptionBox;
|
||||||
|
final SettingsStore settingsStore;
|
||||||
|
|
||||||
|
final List<TransactionDetailsListItem> items;
|
||||||
|
bool showRecipientAddress;
|
||||||
|
}
|
Loading…
Reference in a new issue