diff --git a/chfs-ng/internal/api/web/index.html b/chfs-ng/internal/api/web/index.html index 14f1011..d6041bd 100644 --- a/chfs-ng/internal/api/web/index.html +++ b/chfs-ng/internal/api/web/index.html @@ -75,7 +75,7 @@ function toggleTile(p){selectItem(p,!selected.has(p))} function openSelected(){if(selected.size!==1)return;const p=[...selected][0],f=lastItems.find(x=>(current?current+"/":"")+x.name===p);if(!f)return;if(f.dir&&(f.mask||"").includes("R"))openDir(p);else if((f.mask||"").includes("R"))previewFile(p)} function toggleAll(v){lastItems.forEach(f=>{const p=current?current+"/"+f.name:f.name;if(v)selected.add(p);else selected.delete(p)});render(lastItems)} function clearSelection(){selected.clear();updateSelection();renderGrid(lastItems);renderList(lastItems)} -function updateSelection(){const n=selected.size;$("bulk").classList.toggle("show",n>0);$("selectedCount").textContent=n?`已选择 ${n} 项`:"";$("grid").querySelectorAll('.tile').forEach((el,i)=>{const f=lastItems[i];if(f)el.classList.toggle('selected',selected.has(current?current+'/'+f.name:f.name))})} +function updateSelection(){const n=selected.size;$("bulk").classList.toggle("show",n>0);$("selectedCount").textContent=n?("已选择 "+n+" 项"):"";document.querySelectorAll("#files .file-row").forEach(row=>{const p=row.dataset.searchPath||row.dataset.filePath;row.classList.toggle("selected",!!p&&selected.has(p));const cb=row.querySelector(".selectbox");if(cb)cb.checked=!!p&&selected.has(p)});$("grid").querySelectorAll(".tile").forEach((el,i)=>{const f=lastItems[i];if(f){const p=current?current+"/"+f.name:f.name,yes=selected.has(p);el.classList.toggle("selected",yes);const cb=el.querySelector(".selectbox");if(cb)cb.checked=yes}})} function setView(v){localStorage.setItem('chfs-view',v);$("files").parentElement.hidden=v==='grid';$("grid").hidden=v!=='grid';document.querySelectorAll('.viewbtn').forEach(b=>b.classList.remove('active'));$(v+'Btn').classList.add('active')} function itemMenu(e,p){e.preventDefault();if(!selected.has(p)){selected.clear();selected.add(p);updateSelection();renderList(lastItems);renderGrid(lastItems)}const f=lastItems.find(x=>(current?current+'/':'')+x.name===p);const canRead=(f?.mask||'').includes('R'),canWrite=(f?.mask||'').includes('W'),canDelete=(f?.mask||'').includes('D');let html='';if(canRead)html+='';if(f?.dir&&canRead)html+='';if(canWrite)html+='';if(canDelete)html+='';if(f?.guestMask?.includes('R'))html+='';if(!html)html='
';$("context").innerHTML=html;$("context").style.left=Math.min(e.clientX,innerWidth-190)+'px';$("context").style.top=Math.min(e.clientY,innerHeight-220)+'px';$("context").style.display='block'} function closeContext(){$("context").style.display='none'} @@ -120,9 +120,9 @@ function setupDropZone(){const z=$("dropZone"),main=$("fileCard");let depth=0;[d function uploadOne(file,row,relativePath=file.name,task=null){return new Promise(resolve=>{const xhr=new XMLHttpRequest(),fd=new FormData();if(task)task.xhr=xhr;const clean=String(relativePath||file.name).replace(/\\/g,'/').replace(/^\/+|\/+$/g,'');const parts=clean.split('/');const name=parts.pop()||file.name;const folder=parts.length?[current,...parts].filter(Boolean).join('/') : current;fd.append("folder",folder);fd.append("file",file,name);const meta=row.querySelector('.meta'),bar=row.querySelector('i');xhr.open('POST','/chfs/upload');xhr.upload.onprogress=e=>{if(e.lengthComputable){const pct=Math.round(e.loaded/e.total*100);bar.style.width=pct+'%';meta.textContent=fmt(file.size)+' · '+pct+'%'}};xhr.onload=()=>{const ok=xhr.status>=200&&xhr.status<300;if(ok){bar.style.width='100%';meta.textContent=fmt(file.size)+' · 完成'}else{meta.textContent='上传失败'+(xhr.status?' · '+xhr.status:'');bar.style.width='0'};if(task)task.xhr=null;resolve(ok)};xhr.onerror=()=>{if(task&&task.state==='cancelled'){meta.textContent=fmt(file.size)+' · 已取消'}else{meta.textContent='网络错误';bar.style.width='0'};if(task)task.xhr=null;resolve(false)};xhr.onabort=()=>{if(task)task.xhr=null;resolve(false)};xhr.send(fd)})} let searchMode=false,searchItems=[]; $("search").addEventListener("keydown",async e=>{if(e.key!=="Enter")return;const s=e.target.value.trim();if(!s){searchMode=false;searchItems=[];refresh();return}try{const d=await api("/chfs/search?str="+encodeURIComponent(s));renderSearch(d.files||[])}catch(x){fail(x.message)}}) -function renderSearch(items){searchMode=true;searchItems=items;selected.clear();$("crumb").textContent="搜索结果";$("files").parentElement.hidden=false;$("grid").hidden=true;$("bulk").classList.remove("show");const body=$("files");body.innerHTML=items.length?items.map(f=>{const p=f.path;return '