window.addEventListener("DOMContentLoaded", () => { const websocket = new WebSocket("ws://adamwalsh.name:9533"); websocket.addEventListener("open", () => { communicate(websocket); }); }); class Timer { constructor(renderer, end_time, running) { this.renderer = renderer; this.end_time = end_time; this.running = running; this.destroying = false; } render_time() { // Render timer status to the document var timestr; if (this.counter < 0) { timestr = "--:--"; } else { // How many seconds have passed in this block var dur_seconds = Math.floor( (this.end_time - new Date()) / 1000); var seconds = dur_seconds % 60; dur_seconds = dur_seconds - seconds; var minutes = Math.floor(dur_seconds / 60); var hours = Math.floor(minutes / 60); minutes = minutes - 60 * hours; timestr = String(hours).padStart(2, '0') + ':' + String(minutes).padStart(2, '0'); } if (this.running) { this.renderer.update_time(timestr); } } tick() { // Recursive call run per second to update and change stage if (this.destroying) { return } this.render_time(); setTimeout(this.tick.bind(this), 1000); } } class TimerRenderer { constructor (){ this.background = document.getElementsByClassName("timer-bg")[0]; this.time_element = document.getElementsByClassName("timer-time")[0]; this.bg_width = parseInt( window.getComputedStyle( this.background, null ).getPropertyValue('width'), 10 ); this.bg_height = parseInt( window.getComputedStyle( this.background, null ).getPropertyValue('height'), 10 ) } update_time (timestr) { this.time_element.textContent = timestr; } set_break_color () { this.background.style.setProperty('--stage-color', 'var(--break-color)'); this.time_element.style.color = "var(--break-color)"; } set_focus_color () { this.background.style.setProperty('--stage-color', 'var(--focus-color)'); this.time_element.style.color = "var(--focus-color)"; } } function rectBounds(prop, rectHeight, rectWidth) { var totalCircum = 2 * rectHeight + 2 * rectWidth; var propCircum = prop * totalCircum; let bounds; if (propCircum < rectWidth / 2) { var xprop = Math.floor(( (rectWidth/2 + propCircum) / rectWidth ) * 1000)/10; bounds = [ "50% -5%", `${xprop}% -5%`, `${xprop}% 4%`, "50% 4%" ]; } else if (propCircum < rectWidth / 2 + rectHeight) { var yprop = ( (propCircum - rectWidth / 2) / rectHeight ) * 100; bounds = [ "50% -5%", "110% -5%", `110% ${yprop}%`, `96% ${yprop}%`, "95% 4%", "50% 4%" ]; } else if (propCircum < 3 * rectWidth / 2 + rectHeight) { var xprop = ( ((3 * rectWidth/2 + rectHeight) - propCircum) / rectWidth ) * 100; bounds = [ "50% -5%", "110% -5%", "110% 110%", `${xprop}% 110%`, `${xprop}% 96%`, "95% 96%", "95% 4%", "50% 4%" ]; } else if (propCircum < 3 * rectWidth / 2 + 2 * rectHeight) { var yprop = ( ((3 * rectWidth/2 + 2 * rectHeight) - propCircum) / rectHeight ) * 100; bounds = [ "50% -5%", "110% -5%", "110% 110%", "-5% 110%", `-5% ${yprop}%`, `4% ${yprop}%`, "5% 96%", "95% 96%", "95% 4%", "50% 4%" ]; } else { var xprop = ( (propCircum - (3 * rectWidth/2 + 2 * rectHeight)) / rectWidth ) * 100; bounds = [ "50% -5%", "110% -5%", "110% 110%", "-5% 110%", "-5% -5%", `${xprop}% -5%`, `${xprop}% 4%`, "4% 4%", "5% 96%", "95% 96%", "95% 4%", "50% 4%" ]; } return bounds; } function communicate(websocket) { console.log("Communicating"); const params = new URLSearchParams(window.location.search); websocket.send(JSON.stringify({type: "init", channel: "SubTimer", channelid: params.get('channelid')})); var renderer = new TimerRenderer(); let timer; websocket.addEventListener("message", ({ data }) => { console.log("Rec Event " + data); const event = JSON.parse(data); switch (event.type) { case "DO": let args = event.args; // Call the specified method switch (event.method) { case "setTimer": if (timer != null) { timer.destroying = true; } timer = new Timer( renderer, new Date(args.end_at), true ) timer.tick(); timer.running = args.running; break; default: throw new Error(`Unsupported method requested: ${event.method}.`) } break; default: throw new Error(`Unsupported event type: ${event.type}.`); } }); }