Eve/src/components/Widgets/BitcoinBlockWidget.ts
2025-02-20 19:28:48 +01:00

101 lines
2 KiB
TypeScript

import { html, css, LitElement } from "lit";
import { customElement, state } from "lit/decorators.js";
import { getLastBlockHeight } from "@utils/lastBlockHeight";
@customElement("arx-bitcoin-block-widget")
export class BitcoinBlockWidget extends LitElement {
@state()
private lastBlock: number | null = null;
@state()
private isLoading = true;
@state()
private error: string | null = null;
private REFRESH_INTERVAL = 5000;
@state()
private timer: number | null = null;
constructor() {
super();
this.loadBlockHeight();
this.timer = window.setInterval(
this.loadBlockHeight,
this.REFRESH_INTERVAL
);
}
override disconnectedCallback() {
super.disconnectedCallback();
if (this.timer) clearInterval(this.timer);
}
async loadBlockHeight() {
try {
const response = await getLastBlockHeight();
this.lastBlock = response.height;
this.error = null;
} catch (error) {
this.error = "Failed to load block height";
console.error(error);
} finally {
this.isLoading = false;
}
}
static override styles = [
css`
.error {
color: #dc3545;
padding: 0.5rem;
border-radius: 4px;
background: #f8d7da;
}
.loading {
display: flex;
align-items: center;
gap: 0.5rem;
}
.block-height {
display: flex;
align-items: center;
gap: 0.5rem;
}
.label {
font-weight: 500;
}
.value {
font-size: 1.25rem;
font-weight: 600;
}
`,
];
override render() {
if (this.error) {
return html`<div class="error">${this.error}</div>`;
}
if (this.isLoading) {
return html`
<div class="loading">
<span class="loader"></span>
Loading latest block...
</div>
`;
}
return html`
<div class="block-height">
<span class="label">Last Block:</span>
<span class="value">${this.lastBlock?.toLocaleString()}</span>
</div>
`;
}
}