Skip to content

Commit

Permalink
Merge pull request #2032 from axpoems/add-feedback-to-price-step
Browse files Browse the repository at this point in the history
Add feedback for buyer in price step
  • Loading branch information
djing-chan authored Apr 13, 2024
2 parents c7d177c + a32db26 commit a6a3998
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public void onActivate() {
tradeWizardSelectOfferController.setDirection(direction);
tradeWizardAmountController.setDirection(direction);
tradeWizardPaymentMethodController.setDirection(direction);
tradeWizardPriceController.setDirection(direction);
});
marketPin = EasyBind.subscribe(tradeWizardMarketController.getMarket(), market -> {
tradeWizardSelectOfferController.setMarket(market);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@
import bisq.desktop.components.overlay.Popup;
import bisq.desktop.main.content.bisq_easy.components.PriceInput;
import bisq.i18n.Res;
import bisq.offer.Direction;
import bisq.offer.price.PriceUtil;
import bisq.offer.price.spec.*;
import bisq.offer.price.spec.FixPriceSpec;
import bisq.offer.price.spec.FloatPriceSpec;
import bisq.offer.price.spec.MarketPriceSpec;
import bisq.offer.price.spec.PriceSpec;
import bisq.offer.price.spec.PriceSpecUtil;
import bisq.presentation.formatters.PriceFormatter;
import bisq.settings.CookieKey;
import bisq.settings.SettingsService;
Expand All @@ -50,7 +55,7 @@ public class TradeWizardPriceController implements Controller {
private final PriceInput priceInput;
private final MarketPriceService marketPriceService;
private final SettingsService settingsService;
private Subscription priceInputPin, isPriceInvalidPin;
private Subscription priceInputPin, isPriceInvalidPin, priceSpecPin;
@Nullable
private Popup invalidPricePopup;

Expand All @@ -70,6 +75,12 @@ public void setMarket(Market market) {
model.setMarket(market);
}

public void setDirection(Direction direction) {
if (direction != null) {
model.setDirection(direction);
}
}

public ReadOnlyObjectProperty<PriceSpec> getPriceSpec() {
return model.getPriceSpec();
}
Expand Down Expand Up @@ -100,9 +111,12 @@ public void onActivate() {
maybeShowPopup();
}
});
priceSpecPin = EasyBind.subscribe(model.getPriceSpec(), this::updateFeedback);

String marketCodes = model.getMarket().getMarketCodes();
priceInput.setDescription(Res.get("bisqEasy.price.tradePrice", marketCodes));
priceInput.setDescription(Res.get("bisqEasy.price.tradePrice.inputBoxText", marketCodes));

model.getShouldShowFeedback().set(model.getDirection().isBuy());

applyPriceSpec();
}
Expand All @@ -111,6 +125,7 @@ public void onActivate() {
public void onDeactivate() {
priceInputPin.unsubscribe();
isPriceInvalidPin.unsubscribe();
priceSpecPin.unsubscribe();
}

void onPercentageFocussed(boolean focussed) {
Expand Down Expand Up @@ -158,6 +173,26 @@ void onToggleUseFixPrice() {
applyPriceSpec();
}

void useFixedPrice() {
if (!model.getUseFixPrice().get()) {
onToggleUseFixPrice();
}
}

void usePercentagePrice() {
if (model.getUseFixPrice().get()) {
onToggleUseFixPrice();
}
}

void showLearnWhySection() {
model.getShouldShowLearnWhyOverlay().set(true);
}

void closeLearnWhySection() {
model.getShouldShowLearnWhyOverlay().set(false);
}

private void applyPriceSpec() {
if (model.getUseFixPrice().get()) {
model.getPriceSpec().set(new FixPriceSpec(priceInput.getQuote().get()));
Expand Down Expand Up @@ -253,5 +288,34 @@ private void maybeShowPopup() {
.show();
}
}
}

private void updateFeedback(PriceSpec priceSpec) {
// TODO: We should show the recommended % price based on the selected amount: e.g.
// amount range recommended price
// 0.0001 BTC - 0.001 BTC 10-15%
// 0.001 BTC - 0.01 BTC 2-10%
Optional<Double> percentage = PriceUtil.findPercentFromMarketPrice(marketPriceService, priceSpec, model.getMarket());
if (percentage.isPresent()) {
double percentageValue = percentage.get();
String feedbackSentence;
if (percentageValue < -0.05) {
feedbackSentence = getFeedbackSentence(Res.get("bisqEasy.price.feedback.sentence.veryLow"));
} else if (percentageValue < 0d) {
feedbackSentence = getFeedbackSentence(Res.get("bisqEasy.price.feedback.sentence.low"));
} else if (percentageValue < 0.05) {
feedbackSentence = getFeedbackSentence(Res.get("bisqEasy.price.feedback.sentence.some"));
} else if (percentageValue < 0.15) {
feedbackSentence = getFeedbackSentence(Res.get("bisqEasy.price.feedback.sentence.good"));
} else {
feedbackSentence = getFeedbackSentence(Res.get("bisqEasy.price.feedback.sentence.veryGood"));
}
model.getFeedbackSentence().set(feedbackSentence);
} else {
model.getFeedbackSentence().set(null);
}
}

private String getFeedbackSentence(String adjective) {
return Res.get("bisqEasy.price.feedback.sentence", adjective);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@
import bisq.common.currency.Market;
import bisq.common.monetary.PriceQuote;
import bisq.desktop.common.view.Model;
import bisq.offer.Direction;
import bisq.offer.price.spec.MarketPriceSpec;
import bisq.offer.price.spec.PriceSpec;
import javafx.beans.property.*;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import lombok.Getter;
import lombok.Setter;

Expand All @@ -32,6 +40,8 @@
public class TradeWizardPriceModel implements Model {
@Setter
private Market market = null;
@Setter
private Direction direction;
private final DoubleProperty percentage = new SimpleDoubleProperty();
private final StringProperty percentageAsString = new SimpleStringProperty();
private final StringProperty priceAsString = new SimpleStringProperty();
Expand All @@ -41,15 +51,22 @@ public class TradeWizardPriceModel implements Model {
@Nullable
@Setter
private PriceQuote lastValidPriceQuote;
private final StringProperty feedbackSentence = new SimpleStringProperty();
private final BooleanProperty shouldShowLearnWhyOverlay = new SimpleBooleanProperty();
private final BooleanProperty shouldShowFeedback = new SimpleBooleanProperty();

public void reset() {
market = null;
direction = null;
percentage.set(0d);
percentageAsString.set(null);
priceAsString.set(null);
useFixPrice.set(false);
priceSpec.set(new MarketPriceSpec());
invalidPriceErrorMessage.set(null);
lastValidPriceQuote = null;
feedbackSentence.set(null);
shouldShowLearnWhyOverlay.set(false);
shouldShowFeedback.set(false);
}
}
}
Loading

0 comments on commit a6a3998

Please sign in to comment.