Skip to content

Commit

Permalink
Merge pull request #2052 from axpoems/fix-accept-price-overlay
Browse files Browse the repository at this point in the history
Various fixes and improvements for buyer as maker case
  • Loading branch information
djing-chan authored Apr 15, 2024
2 parents fa5df7e + efabc5a commit 7cb2605
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

import javax.annotation.Nullable;
import java.util.Optional;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;

Expand Down Expand Up @@ -120,7 +121,10 @@ public void onActivate() {
tradePhaseBox.setBisqEasyTrade(bisqEasyTrade);

bisqEasyTradeStatePin = bisqEasyTrade.tradeStateObservable().addObserver(state ->
UIThread.run(() -> applyStateInfoVBox(state)));
UIThread.run(() -> {
applyStateInfoVBox(state);
updateShouldShowSellerPriceApprovalOverlay();
}));

errorMessagePin = bisqEasyTrade.errorMessageObservable().addObserver(errorMessage -> {
if (errorMessage != null) {
Expand Down Expand Up @@ -207,26 +211,29 @@ void onInterruptTrade() {

new Popup().warning(message)
.actionButtonText(Res.get("confirmation.yes"))
.onAction(() -> {
switch (model.getTradeCloseType()) {
case REJECT:
channelService.sendSystemMessage(Res.get("bisqEasy.openTrades.systemMessage.rejected",
model.getChannel().get().getMyUserIdentity().getUserName()), model.getChannel().get());
bisqEasyTradeService.rejectTrade(trade);
break;
case CANCEL:
channelService.sendSystemMessage(Res.get("bisqEasy.openTrades.systemMessage.cancelled",
model.getChannel().get().getMyUserIdentity().getUserName()), model.getChannel().get());
bisqEasyTradeService.cancelTrade(trade);
break;
case COMPLETED:
default:
}
})
.onAction(this::doInterruptTrade)
.closeButtonText(Res.get("confirmation.no"))
.show();
}

void doInterruptTrade() {
BisqEasyTrade trade = model.getBisqEasyTrade().get();
switch (model.getTradeCloseType()) {
case REJECT:
channelService.sendSystemMessage(Res.get("bisqEasy.openTrades.systemMessage.rejected",
model.getChannel().get().getMyUserIdentity().getUserName()), model.getChannel().get());
bisqEasyTradeService.rejectTrade(trade);
break;
case CANCEL:
channelService.sendSystemMessage(Res.get("bisqEasy.openTrades.systemMessage.cancelled",
model.getChannel().get().getMyUserIdentity().getUserName()), model.getChannel().get());
bisqEasyTradeService.cancelTrade(trade);
break;
case COMPLETED:
default:
}
}

void onCloseTrade() {
new Popup().warning(Res.get("bisqEasy.openTrades.closeTrade.warning.interrupted"))
.actionButtonText(Res.get("confirmation.yes"))
Expand Down Expand Up @@ -482,6 +489,15 @@ && requiresSellerPriceAcceptance()
private boolean requiresSellerPriceAcceptance() {
PriceSpec buyerPriceSpec = model.getBisqEasyTrade().get().getOffer().getPriceSpec();
PriceSpec sellerPriceSpec = model.getBisqEasyTrade().get().getContract().getAgreedPriceSpec();
return !buyerPriceSpec.equals(sellerPriceSpec);
boolean priceSpecChanged = !buyerPriceSpec.equals(sellerPriceSpec);

Set<BisqEasyTradeState> validStatesToRejectPrice = Set.of(
BisqEasyTradeState.MAKER_SENT_TAKE_OFFER_RESPONSE__BUYER_DID_NOT_SENT_BTC_ADDRESS__BUYER_DID_NOT_RECEIVED_ACCOUNT_DATA,
BisqEasyTradeState.MAKER_SENT_TAKE_OFFER_RESPONSE__BUYER_DID_NOT_SENT_BTC_ADDRESS__BUYER_RECEIVED_ACCOUNT_DATA,
BisqEasyTradeState.MAKER_DID_NOT_SENT_TAKE_OFFER_RESPONSE__BUYER_DID_NOT_SENT_BTC_ADDRESS__BUYER_RECEIVED_ACCOUNT_DATA,
BisqEasyTradeState.MAKER_SENT_TAKE_OFFER_RESPONSE__BUYER_DID_NOT_SENT_BTC_ADDRESS__BUYER_RECEIVED_ACCOUNT_DATA_
);
boolean isInValidStateToRejectPrice = validStatesToRejectPrice.contains(model.getBisqEasyTrade().get().tradeStateObservable().get());
return priceSpecChanged && isInValidStateToRejectPrice;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public class TradeStateView extends View<VBox, TradeStateModel, TradeStateContro
private final Button cancelButton, closeTradeButton, exportButton, reportToMediatorButton, acceptSellersPriceButton,
rejectPriceButton;
private final Label cancelledInfo, errorMessage;
private VBox sellerPriceApprovalOverlay;
private Pane sellerPriceApprovalContent;
private final VBox sellerPriceApprovalOverlay;
private final Pane sellerPriceApprovalContent;
private Subscription stateInfoVBoxPin, showSellersPriceApprovalOverlayPin, sellerPriceApprovalContentPin;

public TradeStateView(TradeStateModel model,
Expand All @@ -57,10 +57,6 @@ public TradeStateView(TradeStateModel model,
cancelButton.setMinWidth(160);
cancelButton.getStyleClass().add("outlined-button");

rejectPriceButton = new Button();
rejectPriceButton.setMinWidth(160);
rejectPriceButton.setDefaultButton(true);

tradeDataHeader.getChildren().addAll(Spacer.fillHBox(), cancelButton);


Expand Down Expand Up @@ -116,9 +112,14 @@ public TradeStateView(TradeStateModel model,
VBox content = new VBox(tradeDataHeader, Layout.hLine(), isInMediationHBox, interruptedHBox, phaseAndInfoHBox);
content.getStyleClass().add("bisq-easy-container");

// Accept seller's price overlay
sellerPriceApprovalContent = new Pane();
acceptSellersPriceButton = new Button(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.button.accept"));
acceptSellersPriceButton.getStyleClass().add("outlined-button");
setUpSellerPriceApprovalOverlay();
rejectPriceButton = new Button();
rejectPriceButton.setMinWidth(160);
rejectPriceButton.setDefaultButton(true);
sellerPriceApprovalOverlay = createAndGetSellerPriceApprovalOverlay();

StackPane layeredContent = new StackPane(content, sellerPriceApprovalOverlay);
root.getChildren().add(layeredContent);
Expand All @@ -143,12 +144,10 @@ protected void onViewAttached() {
errorMessage.textProperty().bind(model.getErrorMessage());

cancelButton.textProperty().bind(model.getInterruptTradeButtonText());
cancelButton.visibleProperty().bind(model.getCancelButtonVisible());
cancelButton.managedProperty().bind(model.getCancelButtonVisible());
cancelButton.visibleProperty().bind(model.getCancelButtonVisible().and(model.getShouldShowSellerPriceApprovalOverlay().not()));
cancelButton.managedProperty().bind(model.getCancelButtonVisible().and(model.getShouldShowSellerPriceApprovalOverlay().not()));

rejectPriceButton.textProperty().bind(model.getInterruptTradeButtonText());
rejectPriceButton.visibleProperty().bind(model.getCancelButtonVisible());
rejectPriceButton.managedProperty().bind(model.getCancelButtonVisible());

stateInfoVBoxPin = EasyBind.subscribe(model.getStateInfoVBox(), stateInfoVBox -> {
if (phaseAndInfoHBox.getChildren().size() == 2) {
Expand Down Expand Up @@ -184,7 +183,7 @@ protected void onViewAttached() {
cancelButton.setOnAction(e -> controller.onInterruptTrade());
closeTradeButton.setOnAction(e -> controller.onCloseTrade());
exportButton.setOnAction(e -> controller.onExportTrade());
rejectPriceButton.setOnAction(e -> controller.onInterruptTrade());
rejectPriceButton.setOnAction(e -> controller.doInterruptTrade());
reportToMediatorButton.setOnAction(e -> controller.onReportToMediator());
acceptSellersPriceButton.setOnAction(e -> controller.onAcceptSellersPriceButton());
}
Expand Down Expand Up @@ -212,8 +211,6 @@ protected void onViewDetached() {
cancelButton.managedProperty().unbind();

rejectPriceButton.textProperty().unbind();
rejectPriceButton.visibleProperty().unbind();
rejectPriceButton.managedProperty().unbind();

stateInfoVBoxPin.unsubscribe();
showSellersPriceApprovalOverlayPin.unsubscribe();
Expand All @@ -231,26 +228,33 @@ protected void onViewDetached() {
}
}

private void setUpSellerPriceApprovalOverlay() {
sellerPriceApprovalOverlay = new VBox();
sellerPriceApprovalOverlay.setAlignment(Pos.TOP_LEFT);
sellerPriceApprovalOverlay.getStyleClass().addAll("trade-wizard-feedback-bg", "seller-price-approval-popup");
sellerPriceApprovalOverlay.visibleProperty().set(false);
sellerPriceApprovalOverlay.managedProperty().set(false);
private VBox createAndGetSellerPriceApprovalOverlay() {
VBox overlay = new VBox(10);
overlay.setAlignment(Pos.TOP_LEFT);
overlay.getStyleClass().addAll("trade-wizard-feedback-bg", "seller-price-approval-popup");
overlay.visibleProperty().set(false);
overlay.managedProperty().set(false);

Label titleLabel = new Label(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.title"));
titleLabel.getStyleClass().addAll("seller-price-approval-title", "large-text", "font-default");

Label sellerPriceApprovalTitleLabel = new Label(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.title"));
sellerPriceApprovalTitleLabel.getStyleClass().addAll("seller-price-approval-title", "large-text", "font-default");
sellerPriceApprovalContent = new Pane();
sellerPriceApprovalContent.getStyleClass().addAll("seller-price-approval-description", "normal-text", "font-default");
Label sellerPriceApprovalQuestionLabel = new Label(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.description.question"));
sellerPriceApprovalQuestionLabel.getStyleClass().addAll("seller-price-approval-description", "normal-text",

Label questionLabel = new Label(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.description.question"));
questionLabel.getStyleClass().addAll("seller-price-approval-description", "normal-text",
"font-default", "seller-price-approval-question");
HBox sellerPriceApprovalButtons = new HBox(10, acceptSellersPriceButton, rejectPriceButton);
sellerPriceApprovalButtons.setAlignment(Pos.BOTTOM_RIGHT);

sellerPriceApprovalOverlay.getChildren().addAll(sellerPriceApprovalTitleLabel, sellerPriceApprovalContent,
sellerPriceApprovalQuestionLabel, Spacer.fillVBox(), sellerPriceApprovalButtons);
StackPane.setAlignment(sellerPriceApprovalOverlay, Pos.TOP_CENTER);
StackPane.setMargin(sellerPriceApprovalOverlay, new Insets(63, 0, 0, 0));
Label disclaimerLabel = new Label(Res.get("bisqEasy.tradeState.acceptOrRejectSellersPrice.description.disclaimer"));
disclaimerLabel.getStyleClass().addAll("seller-price-approval-description", "small-text", "font-default",
"seller-price-approval-disclaimer");

HBox acceptOrRejectButtons = new HBox(10, acceptSellersPriceButton, rejectPriceButton);
acceptOrRejectButtons.setAlignment(Pos.BOTTOM_RIGHT);

overlay.getChildren().addAll(titleLabel, sellerPriceApprovalContent,
questionLabel, disclaimerLabel, Spacer.fillVBox(), acceptOrRejectButtons);
StackPane.setAlignment(overlay, Pos.TOP_CENTER);
StackPane.setMargin(overlay, new Insets(63, 0, 0, 0));
return overlay;
}
}
11 changes: 9 additions & 2 deletions apps/desktop/desktop/src/main/resources/css/bisq_easy.css
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@
.seller-price-approval-popup .seller-price-approval-content {
-fx-fill: -fx-light-text-color;
-fx-text-fill: -fx-light-text-color;
-fx-padding: 30 0 0 0;
-fx-padding: 15 0 0 0;
-fx-spacing: 10;
}

Expand All @@ -464,7 +464,14 @@
}

.seller-price-approval-popup .seller-price-approval-question {
-fx-padding: 30 0 0 0;
-fx-line-spacing: 10;
}

.seller-price-approval-popup .seller-price-approval-disclaimer {
-fx-padding: 10 0 0 0;
-fx-fill: -fx-mid-text-color;
-fx-text-fill: -fx-mid-text-color;
-fx-line-spacing: 10;
}


Expand Down
11 changes: 6 additions & 5 deletions i18n/src/main/resources/bisq_easy.properties
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bisqEasy.price.feedback.sentence.veryGood=very good
bisqEasy.price.feedback.learnWhySection.openButton=Why?
bisqEasy.price.feedback.learnWhySection.closeButton=Back to Trade Price
bisqEasy.price.feedback.learnWhySection.title=Why should I pay a higher price to the seller?
bisqEasy.price.feedback.learnWhySection.description.intro=The reason for that is that the seller has to cover extra expenses\
bisqEasy.price.feedback.learnWhySection.description.intro=The reason for that is that the seller has to cover extra expenses \
and compensate for the seller's service specifically:
bisqEasy.price.feedback.learnWhySection.description.exposition=\
- Build up reputation which can be costly.\
Expand Down Expand Up @@ -576,10 +576,11 @@ bisqEasy.openTrades.welcome.line3=Make yourself familiar with the trade rules

bisqEasy.tradeState.requestMediation=Request mediation
bisqEasy.tradeState.reportToMediator=Report to mediator
bisqEasy.tradeState.acceptOrRejectSellersPrice.title=Attention!
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.buyersPrice=Your offer price to buy Bitcoin was: {0}.
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.sellersPrice=However, the seller is offering you this price: {0}.
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.question=Do you want to accept this new price or do you want to cancel/reject the trade?
bisqEasy.tradeState.acceptOrRejectSellersPrice.title=Attention to Price Change!
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.buyersPrice=Your offer price to buy Bitcoin was {0}.
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.sellersPrice=However, the seller is offering you this price {0}.
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.question=Do you want to accept this new price or do you want to reject/cancel* the trade?
bisqEasy.tradeState.acceptOrRejectSellersPrice.description.disclaimer=(*Note that in this specific case, cancelling the trade will NOT be considered a violation of the trading rules.)
bisqEasy.tradeState.acceptOrRejectSellersPrice.button.accept=Accept price

# Trade State: Header
Expand Down

0 comments on commit 7cb2605

Please sign in to comment.