const $ = (id) => document.getElementById(id); const syncBtn = $('sync'); const statusEl = $('status'); function render(status) { if (!status) { statusEl.dataset.state = 'idle'; statusEl.textContent = 'Ready.'; return; } statusEl.dataset.state = status.state || 'idle'; const busy = status.state === 'collecting' || status.state === 'pushing'; statusEl.innerHTML = busy ? '' : ''; statusEl.append(status.message || ''); syncBtn.disabled = busy; syncBtn.textContent = busy ? 'Syncing…' : 'Sync now'; } async function init() { const { serverUrl, token, syncStatus } = await chrome.storage.local.get(['serverUrl', 'token', 'syncStatus']); if (!serverUrl || !token) { render({ state: 'error', message: 'Set server URL and token in settings first.' }); } else { render(syncStatus); } } syncBtn.addEventListener('click', async () => { render({ state: 'collecting', message: 'Starting…' }); try { const res = await chrome.runtime.sendMessage({ type: 'SYNC' }); render(res); } catch (err) { render({ state: 'error', message: String(err?.message || err) }); } }); $('open-options').addEventListener('click', (e) => { e.preventDefault(); chrome.runtime.openOptionsPage(); }); // Live-update while a sync runs in the worker. chrome.storage.onChanged.addListener((changes, area) => { if (area === 'local' && changes.syncStatus) render(changes.syncStatus.newValue); }); init();