haveno/desktop/src/main/java/bisq/desktop/components/PeerInfoIcon.java
woodser 88578bed10 general rebase in order to update payment methods and desktop app
Co-authored-by: Alva Swanson <alvasw@protonmail.com>
Co-authored-by: andyheko <haoen.ko@gmail.com>
Co-authored-by: Bisq GitHub Admin <51445974+bisq-github-admin-3@users.noreply.github.com>
Co-authored-by: BtcContributor <79100296+BtcContributor@users.noreply.github.com>
Co-authored-by: cd2357 <cd2357@users.noreply.github.com>
Co-authored-by: chimp1984 <chimp1984@gmx.com>
Co-authored-by: Chris Beams <chris@beams.io>
Co-authored-by: Christoph Atteneder <christoph.atteneder@gmail.com>
Co-authored-by: Devin Bileck <603793+devinbileck@users.noreply.github.com>
Co-authored-by: ghubstan <36207203+ghubstan@users.noreply.github.com>
Co-authored-by: Huey <hueydane@gmail.com>
Co-authored-by: Jakub Loucký <jakub.loucky@outlook.cz>
Co-authored-by: jmacxx <47253594+jmacxx@users.noreply.github.com>
Co-authored-by: KanoczTomas <tomas.kanocz@cnl.sk>
Co-authored-by: m52go <735155+m52go@users.noreply.github.com>
Co-authored-by: Marcus0x <marcus0x@xrhodium.org>
Co-authored-by: MarnixCroes <93143998+MarnixCroes@users.noreply.github.com>
Co-authored-by: Martin Harrigan <martinharrigan@gmail.com>
Co-authored-by: MwithM <50149324+MwithM@users.noreply.github.com>
Co-authored-by: sqrrm <sqrrm@users.noreply.github.com>
Co-authored-by: Stan <36207203+ghubstan@users.noreply.github.com>
Co-authored-by: Stephan Oeste <emzy@emzy.de>
Co-authored-by: Steven Barclay <stejbac@gmail.com>
Co-authored-by: WAT <shiido.it@gmail.com>
Co-authored-by: wiz <j@wiz.biz>
Co-authored-by: xyzmaker123 <84982606+xyzmaker123@users.noreply.github.com>
2022-05-28 13:56:29 -04:00

232 lines
8.8 KiB
Java

