mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-20 10:22:18 +01:00
Use percentage based price as default, swap input text controls when toggle between fixed price and percentage based price. Hide percentage based inputs if no market price is available.
This commit is contained in:
parent
3777a65b2f
commit
78a8e1ba39
@ -129,7 +129,7 @@ public final class Preferences implements Persistable {
|
||||
|
||||
private boolean useStickyMarketPrice = false;
|
||||
private boolean sortMarketCurrenciesNumerically = true;
|
||||
private boolean usePercentageBasedPrice = false;
|
||||
private boolean usePercentageBasedPrice = true;
|
||||
private Map<String, String> peerTagMap = new HashMap<>();
|
||||
private String bitcoinNodes = "";
|
||||
|
||||
|
@ -612,10 +612,8 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
void updateTradeFee() {
|
||||
createOfferFeeAsCoin = Utilities.getFeePerBtc(feeService.getCreateOfferFeeInBtcPerBtc(), amount.get());
|
||||
|
||||
// We don't want too fractional btc values so we use only a divide by 10 instead of 100
|
||||
createOfferFeeAsCoin = createOfferFeeAsCoin.divide(10).multiply(Math.round(marketPriceMargin * 1_000));
|
||||
|
||||
createOfferFeeAsCoin = Utilities.maxCoin(createOfferFeeAsCoin, feeService.getMinCreateOfferFeeInBtc());
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,12 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
private List<Node> editOfferElements = new ArrayList<>();
|
||||
private boolean isActivated;
|
||||
private Label xLabel;
|
||||
private VBox fixedPriceBox;
|
||||
private VBox percentagePriceBox;
|
||||
private HBox secondRowHBox;
|
||||
private HBox firstRowHBox;
|
||||
private HBox toggleButtonsHBox;
|
||||
private ChangeListener<Number> marketPriceAvailableListener;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -190,9 +196,6 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
if (waitingForFundsBusyAnimation != null)
|
||||
waitingForFundsBusyAnimation.play();
|
||||
|
||||
useMarketBasedPriceButton.setSelected(model.dataModel.useMarketBasedPrice.get());
|
||||
fixedPriceButton.setSelected(!model.dataModel.useMarketBasedPrice.get());
|
||||
|
||||
directionLabel.setText(model.getDirectionLabel());
|
||||
amountDescriptionLabel.setText(model.getAmountDescription());
|
||||
addressTextField.setAddress(model.getAddressAsString());
|
||||
@ -437,10 +440,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
private void addBindings() {
|
||||
amountBtcLabel.textProperty().bind(model.btcCode);
|
||||
priceCurrencyLabel.textProperty().bind(createStringBinding(() -> formatter.getCounterCurrency(model.tradeCurrencyCode.get()), model.btcCode, model.tradeCurrencyCode));
|
||||
fixedPriceTextField.disableProperty().bind(model.dataModel.useMarketBasedPrice);
|
||||
priceCurrencyLabel.disableProperty().bind(model.dataModel.useMarketBasedPrice);
|
||||
marketBasedPriceTextField.disableProperty().bind(model.dataModel.useMarketBasedPrice.not());
|
||||
marketBasedPriceLabel.disableProperty().bind(model.dataModel.useMarketBasedPrice.not());
|
||||
|
||||
marketBasedPriceLabel.prefWidthProperty().bind(priceCurrencyLabel.widthProperty());
|
||||
volumeCurrencyLabel.textProperty().bind(model.tradeCurrencyCode);
|
||||
minAmountBtcLabel.textProperty().bind(model.btcCode);
|
||||
@ -645,10 +645,24 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
marketPriceAvailableListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue.intValue() > -1) {
|
||||
boolean isMarketPriceAvailable = newValue.intValue() == 1;
|
||||
percentagePriceBox.setVisible(isMarketPriceAvailable);
|
||||
percentagePriceBox.setManaged(isMarketPriceAvailable);
|
||||
toggleButtonsHBox.setVisible(isMarketPriceAvailable);
|
||||
toggleButtonsHBox.setManaged(isMarketPriceAvailable);
|
||||
boolean fixedPriceSelected = !model.dataModel.useMarketBasedPrice.get() || !isMarketPriceAvailable;
|
||||
updateToggleButtons(fixedPriceSelected);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
model.tradeCurrencyCode.addListener(tradeCurrencyCodeListener);
|
||||
model.marketPriceAvailableProperty.addListener(marketPriceAvailableListener);
|
||||
|
||||
// focus out
|
||||
amountTextField.focusedProperty().addListener(amountFocusedListener);
|
||||
@ -670,6 +684,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
|
||||
private void removeListeners() {
|
||||
model.tradeCurrencyCode.removeListener(tradeCurrencyCodeListener);
|
||||
model.marketPriceAvailableProperty.removeListener(marketPriceAvailableListener);
|
||||
|
||||
// focus out
|
||||
amountTextField.focusedProperty().removeListener(amountFocusedListener);
|
||||
@ -944,17 +959,16 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
xLabel.setMinWidth(14);
|
||||
xLabel.setMaxWidth(14);
|
||||
|
||||
// price as fiat
|
||||
Tuple3<HBox, InputTextField, Label> priceValueCurrencyBoxTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
|
||||
HBox priceValueCurrencyBox = priceValueCurrencyBoxTuple.first;
|
||||
fixedPriceTextField = priceValueCurrencyBoxTuple.second;
|
||||
editOfferElements.add(fixedPriceTextField);
|
||||
priceCurrencyLabel = priceValueCurrencyBoxTuple.third;
|
||||
editOfferElements.add(priceCurrencyLabel);
|
||||
Tuple2<Label, VBox> priceInputBoxTuple = getTradeInputBox(priceValueCurrencyBox, "");
|
||||
priceDescriptionLabel = priceInputBoxTuple.first;
|
||||
editOfferElements.add(priceDescriptionLabel);
|
||||
VBox priceBox = priceInputBoxTuple.second;
|
||||
// price as percent
|
||||
Tuple3<HBox, InputTextField, Label> priceAsPercentageTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
|
||||
HBox priceAsPercentageValueCurrencyBox = priceAsPercentageTuple.first;
|
||||
marketBasedPriceTextField = priceAsPercentageTuple.second;
|
||||
editOfferElements.add(marketBasedPriceTextField);
|
||||
marketBasedPriceLabel = priceAsPercentageTuple.third;
|
||||
editOfferElements.add(marketBasedPriceLabel);
|
||||
Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price");
|
||||
priceAsPercentageInputBoxTuple.first.setPrefWidth(200);
|
||||
percentagePriceBox = priceAsPercentageInputBoxTuple.second;
|
||||
|
||||
// Fixed/Percentage toggle
|
||||
ToggleGroup toggleGroup = new ToggleGroup();
|
||||
@ -963,8 +977,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
fixedPriceButton.setId("toggle-price-left");
|
||||
fixedPriceButton.setToggleGroup(toggleGroup);
|
||||
fixedPriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
model.dataModel.setUseMarketBasedPrice(!newValue);
|
||||
useMarketBasedPriceButton.setSelected(!newValue);
|
||||
updateToggleButtons(newValue);
|
||||
});
|
||||
|
||||
useMarketBasedPriceButton = new ToggleButton("Percentage");
|
||||
@ -972,13 +985,12 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
useMarketBasedPriceButton.setId("toggle-price-right");
|
||||
useMarketBasedPriceButton.setToggleGroup(toggleGroup);
|
||||
useMarketBasedPriceButton.selectedProperty().addListener((ov, oldValue, newValue) -> {
|
||||
model.dataModel.setUseMarketBasedPrice(newValue);
|
||||
fixedPriceButton.setSelected(!newValue);
|
||||
updateToggleButtons(!newValue);
|
||||
});
|
||||
|
||||
HBox toggleButtons = new HBox();
|
||||
toggleButtons.setPadding(new Insets(18, 0, 0, 0));
|
||||
toggleButtons.getChildren().addAll(fixedPriceButton, useMarketBasedPriceButton);
|
||||
toggleButtonsHBox = new HBox();
|
||||
toggleButtonsHBox.setPadding(new Insets(18, 0, 0, 0));
|
||||
toggleButtonsHBox.getChildren().addAll(fixedPriceButton, useMarketBasedPriceButton);
|
||||
|
||||
// =
|
||||
Label resultLabel = new Label("=");
|
||||
@ -997,28 +1009,69 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
editOfferElements.add(volumeDescriptionLabel);
|
||||
VBox volumeBox = volumeInputBoxTuple.second;
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setSpacing(5);
|
||||
hBox.setAlignment(Pos.CENTER_LEFT);
|
||||
hBox.getChildren().addAll(amountBox, xLabel, priceBox, toggleButtons, resultLabel, volumeBox);
|
||||
GridPane.setRowIndex(hBox, gridRow);
|
||||
GridPane.setColumnIndex(hBox, 1);
|
||||
GridPane.setMargin(hBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 10, 0, 0));
|
||||
GridPane.setColumnSpan(hBox, 2);
|
||||
gridPane.getChildren().add(hBox);
|
||||
firstRowHBox = new HBox();
|
||||
firstRowHBox.setSpacing(5);
|
||||
firstRowHBox.setAlignment(Pos.CENTER_LEFT);
|
||||
firstRowHBox.getChildren().addAll(amountBox, xLabel, percentagePriceBox, toggleButtonsHBox, resultLabel, volumeBox);
|
||||
GridPane.setRowIndex(firstRowHBox, gridRow);
|
||||
GridPane.setColumnIndex(firstRowHBox, 1);
|
||||
GridPane.setMargin(firstRowHBox, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 10, 0, 0));
|
||||
GridPane.setColumnSpan(firstRowHBox, 2);
|
||||
gridPane.getChildren().add(firstRowHBox);
|
||||
}
|
||||
|
||||
private void updateToggleButtons(boolean fixedPriceSelected) {
|
||||
int marketPriceAvailable = model.marketPriceAvailableProperty.get();
|
||||
fixedPriceSelected |= marketPriceAvailable == 0;
|
||||
|
||||
if (marketPriceAvailable == 1) {
|
||||
model.dataModel.setUseMarketBasedPrice(!fixedPriceSelected);
|
||||
|
||||
if (!fixedPriceButton.isSelected() && fixedPriceSelected)
|
||||
fixedPriceButton.setSelected(fixedPriceSelected);
|
||||
if (useMarketBasedPriceButton.isSelected() && !fixedPriceSelected)
|
||||
useMarketBasedPriceButton.setSelected(!fixedPriceSelected);
|
||||
}
|
||||
|
||||
fixedPriceButton.setMouseTransparent(fixedPriceSelected);
|
||||
useMarketBasedPriceButton.setMouseTransparent(!fixedPriceSelected);
|
||||
|
||||
fixedPriceButton.setStyle(fixedPriceSelected ? "-fx-background-color: -bs-blue-transparent" : "-fx-background-color: -bs-very-light-grey");
|
||||
useMarketBasedPriceButton.setStyle(!fixedPriceSelected ? "-fx-background-color: -bs-blue-transparent" : "-fx-background-color: -bs-very-light-grey");
|
||||
|
||||
if (fixedPriceSelected) {
|
||||
if (firstRowHBox.getChildren().contains(percentagePriceBox))
|
||||
firstRowHBox.getChildren().remove(percentagePriceBox);
|
||||
if (secondRowHBox.getChildren().contains(fixedPriceBox))
|
||||
secondRowHBox.getChildren().remove(fixedPriceBox);
|
||||
if (!firstRowHBox.getChildren().contains(fixedPriceBox))
|
||||
firstRowHBox.getChildren().add(2, fixedPriceBox);
|
||||
if (!secondRowHBox.getChildren().contains(percentagePriceBox))
|
||||
secondRowHBox.getChildren().add(percentagePriceBox);
|
||||
} else {
|
||||
if (firstRowHBox.getChildren().contains(fixedPriceBox))
|
||||
firstRowHBox.getChildren().remove(fixedPriceBox);
|
||||
if (secondRowHBox.getChildren().contains(percentagePriceBox))
|
||||
secondRowHBox.getChildren().remove(percentagePriceBox);
|
||||
if (!firstRowHBox.getChildren().contains(percentagePriceBox))
|
||||
firstRowHBox.getChildren().add(2, percentagePriceBox);
|
||||
if (!secondRowHBox.getChildren().contains(fixedPriceBox))
|
||||
secondRowHBox.getChildren().add(fixedPriceBox);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSecondRow() {
|
||||
Tuple3<HBox, InputTextField, Label> priceAsPercentageTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
|
||||
HBox priceAsPercentageValueCurrencyBox = priceAsPercentageTuple.first;
|
||||
marketBasedPriceTextField = priceAsPercentageTuple.second;
|
||||
editOfferElements.add(marketBasedPriceTextField);
|
||||
marketBasedPriceLabel = priceAsPercentageTuple.third;
|
||||
editOfferElements.add(marketBasedPriceLabel);
|
||||
|
||||
Tuple2<Label, VBox> priceAsPercentageInputBoxTuple = getTradeInputBox(priceAsPercentageValueCurrencyBox, "Distance in % from market price");
|
||||
priceAsPercentageInputBoxTuple.first.setPrefWidth(200);
|
||||
VBox priceAsPercentageInputBox = priceAsPercentageInputBoxTuple.second;
|
||||
// price as fiat
|
||||
Tuple3<HBox, InputTextField, Label> priceValueCurrencyBoxTuple = FormBuilder.getValueCurrencyBox(BSResources.get("createOffer.price.prompt"));
|
||||
HBox priceValueCurrencyBox = priceValueCurrencyBoxTuple.first;
|
||||
fixedPriceTextField = priceValueCurrencyBoxTuple.second;
|
||||
editOfferElements.add(fixedPriceTextField);
|
||||
priceCurrencyLabel = priceValueCurrencyBoxTuple.third;
|
||||
editOfferElements.add(priceCurrencyLabel);
|
||||
Tuple2<Label, VBox> priceInputBoxTuple = getTradeInputBox(priceValueCurrencyBox, "");
|
||||
priceDescriptionLabel = priceInputBoxTuple.first;
|
||||
editOfferElements.add(priceDescriptionLabel);
|
||||
fixedPriceBox = priceInputBoxTuple.second;
|
||||
|
||||
marketBasedPriceTextField.setPromptText("Enter % value");
|
||||
marketBasedPriceLabel.setText("%");
|
||||
@ -1039,15 +1092,15 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
xLabel.setPadding(new Insets(14, 3, 0, 3));
|
||||
xLabel.setVisible(false); // we just use it to get the same layout as the upper row
|
||||
|
||||
HBox hBox = new HBox();
|
||||
hBox.setSpacing(5);
|
||||
hBox.setAlignment(Pos.CENTER_LEFT);
|
||||
hBox.getChildren().addAll(amountInputBoxTuple.second, xLabel, priceAsPercentageInputBox);
|
||||
GridPane.setRowIndex(hBox, ++gridRow);
|
||||
GridPane.setColumnIndex(hBox, 1);
|
||||
GridPane.setMargin(hBox, new Insets(5, 10, 5, 0));
|
||||
GridPane.setColumnSpan(hBox, 2);
|
||||
gridPane.getChildren().add(hBox);
|
||||
secondRowHBox = new HBox();
|
||||
secondRowHBox.setSpacing(5);
|
||||
secondRowHBox.setAlignment(Pos.CENTER_LEFT);
|
||||
secondRowHBox.getChildren().addAll(amountInputBoxTuple.second, xLabel, fixedPriceBox);
|
||||
GridPane.setRowIndex(secondRowHBox, ++gridRow);
|
||||
GridPane.setColumnIndex(secondRowHBox, 1);
|
||||
GridPane.setMargin(secondRowHBox, new Insets(5, 10, 5, 0));
|
||||
GridPane.setColumnSpan(secondRowHBox, 2);
|
||||
gridPane.getChildren().add(secondRowHBox);
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,6 +126,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
private boolean inputIsMarketBasedPrice;
|
||||
private ChangeListener<Boolean> useMarketBasedPriceListener;
|
||||
private boolean ignorePriceStringListener, ignoreVolumeStringListener, ignoreAmountStringListener;
|
||||
private MarketPrice marketPrice;
|
||||
final IntegerProperty marketPriceAvailableProperty = new SimpleIntegerProperty(-1);
|
||||
private ChangeListener<Number> currenciesUpdateListener;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -161,7 +164,10 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
UserThread.runAfter(() -> {
|
||||
amount.set("1");
|
||||
minAmount.set(amount.get());
|
||||
price.set("1000");
|
||||
UserThread.runAfter(() -> {
|
||||
price.set("1000");
|
||||
onFocusOutPriceAsPercentageTextField(true, false, "");
|
||||
}, 1);
|
||||
|
||||
setAmountToModel();
|
||||
setMinAmountToModel();
|
||||
@ -247,6 +253,10 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
updateButtonDisableState();
|
||||
};
|
||||
priceStringListener = (ov, oldValue, newValue) -> {
|
||||
final String currencyCode = dataModel.tradeCurrencyCode.get();
|
||||
marketPrice = priceFeedService.getMarketPrice(currencyCode);
|
||||
marketPriceAvailableProperty.set(marketPrice == null ? 0 : 1);
|
||||
|
||||
if (!ignorePriceStringListener) {
|
||||
if (isPriceInputValid(newValue).isValid) {
|
||||
setPriceToModel();
|
||||
@ -254,8 +264,6 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
dataModel.calculateTotalToPay();
|
||||
|
||||
if (!inputIsMarketBasedPrice) {
|
||||
final String currencyCode = dataModel.tradeCurrencyCode.get();
|
||||
MarketPrice marketPrice = priceFeedService.getMarketPrice(currencyCode);
|
||||
if (marketPrice != null) {
|
||||
double marketPriceAsDouble = marketPrice.getPrice(getPriceFeedType());
|
||||
try {
|
||||
@ -280,8 +288,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
}
|
||||
}
|
||||
}
|
||||
updateButtonDisableState();
|
||||
}
|
||||
updateButtonDisableState();
|
||||
};
|
||||
marketPriceMarginStringListener = (ov, oldValue, newValue) -> {
|
||||
if (inputIsMarketBasedPrice) {
|
||||
@ -298,7 +306,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
percentage = MathUtils.roundDouble(percentage, 4);
|
||||
dataModel.setMarketPriceMargin(percentage);
|
||||
dataModel.updateTradeFee();
|
||||
|
||||
|
||||
double marketPriceAsDouble = marketPrice.getPrice(getPriceFeedType());
|
||||
double factor;
|
||||
if (CurrencyUtil.isCryptoCurrency(currencyCode))
|
||||
@ -379,6 +387,13 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
/* feeFromFundingTxListener = (ov, oldValue, newValue) -> {
|
||||
updateButtonDisableState();
|
||||
};*/
|
||||
|
||||
currenciesUpdateListener = (observable, oldValue, newValue) -> {
|
||||
final String currencyCode = dataModel.tradeCurrencyCode.get();
|
||||
marketPrice = priceFeedService.getMarketPrice(currencyCode);
|
||||
marketPriceAvailableProperty.set(marketPrice == null ? 0 : 1);
|
||||
updateButtonDisableState();
|
||||
};
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
@ -399,6 +414,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
|
||||
// dataModel.feeFromFundingTxProperty.addListener(feeFromFundingTxListener);
|
||||
dataModel.isWalletFunded.addListener(isWalletFundedListener);
|
||||
|
||||
priceFeedService.currenciesUpdateFlagProperty().addListener(currenciesUpdateListener);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
@ -420,6 +437,8 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
|
||||
if (offer != null && errorMessageListener != null)
|
||||
offer.errorMessageProperty().removeListener(errorMessageListener);
|
||||
|
||||
priceFeedService.currenciesUpdateFlagProperty().removeListener(currenciesUpdateListener);
|
||||
}
|
||||
|
||||
|
||||
@ -497,6 +516,10 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
|
||||
public void onCurrencySelected(TradeCurrency tradeCurrency) {
|
||||
dataModel.onCurrencySelected(tradeCurrency);
|
||||
|
||||
marketPrice = priceFeedService.getMarketPrice(dataModel.tradeCurrencyCode.get());
|
||||
marketPriceAvailableProperty.set(marketPrice == null ? 0 : 1);
|
||||
updateButtonDisableState();
|
||||
}
|
||||
|
||||
void onShowPayFundsScreen() {
|
||||
|
Loading…
Reference in New Issue
Block a user