记忆台
← 返回 国内API中转站对比清单_20260814.html 32.9K · 2026-10-05
\n\n\n"; const ta=document.getElementById('src'), pv=document.getElementById('preview'); ta.value=text; let dirty=false; const dot=document.getElementById('dot'); function refresh(){ pv.innerHTML=mdToHtml(ta.value); } function grow(){ ta.style.height='auto'; ta.style.height=(ta.scrollHeight+4)+'px'; } function markDirty(){ dirty=true; dot.classList.add('on'); document.getElementById('stat').textContent='未保存'; } ta.addEventListener('input',()=>{ markDirty(); grow(); // 草稿:切走 App 或刷新时先落在本机,回来能捡 const DKEY='memodesk-draft:'+PATH; ta.addEventListener('input',()=>{ try{ localStorage.setItem(DKEY, JSON.stringify({t:ta.value,at:Date.now()})); }catch(e){} }); (function(){ let d=null; try{ d=JSON.parse(localStorage.getItem(DKEY)||'null'); }catch(e){} if(d && d.t && d.t!==ta.value){ const bar=document.createElement('div'); bar.style.cssText='margin:10px 0 0;padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:var(--panel2);font-size:13.5px;display:flex;gap:10px;align-items:center;flex-wrap:wrap'; bar.innerHTML='有个没存的草稿('+new Date(d.at).toLocaleString('zh-CN')+')'; const b1=document.createElement('button'); b1.className='btn'; b1.textContent='捡回来'; b1.onclick=()=>{ ta.value=d.t; markDirty(); grow(); bar.remove(); }; const b2=document.createElement('button'); b2.className='btn ghost'; b2.textContent='丢掉'; b2.onclick=()=>{ localStorage.removeItem(DKEY); bar.remove(); }; bar.appendChild(b1); bar.appendChild(b2); document.getElementById('editor-area').prepend(bar); } })(); }); ta.addEventListener('keydown',e=>{ if(e.key==='Tab'){ e.preventDefault(); const s=ta.selectionStart, en=ta.selectionEnd; ta.value=ta.value.slice(0,s)+' '+ta.value.slice(en); ta.selectionStart=ta.selectionEnd=s+2; markDirty(); grow(); } }); grow(); document.getElementById('toggle').onclick=()=>{ const showing=pv.style.display!=='none'; if(showing){ pv.style.display='none'; ta.style.display='block'; grow(); document.getElementById('toggle').textContent='预览'; } else { refresh(); pv.style.display='block'; ta.style.display='none'; document.getElementById('toggle').textContent='编辑'; } }; function toast(t){ const el=document.getElementById('toast'); el.textContent=t; el.classList.add('show'); setTimeout(()=>el.classList.remove('show'),1600); } async function save(){ const btn=document.getElementById('save'); btn.disabled=true; btn.textContent='存…'; try{ const r=await fetch('./api/save',{method:'POST',headers:{'Content-Type':'application/json'}, body:JSON.stringify({p:PATH,text:ta.value})}); const j=await r.json(); if(!j.ok) throw new Error(j.error||'保存失败'); dirty=false; dot.classList.remove('on'); try{ localStorage.removeItem('memodesk-draft:'+PATH); }catch(e){} document.getElementById('stat').textContent=j.size+' · 刚刚'; btn.textContent='已存'; toast('存好了喵'); setTimeout(()=>btn.textContent='保存',1200); }catch(e){ toast('保存失败:'+e.message); btn.textContent='保存'; } finally{ btn.disabled=false; } } document.getElementById('save').onclick=save; document.addEventListener('keydown',e=>{ if((e.metaKey||e.ctrlKey)&&e.key==='s'){ e.preventDefault(); save(); } }); window.addEventListener('beforeunload',e=>{ if(dirty){ e.preventDefault(); e.returnValue=''; } }); document.getElementById('history').onclick=async()=>{ const box=document.getElementById('histbox'); const list=JSON.parse([]); if(!list.length){ toast('还没有旧稿'); return; } box.style.display='block'; box.innerHTML='
'+list.map(h=>`
${h.id}${h.when} · ${h.size}
`).join('')+'
'; }; async function restore(id){ if(!confirm('用这份旧稿覆盖当前内容?')) return; const r=await fetch('./api/restore',{method:'POST',headers:{'Content-Type':'application/json'}, body:JSON.stringify({p:PATH,id:id})}); const j=await r.json(); if(j.ok){ ta.value=j.text; dirty=true; toast('已载入旧稿,记得保存'); } else toast('恢复失败'); }