{% extends "base.html" %}
{% block content %}
<div class="card">
<div id="status" hx-get="/status" hx-trigger="load, every 5s" hx-swap="innerHTML">
Loading...
</div>
</div>
<div class="card preview" id="preview-card">
<h2>Display Preview</h2>
<div id="preview-loading" class="loading-overlay" style="display: none;">
<span class="spinner" style="width: 2em; height: 2em;"></span>
</div>
<img id="lcd-preview" src="/lcd.png" alt="LCD Preview">
</div>
<script>
(function() {
const img = document.getElementById('lcd-preview');
const loading = document.getElementById('preview-loading');
let intervalId = null;
let pendingRefresh = false;
function showLoading() {
loading.style.display = 'flex';
}
function hideLoading() {
loading.style.display = 'none';
}
function refresh() {
const next = new Image();
next.onload = () => {
img.src = next.src;
hideLoading();
pendingRefresh = false;
};
next.onerror = () => {
hideLoading();
pendingRefresh = false;
};
next.src = '/lcd.png?t=' + Date.now();
}
function refreshAfterChange() {
if (pendingRefresh) return;
pendingRefresh = true;
showLoading();
setTimeout(refresh, 100);
}
document.body.addEventListener('htmx:beforeRequest', function(evt) {
const target = evt.detail.elt;
if (target.closest('#orientation, #theme-controls, #face-controls, #complications-controls, #led-controls')) {
showLoading();
}
});
document.body.addEventListener('htmx:afterSettle', function(evt) {
const target = evt.detail.elt;
if (target.closest('#orientation, #theme-controls, #face-controls, #complications-controls')) {
refreshAfterChange();
}
});
const evtSource = new EventSource('/events');
evtSource.addEventListener('orientation', function(e) {
htmx.trigger('#orientation', 'load');
refreshAfterChange();
});
evtSource.addEventListener('display', function(e) {
htmx.trigger('#theme-controls', 'load');
htmx.trigger('#face-controls', 'load');
htmx.trigger('#complications-controls', 'reload');
refreshAfterChange();
});
evtSource.addEventListener('complication', function(e) {
htmx.trigger('#complications-controls', 'reload');
refreshAfterChange();
});
evtSource.addEventListener('led', function(e) {
htmx.trigger('#led-controls', 'load');
});
evtSource.onerror = function() {
setTimeout(function() {
evtSource.close();
}, 5000);
};
intervalId = setInterval(refresh, 1000);
})();
</script>
<div class="section">
<h3 class="section-header">LCD Display</h3>
<div class="card">
<h2>Orientation</h2>
<div id="orientation" hx-get="/orientation" hx-trigger="load" hx-swap="innerHTML">
Loading...
</div>
</div>
<div class="card-row">
<div class="card">
<h2>Theme</h2>
<div id="theme-controls" hx-get="/theme" hx-trigger="load" hx-swap="innerHTML">
Loading...
</div>
</div>
<div class="card">
<h2>Display Face</h2>
<div id="face-controls" hx-get="/face" hx-trigger="load" hx-swap="innerHTML"
hx-on::after-settle="htmx.trigger('#complications-controls', 'reload')">
Loading...
</div>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<h2>Complications</h2>
<div id="complications-controls" hx-get="/complications" hx-trigger="load, reload" hx-swap="innerHTML">
Loading...
</div>
</div>
</div>
<div class="section">
<h3 class="section-header">LED Strip</h3>
<div class="card">
<div id="led-controls" hx-get="/led" hx-trigger="load" hx-swap="innerHTML">
Loading...
</div>
</div>
</div>
{% endblock %}