show transaction details popup with tx key #1309 (#1311)

This commit is contained in:
woodser 2024-10-06 12:01:55 -04:00 committed by GitHub
parent e25d3fb52e
commit a1b50a7b42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 186 additions and 35 deletions

View file

@ -2021,9 +2021,12 @@ tradeDetailsWindow.agentAddresses=Arbitrator/Mediator
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.xmr.noteSent=You have sent XMR.
txDetailsWindow.xmr.noteReceived=You have received XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.receivedWith=Received with
txDetailsWindow.txId=TxId
txDetailsWindow.txKey=Transaction Key
closedTradesSummaryWindow.headline=Trade history summary
closedTradesSummaryWindow.totalAmount.title=Total trade amount

View file

@ -1502,8 +1502,10 @@ tradeDetailsWindow.agentAddresses=Rozhodce/Mediátor
tradeDetailsWindow.detailData=Detailní data
txDetailsWindow.headline=Detaily transakce
txDetailsWindow.xmr.note=Poslali jste XMR.
txDetailsWindow.xmr.noteSent=Poslali jste XMR.
txDetailsWindow.xmr.noteReceived=Obdrželi jste XMR.
txDetailsWindow.sentTo=Odesláno na
txDetailsWindow.receivedWith=Přijato s
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Souhrn uzavřených obchodů

View file

@ -1502,8 +1502,10 @@ tradeDetailsWindow.agentAddresses=Vermittler/Mediator
tradeDetailsWindow.detailData=Detaillierte Daten
txDetailsWindow.headline=Transaktionsdetails
txDetailsWindow.xmr.note=Sie haben XMR gesendet.
txDetailsWindow.xmr.noteSent=Sie haben XMR gesendet.
txDetailsWindow.xmr.noteReceived=Sie haben XMR erhalten.
txDetailsWindow.sentTo=Gesendet an
txDetailsWindow.receivedWith=Erhalten mit
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1503,8 +1503,10 @@ tradeDetailsWindow.agentAddresses=Árbitro/Mediador
tradeDetailsWindow.detailData=Detalle de datos
txDetailsWindow.headline=Detalles de transacción
txDetailsWindow.xmr.note=Ha enviado XMR
txDetailsWindow.xmr.noteSent=Ha enviado XMR
txDetailsWindow.xmr.noteReceived=Has recibido XMR.
txDetailsWindow.sentTo=Enviado a
txDetailsWindow.receivedWith=Recibido con
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Resume de historia de intercambio

View file

@ -1498,8 +1498,10 @@ tradeDetailsWindow.agentAddresses=Arbitrator/Mediator
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=شما XMR ارسال کرده‌اید.
txDetailsWindow.xmr.noteReceived=شما XMR دریافت کرده‌اید.
txDetailsWindow.sentTo=ارسال به
txDetailsWindow.receivedWith=دریافت با
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1504,8 +1504,10 @@ tradeDetailsWindow.agentAddresses=Arbitre/Médiateur
tradeDetailsWindow.detailData=Données détaillées
txDetailsWindow.headline=Détails de la transaction
txDetailsWindow.xmr.note=Vous avez envoyé du XMR.
txDetailsWindow.xmr.noteSent=Vous avez envoyé du XMR.
txDetailsWindow.xmr.noteReceived=Vous avez reçu XMR.
txDetailsWindow.sentTo=Envoyé à
txDetailsWindow.receivedWith=Reçu avec
txDetailsWindow.txId=ID de transaction
closedTradesSummaryWindow.headline=Résumé de l'historique de trade

View file

