mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-07 17:18:13 -07:00
140 lines
3.9 KiB
JavaScript
140 lines
3.9 KiB
JavaScript
import { createBrand } from "../../brand/index.js";
|
|
import { openDialog } from "../../dialog/index.js";
|
|
import { getCoinbaseMessage } from "./format.js";
|
|
import { createBlockUrl, getReceiptSections } from "./receipt/data.js";
|
|
import { createReceiptQr } from "./receipt/qr.js";
|
|
import { createBlockTitle } from "./title.js";
|
|
|
|
/** @typedef {import("../../modules/brk-client/index.js").BlockInfoV1} Block */
|
|
/** @typedef {import("./receipt/data.js").ReceiptRow} ReceiptRow */
|
|
/** @typedef {import("./receipt/data.js").ReceiptSection} ReceiptSection */
|
|
|
|
/** @param {ReceiptRow} data */
|
|
function createReceiptRow(data) {
|
|
const row = document.createElement("div");
|
|
const name = document.createElement("span");
|
|
const amount = document.createElement("strong");
|
|
|
|
row.dataset.receiptRow = data.variant ?? (data.detail ? "amount" : "");
|
|
name.textContent = data.label;
|
|
amount.textContent = data.value;
|
|
if (data.detail) {
|
|
const detail = document.createElement("small");
|
|
|
|
detail.textContent = data.detail;
|
|
amount.append(detail);
|
|
}
|
|
row.append(name, amount);
|
|
|
|
return row;
|
|
}
|
|
|
|
/** @param {ReceiptSection} data */
|
|
function createReceiptSection(data) {
|
|
const section = document.createElement("section");
|
|
const heading = document.createElement("h3");
|
|
|
|
section.dataset.receiptSection = "";
|
|
heading.textContent = data.title;
|
|
section.append(heading, ...data.rows.map(createReceiptRow));
|
|
|
|
return section;
|
|
}
|
|
|
|
/** @param {string} message */
|
|
function createCoinbaseNote(message) {
|
|
const note = document.createElement("p");
|
|
|
|
note.dataset.receiptNote = "";
|
|
note.textContent = message;
|
|
|
|
return note;
|
|
}
|
|
|
|
/** @param {Block} block */
|
|
function createReceiptHead(block) {
|
|
const head = document.createElement("header");
|
|
const title = document.createElement("h2");
|
|
|
|
head.dataset.receiptHead = "";
|
|
title.append(...createBlockTitle(block.height));
|
|
head.append(title);
|
|
|
|
return head;
|
|
}
|
|
|
|
function createReceiptBrand() {
|
|
const section = document.createElement("section");
|
|
|
|
section.dataset.receiptBrand = "";
|
|
section.append(createBrand({ tone: "receipt", fill: 1 }));
|
|
|
|
return section;
|
|
}
|
|
|
|
/** @param {Block} block */
|
|
function openReceiptDialog(block) {
|
|
const dialog = document.createElement("dialog");
|
|
const paper = document.createElement("article");
|
|
const controls = document.createElement("footer");
|
|
const print = document.createElement("button");
|
|
const closeForm = document.createElement("form");
|
|
const close = document.createElement("button");
|
|
const url = createBlockUrl(block);
|
|
const coinbase = getCoinbaseMessage(block.extras.coinbaseSignatureAscii);
|
|
|
|
dialog.dataset.blockReceipt = "";
|
|
dialog.tabIndex = -1;
|
|
paper.dataset.receiptPaper = "";
|
|
controls.dataset.receiptControls = "";
|
|
print.type = "button";
|
|
print.dataset.receiptAction = "print";
|
|
print.textContent = "Print";
|
|
closeForm.method = "dialog";
|
|
close.type = "submit";
|
|
close.dataset.receiptAction = "close";
|
|
close.textContent = "Close";
|
|
closeForm.append(close);
|
|
controls.append(closeForm, print);
|
|
paper.append(
|
|
createReceiptHead(block),
|
|
...getReceiptSections(block).map(createReceiptSection),
|
|
...(coinbase ? [createCoinbaseNote(coinbase)] : []),
|
|
createReceiptQr(block, url),
|
|
createReceiptBrand(),
|
|
);
|
|
dialog.append(paper, controls);
|
|
|
|
print.addEventListener("click", () => {
|
|
window.print();
|
|
});
|
|
openDialog(dialog, document.body);
|
|
dialog.focus({ preventScroll: true });
|
|
dialog.scrollTop = 0;
|
|
}
|
|
|
|
export function createBlockReceipt() {
|
|
const button = document.createElement("button");
|
|
/** @type {Block | null} */
|
|
let block = null;
|
|
|
|
button.type = "button";
|
|
button.disabled = true;
|
|
button.dataset.receiptButton = "";
|
|
button.textContent = "Receipt";
|
|
button.addEventListener("click", () => {
|
|
if (block) openReceiptDialog(block);
|
|
});
|
|
|
|
/** @param {Block} nextBlock */
|
|
function update(nextBlock) {
|
|
block = nextBlock;
|
|
button.disabled = false;
|
|
}
|
|
|
|
return /** @type {const} */ ({
|
|
button,
|
|
update,
|
|
});
|
|
}
|