Files

63 lines
2.5 KiB
JavaScript
Raw Permalink Normal View History

2026-06-28 13:25:14 -05:00
class TemperatureCard extends HTMLElement {
2026-06-28 13:15:53 -05:00
constructor() {
super();
this.source = null;
}
connectedCallback() {
this.innerHTML = `
<style>
2026-06-28 13:25:14 -05:00
:host{display:block}section{height:100%;box-sizing:border-box}.liveValue{font-size:34px;font-weight:700;line-height:1.15;margin-top:10px}.secondaryValue{font-size:18px;font-weight:600;margin-top:2px}.state{display:inline-flex;align-items:center;gap:6px;margin-top:6px}.dot{width:9px;height:9px;border-radius:50%;background:#b3261e}.dot.on{background:#188038}
2026-06-28 13:15:53 -05:00
</style>
<section>
<h3>Live temperature</h3>
<div class="muted">Server-Sent Events</div>
2026-06-28 13:25:14 -05:00
<div class="liveValue"><span id="temperatureC">--</span>&deg;C</div>
<div class="secondaryValue"><span id="temperatureF">--</span>&deg;F</div>
2026-06-28 13:15:53 -05:00
<div class="muted state"><span id="dot" class="dot"></span><span id="state">Disconnected</span></div>
</section>`;
window.addEventListener('app:login', event => this.start(event.detail.token));
window.addEventListener('beforeunload', () => this.stop());
if (window.App && window.App.token()) this.start(window.App.token());
}
disconnectedCallback() {
this.stop();
}
setState(text, connected) {
this.querySelector('#state').textContent = text;
this.querySelector('#dot').classList.toggle('on', !!connected);
}
start(token) {
this.stop();
if (!token || !window.EventSource) {
this.setState('Unavailable', false);
return;
}
this.setState('Connecting', false);
2026-06-28 13:25:14 -05:00
this.source = new EventSource('/api/temperature/events?token=' + encodeURIComponent(token));
2026-06-28 13:15:53 -05:00
this.source.addEventListener('open', () => this.setState('Connected', true));
this.source.addEventListener('temperature', event => {
try {
const json = JSON.parse(event.data);
2026-06-28 13:25:14 -05:00
const connected = !!json.sensorConnected && json.temperatureC !== null && json.temperatureF !== null;
this.querySelector('#temperatureC').textContent = connected ? Number(json.temperatureC).toFixed(2) : '--';
this.querySelector('#temperatureF').textContent = connected ? Number(json.temperatureF).toFixed(2) : '--';
2026-06-28 13:15:53 -05:00
this.setState(connected ? 'Connected' : 'Sensor unavailable', connected);
} catch (error) {
this.setState('Invalid event', false);
}
});
this.source.addEventListener('error', () => this.setState('Reconnecting', false));
}
stop() {
if (this.source) this.source.close();
this.source = null;
}
}
2026-06-28 13:25:14 -05:00
customElements.define('temperature-card', TemperatureCard);