// Verstak Bridge — Popup Script // Shows connection status, queue count, and recent events. const STORAGE_KEY = 'verstak_queue'; const BRIDGE_KEY = 'verstak_bridge_config'; const RECENT_KEY = 'verstak_recent'; document.addEventListener('DOMContentLoaded', () => { updateUI(); restoreToggleState(); document.getElementById('sync-btn').addEventListener('click', forceSync); document.getElementById('track-toggle').addEventListener('change', onToggle); document.getElementById('config-btn').addEventListener('click', () => { // For now, just show bridge config in console chrome.storage.local.get(BRIDGE_KEY, (data) => { console.log('[verstak] bridge config:', data[BRIDGE_KEY]); }); }); }); function updateUI() { chrome.storage.local.get([STORAGE_KEY, BRIDGE_KEY, RECENT_KEY], (data) => { const queue = data[STORAGE_KEY] || []; const config = data[BRIDGE_KEY] || {}; const recent = data[RECENT_KEY] || []; // Queue count document.getElementById('queue-count').textContent = queue.length; // Bridge status const statusEl = document.getElementById('bridge-status'); const portEl = document.getElementById('bridge-port'); const dotEl = document.getElementById('status-dot'); if (config.bridgeReachable) { statusEl.textContent = 'Доступен'; statusEl.className = 'value online'; dotEl.className = 'dot online'; portEl.textContent = config.port || '?'; } else { statusEl.textContent = 'Недоступен'; statusEl.className = 'value offline'; dotEl.className = 'dot offline'; portEl.textContent = config.lastPing ? '—' : 'проверка...'; } // Recent events renderRecent(recent, config.bridgeReachable); }); } function renderRecent(events, reachable) { const list = document.getElementById('event-list'); list.innerHTML = ''; if (!events || events.length === 0) { list.innerHTML = '

Нет событий

'; return; } // Show last 5 const lastFive = events.slice(-5).reverse(); for (const ev of lastFive) { const item = document.createElement('div'); item.className = 'event-item'; item.innerHTML = `
${escapeHtml(ev.domain || '?')}
${escapeHtml(truncate(ev.title || ev.url, 60))}
${ev.active_seconds || 0}с${reachable ? '' : ' (ожидает)'}
`; list.appendChild(item); } } function forceSync() { const btn = document.getElementById('sync-btn'); btn.disabled = true; btn.textContent = '⏳ Отправка...'; // Ask background to flush chrome.runtime.sendMessage({ type: 'FORCE_FLUSH' }, (response) => { setTimeout(() => { updateUI(); btn.disabled = false; btn.textContent = '🔄 Отправить сейчас'; }, 1000); }); } function onToggle(e) { const enabled = e.target.checked; chrome.storage.local.set({ 'verstak_tracking_enabled': enabled }); // Notify background chrome.runtime.sendMessage({ type: 'SET_TRACKING', enabled }); } function restoreToggleState() { chrome.storage.local.get('verstak_tracking_enabled', (data) => { const enabled = data.verstak_tracking_enabled !== false; document.getElementById('track-toggle').checked = enabled; }); } // Listen for updates from background chrome.runtime.onMessage.addListener((msg) => { if (msg.type === 'UI_UPDATE') { updateUI(); } }); // --- Helpers --- function truncate(s, n) { if (!s) return ''; return s.length > n ? s.substring(0, n) + '...' : s; } function escapeHtml(s) { if (!s) return ''; return s .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); }