Add copy-on-click and etherscan links to transaction detail page
Some checks failed
check / check (push) Has been cancelled
Some checks failed
check / check (push) Has been cancelled
From address, to address, and tx hash are now clickable to copy. Each also has a small box-arrow icon linking to the corresponding etherscan page. ENS names and full addresses are both copyable.
This commit is contained in:
@@ -182,27 +182,46 @@ function etherscanTxLink(hash) {
|
|||||||
return `https://etherscan.io/tx/${hash}`;
|
return `https://etherscan.io/tx/${hash}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EXT_ICON =
|
||||||
|
`<span style="display:inline-block;width:10px;height:10px;margin-left:4px;vertical-align:middle">` +
|
||||||
|
`<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5">` +
|
||||||
|
`<path d="M4.5 1.5H2a.5.5 0 00-.5.5v8a.5.5 0 00.5.5h8a.5.5 0 00.5-.5V7.5"/>` +
|
||||||
|
`<path d="M7 1.5h3.5V5M7 5.5L10.5 1.5"/>` +
|
||||||
|
`</svg></span>`;
|
||||||
|
|
||||||
|
function copyableHtml(text, extraClass) {
|
||||||
|
const cls =
|
||||||
|
"underline decoration-dashed cursor-pointer" +
|
||||||
|
(extraClass ? " " + extraClass : "");
|
||||||
|
return `<span class="${cls}" data-copy="${escapeHtml(text)}">${escapeHtml(text)}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
function txDetailAddressHtml(address) {
|
function txDetailAddressHtml(address) {
|
||||||
const ensName = ensNameMap.get(address) || null;
|
const ensName = ensNameMap.get(address) || null;
|
||||||
const dot = addressDotHtml(address);
|
const dot = addressDotHtml(address);
|
||||||
const link = etherscanAddressLink(address);
|
const link = etherscanAddressLink(address);
|
||||||
|
const extLink = `<a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
||||||
if (ensName) {
|
if (ensName) {
|
||||||
return (
|
return (
|
||||||
dot +
|
dot +
|
||||||
`<a href="${link}" target="_blank" class="underline decoration-dashed">${escapeHtml(ensName)}</a>` +
|
copyableHtml(ensName, "") +
|
||||||
`<div class="break-all"><a href="${link}" target="_blank" class="underline decoration-dashed">${escapeHtml(address)}</a></div>`
|
extLink +
|
||||||
|
`<div class="break-all">` +
|
||||||
|
copyableHtml(address, "break-all") +
|
||||||
|
`</div>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return dot + copyableHtml(address, "break-all") + extLink;
|
||||||
dot +
|
}
|
||||||
`<a href="${link}" target="_blank" class="underline decoration-dashed break-all">${escapeHtml(address)}</a>`
|
|
||||||
);
|
function txDetailHashHtml(hash) {
|
||||||
|
const link = etherscanTxLink(hash);
|
||||||
|
const extLink = `<a href="${link}" target="_blank" rel="noopener" class="inline-flex items-center">${EXT_ICON}</a>`;
|
||||||
|
return copyableHtml(hash, "break-all") + extLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showTxDetail(tx) {
|
function showTxDetail(tx) {
|
||||||
const txLink = etherscanTxLink(tx.hash);
|
$("tx-detail-hash").innerHTML = txDetailHashHtml(tx.hash);
|
||||||
$("tx-detail-hash").innerHTML =
|
|
||||||
`<a href="${txLink}" target="_blank" class="underline decoration-dashed">${escapeHtml(tx.hash)}</a>`;
|
|
||||||
$("tx-detail-from").innerHTML = txDetailAddressHtml(tx.from);
|
$("tx-detail-from").innerHTML = txDetailAddressHtml(tx.from);
|
||||||
$("tx-detail-to").innerHTML = txDetailAddressHtml(tx.to);
|
$("tx-detail-to").innerHTML = txDetailAddressHtml(tx.to);
|
||||||
$("tx-detail-value").textContent = tx.value + " " + tx.symbol;
|
$("tx-detail-value").textContent = tx.value + " " + tx.symbol;
|
||||||
@@ -210,6 +229,17 @@ function showTxDetail(tx) {
|
|||||||
isoDate(tx.timestamp) + " (" + timeAgo(tx.timestamp) + ")";
|
isoDate(tx.timestamp) + " (" + timeAgo(tx.timestamp) + ")";
|
||||||
$("tx-detail-status").textContent = tx.isError ? "Failed" : "Success";
|
$("tx-detail-status").textContent = tx.isError ? "Failed" : "Success";
|
||||||
showView("transaction");
|
showView("transaction");
|
||||||
|
|
||||||
|
// Attach copy handlers
|
||||||
|
document
|
||||||
|
.getElementById("view-transaction")
|
||||||
|
.querySelectorAll("[data-copy]")
|
||||||
|
.forEach((el) => {
|
||||||
|
el.onclick = () => {
|
||||||
|
navigator.clipboard.writeText(el.dataset.copy);
|
||||||
|
showFlash("Copied!");
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(ctx) {
|
function init(ctx) {
|
||||||
|
|||||||
Reference in New Issue
Block a user