diff --git a/index.html b/index.html index 6a0d551..a8895b8 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,11 @@ Astrolabe logo

Astrolabe

+
+ + + +
diff --git a/src/StorageManager.js b/src/StorageManager.js index c241f96..0e8c97d 100644 --- a/src/StorageManager.js +++ b/src/StorageManager.js @@ -13,4 +13,31 @@ export class StorageManager { saveSnippets(snippets) { localStorage.setItem(this.SNIPPETS_KEY, JSON.stringify(snippets)); } + + exportSnippets() { + const snippets = this.loadSnippets(); + const blob = new Blob([JSON.stringify(snippets, null, 2)], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'astrolabe-snippets.json'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } + + async importSnippets(file) { + try { + const text = await file.text(); + const snippets = JSON.parse(text); + if (!Array.isArray(snippets)) { + throw new Error('Invalid snippets format'); + } + this.saveSnippets(snippets); + return snippets; + } catch (err) { + throw new Error('Failed to import snippets: ' + err.message); + } + } } diff --git a/src/main.js b/src/main.js index f3eeb22..878a572 100644 --- a/src/main.js +++ b/src/main.js @@ -21,4 +21,28 @@ require(['vs/editor/editor.main'], async function () { window.editor = editor; snippetManager.setEditor(editor); + + document.getElementById('export-snippets').addEventListener('click', () => { + snippetManager.storageManager.exportSnippets(); + }); + + document.getElementById('import-snippets').addEventListener('click', () => { + document.getElementById('import-file').click(); + }); + + document.getElementById('import-file').addEventListener('change', async (e) => { + if (e.target.files.length > 0) { + try { + const snippets = await snippetManager.storageManager.importSnippets(e.target.files[0]); + snippetManager.snippets = snippets; + snippetManager.uiManager.renderSnippetList(snippets, snippetManager.currentSnippetId); + if (snippets.length > 0) { + snippetManager.loadSnippet(snippets[0].id); + } + e.target.value = ''; // Reset file input + } catch (err) { + alert(err.message); + } + } + }); }); diff --git a/src/styles.css b/src/styles.css index 550aecf..813c0c0 100644 --- a/src/styles.css +++ b/src/styles.css @@ -9,6 +9,7 @@ display: flex; align-items: center; gap: 0.75rem; + justify-content: space-between; } .app-header a { @@ -37,6 +38,21 @@ margin: 0; } +.header-controls { + display: flex; + gap: 0.5rem; +} + +.button.mini { + padding: 0.25rem 0.75rem; + font-size: 0.875rem; + background: #607D8B; +} + +.button.mini:hover { + background: #546E7A; +} + #vis { width: 100%; height: 100%;