Speed up library loading with shared runtime checks and browser cache

This commit is contained in:
Mikei386
2026-10-01 09:32:44 +02:00
parent e16e3dea38
commit a72ebe045a
4 changed files with 52 additions and 8 deletions
+10 -2
View File
@@ -1,5 +1,6 @@
/* Original Deck UI, inspired by LocalAI's explore/detail/download workflow. */
window.CatalogUI = (() => {
let cachedCatalog = null; // Memory only: refreshed on every visit; never stores access tokens.
const escape = value => String(value ?? '').replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
const size = n => { if (!Number.isFinite(n)) return 'Unbekannt'; if(n < 1024) return n+' B'; const unit = n >= 1024**3 ? 'GiB' : n >= 1024**2 ? 'MiB' : 'KiB'; return (n / (unit === 'GiB' ? 1024**3 : unit === 'MiB' ? 1024**2 : 1024)).toFixed(1)+' '+unit; };
const number = n => Number.isFinite(n) ? new Intl.NumberFormat('de-DE', {notation:'compact'}).format(n) : '–';
@@ -45,8 +46,8 @@ window.CatalogUI = (() => {
}
async function refresh() {
if (refreshing || !root.isConnected) return; refreshing = true; clearTimeout(timer);
try { const next = await api(''); if (!root.isConnected) return; const entriesChanged = JSON.stringify(next.entries) !== JSON.stringify(state.entries); const statusChanged = JSON.stringify(next) !== JSON.stringify(state); state = next; if (statusChanged) renderJob(); if (library) { if (entriesChanged || !libraryRendered) { renderLibrary(); libraryRendered = true; root.querySelectorAll('[data-profile-model]').forEach(b=>b.onclick=()=>kind==='video'?fetch('/api/v1/video/service',{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify({id:b.dataset.profileModel})}).then(async r=>{const data=await r.json();if(!r.ok)throw Error(data.error);location.hash='video';VideoUI.runtime();}).catch(x=>alert(x.message)):Studio.openProfile(kind,b.dataset.profileModel)); } } else if (!downloads) { if (entriesChanged) renderModels(); updateSelection(); } }
catch(error) { message(error.message); }
try { const next = await api(''); if (!root.isConnected) return; const entriesChanged = JSON.stringify(next.entries) !== JSON.stringify(state.entries); const statusChanged = JSON.stringify(next) !== JSON.stringify(state); state = next; cachedCatalog = next; if (statusChanged) renderJob(); if (library) { if (entriesChanged || !libraryRendered) { renderLibrary(); libraryRendered = true; message(''); root.querySelectorAll('[data-profile-model]').forEach(b=>b.onclick=()=>kind==='video'?fetch('/api/v1/video/service',{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify({id:b.dataset.profileModel})}).then(async r=>{const data=await r.json();if(!r.ok)throw Error(data.error);location.hash='video';VideoUI.runtime();}).catch(x=>alert(x.message)):Studio.openProfile(kind,b.dataset.profileModel)); } } else if (!downloads) { if (entriesChanged) renderModels(); updateSelection(); } }
catch(error) { message(library && cachedCatalog ? 'Zuletzt geladene Dateien · Aktualisierung fehlgeschlagen: '+error.message : error.message); }
finally { refreshing = false; if (root.isConnected) timer = setTimeout(refresh, 2500); }
}
async function search(q) {
@@ -99,6 +100,13 @@ window.CatalogUI = (() => {
}
el('hub-refresh').onclick = refresh;
if (!library && !downloads) { try { el('hub-base-only').checked=localStorage.getItem('deck-base-only')==='true'; } catch {} el('hub-base-only').onchange=()=>{try { localStorage.setItem('deck-base-only',String(el('hub-base-only').checked)); } catch {} search(new FormData(el('hub-search')).get('q').trim());}; el('hub-sort').onchange = () => search(new FormData(el('hub-search')).get('q').trim()); el('hub-search').onsubmit = event => { event.preventDefault(); search(new FormData(event.target).get('q').trim()); }; search(''); }
if (library) {
if (cachedCatalog) {
state = cachedCatalog; renderLibrary();
root.querySelectorAll('[data-delete-model], [data-profile-model]').forEach(b=>b.disabled=true);
message('Zuletzt geladene Dateien · wird aktualisiert …');
} else message('Bibliothek wird geladen …');
}
refresh();
}
return {html,bind,executionHTML};