From 60e141e2ae8b5674389c61a65f2372fefca3b80b Mon Sep 17 00:00:00 2001 From: Interitio Date: Sat, 14 Mar 2026 00:13:42 +1000 Subject: [PATCH] Add parametrisation for timer vars --- index.html | 2 +- timer.css | 11 ++--- timer.js | 119 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 92 insertions(+), 40 deletions(-) diff --git a/index.html b/index.html index a7ad952..a0271d3 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ Croccy Timer - +
diff --git a/timer.css b/timer.css index 118794d..5d21f56 100644 --- a/timer.css +++ b/timer.css @@ -1,6 +1,7 @@ :root { --break-color: #8CD5CA; --focus-color: #EED59F; + --bg-color: #1E202F; --stage-color: var(--break-color); --clip-path: none; } @@ -18,10 +19,10 @@ height: 175px; width: 397px; position: absolute; - background-color: #1E202F; + background-color: var(--bg-color); border-radius: 40px; - outline-offset: -5px; - outline: dotted 10px #534F72; + outline-offset: -3px; + outline: dotted 6px #534F72; } .timer-bg:before { content: ""; @@ -29,8 +30,8 @@ height: 175px; width: 397px; border-radius: 40px; - outline-offset: -5px; - outline: dotted 10px var(--stage-color); + outline-offset: -3px; + outline: dotted 6px var(--stage-color); border-radius: 40px; clip-path: var(--clip-path); } diff --git a/timer.js b/timer.js index f4eec4b..618cdf2 100644 --- a/timer.js +++ b/timer.js @@ -1,12 +1,47 @@ -window.addEventListener("DOMContentLoaded", () => { - const websocket = new WebSocket("ws://adamwalsh.name:9500"); +var renderer; +var timer; - websocket.addEventListener("open", () => { - communicate(websocket); - }); +window.addEventListener("DOMContentLoaded", () => { + renderer = new TimerRenderer(); + + const queryString = window.location.search; + console.log(queryString); + // Set colours from querystring too, background, focus, break + if (queryString) { + updateTimerFromQuery(queryString) + } else { + const websocket = new WebSocket("wss://croccy.thewisewolf.dev/ws"); + + websocket.addEventListener("open", () => { + communicate(websocket); + }); + } }); +function updateTimerFromQuery(queryString) { + const params = new URLSearchParams(queryString); + + const block_number = parseInt(params.get('block') || 1); + const focus_length = parseInt(params.get('focus') || 50) * 60; + const break_length = parseInt(params.get('break') || 10) * 60; + const block_goal = parseInt(params.get('goal') || 0); + + const focus_colour = "#" + (params.get('focuscolour') || "EED59F"); + const break_colour = "#" + (params.get('breakcolour') || "8CD5CA"); + const background = "#" + (params.get('background') || "1E202F"); + + const root = document.documentElement; + root.style.setProperty('--focus-color', focus_colour); + root.style.setProperty('--break-color', break_colour); + root.style.setProperty('--bg-color', background); + + + + const now = new Date(); + const start_at = new Date(now.getTime() - (focus_length + break_length) * 1000 * (block_number - 1)); + update_timer(start_at, focus_length, break_length, block_goal); +} class Timer { constructor(renderer, start_at, focus_length, break_length, block_goal) { @@ -34,20 +69,20 @@ class Timer { get count_now() { // Current actual block number. 0 for the first block, -1 if not running - var diff = Math.floor((new Date() - this.start_at) / 1000); + var diff = Math.floor( (new Date() - this.start_at) / 1000 ); if (diff < 0) { return -1; } else { - var stage = Math.floor(diff / this.block_length); + var stage = Math.floor( diff / this.block_length ); return stage; } } get is_break() { // Whether the current block is on break. - if (this.counter < 0) { + if (this.counter < 0){ return true - } else { + } else{ return ((new Date() - this.block_start) / 1000) > this.focus_length; } } @@ -62,7 +97,7 @@ class Timer { proportion = 0; } else { // How many seconds have passed in this block - var dur_seconds = Math.floor((new Date() - this.block_start) / 1000); + var dur_seconds = Math.floor( (new Date() - this.block_start) / 1000); if (dur_seconds < this.focus_length) { // How many seconds are left in the focus session dur_seconds = this.focus_length - dur_seconds; @@ -83,8 +118,14 @@ class Timer { this.renderer.update_time(timestr); this.renderer.update_proportion(proportion); - this.renderer.update_block(String(this.counter + 1) + '/' + String(this.block_goal)); - if (this.is_break) { + let goal; + if (this.block_goal <= 0) { + goal = "??"; + } else { + goal = String(this.block_goal); + } + this.renderer.update_block(String(this.counter + 1) + '/' + String(goal)); + if (this.is_break){ this.renderer.update_stage("BREAK"); this.renderer.set_break_color(); } else { @@ -102,14 +143,18 @@ class Timer { if (this.is_break && !this.break_notified && this.counter >= 0) { // Notify for break + // TODO voice alert this.renderer.break_alert.play(); + // TODO chat message? console.log("Notifying Break.") this.break_notified = true; } else if (this.count_now > this.counter) { this.counter++; this.break_notified = false; // Notify for focus + // TODO voice alert this.renderer.focus_alert.play(); + // TODO chat message? console.log("Notifying Focus.") } this.render_time(); @@ -118,7 +163,7 @@ class Timer { } class TimerRenderer { - constructor() { + constructor (){ this.background = document.getElementsByClassName("timer-bg")[0]; this.time_element = document.getElementsByClassName("timer-time")[0]; this.stage_element = document.getElementsByClassName("timer-details-stage-text")[0]; @@ -141,11 +186,11 @@ class TimerRenderer { ) } - update_time(timestr) { + update_time (timestr) { this.time_element.textContent = timestr; } - update_proportion(proportion) { + update_proportion (proportion) { var bounds = rectBounds( proportion, this.bg_width, this.bg_height ); @@ -155,20 +200,20 @@ class TimerRenderer { ); } - update_block(blockstr) { + update_block (blockstr) { this.block_element.textContent = blockstr; } - update_stage(stagestr) { + update_stage (stagestr) { this.stage_element.textContent = stagestr; } - set_break_color() { + set_break_color () { this.background.style.setProperty('--stage-color', 'var(--break-color)'); this.time_element.style.color = "var(--break-color)"; } - set_focus_color() { + set_focus_color () { this.background.style.setProperty('--stage-color', 'var(--focus-color)'); this.time_element.style.color = "var(--focus-color)"; } @@ -182,8 +227,8 @@ function rectBounds(prop, rectHeight, rectWidth) { if (propCircum < rectWidth / 2) { var xprop = Math.floor(( - (rectWidth / 2 + propCircum) / rectWidth - ) * 1000) / 10; + (rectWidth/2 + propCircum) / rectWidth + ) * 1000)/10; bounds = [ "50% -5%", `${xprop}% -5%`, @@ -201,7 +246,7 @@ function rectBounds(prop, rectHeight, rectWidth) { ]; } else if (propCircum < 3 * rectWidth / 2 + rectHeight) { var xprop = ( - ((3 * rectWidth / 2 + rectHeight) - propCircum) / rectWidth + ((3 * rectWidth/2 + rectHeight) - propCircum) / rectWidth ) * 100; bounds = [ "50% -5%", "110% -5%", @@ -212,7 +257,7 @@ function rectBounds(prop, rectHeight, rectWidth) { ]; } else if (propCircum < 3 * rectWidth / 2 + 2 * rectHeight) { var yprop = ( - ((3 * rectWidth / 2 + 2 * rectHeight) - propCircum) / rectHeight + ((3 * rectWidth/2 + 2 * rectHeight) - propCircum) / rectHeight ) * 100; bounds = [ "50% -5%", "110% -5%", @@ -223,7 +268,7 @@ function rectBounds(prop, rectHeight, rectWidth) { ]; } else { var xprop = ( - (propCircum - (3 * rectWidth / 2 + 2 * rectHeight)) / rectWidth + (propCircum - (3 * rectWidth/2 + 2 * rectHeight)) / rectWidth ) * 100; bounds = [ "50% -5%", "110% -5%", @@ -240,10 +285,7 @@ function rectBounds(prop, rectHeight, rectWidth) { function communicate(websocket) { console.log("Communicating"); - websocket.send(JSON.stringify({ type: "init", channel: "Timer" })); - - var renderer = new TimerRenderer(); - let timer; + websocket.send(JSON.stringify({type: "init", channel: "Timer"})); websocket.addEventListener("message", ({ data }) => { console.log("Rec Event " + data); @@ -255,17 +297,12 @@ function communicate(websocket) { // Call the specified method switch (event.method) { case "setTimer": - if (timer != null) { - timer.destroying = true; - } - timer = new Timer( - renderer, + update_timer( new Date(args.start_at), args.focus_length, args.break_length, args.block_goal ) - timer.tick(); break; default: throw new Error(`Unsupported method requested: ${event.method}.`) @@ -276,3 +313,17 @@ function communicate(websocket) { } }); } + +function update_timer(start_at, focus_length, break_length, goal) { + if (timer != null) { + timer.destroying = true; + } + timer = new Timer( + renderer, + start_at, + focus_length, + break_length, + goal + ) + timer.tick(); +}