Sync-Fix, Dateinamen mit Leerzeichen, E-Mail-Dropdown, Defaults-System

- 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)
This commit is contained in:
Kendrick Bollens
2026-05-07 10:22:42 +02:00
parent 1d00a06e30
commit 533d5a34f2
4 changed files with 42 additions and 7 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
defaults.local.js

View File

@@ -203,13 +203,13 @@ class SyncManager {
static toFilename(name) { static toFilename(name) {
return name return name
.toLowerCase()
.replace(/[äÄ]/g, 'ae') .replace(/[äÄ]/g, 'ae')
.replace(/[öÖ]/g, 'oe') .replace(/[öÖ]/g, 'oe')
.replace(/[üÜ]/g, 'ue') .replace(/[üÜ]/g, 'ue')
.replace(/ß/g, 'ss') .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; syncState.fileShas = newShas;
await this.saveSyncState(syncState); await this.saveSyncState(syncState);

View File

@@ -976,8 +976,10 @@
<input type="text" id="sync-author-name" placeholder="z.B. Max Mustermann"> <input type="text" id="sync-author-name" placeholder="z.B. Max Mustermann">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="sync-author-email">Deine E-Mail (optional)</label> <label for="sync-author-email">Deine E-Mail</label>
<input type="text" id="sync-author-email" placeholder="z.B. max@hotel-park-soltau.de"> <select id="sync-author-email" style="width:100%;">
<option value="">— Bitte wählen —</option>
</select>
</div> </div>
</div> </div>
@@ -1060,6 +1062,7 @@
</div> </div>
</div> </div>
<script src="../defaults.local.js" onerror=""></script>
<script src="templates_options.js"></script> <script src="templates_options.js"></script>
</body> </body>
</html> </html>

View File

@@ -1366,10 +1366,34 @@ document.getElementById('footer-save-button').addEventListener('click', async ()
// ── Sync Settings UI ── // ── 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() { async function loadSyncConfig() {
try { try {
const result = await browser.storage.local.get(SYNC_CONFIG_KEY); 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) { if (config) {
document.getElementById('sync-url').value = config.baseUrl || ''; document.getElementById('sync-url').value = config.baseUrl || '';
document.getElementById('sync-owner').value = config.owner || ''; document.getElementById('sync-owner').value = config.owner || '';
@@ -1640,6 +1664,7 @@ window.addEventListener('load', async () => {
const templates = await getTemplates(); const templates = await getTemplates();
renderTemplates(templates); renderTemplates(templates);
updateTplSyncIndicator(); updateTplSyncIndicator();
await populateEmailDropdown();
loadSyncConfig(); loadSyncConfig();
await loadIdentities(); await loadIdentities();