Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate amount and price in create offer wizard #3057

Merged
merged 33 commits into from
Dec 19, 2024
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
aa496c6
refactor: rename trade wizard direction and market package
axpoems Nov 2, 2024
c899d6a
Add new page to trade wizard consolidating amount and price
axpoems Nov 3, 2024
67866b4
Use amount component inside amountAndPrice
axpoems Nov 3, 2024
9d93baa
Add new amount model selection
axpoems Nov 3, 2024
640f617
Refactor: rename IsMinAmountEnabled to isRangeAmountEnabled
axpoems Nov 3, 2024
a76fc47
Add logic to new amount model selection buttons
axpoems Nov 3, 2024
352a815
Remove old toggle to switch between amount model
axpoems Nov 3, 2024
d78b85f
Remove old description texts
axpoems Nov 3, 2024
08947f0
Improve AmountComponent
axpoems Nov 4, 2024
1fb01da
More improvements in amount component
axpoems Nov 4, 2024
1605975
Refactor: split amount component into controller/model/view files
axpoems Nov 5, 2024
2e5101a
Improve amount component for the case of using range
axpoems Nov 5, 2024
f2c1b97
Apply new design for amount ranges
axpoems Nov 6, 2024
5e1e782
Several improvements
axpoems Dec 9, 2024
25164eb
Add double slider to select amount range
axpoems Dec 11, 2024
a603c6e
Improve slider labels
axpoems Dec 11, 2024
d0bcb0f
Fix amount limit info
axpoems Dec 11, 2024
1d755f1
Separate info and warnings section from main amount component
axpoems Dec 12, 2024
cb7d9e1
Add price component into amountAndPrice
axpoems Dec 12, 2024
ad669f8
Align amount and price input box design
axpoems Dec 15, 2024
c0969c6
Fix price text input font size selection
axpoems Dec 15, 2024
b6e83a2
Set conversion price
axpoems Dec 15, 2024
d7ecb64
Use same input box for percentage price selection
axpoems Dec 15, 2024
afd2c68
Adjust visibilities depending on whether is create or select offer
axpoems Dec 16, 2024
c1d1bf3
Fix overlapping issues
axpoems Dec 17, 2024
c605427
Open overlay from amountAtPrice
axpoems Dec 17, 2024
3b3331f
Fix range amount focus
axpoems Dec 17, 2024
cba1fb4
Add style improvements
axpoems Dec 17, 2024
4285633
Remove min/max labels in slider
axpoems Dec 18, 2024
eb8147c
Fix position of slider indicators
axpoems Dec 18, 2024
3a7c88a
Fix issue with percentage price not sticking
axpoems Dec 18, 2024
3f9aac3
Only apply price spec in select offer wizard
axpoems Dec 18, 2024
dcdeb09
Adjust paddings
axpoems Dec 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ public class MaterialTextField extends Pane {
@Getter
protected final Label errorLabel = new Label();
@Getter
private final BisqIconButton iconButton = new BisqIconButton();
protected final BisqIconButton iconButton = new BisqIconButton();
protected final ValidationControl validationControl;
private final BooleanProperty isValid = new SimpleBooleanProperty(false);
private Optional<StringConverter<Number>> stringConverter = Optional.empty();

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -23,12 +23,19 @@
import bisq.common.observable.Pin;
import bisq.common.util.MathUtils;
import bisq.desktop.common.threading.UIThread;
import bisq.desktop.components.controls.MaterialTextField;
import bisq.desktop.components.controls.validator.NumberValidator;
import bisq.i18n.Res;
import bisq.presentation.formatters.PriceFormatter;
import bisq.presentation.parser.PriceParser;
import javafx.beans.property.*;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import lombok.Getter;
@@ -66,6 +73,10 @@ public void setQuote(PriceQuote priceQuote) {
controller.setQuote(priceQuote);
}

public void setPercentage(String percentage) {
controller.setPercentage(percentage);
}

public void setIsTakeOffer() {
controller.model.isEditable = false;
}
@@ -129,9 +140,14 @@ public void setQuote(PriceQuote priceQuote) {
model.priceQuote.set(priceQuote);
}

public void setPercentage(String percentage) {
model.percentagePriceString.set(percentage);
}

private void updateFromMarketPrice() {
if (model.market != null && model.description.get() == null) {
model.description.set(Res.get("component.priceInput.description", model.market.getMarketCodes()));
model.textInputCurrencyCodes.set(model.market.getMarketCodes());
}
if (model.isEditable) {
setQuoteFromMarketPrice();
@@ -145,7 +161,9 @@ public void onActivate() {

marketPricePin = marketPriceService.getMarketPriceByCurrencyMap().addObserver(() -> {
// We only set it initially
if (model.priceQuote.get() != null) return;
if (model.priceQuote.get() != null) {
return;
}
UIThread.run(this::setQuoteFromMarketPrice);
});

@@ -196,7 +214,9 @@ private void onFocusedChanged(boolean isFocused) {
}

private void setQuoteFromMarketPrice() {
if (model.market == null) return;
if (model.market == null) {
return;
}
marketPriceService.findMarketPrice(model.market)
.ifPresent(marketPrice -> model.priceQuote.set(marketPrice.getPriceQuote()));
}
@@ -209,6 +229,8 @@ private static class Model implements bisq.desktop.common.view.Model {
private Market market;
private boolean isFocused;
private final StringProperty description = new SimpleStringProperty();
private final StringProperty textInputCurrencyCodes = new SimpleStringProperty();
private final StringProperty percentagePriceString = new SimpleStringProperty();
private boolean isEditable = true;
private final BooleanProperty isPriceValid = new SimpleBooleanProperty();
private final BooleanProperty doResetValidation = new SimpleBooleanProperty();
@@ -222,29 +244,35 @@ public void reset() {
market = null;
isFocused = false;
description.set(null);
textInputCurrencyCodes.set(null);
percentagePriceString.set(null);
isEditable = true;
}
}

public static class View extends bisq.desktop.common.view.View<Pane, Model, Controller> {
private final static int WIDTH = 250;
private final MaterialTextField textInput;
private final PriceInputBox textInput;
private Subscription focusedPin, doResetValidationPin;

private View(Model model, Controller controller, NumberValidator validator) {
super(new VBox(), model, controller);

textInput = new MaterialTextField(model.description.get(), Res.get("component.priceInput.prompt"));
textInput = new PriceInputBox(model.description.get(), Res.get("component.priceInput.prompt"));
textInput.setPrefWidth(WIDTH);
textInput.setValidator(validator);
textInput.conversionPriceSymbolTextProperty().set("%");

root.getChildren().add(textInput);
}

@Override
protected void onViewAttached() {
textInput.descriptionProperty().bind(model.description);
textInput.textInputSymbolTextProperty().bind(model.textInputCurrencyCodes);
textInput.conversionPriceTextProperty().bind(model.percentagePriceString);
textInput.textProperty().bindBidirectional(model.priceString);
textInput.initialize();
focusedPin = EasyBind.subscribe(textInput.textInputFocusedProperty(), controller::onFocusedChanged);
doResetValidationPin = EasyBind.subscribe(model.doResetValidation, doResetValidation -> {
if (doResetValidation != null && doResetValidation) {
@@ -257,10 +285,13 @@ protected void onViewAttached() {
@Override
protected void onViewDetached() {
textInput.descriptionProperty().unbind();
textInput.textInputSymbolTextProperty().unbind();
textInput.conversionPriceTextProperty().unbind();
textInput.textProperty().unbindBidirectional(model.priceString);
textInput.resetValidation();
textInput.dispose();
focusedPin.unsubscribe();
doResetValidationPin.unsubscribe();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.main.content.bisq_easy.components;

import bisq.desktop.components.controls.MaterialTextField;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PriceInputBox extends MaterialTextField {
public final static int AMOUNT_BOX_WIDTH = 340;
public final static int AMOUNT_BOX_HEIGHT = 127;
private final static String INPUT_TEXT_9_STYLE_CLASS = "input-text-9";
private final static String INPUT_TEXT_10_STYLE_CLASS = "input-text-10";
private final static String INPUT_TEXT_11_STYLE_CLASS = "input-text-11";
private final static String INPUT_TEXT_12_STYLE_CLASS = "input-text-12";
private final static String INPUT_TEXT_13_STYLE_CLASS = "input-text-13";
private final static String INPUT_TEXT_14_STYLE_CLASS = "input-text-14";

private final Label textInputSymbolLabel, conversionPriceLabel, conversionPriceLabelSymbol;
private final HBox textInputAndSymbolHBox;
private final ChangeListener<Number> textInputLengthListener;

public PriceInputBox(String description, String prompt) {
super(description, prompt);

bg.getStyleClass().setAll("bisq-dual-amount-bg");

descriptionLabel.setLayoutX(20);
descriptionLabel.setPadding(new Insets(2, 0, 0, 0));
textInputSymbolLabel = new Label();
textInputSymbolLabel.getStyleClass().add("text-input-symbol");
textInputAndSymbolHBox = new HBox(10, textInputControl, textInputSymbolLabel);
textInputAndSymbolHBox.setLayoutY(27);

conversionPriceLabel = new Label();
conversionPriceLabel.getStyleClass().add("conversion-price");
conversionPriceLabelSymbol = new Label();
conversionPriceLabelSymbol.getStyleClass().add("conversion-price-symbol");
HBox conversionPriceBox = new HBox(7, conversionPriceLabel, conversionPriceLabelSymbol);
conversionPriceBox.getStyleClass().add("conversion-price-box");
conversionPriceBox.setLayoutY(97);

getChildren().setAll(bg, conversionPriceBox, line, selectionLine, descriptionLabel, textInputAndSymbolHBox, iconButton, helpLabel, errorLabel);
getStyleClass().add("price-input-box");

textInputLengthListener = (observable, oldValue, newValue) -> applyFontStyle(newValue.intValue());
initialize();
}

public PriceInputBox(String description) {
this(description, null);
}

public void initialize() {
textInputControl.lengthProperty().addListener(textInputLengthListener);
}

public void dispose() {
textInputControl.lengthProperty().removeListener(textInputLengthListener);
}

public final StringProperty textInputSymbolTextProperty() {
return textInputSymbolLabel.textProperty();
}

public final StringProperty conversionPriceTextProperty() {
return conversionPriceLabel.textProperty();
}

public final StringProperty conversionPriceSymbolTextProperty() {
return conversionPriceLabelSymbol.textProperty();
}

private void applyFontStyle(int length) {
textInputAndSymbolHBox.getStyleClass().clear();
textInputAndSymbolHBox.getStyleClass().addAll("text-input-and-units-box",
getFontStyleBasedOnTextLength(length));
}

@Override
protected double getBgHeight() {
return AMOUNT_BOX_HEIGHT;
}

private static String getFontStyleBasedOnTextLength(int charCount) {
if (charCount < 9) {
return INPUT_TEXT_9_STYLE_CLASS;
}
if (charCount == 9) {
return INPUT_TEXT_10_STYLE_CLASS;
}
if (charCount == 10) {
return INPUT_TEXT_11_STYLE_CLASS;
}
if (charCount == 11) {
return INPUT_TEXT_12_STYLE_CLASS;
}
if (charCount == 12) {
return INPUT_TEXT_13_STYLE_CLASS;
}
return INPUT_TEXT_14_STYLE_CLASS;
}
}
Loading
Loading