function bulkDownload(){if(!selected.size)return;const first=[...selected][0];if(selected.size===1){downloadFile(first);return}location.href='/chfs/downloaddir/'+encodeURI(first.split('/').slice(0,-1).join('/'))}
function bulkDownload(){if(!selected.size)return;const q=[...selected].map(p=>'path='+encodeURIComponent(p)).join('&');location.href='/chfs/downloadzip?'+q}
async function bulkDelete(){if(!selected.size)return;if(!await confirmBox("批量删除","确定删除已选择的 "+selected.size+" 项?"))return;for(const p of [...selected]){try{await api('/chfs/rmfiles',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({filepath:p})})}catch(e){alert(p+': '+e.message)}}selected.clear();refresh()}
async function showRoots(){try{const d=await api("/chfs/roots");const roots=d.roots||[];let html='<h2>选择位置</h2><div>';for(const r of roots)html+='<buttonclass="ghost"style="display:block;width:100%;text-align:left;margin:8px 0"onclick="jumpRoot('+JSON.stringify(r.path)+')"><b>'+esc(r.name)+'</b><spanclass="meta"> · '+esc(r.path||"/")+' · '+esc(r.mask)+'</span></button>';if(!roots.length)html+='<divclass="empty">没有可进入的共享位置</div>';html+='</div><divclass="row"><buttonclass="ghost"onclick="closeModal()">关闭</button></div>';show(html)}catch(e){alert(e.message)}}
function jumpRoot(p){current=p;closeModal();refresh()}
@@ -77,7 +78,10 @@ async function renameItem(p){const name=p.split("/").pop();const n=await ask("
async function removeItem(p){if(!await confirmBox("确认删除","确定删除 "+p+"?"))return;try{await api("/chfs/rmfiles",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({filepath:p})});refresh()}catch(e){alert(e.message)}}
async function newFolder(){const n=await ask("新建文件夹","文件夹名称");if(!n)return;const p=current?current+"/"+n:n;try{await api("/chfs/newdir",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({filepath:p})});refresh()}catch(e){alert(e.message)}}
async function newText(){const n=await ask("新建文本","文件名","new.txt");if(!n)return;const text=await ask("新建文本","文本内容");if(text===null)return;try{await api("/chfs/newtext",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({filepath:current,title:n,text:text||""})});refresh()}catch(e){alert(e.message)}}
async function uploadFiles(files){const list=[...files];if(!list.length)return;show('<h2>上传文件</h2><divid="uploadList"></div><divclass="row"><buttonclass="ghost"onclick="closeModal()">后台继续</button></div>');const box=$("uploadList");for(const file of list){const row=document.createElement("div");row.className="upload-row";row.innerHTML='<b>'+esc(file.name)+'</b><spanclass="meta">'+fmt(file.size)+' · 准备上传</span><divclass="progress"><i></i></div>';box.appendChild(row);await uploadOne(file,row)}refresh()}
function showMobileTransfer(){const u=new URL(location.href);u.hash='folder='+encodeURIComponent(current);show('<h2>手机传输</h2><divclass="notice">用手机扫描二维码打开当前文件夹。登录后即可按你的权限上传、下载和管理文件。</div><imgclass="qr"src="/chfs/qrcode?url='+encodeURIComponent(u.href)+'"alt="QR Code"><divclass="field"><inputvalue="'+esc(u.href)+'"readonly></div><divclass="row"><buttonclass="ghost"onclick="closeModal()">关闭</button></div>')}
function setupDropZone(){const z=$("dropZone"),main=$("fileCard");let depth=0;[document,main].forEach(el=>{el.addEventListener('dragenter',e=>{if(!e.dataTransfer?.types.includes('Files'))return;e.preventDefault();depth++;z.style.display='block';z.classList.add('drop-active')});el.addEventListener('dragover',e=>{if(e.dataTransfer?.types.includes('Files'))e.preventDefault()});el.addEventListener('dragleave',e=>{if(!e.dataTransfer?.types.includes('Files'))return;depth--;if(depth<=0){depth=0;z.classList.remove('drop-active')}});el.addEventListener('drop',async e=>{if(!e.dataTransfer?.files?.length)return;e.preventDefault();depth=0;z.classList.remove('drop-active');z.style.display='none';await uploadFiles(e.dataTransfer.files)})})}
function uploadOne(file,row){return new Promise(resolve=>{const xhr=new XMLHttpRequest(),fd=new FormData();fd.append("folder",current);fd.append("file",file);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=()=>{if(xhr.status>=200&&xhr.status<300){bar.style.width='100%';meta.textContent=fmt(file.size)+' · 完成'}else{meta.textContent='上传失败';bar.style.width='0'}};xhr.onerror=()=>{meta.textContent='网络错误';bar.style.width='0'};xhr.onloadend=resolve;xhr.send(fd)})}
function renderSearch(items){$("crumb").textContent="搜索结果";const body=$("files");body.innerHTML="";for(const f of items){const row=document.createElement("tr");row.innerHTML='<td><divclass="name">🔎 <ahref="#"onclick="openDir('+JSON.stringify(f.dir?f.path:f.path.split("/").slice(0,-1).join("/")).replace(/^"/,'\\"')+');returnfalse">'+esc(f.path)+'</a></div></td><tdclass="meta">'+(f.dir?"—":fmt(f.size))+'</td><tdclass="meta">'+esc(f.modified||"")+'</td><td></td>';body.appendChild(row)}}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.