@ -1501,8 +1501,10 @@ tradeDetailsWindow.agentAddresses=Arbitro/Mediatore
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=Hai inviato XMR.
txDetailsWindow.xmr.noteReceived=Hai ricevuto XMR.
txDetailsWindow.sentTo=Inviato a
txDetailsWindow.receivedWith=Ricevuto con
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1502,8 +1502,10 @@ tradeDetailsWindow.agentAddresses=仲裁者 / 調停人
tradeDetailsWindow.detailData=詳細データ
txDetailsWindow.headline=トランザクション詳細
txDetailsWindow.xmr.note=XMRを送金しました。
txDetailsWindow.xmr.noteSent=XMRを送金しました。
txDetailsWindow.xmr.noteReceived=XMRを受け取りました。
txDetailsWindow.sentTo=送信先
txDetailsWindow.receivedWith=受け取りました。
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1505,8 +1505,10 @@ tradeDetailsWindow.agentAddresses=Árbitro/Mediador
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=Você enviou XMR.
txDetailsWindow.xmr.noteReceived=Você recebeu XMR.
txDetailsWindow.sentTo=Enviado para
txDetailsWindow.receivedWith=Recebido com
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1498,8 +1498,10 @@ tradeDetailsWindow.agentAddresses=Árbitro/Mediador
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=Você enviou XMR.
txDetailsWindow.xmr.noteReceived=Você recebeu XMR.
txDetailsWindow.sentTo=Enviado para
txDetailsWindow.receivedWith=Recebido com
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1499,8 +1499,10 @@ tradeDetailsWindow.agentAddresses=Arbitrator/Mediator
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=Вы отправили XMR.
txDetailsWindow.xmr.noteReceived=Вы получили XMR.
txDetailsWindow.sentTo=Отправлено в
txDetailsWindow.receivedWith=Получено с
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1499,8 +1499,10 @@ tradeDetailsWindow.agentAddresses=Arbitrator/Mediator
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=คุณได้ส่ง XMR แล้ว
txDetailsWindow.xmr.noteReceived=คุณได้รับ XMR แล้ว
txDetailsWindow.sentTo=ส่งไปยัง
txDetailsWindow.receivedWith=ได้รับด้วย
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -2016,8 +2016,10 @@ tradeDetailsWindow.agentAddresses=Hakem/Arabulucu
tradeDetailsWindow.detailData=Detay verileri
txDetailsWindow.headline=İşlem Detayları
txDetailsWindow.xmr.note=XMR gönderdiniz.
txDetailsWindow.xmr.noteSent=XMR gönderdiniz.
txDetailsWindow.xmr.noteReceived=XMR aldınız.
txDetailsWindow.sentTo=Gönderilen adres
txDetailsWindow.receivedWith=Alındı ile
txDetailsWindow.txId=İşlem Kimliği (TxId)
closedTradesSummaryWindow.headline=Ticaret geçmişi özeti

View file

@ -1501,8 +1501,10 @@ tradeDetailsWindow.agentAddresses=Arbitrator/Mediator
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=Bạn đã gửi XMR.
txDetailsWindow.xmr.noteReceived=Bạn đã nhận được XMR.
txDetailsWindow.sentTo=Gửi đến
txDetailsWindow.receivedWith=Đã nhận với
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1503,8 +1503,10 @@ tradeDetailsWindow.agentAddresses=仲裁员/调解员
tradeDetailsWindow.detailData=详情数据
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=您已发送 XMR。
txDetailsWindow.xmr.noteReceived=你已收到XMR。
txDetailsWindow.sentTo=发送至
txDetailsWindow.receivedWith=已收到,带有
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -1503,8 +1503,10 @@ tradeDetailsWindow.agentAddresses=仲裁員/調解員
tradeDetailsWindow.detailData=Detail data
txDetailsWindow.headline=Transaction Details
txDetailsWindow.xmr.note=You have sent XMR.
txDetailsWindow.sentTo=Sent to
txDetailsWindow.xmr.noteSent=您已發送XMR。
txDetailsWindow.xmr.noteReceived=您已收到 XMR。
txDetailsWindow.sentTo=發送至
txDetailsWindow.receivedWith=已收到與
txDetailsWindow.txId=TxId
closedTradesSummaryWindow.headline=Trade history summary

View file

