write doc
Took 2 hours 59 minutes
This commit is contained in:
@ -42,6 +42,8 @@ export class Utils {
|
||||
reject(new Error(`Request Failed With a Status Code: ${res.statusCode}`));
|
||||
|
||||
}
|
||||
}).on("error", (e) => {
|
||||
reject(new Error("Request failed " + e))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -8,6 +8,6 @@ export enum WebSocketEvent {
|
||||
SETUP = "SETUP",
|
||||
REQUEST = "REQUEST",
|
||||
RESPONSE = "RESPONSE",
|
||||
FILL = "FILL",
|
||||
CANCEL = "CANCEL"
|
||||
CANCEL = "CANCEL",
|
||||
ERROR = "ERROR",
|
||||
}
|
@ -17,7 +17,6 @@ import {IIngredient} from "./database/IIngredient";
|
||||
import Ingredient from "./database/Ingredient";
|
||||
import {clearInterval} from "timers";
|
||||
import {RejectReason} from "./RejectReason";
|
||||
import {Settings} from "./Settings";
|
||||
import axios from "axios";
|
||||
import GPIO from "rpi-gpio";
|
||||
import {MyGPIO} from "./MyGPIO";
|
||||
@ -27,6 +26,10 @@ const isPI = require("detect-rpi");
|
||||
const log = debug("itender:station");
|
||||
const mixLog = debug("itender:mix");
|
||||
|
||||
|
||||
/**
|
||||
* The main class of the itender, here a located all main features of the system, like starting pumps, firing events and stuff
|
||||
*/
|
||||
export class iTender {
|
||||
private static secondsPer100ml: number = 35.3335;
|
||||
|
||||
@ -34,6 +37,9 @@ export class iTender {
|
||||
return this._drinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current job of the itender
|
||||
*/
|
||||
static get currentJob(): IJob | null {
|
||||
return this._currentJob;
|
||||
}
|
||||
@ -43,6 +49,9 @@ export class iTender {
|
||||
private static _jobCheckInterval: NodeJS.Timer;
|
||||
private static _internetConnection: boolean = false;
|
||||
|
||||
/**
|
||||
* Returns true if internet connection is active
|
||||
*/
|
||||
static get internetConnection(): boolean {
|
||||
return this._internetConnection;
|
||||
}
|
||||
@ -60,6 +69,11 @@ export class iTender {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is fired if the user likes to mix a drink
|
||||
* @param data
|
||||
*/
|
||||
static onReceiveFill(data: { drink: IDrink, amounts?: { ingredient: String, amount: number }[], amount?: number }): Promise<IJob> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
mixLog("Receiving fill");
|
||||
@ -71,6 +85,7 @@ export class iTender {
|
||||
|
||||
const job = new Job();
|
||||
|
||||
|
||||
let amounts: { ingredient: IIngredient, amount: number, container?: IContainer }[] = [];
|
||||
job.completeAmount = 0;
|
||||
if (data.amounts) {
|
||||
@ -121,8 +136,7 @@ export class iTender {
|
||||
console.log(amounts);
|
||||
job.drink = drink
|
||||
job.amounts = amounts as { ingredient: IIngredient, amount: number, container: IContainer }[];
|
||||
if( job.estimatedTime < 0.5 )
|
||||
{
|
||||
if (job.estimatedTime < 0.5) {
|
||||
job.estimatedTime = 1;
|
||||
}
|
||||
await job.save()
|
||||
@ -134,6 +148,11 @@ export class iTender {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the internal fill method
|
||||
* @param job
|
||||
*/
|
||||
static async startFill(job: IJob) {
|
||||
job.startedAt = new Date();
|
||||
await job.populate([{path: "amounts.ingredient"}, {path: "amounts.container"}, {path: "drink"}]);
|
||||
@ -149,7 +168,7 @@ export class iTender {
|
||||
try {
|
||||
await MyGPIO.setup(x.container.pumpPin, GPIO.DIR_OUT)
|
||||
|
||||
await MyGPIO.write(x.container.pumpPin, true );
|
||||
await MyGPIO.write(x.container.pumpPin, true);
|
||||
} catch (e) {
|
||||
if (isPI()) {
|
||||
log("[ERROR] GPIO I/O Error " + e);
|
||||
@ -177,7 +196,7 @@ export class iTender {
|
||||
mixLog(`Stopping output of pump ${x.container.pumpPin}`);
|
||||
// Stop pump here
|
||||
try {
|
||||
await MyGPIO.write(x.container.pumpPin, false );
|
||||
await MyGPIO.write(x.container.pumpPin, false);
|
||||
} catch (e) {
|
||||
if (isPI()) {
|
||||
log("[ERROR] GPIO I/O Error " + e);
|
||||
@ -204,11 +223,15 @@ export class iTender {
|
||||
job.successful = true;
|
||||
await job.save();
|
||||
mixLog("Job successful");
|
||||
setTimeout( () => iTender.setStatus(iTenderStatus.READY), 3000 )
|
||||
setTimeout(() => iTender.setStatus(iTenderStatus.READY), 3000)
|
||||
|
||||
}, 500);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancel the fill
|
||||
*/
|
||||
static async cancelFill() {
|
||||
if (!this._currentJob || this.status != iTenderStatus.FILLING)
|
||||
return;
|
||||
@ -221,7 +244,7 @@ export class iTender {
|
||||
for (let x of this._currentJob.amounts) {
|
||||
// stop pump pin
|
||||
try {
|
||||
await MyGPIO.write(x.container.pumpPin, false );
|
||||
await MyGPIO.write(x.container.pumpPin, false);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
@ -231,6 +254,10 @@ export class iTender {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Measure all containers based on their sensor values
|
||||
*/
|
||||
static measureContainers(): Promise<void> {
|
||||
log("Measuring containers...");
|
||||
|
||||
@ -269,6 +296,11 @@ export class iTender {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh the drinks to the local variable
|
||||
* Check which drinks can be done, based on the current container ingredients
|
||||
*/
|
||||
static refreshDrinks(): Promise<void> {
|
||||
log("Refreshing drinks...");
|
||||
return new Promise(async resolve => {
|
||||
@ -326,6 +358,10 @@ export class iTender {
|
||||
try {
|
||||
const requestIngredients = await axios.get("https://itender.iif.li/api/ingredients");
|
||||
let serverIngredients = requestIngredients.data as IIngredient[];
|
||||
if (serverIngredients.length == 0) {
|
||||
log("Got 0 ingredients from the server... aborting.");
|
||||
throw new Error("Got 0 ingredients from the server, invalid");
|
||||
}
|
||||
log("Got " + serverIngredients.length + " ingredients from server");
|
||||
|
||||
let localIngredients = await Ingredient.find();
|
||||
@ -362,6 +398,10 @@ export class iTender {
|
||||
|
||||
const requestDrinks = await axios.get("https://itender.iif.li/api/drinks");
|
||||
let serverDrinks = requestDrinks.data as IDrink[];
|
||||
if (serverDrinks.length == 0) {
|
||||
log("Got 0 drinks from the server... aborting.");
|
||||
throw new Error("Got 0 drinks from the server, invalid");
|
||||
}
|
||||
log("Got " + serverDrinks.length + " drinks from server");
|
||||
|
||||
|
||||
@ -405,16 +445,16 @@ export class iTender {
|
||||
log("Drink " + remote.name + " failed to download thumbnail! (" + url + ") | " + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error("Could not refresh drinks " + e);
|
||||
await WebSocketHandler.send(new WebSocketPayload(WebSocketEvent.ERROR, false, "Beim aktualisieren der Getränke ist ein Netzwerk-Fehler aufgetreten.<br>Bitte später erneut versuchen!"));
|
||||
}
|
||||
|
||||
iTender.setStatus(iTenderStatus.READY);
|
||||
resolve();
|
||||
iTender.refreshDrinks();
|
||||
await iTender.refreshDrinks();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,10 @@ import {WebSocketPayload} from "../WebSocketPayload";
|
||||
import {WebSocketEvent} from "../WebSocketEvent";
|
||||
|
||||
export class Containers {
|
||||
|
||||
/**
|
||||
* Open the menu for the container ingredient setup
|
||||
*/
|
||||
static openMenu() {
|
||||
let modal = new Modal("containers", "Behälter aktualisieren");
|
||||
let txt = document.createElement("p");
|
||||
@ -24,6 +28,7 @@ export class Containers {
|
||||
btnSave.disabled = true;
|
||||
|
||||
let containerVolumes: Record<any, number> = {};
|
||||
let containers: Record<string, IContainer> = {};
|
||||
|
||||
let volume = document.createElement("span");
|
||||
volume.innerText = "";
|
||||
@ -35,6 +40,7 @@ export class Containers {
|
||||
volumeSlider.style.visibility = "hidden";
|
||||
volumeSlider.id = "containers_volumeSlider"
|
||||
|
||||
// When volume slider is changed
|
||||
function onChange() {
|
||||
volume.innerText = volumeSlider.value + " ml ";
|
||||
txt.innerText = "Speichern zum abschließen"
|
||||
@ -52,6 +58,8 @@ export class Containers {
|
||||
let selectIngredient = document.createElement("select");
|
||||
selectIngredient.style.visibility = "hidden";
|
||||
selectIngredient.classList.add("input");
|
||||
|
||||
// When ingredient is changed
|
||||
selectIngredient.onchange = () => {
|
||||
if (selectIngredient.value == "null") {
|
||||
volumeSlider.value = "0";
|
||||
@ -78,27 +86,40 @@ export class Containers {
|
||||
|
||||
let selectContainer = document.createElement("select");
|
||||
selectContainer.classList.add("input");
|
||||
//let containers : IContainer[] = [];
|
||||
selectContainer.onchange = () => {
|
||||
// Enable select ingredient field and set max and min to the slider
|
||||
selectIngredient.style.visibility = "visible";
|
||||
volumeSlider.max = String(containerVolumes[selectContainer.value]);
|
||||
volumeSlider.min = String(0);
|
||||
volumeSlider.value = String(containerVolumes[selectContainer.value] / 2);
|
||||
txt.innerText = "Ingredient des Behälters auswählen";
|
||||
|
||||
// When content of container is filled, preselect the ingredient selector
|
||||
if (containers[selectContainer.value].content) {
|
||||
selectIngredient.value = containers[selectContainer.value].content?._id;
|
||||
let event = new Event('change', {bubbles: true});
|
||||
selectIngredient.dispatchEvent(event);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
selectContainer.append(nonSelect.cloneNode(true));
|
||||
selectContainer.selectedIndex = 0;
|
||||
|
||||
|
||||
WebWebSocketHandler.request(RequestType.CONTAINERS).then((payload) => {
|
||||
for (let container of (payload.data["content"] as IContainer[])) {
|
||||
containerVolumes[container._id] = container.volume;
|
||||
let option = document.createElement("option");
|
||||
option.value = container._id;
|
||||
option.innerText = "Behälter Slot " + container.slot + "[" + (container.content && container.content.name ? container.content.name : "Kein Inhalt") + "]";
|
||||
option.innerText = "Behälter Slot " + (container.slot+1) + "[" + (container.content && container.content.name ? container.content.name : "Kein Inhalt") + "]";
|
||||
selectContainer.append(option);
|
||||
|
||||
containers[container._id] = container;
|
||||
}
|
||||
//containers = payload.data["content"] as IContainer[];
|
||||
});
|
||||
WebWebSocketHandler.request(RequestType.INGREDIENTS).then((payload) => {
|
||||
for (let ingredient of (payload.data["content"] as IIngredient[])) {
|
||||
@ -134,7 +155,14 @@ export class Containers {
|
||||
ingredient: (selectIngredient.value == "null") ? null : selectIngredient.value,
|
||||
filled: volumeSlider.value
|
||||
});
|
||||
WebWebSocketHandler.send(payload).then(() => modal.close());
|
||||
|
||||
WebWebSocketHandler.send(payload).then(() => {
|
||||
selectContainer.value = "-1";
|
||||
selectIngredient.value = "-1";
|
||||
let event = new Event('change', {bubbles: true});
|
||||
selectContainer.dispatchEvent(event);
|
||||
selectIngredient.dispatchEvent(event);
|
||||
});
|
||||
};
|
||||
|
||||
modal.open();
|
||||
|
101
src/web/Fill.ts
Normal file
101
src/web/Fill.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import {WebSocketPayload} from "../WebSocketPayload";
|
||||
import {Modal} from "./Modal";
|
||||
import {WebSocketEvent} from "../WebSocketEvent";
|
||||
import {RequestType} from "../RequestType";
|
||||
import {IJob} from "../database/IJob";
|
||||
import {WebWebSocketHandler} from "./WebWebSocketHandler";
|
||||
|
||||
export class Fill {
|
||||
static onFillEvent(payload: WebSocketPayload) {
|
||||
let modal = new Modal("fill", "Cocktail wird zubereitet");
|
||||
let header = document.createElement("h2");
|
||||
header.innerText = "";
|
||||
|
||||
modal.addContent(header);
|
||||
|
||||
let txt = document.createElement("p");
|
||||
txt.innerHTML = `Der Cocktail wird gerade zubereitet`;
|
||||
txt.id = "main_fillTxt";
|
||||
|
||||
let waterAnimDiv = document.createElement("div");
|
||||
waterAnimDiv.classList.add("water");
|
||||
modal.addContent(txt);
|
||||
|
||||
modal.addContent(waterAnimDiv);
|
||||
|
||||
let seconds = document.createElement("span");
|
||||
seconds.innerText = "60s";
|
||||
seconds.style.marginRight = "3%";
|
||||
|
||||
modal.addContent(seconds);
|
||||
|
||||
let ml = document.createElement("span");
|
||||
ml.innerText = "200ml";
|
||||
modal.addContent(ml);
|
||||
|
||||
modal.addContent(document.createElement("br"));
|
||||
modal.addContent(document.createElement("br"));
|
||||
|
||||
|
||||
let cancelBtn = document.createElement("button");
|
||||
cancelBtn.classList.add("btn", "btn-danger");
|
||||
cancelBtn.innerText = "Abbrechen";
|
||||
cancelBtn.disabled = true;
|
||||
setTimeout(() => {
|
||||
cancelBtn.disabled = false;
|
||||
}, 1000);
|
||||
cancelBtn.onclick = () => {
|
||||
cancelBtn.disabled = true;
|
||||
txt.innerHTML = "Der Vorgang wird abgebrochen...";
|
||||
waterAnimDiv.classList.add("waterCancel");
|
||||
|
||||
WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.CANCEL));
|
||||
};
|
||||
modal.addContent(cancelBtn);
|
||||
|
||||
function riseSlowlyUp(lastNumber: number, number: number) {
|
||||
for (let i = lastNumber; i < number; i++) {
|
||||
setTimeout(() => {
|
||||
ml.innerText = Math.floor(i) + "ml";
|
||||
}, (number - lastNumber / 1000) + i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
modal.open().then(() => {
|
||||
WebWebSocketHandler.request(RequestType.JOB).then((payload) => {
|
||||
let minus = 0;
|
||||
let job = payload.data.content as IJob;
|
||||
ml.innerText = Math.floor((job.completeAmount / job.estimatedTime) * minus) + "ml";
|
||||
waterAnimDiv.style.setProperty("--fillTime", job.estimatedTime + "s");
|
||||
waterAnimDiv.style.backgroundImage = `url("/images/${job.drink._id}.png")`;
|
||||
header.innerText = job.drink.name;
|
||||
seconds.innerText = Math.floor(job.estimatedTime) + "s";
|
||||
|
||||
let last = 0;
|
||||
let interval = setInterval(() => {
|
||||
minus++;
|
||||
if (minus + 1 > (job.estimatedTime as number)) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
seconds.innerText = (Math.floor(job.estimatedTime as number - minus)) + "s";
|
||||
let calc = Math.floor((job.completeAmount / job.estimatedTime) * minus);
|
||||
riseSlowlyUp(last, calc)
|
||||
last = calc;
|
||||
}, 1000);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
txt.innerHTML = "Bitte entnehme den Cocktail";
|
||||
modal.title.innerHTML = "Cocktail fertig gestellt"
|
||||
|
||||
cancelBtn.classList.add("btn-blendout");
|
||||
waterAnimDiv.classList.add("waterFinished");
|
||||
cancelBtn.onclick = () => {
|
||||
modal.close();
|
||||
}
|
||||
}, job.estimatedTime * 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
import {ButtonType} from "./ButtonType";
|
||||
|
||||
export class Modal {
|
||||
get title(): HTMLHeadingElement {
|
||||
return this._title;
|
||||
}
|
||||
|
||||
private static currentModalId: string | undefined = "";
|
||||
|
||||
private _title: string = "iTender";
|
||||
private _title: HTMLHeadingElement;
|
||||
private _id: string = "";
|
||||
private _loader: boolean = false;
|
||||
private _buttons: { type: string, content: string, onclick: Function }[] = [];
|
||||
@ -19,11 +22,10 @@ export class Modal {
|
||||
|
||||
constructor(id, title: string) {
|
||||
this._id = id;
|
||||
this._title = title;
|
||||
|
||||
let t = document.createElement("h1");
|
||||
t.innerText = title;
|
||||
this._elements.push(t);
|
||||
this._title = document.createElement("h1") as HTMLHeadingElement;
|
||||
this._title.innerText = title;
|
||||
this._elements.push(this._title);
|
||||
}
|
||||
|
||||
public static isModalOpen(): boolean {
|
||||
@ -91,6 +93,10 @@ export class Modal {
|
||||
});
|
||||
}
|
||||
|
||||
public setTitle(title) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param elements
|
||||
* @param id
|
||||
|
@ -7,7 +7,7 @@ import {WebHandler} from "./WebHandler";
|
||||
import {Setup} from "./Setup";
|
||||
import {Pane} from "./Pane";
|
||||
import {RequestType} from "../RequestType";
|
||||
import {IJob} from "../database/IJob";
|
||||
import {Fill} from "./Fill";
|
||||
|
||||
export class WebWebSocketHandler {
|
||||
private static socket: WebSocket;
|
||||
@ -29,8 +29,7 @@ export class WebWebSocketHandler {
|
||||
}
|
||||
|
||||
public static registerForEvent(event: WebSocketEvent, fn: (payload: WebSocketPayload) => void) {
|
||||
for( let e of WebWebSocketHandler.eventRegister )
|
||||
{
|
||||
for (let e of WebWebSocketHandler.eventRegister) {
|
||||
if (e.fn == fn) {
|
||||
console.log("Event fn already registered");
|
||||
return;
|
||||
@ -55,11 +54,27 @@ export class WebWebSocketHandler {
|
||||
|
||||
switch (payload.event) {
|
||||
case WebSocketEvent.CONFIG: {
|
||||
// Incoming WebSocketStatus
|
||||
Setup.onConfigUpdate(payload);
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketEvent.DRINKS: {
|
||||
WebHandler.onDrinkUpdate(payload);
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketEvent.ERROR: {
|
||||
let modal = new Modal("error", "Aww crap!");
|
||||
let txt = document.createElement("p");
|
||||
txt.innerHTML = payload.data;
|
||||
modal.addContent(txt);
|
||||
modal.addContent(document.createElement("br"));
|
||||
modal.addButton(ButtonType.PRIMARY, "Schließen", () => modal.close() );
|
||||
modal.open();
|
||||
break;
|
||||
}
|
||||
|
||||
// Incoming WebSocketStatus
|
||||
case WebSocketEvent.STATUS: {
|
||||
let statusElement = document.getElementById("status");
|
||||
if (statusElement)
|
||||
@ -90,19 +105,16 @@ export class WebWebSocketHandler {
|
||||
case iTenderStatus.DOWNLOADING: {
|
||||
let modal = new Modal("download", "Aktualisieren");
|
||||
let txt = document.createElement("p");
|
||||
txt.innerHTML = `Einen Augenblick bitte<br>iTender aktualisiert die Getränke vom Server.`;
|
||||
txt.innerHTML = `Einen Augenblick bitte<br>iTender aktualisiert die Getränke vom Server...`;
|
||||
modal.addContent(txt);
|
||||
modal.loader = true;
|
||||
modal.open();
|
||||
break;
|
||||
}
|
||||
case iTenderStatus.REFRESHING: {
|
||||
/* let modal = new Modal("refreshing", "Aktualisieren...");
|
||||
let txt = document.createElement("p");
|
||||
txt.innerHTML = `Einen Augenblick bitte<br>iTender aktualisiert die Getränke...`;
|
||||
modal.addContent(txt);
|
||||
modal.loader = true;
|
||||
modal.open();*/
|
||||
setTimeout( () => {
|
||||
if( txt )
|
||||
{
|
||||
txt.innerHTML = txt.innerHTML + "<br><br>Der Vorgang dauert länger als gewöhnlich.<br>Überprüfe deine Internetverbindung!"
|
||||
}
|
||||
}, 1000 * 15 )
|
||||
break;
|
||||
}
|
||||
case iTenderStatus.SETUP: {
|
||||
@ -111,111 +123,16 @@ export class WebWebSocketHandler {
|
||||
break;
|
||||
}
|
||||
case iTenderStatus.FILLING: {
|
||||
|
||||
let modal = new Modal("fill", "Getränk wird ausgegeben");
|
||||
let header = document.createElement("h2");
|
||||
header.innerText = "";
|
||||
|
||||
modal.addContent(header);
|
||||
|
||||
let txt = document.createElement("p");
|
||||
txt.innerHTML = `Dein Cocktail wird gerade zubereitet`;
|
||||
txt.id = "main_fillTxt";
|
||||
|
||||
let waterAnimDiv = document.createElement("div");
|
||||
waterAnimDiv.classList.add("water");
|
||||
modal.addContent(txt);
|
||||
|
||||
modal.addContent(waterAnimDiv);
|
||||
|
||||
let seconds = document.createElement("span");
|
||||
seconds.innerText = "60s";
|
||||
seconds.style.marginRight = "3%";
|
||||
|
||||
modal.addContent(seconds);
|
||||
|
||||
let ml = document.createElement("span");
|
||||
ml.innerText = "200ml";
|
||||
modal.addContent(ml);
|
||||
|
||||
modal.addContent(document.createElement("br"));
|
||||
modal.addContent(document.createElement("br"));
|
||||
|
||||
|
||||
let cancelBtn = document.createElement("button");
|
||||
cancelBtn.classList.add("btn", "btn-danger");
|
||||
cancelBtn.innerText = "Abbrechen";
|
||||
cancelBtn.disabled = true;
|
||||
setTimeout(() => {
|
||||
cancelBtn.disabled = false;
|
||||
}, 1000);
|
||||
cancelBtn.onclick = () => {
|
||||
cancelBtn.disabled = true;
|
||||
txt.innerHTML = "Der Vorgang wird abgebrochen...";
|
||||
waterAnimDiv.classList.add("waterCancel");
|
||||
|
||||
WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.CANCEL));
|
||||
};
|
||||
modal.addContent(cancelBtn);
|
||||
|
||||
function riseSlowlyUp(lastNumber:number, number: number) {
|
||||
for (let i = lastNumber; i < number; i++) {
|
||||
setTimeout(() => {
|
||||
ml.innerText = i + "ml";
|
||||
}, (number-lastNumber/1000)+i*4);
|
||||
}
|
||||
}
|
||||
|
||||
modal.open().then(() => {
|
||||
WebWebSocketHandler.request(RequestType.JOB).then((payload) => {
|
||||
let minus = 0;
|
||||
let job = payload.data.content as IJob;
|
||||
ml.innerText = Math.floor((job.completeAmount / job.estimatedTime) * minus) + "ml";
|
||||
waterAnimDiv.style.setProperty("--fillTime", job.estimatedTime + "s");
|
||||
waterAnimDiv.style.backgroundImage = `url("/images/${job.drink._id}.png")`;
|
||||
header.innerText = job.drink.name;
|
||||
seconds.innerText = job.estimatedTime + "s";
|
||||
|
||||
let last = 0;
|
||||
let interval = setInterval(() => {
|
||||
minus++;
|
||||
if (minus + 1 > (job.estimatedTime as number)) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
seconds.innerText = (Math.floor(job.estimatedTime as number - minus)) + "s";
|
||||
let calc = Math.floor((job.completeAmount / job.estimatedTime) * minus);
|
||||
riseSlowlyUp(last, calc)
|
||||
last = calc;
|
||||
//ml.innerText = + "ml";
|
||||
}, 1000);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
txt.innerHTML = "Bitte entnehme den Cocktail!";
|
||||
/*cancelBtn.classList.add("btn-primary");
|
||||
cancelBtn.classList.remove("btn-danger");
|
||||
cancelBtn.innerText = "Schließen";*/
|
||||
cancelBtn.classList.add("btn-blendout");
|
||||
waterAnimDiv.classList.add("waterFinished");
|
||||
cancelBtn.onclick = () => {
|
||||
modal.close();
|
||||
}
|
||||
//setTimeout(() => modal.close(), 1000 * 4.5);
|
||||
}, job.estimatedTime * 1000);
|
||||
});
|
||||
});
|
||||
Fill.onFillEvent(payload);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
console.log("Unknown to handle " + status);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WebSocketEvent.DRINKS: {
|
||||
WebHandler.onDrinkUpdate(payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,12 +140,8 @@ export class WebWebSocketHandler {
|
||||
private onOpen(event) {
|
||||
console.log("[WS] Connected", event);
|
||||
|
||||
/*let connectionElement = document.getElementById("right");
|
||||
if (connectionElement) {
|
||||
connectionElement.innerText = "Verbunden";
|
||||
connectionElement.style.color = "green";
|
||||
}*/
|
||||
|
||||
const blockPanel = document.getElementById("blockPanel") as HTMLDivElement;
|
||||
blockPanel.classList.add("opacityOutDisplayNone");
|
||||
}
|
||||
|
||||
private onClose(event) {
|
||||
|
Reference in New Issue
Block a user