From 57710fd0010e61a2cf05d9757202967ed533e22e Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 7 Jun 2026 05:36:45 -0400 Subject: [PATCH] Files in, files out: Save .txt and drag-drop import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drafts escape localStorage — a Save .txt button downloads the current draft (named after its first line), and dropping text files anywhere on the page turns each into a new draft tab. Co-Authored-By: Claude Opus 4.8 (1M context) --- static/index.html | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/static/index.html b/static/index.html index 7712ec2..9c02a90 100644 --- a/static/index.html +++ b/static/index.html @@ -278,6 +278,7 @@ Double-click any word to look it up on the right.">
+ @@ -943,6 +944,39 @@ document.getElementById('exportBtn').addEventListener('click', async ()=>{ }); }); +/* ============================================================ + FILES IN, FILES OUT — drafts shouldn't be hostage to localStorage +============================================================ */ +function draftFilename(){ + const doc = docsState.docs.find(d=>d.id===docsState.current); + return (((doc && doc.title && doc.title !== 'Untitled') ? doc.title : 'rhymepad') + .replace(/[^\w\- ]+/g, '').trim() || 'rhymepad') + '.txt'; +} +document.getElementById('downloadBtn').addEventListener('click', ()=>{ + if(!editor.value.trim()) return; + const a = document.createElement('a'); + a.href = URL.createObjectURL(new Blob([editor.value], {type: 'text/plain'})); + a.download = draftFilename(); + a.click(); + setTimeout(()=>URL.revokeObjectURL(a.href), 5000); + flash('downloadBtn', 'Saved \u2713'); +}); +// drop a .txt (or any text file) anywhere -> it becomes a new draft +document.addEventListener('dragover', e=>{ e.preventDefault(); }); +document.addEventListener('drop', async e=>{ + e.preventDefault(); + const files = [...(e.dataTransfer?.files || [])].slice(0, 8); + for(const f of files){ + if(f.size > 1024 * 1024) continue; + const text = await f.text(); + if(!text.trim()) continue; + const id = newId(); + docsState.docs.push({id, title: titleOf(text)}); + localStorage.setItem(docKey(id), text); + openDoc(id); + } +}); + /* ============================================================ COPY / CLEAR / SAMPLE ============================================================ */