@ -42,7 +42,7 @@ import java.util.Date;
import java.util.Optional;
@Slf4j
class TransactionsListItem {
public class TransactionsListItem {
private String dateString;
private final Date date;
private final String txId;
@ -61,6 +61,8 @@ class TransactionsListItem {
private boolean initialTxConfidenceVisibility = true;
private final Supplier<LazyFields> lazyFieldsSupplier;
private XmrWalletService xmrWalletService;
@Getter
private MoneroTxWallet tx;
private static class LazyFields {
TxConfidenceIndicator txConfidenceIndicator;
@ -81,6 +83,7 @@ class TransactionsListItem {
TransactionsListItem(MoneroTxWallet tx,
XmrWalletService xmrWalletService,
TransactionAwareTradable transactionAwareTradable) {
this.tx = tx;
this.memo = tx.getNote();
this.txId = tx.getHash();
this.xmrWalletService = xmrWalletService;

View file

@ -32,10 +32,10 @@ import haveno.desktop.common.view.FxmlView;
import haveno.desktop.components.AddressWithIconAndDirection;
import haveno.desktop.components.AutoTooltipButton;
import haveno.desktop.components.AutoTooltipLabel;
import haveno.desktop.components.ExternalHyperlink;
import haveno.desktop.components.HyperlinkWithIcon;
import haveno.desktop.main.overlays.windows.OfferDetailsWindow;
import haveno.desktop.main.overlays.windows.TradeDetailsWindow;
import haveno.desktop.main.overlays.windows.TxDetailsWindow;
import haveno.desktop.util.GUIUtil;
import haveno.network.p2p.P2PService;
import java.math.BigInteger;
@ -85,6 +85,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
private final Preferences preferences;
private final TradeDetailsWindow tradeDetailsWindow;
private final OfferDetailsWindow offerDetailsWindow;
private final TxDetailsWindow txDetailsWindow;
private EventHandler<KeyEvent> keyEventEventHandler;
private Scene scene;
@ -113,11 +114,13 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
Preferences preferences,
TradeDetailsWindow tradeDetailsWindow,
OfferDetailsWindow offerDetailsWindow,
TxDetailsWindow txDetailsWindow,
DisplayedTransactionsFactory displayedTransactionsFactory) {
this.xmrWalletService = xmrWalletService;
this.preferences = preferences;
this.tradeDetailsWindow = tradeDetailsWindow;
this.offerDetailsWindow = offerDetailsWindow;
this.txDetailsWindow = txDetailsWindow;
this.displayedTransactions = displayedTransactionsFactory.create();
this.sortedDisplayedTransactions = displayedTransactions.asSortedList();
}
@ -253,6 +256,10 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
tradeDetailsWindow.show((Trade) item.getTradable());
}
private void openTxDetailPopup(TransactionsListItem item) {
txDetailsWindow.show(item);
}
///////////////////////////////////////////////////////////////////////////////////////////
// ColumnCellFactories
@ -376,9 +383,9 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
//noinspection Duplicates
if (item != null && !empty) {
String transactionId = item.getTxId();
hyperlinkWithIcon = new ExternalHyperlink(transactionId);
hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item));
hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId)));
hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.INFO_SIGN);
hyperlinkWithIcon.setOnAction(event -> openTxDetailPopup(item));
hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("txDetailsWindow.headline")));
setGraphic(hyperlinkWithIcon);
} else {
setGraphic(null);

View file

@ -51,7 +51,7 @@ import haveno.desktop.components.BusyAnimation;
import haveno.desktop.components.HyperlinkWithIcon;
import haveno.desktop.components.TitledGroupBg;
import haveno.desktop.main.overlays.popups.Popup;
import haveno.desktop.main.overlays.windows.TxDetails;
import haveno.desktop.main.overlays.windows.TxWithdrawWindow;
import haveno.desktop.main.overlays.windows.WalletPasswordWindow;
import haveno.desktop.util.FormBuilder;
import haveno.desktop.util.GUIUtil;
@ -333,7 +333,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
xmrWalletService.getWallet().setTxNote(tx.getHash(), withdrawMemoTextField.getText()); // TODO (monero-java): tx note does not persist when tx created then relayed
String key = "showTransactionSent";
if (DontShowAgainLookup.showAgain(key)) {
new TxDetails(tx.getHash(), withdrawToAddress, HavenoUtils.formatXmr(receiverAmount, true), HavenoUtils.formatXmr(fee, true), xmrWalletService.getWallet().getTxNote(tx.getHash()))
new TxWithdrawWindow(tx.getHash(), withdrawToAddress, HavenoUtils.formatXmr(receiverAmount, true), HavenoUtils.formatXmr(fee, true), xmrWalletService.getWallet().getTxNote(tx.getHash()))
.dontShowAgainId(key)
.show();
}

View file

@ -0,0 +1,108 @@
/*
* 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 haveno.desktop.main.overlays.windows;
import haveno.core.locale.Res;
import haveno.core.trade.HavenoUtils;
import haveno.core.xmr.wallet.XmrWalletService;
import haveno.desktop.main.funds.transactions.TransactionsListItem;
import haveno.desktop.main.overlays.Overlay;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import monero.wallet.model.MoneroTxWallet;
import static haveno.desktop.util.FormBuilder.addConfirmationLabelLabel;
import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextFieldWithCopyIcon;
import static haveno.desktop.util.FormBuilder.addLabelTxIdTextField;
import static haveno.desktop.util.FormBuilder.addMultilineLabel;
import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
import java.math.BigInteger;
import com.google.inject.Inject;
public class TxDetailsWindow extends Overlay<TxDetailsWindow> {
private XmrWalletService xmrWalletService;
private TransactionsListItem item;
@Inject
public TxDetailsWindow(XmrWalletService xmrWalletService) {
this.xmrWalletService = xmrWalletService;
}
public void show(TransactionsListItem item) {
this.item = item;
rowIndex = -1;
width = 918;
createGridPane();
gridPane.setHgap(15);
addHeadLine();
addContent();
addButtons();
addDontShowAgainCheckBox();
applyStyles();
display();
}
protected void addContent() {
int rows = 10;
MoneroTxWallet tx = item.getTx();
String memo = tx.getNote();
if (memo != null && !"".equals(memo)) rows++;
String txKey = null;
boolean isOutgoing = tx.getOutgoingTransfer() != null;
if (isOutgoing) {
try {
txKey = xmrWalletService.getWallet().getTxKey(tx.getHash());
} catch (Exception e) {
// TODO (monero-java): wallet.getTxKey() should return null if key does not exist instead of throwing exception
}
}
if (txKey != null && !"".equals(txKey)) rows++;
// add title
addTitledGroupBg(gridPane, ++rowIndex, rows, Res.get("txDetailsWindow.headline"));
Region spacer = new Region();
spacer.setMinHeight(15);
gridPane.add(spacer, 0, ++rowIndex);
// add sent or received note
String resKey = isOutgoing ? "txDetailsWindow.xmr.noteSent" : "txDetailsWindow.xmr.noteReceived";
GridPane.setColumnSpan(addMultilineLabel(gridPane, ++rowIndex, Res.get(resKey), 0), 2);
spacer = new Region();
spacer.setMinHeight(15);
gridPane.add(spacer, 0, ++rowIndex);
// add tx fields
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.dateTime"), item.getDateString());
BigInteger amount;
if (isOutgoing) {
addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("txDetailsWindow.sentTo"), item.getAddressString());
amount = tx.getOutgoingAmount();
} else {
addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("txDetailsWindow.receivedWith"), item.getAddressString());
amount = tx.getIncomingAmount();
}
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.amount"), HavenoUtils.formatXmr(amount));
addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("shared.txFee"), HavenoUtils.formatXmr(tx.getFee()));
if (memo != null && !"".equals(memo)) addConfirmationLabelLabel(gridPane, ++rowIndex, Res.get("funds.withdrawal.memoLabel"), memo);
if (txKey != null && !"".equals(txKey)) addConfirmationLabelTextFieldWithCopyIcon(gridPane, ++rowIndex, Res.get("txDetailsWindow.txKey"), txKey);
addLabelTxIdTextField(gridPane, ++rowIndex, Res.get("txDetailsWindow.txId"), tx.getHash());
}
}

View file

@ -28,12 +28,12 @@ import static haveno.desktop.util.FormBuilder.addConfirmationLabelTextFieldWithC
import static haveno.desktop.util.FormBuilder.addLabelTxIdTextField;
import static haveno.desktop.util.FormBuilder.addMultilineLabel;
public class TxDetails extends Overlay<TxDetails> {
public class TxWithdrawWindow extends Overlay<TxWithdrawWindow> {
protected String txId, address, amount, fee, memo;
protected TxIdTextField txIdTextField;
public TxDetails(String txId, String address, String amount, String fee, String memo) {
public TxWithdrawWindow(String txId, String address, String amount, String fee, String memo) {
type = Type.Attention;
this.txId = txId;
this.address = address;
@ -59,7 +59,7 @@ public class TxDetails extends Overlay<TxDetails> {
protected void addContent() {
GridPane.setColumnSpan(
addMultilineLabel(gridPane, ++rowIndex, Res.get("txDetailsWindow.xmr.note"), 0), 2);
addMultilineLabel(gridPane, ++rowIndex, Res.get("txDetailsWindow.xmr.noteSent"), 0), 2);
Region spacer = new Region();
spacer.setMinHeight(20);
gridPane.add(spacer, 0, ++rowIndex);