Files
jackboxpartypack-gamepicker/chrome-extension/popup.js

196 lines
5.3 KiB
JavaScript
Raw Normal View History

// Popup script for Jackbox Chat Tracker
console.log('Jackbox Chat Tracker: Popup loaded');
let isTracking = false;
let votes = [];
// DOM elements
const startBtn = document.getElementById('startTracking');
const stopBtn = document.getElementById('stopTracking');
const statusIndicator = document.getElementById('statusIndicator');
const statusText = document.getElementById('statusText');
const votesDisplay = document.getElementById('votesDisplay');
const voteCount = document.getElementById('voteCount');
const resetVotesBtn = document.getElementById('resetVotes');
const exportVotesBtn = document.getElementById('exportVotes');
// Initialize
loadState();
// Poll for updates every 2 seconds to keep sidebar in sync
setInterval(() => {
chrome.storage.local.get(['isTracking', 'votes'], (result) => {
const wasTracking = isTracking;
isTracking = result.isTracking || false;
votes = result.votes || [];
if (wasTracking !== isTracking) {
updateTrackingUI();
}
updateDisplay();
});
}, 2000);
// Event listeners
startBtn.addEventListener('click', startTracking);
stopBtn.addEventListener('click', stopTracking);
resetVotesBtn.addEventListener('click', resetVotes);
exportVotesBtn.addEventListener('click', exportVotes);
// Listen for updates from content script
chrome.runtime.onMessage.addListener((message) => {
if (message.action === 'votesUpdated') {
votes = message.votes;
updateDisplay();
}
});
function loadState() {
chrome.storage.local.get(['isTracking', 'votes'], (result) => {
isTracking = result.isTracking || false;
votes = result.votes || [];
updateDisplay();
updateTrackingUI();
// Request current votes from content script
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]) {
chrome.tabs.sendMessage(tabs[0].id, { action: 'getVotes' }, (response) => {
if (response && response.votes) {
votes = response.votes;
updateDisplay();
}
});
}
});
});
}
function startTracking() {
isTracking = true;
chrome.storage.local.set({ isTracking });
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]) {
chrome.tabs.sendMessage(tabs[0].id, { action: 'startTracking' }, (response) => {
if (response && response.success) {
console.log('Tracking started');
updateTrackingUI();
}
});
}
});
}
function stopTracking() {
isTracking = false;
chrome.storage.local.set({ isTracking });
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]) {
chrome.tabs.sendMessage(tabs[0].id, { action: 'stopTracking' }, (response) => {
if (response && response.success) {
console.log('Tracking stopped');
updateTrackingUI();
}
});
}
});
}
function resetVotes() {
if (!confirm('Reset all recorded votes? This cannot be undone.')) {
return;
}
votes = [];
chrome.storage.local.set({ votes });
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]) {
chrome.tabs.sendMessage(tabs[0].id, { action: 'resetVotes' }, (response) => {
if (response && response.success) {
console.log('Votes reset');
updateDisplay();
}
});
}
});
}
function exportVotes() {
// Export votes in the new format
const exportData = votes.map(vote => ({
username: vote.username,
message: vote.message,
timestamp: vote.timestamp
}));
const dataStr = JSON.stringify(exportData, null, 2);
const dataBlob = new Blob([dataStr], { type: 'application/json' });
const url = URL.createObjectURL(dataBlob);
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `jackbox-votes-${timestamp}.json`;
chrome.downloads.download({
url: url,
filename: filename,
saveAs: true
});
}
function updateTrackingUI() {
if (isTracking) {
statusIndicator.classList.add('active');
statusText.textContent = 'Tracking Active';
startBtn.disabled = true;
stopBtn.disabled = false;
} else {
statusIndicator.classList.remove('active');
statusText.textContent = 'Not Tracking';
startBtn.disabled = false;
stopBtn.disabled = true;
}
}
function updateDisplay() {
voteCount.textContent = votes.length;
if (votes.length === 0) {
votesDisplay.innerHTML = '<p class="empty-state">No votes recorded yet. Start tracking to begin!</p>';
return;
}
// Display votes in reverse chronological order (most recent first)
const sortedVotes = [...votes].reverse();
let html = '<div class="vote-list">';
sortedVotes.forEach((vote, index) => {
const localTime = new Date(vote.timestamp).toLocaleString();
const isPositive = vote.message.includes('++');
const voteClass = isPositive ? 'vote-positive' : 'vote-negative';
html += `
<div class="vote-item ${voteClass}">
<div class="vote-header">
<strong>${escapeHtml(vote.username)}</strong>
<span class="vote-time">${localTime}</span>
</div>
<div class="vote-message">${escapeHtml(vote.message)}</div>
</div>
`;
});
html += '</div>';
votesDisplay.innerHTML = html;
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}