let startTime = 0; let endTime = 0; let messagesCount = 0; let puzzleScoreboard = null; let showMessages = false; let showConnect = false; async function init() { const data = await chrome.storage.local.get(['startTime', 'endTime']); if (data?.endTime > 0) { startTime = data.startTime; endTime = data.endTime; document.getElementById('reset-button').style.display = 'block'; } else if (data?.startTime > 0) { startTime = data.startTime; document.getElementById('start-button').style.display = 'none'; document.getElementById('end-button').style.display = 'block'; } const startButton = document.getElementById('start-button'); startButton.onclick = startContest; const endButton = document.getElementById('end-button'); endButton.onclick = endContest; const resetButton = document.getElementById('reset-button'); resetButton.onclick = resetData; const messagesButton = document.getElementById('messages-button'); messagesButton.onclick = switchMessages; const connectButton = document.getElementById('connect-button'); connectButton.onclick = switchConnectForm; const connectSubmitButton = document.getElementById('connect-submit-button'); connectSubmitButton.onclick = connectToPuzzleScoreboard; initConnect(); update(); } async function fetchMessages() { const data = await chrome.storage.local.get('messages'); if (data.messages && data.messages.length > messagesCount) { const messagesEl = document.getElementById('messages'); let html = messagesEl.innerHTML; for (let i = messagesCount; i < data.messages.length; i++) { const {displayTime, completionTime, name, text} = data.messages[i]; html += `
${displayTime}${name}${text}
` } messagesEl.innerHTML = html; messagesCount = data.messages.length; } } function sendMessage(message, callback) { chrome.tabs.query({active: true, currentWindow: true}, tabs => { tabs.forEach(tab => chrome.tabs.sendMessage(tab.id, message, callback)); }); } function startContest() { startTime = Date.now(); endTime = 0; chrome.storage.local.set({ startTime: startTime, endTime: 0, messages: [] }); document.getElementById('start-button').style.display = 'none'; document.getElementById('end-button').style.display = 'block'; document.getElementById('reset-button').style.display = 'none'; document.getElementById('messages').innerHTML = ''; if (showMessages) switchMessages(); sendStartTime(startTime); } function endContest() { endTime = Date.now(); chrome.storage.local.set({ endTime: endTime }); document.getElementById('start-button').style.display = 'block'; document.getElementById('end-button').style.display = 'none'; document.getElementById('reset-button').style.display = 'block'; } function resetData() { chrome.storage.local.set({ startTime: 0, endTime: 0, messages: [] }); startTime = 0; endTime = 0; document.getElementById('time').innerHTML = '0:00:00'; document.getElementById('reset-button').style.display = 'none'; document.getElementById('messages').innerHTML = ''; if (showMessages) switchMessages(); } function switchMessages() { const messagesEl = document.getElementById('messages'); const messagesButtonEl = document.getElementById('messages-button'); if (showMessages) { messagesEl.style.display = 'none'; messagesButtonEl.innerHTML = 'Show messages'; } else { messagesEl.style.display = 'block'; messagesButtonEl.innerHTML = 'Hide messages'; } showMessages = !showMessages; } function switchConnectForm() { const connectFormEl = document.getElementById('connect-form') if (showConnect) { connectFormEl.style.display = 'none'; } else { connectFormEl.style.display = 'flex'; } showConnect = !showConnect; } async function sendStartTime(startTime) { const data = await chrome.storage.local.get(['puzzleScoreboard']); if (!data?.puzzleScoreboard || !data.puzzleScoreboard.includes('/message')) return; fetch(data.puzzleScoreboard.replace('/message', '/start'), { method: "post", headers: {'Content-Type': 'application/json'}, body: JSON.stringify({startTime}), }); } async function scoreboardConnect(puzzleScoreboard) { if (puzzleScoreboard.includes('/message')) { const resp = await fetch(puzzleScoreboard.replace('/message', '/connect'), { method: "post", headers: {'Content-Type': 'application/json'}, }); if (resp.status != 200) return {connected: false, error: 'Invalid contest token'}; const json = await resp.json(); return {connected: true, name: json?.name}; } return {connected: false, error: 'Invalid connection link'}; } async function initConnect() { const data = await chrome.storage.local.get(['puzzleScoreboard']); if (data?.puzzleScoreboard) { puzzleScoreboard = data.puzzleScoreboard; const connection = await scoreboardConnect(puzzleScoreboard); const connectButtonEl = document.getElementById('connect-button') if (connection.connected) connectButtonEl.innerHTML = `Connected: ${connection.name}`; else connectButtonEl.innerHTML = `${connection.error}`; const connectTextEl = document.getElementById('connect-text') connectTextEl.style.display = 'none'; const connectSubmitButtonEl = document.getElementById('connect-submit-button') connectSubmitButtonEl.innerHTML = 'disconnect'; } } async function connectToPuzzleScoreboard() { const connectButtonEl = document.getElementById('connect-button') const connectTextEl = document.getElementById('connect-text') const connectSubmitButtonEl = document.getElementById('connect-submit-button') if (puzzleScoreboard) { puzzleScoreboard = null; chrome.storage.local.remove('puzzleScoreboard'); connectButtonEl.innerHTML = `Connect to a puzzle scoreboard`; connectTextEl.style.display = 'block'; connectSubmitButtonEl.innerHTML = 'connect'; } else { puzzleScoreboard = connectTextEl.value; chrome.storage.local.set({ puzzleScoreboard: puzzleScoreboard }); const connection = await scoreboardConnect(puzzleScoreboard); const connectFormEl = document.getElementById('connect-form') connectFormEl.style.display = 'none'; showConnect = false; if (connection.connected) connectButtonEl.innerHTML = `Connected: ${connection.name}`; else connectButtonEl.innerHTML = `${connection.error}`; connectTextEl.style.display = 'none'; connectSubmitButtonEl.innerHTML = 'disconnect'; } } function dis(n) { if (n < 10) return "0" + n; return n.toString(); } function update() { // Update the display time in the popup. let displayTime = '0:00:00'; if (startTime != 0) { let rawTime = Math.floor((Date.now() - startTime) / 1000); if (endTime > 0) rawTime = Math.floor((endTime - startTime) / 1000); displayTime = `${Math.floor(rawTime / 3600)}:${dis(Math.floor((rawTime % 3600) / 60))}:${dis(rawTime % 60)}`; } document.getElementById('time').innerHTML = displayTime; setTimeout(update, 1000); // Fetch and save new messages. fetchMessages(); } setTimeout(init, 20);