load offer book views off main thread #1518

This commit is contained in:
woodser 2025-01-05 18:23:21 -05:00
parent 3e0b694e13
commit e8d5366941

View file

@ -788,11 +788,13 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
if (item != null && !empty) super.updateItem(item, empty);
setGraphic(new ColoredDecimalPlacesWithZerosText(model.getAmount(item), GUIUtil.AMOUNT_DECIMALS_WITH_ZEROS)); if (item != null && !empty)
else setGraphic(new ColoredDecimalPlacesWithZerosText(model.getAmount(item), GUIUtil.AMOUNT_DECIMALS_WITH_ZEROS));
setGraphic(null); else
setGraphic(null);
});
} }
}; };
} }
@ -817,12 +819,13 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
if (item != null && !empty) if (item != null && !empty)
setText(CurrencyUtil.getCurrencyPair(item.getOffer().getCurrencyCode())); setText(CurrencyUtil.getCurrencyPair(item.getOffer().getCurrencyCode()));
else else
setText(""); setText("");
});
} }
}; };
} }
@ -852,13 +855,15 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
if (item != null && !empty) { if (item != null && !empty) {
setGraphic(getPriceAndPercentage(item)); setGraphic(getPriceAndPercentage(item));
} else { } else {
setGraphic(null); setGraphic(null);
} }
});
} }
private HBox getPriceAndPercentage(OfferBookListItem item) { private HBox getPriceAndPercentage(OfferBookListItem item) {
@ -934,21 +939,23 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
if (item != null && !empty) { if (item != null && !empty) {
if (item.getOffer().getPrice() == null) { if (item.getOffer().getPrice() == null) {
setText(Res.get("shared.na")); setText(Res.get("shared.na"));
setGraphic(null); setGraphic(null);
} else {
setText("");
setGraphic(new ColoredDecimalPlacesWithZerosText(model.getVolume(item),
model.getNumberOfDecimalsForVolume(item)));
}
} else { } else {
setText(""); setText("");
setGraphic(new ColoredDecimalPlacesWithZerosText(model.getVolume(item), setGraphic(null);
model.getNumberOfDecimalsForVolume(item)));
} }
} else { });
setText("");
setGraphic(null);
}
} }
}; };
} }
@ -974,30 +981,32 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
if (item != null && !empty) { if (item != null && !empty) {
Offer offer = item.getOffer(); Offer offer = item.getOffer();
if (model.isOfferBanned(offer)) { if (model.isOfferBanned(offer)) {
setGraphic(new AutoTooltipLabel(model.getPaymentMethod(item))); setGraphic(new AutoTooltipLabel(model.getPaymentMethod(item)));
} else {
if (offer.isXmrAutoConf()) {
field = new HyperlinkWithIcon(model.getPaymentMethod(item), AwesomeIcon.ROCKET);
} else { } else {
field = new HyperlinkWithIcon(model.getPaymentMethod(item)); if (offer.isXmrAutoConf()) {
field = new HyperlinkWithIcon(model.getPaymentMethod(item), AwesomeIcon.ROCKET);
} else {
field = new HyperlinkWithIcon(model.getPaymentMethod(item));
}
field.setOnAction(event -> {
offerDetailsWindow.show(offer);
});
field.setTooltip(new Tooltip(model.getPaymentMethodToolTip(item)));
setGraphic(field);
} }
field.setOnAction(event -> { } else {
offerDetailsWindow.show(offer); setGraphic(null);
}); if (field != null)
field.setTooltip(new Tooltip(model.getPaymentMethodToolTip(item))); field.setOnAction(null);
setGraphic(field);
} }
} else { });
setGraphic(null);
if (field != null)
field.setOnAction(null);
}
} }
}; };
} }
@ -1026,25 +1035,28 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
if (item != null && !empty) { super.updateItem(item, empty);
var isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL;
var deposit = isSellOffer ? item.getOffer().getMaxBuyerSecurityDeposit() : if (item != null && !empty) {
item.getOffer().getMaxSellerSecurityDeposit(); var isSellOffer = item.getOffer().getDirection() == OfferDirection.SELL;
if (deposit == null) { var deposit = isSellOffer ? item.getOffer().getMaxBuyerSecurityDeposit() :
setText(Res.get("shared.na")); item.getOffer().getMaxSellerSecurityDeposit();
setGraphic(null); if (deposit == null) {
setText(Res.get("shared.na"));
setGraphic(null);
} else {
setText("");
String rangePrefix = item.getOffer().isRange() ? "<= " : "";
setGraphic(new ColoredDecimalPlacesWithZerosText(rangePrefix + model.formatDepositString(
deposit, item.getOffer().getAmount().longValueExact()),
GUIUtil.AMOUNT_DECIMALS_WITH_ZEROS));
}
} else { } else {
setText(""); setText("");
String rangePrefix = item.getOffer().isRange() ? "<= " : ""; setGraphic(null);
setGraphic(new ColoredDecimalPlacesWithZerosText(rangePrefix + model.formatDepositString(
deposit, item.getOffer().getAmount().longValueExact()),
GUIUtil.AMOUNT_DECIMALS_WITH_ZEROS));
} }
} else { });
setText("");
setGraphic(null);
}
} }
}; };
} }
@ -1071,112 +1083,114 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
final ImageView iconView = new ImageView(); final ImageView iconView = new ImageView();
final AutoTooltipButton button = new AutoTooltipButton(); final AutoTooltipButton button = new AutoTooltipButton();
{ {
button.setGraphic(iconView); button.setGraphic(iconView);
button.setGraphicTextGap(10); button.setGraphicTextGap(10);
button.setPrefWidth(10000); button.setPrefWidth(10000);
}
final ImageView iconView2 = new ImageView();
final AutoTooltipButton button2 = new AutoTooltipButton();
{
button2.setGraphic(iconView2);
button2.setGraphicTextGap(10);
button2.setPrefWidth(10000);
}
final HBox hbox = new HBox();
{
hbox.setSpacing(8);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().add(button);
hbox.getChildren().add(button2);
HBox.setHgrow(button, Priority.ALWAYS);
HBox.setHgrow(button2, Priority.ALWAYS);
}
TableRow<OfferBookListItem> tableRow = getTableRow();
if (item != null && !empty) {
Offer offer = item.getOffer();
boolean myOffer = model.isMyOffer(offer);
// https://github.com/bisq-network/bisq/issues/4986
if (tableRow != null) {
canTakeOfferResult = model.offerFilterService.canTakeOffer(offer, false);
tableRow.setOpacity(canTakeOfferResult.isValid() || myOffer ? 1 : 0.4);
if (myOffer) {
button.setDefaultButton(false);
tableRow.setOnMousePressed(null);
} else if (canTakeOfferResult.isValid()) {
// set first row button as default
button.setDefaultButton(getIndex() == 0);
tableRow.setOnMousePressed(null);
} else {
button.setDefaultButton(false);
tableRow.setOnMousePressed(e -> {
// ugly hack to get the icon clickable when deactivated
if (!(e.getTarget() instanceof ImageView || e.getTarget() instanceof Canvas))
onShowInfo(offer, canTakeOfferResult);
});
}
} }
String title; final ImageView iconView2 = new ImageView();
if (myOffer) { final AutoTooltipButton button2 = new AutoTooltipButton();
iconView.setId("image-remove");
title = Res.get("shared.remove");
button.setOnAction(e -> onRemoveOpenOffer(offer));
iconView2.setId("image-edit"); {
button2.updateText(Res.get("shared.edit")); button2.setGraphic(iconView2);
button2.setOnAction(e -> onEditOpenOffer(offer)); button2.setGraphicTextGap(10);
button2.setManaged(true); button2.setPrefWidth(10000);
button2.setVisible(true);
} else {
boolean isSellOffer = OfferViewUtil.isShownAsSellOffer(offer);
boolean isPrivateOffer = offer.isPrivateOffer();
iconView.setId(isPrivateOffer ? "image-lock2x" : isSellOffer ? "image-buy-white" : "image-sell-white");
iconView.setFitHeight(16);
iconView.setFitWidth(16);
button.setId(isSellOffer ? "buy-button" : "sell-button");
button.setStyle("-fx-text-fill: white");
title = Res.get("offerbook.takeOffer");
button.setTooltip(new Tooltip(Res.get("offerbook.takeOfferButton.tooltip", model.getDirectionLabelTooltip(offer))));
button.setOnAction(e -> onTakeOffer(offer));
button2.setManaged(false);
button2.setVisible(false);
} }
if (!myOffer) { final HBox hbox = new HBox();
if (canTakeOfferResult == null) {
{
hbox.setSpacing(8);
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().add(button);
hbox.getChildren().add(button2);
HBox.setHgrow(button, Priority.ALWAYS);
HBox.setHgrow(button2, Priority.ALWAYS);
}
TableRow<OfferBookListItem> tableRow = getTableRow();
if (item != null && !empty) {
Offer offer = item.getOffer();
boolean myOffer = model.isMyOffer(offer);
// https://github.com/bisq-network/bisq/issues/4986
if (tableRow != null) {
canTakeOfferResult = model.offerFilterService.canTakeOffer(offer, false); canTakeOfferResult = model.offerFilterService.canTakeOffer(offer, false);
tableRow.setOpacity(canTakeOfferResult.isValid() || myOffer ? 1 : 0.4);
if (myOffer) {
button.setDefaultButton(false);
tableRow.setOnMousePressed(null);
} else if (canTakeOfferResult.isValid()) {
// set first row button as default
button.setDefaultButton(getIndex() == 0);
tableRow.setOnMousePressed(null);
} else {
button.setDefaultButton(false);
tableRow.setOnMousePressed(e -> {
// ugly hack to get the icon clickable when deactivated
if (!(e.getTarget() instanceof ImageView || e.getTarget() instanceof Canvas))
onShowInfo(offer, canTakeOfferResult);
});
}
} }
if (!canTakeOfferResult.isValid()) { String title;
button.setOnAction(e -> onShowInfo(offer, canTakeOfferResult)); if (myOffer) {
iconView.setId("image-remove");
title = Res.get("shared.remove");
button.setOnAction(e -> onRemoveOpenOffer(offer));
iconView2.setId("image-edit");
button2.updateText(Res.get("shared.edit"));
button2.setOnAction(e -> onEditOpenOffer(offer));
button2.setManaged(true);
button2.setVisible(true);
} else {
boolean isSellOffer = OfferViewUtil.isShownAsSellOffer(offer);
boolean isPrivateOffer = offer.isPrivateOffer();
iconView.setId(isPrivateOffer ? "image-lock2x" : isSellOffer ? "image-buy-white" : "image-sell-white");
iconView.setFitHeight(16);
iconView.setFitWidth(16);
button.setId(isSellOffer ? "buy-button" : "sell-button");
button.setStyle("-fx-text-fill: white");
title = Res.get("offerbook.takeOffer");
button.setTooltip(new Tooltip(Res.get("offerbook.takeOfferButton.tooltip", model.getDirectionLabelTooltip(offer))));
button.setOnAction(e -> onTakeOffer(offer));
button2.setManaged(false);
button2.setVisible(false);
}
if (!myOffer) {
if (canTakeOfferResult == null) {
canTakeOfferResult = model.offerFilterService.canTakeOffer(offer, false);
}
if (!canTakeOfferResult.isValid()) {
button.setOnAction(e -> onShowInfo(offer, canTakeOfferResult));
}
}
button.updateText(title);
setPadding(new Insets(0, 15, 0, 0));
setGraphic(hbox);
} else {
setGraphic(null);
button.setOnAction(null);
button2.setOnAction(null);
if (tableRow != null) {
tableRow.setOpacity(1);
tableRow.setOnMousePressed(null);
} }
} }
});
button.updateText(title);
setPadding(new Insets(0, 15, 0, 0));
setGraphic(hbox);
} else {
setGraphic(null);
button.setOnAction(null);
button2.setOnAction(null);
if (tableRow != null) {
tableRow.setOpacity(1);
tableRow.setOnMousePressed(null);
}
}
} }
}; };
} }
@ -1204,17 +1218,19 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem item, boolean empty) { public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty); UserThread.execute(() -> {
super.updateItem(item, empty);
if (item != null && !empty) { if (item != null && !empty) {
var witnessAgeData = item.getWitnessAgeData(accountAgeWitnessService, signedWitnessService); var witnessAgeData = item.getWitnessAgeData(accountAgeWitnessService, signedWitnessService);
var label = witnessAgeData.isSigningRequired() var label = witnessAgeData.isSigningRequired()
? new AccountStatusTooltipLabel(witnessAgeData) ? new AccountStatusTooltipLabel(witnessAgeData)
: new InfoAutoTooltipLabel(witnessAgeData.getDisplayString(), witnessAgeData.getIcon(), ContentDisplay.RIGHT, witnessAgeData.getInfo()); : new InfoAutoTooltipLabel(witnessAgeData.getDisplayString(), witnessAgeData.getIcon(), ContentDisplay.RIGHT, witnessAgeData.getInfo());
setGraphic(label); setGraphic(label);
} else { } else {
setGraphic(null); setGraphic(null);
} }
});
} }
}; };
} }
@ -1240,24 +1256,26 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return new TableCell<>() { return new TableCell<>() {
@Override @Override
public void updateItem(final OfferBookListItem newItem, boolean empty) { public void updateItem(final OfferBookListItem newItem, boolean empty) {
super.updateItem(newItem, empty); UserThread.execute(() -> {
if (newItem != null && !empty) { super.updateItem(newItem, empty);
final Offer offer = newItem.getOffer(); if (newItem != null && !empty) {
final NodeAddress makersNodeAddress = offer.getOwnerNodeAddress(); final Offer offer = newItem.getOffer();
String role = Res.get("peerInfoIcon.tooltip.maker"); final NodeAddress makersNodeAddress = offer.getOwnerNodeAddress();
int numTrades = model.getNumTrades(offer); String role = Res.get("peerInfoIcon.tooltip.maker");
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(makersNodeAddress, int numTrades = model.getNumTrades(offer);
role, PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(makersNodeAddress,
numTrades, role,
privateNotificationManager, numTrades,
offer, privateNotificationManager,
model.preferences, offer,
model.accountAgeWitnessService, model.preferences,
useDevPrivilegeKeys); model.accountAgeWitnessService,
setGraphic(peerInfoIcon); useDevPrivilegeKeys);
} else { setGraphic(peerInfoIcon);
setGraphic(null); } else {
} setGraphic(null);
}
});
} }
}; };
} }