diff --git a/index.js b/index.js
index 0aefbe7..f5626d7 100644
--- a/index.js
+++ b/index.js
@@ -156,10 +156,15 @@ app.get("/", function (req, res) {
});
app.get("/timer", function (req, res) {
- const data = fs.readFileSync("templates/timerPage.html", "utf8");
+ const data = fs.readFileSync("templates/ng-timerview.html", "utf8");
res.send(data);
});
+app.get("/timer-old", function (req, res) {
+ const data = fs.readFileSync("templates/timerPage.html", "utf8");
+ res.send(data);
+ });
+
app.get("/api/v1/data", function (req, res) {
currentState.srvTime = new Date().getTime()
res.json(currentState);
diff --git a/lang/de_de.json b/lang/de_de.json
index 9c14a61..c931975 100644
--- a/lang/de_de.json
+++ b/lang/de_de.json
@@ -30,8 +30,9 @@
{
"timer": "Timer",
"clock": "Uhr",
- "black": "Schwarz",
- "test": "Testbild"
+ "black": "Leer",
+ "test": "Testbild",
+ "screensaver": "Bildschirmschoner"
},
"labels":
{
diff --git a/lang/en_uk.json b/lang/en_uk.json
index 0c0f6a4..56d604c 100644
--- a/lang/en_uk.json
+++ b/lang/en_uk.json
@@ -32,7 +32,8 @@
"timer": "Timer",
"clock": "Clock",
"black": "Black",
- "test": "Testimage"
+ "test": "Testimage",
+ "screensaver": "Screensaver"
},
"labels":
{
diff --git a/lang/proto_black.json b/lang/proto_black.json
index d111cde..bf4547a 100644
--- a/lang/proto_black.json
+++ b/lang/proto_black.json
@@ -31,7 +31,8 @@
"timer": "████",
"clock": "█████",
"black": "████",
- "test": "███████"
+ "test": "███████",
+ "screensaver": "████████"
},
"labels":
{
diff --git a/static/css/styles.css b/static/css/styles.css
index dcc820c..949c3c4 100644
--- a/static/css/styles.css
+++ b/static/css/styles.css
@@ -110,4 +110,41 @@ animation:fade 1000ms infinite;
width: 100vw;
font-size: x-large;
font-family: sans-serif;
-}
\ No newline at end of file
+}
+
+
+#moveClock {
+ font-size: xx-large;
+ font-family: sans-serif;
+ position: absolute;
+ -webkit-animation: moveX 40s linear 0s infinite alternate, moveY 45s linear 0s infinite alternate;
+ -moz-animation: moveX 40s linear 0s infinite alternate, moveY 45s linear 0s infinite alternate;
+ -o-animation: moveX 40s linear 0s infinite alternate, moveY 45s linear 0s infinite alternate;
+ animation: moveX 40s linear 0s infinite alternate, moveY 45s linear 0s infinite alternate;
+}
+
+@-webkit-keyframes moveX {
+ from { left: 0; } to { left: 100%; }
+ }
+ @-moz-keyframes moveX {
+ from { left: 0; } to { left: 100%; }
+ }
+ @-o-keyframes moveX {
+ from { left: 0; } to { left: 100%; }
+ }
+ @keyframes moveX {
+ from { left: 0; } to { left: 100%; }
+ }
+
+ @-webkit-keyframes moveY {
+ from { top: 0; } to { top: 100%; }
+ }
+ @-moz-keyframes moveY {
+ from { top: 0; } to { top: 100%; }
+ }
+ @-o-keyframes moveY {
+ from { top: 0; } to { top: 100%; }
+ }
+ @keyframes moveY {
+ from { top: 0; } to { top: 100%; }
+ }
\ No newline at end of file
diff --git a/static/js/interface.js b/static/js/interface.js
index be723bc..12d2fa9 100644
--- a/static/js/interface.js
+++ b/static/js/interface.js
@@ -25,7 +25,7 @@ function convertColorSegments(elementId) {
$(function () {
// $(".numVal").bind("DOMSubtreeModified", alert);
- const modes = ["timer", "clock", "black", "test"]
+ const modes = ["timer", "clock", "black", "test", "screensaver"]
let selectPresetTime = 0;
if (Cookies.get("interfaceColor") != undefined) {
diff --git a/static/js/script.js b/static/js/script.js
index 9f81b8c..4a9177f 100644
--- a/static/js/script.js
+++ b/static/js/script.js
@@ -13,44 +13,44 @@ let lastTime = "00:00:00";
let timerCountdownFirst = true;
socket.onopen = function (e) {
- // alert("[open] Connection established");
- //alert("Sending to server");
- socket.send("new client");
+ // alert("[open] Connection established");
+ //alert("Sending to server");
+ socket.send("new client");
};
socket.onmessage = function (event) {
- // alert(`[message] Data received from server: ${event.data}`);
- let inData = JSON.parse(event.data)
- if (isFirstPacket) {
- isFirstPacket = false
- dataFame = JSON.parse(event.data);
- timeDiff = new Date().getTime() - dataFame.srvTime
- } else {
- if (inData.sessionToken == dataFame.sessionToken) {
- dataFame = JSON.parse(event.data);
- timeDiff = new Date().getTime() - dataFame.srvTime
- } else {
- if (ackdSessionToken == false) {
+ // alert(`[message] Data received from server: ${event.data}`);
+ let inData = JSON.parse(event.data)
+ if (isFirstPacket) {
+ isFirstPacket = false
+ dataFame = JSON.parse(event.data);
+ timeDiff = new Date().getTime() - dataFame.srvTime
+ } else {
+ if (inData.sessionToken == dataFame.sessionToken) {
+ dataFame = JSON.parse(event.data);
+ timeDiff = new Date().getTime() - dataFame.srvTime
+ } else {
+ if (ackdSessionToken == false) {
- ackdSessionToken = true
+ ackdSessionToken = true
- if (confirm("Session token mismatch, reload the page?")) {
- location.reload();
- }
- }
- }
- }
+ if (confirm("Session token mismatch, reload the page?")) {
+ location.reload();
+ }
+ }
+ }
+ }
};
socket.onclose = function (event) {
- if (event.wasClean) {
- console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
- } else {
- // e.g. server process killed or network down
- // event.code is usually 1006 in this case
- console.error('[close] Connection died');
- }
+ if (event.wasClean) {
+ console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
+ } else {
+ // e.g. server process killed or network down
+ // event.code is usually 1006 in this case
+ console.error('[close] Connection died');
+ }
};
allowFullscreen = true
@@ -58,229 +58,229 @@ let dataFame = {}
let timeDiff = 0
function enterFullscreen(element) {
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen();
- }
+ if (element.requestFullscreen) {
+ element.requestFullscreen();
+ } else if (element.msRequestFullscreen) {
+ element.msRequestFullscreen();
+ } else if (element.webkitRequestFullscreen) {
+ element.webkitRequestFullscreen();
+ }
}
function returnData() {
- return (JSON.parse(document.getElementById("incomeData").innerHTML))
+ return (JSON.parse(document.getElementById("incomeData").innerHTML))
}
function percentage(partialValue, totalValue) {
- return (100 * partialValue) / totalValue;
+ return (100 * partialValue) / totalValue;
}
function updateFullscreen() {
- if (JSON.parse(document.getElementById("incomeData").innerHTML).defaultFullScreen && allowFullscreen) {
- enterFullscreen(document.documentElement)
- }
+ if (JSON.parse(document.getElementById("incomeData").innerHTML).defaultFullScreen && allowFullscreen) {
+ enterFullscreen(document.documentElement)
+ }
}
function msToTime(s, data) {
- isSmallerThenZero = false
- if (s < 0) {
- isSmallerThenZero = true
- }
+ isSmallerThenZero = false
+ if (s < 0) {
+ isSmallerThenZero = true
+ }
- var ms = s % 1000;
- s = (s - ms) / 1000;
- var secs = s % 60;
- s = (s - secs) / 60;
- var mins = s % 60;
- var hrs = (s - mins) / 60;
- let out = ""
+ var ms = s % 1000;
+ s = (s - ms) / 1000;
+ var secs = s % 60;
+ s = (s - secs) / 60;
+ var mins = s % 60;
+ var hrs = (s - mins) / 60;
+ let out = ""
- if (!data.showMilliSeconds) {
- out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2)
- } else {
- out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2) + '.' + ('000' + Math.abs(ms)).slice(-3)
- }
+ if (!data.showMilliSeconds) {
+ out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2)
+ } else {
+ out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2) + '.' + ('000' + Math.abs(ms)).slice(-3)
+ }
- if (isSmallerThenZero) {
- out = "-" + out
- }
- return out;
+ if (isSmallerThenZero) {
+ out = "-" + out
+ }
+ return out;
}
function findProgessColor(colors, value) {
- const allColors = Object.keys(colors);
- let resColor = colors["START"]
- for (let color in allColors) {
- const currColor = allColors[color]
- // console.log(color, currColor, parseInt(currColor), value, colors[String(currColor)], resColor)
- if (value <= parseInt(currColor)) {
- resColor = colors[String(currColor)]
- break
- }
- }
- return (resColor)
+ const allColors = Object.keys(colors);
+ let resColor = colors["START"]
+ for (let color in allColors) {
+ const currColor = allColors[color]
+ // console.log(color, currColor, parseInt(currColor), value, colors[String(currColor)], resColor)
+ if (value <= parseInt(currColor)) {
+ resColor = colors[String(currColor)]
+ break
+ }
+ }
+ return (resColor)
}
function requestBackend() {
- resp = httpGet("/api/v1/data");
- resp.onloadend = function (e) {
- if (resp.status == 200) {
- resp = resp.responseText;
- var data = JSON.parse(resp);
- timeDiff = new Date().getTime() - data.srvTime
- dataFame = data;
- }
- }
+ resp = httpGet("/api/v1/data");
+ resp.onloadend = function (e) {
+ if (resp.status == 200) {
+ resp = resp.responseText;
+ var data = JSON.parse(resp);
+ timeDiff = new Date().getTime() - data.srvTime
+ dataFame = data;
+ }
+ }
}
let isSlowed = false
function handleRecovery() {
- var img = document.body.appendChild(document.createElement("img"));
- img.onload = function () {
- location.reload();
- };
- img.src = "SMPTE_Color_Bars.svg";
+ var img = document.body.appendChild(document.createElement("img"));
+ img.onload = function () {
+ location.reload();
+ };
+ img.src = "SMPTE_Color_Bars.svg";
}
let recoInter = -1
function handleUpdate() {
- var data = dataFame;
- document.getElementById("incomeData").innerHTML = JSON.stringify(data)
- document.getElementById("timediff").innerHTML = timeDiff + "
" + String(new Date().getTime() - data.srvTime);
-
- if (data.debug) {
- document.getElementById("timediff").style.display = "block";
- } else {
- document.getElementById("timediff").style.display = "none";
- }
+ var data = dataFame;
+ document.getElementById("incomeData").innerHTML = JSON.stringify(data)
+ document.getElementById("timediff").innerHTML = timeDiff + "
" + String(new Date().getTime() - data.srvTime);
- if (data.defaultFullScreen && document.getElementById("initalDate").innerHTML.includes("true") && allowFullscreen) {
- enterFullscreen(document.documentElement);
- document.getElementById("initalDate").innerHTML = "false"
- }
+ if (data.debug) {
+ document.getElementById("timediff").style.display = "block";
+ } else {
+ document.getElementById("timediff").style.display = "none";
+ }
- if (data.showMessage) {
- document.getElementById("overlay").style.display = "block";
- document.getElementById("text").innerHTML = data.message
- } else {
- document.getElementById("overlay").style.display = "none";
- }
+ if (data.defaultFullScreen && document.getElementById("initalDate").innerHTML.includes("true") && allowFullscreen) {
+ enterFullscreen(document.documentElement);
+ document.getElementById("initalDate").innerHTML = "false"
+ }
- if (data.showTimeOnCountdown && data.mode == "timer") {
- document.getElementById("clockSec").innerHTML = getTime();
- } else {
- document.getElementById("clockSec").innerHTML = "";
- }
+ if (data.showMessage) {
+ document.getElementById("overlay").style.display = "block";
+ document.getElementById("text").innerHTML = data.message
+ } else {
+ document.getElementById("overlay").style.display = "none";
+ }
- if (new Date().getTime() - data.messageAppearTime < 5000) {
- if (!document.getElementById("text").classList.contains('blink')) {
- document.getElementById("text").classList.add("blink")
- }
- } else {
- if (document.getElementById("text").classList.contains('blink')) {
- document.getElementById("text").classList.remove("blink")
- }
- }
+ if (data.showTimeOnCountdown && data.mode == "timer") {
+ document.getElementById("clockSec").innerHTML = getTime();
+ } else {
+ document.getElementById("clockSec").innerHTML = "";
+ }
+
+ if (new Date().getTime() - data.messageAppearTime < 5000) {
+ if (!document.getElementById("text").classList.contains('blink')) {
+ document.getElementById("text").classList.add("blink")
+ }
+ } else {
+ if (document.getElementById("text").classList.contains('blink')) {
+ document.getElementById("text").classList.remove("blink")
+ }
+ }
- if (data.mode == "clock") {
- document.getElementById("timer").innerHTML = getTime();
- document.getElementById("testImg").style.display = "none";
- document.getElementById("wholeProgBar").style.display = "none";
- document.getElementById("clockSec").innerHTML = "";
- document.getElementById("timer").style.color = "white"
- timerCountdownFirst = true;
+ if (data.mode == "clock") {
+ document.getElementById("timer").innerHTML = getTime();
+ document.getElementById("testImg").style.display = "none";
+ document.getElementById("wholeProgBar").style.display = "none";
+ document.getElementById("clockSec").innerHTML = "";
+ document.getElementById("timer").style.color = "white"
+ timerCountdownFirst = true;
- } else if (data.mode == "timer") {
- if(data.showProgressbar) {
- document.getElementById("wholeProgBar").style.display = "block";
- } else {
- document.getElementById("wholeProgBar").style.display = "none";
- }
-
- const now = new Date()
+ } else if (data.mode == "timer") {
+ if (data.showProgressbar) {
+ document.getElementById("wholeProgBar").style.display = "block";
+ } else {
+ document.getElementById("wholeProgBar").style.display = "none";
+ }
- if(timerCountdownFirst){
- const diff = data.countdownGoal - now.getTime()
- timerCountdownFirst = false
- document.getElementById("timer").innerHTML = msToTime(diff, data);
- if (diff > 0) {
- document.getElementById("progBar").style.width = percentage(diff, data.timeAmountInital) + "%";
- } else {
- document.getElementById("progBar").style.width = "0%";
- }
+ const now = new Date()
- document.getElementById("progBar").style.backgroundColor = findProgessColor(data.colorSegments, diff)
- document.getElementById("testImg").style.display = "none";
- if (data.enableColoredText) {
- document.getElementById("timer").style.color = findProgessColor(data.textColors, diff)
- } else {
- document.getElementById("timer").style.color = "white"
- }
- }
+ if (timerCountdownFirst) {
+ const diff = data.countdownGoal - now.getTime()
+ timerCountdownFirst = false
+ document.getElementById("timer").innerHTML = msToTime(diff, data);
+ if (diff > 0) {
+ document.getElementById("progBar").style.width = percentage(diff, data.timeAmountInital) + "%";
+ } else {
+ document.getElementById("progBar").style.width = "0%";
+ }
- if (data.timerRunState) {
- const diff = data.countdownGoal - now.getTime()
- document.getElementById("timer").innerHTML = msToTime(diff, data);
- lastTime = msToTime(diff, data);
- if (diff > 0) {
- document.getElementById("progBar").style.width = percentage(diff, data.timeAmountInital) + "%";
- } else {
- document.getElementById("progBar").style.width = "0%";
- }
+ document.getElementById("progBar").style.backgroundColor = findProgessColor(data.colorSegments, diff)
+ document.getElementById("testImg").style.display = "none";
+ if (data.enableColoredText) {
+ document.getElementById("timer").style.color = findProgessColor(data.textColors, diff)
+ } else {
+ document.getElementById("timer").style.color = "white"
+ }
+ }
- document.getElementById("progBar").style.backgroundColor = findProgessColor(data.colorSegments, diff)
- document.getElementById("testImg").style.display = "none";
- if (data.enableColoredText) {
- document.getElementById("timer").style.color = findProgessColor(data.textColors, diff)
- } else {
- document.getElementById("timer").style.color = "white"
- }
+ if (data.timerRunState) {
+ const diff = data.countdownGoal - now.getTime()
+ document.getElementById("timer").innerHTML = msToTime(diff, data);
+ lastTime = msToTime(diff, data);
+ if (diff > 0) {
+ document.getElementById("progBar").style.width = percentage(diff, data.timeAmountInital) + "%";
+ } else {
+ document.getElementById("progBar").style.width = "0%";
+ }
- } else {
- document.getElementById("timer").innerHTML = lastTime
- }
- } else if (data.mode == "black") {
- timerCountdownFirst = true;
- document.getElementById("timer").innerHTML = "";
- document.getElementById("testImg").style.display = "none";
- document.getElementById("wholeProgBar").style.display = "none";
- document.getElementById("clockSec").innerHTML = "";
+ document.getElementById("progBar").style.backgroundColor = findProgessColor(data.colorSegments, diff)
+ document.getElementById("testImg").style.display = "none";
+ if (data.enableColoredText) {
+ document.getElementById("timer").style.color = findProgessColor(data.textColors, diff)
+ } else {
+ document.getElementById("timer").style.color = "white"
+ }
- } else if (data.mode == "test") {
- timerCountdownFirst = true;
- document.getElementById("timer").innerHTML = "";
- document.getElementById("testImg").style.display = "block";
- document.getElementById("progBar").style.display = "none";
- document.getElementById("clockSec").innerHTML = "";
- }
+ } else {
+ document.getElementById("timer").innerHTML = lastTime
+ }
+ } else if (data.mode == "black") {
+ timerCountdownFirst = true;
+ document.getElementById("timer").innerHTML = "";
+ document.getElementById("testImg").style.display = "none";
+ document.getElementById("wholeProgBar").style.display = "none";
+ document.getElementById("clockSec").innerHTML = "";
+
+ } else if (data.mode == "test") {
+ timerCountdownFirst = true;
+ document.getElementById("timer").innerHTML = "";
+ document.getElementById("testImg").style.display = "block";
+ document.getElementById("progBar").style.display = "none";
+ document.getElementById("clockSec").innerHTML = "";
+ }
}
function httpGet(theUrl) {
- var xmlHttp = new XMLHttpRequest();
- xmlHttp.open("GET", theUrl, true); // false for synchronous request
- xmlHttp.send(null);
- xmlHttp.onerror = function (e) {
- console.log(e);
- };
- return xmlHttp;
+ var xmlHttp = new XMLHttpRequest();
+ xmlHttp.open("GET", theUrl, true); // false for synchronous request
+ xmlHttp.send(null);
+ xmlHttp.onerror = function (e) {
+ console.log(e);
+ };
+ return xmlHttp;
}
function getTime() {
- var date = new Date();
- var h = date.getHours(); // 0 - 23
- var m = date.getMinutes(); // 0 - 59
- var s = date.getSeconds(); // 0 - 59
+ var date = new Date();
+ var h = date.getHours(); // 0 - 23
+ var m = date.getMinutes(); // 0 - 59
+ var s = date.getSeconds(); // 0 - 59
- h = h < 10 ? "0" + h : h;
- m = m < 10 ? "0" + m : m;
- s = s < 10 ? "0" + s : s;
+ h = h < 10 ? "0" + h : h;
+ m = m < 10 ? "0" + m : m;
+ s = s < 10 ? "0" + s : s;
- var time = h + ":" + m + ":" + s;
- return time;
+ var time = h + ":" + m + ":" + s;
+ return time;
}
@@ -291,7 +291,7 @@ let temp = new URLSearchParams(window.location.search).get("smaller");
if (temp == "true") {
- var cssURL = '/css/smallerTextMod.css';
- document.head.innerHTML += ''
- allowFullscreen = false
+ var cssURL = '/css/smallerTextMod.css';
+ document.head.innerHTML += ''
+ allowFullscreen = false
}
diff --git a/static/js/timer/timerview.js b/static/js/timer/timerview.js
new file mode 100644
index 0000000..2a03089
--- /dev/null
+++ b/static/js/timer/timerview.js
@@ -0,0 +1,285 @@
+// Scale down the interface if the smaller parameter is set
+let smallerFlag = new URLSearchParams(window.location.search).get("smaller");
+if (smallerFlag == "true") {
+ var cssURL = '/css/smallerTextMod.css';
+ document.head.innerHTML += '';
+ allowFullscreen = false;
+}
+
+// References to the HTML elements
+let warningBox = document.getElementById("warningBanner");
+let timer = document.getElementById("timer");
+let testImage = document.getElementById("testImg");
+let clockSec = document.getElementById("clockSec");
+let timeDiffContainer = document.getElementById("timediff");
+let wholeProgressBar = document.getElementById("wholeProgBar");
+let progressBar = document.getElementById("progBar");
+let overlay = document.getElementById("overlay");
+let overlayText = document.getElementById("text");
+let screensaverText = document.getElementById("moveClock");
+let screensaverClock = document.getElementById("screensaverClock");
+
+// Prepare connection to backend
+let socket = new ReconnectingWebSocket("ws://127.0.0.1:" + location.port);
+
+// State variables
+let ackSessionTokenChange = false; // Wether the user has acknowledged the session token mismatch
+let dataFrame = {};
+let timeDiffToServer = 0;
+let sessionToken = ""; // Our current session token
+
+// Handle connection event
+socket.onopen = function (e) {
+ socket.send("new client");
+};
+
+// Handle connection close event
+socket.onclose = function (event) {
+ warningBox.style.display = "block"; // Show warning banner
+ if (event.wasClean) {
+ console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
+ } else {
+ // e.g. server process killed or network down
+ // event.code is usually 1006 in this case
+ console.error('[close] Connection died');
+ }
+};
+
+// Handle incoming data
+socket.onmessage = function (event) {
+ // Parse the incoming data as JSON
+ const inData = JSON.parse(event.data);
+ // Check if the backend has restarted in the background
+ if (inData.sessionToken == sessionToken || sessionToken == "") {
+ dataFrame = JSON.parse(event.data);
+ // Time difference between the client and the server
+ timeDiffToServer = new Date().getTime() - dataFrame.srvTime;
+
+ if(dataFrame.debug) {
+ console.log(dataFrame)
+ timeDiffContainer.innerHTML = timeDiffToServer
+ timeDiffContainer.style.display = "block"
+ } else {
+ timeDiffContainer.style.display = "none"
+ }
+
+ // Process the data
+ handleUpdate();
+ } else {
+ // If the user has not acknowledged the session token mismatch, show a warning
+ if (!ackSessionTokenChange) {
+ ackSessionTokenChange = true;
+ if (confirm("Session token mismatch, reload the page?")) {
+ location.reload();
+ }
+ }
+ }
+};
+
+// Update timer data regularly (every 20ms)
+let updateIntervalReference = setInterval(handleUpdate, 20);
+
+// Helper functions
+
+// Get the current time in a HH:MM:SS format
+function getTime() {
+ var date = new Date();
+ var h = date.getHours(); // 0 - 23
+ var m = date.getMinutes(); // 0 - 59
+ var s = date.getSeconds(); // 0 - 59
+
+ h = h < 10 ? "0" + h : h;
+ m = m < 10 ? "0" + m : m;
+ s = s < 10 ? "0" + s : s;
+
+ var time = h + ":" + m + ":" + s;
+ return time;
+}
+
+function percentage(partialValue, totalValue) {
+ return (100 * partialValue) / totalValue;
+}
+
+function msToTime(s, data) {
+ isSmallerThenZero = false
+ if (s < 0) {
+ isSmallerThenZero = true
+ }
+
+ var ms = s % 1000;
+ s = (s - ms) / 1000;
+ var secs = s % 60;
+ s = (s - secs) / 60;
+ var mins = s % 60;
+ var hrs = (s - mins) / 60;
+ let out = ""
+
+ if (!data.showMilliSeconds) {
+ out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2)
+ } else {
+ out = ('00' + Math.abs(hrs)).slice(-2) + ':' + ('00' + Math.abs(mins)).slice(-2) + ':' + ('00' + Math.abs(secs)).slice(-2) + '.' + ('000' + Math.abs(ms)).slice(-3)
+ }
+
+ if (isSmallerThenZero) {
+ out = "-" + out
+ }
+ return out;
+}
+
+function findProgessColor(colors, value) {
+ const allColors = Object.keys(colors);
+ let resColor = colors["START"]
+ for (let color in allColors) {
+ const currColor = allColors[color]
+ if (value <= parseInt(currColor)) {
+ resColor = colors[String(currColor)]
+ break
+ }
+ }
+ return (resColor)
+}
+
+function handleUpdate() {
+ switch (dataFrame.mode) {
+ case "timer":
+ // Timer mode
+ timer.style.display = "block";
+ testImage.style.display = "none";
+ screensaverText.style.display = "none";
+
+ if(dataFrame.showTimeOnCountdown) {
+ // Show time on countdown
+ clockSec.innerHTML = getTime();
+ clockSec.style.display = "block";
+ } else {
+ clockSec.style.display = "none";
+ }
+ if(dataFrame.showProgressbar) {
+ // Show progressbar
+ wholeProgressBar.style.display = "block";
+ } else {
+ wholeProgressBar.style.display = "none";
+ }
+ // Calculate the time difference between the goal and the current time
+ const now = new Date();
+ let diff = 0;
+ if(dataFrame.timerRunState) {
+ diff = dataFrame.countdownGoal - now.getTime()
+ } else {
+ diff = (now.getTime() - dataFrame.pauseMoment) + dataFrame.countdownGoal - now.getTime()
+ }
+
+ timer.innerHTML = msToTime(diff, dataFrame);
+
+ // Handle the progressbar
+ if (diff >= 0) {
+ progressBar.style.width = percentage(diff, dataFrame.timeAmountInital) + "%";
+ } else {
+ progressBar.style.width = "0%";
+ }
+ progressBar.style.backgroundColor = findProgessColor(dataFrame.colorSegments, diff)
+
+ // Handle the text color
+ if (dataFrame.enableColoredText) {
+ timer.style.color = findProgessColor(dataFrame.textColors, diff)
+ } else {
+ timer.style.color = "white"
+ }
+ break;
+ case "clock":
+ // Clock mode
+ timer.innerHTML = getTime();
+ testImage.style.display = "none";
+ clockSec.style.display = "none";
+ wholeProgressBar.style.display = "none";
+ timer.style.display = "block";
+ screensaverText.style.display = "none";
+ timer.style.color = "white";
+ break;
+ case "black":
+ // Black screen mode
+ testImage.style.display = "none";
+ clockSec.style.display = "none";
+ wholeProgressBar.style.display = "none";
+ timer.style.display = "none";
+ screensaverText.style.display = "none";
+ timer.style.color = "white";
+ break;
+ case "test":
+ // Test image mode
+ testImage.style.display = "block";
+ clockSec.style.display = "none";
+ wholeProgressBar.style.display = "none";
+ timer.style.display = "none";
+ screensaverText.style.display = "none";
+ timer.style.color = "white";
+ break;
+ case "screensaver":
+ // Screensaver mode
+ testImage.style.display = "none";
+ clockSec.style.display = "none";
+ wholeProgressBar.style.display = "none";
+ timer.style.display = "none";
+ timer.style.color = "white";
+ screensaverText.style.display = "block";
+ screensaverClock.innerHTML = getTime();
+ break;
+ }
+
+ // Handle the message overlay
+ if (dataFrame.showMessage) {
+ overlay.style.display = "block";
+ overlayText.innerHTML = dataFrame.message
+ } else {
+ overlay.style.display = "none";
+ }
+ // This will result in the text fading in and out when the message changes
+ if (new Date().getTime() - dataFrame.messageAppearTime < 5000) {
+ if (!overlayText.classList.contains('blink')) {
+ overlayText.classList.add("blink")
+ }
+ } else {
+ if (overlayText.classList.contains('blink')) {
+ overlayText.classList.remove("blink")
+ }
+ }
+}
+
+/**
+ Additional documentation
+
+ {
+ "mode": "clock",
+ "countdownGoal": 1668368090542,
+ "showMilliSeconds": false,
+ "defaultFullScreen": true,
+ "timeAmountInital": 0,
+ "timerRunState": false,
+ "pauseMoment": 0,
+ "showTimeOnCountdown": true,
+ "message": "",
+ "showMessage": false,
+ "messageAppearTime": 0,
+ "showProgressbar": true,
+ "colorSegments": {
+ "5000": "#ff0000",
+ "20000": "#FFAE00",
+ "40000": "yellow",
+ "START": "green"
+ },
+ "textColors": {
+ "5000": "#ff0000",
+ "20000": "#FFAE00",
+ "40000": "yellow",
+ "START": "green"
+ },
+ "srvTime": 1668369368722,
+ "enableColoredText": true,
+ "debug": false,
+ "sessionToken": "c184x6on5yb99lkq3ola"
+}
+
+Possible modes:
+const modes = ["timer", "clock", "black", "test"]
+
+*/
\ No newline at end of file
diff --git a/templates/newAdminPanel.html b/templates/newAdminPanel.html
index 2c9b6c9..5c0107d 100644
--- a/templates/newAdminPanel.html
+++ b/templates/newAdminPanel.html
@@ -156,6 +156,9 @@
+
+
+
diff --git a/templates/ng-timerview.html b/templates/ng-timerview.html
new file mode 100644
index 0000000..fd721b5
--- /dev/null
+++ b/templates/ng-timerview.html
@@ -0,0 +1,62 @@
+
+
+
+
+