feat: add click-to-copy on timestamps in all transaction list views
check / check (push) Successful in 9s

Adds click-to-copy (copies ISO date string) to timestamp displays in:
- home view (relative time ago)
- addressDetail view (relative time ago)
- addressToken view (relative time ago)
- transactionDetail view (full ISO date)

All timestamps now show dashed underline to indicate copyability,
matching the existing UX pattern for addresses, tx hashes, and
block numbers.
Цей коміт міститься в:
user
2026-02-28 14:40:11 -08:00
джерело 5565e76796
коміт 3005813f2c
4 змінених файлів з 27 додано та 5 видалено
+8 -1
Переглянути файл
@@ -216,12 +216,19 @@ function renderTransactions(txs) {
const ago = escapeHtml(timeAgo(tx.timestamp));
const iso = escapeHtml(isoDate(tx.timestamp));
html += `<div class="tx-row py-2 border-b border-border-light text-xs cursor-pointer hover:bg-hover" data-tx="${i}" style="${opacity}">`;
html += `<div class="flex justify-between"><span class="text-muted" title="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="text-muted underline decoration-dashed cursor-pointer" title="${iso}" data-copy="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="flex items-center">${dot}${addrStr}</span><span>${amountStr}</span></div>`;
html += `</div>`;
i++;
}
list.innerHTML = html;
list.querySelectorAll("[data-copy]").forEach((el) => {
el.addEventListener("click", (e) => {
e.stopPropagation();
navigator.clipboard.writeText(el.dataset.copy);
showFlash("Copied!");
});
});
list.querySelectorAll(".tx-row").forEach((row) => {
row.addEventListener("click", () => {
const idx = parseInt(row.dataset.tx, 10);
+8 -1
Переглянути файл
@@ -293,12 +293,19 @@ function renderTransactions(txs) {
const ago = escapeHtml(timeAgo(tx.timestamp));
const iso = escapeHtml(isoDate(tx.timestamp));
html += `<div class="tx-row py-2 border-b border-border-light text-xs cursor-pointer hover:bg-hover" data-tx="${i}" style="${opacity}">`;
html += `<div class="flex justify-between"><span class="text-muted" title="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="text-muted underline decoration-dashed cursor-pointer" title="${iso}" data-copy="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="flex items-center">${dot}${addrStr}</span><span>${amountStr}</span></div>`;
html += `</div>`;
i++;
}
list.innerHTML = html;
list.querySelectorAll("[data-copy]").forEach((el) => {
el.addEventListener("click", (e) => {
e.stopPropagation();
navigator.clipboard.writeText(el.dataset.copy);
showFlash("Copied!");
});
});
list.querySelectorAll(".tx-row").forEach((row) => {
row.addEventListener("click", () => {
const idx = parseInt(row.dataset.tx, 10);
+8 -1
Переглянути файл
@@ -130,12 +130,19 @@ function renderHomeTxList(ctx) {
const ago = escapeHtml(timeAgo(tx.timestamp));
const iso = escapeHtml(isoDate(tx.timestamp));
html += `<div class="home-tx-row py-2 border-b border-border-light text-xs cursor-pointer hover:bg-hover" data-tx="${i}" style="${opacity}">`;
html += `<div class="flex justify-between"><span class="text-muted" title="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="text-muted underline decoration-dashed cursor-pointer" title="${iso}" data-copy="${iso}">${ago}</span><span>${dirLabel}${err}</span></div>`;
html += `<div class="flex justify-between"><span class="flex items-center">${dot}${addrStr}</span><span>${amountStr}</span></div>`;
html += `</div>`;
i++;
}
list.innerHTML = html;
list.querySelectorAll("[data-copy]").forEach((el) => {
el.addEventListener("click", (e) => {
e.stopPropagation();
navigator.clipboard.writeText(el.dataset.copy);
showFlash("Copied!");
});
});
list.querySelectorAll(".home-tx-row").forEach((row) => {
row.addEventListener("click", () => {
const idx = parseInt(row.dataset.tx, 10);
+3 -2
Переглянути файл
@@ -158,8 +158,9 @@ function render() {
loadCalldata(tx.hash, tx.to);
}
$("tx-detail-time").textContent =
isoDate(tx.timestamp) + " (" + timeAgo(tx.timestamp) + ")";
const isoStr = isoDate(tx.timestamp);
$("tx-detail-time").innerHTML =
copyableHtml(isoStr) + " (" + escapeHtml(timeAgo(tx.timestamp)) + ")";
$("tx-detail-status").textContent = tx.isError ? "Failed" : "Success";
showView("transaction");