Merge branch 'master' of https://github.com/bisq-network/bisq into master_upstream

This commit is contained in:
chimp1984 2021-02-01 11:23:17 -05:00
commit 927ab2de21
No known key found for this signature in database
GPG key ID: 9801B4EC591F90E3
5 changed files with 69 additions and 69 deletions

View file

@ -85,10 +85,10 @@ import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.text.TextAlignment;
@ -113,6 +113,8 @@ import javafx.util.StringConverter;
import java.util.Comparator;
import java.util.Optional;
import org.jetbrains.annotations.NotNull;
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
@FxmlView
@ -173,10 +175,10 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
final TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 2, Res.get("offerbook.availableOffers"));
titledGroupBg.getStyleClass().add("last");
HBox hBox = new HBox();
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setSpacing(35);
hBox.setPadding(new Insets(10, 0, 0, 0));
HBox offerToolsBox = new HBox();
offerToolsBox.setAlignment(Pos.BOTTOM_LEFT);
offerToolsBox.setSpacing(10);
offerToolsBox.setPadding(new Insets(10, 0, 0, 0));
Tuple3<VBox, Label, AutocompleteComboBox<TradeCurrency>> currencyBoxTuple = FormBuilder.addTopLabelAutocompleteComboBox(
Res.get("offerbook.filterByCurrency"));
@ -193,25 +195,19 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
matchingOffersToggle.setText(Res.get("offerbook.matchingOffers"));
HBox.setMargin(matchingOffersToggle, new Insets(7, 0, -9, -15));
hBox.getChildren().addAll(currencyBoxTuple.first, paymentBoxTuple.first, matchingOffersToggle);
AnchorPane.setLeftAnchor(hBox, 0d);
AnchorPane.setTopAnchor(hBox, 0d);
AnchorPane.setBottomAnchor(hBox, 0d);
createOfferButton = new AutoTooltipButton();
createOfferButton.setMinHeight(40);
createOfferButton.setGraphicTextGap(10);
AnchorPane.setRightAnchor(createOfferButton, 0d);
AnchorPane.setBottomAnchor(createOfferButton, 0d);
AnchorPane anchorPane = new AnchorPane();
anchorPane.getChildren().addAll(hBox, createOfferButton);
offerToolsBox.getChildren().addAll(currencyBoxTuple.first, paymentBoxTuple.first,
matchingOffersToggle, getSpacer(), createOfferButton);
GridPane.setHgrow(anchorPane, Priority.ALWAYS);
GridPane.setRowIndex(anchorPane, gridRow);
GridPane.setColumnSpan(anchorPane, 2);
GridPane.setMargin(anchorPane, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 0));
root.getChildren().add(anchorPane);
GridPane.setHgrow(offerToolsBox, Priority.ALWAYS);
GridPane.setRowIndex(offerToolsBox, gridRow);
GridPane.setColumnSpan(offerToolsBox, 2);
GridPane.setMargin(offerToolsBox, new Insets(Layout.FIRST_ROW_DISTANCE, 0, 0, 0));
root.getChildren().add(offerToolsBox);
tableView = new TableView<>();
@ -453,7 +449,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
}
static class CurrencyStringConverter extends StringConverter<TradeCurrency> {
private ComboBox<TradeCurrency> comboBox;
private final ComboBox<TradeCurrency> comboBox;
CurrencyStringConverter(ComboBox<TradeCurrency> comboBox) {
this.comboBox = comboBox;
@ -497,7 +493,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
}
static class PaymentMethodStringConverter extends StringConverter<PaymentMethod> {
private ComboBox<PaymentMethod> comboBox;
private final ComboBox<PaymentMethod> comboBox;
PaymentMethodStringConverter(ComboBox<PaymentMethod> comboBox) {
this.comboBox = comboBox;
@ -1134,8 +1130,6 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
@Override
public TableCell<OfferBookListItem, OfferBookListItem> call(TableColumn<OfferBookListItem, OfferBookListItem> column) {
return new TableCell<>() {
private HyperlinkWithIcon field;
@Override
public void updateItem(final OfferBookListItem item, boolean empty) {
super.updateItem(item, empty);
@ -1199,4 +1193,11 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
});
return column;
}
@NotNull
private Region getSpacer() {
final Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
}

View file

@ -126,16 +126,16 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
private Subscription selectedItemSubscription;
private Stage chatPopupStage;
private ListChangeListener<PendingTradesListItem> tradesListChangeListener;
private Map<String, Long> newChatMessagesByTradeMap = new HashMap<>();
private final Map<String, Long> newChatMessagesByTradeMap = new HashMap<>();
private String tradeIdOfOpenChat;
private double chatPopupStageXPosition = -1;
private double chatPopupStageYPosition = -1;
private ChangeListener<Number> xPositionListener;
private ChangeListener<Number> yPositionListener;
private Map<String, Button> buttonByTrade = new HashMap<>();
private Map<String, JFXBadge> badgeByTrade = new HashMap<>();
private Map<String, ListChangeListener<ChatMessage>> listenerByTrade = new HashMap<>();
private final Map<String, Button> buttonByTrade = new HashMap<>();
private final Map<String, JFXBadge> badgeByTrade = new HashMap<>();
private final Map<String, ListChangeListener<ChatMessage>> listenerByTrade = new HashMap<>();
private ChangeListener<Trade.State> tradeStateListener;
private ChangeListener<Trade.DisputeState> disputeStateListener;
private ChangeListener<MediationResultState> mediationResultStateListener;
@ -536,9 +536,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
if (selectedItemFromModel != null) {
// Select and focus selectedItem from model
int index = tableView.getItems().indexOf(selectedItemFromModel);
UserThread.execute(() -> {
tableView.getSelectionModel().select(index);
});
UserThread.execute(() -> tableView.getSelectionModel().select(index));
}
}
@ -578,12 +576,16 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
setGraphic(null);
if (trade != null && listener != null) {
trade.stateProperty().removeListener(listener);
trade = null;
listener = null;
}
}
}
private void update() {
HyperlinkWithIcon field;
if (trade == null) return;
if (isMaybeInvalidTrade(trade)) {
field = new HyperlinkWithIcon(trade.getShortId());
field.setIcon(FormBuilder.getMediumSizeIcon(MaterialDesignIcon.ALERT_CIRCLE_OUTLINE));
@ -864,7 +866,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
return chatColumn;
}
private TableColumn<PendingTradesListItem, PendingTradesListItem> setRemoveTradeColumnCellFactory() {
private void setRemoveTradeColumnCellFactory() {
moveTradeToFailedColumn.setCellValueFactory((trade) -> new ReadOnlyObjectWrapper<>(trade.getValue()));
moveTradeToFailedColumn.setCellFactory(
new Callback<>() {
@ -937,6 +939,5 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
};
}
});
return moveTradeToFailedColumn;
}
}

