import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/balance.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; import 'package:flutter/cupertino.dart'; import 'package:mobx/mobx.dart'; part 'balance_view_model.g.dart'; class BalanceRecord { const BalanceRecord({this.availableBalance, this.additionalBalance, this.fiatAvailableBalance, this.fiatAdditionalBalance, this.asset, this.formattedAssetTitle}); final String fiatAdditionalBalance; final String fiatAvailableBalance; final String additionalBalance; final String availableBalance; final CryptoCurrency asset; final String formattedAssetTitle; } class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel; abstract class BalanceViewModelBase with Store { BalanceViewModelBase( {@required this.appStore, @required this.settingsStore, @required this.fiatConvertationStore}) { isReversing = false; wallet ??= appStore.wallet; reaction((_) => appStore.wallet, _onWalletChange); } final AppStore appStore; final SettingsStore settingsStore; final FiatConversionStore fiatConvertationStore; bool get canReverse => false; @observable bool isReversing; @observable WalletBase, TransactionInfo> wallet; @computed double get price => fiatConvertationStore.prices[appStore.wallet.currency]; @computed BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode; @computed String get asset { final typeFormatted = walletTypeToString(appStore.wallet.type); switch(wallet.type) { case WalletType.haven: return '$typeFormatted Assets'; default: return typeFormatted; } } @computed BalanceDisplayMode get displayMode { if (isReversing) { if (savedDisplayMode == BalanceDisplayMode.hiddenBalance) { return BalanceDisplayMode.displayableBalance; } else { return BalanceDisplayMode.hiddenBalance; } } return savedDisplayMode; } @computed String get availableBalanceLabel { switch(wallet.type) { case WalletType.monero: case WalletType.haven: return S.current.xmr_available_balance; default: return S.current.confirmed; } } @computed String get additionalBalanceLabel { switch(wallet.type) { case WalletType.monero: case WalletType.haven: return S.current.xmr_full_balance; default: return S.current.unconfirmed; } } @computed bool get hasMultiBalance => appStore.wallet.type == WalletType.haven; @computed String get availableBalance { final walletBalance = _walletBalance; if (displayMode == BalanceDisplayMode.hiddenBalance) { return '---'; } return walletBalance.formattedAvailableBalance; } @computed String get additionalBalance { final walletBalance = _walletBalance; if (displayMode == BalanceDisplayMode.hiddenBalance) { return '---'; } return walletBalance.formattedAdditionalBalance; } @computed String get availableFiatBalance { final walletBalance = _walletBalance; final fiatCurrency = settingsStore.fiatCurrency; if (displayMode == BalanceDisplayMode.hiddenBalance) { return '---'; } return _getFiatBalance( price: price, cryptoAmount: walletBalance.formattedAvailableBalance) + ' ' + fiatCurrency.toString(); } @computed String get additionalFiatBalance { final walletBalance = _walletBalance; final fiatCurrency = settingsStore.fiatCurrency; if (displayMode == BalanceDisplayMode.hiddenBalance) { return '---'; } return _getFiatBalance( price: price, cryptoAmount: walletBalance.formattedAdditionalBalance) + ' ' + fiatCurrency.toString(); } @computed Map get balances { return wallet.balance.map((key, value) { if (displayMode == BalanceDisplayMode.hiddenBalance) { return MapEntry(key, BalanceRecord( availableBalance: '---', additionalBalance: '---', fiatAdditionalBalance: '---', fiatAvailableBalance: '---', asset: key, formattedAssetTitle: _formatterAsset(key))); } final fiatCurrency = settingsStore.fiatCurrency; final additionalFiatBalance = fiatCurrency.toString() + ' ' + _getFiatBalance( price: fiatConvertationStore.prices[key], cryptoAmount: value.formattedAdditionalBalance); final availableFiatBalance = fiatCurrency.toString() + ' ' + _getFiatBalance( price: fiatConvertationStore.prices[key], cryptoAmount: value.formattedAvailableBalance); return MapEntry(key, BalanceRecord( availableBalance: value.formattedAvailableBalance, additionalBalance: value.formattedAdditionalBalance, fiatAdditionalBalance: additionalFiatBalance, fiatAvailableBalance: availableFiatBalance, asset: key, formattedAssetTitle: _formatterAsset(key))); }); } @computed List get formattedBalances { final balance = balances.values.toList(); balance.sort((BalanceRecord a, BalanceRecord b) { if (b.asset == CryptoCurrency.xhv) { return 1; } if (b.asset == CryptoCurrency.xusd) { if (a.asset == CryptoCurrency.xhv) { return -1; } return 1; } if (b.asset == CryptoCurrency.xbtc) { return 1; } if (b.asset == CryptoCurrency.xeur) { return 1; } return 0; }); return balance; } @computed Balance get _walletBalance => wallet.balance[wallet.currency]; @computed CryptoCurrency get currency => appStore.wallet.currency; ReactionDisposer _onCurrentWalletChangeReaction; @action void _onWalletChange( WalletBase, TransactionInfo> wallet) { this.wallet = wallet; _onCurrentWalletChangeReaction?.reaction?.dispose(); } String _getFiatBalance({double price, String cryptoAmount}) { if (cryptoAmount == null) { return '0.00'; } return calculateFiatAmount(price: price, cryptoAmount: cryptoAmount); } String _formatterAsset(CryptoCurrency asset) { switch (wallet.type) { case WalletType.haven: final assetStringified = asset.toString(); if (asset != CryptoCurrency.xhv && assetStringified[0].toUpperCase() == 'X') { return assetStringified.replaceFirst('X', 'x'); } return asset.toString(); default: return asset.toString(); } } }