Fixes for update fiat rate after change of current wallet type. Fixes for change amount for btc transactions. Changed displaying of balance for btc wallet. General fixes.

This commit is contained in:
M 2020-12-15 18:29:10 +02:00
parent eede39ee7a
commit 8cb9bd15cd
29 changed files with 340 additions and 276 deletions

View file

@ -354,7 +354,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -371,7 +371,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.9;
MARKETING_VERSION = 4.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -494,7 +494,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -511,7 +511,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.9;
MARKETING_VERSION = 4.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -528,7 +528,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 32J6BB6VUS;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -545,7 +545,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
MARKETING_VERSION = 4.0.9;
MARKETING_VERSION = 4.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View file

@ -1,11 +1,13 @@
import 'dart:convert';
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart';
import 'package:cake_wallet/entities/balance.dart';
class BitcoinBalance extends Balance {
const BitcoinBalance({@required this.confirmed, @required this.unconfirmed}) : super();
const BitcoinBalance({@required this.confirmed, @required this.unconfirmed})
: super(const [BalanceDisplayMode.availableBalance]);
factory BitcoinBalance.fromJSON(String jsonSource) {
if (jsonSource == null) {
@ -30,6 +32,18 @@ class BitcoinBalance extends Balance {
String get totalFormatted => bitcoinAmountToString(amount: total);
@override
String formattedBalance(BalanceDisplayMode mode) {
switch (mode) {
case BalanceDisplayMode.fullBalance:
return totalFormatted;
case BalanceDisplayMode.availableBalance:
return totalFormatted;
default:
return null;
}
}
String toJSON() =>
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed});
}

View file

@ -262,9 +262,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
final utxs = await unptsFutures;
for (final utx in utxs) {
final inAmount = utx.value > totalAmount ? totalAmount : utx.value;
leftAmount = leftAmount - inAmount;
totalInputAmount += inAmount;
leftAmount = leftAmount - utx.value;
totalInputAmount += utx.value;
inputs.add(utx);
if (leftAmount <= 0) {
@ -348,6 +347,11 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
// FIXME: Unimplemented
}
@override
void close() {
}
void _subscribeForUpdates() {
scriptHashes.forEach((sh) async {
await _scripthashesUpdateSubject[sh]?.close();

View file

@ -75,7 +75,7 @@ class ElectrumClient {
try {
final jsoned =
json.decode(utf8.decode(event.toList())) as Map<String, Object>;
print(jsoned);
// print(jsoned);
final method = jsoned['method'];
final id = jsoned['id'] as String;
final result = jsoned['result'];
@ -92,7 +92,9 @@ class ElectrumClient {
}, onError: (Object error) {
print(error.toString());
_setIsConnected(false);
}, onDone: () => _setIsConnected(false));
}, onDone: () {
_setIsConnected(false);
});
keepAlive();
}
@ -103,7 +105,7 @@ class ElectrumClient {
Future<void> ping() async {
try {
// await callWithTimeout(method: 'server.ping');
await callWithTimeout(method: 'server.ping');
_setIsConnected(true);
} on RequestFailedTimeoutException catch (_) {
_setIsConnected(false);

View file

@ -52,4 +52,6 @@ abstract class WalletBase<BalaceType> {
Future<void> save();
Future<void> rescan({int height});
void close();
}

View file

@ -1,3 +1,9 @@
import 'package:cake_wallet/entities/balance_display_mode.dart';
abstract class Balance {
const Balance();
const Balance(this.availableModes);
final List<BalanceDisplayMode> availableModes;
String formattedBalance(BalanceDisplayMode mode);
}

View file

@ -19,5 +19,5 @@ Future<void> loadCurrentWallet() async {
await getIt.get<KeyService>().getWalletPassword(walletName: name);
final _service = getIt.get<WalletService>(param1: type);
final wallet = await _service.openWallet(name, password);
appStore.wallet = wallet;
appStore.changeCurrentWallet(wallet);
}

View file

@ -39,9 +39,9 @@ Future<List<Node>> loadElectrumServerList() async {
Future resetToDefault(Box<Node> nodeSource) async {
final moneroNodes = await loadDefaultNodes();
// final bitcoinElectrumServerList = await loadElectrumServerList();
// final nodes = moneroNodes + bitcoinElectrumServerList;
final bitcoinElectrumServerList = await loadElectrumServerList();
final nodes = moneroNodes + bitcoinElectrumServerList;
await nodeSource.clear();
await nodeSource.addAll(moneroNodes);
await nodeSource.addAll(nodes);
}

View file

@ -83,7 +83,6 @@ void main() async {
)))));
}
}
Future<void> initialSetup(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes,

View file

@ -1,20 +1,42 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/monero/monero_amount_format.dart';
class MoneroBalance {
class MoneroBalance extends Balance {
MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
moneroAmountToString(amount: unlockedBalance);
moneroAmountToString(amount: unlockedBalance),
super(const [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
MoneroBalance.fromString(
{@required this.formattedFullBalance,
@required this.formattedUnlockedBalance})
@required this.formattedUnlockedBalance})
: fullBalance = moneroParseAmount(amount: formattedFullBalance),
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance);
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
super(const [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
final int fullBalance;
final int unlockedBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
}
@override
String formattedBalance(BalanceDisplayMode mode) {
switch (mode) {
case BalanceDisplayMode.fullBalance:
return formattedFullBalance;
case BalanceDisplayMode.availableBalance:
return formattedUnlockedBalance;
default:
return null;
}
}
}

View file

@ -43,7 +43,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
unlockedBalance:
monero_wallet.getUnlockedBalance(accountIndex: account.id));
monero_wallet.getUnlockedBalance(accountIndex: account.id));
subaddressList.update(accountIndex: account.id);
subaddress = subaddressList.subaddresses.first;
address = subaddress.address;
@ -120,6 +120,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
}
}
@override
void close() {
_listener?.stop();
_onAccountChangeReaction?.reaction?.dispose();
@ -315,9 +316,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
}
}
Future<void> _askForUpdateTransactionHistory() async {
await transactionHistory.update();
}
Future<void> _askForUpdateTransactionHistory() async =>
await transactionHistory.update();
int _getFullBalance() =>
monero_wallet.getFullBalance(accountIndex: account.id);
@ -326,13 +326,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
monero_wallet.getUnlockedBalance(accountIndex: account.id);
Future<void> _afterSyncSave() async {
if (_isSavingAfterSync) {
return;
}
_isSavingAfterSync = true;
try {
if (_isSavingAfterSync) {
return;
}
_isSavingAfterSync = true;
final nowTimestamp = DateTime.now().millisecondsSinceEpoch;
final sum = _lastAutosaveTimestamp + _autoAfterSyncSaveInterval;
@ -350,13 +350,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
}
Future<void> _afterNewTransactionSave() async {
if (_isSavingAfterNewTransaction) {
return;
}
_isSavingAfterNewTransaction = true;
try {
if (_isSavingAfterNewTransaction) {
return;
}
_isSavingAfterNewTransaction = true;
await save();
} catch (e) {
print(e.toString());
@ -366,30 +366,38 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
}
void _onNewBlock(int height, int blocksLeft, double ptc) async {
if (walletInfo.isRecovery) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
}
if (blocksLeft < 100) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
syncStatus = SyncedSyncStatus();
await _afterSyncSave();
try {
if (walletInfo.isRecovery) {
await setAsRecovered();
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
}
} else {
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
if (blocksLeft < 100) {
await _askForUpdateTransactionHistory();
_askForUpdateBalance();
accountList.update();
syncStatus = SyncedSyncStatus();
await _afterSyncSave();
if (walletInfo.isRecovery) {
await setAsRecovered();
}
} else {
syncStatus = SyncingSyncStatus(blocksLeft, ptc);
}
} catch (e) {
print(e.toString());
}
}
void _onNewTransaction() {
_askForUpdateTransactionHistory();
_askForUpdateBalance();
Timer(Duration(seconds: 1), () => _afterNewTransactionSave());
try {
_askForUpdateTransactionHistory();
_askForUpdateBalance();
Timer(Duration(seconds: 1), () => _afterNewTransactionSave());
} catch (e) {
print(e.toString());
}
}
}

View file

@ -12,12 +12,13 @@ Future<void> startFiatRateUpdate(AppStore appStore, SettingsStore settingsStore,
return;
}
fiatConversionStore.price = await FiatConversionService.fetchPrice(
appStore.wallet.currency, settingsStore.fiatCurrency);
fiatConversionStore.prices[appStore.wallet.currency] =
await FiatConversionService.fetchPrice(
appStore.wallet.currency, settingsStore.fiatCurrency);
_timer = Timer.periodic(
Duration(seconds: 30),
(_) async => fiatConversionStore.price =
(_) async => fiatConversionStore.prices[appStore.wallet.currency] =
await FiatConversionService.fetchPrice(
appStore.wallet.currency, settingsStore.fiatCurrency));
}

View file

@ -7,12 +7,13 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
ReactionDisposer _onCurrentFiatCurrencyChangeDisposer;
void startCurrentFiatChangeReaction(AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
void startCurrentFiatChangeReaction(AppStore appStore,
SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
_onCurrentFiatCurrencyChangeDisposer?.reaction?.dispose();
_onCurrentFiatCurrencyChangeDisposer = reaction(
(_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async {
(_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async {
final cryptoCurrency = appStore.wallet.currency;
fiatConversionStore.price = await FiatConversionService.fetchPrice(
cryptoCurrency, fiatCurrency);
fiatConversionStore.prices[appStore.wallet.currency] =
await FiatConversionService.fetchPrice(cryptoCurrency, fiatCurrency);
});
}
}

View file

@ -6,10 +6,9 @@ ReactionDisposer _onCurrentNodeChangeReaction;
void startOnCurrentNodeChangeReaction(AppStore appStore) {
_onCurrentNodeChangeReaction?.reaction?.dispose();
_onCurrentNodeChangeReaction =
reaction((_) => appStore.settingsStore.currentNode, (Node node) async {
appStore.settingsStore.nodes.observe((change) async {
try {
await appStore.wallet.connectToNode(node: node);
await appStore.wallet.connectToNode(node: change.newValue);
} catch (e) {
print(e.toString());
}

View file

@ -12,6 +12,7 @@ import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
ReactionDisposer _onCurrentWalletChangeReaction;
ReactionDisposer _onCurrentWalletChangeFiatRateUpdateReaction;
void startCurrentWalletChangeReaction(AppStore appStore,
SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
@ -29,8 +30,16 @@ void startCurrentWalletChangeReaction(AppStore appStore,
await getIt.get<SharedPreferences>().setInt(
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
await wallet.connectToNode(node: node);
} catch (e) {
print(e.toString());
}
});
fiatConversionStore.price = await FiatConversionService.fetchPrice(
_onCurrentWalletChangeFiatRateUpdateReaction =
reaction((_) => appStore.wallet, (WalletBase wallet) async {
try {
fiatConversionStore.prices[wallet.currency] = 0;
fiatConversionStore.prices[wallet.currency] = await FiatConversionService.fetchPrice(
wallet.currency, settingsStore.fiatCurrency);
} catch (e) {
print(e.toString());

View file

@ -11,58 +11,66 @@ class BalancePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
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(),
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.bold,
color: Theme.of(context).indicatorColor,
height: 1),
);
}),
Observer(builder: (_) {
return Text(
dashboardViewModel.balanceViewModel.displayMode.toString(),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context).indicatorColor,
height: 1),
);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return AutoSizeText(dashboardViewModel.balanceViewModel.cryptoBalance,
padding: EdgeInsets.all(24),
child: GestureDetector(
onTapUp: (_) {
if (dashboardViewModel.balanceViewModel.canReverse) {
dashboardViewModel.balanceViewModel.isReversing = false;
}
},
onTapDown: (_) {
if (dashboardViewModel.balanceViewModel.canReverse) {
dashboardViewModel.balanceViewModel.isReversing = true;
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Observer(builder: (_) {
return Text(
dashboardViewModel.balanceViewModel.currency.toString(),
style: TextStyle(
fontSize: 54,
fontSize: 40,
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);
}),
],
),
)
);
);
}),
Observer(builder: (_) {
return Text(
dashboardViewModel.balanceViewModel.displayMode.toString(),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context).indicatorColor,
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);
}),
],
),
));
}
}

View file

@ -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) {

View file

@ -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;
});
},
),
);

View file

@ -204,7 +204,7 @@ class AddressTextField extends StatelessWidget {
onURIScanned(uri);
}
} catch (e) {
print('Error $e');
print(e.toString());
}
}

View file

@ -26,4 +26,10 @@ abstract class AppStoreBase with Store {
SettingsStore settingsStore;
NodeListStore nodeListStore;
@action
void changeCurrentWallet(WalletBase wallet) {
this.wallet?.close();
this.wallet = wallet;
}
}

View file

@ -1,13 +1,13 @@
import 'package:cake_wallet/entities/crypto_currency.dart';
import 'package:mobx/mobx.dart';
part 'fiat_conversion_store.g.dart';
class FiatConversionStore = FiatConversionStoreBase
with _$FiatConversionStore;
class FiatConversionStore = FiatConversionStoreBase with _$FiatConversionStore;
abstract class FiatConversionStoreBase with Store {
FiatConversionStoreBase() : price = 0.0;
FiatConversionStoreBase() : prices = ObservableMap<CryptoCurrency, double>();
@observable
double price;
ObservableMap<CryptoCurrency, double> prices;
}

View file

@ -43,7 +43,6 @@ abstract class SettingsStoreBase with Store {
isDarkTheme = initialDarkTheme;
pinCodeLength = initialPinLength;
languageCode = initialLanguageCode;
currentNode = nodes[WalletType.monero];
this.nodes = ObservableMap<WalletType, Node>.of(nodes);
_sharedPreferences = sharedPreferences;
@ -80,13 +79,14 @@ abstract class SettingsStoreBase with Store {
(int pinLength) => sharedPreferences.setInt(
PreferencesKey.currentPinLength, pinLength));
reaction((_) => currentNode,
(Node node) => _saveCurrentNode(node, WalletType.monero));
reaction(
(_) => languageCode,
(String languageCode) => sharedPreferences.setString(
PreferencesKey.currentLanguageCode, languageCode));
this
.nodes
.observe((change) => _saveCurrentNode(change.newValue, change.key));
}
static const defaultPinLength = 4;
@ -116,9 +116,6 @@ abstract class SettingsStoreBase with Store {
@observable
int pinCodeLength;
@observable
Node currentNode;
@computed
ThemeData get theme => isDarkTheme ? Themes.darkTheme : Themes.lightTheme;

View file

@ -57,7 +57,8 @@ extension MobxBindable<T extends Keyable> on Box<T> {
Filter<T> filter,
}) {
if (initialFire) {
dest.addAll(values);
final res = filter != null ? values.where(filter) : values;
dest.addAll(res);
}
return watch().listen((event) {

View file

@ -15,31 +15,34 @@ part 'balance_view_model.g.dart';
class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel;
abstract class BalanceViewModelBase with Store {
BalanceViewModelBase({
@required this.appStore,
@required this.settingsStore,
@required this.fiatConvertationStore
}) : isReversing = false;
BalanceViewModelBase(
{@required this.appStore,
@required this.settingsStore,
@required this.fiatConvertationStore})
: isReversing = false;
final AppStore appStore;
final SettingsStore settingsStore;
final FiatConversionStore fiatConvertationStore;
bool get canReverse =>
(appStore.wallet.balance.availableModes as List).length > 1;
@observable
bool isReversing;
@computed
double get price => fiatConvertationStore.prices[appStore.wallet.currency];
@computed
BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode;
@computed
BalanceDisplayMode get displayMode => isReversing
? (savedDisplayMode == BalanceDisplayMode.availableBalance
? BalanceDisplayMode.fullBalance
: BalanceDisplayMode.availableBalance)
: savedDisplayMode;
@computed
double get price => fiatConvertationStore.price;
? (savedDisplayMode == BalanceDisplayMode.availableBalance
? BalanceDisplayMode.fullBalance
: BalanceDisplayMode.availableBalance)
: savedDisplayMode;
@computed
String get cryptoBalance {
@ -63,15 +66,11 @@ abstract class BalanceViewModelBase with Store {
final fiatCurrency = settingsStore.fiatCurrency;
var balance = '---';
final totalBalance = _getFiatBalance(
price: price,
cryptoAmount: walletBalance.totalBalance
);
final totalBalance =
_getFiatBalance(price: price, cryptoAmount: walletBalance.totalBalance);
final unlockedBalance = _getFiatBalance(
price: price,
cryptoAmount: walletBalance.unlockedBalance
);
price: price, cryptoAmount: walletBalance.unlockedBalance);
if (displayMode == BalanceDisplayMode.availableBalance) {
balance = fiatCurrency.toString() + ' ' + unlockedBalance ?? '0.00';
@ -89,7 +88,7 @@ abstract class BalanceViewModelBase with Store {
final _wallet = appStore.wallet;
if (_wallet is MoneroWallet) {
return WalletBalance(
return WalletBalance(
unlockedBalance: _wallet.balance.formattedUnlockedBalance,
totalBalance: _wallet.balance.formattedFullBalance);
}
@ -113,4 +112,4 @@ abstract class BalanceViewModelBase with Store {
return calculateFiatAmount(price: price, cryptoAmount: cryptoAmount);
}
}
}

View file

@ -13,16 +13,18 @@ part 'node_list_view_model.g.dart';
class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
abstract class NodeListViewModelBase with Store {
NodeListViewModelBase(this._nodeSource, this._wallet, this.settingsStore)
NodeListViewModelBase(this._nodeSource, this.wallet, this.settingsStore)
: nodes = ObservableList<Node>() {
_nodeSource.bindToList(nodes,
filter: (Node val) => val?.type == _wallet.type, initialFire: true);
filter: (Node val) => val?.type == wallet.type, initialFire: true);
}
@computed
Node get currentNode => settingsStore.nodes[wallet.type];
final ObservableList<Node> nodes;
final SettingsStore settingsStore;
final WalletBase _wallet;
final WalletBase wallet;
final Box<Node> _nodeSource;
Future<void> reset() async {
@ -30,14 +32,12 @@ abstract class NodeListViewModelBase with Store {
Node node;
switch (_wallet.type) {
switch (wallet.type) {
case WalletType.bitcoin:
node = getBitcoinDefaultElectrumServer(nodes: _nodeSource);
break;
case WalletType.monero:
node = getMoneroDefaultNode(
nodes: _nodeSource,
);
node = getMoneroDefaultNode(nodes: _nodeSource);
break;
default:
break;
@ -50,5 +50,5 @@ abstract class NodeListViewModelBase with Store {
Future<void> delete(Node node) async => node.delete();
Future<void> setAsCurrent(Node node) async =>
settingsStore.currentNode = node;
settingsStore.nodes[wallet.type] = node;
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:hive/hive.dart';
import 'package:intl/intl.dart';
@ -77,19 +78,9 @@ abstract class SendViewModelBase with Store {
PendingTransaction pendingTransaction;
@computed
String get balance {
String balance = '0.0';
if (_wallet is MoneroWallet) {
balance = _wallet.balance.formattedUnlockedBalance as String ?? '';
}
if (_wallet is BitcoinWallet) {
balance = _wallet.balance.confirmedFormatted as String ?? '';
}
return balance;
}
String get balance =>
_wallet.balance.formattedBalance(BalanceDisplayMode.availableBalance)
as String ?? '0.0';
@computed
bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
@ -176,7 +167,7 @@ abstract class SendViewModelBase with Store {
void _updateFiatAmount() {
try {
final fiat = calculateFiatAmount(
price: _fiatConversationStore.price,
price: _fiatConversationStore.prices[_wallet.currency],
cryptoAmount: cryptoAmount.replaceAll(',', '.'));
if (fiatAmount != fiat) {
fiatAmount = fiat;
@ -190,7 +181,7 @@ abstract class SendViewModelBase with Store {
void _updateCryptoAmount() {
try {
final crypto = double.parse(fiatAmount.replaceAll(',', '.')) /
_fiatConversationStore.price;
_fiatConversationStore.prices[_wallet.currency];
final cryptoAmountTmp = _cryptoNumberFormat.format(crypto);
if (cryptoAmount != cryptoAmountTmp) {

View file

@ -35,12 +35,13 @@ abstract class SettingsViewModelBase with Store {
(PackageInfo packageInfo) => currentVersion = packageInfo.version);
sections = [
[
PickerListItem(
title: S.current.settings_display_balance_as,
items: BalanceDisplayMode.all,
selectedItem: () => balanceDisplayMode,
onItemSelected: (BalanceDisplayMode mode) =>
_settingsStore.balanceDisplayMode = mode),
if ((wallet.balance.availableModes as List).length > 1)
PickerListItem(
title: S.current.settings_display_balance_as,
items: BalanceDisplayMode.all,
selectedItem: () => balanceDisplayMode,
onItemSelected: (BalanceDisplayMode mode) =>
_settingsStore.balanceDisplayMode = mode),
PickerListItem(
title: S.current.settings_currency,
items: FiatCurrency.all,

View file

@ -51,7 +51,7 @@ abstract class WalletCreationVMBase with Store {
credentials.walletInfo = walletInfo;
final wallet = await process(credentials);
await _walletInfoSource.add(walletInfo);
_appStore.wallet = wallet;
_appStore.changeCurrentWallet(wallet);
_appStore.authenticationStore.allowed();
state = ExecutedSuccessfullyState();
} catch (e) {

View file

@ -32,7 +32,8 @@ abstract class WalletListViewModelBase with Store {
final password =
await _keyService.getWalletPassword(walletName: wallet.name);
final walletService = getIt.get<WalletService>(param1: wallet.type);
_appStore.wallet = await walletService.openWallet(wallet.name, password);
final loadedWallet = await walletService.openWallet(wallet.name, password);
_appStore.changeCurrentWallet(loadedWallet);
_updateList();
}