View file

@ -147,7 +147,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
this.networkNode.addConnectionListener(this);
this.networkNode.addMessageListener(this);
this.requestDataManager.addListener(this);
this.requestDataManager.setListener(this);
// We need to have both the initial data delivered and the hidden service published
networkReadyBinding = EasyBind.combine(hiddenServicePublished, preliminaryDataReceived,
@ -317,6 +317,11 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
public void onUpdatedDataReceived() {
if (!isBootstrapped) {
isBootstrapped = true;
// We don't use a listener at mailboxMessageService as we require the correct
// order of execution. The p2pServiceListeners must be called after
// mailboxMessageService.onUpdatedDataReceived.
mailboxMessageService.onUpdatedDataReceived();
p2pServiceListeners.forEach(P2PServiceListener::onUpdatedDataReceived);
p2PDataStorage.onBootstrapComplete();
}

View file

@ -112,7 +112,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
@Singleton
@Slf4j
public class MailboxMessageService implements SetupListener, RequestDataManager.Listener, HashMapChangedListener,
public class MailboxMessageService implements SetupListener, HashMapChangedListener,
PersistedDataHost {
private static final long REPUBLISH_DELAY_SEC = TimeUnit.MINUTES.toSeconds(2);
@ -155,7 +155,6 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
this.clock = clock;
this.republishMailboxEntries = republishMailboxEntries;
this.requestDataManager.addListener(this);
this.networkNode.addSetupListener(this);
this.persistenceManager.initialize(mailboxMessageList, PersistenceManager.Source.PRIVATE_LOW_PRIO);
@ -224,6 +223,19 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
// API
///////////////////////////////////////////////////////////////////////////////////////////
// We don't listen on requestDataManager directly as we require the correct
// order of execution. The p2pService is handling the correct order of execution and we get called
// directly from there.
public void onUpdatedDataReceived() {
if (!isBootstrapped) {
isBootstrapped = true;
// Only now we start listening and processing. The p2PDataStorage is our cache for data we have received
// after the hidden service was ready.
addHashMapChangedListenerAndApply();
maybeRepublishMailBoxMessages();
}
}
public void sendEncryptedMailboxMessage(NodeAddress peer,
PubKeyRing peersPubKeyRing,
MailboxMessage mailboxMessage,
@ -238,8 +250,9 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
"My node address must not be null at sendEncryptedMailboxMessage");
checkArgument(!keyRing.getPubKeyRing().equals(peersPubKeyRing), "We got own keyring instead of that from peer");
if (!isBootstrapped)
if (!isBootstrapped) {
throw new NetworkNotReadyException();
}
if (networkNode.getAllConnections().isEmpty()) {
sendMailboxMessageListener.onFault("There are no P2P network nodes connected. " +
@ -349,30 +362,6 @@ public class MailboxMessageService implements SetupListener, RequestDataManager.
}
///////////////////////////////////////////////////////////////////////////////////////////
// RequestDataManager.Listener implementation
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public void onPreliminaryDataReceived() {
}
@Override
public void onUpdatedDataReceived() {
if (!isBootstrapped) {
isBootstrapped = true;
// Only now we start listening and processing. The p2PDataStorage is our cache for data we have received
// after the hidden service was ready.
addHashMapChangedListenerAndApply();
maybeRepublishMailBoxMessages();
}
}
@Override
public void onDataReceived() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// HashMapChangedListener implementation for ProtectedStorageEntry items
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -40,11 +40,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@ -53,6 +51,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
public class RequestDataManager implements MessageListener, ConnectionListener, PeerManager.Listener {
@ -91,7 +90,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
private final P2PDataStorage dataStorage;
private final PeerManager peerManager;
private final List<NodeAddress> seedNodeAddresses;
private final Set<Listener> listeners = new HashSet<>();
// As we use Guice injection we cannot set the listener in our constructor but the P2PService calls the setListener
// in it's constructor so we can guarantee it is not null.
private Listener listener;
private final Map<NodeAddress, RequestDataHandler> handlerMap = new HashMap<>();
private final Map<String, GetDataRequestHandler> getDataRequestHandlers = new HashMap<>();
@ -147,8 +149,10 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
// API
///////////////////////////////////////////////////////////////////////////////////////////
public void addListener(Listener listener) {
listeners.add(listener);
// We only support one listener as P2PService will manage calls on other clients in the correct order of execution.
// The listener is set from the P2PService constructor so we can guarantee it is not null.
public void setListener(Listener listener) {
this.listener = listener;
}
public boolean requestPreliminaryData() {
@ -334,16 +338,16 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
// We delay because it can be that we get the HS published before we receive the
// preliminary data and the onPreliminaryDataReceived call triggers the
// dataUpdateRequested set to true, so we would also call the onUpdatedDataReceived.
UserThread.runAfter(() -> listeners.forEach(Listener::onPreliminaryDataReceived), 100, TimeUnit.MILLISECONDS);
UserThread.runAfter(checkNotNull(listener)::onPreliminaryDataReceived, 100, TimeUnit.MILLISECONDS);
}
// 2. Later we get a response from requestUpdatesData
if (dataUpdateRequested) {
dataUpdateRequested = false;
listeners.forEach(Listener::onUpdatedDataReceived);
checkNotNull(listener).onUpdatedDataReceived();
}
listeners.forEach(Listener::onDataReceived);
checkNotNull(listener).onDataReceived();
}
@Override
@ -371,9 +375,9 @@ public class RequestDataManager implements MessageListener, ConnectionListener,
// Notify listeners
if (!nodeAddressOfPreliminaryDataRequest.isPresent()) {
if (peerManager.isSeedNode(nodeAddress)) {
listeners.forEach(Listener::onNoSeedNodeAvailable);
checkNotNull(listener).onNoSeedNodeAvailable();
} else {
listeners.forEach(Listener::onNoPeersAvailable);
checkNotNull(listener).onNoPeersAvailable();
}
}