// --- begin, important constants const data = { duration: 1, // will be multiplied by 30 machine_id: "" } const API_URL = "https://backend.laundryweb.altafcreator.com" // --- check user status // returns true if there exists a timer, and returns false otherwise. // cookie need to be included. async function checkUserStatus() { const response = await fetch(`${API_URL}/check`, { credentials: "include", method: "POST", }); return await response.text(); } // --- check machine status // returns a 2d array representing machines // []: root array // []: block // enum: machine status async function checkMachineStatus() { const response = await fetch(`${API_URL}/status`, { method: "POST", credentials: "include", }); return await response.json(); } // --- timer duration const minField = document.getElementById("min-field"); const decBtn = document.getElementById("decTime"); function increaseTime() { data.duration += 1; minField.innerText = (30 * data.duration).toString() + " minutes"; decBtn.disabled = false; } function decreaseTime() { data.duration -= 1; data.duration = Math.max(data.duration, 1); if (data.duration == 1) { decBtn.disabled = true; } minField.innerText = (30 * data.duration).toString() + " minutes"; } // --- starting a timer function start() { fetch(`${API_URL}/start`, { credentials: "include", method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }).then(response => response.text()) .then(data => { console.log(data); if (data == "all good bro timer started") { window.location.href = "/timer/"; } }); } // --- information loading + cookie setting (from server) async function information(urlParam = null) { const response = fetch(`${API_URL}/info`, { credentials: "include", method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "machine_id": urlParam ? urlParam : "" }), }); const block = await response.json()["block"]; document.getElementById("logo-id").innerText = block; return Promise.resolve(block); } // ------ page specific ----- // ---- machine status page const STATUS_INTERVAL = 30 // --- machines visual async function startUpdateMachines() { const urlParams = new URLSearchParams(window.location.search); await information(urlParams.get("block")); updateMachines(); while (true) { await delay(STATUS_INTERVAL * 1000); await updateMachines(); } } async function updateMachines() { const dryer1 = document.getElementById("dryer1-img"); const washer1 = document.getElementById("washer1-img"); const dryer2 = document.getElementById("dryer2-img"); const washer2 = document.getElementById("washer2-img"); const machine_imgs = [dryer1, washer1, dryer2, washer2]; const dryer1txt = document.getElementById("dryer1-span"); const washer1txt = document.getElementById("washer1-span"); const dryer2txt = document.getElementById("dryer2-span"); const washer2txt = document.getElementById("washer2-span"); const machine_txts = [dryer1txt, washer1txt, dryer2txt, washer2txt]; const status = await checkMachineStatus(); console.log(status); for (let i = 0; i < status[0].length; i++) { if (status[0][i] == "RUNNING") { if ((i + 1) % 2 == 0) { machine_imgs[i].src = "/assets/img/washer_on.png"; } else { machine_imgs[i].src = "/assets/img/dryer_on.png"; } const now = Date.now(); const start = Date.parse(status[1][i]); machine_txts[i].innerHTML = Math.ceil(((start + (status[2][i] * 60000)) - now) / 60000).toString() + " min(s) left"; } else if (status[0][i] == "FINISHED") { if ((i + 1) % 2 == 0) { machine_imgs[i].src = "/assets/img/washer_clothes.png"; } else { machine_imgs[i].src = "/assets/img/dryer_clothes.png"; } machine_txts[i].innerHTML = "Idle" } else { if ((i + 1) % 2 == 0) { machine_imgs[i].src = "/assets/img/washer_off.png"; } else { machine_imgs[i].src = "/assets/img/dryer_off.png"; } machine_txts[i].innerHTML = "Idle" } } } // --- current timers async function startLoadTimers() { const timersData = await fetchTimers(); if (timersData[0] != 200) { console.error(timersData[0].toString() + " from backend: " + timersData[1]); return; } const timers = timersData[1]; const container = document.getElementById("timer-container") const textList = [] const progList = [] const endTimestamps = [] for (let i = 0; i < timers.length; i++) { container.innerHTML += `

Timer #${(i + 1).toString()}

Dryer 1
Washer 1
Dryer 2
Washer 2
15:00
` textList.push(`timer-txt-${i}`); progList.push(`timer-prog-${i}`); endTimestamps.push(Date.parse(timers[i]["start_time"]) + timers[i]["duration"] * 60000); } for (let i = 0; i < timers.length; i++) { // html rebuilds everytime innerHTML is modified document.getElementById(`timer-btn-${i}`).addEventListener("click", function () { finishLaundryTimer(timers[i]["id"]); }); console.log("added!"); } console.log(textList); console.log(endTimestamps); while (true) { for (let i = 0; i < textList.length; i++) { const text = document.getElementById(textList[i]); text.innerText = ""; const timeRemaining = Math.max(Math.round((endTimestamps[i] - Date.now()) / 1000), 0); const hours = Math.floor(timeRemaining / 3600); const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; if (hours > 0) text.innerText += hours.toString().padStart(2, '0') + ':'; text.innerText += minutes.toString().padStart(2, '0') + ':'; text.innerText += seconds.toString().padStart(2, '0'); const prog = document.getElementById(progList[i]); prog.style.width = ((timeRemaining / (timers[i]["duration"] * 60)) * 100).toString() + "%"; if (timeRemaining <= 0) { document.getElementById(`timer-btn-${i}`).disabled = false; } } await delay(1000); } } async function fetchTimers() { const response = await fetch(`${API_URL}/laundry`, { method: "POST", credentials: "include", }); return [response.status, await response.json()]; } // --- finish / collect timer / laundry async function finishLaundryTimer(timerId) { console.log("finishing timer! w/ id "+timerId.toString()); const response = await fetch(`${API_URL}/finish`, { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify({id: timerId}), }); if (await response.text() == "laundry finished") { window.location.reload(); } } const delay = (durationMs) => { return new Promise(resolve => setTimeout(resolve, durationMs)); }