mirror of
https://github.com/bisq-network/bisq.git
synced 2025-03-13 11:09:10 +01:00
add generic PM, CB, Model baseclasses
This commit is contained in:
parent
d9e625a684
commit
b7c1fa58d7
7 changed files with 408 additions and 207 deletions
73
src/main/java/io/bitsquare/gui/CachedCodeBehind.java
Normal file
73
src/main/java/io/bitsquare/gui/CachedCodeBehind.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
package io.bitsquare.gui;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CachedCodeBehind<T extends PresentationModel> extends CodeBehind<T> {
|
||||
private static final Logger log = LoggerFactory.getLogger(CachedCodeBehind.class);
|
||||
|
||||
public CachedCodeBehind(T pm) {
|
||||
super(pm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get called form GUI framework when the UI is ready.
|
||||
* In caching controllers the initialize is only used for static UI setup.
|
||||
* The activate() method is called to start resources like.
|
||||
*
|
||||
* @param url
|
||||
* @param rb
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
|
||||
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
|
||||
// we got removed from the scene
|
||||
// lets terminate
|
||||
log.trace("Lifecycle: sceneProperty changed: " + this.getClass().getSimpleName() + " / oldValue=" +
|
||||
oldValue + " / newValue=" + newValue);
|
||||
if (oldValue == null && newValue != null) activate();
|
||||
else if (oldValue != null && newValue == null) deactivate();
|
||||
});
|
||||
|
||||
activate();
|
||||
pm.initialized();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to activate resources (adding listeners, starting timers or animations,...)
|
||||
*/
|
||||
public void activate() {
|
||||
log.trace("Lifecycle: activate " + this.getClass().getSimpleName());
|
||||
if (childController instanceof CachedViewController) ((CachedViewController) childController).activate();
|
||||
|
||||
pm.activate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for deactivating resources (removing listeners, stopping timers or animations,...)
|
||||
*/
|
||||
public void deactivate() {
|
||||
log.trace("Lifecycle: deactivate " + this.getClass().getSimpleName());
|
||||
if (childController instanceof CachedViewController) ((CachedViewController) childController).deactivate();
|
||||
|
||||
pm.deactivate();
|
||||
}
|
||||
|
||||
/**
|
||||
* In caching controllers the terminate calls the deactivate method.
|
||||
*/
|
||||
@Override
|
||||
public void terminate() {
|
||||
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
|
||||
super.terminate();
|
||||
|
||||
deactivate();
|
||||
pm.terminate();
|
||||
}
|
||||
|
||||
}
|
79
src/main/java/io/bitsquare/gui/CodeBehind.java
Normal file
79
src/main/java/io/bitsquare/gui/CodeBehind.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package io.bitsquare.gui;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CodeBehind<T extends PresentationModel> implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(CodeBehind.class);
|
||||
|
||||
protected T pm;
|
||||
protected ViewController childController;
|
||||
protected ViewController parentController;
|
||||
@FXML protected Parent root;
|
||||
|
||||
public CodeBehind(T pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
public T pm() {
|
||||
return (T) pm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get called form GUI framework when the UI is ready.
|
||||
*
|
||||
* @param url
|
||||
* @param rb
|
||||
*/
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
log.trace("Lifecycle: initialize " + this.getClass().getSimpleName());
|
||||
root.sceneProperty().addListener((ov, oldValue, newValue) -> {
|
||||
// we got removed from the scene
|
||||
// lets terminate
|
||||
if (oldValue != null && newValue == null) terminate();
|
||||
});
|
||||
|
||||
pm.initialized();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called automatically when view gets removed. Used for house keeping (removing listeners,
|
||||
* stopping timers or animations,...).
|
||||
*/
|
||||
public void terminate() {
|
||||
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
|
||||
if (childController != null) childController.terminate();
|
||||
|
||||
pm.terminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parentController Controller who has created this.getClass().getSimpleName() instance (via
|
||||
* navigateToView/FXMLLoader).
|
||||
*/
|
||||
public void setParentController(ViewController parentController) {
|
||||
log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " +
|
||||
parentController);
|
||||
this.parentController = parentController;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param navigationItem NavigationItem to be loaded.
|
||||
* @return The ViewController of the loaded view.
|
||||
*/
|
||||
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
|
||||
log.trace("Lifecycle: loadViewAndGetChildController " + this.getClass().getSimpleName() + " / navigationItem " +
|
||||
"= " + navigationItem);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
36
src/main/java/io/bitsquare/gui/PresentationModel.java
Normal file
36
src/main/java/io/bitsquare/gui/PresentationModel.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package io.bitsquare.gui;
|
||||
|
||||
public class PresentationModel<T extends UIModel> {
|
||||
|
||||
private T model;
|
||||
|
||||
public T model() {
|
||||
return (T) model;
|
||||
}
|
||||
|
||||
public PresentationModel(T model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public PresentationModel() {
|
||||
}
|
||||
|
||||
public void initialized() {
|
||||
model.initialized();
|
||||
activate();
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
model.activate();
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
model.deactivate();
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
model.terminate();
|
||||
deactivate();
|
||||
}
|
||||
|
||||
}
|
22
src/main/java/io/bitsquare/gui/UIModel.java
Normal file
22
src/main/java/io/bitsquare/gui/UIModel.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package io.bitsquare.gui;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class UIModel<T> {
|
||||
private static final Logger log = LoggerFactory.getLogger(UIModel.class);
|
||||
|
||||
public void initialized() {
|
||||
activate();
|
||||
}
|
||||
|
||||
public void activate() {
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
deactivate();
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.trade.createoffer;
|
||||
|
||||
import io.bitsquare.gui.CachedViewController;
|
||||
import io.bitsquare.gui.CachedCodeBehind;
|
||||
import io.bitsquare.gui.components.Popups;
|
||||
import io.bitsquare.gui.components.ValidatingTextField;
|
||||
import io.bitsquare.gui.components.btc.AddressTextField;
|
||||
|
@ -39,11 +39,9 @@ import javafx.scene.layout.*;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CreateOfferCB extends CachedViewController {
|
||||
public class CreateOfferCB extends CachedCodeBehind<CreateOfferPM> {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOfferCB.class);
|
||||
|
||||
private final CreateOfferPM pm;
|
||||
|
||||
@FXML private Label buyLabel, confirmationLabel, txTitleLabel, collateralLabel;
|
||||
@FXML private ValidatingTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
|
||||
@FXML private Button placeOfferButton, closeButton;
|
||||
|
@ -63,7 +61,7 @@ public class CreateOfferCB extends CachedViewController {
|
|||
//TODO find a better solution, handle at base class?
|
||||
@Inject
|
||||
public CreateOfferCB(CreateOfferModel model) {
|
||||
pm = new CreateOfferPM(model);
|
||||
super(new CreateOfferPM(model));
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,41 +73,27 @@ public class CreateOfferCB extends CachedViewController {
|
|||
public void initialize(URL url, ResourceBundle rb) {
|
||||
super.initialize(url, rb);
|
||||
|
||||
//TODO handle in base class
|
||||
pm.onViewInitialized();
|
||||
|
||||
setupBindings();
|
||||
setupListeners();
|
||||
configTextFieldValidators();
|
||||
balanceTextField.setup(pm.getWalletFacade(), pm.address.get());
|
||||
balanceTextField.setup(pm().getWalletFacade(), pm().address.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
|
||||
//TODO handle in base class
|
||||
pm.deactivate();
|
||||
|
||||
//TODO check that again
|
||||
if (parentController != null) ((TradeController) parentController).onCreateOfferViewRemoved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
|
||||
//TODO handle in base class
|
||||
pm.activate();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setOrderBookFilter(OrderBookFilter orderBookFilter) {
|
||||
pm.setOrderBookFilter(orderBookFilter);
|
||||
pm().setOrderBookFilter(orderBookFilter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,12 +103,12 @@ public class CreateOfferCB extends CachedViewController {
|
|||
|
||||
@FXML
|
||||
public void onPlaceOffer() {
|
||||
pm.placeOffer();
|
||||
pm().placeOffer();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void onClose() {
|
||||
pm.close();
|
||||
pm().close();
|
||||
|
||||
TabPane tabPane = ((TabPane) (root.getParent().getParent()));
|
||||
tabPane.getTabs().remove(tabPane.getSelectionModel().getSelectedItem());
|
||||
|
@ -137,91 +121,91 @@ public class CreateOfferCB extends CachedViewController {
|
|||
|
||||
private void setupListeners() {
|
||||
volumeTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
|
||||
pm.onFocusOutVolumeTextField(oldValue, newValue);
|
||||
volumeTextField.setText(pm.volume.get());
|
||||
pm().onFocusOutVolumeTextField(oldValue, newValue);
|
||||
volumeTextField.setText(pm().volume.get());
|
||||
});
|
||||
|
||||
amountTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
|
||||
pm.onFocusOutAmountTextField(oldValue, newValue);
|
||||
amountTextField.setText(pm.amount.get());
|
||||
pm().onFocusOutAmountTextField(oldValue, newValue);
|
||||
amountTextField.setText(pm().amount.get());
|
||||
});
|
||||
|
||||
priceTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
|
||||
pm.onFocusOutPriceTextField(oldValue, newValue);
|
||||
priceTextField.setText(pm.price.get());
|
||||
pm().onFocusOutPriceTextField(oldValue, newValue);
|
||||
priceTextField.setText(pm().price.get());
|
||||
});
|
||||
|
||||
minAmountTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
|
||||
pm.onFocusOutMinAmountTextField(oldValue, newValue);
|
||||
minAmountTextField.setText(pm.minAmount.get());
|
||||
pm().onFocusOutMinAmountTextField(oldValue, newValue);
|
||||
minAmountTextField.setText(pm().minAmount.get());
|
||||
});
|
||||
|
||||
pm.showWarningInvalidBtcDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
||||
pm().showWarningInvalidBtcDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
Popups.openWarningPopup("Warning", "The amount you have entered exceeds the number of allowed decimal" +
|
||||
" places.\nThe amount has been adjusted to 4 decimal places.");
|
||||
pm.showWarningInvalidBtcDecimalPlaces.set(false);
|
||||
pm().showWarningInvalidBtcDecimalPlaces.set(false);
|
||||
}
|
||||
});
|
||||
|
||||
pm.showWarningInvalidFiatDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
||||
pm().showWarningInvalidFiatDecimalPlaces.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
Popups.openWarningPopup("Warning", "The amount you have entered exceeds the number of allowed decimal" +
|
||||
" places.\nThe amount has been adjusted to 2 decimal places.");
|
||||
pm.showWarningInvalidFiatDecimalPlaces.set(false);
|
||||
pm().showWarningInvalidFiatDecimalPlaces.set(false);
|
||||
}
|
||||
});
|
||||
|
||||
pm.showWarningAdjustedVolume.addListener((o, oldValue, newValue) -> {
|
||||
pm().showWarningAdjustedVolume.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
Popups.openWarningPopup("Warning", "The total volume you have entered leads to invalid fractional " +
|
||||
"Bitcoin amounts.\nThe amount has been adjusted and a new total volume be calculated from it.");
|
||||
pm.showWarningAdjustedVolume.set(false);
|
||||
volumeTextField.setText(pm.volume.get());
|
||||
pm().showWarningAdjustedVolume.set(false);
|
||||
volumeTextField.setText(pm().volume.get());
|
||||
}
|
||||
});
|
||||
|
||||
pm.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
|
||||
pm().requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
Popups.openErrorPopup("Error", "An error occurred when placing the offer.\n" +
|
||||
pm.requestPlaceOfferErrorMessage);
|
||||
pm.requestPlaceOfferFailed.set(false);
|
||||
pm().requestPlaceOfferErrorMessage);
|
||||
pm().requestPlaceOfferFailed.set(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupBindings() {
|
||||
buyLabel.textProperty().bind(pm.directionLabel);
|
||||
amountTextField.textProperty().bindBidirectional(pm.amount);
|
||||
priceTextField.textProperty().bindBidirectional(pm.price);
|
||||
volumeTextField.textProperty().bindBidirectional(pm.volume);
|
||||
buyLabel.textProperty().bind(pm().directionLabel);
|
||||
amountTextField.textProperty().bindBidirectional(pm().amount);
|
||||
priceTextField.textProperty().bindBidirectional(pm().price);
|
||||
volumeTextField.textProperty().bindBidirectional(pm().volume);
|
||||
|
||||
minAmountTextField.textProperty().bindBidirectional(pm.minAmount);
|
||||
collateralLabel.textProperty().bind(pm.collateralLabel);
|
||||
collateralTextField.textProperty().bind(pm.collateral);
|
||||
totalToPayTextField.textProperty().bind(pm.totalToPay);
|
||||
minAmountTextField.textProperty().bindBidirectional(pm().minAmount);
|
||||
collateralLabel.textProperty().bind(pm().collateralLabel);
|
||||
collateralTextField.textProperty().bind(pm().collateral);
|
||||
totalToPayTextField.textProperty().bind(pm().totalToPay);
|
||||
|
||||
addressTextField.amountAsCoinProperty().bind(pm.totalToPayAsCoin);
|
||||
addressTextField.paymentLabelProperty().bind(pm.paymentLabel);
|
||||
addressTextField.addressProperty().bind(pm.addressAsString);
|
||||
addressTextField.amountAsCoinProperty().bind(pm().totalToPayAsCoin);
|
||||
addressTextField.paymentLabelProperty().bind(pm().paymentLabel);
|
||||
addressTextField.addressProperty().bind(pm().addressAsString);
|
||||
|
||||
bankAccountTypeTextField.textProperty().bind(pm.bankAccountType);
|
||||
bankAccountCurrencyTextField.textProperty().bind(pm.bankAccountCurrency);
|
||||
bankAccountCountyTextField.textProperty().bind(pm.bankAccountCounty);
|
||||
bankAccountTypeTextField.textProperty().bind(pm().bankAccountType);
|
||||
bankAccountCurrencyTextField.textProperty().bind(pm().bankAccountCurrency);
|
||||
bankAccountCountyTextField.textProperty().bind(pm().bankAccountCounty);
|
||||
|
||||
acceptedCountriesTextField.textProperty().bind(pm.acceptedCountries);
|
||||
acceptedLanguagesTextField.textProperty().bind(pm.acceptedLanguages);
|
||||
totalFeesTextField.textProperty().bind(pm.totalFees);
|
||||
transactionIdTextField.textProperty().bind(pm.transactionId);
|
||||
acceptedCountriesTextField.textProperty().bind(pm().acceptedCountries);
|
||||
acceptedLanguagesTextField.textProperty().bind(pm().acceptedLanguages);
|
||||
totalFeesTextField.textProperty().bind(pm().totalFees);
|
||||
transactionIdTextField.textProperty().bind(pm().transactionId);
|
||||
|
||||
amountTextField.amountValidationResultProperty().bind(pm.amountValidationResult);
|
||||
minAmountTextField.amountValidationResultProperty().bind(pm.minAmountValidationResult);
|
||||
priceTextField.amountValidationResultProperty().bind(pm.priceValidationResult);
|
||||
volumeTextField.amountValidationResultProperty().bind(pm.volumeValidationResult);
|
||||
amountTextField.amountValidationResultProperty().bind(pm().amountValidationResult);
|
||||
minAmountTextField.amountValidationResultProperty().bind(pm().minAmountValidationResult);
|
||||
priceTextField.amountValidationResultProperty().bind(pm().priceValidationResult);
|
||||
volumeTextField.amountValidationResultProperty().bind(pm().volumeValidationResult);
|
||||
|
||||
placeOfferButton.visibleProperty().bind(pm.isPlaceOfferButtonVisible);
|
||||
placeOfferButton.disableProperty().bind(pm.isPlaceOfferButtonDisabled);
|
||||
closeButton.visibleProperty().bind(pm.isCloseButtonVisible);
|
||||
placeOfferButton.visibleProperty().bind(pm().isPlaceOfferButtonVisible);
|
||||
placeOfferButton.disableProperty().bind(pm().isPlaceOfferButtonDisabled);
|
||||
closeButton.visibleProperty().bind(pm().isCloseButtonVisible);
|
||||
}
|
||||
|
||||
private void configTextFieldValidators() {
|
||||
|
|
|
@ -21,6 +21,7 @@ import io.bitsquare.bank.BankAccount;
|
|||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.UIModel;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.settings.Settings;
|
||||
import io.bitsquare.trade.Direction;
|
||||
|
@ -58,7 +59,7 @@ import static io.bitsquare.gui.util.BSFormatter.reduceto4Dezimals;
|
|||
* Note that the create offer domain has a deeper scope in the application domain (TradeManager).
|
||||
* That model is just responsible for the domain specific parts displayed needed in that UI element.
|
||||
*/
|
||||
class CreateOfferModel {
|
||||
class CreateOfferModel extends UIModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOfferModel.class);
|
||||
|
||||
private final TradeManager tradeManager;
|
||||
|
@ -99,7 +100,7 @@ class CreateOfferModel {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
CreateOfferModel(TradeManager tradeManager, WalletFacade walletFacade, Settings settings, User user) {
|
||||
public CreateOfferModel(TradeManager tradeManager, WalletFacade walletFacade, Settings settings, User user) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.walletFacade = walletFacade;
|
||||
this.settings = settings;
|
||||
|
@ -107,35 +108,52 @@ class CreateOfferModel {
|
|||
|
||||
// static data
|
||||
offerId = UUID.randomUUID().toString();
|
||||
totalFeesAsCoin.set(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE));
|
||||
totalFeesAsCoin.setValue(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE));
|
||||
|
||||
|
||||
//TODO just for unit testing, use mockito?
|
||||
if (walletFacade != null && walletFacade.getWallet() != null)
|
||||
addressEntry = walletFacade.getAddressInfoByTradeID(offerId);
|
||||
|
||||
collateralAsLong.setValue(settings.getCollateral());
|
||||
|
||||
BankAccount bankAccount = user.getCurrentBankAccount();
|
||||
if (bankAccount != null) {
|
||||
bankAccountType.setValue(bankAccount.getBankAccountType().toString());
|
||||
bankAccountCurrency.setValue(bankAccount.getCurrency().getCurrencyCode());
|
||||
bankAccountCounty.setValue(bankAccount.getCountry().getName());
|
||||
}
|
||||
acceptedCountries.setAll(settings.getAcceptedCountries());
|
||||
acceptedLanguages.setAll(settings.getAcceptedLanguageLocales());
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialized() {
|
||||
super.initialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void activate() {
|
||||
// dynamic data, might be changing when switching screen and returning (edit settings)
|
||||
collateralAsLong.set(settings.getCollateral());
|
||||
|
||||
BankAccount bankAccount = user.getCurrentBankAccount();
|
||||
if (bankAccount != null) {
|
||||
bankAccountType.set(bankAccount.getBankAccountType().toString());
|
||||
bankAccountCurrency.set(bankAccount.getCurrency().getCurrencyCode());
|
||||
bankAccountCounty.set(bankAccount.getCountry().getName());
|
||||
}
|
||||
acceptedCountries.setAll(settings.getAcceptedCountries());
|
||||
acceptedLanguages.setAll(settings.getAcceptedLanguageLocales());
|
||||
}
|
||||
|
||||
void deactivate() {
|
||||
}
|
||||
|
||||
void placeOffer() {
|
||||
tradeManager.requestPlaceOffer(offerId,
|
||||
|
@ -144,29 +162,29 @@ class CreateOfferModel {
|
|||
amountAsCoin.get(),
|
||||
minAmountAsCoin.get(),
|
||||
(transaction) -> {
|
||||
requestPlaceOfferSuccess.set(true);
|
||||
transactionId.set(transaction.getHashAsString());
|
||||
requestPlaceOfferSuccess.setValue(true);
|
||||
transactionId.setValue(transaction.getHashAsString());
|
||||
},
|
||||
(errorMessage) -> {
|
||||
requestPlaceOfferFailed.set(true);
|
||||
requestPlaceOfferErrorMessage.set(errorMessage);
|
||||
requestPlaceOfferFailed.setValue(true);
|
||||
requestPlaceOfferErrorMessage.setValue(errorMessage);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void calculateVolume() {
|
||||
if (priceAsFiat.get() != null && amountAsCoin.get() != null /*&& !amountAsCoin.get().isZero()*/)
|
||||
volumeAsFiat.set(new ExchangeRate(priceAsFiat.get()).coinToFiat(amountAsCoin.get()));
|
||||
volumeAsFiat.setValue(new ExchangeRate(priceAsFiat.get()).coinToFiat(amountAsCoin.get()));
|
||||
}
|
||||
|
||||
void calculateAmount() {
|
||||
|
||||
if (volumeAsFiat.get() != null && priceAsFiat.get() != null/* && !volumeAsFiat.get().isZero() && !priceAsFiat
|
||||
.get().isZero()*/) {
|
||||
amountAsCoin.set(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get()));
|
||||
amountAsCoin.setValue(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get()));
|
||||
|
||||
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
|
||||
amountAsCoin.set(reduceto4Dezimals(amountAsCoin.get()));
|
||||
amountAsCoin.setValue(reduceto4Dezimals(amountAsCoin.get()));
|
||||
calculateTotalToPay();
|
||||
calculateCollateral();
|
||||
}
|
||||
|
@ -176,14 +194,14 @@ class CreateOfferModel {
|
|||
calculateCollateral();
|
||||
|
||||
if (collateralAsCoin.get() != null) {
|
||||
totalToPayAsCoin.set(collateralAsCoin.get().add(totalFeesAsCoin.get()));
|
||||
totalToPayAsCoin.setValue(collateralAsCoin.get().add(totalFeesAsCoin.get()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void calculateCollateral() {
|
||||
if (amountAsCoin.get() != null)
|
||||
collateralAsCoin.set(amountAsCoin.get().multiply(collateralAsLong.get()).divide(1000));
|
||||
collateralAsCoin.setValue(amountAsCoin.get().multiply(collateralAsLong.get()).divide(1000));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package io.bitsquare.gui.trade.createoffer;
|
||||
|
||||
import io.bitsquare.btc.WalletFacade;
|
||||
import io.bitsquare.gui.PresentationModel;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.validation.BtcValidator;
|
||||
import io.bitsquare.gui.util.validation.FiatValidator;
|
||||
|
@ -44,10 +45,10 @@ import org.slf4j.LoggerFactory;
|
|||
import static io.bitsquare.gui.util.BSFormatter.*;
|
||||
import static javafx.beans.binding.Bindings.createStringBinding;
|
||||
|
||||
class CreateOfferPM {
|
||||
class CreateOfferPM extends PresentationModel<CreateOfferModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOfferPM.class);
|
||||
|
||||
private CreateOfferModel model;
|
||||
|
||||
private BtcValidator btcValidator = new BtcValidator();
|
||||
private FiatValidator fiatValidator = new FiatValidator();
|
||||
|
||||
|
@ -86,7 +87,6 @@ class CreateOfferPM {
|
|||
|
||||
// That is needed for the addressTextField
|
||||
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
|
||||
|
||||
final ObjectProperty<Address> address = new SimpleObjectProperty<>();
|
||||
|
||||
|
||||
|
@ -95,60 +95,60 @@ class CreateOfferPM {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CreateOfferPM(CreateOfferModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
super(model);
|
||||
|
||||
paymentLabel.setValue("Bitsquare trade (" + model().getOfferId() + ")");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle (called by CB)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void onViewInitialized() {
|
||||
// todo move to contr.
|
||||
|
||||
// static
|
||||
paymentLabel.set("Bitsquare trade (" + model.getOfferId() + ")");
|
||||
|
||||
if (model.addressEntry != null) {
|
||||
addressAsString.set(model.addressEntry.getAddress().toString());
|
||||
address.set(model.addressEntry.getAddress());
|
||||
if (model().addressEntry != null) {
|
||||
addressAsString.setValue(model().addressEntry.getAddress().toString());
|
||||
address.setValue(model().addressEntry.getAddress());
|
||||
}
|
||||
|
||||
setupModelBindings();
|
||||
setupUIInputListeners();
|
||||
|
||||
// TODO transactionId,
|
||||
}
|
||||
|
||||
void activate() {
|
||||
//TODO handle in base class
|
||||
model.activate();
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Lifecycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void initialized() {
|
||||
super.initialized();
|
||||
}
|
||||
|
||||
|
||||
void deactivate() {
|
||||
//TODO handle in base class
|
||||
model.deactivate();
|
||||
@Override
|
||||
public void activate() {
|
||||
super.activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
super.deactivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate() {
|
||||
super.terminate();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API methods (called by CB)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setOrderBookFilter(OrderBookFilter orderBookFilter) {
|
||||
model.setDirection(orderBookFilter.getDirection());
|
||||
directionLabel.set(model.getDirection() == Direction.BUY ? "Buy:" : "Sell:");
|
||||
model().setDirection(orderBookFilter.getDirection());
|
||||
directionLabel.setValue(model().getDirection() == Direction.BUY ? "Buy:" : "Sell:");
|
||||
|
||||
if (orderBookFilter.getAmount() != null && isBtcInputValid(orderBookFilter.getAmount().toPlainString())
|
||||
.isValid) {
|
||||
model.amountAsCoin.set(orderBookFilter.getAmount());
|
||||
model.minAmountAsCoin.set(orderBookFilter.getAmount());
|
||||
model().amountAsCoin.setValue(orderBookFilter.getAmount());
|
||||
model().minAmountAsCoin.setValue(orderBookFilter.getAmount());
|
||||
}
|
||||
|
||||
// TODO use Fiat in orderBookFilter
|
||||
if (orderBookFilter.getPrice() != 0 && isBtcInputValid(String.valueOf(orderBookFilter.getPrice())).isValid)
|
||||
model.priceAsFiat.set(parseToFiatWith2Decimals(String.valueOf(orderBookFilter.getPrice())));
|
||||
model().priceAsFiat.setValue(parseToFiatWith2Decimals(String.valueOf(orderBookFilter.getPrice())));
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,9 +157,9 @@ class CreateOfferPM {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void placeOffer() {
|
||||
model.placeOffer();
|
||||
isPlaceOfferButtonDisabled.set(true);
|
||||
isPlaceOfferButtonVisible.set(true);
|
||||
model().placeOffer();
|
||||
isPlaceOfferButtonDisabled.setValue(true);
|
||||
isPlaceOfferButtonVisible.setValue(true);
|
||||
}
|
||||
|
||||
void close() {
|
||||
|
@ -175,22 +175,22 @@ class CreateOfferPM {
|
|||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(amount.get());
|
||||
boolean isValid = result.isValid;
|
||||
amountValidationResult.set(result);
|
||||
amountValidationResult.setValue(result);
|
||||
if (isValid) {
|
||||
showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(amount.get()));
|
||||
showWarningInvalidBtcDecimalPlaces.setValue(!hasBtcValidDecimals(amount.get()));
|
||||
// only allow max 4 decimal places for btc values
|
||||
setAmountToModel();
|
||||
// reformat input to general btc format
|
||||
calculateVolume();
|
||||
|
||||
if (!model.isMinAmountLessOrEqualAmount()) {
|
||||
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||
if (!model().isMinAmountLessOrEqualAmount()) {
|
||||
amountValidationResult.setValue(new InputValidator.ValidationResult(false,
|
||||
"Amount cannot be smaller than minimum amount."));
|
||||
}
|
||||
else {
|
||||
amountValidationResult.set(result);
|
||||
amountValidationResult.setValue(result);
|
||||
if (minAmount.get() != null)
|
||||
minAmountValidationResult.set(isBtcInputValid(minAmount.get()));
|
||||
minAmountValidationResult.setValue(isBtcInputValid(minAmount.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,19 +201,19 @@ class CreateOfferPM {
|
|||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(minAmount.get());
|
||||
boolean isValid = result.isValid;
|
||||
minAmountValidationResult.set(result);
|
||||
minAmountValidationResult.setValue(result);
|
||||
if (isValid) {
|
||||
showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(minAmount.get()));
|
||||
showWarningInvalidBtcDecimalPlaces.setValue(!hasBtcValidDecimals(minAmount.get()));
|
||||
setMinAmountToModel();
|
||||
|
||||
if (!model.isMinAmountLessOrEqualAmount()) {
|
||||
minAmountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||
if (!model().isMinAmountLessOrEqualAmount()) {
|
||||
minAmountValidationResult.setValue(new InputValidator.ValidationResult(false,
|
||||
"Minimum amount cannot be larger than amount."));
|
||||
}
|
||||
else {
|
||||
minAmountValidationResult.set(result);
|
||||
minAmountValidationResult.setValue(result);
|
||||
if (amount.get() != null)
|
||||
amountValidationResult.set(isBtcInputValid(amount.get()));
|
||||
amountValidationResult.setValue(isBtcInputValid(amount.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,9 +223,9 @@ class CreateOfferPM {
|
|||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isFiatInputValid(price.get());
|
||||
boolean isValid = result.isValid;
|
||||
priceValidationResult.set(result);
|
||||
priceValidationResult.setValue(result);
|
||||
if (isValid) {
|
||||
showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(price.get()));
|
||||
showWarningInvalidFiatDecimalPlaces.setValue(!hasFiatValidDecimals(price.get()));
|
||||
setPriceToModel();
|
||||
|
||||
calculateVolume();
|
||||
|
@ -237,17 +237,18 @@ class CreateOfferPM {
|
|||
if (oldValue && !newValue) {
|
||||
InputValidator.ValidationResult result = isBtcInputValid(volume.get());
|
||||
boolean isValid = result.isValid;
|
||||
volumeValidationResult.set(result);
|
||||
volumeValidationResult.setValue(result);
|
||||
if (isValid) {
|
||||
String origVolume = volume.get();
|
||||
showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(volume.get()));
|
||||
showWarningInvalidFiatDecimalPlaces.setValue(!hasFiatValidDecimals(volume.get()));
|
||||
setVolumeToModel();
|
||||
|
||||
calculateAmount();
|
||||
|
||||
// must be after calculateAmount (btc value has been adjusted in case the calculation leads to
|
||||
// invalid decimal places for the amount value
|
||||
showWarningAdjustedVolume.set(!formatFiat(parseToFiatWith2Decimals(origVolume)).equals(volume.get()));
|
||||
showWarningAdjustedVolume.setValue(!formatFiat(parseToFiatWith2Decimals(origVolume)).equals(volume
|
||||
.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +259,7 @@ class CreateOfferPM {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WalletFacade getWalletFacade() {
|
||||
return model.getWalletFacade();
|
||||
return model().getWalletFacade();
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,123 +273,111 @@ class CreateOfferPM {
|
|||
// We do volume/amount calculation during input
|
||||
amount.addListener((ov, oldValue, newValue) -> {
|
||||
if (isBtcInputValid(newValue).isValid) {
|
||||
model.amountAsCoin.set(parseToCoinWith4Decimals(newValue));
|
||||
model().amountAsCoin.setValue(parseToCoinWith4Decimals(newValue));
|
||||
calculateVolume();
|
||||
model.calculateTotalToPay();
|
||||
model.calculateCollateral();
|
||||
model().calculateTotalToPay();
|
||||
model().calculateCollateral();
|
||||
}
|
||||
});
|
||||
|
||||
price.addListener((ov, oldValue, newValue) -> {
|
||||
if (isFiatInputValid(newValue).isValid) {
|
||||
model.priceAsFiat.set(parseToFiatWith2Decimals(newValue));
|
||||
model().priceAsFiat.setValue(parseToFiatWith2Decimals(newValue));
|
||||
calculateVolume();
|
||||
model.calculateTotalToPay();
|
||||
model.calculateCollateral();
|
||||
model().calculateTotalToPay();
|
||||
model().calculateCollateral();
|
||||
}
|
||||
});
|
||||
|
||||
volume.addListener((ov, oldValue, newValue) -> {
|
||||
if (isFiatInputValid(newValue).isValid) {
|
||||
model.volumeAsFiat.set(parseToFiatWith2Decimals(newValue));
|
||||
model().volumeAsFiat.setValue(parseToFiatWith2Decimals(newValue));
|
||||
setVolumeToModel();
|
||||
setPriceToModel();
|
||||
model.calculateAmount();
|
||||
model.calculateTotalToPay();
|
||||
model.calculateCollateral();
|
||||
model().calculateAmount();
|
||||
model().calculateTotalToPay();
|
||||
model().calculateCollateral();
|
||||
}
|
||||
});
|
||||
|
||||
// Binding with Bindings.createObjectBinding does not work becaue of bi-directional binding in CB
|
||||
model().amountAsCoin.addListener((ov, oldValue, newValue) -> amount.set(formatCoin(newValue)));
|
||||
model().minAmountAsCoin.addListener((ov, oldValue, newValue) -> minAmount.set(formatCoin(newValue)));
|
||||
model().priceAsFiat.addListener((ov, oldValue, newValue) -> price.set(formatFiat(newValue)));
|
||||
model().volumeAsFiat.addListener((ov, oldValue, newValue) -> volume.set(formatFiat(newValue)));
|
||||
}
|
||||
|
||||
private void setupModelBindings() {
|
||||
|
||||
amount.bind(Bindings.createObjectBinding(() -> formatCoin(model.amountAsCoin.get()), model.amountAsCoin));
|
||||
minAmount.bind(Bindings.createObjectBinding(() -> formatCoin(model.minAmountAsCoin.get()),
|
||||
model.minAmountAsCoin));
|
||||
price.bind(Bindings.createObjectBinding(() -> formatFiat(model.priceAsFiat.get()), model.priceAsFiat));
|
||||
volume.bind(Bindings.createObjectBinding(() -> formatFiat(model.volumeAsFiat.get()), model.volumeAsFiat));
|
||||
|
||||
totalToPay.bind(createStringBinding(() -> formatCoinWithCode(model.totalToPayAsCoin.get()),
|
||||
model.totalToPayAsCoin));
|
||||
collateral.bind(createStringBinding(() -> formatCoinWithCode(model.collateralAsCoin.get()),
|
||||
model.collateralAsCoin));
|
||||
totalToPay.bind(createStringBinding(() -> formatCoinWithCode(model().totalToPayAsCoin.get()),
|
||||
model().totalToPayAsCoin));
|
||||
collateral.bind(createStringBinding(() -> formatCoinWithCode(model().collateralAsCoin.get()),
|
||||
model().collateralAsCoin));
|
||||
|
||||
collateralLabel.bind(Bindings.createStringBinding(() -> "Collateral (" + BSFormatter.formatCollateralPercent
|
||||
(model.collateralAsLong.get()) + "):", model.collateralAsLong));
|
||||
totalToPayAsCoin.bind(model.totalToPayAsCoin);
|
||||
(model().collateralAsLong.get()) + "):", model().collateralAsLong));
|
||||
totalToPayAsCoin.bind(model().totalToPayAsCoin);
|
||||
|
||||
bankAccountType.bind(Bindings.createStringBinding(() -> Localisation.get(model.bankAccountType.get()),
|
||||
model.bankAccountType));
|
||||
bankAccountCurrency.bind(model.bankAccountCurrency);
|
||||
bankAccountCounty.bind(model.bankAccountCounty);
|
||||
bankAccountType.bind(Bindings.createStringBinding(() -> Localisation.get(model().bankAccountType.get()),
|
||||
model().bankAccountType));
|
||||
bankAccountCurrency.bind(model().bankAccountCurrency);
|
||||
bankAccountCounty.bind(model().bankAccountCounty);
|
||||
|
||||
// ObservableLists
|
||||
model.acceptedCountries.addListener((Observable o) -> acceptedCountries.set(BSFormatter
|
||||
.countryLocalesToString(model.acceptedCountries)));
|
||||
model.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(BSFormatter
|
||||
.languageLocalesToString(model.acceptedLanguages)));
|
||||
model().acceptedCountries.addListener((Observable o) -> acceptedCountries.setValue(BSFormatter
|
||||
.countryLocalesToString(model().acceptedCountries)));
|
||||
model().acceptedLanguages.addListener((Observable o) -> acceptedLanguages.setValue(BSFormatter
|
||||
.languageLocalesToString(model().acceptedLanguages)));
|
||||
|
||||
isCloseButtonVisible.bind(model.requestPlaceOfferSuccess);
|
||||
requestPlaceOfferErrorMessage.bind(model.requestPlaceOfferErrorMessage);
|
||||
requestPlaceOfferFailed.bind(model.requestPlaceOfferFailed);
|
||||
showTransactionPublishedScreen.bind(model.requestPlaceOfferSuccess);
|
||||
isCloseButtonVisible.bind(model().requestPlaceOfferSuccess);
|
||||
requestPlaceOfferErrorMessage.bind(model().requestPlaceOfferErrorMessage);
|
||||
requestPlaceOfferFailed.bind(model().requestPlaceOfferFailed);
|
||||
showTransactionPublishedScreen.bind(model().requestPlaceOfferSuccess);
|
||||
|
||||
isPlaceOfferButtonDisabled.bind(Bindings.createBooleanBinding(() -> !model().requestPlaceOfferFailed.get(),
|
||||
model().requestPlaceOfferFailed));
|
||||
|
||||
amount.bind(Bindings.createObjectBinding(() -> formatCoin(model.amountAsCoin.get()), model.amountAsCoin));
|
||||
|
||||
isPlaceOfferButtonDisabled.bind(Bindings.createBooleanBinding(() -> !model.requestPlaceOfferFailed.get(),
|
||||
model.requestPlaceOfferFailed));
|
||||
|
||||
isPlaceOfferButtonVisible.bind(Bindings.createBooleanBinding(() -> !model.requestPlaceOfferSuccess.get(),
|
||||
model.requestPlaceOfferSuccess));
|
||||
|
||||
/* model.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) isPlaceOfferButtonDisabled.set(false);
|
||||
});
|
||||
|
||||
model.requestPlaceOfferSuccess.addListener((o, oldValue, newValue) -> {
|
||||
if (newValue) isPlaceOfferButtonVisible.set(false);
|
||||
});*/
|
||||
isPlaceOfferButtonVisible.bind(Bindings.createBooleanBinding(() -> !model().requestPlaceOfferSuccess.get(),
|
||||
model().requestPlaceOfferSuccess));
|
||||
}
|
||||
|
||||
|
||||
private void calculateVolume() {
|
||||
setAmountToModel();
|
||||
setPriceToModel();
|
||||
model.calculateVolume();
|
||||
model().calculateVolume();
|
||||
}
|
||||
|
||||
private void calculateAmount() {
|
||||
setVolumeToModel();
|
||||
setPriceToModel();
|
||||
model.calculateAmount();
|
||||
model().calculateAmount();
|
||||
|
||||
if (!model.isMinAmountLessOrEqualAmount()) {
|
||||
amountValidationResult.set(new InputValidator.ValidationResult(false,
|
||||
if (!model().isMinAmountLessOrEqualAmount()) {
|
||||
amountValidationResult.setValue(new InputValidator.ValidationResult(false,
|
||||
"Amount cannot be smaller than minimum amount."));
|
||||
}
|
||||
else {
|
||||
if (amount.get() != null)
|
||||
amountValidationResult.set(isBtcInputValid(amount.get()));
|
||||
amountValidationResult.setValue(isBtcInputValid(amount.get()));
|
||||
if (minAmount.get() != null)
|
||||
minAmountValidationResult.set(isBtcInputValid(minAmount.get()));
|
||||
minAmountValidationResult.setValue(isBtcInputValid(minAmount.get()));
|
||||
}
|
||||
}
|
||||
|
||||
private void setAmountToModel() {
|
||||
model.amountAsCoin.set(parseToCoinWith4Decimals(amount.get()));
|
||||
model().amountAsCoin.setValue(parseToCoinWith4Decimals(amount.get()));
|
||||
}
|
||||
|
||||
private void setMinAmountToModel() {
|
||||
model.minAmountAsCoin.set(parseToCoinWith4Decimals(minAmount.get()));
|
||||
model().minAmountAsCoin.setValue(parseToCoinWith4Decimals(minAmount.get()));
|
||||
}
|
||||
|
||||
private void setPriceToModel() {
|
||||
model.priceAsFiat.set(parseToFiatWith2Decimals(price.get()));
|
||||
model().priceAsFiat.setValue(parseToFiatWith2Decimals(price.get()));
|
||||
}
|
||||
|
||||
private void setVolumeToModel() {
|
||||
model.volumeAsFiat.set(parseToFiatWith2Decimals(volume.get()));
|
||||
model().volumeAsFiat.setValue(parseToFiatWith2Decimals(volume.get()));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Reference in a new issue