From 0e3ccac6a92527219fd508b0760e3d90e97e8015 Mon Sep 17 00:00:00 2001 From: Thomas Cravey Date: Sun, 17 Aug 2025 14:53:57 -0500 Subject: [PATCH] fix(webui): compute dynamic header/footer heights; use CSS vars for margins; re-scroll after images/cards via rAF --- internal/httpapi/static/app.css | 2 +- internal/httpapi/static/app.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/httpapi/static/app.css b/internal/httpapi/static/app.css index 6cd2359..f10eb61 100644 --- a/internal/httpapi/static/app.css +++ b/internal/httpapi/static/app.css @@ -1,7 +1,7 @@ html, body { height: 100%; } body { padding: 0; min-height: 100vh; } header.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; padding: .6rem 1rem; border-bottom: 1px solid var(--muted-border-color); display: flex; justify-content: space-between; align-items: center; background-color: var(--pico-background-color, #fff); } -main, article, .dash { margin-top: 56px; margin-bottom: 44px; } +main, article, .dash { margin-top: var(--headerH, 56px); margin-bottom: var(--footerH, 44px); } header.nav a.brand { text-decoration: none; font-weight: 600; } /* Dashboard-only grid layout */ .dash { display: grid; grid-template-columns: 220px 1fr; gap: 0; } diff --git a/internal/httpapi/static/app.js b/internal/httpapi/static/app.js index e461d1d..b9735d3 100644 --- a/internal/httpapi/static/app.js +++ b/internal/httpapi/static/app.js @@ -65,6 +65,11 @@ function startStream(){ const el=document.getElementById('tail'); if(!el) return async function summarize(){ const ch=document.getElementById('channel'); const win=document.getElementById('window'); const push=document.getElementById('push'); const btn=document.getElementById('btn'); const out=document.getElementById('out'); if(!ch||!win||!btn||!out) return; btn.disabled=true; out.textContent=''; try{ const data = await api('/api/trigger',{query:{channel:ch.value,window:win.value||'6h',push:push && push.checked? '1':'0'}}); if(typeof data === 'string'){ out.textContent = data; } else { out.textContent = (data.summary||''); } } catch(e){ out.textContent = 'error: '+e; } btn.disabled=false; } window.addEventListener('DOMContentLoaded', ()=>{ + // measure header/footer and set margins so last lines are visible + const hdr = document.querySelector('header.nav'); + const ftr = document.querySelector('footer'); + if(hdr){ document.documentElement.style.setProperty('--headerH', hdr.getBoundingClientRect().height+'px'); } + if(ftr){ document.documentElement.style.setProperty('--footerH', ftr.getBoundingClientRect().height+'px'); } if(document.getElementById('chanlist')){ loadChannels(); } if(document.getElementById('channel')){ fetch('/api/channels').then(r=>r.json()).then(arr=>{ const sel=document.getElementById('channel'); arr.forEach(c=>{ const o=document.createElement('option'); o.value=c; o.textContent=c; sel.appendChild(o); }); }).catch(()=>{});