// Hintergrunddienst: prüft jede Minute auf neue Tickets/Antworten, zeigt den Zähler am Symbol und Benachrichtigungen, // bietet „Als DeskHub-Ticket anlegen“ im Rechtsklick-Menü an. import { apiCall, getSession, getSettings, truncate } from './lib/core.js'; const ALARM = 'deskhub-poll'; const MENU = 'deskhub-create'; async function setBadge(count, color = '#0f766e') { await chrome.action.setBadgeBackgroundColor({ color }); await chrome.action.setBadgeText({ text: count > 0 ? (count > 99 ? '99+' : String(count)) : '' }); } async function ensureSetup() { if (!(await chrome.alarms.get(ALARM))) chrome.alarms.create(ALARM, { periodInMinutes: 1, delayInMinutes: 0.1 }); chrome.contextMenus.removeAll(() => { chrome.contextMenus.create({ id: MENU, title: 'Als DeskHub-Ticket anlegen', contexts: ['selection', 'page'] }); }); } chrome.runtime.onInstalled.addListener(ensureSetup); chrome.runtime.onStartup.addListener(async () => { await ensureSetup(); poll(); }); /** Fragt den Server nach Neuem seit dem letzten Mal. Merkt sich die Serverzeit als Bezugspunkt (kein Uhrzeit-Abgleich mit dem PC nötig). */ export async function poll() { const session = await getSession(); if (!session) { await setBadge(0); return { skipped: true }; } const { lastSeen, badgeCount = 0 } = await chrome.storage.local.get(['lastSeen', 'badgeCount']); try { const { data } = await apiCall('activity.php', { query: lastSeen ? { since: lastSeen } : {} }); const fresh = (data.newReplies || 0) + (data.newUnassigned || 0); const total = badgeCount + fresh; await chrome.storage.local.set({ lastSeen: data.serverTime, badgeCount: total }); await setBadge(total); if (fresh > 0 && (await getSettings()).notifications) { const parts = []; if (data.newUnassigned) parts.push(`${data.newUnassigned} neu und nicht zugewiesen`); if (data.newReplies) parts.push(`${data.newReplies} Aktualisierung${data.newReplies === 1 ? '' : 'en'} bei deinen Tickets`); chrome.notifications.create('deskhub-new', { type: 'basic', iconUrl: 'icons/icon128.png', title: 'DeskHub', message: parts.join(', '), priority: 1 }); } return { fresh, total }; } catch (e) { if (e.status === 401) { // Anmeldung abgelaufen: Zähler zeigt „!“, bis sich jemand neu anmeldet await setBadge(0); await chrome.action.setBadgeText({ text: '!' }); await chrome.action.setBadgeBackgroundColor({ color: '#b91c1c' }); chrome.notifications.create('deskhub-login', { type: 'basic', iconUrl: 'icons/icon128.png', title: 'DeskHub', message: 'Bitte in der Erweiterung neu anmelden.' }); } return { error: e.code || 'ERROR' }; // Netzwerkfehler: still bleiben, beim nächsten Mal erneut } } chrome.alarms.onAlarm.addListener((alarm) => { if (alarm.name === ALARM) poll(); }); async function openCreateWindow() { return chrome.windows.create({ url: chrome.runtime.getURL('popup.html?window=1&create=1'), type: 'popup', width: 440, height: 680 }); } chrome.contextMenus.onClicked.addListener(async (info, tab) => { if (info.menuItemId !== MENU) return; const subject = truncate((tab?.title || '').trim(), 120); const selection = (info.selectionText || '').trim(); const source = tab?.url && /^https?:/i.test(tab.url) ? `\n\nQuelle: ${tab.url}` : ''; await chrome.storage.local.set({ prefill: { subject, message: (selection + source).trim() } }); await openCreateWindow(); }); chrome.notifications.onClicked.addListener(async (id) => { chrome.notifications.clear(id); try { await chrome.action.openPopup(); } catch { await chrome.windows.create({ url: chrome.runtime.getURL('popup.html?window=1'), type: 'popup', width: 440, height: 680 }); } }); chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { (async () => { if (msg?.type === 'reset-badge') { await chrome.storage.local.set({ badgeCount: 0 }); await setBadge(0); sendResponse({ ok: true }); } else if (msg?.type === 'poll-now') sendResponse(await poll()); else if (msg?.type === 'session-changed') { await chrome.storage.local.remove(['lastSeen', 'badgeCount']); await setBadge(0); sendResponse(await poll()); } else sendResponse({ ok: false }); })(); return true; // Antwort kommt asynchron });