From 5305325d8166195d4c0798f116409bb994e1d0bb Mon Sep 17 00:00:00 2001 From: woogi Date: Wed, 5 Aug 2026 15:42:21 -0500 Subject: [PATCH] Fix model dropdown loading, cache models for 24h, and style build tag. --- frontend/index.html | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/frontend/index.html b/frontend/index.html index 731051c..f432342 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -15,6 +15,7 @@ header { padding:24px 28px; border-bottom:1px solid var(--line); } h1 { margin:0; font-size:20px; letter-spacing:.2px; } .sub { color:var(--muted); font-size:13px; margin-top:4px; } + #buildTag { display:inline-block; font-size:11px; background:rgba(91,140,255,.15); color:var(--accent); padding:2px 8px; border-radius:12px; margin-left:8px; vertical-align:middle; text-transform:none; letter-spacing:.3px; } main { max-width:920px; margin:0 auto; padding:28px; } .drop { border:1.5px dashed var(--line); border-radius:12px; padding:36px; text-align:center; background:var(--panel); transition:border-color .15s; cursor:pointer; } @@ -193,12 +194,38 @@ function fillSelect(sel, items, preferred){ } let modelsLoaded=false; +const MODELS_CACHE_KEY='cc_models_v1'; +const MODELS_CACHE_TTL=24*60*60*1000; +function loadModelsCache(){ + try{ + const raw=localStorage.getItem(MODELS_CACHE_KEY); + if(!raw) return null; + const parsed=JSON.parse(raw); + if(!parsed.ts || Date.now()-parsed.ts > MODELS_CACHE_TTL) return null; + return parsed.data||null; + }catch(e){ return null; } +} +function saveModelsCache(data){ + try{ localStorage.setItem(MODELS_CACHE_KEY, JSON.stringify({ts:Date.now(), data})); } + catch(e){} +} + async function loadModels(){ const note=document.getElementById('modelNote'); + const cached=loadModelsCache(); + if(cached){ + const defs=cached.defaults||{}; + fillSelect(visionSel, cached.vision, defs.vision); + fillSelect(textSel, cached.text, defs.text); + modelsLoaded=true; + note.textContent='('+(cached.text||[]).length+' text / '+(cached.vision||[]).length+' vision cached)'; + return; + } try{ const res=await fetch('/models'); if(!res.ok) throw new Error('models HTTP '+res.status); const data=await res.json(); + saveModelsCache(data); const defs=data.defaults||{}; fillSelect(visionSel, data.vision, defs.vision); fillSelect(textSel, data.text, defs.text); @@ -648,6 +675,7 @@ async function finalizeReview(){ fetch('/health').then(r=>r.ok?r.json():null).then(h=>{ if(h&&h.build) document.getElementById('buildTag').textContent=' ยท build '+h.build; }).catch(()=>{}); + loadModels(); const jobId=new URLSearchParams(location.search).get('job'); if(jobId){ statusEl.innerHTML='Loading job '+esc(jobId)+'...'; poll(jobId); } })();