<meta charset="utf-8">
<title>XMDV</title>
<style>
-.split {
- display: inline-block;
- width: calc(50% - 20px);
- margin: 10px;
- vertical-align: top;
-}
/*
clock styling
- makes div square
/*
media query to make sure the clock is always displayed well
*/
+.clockTimeLeft,.clockTimeRight,.clockTimeTop,.clockTimeBottom {
+ position: absolute;
+ display: block;
+ width: 60px;
+
+}
+#nextLabel, #startLabel {
+ position: absolute;
+ width: 50%;
+ height: 50%;
+ margin: 0;
+ transform: translateX(-50%);
+ top: 50%;
+ left: 50%;
+ text-align: center;
+ line-height: 50%;
+}
+#startLabel {
+ transform: translate(-50%, -2em);
+}
+
@media (orientation: portrait) {
:root {
font-size: 2em;
.clock {
position: relative;
width: 100%;
+ margin: 10px 60px 10px 60px;
aspect-ratio: 1;
}
.clockButton {
{% for p in positions %}
.angle{{p.i}} {top: calc({{p.y}}% - 1em); left: calc({{p.x}}% - 1em);}
{% endfor %}
+
+ .clockTimeLeft {
+ text-align: left;
+ transform: translateX(2em);
+ }
+ .clockTimeRight {
+ text-align: right;
+ transform: translateX(-60px);
+ }
+ .clockTimeTop {
+ text-align: center;
+ transform: translate(calc(-30px + 1em), -2em);
+ }
+ .clockTimeBottom {
+ text-align: center;
+ transform: translate(calc(-30px + 1em), 2em);
+ }
}
@media (orientation: landscape) {
.clock {
position: relative;
height: 70vh;
+ margin: 10px 60px 10px 60px;
aspect-ratio: 1;
}
.clockButton {
{% for p in positions %}
.angle{{p.i}} {top: calc({{p.y}}% - 0.75em); left: calc({{p.x}}% - 0.75em);}
{% endfor %}
+
+ .clockTimeLeft {
+ text-align: left;
+ transform: translateX(1.5em);
+ }
+ .clockTimeRight {
+ text-align: right;
+ transform: translateX(-60px);
+ }
+ .clockTimeTop {
+ text-align: center;
+ transform: translate(calc(-30px + 0.75em), -1.5em);
+ }
+ .clockTimeBottom {
+ text-align: center;
+ transform: translate(calc(-30px + 0.75em), 1.5em);
+ }
}
</style>
</head>
- <body>
+ <body onload="update();mainTimer({{data.current_position}});">
<a href="/admin">.. Back to admin pannel</a>
+ <form action="/admin/clock" method="POST">
+ <input type="checkbox" value="0" name="end_timer_main" checked="checked" style="display: none">
+ <input type="submit" name="update" value="Manual time reset">
+ </form>
+
<form action="/admin/clock" method="POST">
<fieldset>
<legend>Doomsday clock <em>(Incr. {{positions[1].i}} deg)</em></legend>
<div class=clock>
<svg class='clockFace' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'><circle r='45' cx='50' cy='50' fill='none' stroke='#a0a0a0' stroke-width='0.15px'/></svg>
+ <input type="checkbox" value="0" name="end_timer_main" id="checkbox" style="display: none">
{% for p in positions %}
+
+ {% set extra = "" %}
{% if p.i == data.current_position %}
- <input type='radio' class='clockButton angle{{p.i}}' value='{{p.i}}' name='current_position' checked='checked' style='outline: 2px solid red;'>
+ {% set next_index = loop.index %}
+ {% set extra = "checked='checked' style='outline: 2px solid red;'"|safe %}
+ {% endif %}
+ <input type='radio' class='clockButton angle{{p.i}}' value='{{p.i}}' name='current_position' onclick='mainTimer({{p.i}});' {{extra}}>
+ {% if loop.first %}
+ <span class='clockTimeTop angle{{p.i}}' id="{{loop.index0}}">T+00:00</span>
+ {% elif p.i == 180 %}
+ <span class='clockTimeBottom angle{{p.i}}' id="{{loop.index0}}">T+00:00</span>
+ {% elif p.i < 180 %}
+ <span class='clockTimeLeft angle{{p.i}}' id="{{loop.index0}}">T+00:00</span>
{% else %}
- <input type='radio' class='clockButton angle{{p.i}}' value='{{p.i}}' name='current_position'>
+ <span class='clockTimeRight angle{{p.i}}' id="{{loop.index0}}">T+00:00</span>
{% endif %}
{% endfor %}
-
+ <h3 id="startLabel">TX Start @ <span id="start">00:00</span></h3>
+ <h2 id="nextLabel">Next tick in <span id="next">T+00:00</span></h2>
</div>
+ <em>Time will reset automatically on clock reset</em>
</fieldset>
<fieldset>
<legend>Movement</legend>
</fieldset>
<input type="submit" name="update" value="Update">
</form>
+
+ <script>
+
+const timeTotal = 3600;
+
+function mainTimer (value) {
+ const checkbox = document.getElementById("checkbox");
+ if (value == 0) {checkbox.checked = true;}
+ else {checkbox.checked = false;}
+}
+
+function update() {
+ fetch("/api", {cache: "no-store"})
+ .then(data => data.json())
+ .then(data => {
+ for (let t = 0; t <= {{positions|length}}; t++) {
+ const timer = document.getElementById(t);
+ const incrementTime = Math.round(timeTotal / {{positions|length}});
+
+ let current = Math.round((Date.now() + data['timer_offset']) / 1000);
+ var time = (data["end_timer_main"] - current) + (t * incrementTime);
+
+ let negate = "";
+ if (time > 0) {
+ var minutes = Math.floor(time / 60);
+ var seconds = (time - (minutes * 60));
+ } else {
+ var minutes = Math.ceil(time / 60);
+ var seconds = -(time - (minutes * 60));
+ negate = "-";
+ }
+ if (minutes < 0) {seconds = 60 - seconds;} // reverse tick if in the past
+
+ var minutesString = negate + minutes.toString().padStart(2, "0");
+ var secondsString = seconds.toString().padStart(2, "0");
+
+ timer.innerHTML = `T-${minutesString}:${secondsString}`.replace("--","+");
+ if (minutes < 1) {
+ if (time <= 0) {timer.style.color = "red";}
+ else if (seconds % 2 == 0) {timer.style.color = "green";}
+ else {timer.style.color = "orange";}
+ } else {
+ timer.style.color = "green";
+ }
+
+ if (t ==
+ {% for p in positions %}
+ {% if p.i == data.current_position %}
+ {{loop.index}}
+ {% endif %}
+ {% endfor %}
+ ) {
+ document.getElementById("next").innerHTML = `T-${minutesString}:${secondsString}`.replace("--","+");
+
+ const nextLabel = document.getElementById("nextLabel");
+ if (minutes < 1) {
+ if (time <= 0) {nextLabel.style.color = "red";}
+ else if (seconds % 2 == 0) {nextLabel.style.color = "green";}
+ else {nextLabel.style.color = "orange";}
+ } else {
+ nextLabel.style.color = "green";
+ }
+
+ var date = new Date(data["end_timer_main"] * 1000);
+ document.getElementById("start").innerHTML = `${date.getHours()}:${date.getMinutes()}`;
+ }
+ }
+ });
+}
+
+setInterval(update, 1000)
+
+ </script>
</body>
</html>