Include ability to refresh all tags in Portfolio

This commit is contained in:
Android-X13 2022-09-13 21:16:52 +03:00
parent 1e82070e74
commit 73bb97d2dd
No known key found for this signature in database
GPG Key ID: 161BE7DF6FC78FC7
7 changed files with 74 additions and 60 deletions

View File

@ -47,23 +47,13 @@ import java.security.NoSuchAlgorithmException;
import java.util.Map;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
@Slf4j
public class PeerInfoIcon extends Group {
public interface notify {
/**
* Callback from one avatar letting us know that the user updated the tag text.
* We need to update all avatars, as some could be sharing the same tag.
*/
void avatarTagUpdated();
}
@Setter
private notify callback;
protected Preferences preferences;
protected final String fullAddress;
protected String tooltipText;
@ -72,6 +62,7 @@ public class PeerInfoIcon extends Group {
protected Pane tagPane;
protected Pane numTradesPane;
protected int numTrades = 0;
private Map<String, PeerInfoIcon> avatarMap;
public PeerInfoIcon(NodeAddress nodeAddress, Preferences preferences) {
this.preferences = preferences;
@ -188,8 +179,11 @@ public class PeerInfoIcon extends Group {
.position(localToScene(new Point2D(0, 0)))
.onSave(newTag -> {
preferences.setTagForPeer(fullAddress, newTag);
if (callback != null) {
callback.avatarTagUpdated();
if (avatarMap != null) {
log.info("Updating avatar tags, the avatarMap size is {}", avatarMap.size());
avatarMap.forEach((key, avatarIcon) -> avatarIcon.refreshTag());
} else {
this.refreshTag();
}
})
.show();
@ -224,7 +218,7 @@ public class PeerInfoIcon extends Group {
refreshTag();
}
public void refreshTag() {
protected void refreshTag() {
String tag;
Map<String, String> peerTagMap = preferences.getPeerTagMap();
if (peerTagMap.containsKey(fullAddress)) {
@ -242,4 +236,16 @@ public class PeerInfoIcon extends Group {
tagPane.setVisible(!tag.isEmpty());
}
/**
* Sets the map where this icon is stored and associates the latter with the specified key.
* The map will be traversed later on if the user updates an icon's tag, and all avatars
* will be refreshed as some could be sharing the same tag.
* @param avatarMap The map to which this avatar is stored
* @param key Key that is associated with the avatar
*/
public void setAvatarMapAndKey(Map<String, PeerInfoIcon> avatarMap, String key) {
this.avatarMap = avatarMap;
avatarMap.put(key, this);
}
}

View File

@ -8,8 +8,13 @@ import bisq.core.user.Preferences;
import bisq.network.p2p.NodeAddress;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
@Slf4j
public class PeerInfoIconSmall extends PeerInfoIconTrading {
public PeerInfoIconSmall(NodeAddress nodeAddress,
String role,
@ -53,4 +58,10 @@ public class PeerInfoIconSmall extends PeerInfoIconTrading {
numTradesPane.setVisible(false);
tagPane.setVisible(false);
}
@Override
public void setAvatarMapAndKey(Map<String, PeerInfoIcon> avatarMap, String key) {
// We don't show a tag, so no map needs to be traversed to refresh any tags
log.error("setAvatarMapAndKey: method not supported");
}
}

View File

@ -121,7 +121,7 @@ import org.jetbrains.annotations.NotNull;
import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewModel> extends ActivatableViewAndModel<R, M> implements PeerInfoIcon.notify {
abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewModel> extends ActivatableViewAndModel<R, M> {
private final Navigation navigation;
private final OfferDetailsWindow offerDetailsWindow;
@ -154,7 +154,7 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
private static final int SHOW_ALL = 0;
private Label disabledCreateOfferButtonTooltip;
protected VBox currencyComboBoxContainer;
private Map<String, PeerInfoIconTrading> avatarMap = new HashMap<>();
private final Map<String, PeerInfoIcon> avatarMap = new HashMap<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
@ -1271,7 +1271,20 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
public void updateItem(final OfferBookListItem newItem, boolean empty) {
super.updateItem(newItem, empty);
if (newItem != null && !empty) {
PeerInfoIconTrading peerInfoIcon = createAvatar(newItem.getOffer());
final Offer offer = newItem.getOffer();
final NodeAddress makersNodeAddress = offer.getOwnerNodeAddress();
String role = Res.get("peerInfoIcon.tooltip.maker");
int numTrades = model.getNumTrades(offer);
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(makersNodeAddress,
role,
numTrades,
privateNotificationManager,
offer,
model.preferences,
model.accountAgeWitnessService,
useDevPrivilegeKeys);
String key = offer.getId();
peerInfoIcon.setAvatarMapAndKey(avatarMap, key);
setGraphic(peerInfoIcon);
} else {
setGraphic(null);
@ -1283,32 +1296,6 @@ abstract public class OfferBookView<R extends GridPane, M extends OfferBookViewM
return column;
}
private PeerInfoIconTrading createAvatar(Offer offer) {
final NodeAddress makersNodeAddress = offer.getOwnerNodeAddress();
String key = offer.getId();
String role = Res.get("peerInfoIcon.tooltip.maker");
int numTrades = model.getNumTrades(offer);
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(makersNodeAddress,
role,
numTrades,
privateNotificationManager,
offer,
model.preferences,
model.accountAgeWitnessService,
useDevPrivilegeKeys);
peerInfoIcon.setCallback(this);
avatarMap.put(key, peerInfoIcon);
return peerInfoIcon;
}
@Override
public void avatarTagUpdated() {
log.info("Updating avatar tags, the avatarMap size is {}", avatarMap.size());
avatarMap.forEach((key, avatarIcon) -> {
avatarIcon.refreshTag();
});
}
@NotNull
private Region getSpacer() {
final Region spacer = new Region();

View File

@ -22,6 +22,7 @@ import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.PeerInfoIcon;
import bisq.desktop.components.PeerInfoIconTrading;
import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.windows.BsqTradeDetailsWindow;
@ -46,7 +47,6 @@ import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
@ -68,6 +68,8 @@ import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@FxmlView
@ -129,6 +131,7 @@ public class UnconfirmedBsqSwapsView extends ActivatableViewAndModel<VBox, Uncon
private SortedList<UnconfirmedBsqSwapsListItem> sortedList;
private FilteredList<UnconfirmedBsqSwapsListItem> filteredList;
private ChangeListener<Number> widthListener;
private final Map<String, PeerInfoIcon> avatarMap = new HashMap<>();
@Inject
public UnconfirmedBsqSwapsView(UnconfirmedBsqSwapsViewModel model,
@ -259,6 +262,8 @@ public class UnconfirmedBsqSwapsView extends ActivatableViewAndModel<VBox, Uncon
filterBox.deactivate();
root.widthProperty().removeListener(widthListener);
avatarMap.clear();
}
private static <T extends Comparable<T>> Comparator<UnconfirmedBsqSwapsListItem> nullsFirstComparing(
@ -400,7 +405,7 @@ public class UnconfirmedBsqSwapsView extends ActivatableViewAndModel<VBox, Uncon
int numPastTrades = newItem.getNumPastTrades();
final NodeAddress tradingPeerNodeAddress = bsqSwapTrade.getTradingPeerNodeAddress();
String role = Res.get("peerInfoIcon.tooltip.tradePeer");
Node peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
role,
numPastTrades,
privateNotificationManager,
@ -408,6 +413,8 @@ public class UnconfirmedBsqSwapsView extends ActivatableViewAndModel<VBox, Uncon
preferences,
accountAgeWitnessService,
useDevPrivilegeKeys);
String key = bsqSwapTrade.getId();
peerInfoIcon.setAvatarMapAndKey(avatarMap, key);
setPadding(new Insets(1, 15, 0, 0));
setGraphic(peerInfoIcon);
} else {

View File

@ -24,6 +24,7 @@ import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.AutoTooltipTableColumn;
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.PeerInfoIcon;
import bisq.desktop.components.PeerInfoIconTrading;
import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.overlays.popups.Popup;
@ -63,7 +64,6 @@ import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
@ -92,6 +92,8 @@ import javafx.collections.transformation.SortedList;
import javafx.util.Callback;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -158,6 +160,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
private SortedList<ClosedTradesListItem> sortedList;
private FilteredList<ClosedTradesListItem> filteredList;
private ChangeListener<Number> widthListener;
private final Map<String, PeerInfoIcon> avatarMap = new HashMap<>();
@Inject
public ClosedTradesView(ClosedTradesViewModel model,
@ -344,6 +347,8 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
filterBox.deactivate();
root.widthProperty().removeListener(widthListener);
avatarMap.clear();
}
private static <T extends Comparable<T>> Comparator<ClosedTradesListItem> nullsFirstComparing(Function<ClosedTradesListItem, T> keyExtractor) {
@ -528,7 +533,7 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
int numPastTrades = item.getNumPastTrades();
NodeAddress tradingPeerNodeAddress = tradeModel.getTradingPeerNodeAddress();
String role = Res.get("peerInfoIcon.tooltip.tradePeer");
Node peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
role,
numPastTrades,
privateNotificationManager,
@ -536,6 +541,8 @@ public class ClosedTradesView extends ActivatableViewAndModel<VBox, ClosedTrades
preferences,
model.dataModel.accountAgeWitnessService,
useDevPrivilegeKeys);
String key = tradeModel.getId();
peerInfoIcon.setAvatarMapAndKey(avatarMap, key);
setPadding(new Insets(1, 15, 0, 0));
setGraphic(peerInfoIcon);
} else {

View File

@ -22,6 +22,7 @@ import bisq.desktop.common.view.ActivatableViewAndModel;
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.HyperlinkWithIcon;
import bisq.desktop.components.PeerInfoIcon;
import bisq.desktop.components.PeerInfoIconTrading;
import bisq.desktop.components.list.FilterBox;
import bisq.desktop.main.MainView;
@ -68,7 +69,6 @@ import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
@ -152,6 +152,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
private ChangeListener<Trade.DisputeState> disputeStateListener;
private ChangeListener<MediationResultState> mediationResultStateListener;
private ChangeListener<Number> getMempoolStatusListener;
private final Map<String, PeerInfoIcon> avatarMap = new HashMap<>();
///////////////////////////////////////////////////////////////////////////////////////////
@ -357,6 +358,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
if (scene != null)
scene.removeEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
avatarMap.clear();
}
private void removeSelectedSubView() {
@ -829,7 +832,7 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
final NodeAddress tradingPeerNodeAddress = trade.getTradingPeerNodeAddress();
int numPastTrades = model.getNumPastTrades(trade);
String role = Res.get("peerInfoIcon.tooltip.tradePeer");
Node peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
PeerInfoIconTrading peerInfoIcon = new PeerInfoIconTrading(tradingPeerNodeAddress,
role,
numPastTrades,
privateNotificationManager,
@ -837,6 +840,8 @@ public class PendingTradesView extends ActivatableViewAndModel<VBox, PendingTrad
preferences,
model.accountAgeWitnessService,
useDevPrivilegeKeys);
String key = trade.getId();
peerInfoIcon.setAvatarMapAndKey(avatarMap, key);
setPadding(new Insets(1, 0, 0, 0));
setGraphic(peerInfoIcon);
} else {

View File

@ -126,7 +126,7 @@ import javax.annotation.Nullable;
import static bisq.desktop.util.FormBuilder.getIconForLabel;
import static bisq.desktop.util.FormBuilder.getRegularIconButton;
public abstract class DisputeView extends ActivatableView<VBox, Void> implements PeerInfoIcon.notify, DisputeChatPopup.ChatCallback {
public abstract class DisputeView extends ActivatableView<VBox, Void> implements DisputeChatPopup.ChatCallback {
public enum FilterResult {
NO_MATCH("No Match"),
NO_FILTER("No filter text"),
@ -191,7 +191,7 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
private Map<String, Button> chatButtonByDispute = new HashMap<>();
private Map<String, JFXBadge> chatBadgeByDispute = new HashMap<>();
private Map<String, JFXBadge> newBadgeByDispute = new HashMap<>();
private Map<String, PeerInfoIconDispute> avatarMap = new HashMap<>();
private final Map<String, PeerInfoIcon> avatarMap = new HashMap<>();
protected DisputeChatPopup chatPopup;
@ -1489,19 +1489,10 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> implements
disputeManager.getNrOfDisputes(isBuyer, contract),
accountAge,
preferences);
peerInfoIcon.setCallback(this);
avatarMap.put(key, peerInfoIcon);
peerInfoIcon.setAvatarMapAndKey(avatarMap, key);
return peerInfoIcon;
}
@Override
public void avatarTagUpdated() {
log.info("Updating avatar tags, the avatarMap size is {}", avatarMap.size());
avatarMap.forEach((key, avatarIcon) -> {
avatarIcon.refreshTag();
});
}
@Override
public void onCloseDisputeFromChatWindow(Dispute dispute) {
handleOnProcessDispute(dispute);