Another beautiful day changes

This commit is contained in:
M 2021-01-11 19:15:27 +02:00
parent 41b436d9d4
commit 9db6e233c7
24 changed files with 406 additions and 265 deletions

View file

@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:quiver/core.dart';
class BitcoinAddressRecord {
BitcoinAddressRecord(this.address, {this.index});
@ -10,8 +11,15 @@ class BitcoinAddressRecord {
index: decoded['index'] as int);
}
@override
bool operator ==(Object o) =>
o is BitcoinAddressRecord && address == o.address;
final String address;
int index;
@override
int get hashCode => address.hashCode;
String toJSON() => json.encode({'address': address, 'index': index});
}

View file

@ -1,16 +1,12 @@
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 [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
: super(confirmed, unconfirmed);
factory BitcoinBalance.fromJSON(String jsonSource) {
if (jsonSource == null) {
@ -27,31 +23,12 @@ class BitcoinBalance extends Balance {
final int confirmed;
final int unconfirmed;
int get total => confirmed + unconfirmed;
int get availableBalance =>
(confirmed ?? 0) + (unconfirmed < 0 ? unconfirmed : 0);
String get confirmedFormatted => bitcoinAmountToString(amount: confirmed);
String get unconfirmedFormatted => bitcoinAmountToString(amount: unconfirmed);
String get totalFormatted => bitcoinAmountToString(amount: total);
String get availableBalanceFormatted =>
bitcoinAmountToString(amount: availableBalance);
@override
String get formattedAvailableBalance => bitcoinAmountToString(amount: confirmed);
@override
String formattedBalance(BalanceDisplayMode mode) {
switch (mode) {
case BalanceDisplayMode.fullBalance:
return totalFormatted;
case BalanceDisplayMode.availableBalance:
return availableBalanceFormatted;
default:
return null;
}
}
String get formattedAdditionalBalance =>
bitcoinAmountToString(amount: unconfirmed);
String toJSON() =>
json.encode({'confirmed': confirmed, 'unconfirmed': unconfirmed});

View file

@ -47,7 +47,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
network: bitcoin.bitcoin)
.derivePath("m/0'/0"),
addresses = initialAddresses != null
? ObservableList<BitcoinAddressRecord>.of(initialAddresses)
? ObservableList<BitcoinAddressRecord>.of(initialAddresses.toSet())
: ObservableList<BitcoinAddressRecord>(),
syncStatus = NotConnectedSyncStatus(),
_password = password,
@ -267,14 +267,14 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
final fee = feeAmountForPriority(transactionCredentials.priority);
final amount = transactionCredentials.amount != null
? stringDoubleToBitcoinAmount(transactionCredentials.amount)
: balance.availableBalance - fee;
: balance.confirmed - fee;
final totalAmount = amount + fee;
final txb = bitcoin.TransactionBuilder(network: bitcoin.bitcoin);
final changeAddress = address;
var leftAmount = totalAmount;
var totalInputAmount = 0;
if (totalAmount > balance.availableBalance) {
if (totalAmount > balance.confirmed) {
throw BitcoinTransactionWrongBalanceException();
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/entities/wallet_info.dart';
import 'package:cake_wallet/core/pending_transaction.dart';
@ -9,7 +10,7 @@ import 'package:cake_wallet/entities/sync_status.dart';
import 'package:cake_wallet/entities/node.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
abstract class WalletBase<BalaceType> {
abstract class WalletBase<BalaceType extends Balance> {
WalletBase(this.walletInfo);
static String idFor(String name, WalletType type) =>

View file

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

View file

@ -7,15 +7,16 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
: super(title: title, raw: raw);
static const all = [
BalanceDisplayMode.fullBalance,
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.hiddenBalance
BalanceDisplayMode.hiddenBalance,
BalanceDisplayMode.displayableBalance,
];
static const fullBalance = BalanceDisplayMode(raw: 0, title: 'Full Balance');
static const availableBalance =
BalanceDisplayMode(raw: 1, title: 'Available Balance');
static const hiddenBalance =
BalanceDisplayMode(raw: 2, title: 'Hidden Balance');
static const displayableBalance =
BalanceDisplayMode(raw: 3, title: 'Displayable Balance');
static BalanceDisplayMode deserialize({int raw}) {
switch (raw) {
@ -25,6 +26,8 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
return availableBalance;
case 2:
return hiddenBalance;
case 3:
return displayableBalance;
default:
return null;
}
@ -39,6 +42,8 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
return S.current.xmr_available_balance;
case BalanceDisplayMode.hiddenBalance:
return S.current.xmr_hidden;
case BalanceDisplayMode.displayableBalance:
return S.current.displayable;
default:
return '';
}

View file

@ -80,6 +80,11 @@ Future defaultSettingsMigration(
case 5:
await addAddressesForMoneroWallets(walletInfoSource);
break;
case 6:
await updateDisplayModes(sharedPreferences);
break;
default:
break;
}
@ -220,3 +225,10 @@ Future<void> addAddressesForMoneroWallets(
}
});
}
Future<void> updateDisplayModes(SharedPreferences sharedPreferences) async {
final currentBalanceDisplayMode =
sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey);
final balanceDisplayMode = currentBalanceDisplayMode < 2 ? 3 : 2;
await sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
}

View file

@ -374,6 +374,10 @@ class S implements WidgetsLocalizations {
String wallet_list_failed_to_remove(String wallet_name, String error) => "Failed to remove ${wallet_name} wallet. ${error}";
String wallet_list_loading_wallet(String wallet_name) => "Loading ${wallet_name} wallet";
String wallet_list_removing_wallet(String wallet_name) => "Removing ${wallet_name} wallet";
String get exchange_incorrect_current_wallet_for_xmr => "If you want to exchange XMR from your Cake Wallet Monero balance, please switch to your Monero wallet first.";
String get confirmed => 'Confirmed';
String get unconfirmed => 'Unconfirmed';
String get displayable => 'Displayable';
}
class $de extends S {
@ -1088,6 +1092,14 @@ class $de extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Laden fehlgeschlagen ${wallet_name} Wallet. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Entfernen ${wallet_name} Wallet";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Wenn Sie XMR von Ihrem Cake Wallet Monero-Guthaben austauschen möchten, wechseln Sie bitte zuerst zu Ihrem Monero Wallet.";
@override
String get confirmed => 'Bestätigt';
@override
String get unconfirmed => 'Unbestätigt';
@override
String get displayable => 'Anzeigebar';
}
class $hi extends S {
@ -1802,6 +1814,14 @@ class $hi extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "लोड करने में विफल ${wallet_name} बटुआ. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "निकाला जा रहा है ${wallet_name} बटुआ";
@override
String get exchange_incorrect_current_wallet_for_xmr => "यदि आप अपने केक वॉलेट मोनेरो बैलेंस से एक्सएमआर का आदान-प्रदान करना चाहते हैं, तो कृपया अपने मोनेरो वॉलेट में जाएं।";
@override
String get confirmed => 'की पुष्टि की';
@override
String get unconfirmed => 'अपुष्ट';
@override
String get displayable => 'प्रदर्शन योग्य';
}
class $ru extends S {
@ -2516,6 +2536,14 @@ class $ru extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Ошибка при загрузке ${wallet_name} кошелька. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Удаление ${wallet_name} кошелька";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Если вы хотите обменять XMR со своего баланса Monero в Cake Wallet, сначала переключитесь на свой кошелек Monero.";
@override
String get confirmed => 'Подтверждено';
@override
String get unconfirmed => 'Неподтвержденный';
@override
String get displayable => 'Отображаемый';
}
class $ko extends S {
@ -3230,6 +3258,14 @@ class $ko extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "불러 오지 못했습니다 ${wallet_name} 지갑. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "풀이 ${wallet_name} 지갑";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Cake Wallet Monero 잔액에서 XMR을 교환하려면 먼저 Monero 지갑으로 전환하십시오.";
@override
String get confirmed => '확인';
@override
String get unconfirmed => '미확인';
@override
String get displayable => '표시 가능';
}
class $pt extends S {
@ -3944,6 +3980,14 @@ class $pt extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Falha ao abrir a carteira ${wallet_name}. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Removendo a carteira ${wallet_name}";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Se você deseja trocar o XMR de seu saldo da Carteira Monero Cake, troque primeiro para sua carteira Monero.";
@override
String get confirmed => 'Confirmada';
@override
String get unconfirmed => 'Não confirmado';
@override
String get displayable => 'Exibível';
}
class $uk extends S {
@ -4658,6 +4702,14 @@ class $uk extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Помилка при завантаженні ${wallet_name} гаманця. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Видалення ${wallet_name} гаманця";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Якщо ви хочете обміняти XMR із вашого балансу Cake Wallet Monero, спочатку перейдіть на свій гаманець Monero.";
@override
String get confirmed => 'Підтверджено';
@override
String get unconfirmed => 'Непідтверджений';
@override
String get displayable => 'Відображуваний';
}
class $ja extends S {
@ -5372,6 +5424,14 @@ class $ja extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "読み込みに失敗しました ${wallet_name} 財布. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "取りはずし ${wallet_name} 財布";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Cake Wallet Moneroの残高からXMRを交換する場合は、最初にMoneroウォレットに切り替えてください。";
@override
String get confirmed => '確認済み';
@override
String get unconfirmed => '未確認';
@override
String get displayable => '表示可能';
}
class $en extends S {
@ -6090,6 +6150,14 @@ class $pl extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Nie udało się załadować ${wallet_name} portfel. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Usuwanie ${wallet_name} portfel";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Jeśli chcesz wymienić XMR z salda Cake Wallet Monero, najpierw przełącz się na portfel Monero.";
@override
String get confirmed => 'Potwierdzony';
@override
String get unconfirmed => 'niepotwierdzony';
@override
String get displayable => 'Wyświetlane';
}
class $es extends S {
@ -6804,6 +6872,14 @@ class $es extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "No se pudo cargar ${wallet_name} la billetera. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Retirar ${wallet_name} billetera";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Si desea intercambiar XMR de su saldo de Cake Wallet Monero, primero cambie a su billetera Monero.";
@override
String get confirmed => 'Confirmada';
@override
String get unconfirmed => 'inconfirmado';
@override
String get displayable => 'Visualizable';
}
class $nl extends S {
@ -7518,6 +7594,14 @@ class $nl extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "Laden mislukt ${wallet_name} portemonnee. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "Verwijderen ${wallet_name} portemonnee";
@override
String get exchange_incorrect_current_wallet_for_xmr => "Als u XMR wilt omwisselen van uw Cake Wallet Monero-saldo, moet u eerst overschakelen naar uw Monero-portemonnee.";
@override
String get confirmed => 'bevestigd';
@override
String get unconfirmed => 'niet bevestigd';
@override
String get displayable => 'Weer te geven';
}
class $zh extends S {
@ -8232,6 +8316,14 @@ class $zh extends S {
String wallet_list_failed_to_load(String wallet_name, String error) => "加载失败 ${wallet_name} 钱包. ${error}";
@override
String wallet_list_removing_wallet(String wallet_name) => "拆下 ${wallet_name} 钱包";
@override
String get exchange_incorrect_current_wallet_for_xmr => "如果要从Cake Wallet Monero余额中兑换XMR请先切换到Monero钱包。";
@override
String get confirmed => '已确认';
@override
String get unconfirmed => '未经证实';
@override
String get displayable => '可显示';
}
class GeneratedLocalizationsDelegate extends LocalizationsDelegate<S> {

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -54,11 +55,11 @@ void main() async {
TransactionDescription.boxName,
encryptionKey: transactionDescriptionsBoxKey);
final trades =
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
await Hive.openBox<Trade>(Trade.boxName, encryptionKey: tradesBoxKey);
final walletInfoSource = await Hive.openBox<WalletInfo>(WalletInfo.boxName);
final templates = await Hive.openBox<Template>(Template.boxName);
final exchangeTemplates =
await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
await initialSetup(
sharedPreferences: await SharedPreferences.getInstance(),
nodes: nodes,
@ -77,24 +78,24 @@ void main() async {
home: Scaffold(
body: Container(
margin:
EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
child: Text(
'Error:\n${e.toString()}',
style: TextStyle(fontSize: 22),
)))));
}
}
Future<void> initialSetup(
{@required SharedPreferences sharedPreferences,
@required Box<Node> nodes,
@required Box<WalletInfo> walletInfoSource,
@required Box<Contact> contactSource,
@required Box<Trade> tradesSource,
// @required FiatConvertationService fiatConvertationService,
@required Box<Template> templates,
@required Box<ExchangeTemplate> exchangeTemplates,
@required Box<TransactionDescription> transactionDescriptions,
int initialMigrationVersion = 5}) async {
Future<void> initialSetup({@required SharedPreferences sharedPreferences,
@required Box<Node> nodes,
@required Box<WalletInfo> walletInfoSource,
@required Box<Contact> contactSource,
@required Box<Trade> tradesSource,
// @required FiatConvertationService fiatConvertationService,
@required Box<Template> templates,
@required Box<ExchangeTemplate> exchangeTemplates,
@required Box<TransactionDescription> transactionDescriptions,
int initialMigrationVersion = 6}) async {
await defaultSettingsMigration(
version: initialMigrationVersion,
sharedPreferences: sharedPreferences,
@ -122,7 +123,9 @@ class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
final settingsStore = getIt.get<AppStore>().settingsStore;
final settingsStore = getIt
.get<AppStore>()
.settingsStore;
final statusBarColor = Colors.transparent;
final authenticationStore = getIt.get<AuthenticationStore>();
final initialRoute = authenticationStore.state == AuthenticationState.denied
@ -132,11 +135,11 @@ class App extends StatelessWidget {
return Observer(builder: (BuildContext context) {
final currentTheme = settingsStore.currentTheme;
final statusBarBrightness = currentTheme.type == ThemeType.dark
? Brightness.light
: Brightness.dark;
? Brightness.light
: Brightness.dark;
final statusBarIconBrightness = currentTheme.type == ThemeType.dark
? Brightness.light
: Brightness.dark;
? Brightness.light
: Brightness.dark;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: statusBarColor,
statusBarBrightness: statusBarBrightness,

View file

@ -8,20 +8,15 @@ class MoneroBalance extends Balance {
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
moneroAmountToString(amount: unlockedBalance),
super(const [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
super(unlockedBalance, fullBalance);
MoneroBalance.fromString(
{@required this.formattedFullBalance,
@required this.formattedUnlockedBalance})
: fullBalance = moneroParseAmount(amount: formattedFullBalance),
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
super(const [
BalanceDisplayMode.availableBalance,
BalanceDisplayMode.fullBalance
]);
super(moneroParseAmount(amount: formattedUnlockedBalance),
moneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
@ -29,14 +24,8 @@ class MoneroBalance extends Balance {
final String formattedUnlockedBalance;
@override
String formattedBalance(BalanceDisplayMode mode) {
switch (mode) {
case BalanceDisplayMode.fullBalance:
return formattedFullBalance;
case BalanceDisplayMode.availableBalance:
return formattedUnlockedBalance;
default:
return null;
}
}
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/di.dart';
@ -19,7 +20,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
_onCurrentWalletChangeReaction?.reaction?.dispose();
_onCurrentWalletChangeReaction =
reaction((_) => appStore.wallet, (WalletBase wallet) async {
reaction((_) => appStore.wallet, (WalletBase<Balance> wallet) async {
try {
final node = settingsStore.getCurrentNode(wallet.type);
startWalletSyncStatusChangeReaction(wallet);
@ -44,7 +45,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
});
_onCurrentWalletChangeFiatRateUpdateReaction =
reaction((_) => appStore.wallet, (WalletBase wallet) async {
reaction((_) => appStore.wallet, (WalletBase<Balance> wallet) async {
try {
fiatConversionStore.prices[wallet.currency] = 0;
fiatConversionStore.prices[wallet.currency] =

View file

@ -1,10 +1,11 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/sync_status.dart';
ReactionDisposer _onWalletSyncStatusChangeReaction;
void startWalletSyncStatusChangeReaction(WalletBase wallet) {
void startWalletSyncStatusChangeReaction(WalletBase<Balance> wallet) {
_onWalletSyncStatusChangeReaction?.reaction?.dispose();
_onWalletSyncStatusChangeReaction =
reaction((_) => wallet.syncStatus, (SyncStatus status) async {

View file

@ -19,6 +19,9 @@ class AddressPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return KeyboardActions(
autoScroll: false,
disableScroll: true,
tapOutsideToDismiss: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/crypto_currency.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -10,77 +11,87 @@ class BalancePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapUp: (_) {
if (dashboardViewModel.balanceViewModel.canReverse) {
dashboardViewModel.balanceViewModel.isReversing = false;
}
},
onTapDown: (_) {
if (dashboardViewModel.balanceViewModel.canReverse) {
dashboardViewModel.balanceViewModel.isReversing = true;
}
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.all(24),
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)
.accentTextTheme
.display2
.backgroundColor,
height: 1),
);
}),
Observer(builder: (_) {
return Text(
dashboardViewModel.balanceViewModel.displayMode.toString(),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
height: 1),
);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return AutoSizeText(
dashboardViewModel.balanceViewModel.cryptoBalance,
style: TextStyle(
fontSize: 54,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
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);
}),
],
),
));
return Container(
color: Colors.transparent,
padding: EdgeInsets.all(24),
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)
.accentTextTheme
.display2
.backgroundColor,
height: 1),
);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return Text(
'${dashboardViewModel.balanceViewModel.availableBalanceLabel} (${dashboardViewModel.balanceViewModel.availableFiatBalance.toString()})',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
height: 1),
);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return AutoSizeText(
dashboardViewModel.balanceViewModel.availableBalance,
style: TextStyle(
fontSize: 54,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
height: 1),
maxLines: 1,
textAlign: TextAlign.center);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return Text(
'${dashboardViewModel.balanceViewModel.additionalBalanceLabel} (${dashboardViewModel.balanceViewModel.additionalFiatBalance.toString()})',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
height: 1),
);
}),
SizedBox(height: 10),
Observer(builder: (_) {
return AutoSizeText(
dashboardViewModel.balanceViewModel.additionalBalance
.toString(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
height: 1),
maxLines: 1,
textAlign: TextAlign.center);
}),
],
),
);
}
}

View file

@ -1,5 +1,6 @@
import 'dart:ui';
import 'package:cake_wallet/entities/sync_status.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@ -183,9 +184,30 @@ class ExchangePage extends BasePage {
isAmountEstimated: false,
hasRefundAddress: true,
currencies: CryptoCurrency.all,
onCurrencySelected: (currency) =>
exchangeViewModel.changeDepositCurrency(
currency: currency),
onCurrencySelected: (currency) {
// FIXME: need to move it into view model
if (currency == CryptoCurrency.xmr &&
exchangeViewModel.wallet.type ==
WalletType.bitcoin) {
showPopUp<void>(
context: context,
builder: (dialogContext) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: S
.of(context)
.exchange_incorrect_current_wallet_for_xmr,
buttonText: S.of(context).ok,
buttonAction: () =>
Navigator.of(dialogContext)
.pop());
});
return;
}
exchangeViewModel.changeDepositCurrency(
currency: currency);
},
imageArrow: arrowBottomPurple,
currencyButtonColor: Colors.transparent,
addressButtonsColor:

View file

@ -235,33 +235,40 @@ class ExchangeCardState extends State<ExchangeCard> {
)),
Padding(
padding: EdgeInsets.only(top: 5),
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: <
Widget>[
_min != null
? Text(
S.of(context).min_value(_min, _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
)
: Offstage(),
_min != null ? SizedBox(width: 10) : Offstage(),
_max != null
? Text(
S.of(context).max_value(_max, _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor))
: Offstage(),
]),
child: Container(
height: 15,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
_min != null
? Text(
S
.of(context)
.min_value(_min, _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor),
)
: Offstage(),
_min != null ? SizedBox(width: 10) : Offstage(),
_max != null
? Text(
S
.of(context)
.max_value(_max, _selectedCurrency.toString()),
style: TextStyle(
fontSize: 10,
height: 1.2,
color: Theme.of(context)
.accentTextTheme
.display4
.decorationColor))
: Offstage(),
])),
),
!_isAddressEditable && widget.hasRefundAddress
? Padding(

View file

@ -54,7 +54,7 @@ class QRWidget extends StatelessWidget {
]),
isAmountFieldShow
? Padding(
padding: EdgeInsets.only(top: 60),
padding: EdgeInsets.only(top: 40),
child: Row(
children: <Widget>[
Expanded(

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/store/wallet_list_store.dart';
@ -19,7 +20,7 @@ abstract class AppStoreBase with Store {
AuthenticationStore authenticationStore;
@observable
WalletBase wallet;
WalletBase<Balance> wallet;
WalletListStore walletList;

View file

@ -1,14 +1,13 @@
import 'package:cake_wallet/bitcoin/bitcoin_balance.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/crypto_currency.dart';
import 'package:cake_wallet/monero/monero_balance.dart';
import 'package:cake_wallet/entities/wallet_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/monero/monero_wallet.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/view_model/dashboard/wallet_balance.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:flutter/cupertino.dart';
@ -51,8 +50,7 @@ abstract class BalanceViewModelBase with Store {
final SettingsStore settingsStore;
final FiatConversionStore fiatConvertationStore;
bool get canReverse =>
(appStore.wallet.balance.availableModes as List).length > 1;
bool get canReverse => false;
@observable
bool isReversing;
@ -61,7 +59,7 @@ abstract class BalanceViewModelBase with Store {
Balance balance;
@observable
WalletBase wallet;
WalletBase<Balance> wallet;
@computed
double get price => fiatConvertationStore.prices[appStore.wallet.currency];
@ -77,63 +75,80 @@ abstract class BalanceViewModelBase with Store {
: savedDisplayMode;
@computed
String get cryptoBalance {
final walletBalance = _walletBalance;
var _balance = '---';
if (displayMode == BalanceDisplayMode.availableBalance) {
_balance = walletBalance.unlockedBalance ?? '0.0';
String get availableBalanceLabel {
if (wallet.type == WalletType.monero) {
return S.current.xmr_available_balance;
}
if (displayMode == BalanceDisplayMode.fullBalance) {
_balance = walletBalance.totalBalance ?? '0.0';
}
return _balance;
return S.current.confirmed;
}
@computed
String get fiatBalance {
String get additionalBalanceLabel {
if (wallet.type == WalletType.monero) {
return S.current.xmr_full_balance;
}
return S.current.unconfirmed;
}
@computed
String get availableBalance {
final walletBalance = _walletBalance;
if (settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
return walletBalance.formattedAvailableBalance;
}
@computed
String get additionalBalance {
final walletBalance = _walletBalance;
if (settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
return walletBalance.formattedAdditionalBalance;
}
@computed
String get availableFiatBalance {
final walletBalance = _walletBalance;
final fiatCurrency = settingsStore.fiatCurrency;
var _balance = '---';
final totalBalance =
_getFiatBalance(price: price, cryptoAmount: walletBalance.totalBalance);
final unlockedBalance = _getFiatBalance(
price: price, cryptoAmount: walletBalance.unlockedBalance);
if (displayMode == BalanceDisplayMode.availableBalance) {
_balance = fiatCurrency.toString() + ' ' + unlockedBalance ?? '0.00';
if (settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
if (displayMode == BalanceDisplayMode.fullBalance) {
_balance = fiatCurrency.toString() + ' ' + totalBalance ?? '0.00';
}
return _balance;
return fiatCurrency.toString() +
' ' +
_getFiatBalance(
price: price,
cryptoAmount: walletBalance.formattedAvailableBalance);
}
@computed
WalletBalance get _walletBalance {
final _balance = balance;
String get additionalFiatBalance {
final walletBalance = _walletBalance;
final fiatCurrency = settingsStore.fiatCurrency;
if (_balance is MoneroBalance) {
return WalletBalance(
unlockedBalance: _balance.formattedUnlockedBalance,
totalBalance: _balance.formattedFullBalance);
if (settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance) {
return '---';
}
if (_balance is BitcoinBalance) {
return WalletBalance(
unlockedBalance: _balance.availableBalanceFormatted,
totalBalance: _balance.totalFormatted);
}
return null;
return fiatCurrency.toString() +
' ' +
_getFiatBalance(
price: price,
cryptoAmount: walletBalance.formattedAdditionalBalance);
}
@computed
Balance get _walletBalance => wallet.balance;
@computed
CryptoCurrency get currency => appStore.wallet.currency;
@ -141,24 +156,14 @@ abstract class BalanceViewModelBase with Store {
ReactionDisposer _reaction;
@action
void _onWalletChange(WalletBase wallet) {
void _onWalletChange(WalletBase<Balance> wallet) {
this.wallet = wallet;
if (wallet is MoneroWallet) {
balance = wallet.balance;
}
if (wallet is BitcoinWallet) {
balance = wallet.balance;
}
balance = wallet.balance;
_onCurrentWalletChangeReaction?.reaction?.dispose();
_onCurrentWalletChangeReaction =
reaction<void>((_) => wallet.balance, (dynamic balance) {
if (balance is Balance) {
this.balance = balance;
}
});
_onCurrentWalletChangeReaction = reaction<Balance>(
(_) => wallet.balance, (Balance balance) => this.balance = balance);
}
String _getFiatBalance({double price, String cryptoAmount}) {

View file

@ -1,5 +1,6 @@
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/entities/transaction_history.dart';
import 'package:cake_wallet/monero/account.dart';
import 'package:cake_wallet/monero/monero_balance.dart';
@ -184,7 +185,7 @@ abstract class DashboardViewModelBase with Store {
}
@observable
WalletBase wallet;
WalletBase<Balance> wallet;
bool get hasRescan => wallet.type == WalletType.monero;
@ -212,7 +213,7 @@ abstract class DashboardViewModelBase with Store {
}
@action
void _onWalletChange(WalletBase wallet) {
void _onWalletChange(WalletBase<Balance> wallet) {
this.wallet = wallet;
type = wallet.type;
name = wallet.name;

View file

@ -301,7 +301,7 @@ abstract class ExchangeViewModelBase with Store {
@action
void calculateDepositAllAmount() {
if (wallet is BitcoinWallet) {
final availableBalance = wallet.balance.availableBalance as int;
final availableBalance = wallet.balance.available;
final fee = BitcoinWalletBase.feeAmountForPriority(
_settingsStore.transactionPriority);

View file

@ -134,9 +134,7 @@ abstract class SendViewModelBase with Store {
PendingTransaction pendingTransaction;
@computed
String get balance =>
_wallet.balance.formattedBalance(BalanceDisplayMode.availableBalance)
as String ?? '0.0';
String get balance => _wallet.balance.formattedAvailableBalance ?? '0.0';
@computed
bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
@ -183,11 +181,12 @@ abstract class SendViewModelBase with Store {
if (pendingTransaction.id?.isNotEmpty ?? false) {
_settingsStore.shouldSaveRecipientAddress
? await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id, recipientAddress: address,
transactionNote: note))
: await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id, transactionNote: note));
? await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id,
recipientAddress: address,
transactionNote: note))
: await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id, transactionNote: note));
}
state = TransactionCommitted();

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
@ -28,7 +29,7 @@ part 'settings_view_model.g.dart';
class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
abstract class SettingsViewModelBase with Store {
SettingsViewModelBase(this._settingsStore, WalletBase wallet)
SettingsViewModelBase(this._settingsStore, WalletBase<Balance> wallet)
: itemHeaders = {},
_walletType = wallet.type,
_biometricAuth = BiometricAuth() {
@ -45,13 +46,12 @@ abstract class SettingsViewModelBase with Store {
sections = [
[
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_display_balance_as,
items: BalanceDisplayMode.all,
selectedItem: () => balanceDisplayMode,
onItemSelected: (BalanceDisplayMode mode) =>
_settingsStore.balanceDisplayMode = mode),
PickerListItem(
title: S.current.settings_currency,
items: FiatCurrency.all,
@ -120,7 +120,7 @@ abstract class SettingsViewModelBase with Store {
items: ThemeList.all,
selectedItem: () => theme,
onItemSelected: (ThemeBase theme) =>
_settingsStore.currentTheme = theme)
_settingsStore.currentTheme = theme)
],
[
LinkListItem(

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/balance.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
@ -60,7 +61,7 @@ abstract class WalletAddressListViewModelBase with Store {
_appStore = appStore;
_wallet = _appStore.wallet;
hasAccounts = _wallet?.type == WalletType.monero;
_onWalletChangeReaction = reaction((_) => _appStore.wallet, (WalletBase wallet) {
_onWalletChangeReaction = reaction((_) => _appStore.wallet, (WalletBase<Balance> wallet) {
_wallet = wallet;
hasAccounts = _wallet.type == WalletType.monero;
});
@ -145,7 +146,7 @@ abstract class WalletAddressListViewModelBase with Store {
bool get hasAddressList => _wallet.type == WalletType.monero;
@observable
WalletBase _wallet;
WalletBase<Balance> _wallet;
List<ListItem> _baseItems;