diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index ea20d08..914bd5d 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -74,6 +74,7 @@
{{ currentFile || 'No file open' }}
+ Draft saved
{{ fileMeta }}
@@ -514,14 +515,53 @@ async function openFile(path) {
}
}
isDirty.value = false
+ draftSaved.value = false
view.value = 'files'
showHistory.value = false
showShareDialog.value = false
aiResult.value = ''
+
+ // Check for unsaved draft
+ const draft = loadDraft()
+ if (draft && draft !== content.value) {
+ if (confirm('You have an unsaved draft for this file. Restore it?')) {
+ content.value = draft
+ isDirty.value = true
+ } else {
+ clearDraft()
+ }
+ }
loadHistory()
checkGitStatus()
}
+// ─── Auto-draft ──────────────────────────────────────────────────────────────
+
+const draftSaved = ref(false)
+let draftTimer = null
+
+function onEdit() {
+ isDirty.value = true
+ draftSaved.value = false
+ clearTimeout(draftTimer)
+ draftTimer = setTimeout(() => {
+ const key = currentFile.value || '_unsaved'
+ localStorage.setItem('mh_draft_' + key, content.value)
+ draftSaved.value = true
+ }, 1000)
+}
+
+function clearDraft() {
+ const key = currentFile.value || '_unsaved'
+ localStorage.removeItem('mh_draft_' + key)
+ draftSaved.value = false
+}
+
+function loadDraft() {
+ const key = currentFile.value || '_unsaved'
+ return localStorage.getItem('mh_draft_' + key)
+}
+
async function saveFile() {
if (!currentFile.value) {
const name = prompt('Save as (e.g. notes.md):')
@@ -551,6 +591,7 @@ async function saveFile() {
}
cacheFile(currentFile.value, content.value)
isDirty.value = false
+ clearDraft()
setTimeout(checkGitStatus, 1000)
}
@@ -1200,6 +1241,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
}
.file-name { color: var(--text-muted); font-size: 13px; }
+.draft-indicator { color: var(--success); font-size: 11px; opacity: 0.8; }
.export-actions { display: flex; gap: 4px; }
.export-actions button {