From 533d5a34f20432c9b63e9c88f25452e0edd530e5 Mon Sep 17 00:00:00 2001 From: Kendrick Bollens Date: Thu, 7 May 2026 10:22:42 +0200 Subject: [PATCH] Sync-Fix, Dateinamen mit Leerzeichen, E-Mail-Dropdown, Defaults-System MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix: Pull überschreibt lokale Vorlagen nicht mehr (Merge statt Replace) - Fix: toFilename behält Leerzeichen und Groß-/Kleinschreibung - E-Mail in Settings ist jetzt ein Dropdown mit TB-Identitäten - Optionale defaults.local.js für vorkonfigurierte Verbindungsdaten (.gitignored) --- .gitignore | 1 + lib/gitea-sync.js | 14 ++++++++---- templates_options/templates_options.html | 7 ++++-- templates_options/templates_options.js | 27 +++++++++++++++++++++++- 4 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..683b324 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +defaults.local.js diff --git a/lib/gitea-sync.js b/lib/gitea-sync.js index 8755d91..daa7064 100644 --- a/lib/gitea-sync.js +++ b/lib/gitea-sync.js @@ -203,13 +203,13 @@ class SyncManager { static toFilename(name) { return name - .toLowerCase() .replace(/[äÄ]/g, 'ae') .replace(/[öÖ]/g, 'oe') .replace(/[üÜ]/g, 'ue') .replace(/ß/g, 'ss') - .replace(/[^a-z0-9]+/g, '-') - .replace(/^-+|-+$/g, ''); + .replace(/[/\\:*?"<>|]/g, '-') + .replace(/^[\s.-]+|[\s.-]+$/g, '') + .trim(); } /** @@ -291,7 +291,13 @@ class SyncManager { } } - await this.saveLocalTemplates(newTemplates); + // Merge: keep local-only templates that aren't now on the server + const existingTemplates = await this.getLocalTemplates(); + const pulledFilenames = new Set(newTemplates.map(t => SyncManager.toFilename(t.name).toLowerCase())); + const localOnly = existingTemplates.filter(t => !t.remotePath && !pulledFilenames.has(SyncManager.toFilename(t.name).toLowerCase())); + + const merged = [...newTemplates, ...localOnly]; + await this.saveLocalTemplates(merged); syncState.fileShas = newShas; await this.saveSyncState(syncState); diff --git a/templates_options/templates_options.html b/templates_options/templates_options.html index 3cff284..7404451 100644 --- a/templates_options/templates_options.html +++ b/templates_options/templates_options.html @@ -976,8 +976,10 @@
- - + +
@@ -1060,6 +1062,7 @@ + diff --git a/templates_options/templates_options.js b/templates_options/templates_options.js index ce823ee..568ae26 100644 --- a/templates_options/templates_options.js +++ b/templates_options/templates_options.js @@ -1366,10 +1366,34 @@ document.getElementById('footer-save-button').addEventListener('click', async () // ── Sync Settings UI ── +async function populateEmailDropdown() { + const select = document.getElementById('sync-author-email'); + const accounts = await browser.accounts.list(); + const emails = new Set(); + for (const account of accounts) { + for (const identity of account.identities) { + if (identity.email && !emails.has(identity.email)) { + emails.add(identity.email); + const opt = document.createElement('option'); + opt.value = identity.email; + opt.textContent = identity.email; + select.appendChild(opt); + } + } + } +} + async function loadSyncConfig() { try { const result = await browser.storage.local.get(SYNC_CONFIG_KEY); - const config = result[SYNC_CONFIG_KEY]; + let config = result[SYNC_CONFIG_KEY]; + + // First launch: apply defaults from defaults.local.js if available + if (!config && typeof DEFAULT_SYNC_CONFIG !== 'undefined') { + config = { ...DEFAULT_SYNC_CONFIG }; + await browser.storage.local.set({ [SYNC_CONFIG_KEY]: config }); + } + if (config) { document.getElementById('sync-url').value = config.baseUrl || ''; document.getElementById('sync-owner').value = config.owner || ''; @@ -1640,6 +1664,7 @@ window.addEventListener('load', async () => { const templates = await getTemplates(); renderTemplates(templates); updateTplSyncIndicator(); + await populateEmailDropdown(); loadSyncConfig(); await loadIdentities();