Toolbar-Button Fix, QuickMove-Tab, Schlagwörter-Sync, Abteilungsverwaltung
- Toolbar-Button öffnet Settings via browserAction.onClicked statt defektem Popup - Button-Label "Vorlagen & Signaturen" statt Icon - Tab "Erledigt" → "QuickMove" umbenannt - QuickMove: E-Mails markieren + in Zielordner verschieben - Schlagwörter-Sync aus Gitea (_config/schlagwoerter.json) - Abteilungen anlegen (+Button) - attachSignature-Fix entfernt - message_display_action für QuickMove-Button Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1167,6 +1167,7 @@ function showSigStatus(message, color) {
|
||||
|
||||
// Save signature to Thunderbird identity (header + footer)
|
||||
document.getElementById('sig-save-button').addEventListener('click', async () => {
|
||||
try {
|
||||
const identityId = sigIdentitySelect.value;
|
||||
if (!identityId) {
|
||||
showSigStatus('Bitte Identität auswählen.', 'red');
|
||||
@@ -1194,7 +1195,6 @@ document.getElementById('sig-save-button').addEventListener('click', async () =>
|
||||
await browser.identities.update(identityId, {
|
||||
signature: fullSignature,
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
|
||||
if (identity) identity.signature = fullSignature;
|
||||
@@ -1206,28 +1206,37 @@ document.getElementById('sig-save-button').addEventListener('click', async () =>
|
||||
await browser.identities.update(otherId.id, {
|
||||
signature: fullSignature,
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
});
|
||||
otherId.signature = fullSignature;
|
||||
}
|
||||
}
|
||||
|
||||
updateSigSyncIndicator();
|
||||
|
||||
// Auto-push to server
|
||||
// Auto-push to server, then pull to resolve reference chains
|
||||
try {
|
||||
const pushResult = await browser.runtime.sendMessage({ action: 'pushSignatures' });
|
||||
await loadIdentities();
|
||||
for (const id of allIdentities) {
|
||||
sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
|
||||
}
|
||||
saveSyncHashes();
|
||||
updateSigSyncIndicator();
|
||||
const label = source.startsWith('=') ? ` (von ${source.substring(1)})` : '';
|
||||
showSigStatus(`Signatur gespeichert & hochgeladen!${label}`, 'green');
|
||||
await browser.runtime.sendMessage({ action: 'pushSignatures' });
|
||||
} catch (err) {
|
||||
showSigStatus('Gespeichert, aber Upload fehlgeschlagen: ' + err.message, '#e65100');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await browser.runtime.sendMessage({ action: 'pullSignatures' });
|
||||
} catch (_) {}
|
||||
|
||||
await loadIdentities();
|
||||
for (const id of allIdentities) {
|
||||
sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
|
||||
}
|
||||
saveSyncHashes();
|
||||
updateSigSyncIndicator();
|
||||
const label = source.startsWith('=') ? ` (von ${source.substring(1)})` : '';
|
||||
showSigStatus(`Signatur gespeichert & hochgeladen!${label}`, 'green');
|
||||
} catch (err) {
|
||||
console.error('Signatur-Speichern Fehler:', err);
|
||||
showSigStatus('Fehler: ' + err.message, 'red');
|
||||
}
|
||||
});
|
||||
|
||||
// Import signature from HTML file
|
||||
@@ -1399,6 +1408,30 @@ async function populateEmailDropdown() {
|
||||
}
|
||||
}
|
||||
|
||||
async function populateFolderDropdown() {
|
||||
try {
|
||||
let options = '';
|
||||
const accounts = await browser.accounts.list();
|
||||
for (const account of accounts) {
|
||||
const folders = await browser.folders.getSubFolders(account);
|
||||
const addFolders = (list, prefix) => {
|
||||
for (const folder of list) {
|
||||
const label = prefix ? `${prefix} / ${folder.name}` : `${account.name} / ${folder.name}`;
|
||||
const val = JSON.stringify({ accountId: account.id, path: folder.path });
|
||||
options += `<option value='${val.replace(/'/g, ''')}'>${label}</option>`;
|
||||
if (folder.subFolders && folder.subFolders.length) {
|
||||
addFolders(folder.subFolders, label);
|
||||
}
|
||||
}
|
||||
};
|
||||
addFolders(folders, '');
|
||||
}
|
||||
erledigtFolderOptions = options;
|
||||
} catch (e) {
|
||||
console.error('Ordner laden fehlgeschlagen:', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSyncConfig() {
|
||||
try {
|
||||
const result = await browser.storage.local.get(SYNC_CONFIG_KEY);
|
||||
@@ -1651,6 +1684,23 @@ for (const id of ['sync-author-name', 'sync-author-email']) {
|
||||
|
||||
document.getElementById('refresh-departments').addEventListener('click', loadDepartments);
|
||||
|
||||
document.getElementById('add-department').addEventListener('click', async () => {
|
||||
const name = prompt('Name der neuen Abteilung:');
|
||||
if (!name || !name.trim()) return;
|
||||
try {
|
||||
const result = await browser.runtime.sendMessage({ action: 'addDepartment', name: name.trim() });
|
||||
if (result?.success) {
|
||||
showToast(`Abteilung "${name.trim()}" angelegt!`, 'success');
|
||||
await loadDepartments();
|
||||
document.getElementById('sync-department').value = name.trim();
|
||||
} else {
|
||||
showToast(result?.error || 'Fehler beim Anlegen', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
showToast('Fehler: ' + e.message, 'error');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('test-sync-connection').addEventListener('click', async () => {
|
||||
if (!checkOnline()) return;
|
||||
const btn = document.getElementById('test-sync-connection');
|
||||
@@ -1678,6 +1728,80 @@ document.getElementById('test-sync-connection').addEventListener('click', async
|
||||
btn.textContent = origText;
|
||||
});
|
||||
|
||||
// ── Erledigt-Tab ──
|
||||
|
||||
const ERLEDIGT_CONFIG_KEY = 'erledigt_config';
|
||||
let erledigtFolderOptions = '';
|
||||
|
||||
function renderErledigtAction(action, index) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'form-row';
|
||||
div.style.alignItems = 'end';
|
||||
div.style.marginBottom = '8px';
|
||||
div.innerHTML = `
|
||||
<div class="form-group" style="flex:1;">
|
||||
${index === 0 ? '<label>Name</label>' : ''}
|
||||
<input type="text" class="erledigt-name" placeholder="z.B. Erledigt" value="${(action.name || '').replace(/"/g, '"')}">
|
||||
</div>
|
||||
<div class="form-group" style="flex:2;">
|
||||
${index === 0 ? '<label>Zielordner</label>' : ''}
|
||||
<select class="erledigt-folder" style="width:100%;">
|
||||
<option value="">— Kein Ordner (nur markieren) —</option>
|
||||
${erledigtFolderOptions}
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-danger btn-sm erledigt-remove" title="Entfernen" style="margin-bottom:2px;">✕</button>
|
||||
`;
|
||||
if (action.targetFolder) {
|
||||
div.querySelector('.erledigt-folder').value = action.targetFolder;
|
||||
}
|
||||
div.querySelector('.erledigt-remove').addEventListener('click', () => {
|
||||
div.remove();
|
||||
});
|
||||
return div;
|
||||
}
|
||||
|
||||
function renderErledigtActions(actions) {
|
||||
const list = document.getElementById('erledigt-actions-list');
|
||||
list.innerHTML = '';
|
||||
actions.forEach((a, i) => list.appendChild(renderErledigtAction(a, i)));
|
||||
}
|
||||
|
||||
function getErledigtActionsFromForm() {
|
||||
const actions = [];
|
||||
const names = document.querySelectorAll('.erledigt-name');
|
||||
const folders = document.querySelectorAll('.erledigt-folder');
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
const name = names[i].value.trim();
|
||||
if (!name) continue;
|
||||
actions.push({ name, targetFolder: folders[i].value || '' });
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
async function loadErledigtConfig() {
|
||||
const result = await browser.storage.local.get(ERLEDIGT_CONFIG_KEY);
|
||||
const config = result[ERLEDIGT_CONFIG_KEY] || {};
|
||||
const actions = config.actions || [];
|
||||
if (actions.length === 0) actions.push({ name: 'Erledigt', targetFolder: '' });
|
||||
renderErledigtActions(actions);
|
||||
}
|
||||
|
||||
document.getElementById('add-erledigt-action').addEventListener('click', () => {
|
||||
const list = document.getElementById('erledigt-actions-list');
|
||||
list.appendChild(renderErledigtAction({ name: '', targetFolder: '' }, list.children.length));
|
||||
});
|
||||
|
||||
document.getElementById('save-erledigt-config').addEventListener('click', async () => {
|
||||
const actions = getErledigtActionsFromForm();
|
||||
if (actions.length === 0) {
|
||||
showToast('Mindestens eine Aktion mit Namen anlegen.', 'error');
|
||||
return;
|
||||
}
|
||||
await browser.storage.local.set({ [ERLEDIGT_CONFIG_KEY]: { actions } });
|
||||
showToast('Aktionen gespeichert!', 'success');
|
||||
});
|
||||
|
||||
// ── Init ──
|
||||
|
||||
window.addEventListener('load', async () => {
|
||||
@@ -1686,6 +1810,8 @@ window.addEventListener('load', async () => {
|
||||
renderTemplates(templates);
|
||||
updateTplSyncIndicator();
|
||||
await populateEmailDropdown();
|
||||
await populateFolderDropdown();
|
||||
await loadErledigtConfig();
|
||||
loadSyncConfig();
|
||||
await loadIdentities();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user