/*
* This file is part of Haveno.
*
* Haveno is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Haveno is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.components;
import bisq.desktop.main.overlays.editor.PeerInfoWithTagEditor;
import bisq.desktop.util.DisplayUtils;
import bisq.core.alert.PrivateNotificationManager;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.trade.Trade;
import bisq.core.user.Preferences;
import bisq.network.p2p.NodeAddress;
import com.google.common.base.Charsets;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.geometry.Point2D;
import java.security.MessageDigest;
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 {
void avatarTagUpdated();
}
@Setter
private notify callback;
protected Preferences preferences;
protected final String fullAddress;
protected String tooltipText;
protected Label tagLabel;
private Label numTradesLabel;
protected Pane tagPane;
protected Pane numTradesPane;
protected int numTrades = 0;
public PeerInfoIcon(NodeAddress nodeAddress, Preferences preferences) {
this.preferences = preferences;
this.fullAddress = nodeAddress != null ? nodeAddress.getFullAddress() : "";
}
protected void createAvatar(Color ringColor) {
double scaleFactor = getScaleFactor();
double outerSize = 26 * scaleFactor;
Canvas outerBackground = new Canvas(outerSize, outerSize);
GraphicsContext outerBackgroundGc = outerBackground.getGraphicsContext2D();
outerBackgroundGc.setFill(ringColor);
outerBackgroundGc.fillOval(0, 0, outerSize, outerSize);
outerBackground.setLayoutY(1 * scaleFactor);
// inner circle
int maxIndices = 15;
int intValue = 0;
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] bytes = md.digest(fullAddress.getBytes(Charsets.UTF_8));
intValue = Math.abs(((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16)
| ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error(e.toString());
}
int index = (intValue % maxIndices) + 1;
double saturation = (intValue % 1000) / 1000d;
int red = (intValue >> 8) % 256;
int green = (intValue >> 16) % 256;
int blue = (intValue >> 24) % 256;
Color innerColor = Color.rgb(red, green, blue);
innerColor = innerColor.deriveColor(1, saturation, 0.8, 1); // reduce saturation and brightness
double innerSize = scaleFactor * 22;
Canvas innerBackground = new Canvas(innerSize, innerSize);
GraphicsContext innerBackgroundGc = innerBackground.getGraphicsContext2D();
innerBackgroundGc.setFill(innerColor);
innerBackgroundGc.fillOval(0, 0, innerSize, innerSize);
innerBackground.setLayoutY(3 * scaleFactor);
innerBackground.setLayoutX(2 * scaleFactor);
ImageView avatarImageView = new ImageView();
avatarImageView.setId("avatar_" + index);
avatarImageView.setLayoutX(0);
avatarImageView.setLayoutY(1 * scaleFactor);
avatarImageView.setFitHeight(scaleFactor * 26);
avatarImageView.setFitWidth(scaleFactor * 26);
numTradesPane = new Pane();
numTradesPane.relocate(scaleFactor * 18, scaleFactor * 14);
numTradesPane.setMouseTransparent(true);
ImageView numTradesCircle = new ImageView();
numTradesCircle.setId("image-green_circle");
numTradesLabel = new AutoTooltipLabel();
numTradesLabel.relocate(scaleFactor * 5, scaleFactor * 1);
numTradesLabel.setId("ident-num-label");
numTradesPane.getChildren().addAll(numTradesCircle, numTradesLabel);
tagPane = new Pane();
tagPane.relocate(Math.round(scaleFactor * 18), scaleFactor * -2);
tagPane.setMouseTransparent(true);
ImageView tagCircle = new ImageView();
tagCircle.setId("image-blue_circle");
tagLabel = new AutoTooltipLabel();
tagLabel.relocate(Math.round(scaleFactor * 5), scaleFactor * 1);
tagLabel.setId("ident-num-label");
tagPane.getChildren().addAll(tagCircle, tagLabel);
updatePeerInfoIcon();
getChildren().addAll(outerBackground, innerBackground, avatarImageView, tagPane, numTradesPane);
}
protected void addMouseListener(int numTrades,
PrivateNotificationManager privateNotificationManager,
@Nullable Trade trade,
Offer offer,
Preferences preferences,
boolean useDevPrivilegeKeys,
boolean isFiatCurrency,
long peersAccountAge,
long peersSignAge,
String peersAccountAgeInfo,
String peersSignAgeInfo,
String accountSigningState) {
final String accountAgeFormatted = isFiatCurrency ?
peersAccountAge > -1 ?
DisplayUtils.formatAccountAge(peersAccountAge) :
Res.get("peerInfo.unknownAge") :
null;
final String signAgeFormatted = isFiatCurrency && peersSignAgeInfo != null ?
peersSignAge > -1 ?
DisplayUtils.formatAccountAge(peersSignAge) :
Res.get("peerInfo.unknownAge") :
null;
setOnMouseClicked(e -> new PeerInfoWithTagEditor(privateNotificationManager, trade, offer, preferences, useDevPrivilegeKeys)
.fullAddress(fullAddress)
.numTrades(numTrades)
.accountAge(accountAgeFormatted)
.signAge(signAgeFormatted)
.accountAgeInfo(peersAccountAgeInfo)
.signAgeInfo(peersSignAgeInfo)
.accountSigningState(accountSigningState)
.position(localToScene(new Point2D(0, 0)))
.onSave(newTag -> {
preferences.setTagForPeer(fullAddress, newTag);
updatePeerInfoIcon();
if (callback != null) {
callback.avatarTagUpdated();
}
})
.show());
}
protected double getScaleFactor() {
return 1;
}
protected String getAccountAgeTooltip(Long accountAge) {
return accountAge > -1 ?
Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(accountAge)) :
Res.get("peerInfoIcon.tooltip.unknownAge");
}
protected void updatePeerInfoIcon() {
String tag;
Map<String, String> peerTagMap = preferences.getPeerTagMap();
if (peerTagMap.containsKey(fullAddress)) {
tag = peerTagMap.get(fullAddress);
final String text = !tag.isEmpty() ? Res.get("peerInfoIcon.tooltip", tooltipText, tag) : tooltipText;
Tooltip.install(this, new Tooltip(text));
} else {
tag = "";
Tooltip.install(this, new Tooltip(tooltipText));
}
if (!tag.isEmpty())
tagLabel.setText(tag.substring(0, 1));
if (numTrades > 0) {
numTradesLabel.setText(numTrades > 99 ? "*" : String.valueOf(numTrades));
double scaleFactor = getScaleFactor();
if (numTrades > 9 && numTrades < 100) {
numTradesLabel.relocate(scaleFactor * 2, scaleFactor * 1);
} else {
numTradesLabel.relocate(scaleFactor * 5, scaleFactor * 1);
}
}
numTradesPane.setVisible(numTrades > 0);
tagPane.setVisible(!tag.isEmpty());
}
}