fix(webui): correct initial snap-to-bottom using rAF; add top/bottom margins under fixed bars; ensure page shows last lines on load
This commit is contained in:
parent
c125d05f26
commit
645ea9f2b9
2 changed files with 4 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
|||
html, body { height: 100%; }
|
||||
body { padding: 56px 0 44px 0; min-height: 100vh; }
|
||||
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; }
|
||||
header.nav a.brand { text-decoration: none; font-weight: 600; }
|
||||
/* Dashboard-only grid layout */
|
||||
.dash { display: grid; grid-template-columns: 220px 1fr; gap: 0; }
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ async function api(path, params){
|
|||
return res.text();
|
||||
}
|
||||
|
||||
function appendBatch(arr){ const el=document.getElementById('tail'); const frag=document.createDocumentFragment(); arr.forEach(m=>{ const div=document.createElement('div'); div.className='msg'; div.innerHTML=lineHTML(m); frag.appendChild(div); processLinks(div); }); el.appendChild(frag); if(st.atBottom){ window.scrollTo({top: document.body.scrollHeight, behavior: 'instant'}); } }
|
||||
function appendBatch(arr){ const el=document.getElementById('tail'); const frag=document.createDocumentFragment(); arr.forEach(m=>{ const div=document.createElement('div'); div.className='msg'; div.innerHTML=lineHTML(m); frag.appendChild(div); processLinks(div); }); el.appendChild(frag); if(st.atBottom){ requestAnimationFrame(()=>{ window.scrollTo({top: document.documentElement.scrollHeight, behavior: 'instant'}); }); } }
|
||||
function prependBatch(arr){ const el=document.getElementById('tail'); const oldTop=el.firstChild; const beforeTop = oldTop ? oldTop.getBoundingClientRect().top : 0; const frag=document.createDocumentFragment(); arr.forEach(m=>{ const div=document.createElement('div'); div.className='msg'; div.innerHTML=lineHTML(m); frag.appendChild(div); processLinks(div); }); el.insertBefore(frag, el.firstChild); // preserve visual position
|
||||
if(oldTop){ const afterTop = oldTop.getBoundingClientRect().top; const delta = afterTop - beforeTop; window.scrollBy({top: delta, left: 0, behavior: 'instant'}); } }
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ async function loadChannels(){ try{ const data = await api('/api/channels'); st.
|
|||
function renderChannels(){ const list=document.getElementById('chanlist'); if(!list) return; list.innerHTML=''; st.channels.forEach(c=>{ const a=document.createElement('a'); a.href='#'; a.textContent=c; a.onclick=(ev)=>{ev.preventDefault(); selectChannel(c)}; if(c===st.current) a.className='active'; list.appendChild(a); }); }
|
||||
|
||||
async function selectChannel(ch){ if(st.sse){ st.sse.close(); st.sse=null; } st.current=ch; renderChannels(); const el=document.getElementById('tail'); if(!el) return; el.textContent=''; const data = await api('/api/tail',{query:{channel:ch,limit:50}}); appendBatch(data); // snap to bottom after initial load
|
||||
setTimeout(()=>{ window.scrollTo({ top: document.documentElement.scrollHeight, behavior: 'instant' }); st.atBottom=true; }, 0);
|
||||
requestAnimationFrame(()=>{ window.scrollTo({ top: document.documentElement.scrollHeight, behavior: 'instant' }); st.atBottom=true; });
|
||||
st.earliest = data.length? data[0].time : null; startStream(); initScrollHandlers(); }
|
||||
function initScrollHandlers(){ const el=document.getElementById('tail'); if(!el) return; const onScroll = async ()=>{ const nearBottom = (window.innerHeight + window.pageYOffset + 16) >= document.documentElement.scrollHeight; st.atBottom = nearBottom; const nearTop = window.pageYOffset <= 4; if(nearTop && st.earliest){ try{ const older = await api('/api/history',{query:{channel:st.current,before:st.earliest,limit:50}}); if(older.length){ prependBatch(older); st.earliest = older[0].time; } } catch(e){} } }; window.removeEventListener('scroll', st._scrollHandler || (()=>{})); st._scrollHandler = onScroll; window.addEventListener('scroll', onScroll, {passive:true}); }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue