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();
+}