Add Refresh Now button and configurable frame_host

- Trigger endpoint on frame Pi (port 8080) starts birdframe.service
- Frame admin panel has a Refresh Now button at the top
- frame_host config field lets user set the frame Pi's IP/hostname
- Button uses frame_host from config (no hardcoded hostname)

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
Chris Sader
2026-07-17 18:15:27 -05:00
parent 5314b24c02
commit f0c2b8fd05
3 changed files with 32 additions and 2 deletions
+17 -2
View File
@@ -2435,6 +2435,9 @@
.then(function (fc) {
adminBody.innerHTML =
'<div class="admin-settings">'
+ '<div class="menu-row" style="justify-content:center;padding:12px 0">'
+ ' <button type="button" id="frameRefreshBtn" class="frame-refresh-btn">Refresh Now</button>'
+ '</div>'
+ '<div class="frame-section-label">Display</div>'
+ frameSegmented('mode', 'Mode', 'how the time window works', fc.mode, [
{ v: 'today', label: 'today' },
@@ -2465,6 +2468,7 @@
+ frameSlider('mat_opening_w', 'Mat width', 'matte opening width (inches, 0=default)', fc.mat_opening_w, 0, 12, 0.5, 1)
+ frameSlider('mat_opening_h', 'Mat height', 'matte opening height (inches, 0=default)', fc.mat_opening_h, 0, 14, 0.5, 1)
+ frameSlider('mat', 'Extra mat', 'global content shrink inside opening', fc.mat, 0, 0.1, 0.01, 2)
+ frameInput('frame_host', 'Frame address', 'IP or hostname of the frame Pi', fc.frame_host || '')
+ frameInput('panel', 'Panel driver', 'force driver (blank=auto)', fc.panel || '')
+ frameSlider('timeout', 'Timeout', 'seconds to wait for page render', fc.timeout, 10, 120, 5, 0)
+ '<div class="frame-section-label">Source</div>'
@@ -2481,7 +2485,7 @@
+ frameInput('basic_user', 'Username', 'basic auth username', fc.basic_user || '')
+ frameInput('basic_pass', 'Password', 'basic auth password', fc.basic_pass || '', true)
+ '</div>';
wireFrameControls();
wireFrameControls(fc);
})
.catch(function (err) {
adminBody.innerHTML =
@@ -2549,8 +2553,19 @@
}, 500);
}
function wireFrameControls() {
function wireFrameControls(fc) {
var pending = {};
var refreshBtn = document.getElementById('frameRefreshBtn');
if (refreshBtn) {
refreshBtn.addEventListener('click', function () {
refreshBtn.textContent = 'Refreshing...';
refreshBtn.disabled = true;
fetch('http://' + (fc.frame_host || 'birdpic.local') + ':8080/refresh', { method: 'POST', mode: 'cors' })
.then(function () { refreshBtn.textContent = 'Triggered'; })
.catch(function () { refreshBtn.textContent = 'Failed (check LAN)'; })
.finally(function () { setTimeout(function () { refreshBtn.textContent = 'Refresh Now'; refreshBtn.disabled = false; }, 3000); });
});
}
adminBody.querySelectorAll('.switch[data-frame-key]').forEach(function (sw) {
sw.addEventListener('click', function () {
var on = sw.getAttribute('aria-checked') !== 'true';
+14
View File
@@ -1634,3 +1634,17 @@ body.av-local #dd-items { display: block; }
}
.frame-section-label:first-child { padding-top: 4px; }
.frame-refresh-btn {
font: 600 13px/1 var(--sans, ui-sans-serif, system-ui, sans-serif);
padding: 10px 24px;
border: 1px solid var(--ink-soft, #8a8078);
border-radius: 6px;
background: transparent;
color: var(--ink, #1a1612);
cursor: pointer;
transition: background 0.15s, opacity 0.15s;
}
.frame-refresh-btn:hover { background: rgba(26,22,18,0.05); }
.frame-refresh-btn:disabled { opacity: 0.5; cursor: default; }