// --- begin, important constants const data = { duration: 1, // will be multiplied by 30 machine_id: "", onesignal_subscription_id: "", } const API_URL = "https://backend.laundryweb.altafcreator.com" // --- 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 async 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 = await fetch(`${API_URL}/info`, { credentials: "include", method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "machine_id": urlParam ? urlParam : "" }), }); const json = await response.json(); if (json["block"]) { document.getElementById("logo-id").innerText = "H" + json["block"]; } else { document.getElementById("logo-id").innerText = "H?"; } return Promise.resolve(json["block"]); } // ------ page specific ----- // wait WHY THE FUCK ARE THESE HERE THEN? // ---- machine status page const STATUS_INTERVAL = 30 // --- machines visual async function startUpdateMachines() { const urlParams = new URLSearchParams(window.location.search); await information(urlParams.get("machine")); console.log("info done") updateMachines(); while (true) { await delay(STATUS_INTERVAL * 1000); await updateMachines(); } } async function updateMachines() { // less disgusting. const types = ["dryer", "washer"]; const ns = [1, 2]; const machineImgs = []; const machineTxts = []; const machineDetailImgs = []; const machineDetailTitles = []; const machineDetailDescs = []; for (const n of ns) { for (const t of types) { machineImgs.push(document.getElementById(`${t}${n}-img`)); machineTxts.push(document.getElementById(`${t}${n}-span`)); machineDetailImgs.push(document.getElementById(`detail-${t[0]}${n}-img`)); machineDetailTitles.push(document.getElementById(`detail-${t[0]}${n}-title`)); machineDetailDescs.push(document.getElementById(`detail-${t[0]}${n}-desc`)); } } console.log(machineDetailImgs); console.log(machineDetailTitles); console.log(machineDetailDescs); 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) { machineImgs[i].src = "/assets/img/washer_on.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/washer_on.png"; if (machineDetailImgs[0]) machineDetailDescs[i].innerHTML = "Timing might differ due to heavy load or excess suds." } else { machineImgs[i].src = "/assets/img/dryer_on.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/dryer_on.png"; if (machineDetailImgs[0]) machineDetailTitles[i].innerHTML = "Idle" } const now = Date.now(); const end = Date.parse(status[2][i]); const minsLeft = Math.ceil((end - now) / 60000).toString(); machineTxts[i].innerHTML = minsLeft + " min(s) left"; if (machineDetailImgs[0]) machineDetailTitles[i].innerHTML = minsLeft + " minutes left" } else if (status[0][i] == "FINISHED") { if ((i + 1) % 2 == 0) { machineImgs[i].src = "/assets/img/washer_clothes.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/washer_clothes.png"; } else { machineImgs[i].src = "/assets/img/dryer_clothes.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/dryer_clothes.png"; } machineTxts[i].innerHTML = "Idle" if (machineDetailImgs[0]) machineDetailTitles[i].innerHTML = "Idle" if (machineDetailImgs[0]) machineDetailDescs[i].innerHTML = "Clothes may not be collected yet." } else { if ((i + 1) % 2 == 0) { machineImgs[i].src = "/assets/img/washer_off.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/washer_off.png"; } else { machineImgs[i].src = "/assets/img/dryer_off.png"; if (machineDetailImgs[0]) machineDetailImgs[i].src = "/assets/img/dryer_off.png"; } if (machineDetailImgs[0]) machineDetailTitles[i].innerHTML = "Idle" if (machineDetailImgs[0]) machineDetailDescs[i].innerHTML = "" machineTxts[i].innerHTML = "Idle" } } console.log("done"); } // --- current timers async function startLoadTimers() { information(); 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 startTimestamps = [] 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}`); console.log() endTimestamps.push(Date.parse(timers[i]["end_time"])); startTimestamps.push(Date.parse(timers[i]["start_time"])); } 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); console.log(startTimestamps); 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]); const totalTime = endTimestamps - startTimestamps; prog.style.width = ((timeRemaining / (totalTime / 1000)) * 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)); }