Skip to content
Snippets Groups Projects
Commit 8cba374a authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

wip - server-side timer

parent 023cf9af
No related branches found
No related tags found
1 merge request!9Release
Checking pipeline status
import $ from "jquery" import $ from "jquery"
import Timer from "easytimer.js" import Timer from "easytimer.js"
import alertify from "alertifyjs";
import "alertifyjs/build/css/alertify.css";
const updateTimeText = (timer) => {
const timeValues = timer.getTimeValues()
const hours = String(timeValues.minutes + timeValues.hours * 60 + timeValues.days * 1440).padStart(2, '0')
const seconds = String(timeValues.seconds).padStart(2, '0')
$('#timer .timer-values').html(`${hours}:${seconds}`)
}
const assignEventListeners = (timer) => { const assignEventListeners = (timer) => {
timer.addEventListener( timer.addEventListener(
'secondsUpdated', 'secondsUpdated',
(event) => { (event) => {
$('#timer .timer-values').html(timer.getTimeValues().toString(['minutes', 'seconds'])) updateTimeText(timer)
} }
) )
...@@ -17,7 +29,7 @@ const assignEventListeners = (timer) => { ...@@ -17,7 +29,7 @@ const assignEventListeners = (timer) => {
} }
) )
$('#timer .timer-values').html(timer.getTimeValues().toString(['minutes', 'seconds'])) updateTimeText(timer)
} }
$(window).ready( $(window).ready(
...@@ -32,59 +44,79 @@ $(window).ready( ...@@ -32,59 +44,79 @@ $(window).ready(
} }
}) })
const timerSocket = new WebSocket( let timerSocket = null
( let isInitialConnect = true
(window.location.protocol === "https:") ?
"wss://" : "ws://" const connectToSocket = () => {
timerSocket = new WebSocket(
(
(window.location.protocol === "https:") ?
"wss://" : "ws://"
)
+ window.location.host
+ "/ws/timer/"
) )
+ window.location.host
+ "/ws/timer/"
)
timerSocket.onmessage = (event) => { if (!isInitialConnect) {
const data = JSON.parse(event.data) alertify.success("Obnovování spojení.")
}
if ("status" in data) { isInitialConnect = false
if (data["status"] === "playing") {
// Reset if we are playing again.
const remainingTime = timer.getTimeValues()
if (remainingTime.seconds === 0 && remainingTime.minutes === 0) { timerSocket.onmessage = (event) => {
timer = new Timer({ console.log("Received timer message:", event.data)
countdown: true,
startValues: {
minutes: window.startingTime.minutes,
seconds: window.startingTime.seconds,
}
})
assignEventListeners(timer) const data = JSON.parse(event.data)
}
if ("status" in data) {
if (data["status"] === "playing") {
// Reset if we are playing again.
const remainingTime = timer.getTimeValues()
if (remainingTime.seconds === 0 && remainingTime.minutes === 0) {
timer = new Timer({
countdown: true,
startValues: {
minutes: window.startingTime.minutes,
seconds: window.startingTime.seconds,
}
})
timer.start() assignEventListeners(timer)
} else if (data["status"] === "paused") { }
timer.start()
} else if (data["status"] === "paused") {
timer.pause()
}
} else if ("time" in data) {
timer.pause() timer.pause()
}
} else if ("time" in data) {
timer.pause()
window.startingTime = { window.startingTime = {
minutes: data["time"]["minutes"], minutes: data["time"]["minutes"],
seconds: data["time"]["seconds"] seconds: data["time"]["seconds"]
}
timer = new Timer({
countdown: true,
startValues: {
minutes: window.startingTime.minutes,
seconds: window.startingTime.seconds,
}
})
assignEventListeners(timer)
} }
}
timer = new Timer({ timerSocket.onclose = (event) => {
countdown: true, alertify.error("Ztráta spojení, pokoušíme se o zpětné připojení.")
startValues: {
minutes: window.startingTime.minutes,
seconds: window.startingTime.seconds,
}
})
assignEventListeners(timer) setTimeout(connectToSocket, 5000)
} }
} }
connectToSocket()
assignEventListeners(timer) assignEventListeners(timer)
// --- END Timer --- // --- END Timer ---
...@@ -120,10 +152,13 @@ $(window).ready( ...@@ -120,10 +152,13 @@ $(window).ready(
$("#update-time").on( $("#update-time").on(
"click", "click",
(event) => { (event) => {
let minutes = Number($("#minutes").val())
let seconds = Number($("#seconds").val())
timerSocket.send(JSON.stringify({ timerSocket.send(JSON.stringify({
"time": { "time": {
"minutes": Number($("#minutes").val()), "minutes": minutes,
"seconds": Number($("#seconds").val()) "seconds": seconds
} }
})) }))
......
import datetime
import json import json
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer from channels.generic.websocket import AsyncWebsocketConsumer
import time
class TimerConsumer(WebsocketConsumer): class TimerConsumer(AsyncWebsocketConsumer):
def connect(self): timer_is_running = False
async_to_sync(self.channel_layer.group_add)("timer", self.channel_name)
self.accept() async def connect(self) -> None:
await self.channel_layer.group_add("timer", self.channel_name)
await self.accept()
def disconnect(self, close_code): async def disconnect(self, close_code) -> None:
pass await self.channel_layer.group_discard("timer", self.channel_name)
def receive(self, text_data): async def run_timer(self, minutes: int, seconds: int) -> None:
total_seconds = (minutes * 60) + seconds
first_run = True
print("running timer")
for second in range(total_seconds + 1):
if not first_run:
while not self.timer_is_running:
time.sleep(0.05)
# Do on the first run, then every 5 seconds
if first_run or total_seconds % 5 == 0:
new_seconds = total_seconds % 60
new_minutes = round((total_seconds - new_seconds) / 60)
print("sending")
await self.channel_layer.group_send(
"timer",
{
"type": "timer_message",
"text": json.dumps({
"time": {
"minutes": new_minutes,
"seconds": new_seconds
}
})
}
)
if not first_run:
total_seconds -= 1
time.sleep(1)
first_run = False
async def receive(self, text_data: str) -> None:
json_data = json.loads(text_data) json_data = json.loads(text_data)
response = None response = None
time_updated = False
if "status" in json_data: if "status" in json_data:
if json_data["status"] == "playing": if json_data["status"] == "playing":
response = {"status": "playing"} response = {"status": "playing"}
self.timer_is_running = True
elif json_data["status"] == "paused": elif json_data["status"] == "paused":
response = {"status": "paused"} response = {"status": "paused"}
self.timer_is_running = False
if "time" in json_data: if "time" in json_data:
minutes = json_data["time"]["minutes"]
seconds = json_data["time"]["seconds"]
response = { response = {
"time": { "time": {
"minutes": json_data["time"]["minutes"], "minutes": minutes,
"seconds": json_data["time"]["seconds"], "seconds": seconds,
} }
} }
time_updated = True
if response is not None: if response is not None:
async_to_sync(self.channel_layer.group_send)( if time_updated:
"timer", {"type": "timer_message", "text": json.dumps(response)} await self.run_timer(minutes, seconds)
)
self.send(text_data=json.dumps({})) await self.send(text_data=json.dumps({}))
def timer_message(self, event): async def timer_message(self, event: dict) -> None:
self.send(text_data=event["text"]) await self.send(text_data=event["text"])
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
type="number" type="number"
id="minutes" id="minutes"
name="minutes" name="minutes"
min="0"
max="60"
placeholder="Minuty" placeholder="Minuty"
autocomplete="off" autocomplete="off"
> >
...@@ -67,6 +69,8 @@ ...@@ -67,6 +69,8 @@
type="number" type="number"
id="seconds" id="seconds"
name="seconds" name="seconds"
min="0"
max="60"
placeholder="Sekundy" placeholder="Sekundy"
autocomplete="off" autocomplete="off"
> >
......
...@@ -33,7 +33,7 @@ module.exports = { ...@@ -33,7 +33,7 @@ module.exports = {
}, },
output: { output: {
path: path.resolve(__dirname, "shared", "static", "shared"), path: path.resolve(__dirname, "shared", "static", "shared"),
filename: "[name]-[fullhash].js", filename: "[name].js",
}, },
module: { module: {
rules: [ rules: [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment