mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-19 05:58:50 +02:00
Merge branch 'release-4.2.4' into CAKE-345-batch-sending
# Conflicts: # lib/bitcoin/electrum_wallet.dart # lib/src/screens/send/send_page.dart # lib/src/screens/send/send_template_page.dart # lib/view_model/send/send_view_model.dart # res/values/strings_de.arb # res/values/strings_en.arb # res/values/strings_es.arb # res/values/strings_hi.arb # res/values/strings_hr.arb # res/values/strings_it.arb # res/values/strings_ja.arb # res/values/strings_ko.arb # res/values/strings_nl.arb # res/values/strings_pl.arb # res/values/strings_pt.arb # res/values/strings_ru.arb # res/values/strings_uk.arb # res/values/strings_zh.arb
This commit is contained in:
@@ -16,11 +16,22 @@ class ContactListViewModel = ContactListViewModelBase
|
||||
abstract class ContactListViewModelBase with Store {
|
||||
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
|
||||
: contacts = ObservableList<ContactRecord>(),
|
||||
walletContacts = walletInfoSource.values
|
||||
.where((info) => info.address?.isNotEmpty ?? false)
|
||||
.map((info) => WalletContact(
|
||||
info.address, info.name, walletTypeToCryptoCurrency(info.type)))
|
||||
.toList() {
|
||||
walletContacts = [] {
|
||||
walletInfoSource.values.forEach((info) {
|
||||
if (info.addresses?.isNotEmpty ?? false) {
|
||||
info.addresses?.forEach((address, label) {
|
||||
final name = label.isNotEmpty
|
||||
? info.name + ' ($label)'
|
||||
: info.name;
|
||||
|
||||
walletContacts.add(WalletContact(
|
||||
address,
|
||||
name,
|
||||
walletTypeToCryptoCurrency(info.type)));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_subscription = contactSource.bindToListWithTransform(
|
||||
contacts, (Contact contact) => ContactRecord(contactSource, contact),
|
||||
initialFire: true);
|
||||
|
||||
@@ -92,17 +92,17 @@ abstract class DashboardViewModelBase with Store {
|
||||
final _wallet = wallet;
|
||||
|
||||
if (_wallet is MoneroWallet) {
|
||||
subname = _wallet.account?.label;
|
||||
subname = _wallet.walletAddresses.account?.label;
|
||||
|
||||
_onMoneroAccountChangeReaction = reaction((_) => _wallet.account,
|
||||
(Account account) => _onMoneroAccountChange(_wallet));
|
||||
_onMoneroAccountChangeReaction = reaction((_) => _wallet.walletAddresses
|
||||
.account, (Account account) => _onMoneroAccountChange(_wallet));
|
||||
|
||||
_onMoneroBalanceChangeReaction = reaction((_) => _wallet.balance,
|
||||
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
|
||||
|
||||
final _accountTransactions = _wallet
|
||||
.transactionHistory.transactions.values
|
||||
.where((tx) => tx.accountIndex == _wallet.account.id)
|
||||
.where((tx) => tx.accountIndex == _wallet.walletAddresses.account.id)
|
||||
.toList();
|
||||
|
||||
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
|
||||
@@ -131,7 +131,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
filter: (TransactionInfo tx) {
|
||||
final wallet = _wallet;
|
||||
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
||||
return tx.accountIndex == wallet.account.id;
|
||||
return tx.accountIndex == wallet.walletAddresses.account.id;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -153,7 +153,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
String subname;
|
||||
|
||||
@computed
|
||||
String get address => wallet.address;
|
||||
String get address => wallet.walletAddresses.address;
|
||||
|
||||
@computed
|
||||
SyncStatus get status => wallet.syncStatus;
|
||||
@@ -251,13 +251,13 @@ abstract class DashboardViewModelBase with Store {
|
||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
subname = wallet.account?.label;
|
||||
subname = wallet.walletAddresses.account?.label;
|
||||
|
||||
_onMoneroAccountChangeReaction?.reaction?.dispose();
|
||||
_onMoneroBalanceChangeReaction?.reaction?.dispose();
|
||||
|
||||
_onMoneroAccountChangeReaction = reaction((_) => wallet.account,
|
||||
(Account account) => _onMoneroAccountChange(wallet));
|
||||
_onMoneroAccountChangeReaction = reaction((_) => wallet.walletAddresses
|
||||
.account, (Account account) => _onMoneroAccountChange(wallet));
|
||||
|
||||
_onMoneroBalanceChangeReaction = reaction((_) => wallet.balance,
|
||||
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
|
||||
@@ -284,7 +284,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
settingsStore: appStore.settingsStore),
|
||||
filter: (TransactionInfo tx) {
|
||||
if (tx is MoneroTransactionInfo && wallet is MoneroWallet) {
|
||||
return tx.accountIndex == wallet.account.id;
|
||||
return tx.accountIndex == wallet.walletAddresses.account.id;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -293,7 +293,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
|
||||
@action
|
||||
void _onMoneroAccountChange(MoneroWallet wallet) {
|
||||
subname = wallet.account?.label;
|
||||
subname = wallet.walletAddresses.account?.label;
|
||||
_onMoneroTransactionsUpdate(wallet);
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
transactions.clear();
|
||||
|
||||
final _accountTransactions = wallet.transactionHistory.transactions.values
|
||||
.where((tx) => tx.accountIndex == wallet.account.id)
|
||||
.where((tx) => tx.accountIndex == wallet.walletAddresses.account.id)
|
||||
.toList();
|
||||
|
||||
transactions.addAll(_accountTransactions.map((transaction) =>
|
||||
|
||||
@@ -41,7 +41,8 @@ abstract class ExchangeViewModelBase with Store {
|
||||
depositAmount = '';
|
||||
receiveAmount = '';
|
||||
receiveAddress = '';
|
||||
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
|
||||
depositAddress = depositCurrency == wallet.currency
|
||||
? wallet.walletAddresses.address : '';
|
||||
limitsState = LimitsInitialState();
|
||||
tradeState = ExchangeTradeStateInitial();
|
||||
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
|
||||
@@ -308,8 +309,10 @@ abstract class ExchangeViewModelBase with Store {
|
||||
isReceiveAmountEntered = false;
|
||||
depositAmount = '';
|
||||
receiveAmount = '';
|
||||
depositAddress = depositCurrency == wallet.currency ? wallet.address : '';
|
||||
receiveAddress = receiveCurrency == wallet.currency ? wallet.address : '';
|
||||
depositAddress = depositCurrency == wallet.currency
|
||||
? wallet.walletAddresses.address : '';
|
||||
receiveAddress = receiveCurrency == wallet.currency
|
||||
? wallet.walletAddresses.address : '';
|
||||
isDepositAddressEnabled = !(depositCurrency == wallet.currency);
|
||||
isReceiveAddressEnabled = !(receiveCurrency == wallet.currency);
|
||||
isFixedRateMode = false;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/monero/monero_account_list.dart';
|
||||
@@ -10,11 +12,12 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
|
||||
|
||||
abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList,
|
||||
{AccountListItem accountListItem})
|
||||
{@required WalletBase wallet, AccountListItem accountListItem})
|
||||
: state = InitialExecutionState(),
|
||||
isEdit = accountListItem != null,
|
||||
label = accountListItem?.label??'',
|
||||
_accountListItem = accountListItem;
|
||||
_accountListItem = accountListItem,
|
||||
_wallet = wallet;
|
||||
|
||||
final bool isEdit;
|
||||
|
||||
@@ -26,6 +29,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
|
||||
final MoneroAccountList _moneroAccountList;
|
||||
final AccountListItem _accountListItem;
|
||||
final WalletBase _wallet;
|
||||
|
||||
Future<void> save() async {
|
||||
try {
|
||||
@@ -38,6 +42,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
await _moneroAccountList.addAccount(label: label);
|
||||
}
|
||||
|
||||
await _wallet.save();
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
|
||||
@@ -20,15 +20,16 @@ abstract class MoneroAccountListViewModelBase with Store {
|
||||
}
|
||||
|
||||
@computed
|
||||
List<AccountListItem> get accounts => _moneroWallet.accountList.accounts
|
||||
.map((acc) => AccountListItem(
|
||||
List<AccountListItem> get accounts => _moneroWallet.walletAddresses
|
||||
.accountList.accounts.map((acc) => AccountListItem(
|
||||
label: acc.label,
|
||||
id: acc.id,
|
||||
isSelected: acc.id == _moneroWallet.account.id))
|
||||
isSelected: acc.id == _moneroWallet.walletAddresses.account.id))
|
||||
.toList();
|
||||
|
||||
final MoneroWallet _moneroWallet;
|
||||
|
||||
void select(AccountListItem item) =>
|
||||
_moneroWallet.account = Account(id: item.id, label: item.label);
|
||||
_moneroWallet.walletAddresses.account =
|
||||
Account(id: item.id, label: item.label);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
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/view_model/unspent_coins/unspent_coins_item.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_switch_item.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'unspent_coins_details_view_model.g.dart';
|
||||
|
||||
class UnspentCoinsDetailsViewModel = UnspentCoinsDetailsViewModelBase
|
||||
with _$UnspentCoinsDetailsViewModel;
|
||||
|
||||
abstract class UnspentCoinsDetailsViewModelBase with Store {
|
||||
UnspentCoinsDetailsViewModelBase({
|
||||
this.unspentCoinsItem, this.unspentCoinsListViewModel}) {
|
||||
|
||||
final amount = unspentCoinsItem.amount ?? '';
|
||||
final address = unspentCoinsItem.address ?? '';
|
||||
isFrozen = unspentCoinsItem.isFrozen ?? false;
|
||||
note = unspentCoinsItem.note ?? '';
|
||||
|
||||
items = [
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: amount
|
||||
),
|
||||
StandartListItem(
|
||||
title: S.current.widgets_address,
|
||||
value: address
|
||||
),
|
||||
TextFieldListItem(
|
||||
title: S.current.note_tap_to_change,
|
||||
value: note,
|
||||
onSubmitted: (value) {
|
||||
unspentCoinsItem.note = value;
|
||||
unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
|
||||
}),
|
||||
UnspentCoinsSwitchItem(
|
||||
title: S.current.freeze,
|
||||
value: '',
|
||||
switchValue: () => isFrozen,
|
||||
onSwitchValueChange: (value) async {
|
||||
isFrozen = value;
|
||||
unspentCoinsItem.isFrozen = value;
|
||||
if (value) {
|
||||
unspentCoinsItem.isSending = !value;
|
||||
}
|
||||
await unspentCoinsListViewModel.saveUnspentCoinInfo(unspentCoinsItem);
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
@observable
|
||||
bool isFrozen;
|
||||
|
||||
@observable
|
||||
String note;
|
||||
|
||||
final UnspentCoinsItem unspentCoinsItem;
|
||||
final UnspentCoinsListViewModel unspentCoinsListViewModel;
|
||||
List<TransactionDetailsListItem> items;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'unspent_coins_item.g.dart';
|
||||
|
||||
class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem;
|
||||
|
||||
abstract class UnspentCoinsItemBase with Store {
|
||||
UnspentCoinsItemBase({
|
||||
this.address,
|
||||
this.amount,
|
||||
this.hash,
|
||||
this.isFrozen,
|
||||
this.note,
|
||||
this.isSending});
|
||||
|
||||
@observable
|
||||
String address;
|
||||
|
||||
@observable
|
||||
String amount;
|
||||
|
||||
@observable
|
||||
String hash;
|
||||
|
||||
@observable
|
||||
bool isFrozen;
|
||||
|
||||
@observable
|
||||
String note;
|
||||
|
||||
@observable
|
||||
bool isSending;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
|
||||
import 'package:cake_wallet/bitcoin/electrum_wallet.dart';
|
||||
import 'package:cake_wallet/bitcoin/unspent_coins_info.dart';
|
||||
import 'package:cake_wallet/core/wallet_base.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'unspent_coins_list_view_model.g.dart';
|
||||
|
||||
class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel;
|
||||
|
||||
abstract class UnspentCoinsListViewModelBase with Store {
|
||||
UnspentCoinsListViewModelBase({
|
||||
@required WalletBase wallet,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo}) {
|
||||
_unspentCoinsInfo = unspentCoinsInfo;
|
||||
_wallet = wallet as ElectrumWallet;
|
||||
_wallet.updateUnspent();
|
||||
}
|
||||
|
||||
ElectrumWallet _wallet;
|
||||
Box<UnspentCoinsInfo> _unspentCoinsInfo;
|
||||
|
||||
@computed
|
||||
ObservableList<UnspentCoinsItem> get items =>
|
||||
ObservableList.of(_wallet.unspentCoins.map((elem) {
|
||||
final amount = bitcoinAmountToString(amount: elem.value) +
|
||||
' ${_wallet.currency.title}';
|
||||
|
||||
return UnspentCoinsItem(
|
||||
address: elem.address.address,
|
||||
amount: amount,
|
||||
hash: elem.hash,
|
||||
isFrozen: elem.isFrozen,
|
||||
note: elem.note,
|
||||
isSending: elem.isSending
|
||||
);
|
||||
}));
|
||||
|
||||
Future<void> saveUnspentCoinInfo(UnspentCoinsItem item) async {
|
||||
try {
|
||||
final info = _unspentCoinsInfo.values
|
||||
.firstWhere((element) => element.walletId.contains(_wallet.id) &&
|
||||
element.hash.contains(item.hash));
|
||||
|
||||
info.isFrozen = item.isFrozen;
|
||||
info.isSending = item.isSending;
|
||||
info.note = item.note;
|
||||
|
||||
await info.save();
|
||||
await _wallet.updateUnspent();
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
|
||||
|
||||
class UnspentCoinsSwitchItem extends TransactionDetailsListItem {
|
||||
UnspentCoinsSwitchItem({
|
||||
String title,
|
||||
String value,
|
||||
this.switchValue,
|
||||
this.onSwitchValueChange}) : super(title: title, value: value);
|
||||
|
||||
final bool Function() switchValue;
|
||||
final void Function(bool value) onSwitchValueChange;
|
||||
}
|
||||
@@ -64,12 +64,15 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
final wallet = _wallet;
|
||||
|
||||
if (wallet is ElectrumWallet) {
|
||||
await wallet.generateNewAddress();
|
||||
await wallet.walletAddresses.generateNewAddress();
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
await wallet.subaddressList
|
||||
.addSubaddress(accountIndex: wallet.account.id, label: label);
|
||||
await wallet.walletAddresses.subaddressList
|
||||
.addSubaddress(
|
||||
accountIndex: wallet.walletAddresses.account.id,
|
||||
label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
}
|
||||
@@ -77,13 +80,14 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
Future<void> _update() async {
|
||||
final wallet = _wallet;
|
||||
|
||||
if (wallet is BitcoinWallet) {
|
||||
await wallet.updateAddress(_item.address as String);
|
||||
}
|
||||
/*if (wallet is BitcoinWallet) {
|
||||
await wallet.walletAddresses.updateAddress(_item.address as String);
|
||||
await wallet.save();
|
||||
}*/
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
await wallet.subaddressList.setLabelSubaddress(
|
||||
accountIndex: wallet.account.id,
|
||||
await wallet.walletAddresses.subaddressList.setLabelSubaddress(
|
||||
accountIndex: wallet.walletAddresses.account.id,
|
||||
addressIndex: _item.id as int,
|
||||
label: label);
|
||||
await wallet.save();
|
||||
|
||||
@@ -80,7 +80,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
|
||||
@computed
|
||||
WalletAddressListItem get address =>
|
||||
WalletAddressListItem(address: _wallet.address);
|
||||
WalletAddressListItem(address: _wallet.walletAddresses.address);
|
||||
|
||||
@computed
|
||||
PaymentURI get uri {
|
||||
@@ -105,8 +105,10 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
final addressList = ObservableList<ListItem>();
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
final primaryAddress = wallet.subaddressList.subaddresses.first;
|
||||
addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) {
|
||||
final primaryAddress =
|
||||
wallet.walletAddresses.subaddressList.subaddresses.first;
|
||||
addressList.addAll(wallet.walletAddresses.subaddressList.subaddresses
|
||||
.map((subaddress) {
|
||||
final isPrimary = subaddress == primaryAddress;
|
||||
|
||||
return WalletAddressListItem(
|
||||
@@ -118,8 +120,8 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
}
|
||||
|
||||
if (wallet is BitcoinWallet) {
|
||||
final primaryAddress = wallet.addresses.first;
|
||||
final bitcoinAddresses = wallet.addresses.map((addr) {
|
||||
final primaryAddress = wallet.walletAddresses.addresses.first;
|
||||
final bitcoinAddresses = wallet.walletAddresses.addresses.map((addr) {
|
||||
final isPrimary = addr == primaryAddress;
|
||||
|
||||
return WalletAddressListItem(
|
||||
@@ -139,7 +141,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
final wallet = _wallet;
|
||||
|
||||
if (wallet is MoneroWallet) {
|
||||
return wallet.account.label;
|
||||
return wallet.walletAddresses.account.label;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -160,7 +162,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
|
||||
@action
|
||||
void setAddress(WalletAddressListItem address) =>
|
||||
_wallet.address = address.address;
|
||||
_wallet.walletAddresses.address = address.address;
|
||||
|
||||
void _init() {
|
||||
_baseItems = [];
|
||||
@@ -177,7 +179,8 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
final wallet = _wallet;
|
||||
|
||||
if (wallet is ElectrumWallet) {
|
||||
wallet.nextAddress();
|
||||
wallet.walletAddresses.nextAddress();
|
||||
wallet.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class WalletCreationVMBase with Store {
|
||||
dirPath: dirPath);
|
||||
credentials.walletInfo = walletInfo;
|
||||
final wallet = await process(credentials);
|
||||
walletInfo.address = wallet.address;
|
||||
walletInfo.address = wallet.walletAddresses.address;
|
||||
await _walletInfoSource.add(walletInfo);
|
||||
_appStore.changeCurrentWallet(wallet);
|
||||
_appStore.authenticationStore.allowed();
|
||||
|
||||
Reference in New Issue
Block a user