verstak/extension-firefox/popup/popup.js

128 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 = '<p class="empty">Нет событий</p>';
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 = `
<div class="domain">${escapeHtml(ev.domain || '?')}</div>
<div class="title">${escapeHtml(truncate(ev.title || ev.url, 60))}</div>
<div class="duration">${ev.active_seconds || 0}с${reachable ? '' : ' (ожидает)'}</div>
`;
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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}