Update v1.0.1
Took 1 hour 27 minutes
6
ToDo.md
Normal file
@ -0,0 +1,6 @@
|
||||
# ToDo
|
||||
|
||||
- [ ] Behälter unten rechts anzeigen
|
||||
- [ ] Status für Netzwerk oben neben Uhrzeit
|
||||
- [ ] Fix Fehler wenn keine Getränke hinzugefügt worden sind
|
||||
-
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "itender",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.1",
|
||||
"private": true,
|
||||
"author": "Tobias Hopp <tobi@gaminggeneration.de>",
|
||||
"license": "UNLICENSED",
|
||||
@ -23,6 +23,7 @@
|
||||
"@types/rpi-gpio": "^2.1.1",
|
||||
"@types/rpi-ws281x-native": "^1.0.0",
|
||||
"axios": "^1.2.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"debug": "^4.3.4",
|
||||
"express": "~4.16.1",
|
||||
|
BIN
public/images/6372bf5911e5032258e52b5d.png
Normal file
After Width: | Height: | Size: 1020 KiB |
BIN
public/images/637e780e92e2eb68eb272dbb.png
Normal file
After Width: | Height: | Size: 611 KiB |
BIN
public/images/637e782a92e2eb68eb272dc7.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
public/images/637e785c92e2eb68eb272dd9.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
public/images/637e789092e2eb68eb272de7.png
Normal file
After Width: | Height: | Size: 313 KiB |
BIN
public/images/637e78d392e2eb68eb272e0c.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public/images/637e790816d571f976c7a7ae.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
public/images/637e790816d571f976c7a7b2.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
public/images/637e790816d571f976c7a7b8.png
Normal file
After Width: | Height: | Size: 611 KiB |
BIN
public/images/637e790816d571f976c7a7bd.png
Normal file
After Width: | Height: | Size: 313 KiB |
BIN
public/images/637e790816d571f976c7a7c3.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
public/images/637e790992e2eb68eb272e2d.png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
public/images/637e793d92e2eb68eb272e3e.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
public/images/637e795f92e2eb68eb272e4a.png
Normal file
After Width: | Height: | Size: 462 KiB |
BIN
public/images/637e798b92e2eb68eb272e5a.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
public/images/637e79ea92e2eb68eb272e75.png
Normal file
After Width: | Height: | Size: 116 KiB |
BIN
public/images/637e7a1f92e2eb68eb272e8a.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
public/images/637e7c7b92e2eb68eb272e9c.png
Normal file
After Width: | Height: | Size: 817 KiB |
BIN
public/images/637e7cd392e2eb68eb272eb1.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/637e7d0492e2eb68eb272ec2.png
Normal file
After Width: | Height: | Size: 353 KiB |
BIN
public/images/637e7f175340730a377d606a.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
public/images/637e7f485340730a377d621e.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
public/images/637e7f955340730a377d6225.png
Normal file
After Width: | Height: | Size: 640 KiB |
BIN
public/images/637e7ff35340730a377d63a4.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
public/images/637e80175340730a377d63ac.png
Normal file
After Width: | Height: | Size: 370 KiB |
BIN
public/images/637e802d5340730a377d63b5.png
Normal file
After Width: | Height: | Size: 921 KiB |
BIN
public/images/637e804f5340730a377d63bf.png
Normal file
After Width: | Height: | Size: 938 KiB |
BIN
public/images/637e807d5340730a377d640d.png
Normal file
After Width: | Height: | Size: 706 KiB |
BIN
public/images/637e80a35340730a377d6417.png
Normal file
After Width: | Height: | Size: 688 KiB |
BIN
public/images/637e80c05340730a377d641f.png
Normal file
After Width: | Height: | Size: 982 KiB |
BIN
public/images/637e907619ee137bb0a010ed.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
public/images/637e907619ee137bb0a010f2.png
Normal file
After Width: | Height: | Size: 353 KiB |
BIN
public/images/637e907619ee137bb0a010fc.png
Normal file
After Width: | Height: | Size: 640 KiB |
BIN
public/images/637e907619ee137bb0a01100.png
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
public/images/637e907619ee137bb0a01107.png
Normal file
After Width: | Height: | Size: 817 KiB |
BIN
public/images/637e907619ee137bb0a0110d.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
public/images/637e907619ee137bb0a01111.png
Normal file
After Width: | Height: | Size: 462 KiB |
BIN
public/images/637e907619ee137bb0a01116.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
public/images/637e907619ee137bb0a01136.png
Normal file
After Width: | Height: | Size: 167 KiB |
BIN
public/images/637e907619ee137bb0a01148.png
Normal file
After Width: | Height: | Size: 938 KiB |
BIN
public/images/637e907619ee137bb0a0114d.png
Normal file
After Width: | Height: | Size: 982 KiB |
BIN
public/images/637e907619ee137bb0a01151.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
public/images/637e907619ee137bb0a01159.png
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
public/images/637e907619ee137bb0a01160.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
public/images/637e907619ee137bb0a01165.png
Normal file
After Width: | Height: | Size: 688 KiB |
BIN
public/images/637e907619ee137bb0a0116a.png
Normal file
After Width: | Height: | Size: 706 KiB |
BIN
public/images/637e907619ee137bb0a0116f.png
Normal file
After Width: | Height: | Size: 370 KiB |
BIN
public/images/637e907619ee137bb0a01173.png
Normal file
After Width: | Height: | Size: 921 KiB |
BIN
public/images/637e907619ee137bb0a01178.png
Normal file
After Width: | Height: | Size: 116 KiB |
@ -12,6 +12,19 @@
|
||||
|
||||
}
|
||||
|
||||
.btn-blendout {
|
||||
animation: 1s blendOut forwards;
|
||||
}
|
||||
|
||||
@keyframes blendOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.inputGroup {
|
||||
margin-bottom: 1.5%;
|
||||
}
|
||||
@ -107,6 +120,7 @@ label {
|
||||
margin-right: 1%;
|
||||
margin-bottom: 2%;
|
||||
border: 0;
|
||||
background-color: #e9e9ed;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ body {
|
||||
top: -90%;
|
||||
left: -50%;
|
||||
border-radius: 40%;
|
||||
animation: animWater 8s linear infinite, animFillIn var(--fillTime) linear forwards;
|
||||
animation: animWater 7s linear infinite, animFillIn var(--fillTime) linear forwards;
|
||||
}
|
||||
|
||||
.water::after {
|
||||
@ -100,7 +100,7 @@ body {
|
||||
top: -100%;
|
||||
left: -52%;
|
||||
border-radius: 40%;
|
||||
animation: animWater 8s linear infinite, animFillIn var(--fillTime) linear forwards;
|
||||
animation: animWater 7s linear infinite, animFillIn var(--fillTime) linear forwards;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@ -109,6 +109,11 @@ body {
|
||||
transition: background-color 1s;
|
||||
}
|
||||
|
||||
.waterFinished {
|
||||
background-color: green;
|
||||
transition: background-color 2s;
|
||||
}
|
||||
|
||||
@keyframes animFillIn {
|
||||
0% {
|
||||
top: -100%;
|
||||
|
@ -63,12 +63,12 @@
|
||||
|
||||
|
||||
.modalBlendIn {
|
||||
animation: modalBlendIn 0.5s ease;
|
||||
animation: modalBlendIn 0.5s forwards;
|
||||
}
|
||||
|
||||
|
||||
.modalBlendOut {
|
||||
animation: modalBlendOut 0.8s ease;
|
||||
animation: modalBlendOut 0.8s forwards;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ html * {
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-ms-user-select: none; /* IE 10 and IE 11 */
|
||||
user-select: none; /* Standard syntax */
|
||||
cursor: none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +55,12 @@ h1 {
|
||||
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.45em;
|
||||
font-weight: 500;
|
||||
margin-bottom: 2%;
|
||||
|
||||
}
|
||||
|
||||
#overlay {
|
||||
color: white;
|
||||
|
@ -43,4 +43,9 @@ export class Utils {
|
||||
fs.unlinkSync("./public/images/" + id + ".png");
|
||||
}
|
||||
|
||||
static checkForImage( id )
|
||||
{
|
||||
return fs.existsSync("./public/images/" + id + ".png");
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import {WebSocketEvent} from "./WebSocketEvent";
|
||||
import {Buffer} from "buffer";
|
||||
|
||||
export class WebSocketPayload {
|
||||
set event(value: WebSocketEvent) {
|
||||
@ -37,7 +38,8 @@ export class WebSocketPayload {
|
||||
}
|
||||
|
||||
public static parseFromBase64Json(json: string): WebSocketPayload | null {
|
||||
json = (typeof window != 'undefined') ? atob(json) : Buffer.from(json, "base64").toString();
|
||||
//json = (typeof window != 'undefined') ? atob(json).toString() : Buffer.from(json, "base64").toString("utf-8");
|
||||
json = Buffer.from(json, "base64").toString("utf-8");
|
||||
let rawPayload: { event: string, error: boolean, data: any };
|
||||
try {
|
||||
rawPayload = JSON.parse(json);
|
||||
@ -55,6 +57,7 @@ export class WebSocketPayload {
|
||||
*/
|
||||
public toString(): string {
|
||||
let json = JSON.stringify({"event": this._event, status: this._error, data: this._data});
|
||||
|
||||
json = ((typeof window != 'undefined') ? btoa(json) : Buffer.from(json).toString("base64"));
|
||||
return json;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import Ingredient from "./database/Ingredient";
|
||||
import {clearInterval} from "timers";
|
||||
import {RejectReason} from "./RejectReason";
|
||||
import {Settings} from "./Settings";
|
||||
import GPIO from "rpi-gpio";
|
||||
import axios from "axios";
|
||||
|
||||
const log = debug("itender:station");
|
||||
@ -76,12 +75,14 @@ export class iTender {
|
||||
const job = new Job();
|
||||
|
||||
let amounts: { ingredient: IIngredient, amount: number, container?: IContainer }[] = [];
|
||||
job.completeAmount = 0;
|
||||
if (data.amounts) {
|
||||
for (let x of data.amounts) {
|
||||
let ingredient = await Ingredient.findById(x.ingredient);
|
||||
if (!ingredient) continue;
|
||||
|
||||
amounts.push({ingredient: ingredient, amount: x.amount});
|
||||
job.completeAmount+= x.amount;
|
||||
}
|
||||
} else if (data.amount) {
|
||||
let sum = 0;
|
||||
@ -93,17 +94,19 @@ export class iTender {
|
||||
|
||||
for (let x of (drink.ingredients as { type: IIngredient, amount: number }[])) {
|
||||
amounts.push({ingredient: x.type, amount: x.amount * factor})
|
||||
job.completeAmount+= x.amount;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
for (let x of (drink.ingredients as { type: IIngredient, amount: number }[])) {
|
||||
amounts.push({ingredient: x.type, amount: x.amount});
|
||||
job.completeAmount+= x.amount;
|
||||
}
|
||||
}
|
||||
|
||||
job.estimatedTime = 0;
|
||||
let tolerance = 5;
|
||||
let tolerance = 3;
|
||||
for (let x of amounts) {
|
||||
let c = await Container.findOne({$and: [{enabled: true}, {filled: {$gt: x.amount + tolerance}}]});
|
||||
if (!c) {
|
||||
@ -140,15 +143,15 @@ export class iTender {
|
||||
let timers: NodeJS.Timeout[] = [];
|
||||
for (let x of job.amounts) {
|
||||
// Start pump here
|
||||
await GPIO.setup(x.container.pumpPin, GPIO.DIR_OUT);
|
||||
await GPIO.write(x.container.pumpPin, true);
|
||||
//await GPIO.setup(x.container.pumpPin, GPIO.DIR_OUT);
|
||||
//await GPIO.write(x.container.pumpPin, true);
|
||||
|
||||
let waitTime = (Settings.get("secondsPer100ml") as number) / 100 * x.amount * 1000;
|
||||
mixLog(`Starting output of pump ${x.container.pumpPin}`);
|
||||
//mixLog(x.ingredient + " takes " + (waitTime / 1000) + "s for " + x.amount + "ml");
|
||||
let timer = setTimeout(() => {
|
||||
// Stop pump here
|
||||
GPIO.write(x.container.pumpPin, false);
|
||||
//GPIO.write(x.container.pumpPin, false);
|
||||
|
||||
// Remove from list of timers
|
||||
let arr: NodeJS.Timer[] = [];
|
||||
@ -178,7 +181,7 @@ export class iTender {
|
||||
}
|
||||
|
||||
static cancelFill() {
|
||||
if (!this._currentJob)
|
||||
if (!this._currentJob || this.status != iTenderStatus.FILLING)
|
||||
return;
|
||||
clearInterval(this._jobCheckInterval);
|
||||
this._currentJob.successful = false;
|
||||
@ -189,7 +192,7 @@ export class iTender {
|
||||
for (let x of this._currentJob.amounts) {
|
||||
// stop pump pin
|
||||
//x.container.pumpPin
|
||||
GPIO.write(x.container.pumpPin, false);
|
||||
//GPIO.write(x.container.pumpPin, false);
|
||||
}
|
||||
|
||||
iTender.setStatus(iTenderStatus.READY);
|
||||
@ -235,7 +238,6 @@ export class iTender {
|
||||
}
|
||||
|
||||
static refreshDrinks(): Promise<void> {
|
||||
this.setStatus(iTenderStatus.REFRESHING);
|
||||
log("Refreshing drinks...");
|
||||
return new Promise(async resolve => {
|
||||
this._drinks = [];
|
||||
@ -256,7 +258,6 @@ export class iTender {
|
||||
|
||||
}
|
||||
log("Drinks refreshed!");
|
||||
iTender.setStatus(iTenderStatus.READY);
|
||||
await WebSocketHandler.sendDrinks();
|
||||
resolve();
|
||||
|
||||
@ -305,11 +306,9 @@ export class iTender {
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (!found) {
|
||||
await Ingredient.deleteOne({"_id": local._id});
|
||||
for( let c of (await Container.find( {content: local._id } )) )
|
||||
{
|
||||
for (let c of (await Container.find({content: local._id}))) {
|
||||
c.content = undefined;
|
||||
c.save();
|
||||
}
|
||||
@ -319,16 +318,16 @@ export class iTender {
|
||||
|
||||
|
||||
for (let remote of serverIngredients) {
|
||||
let ingredient = await Ingredient.findOne({name: remote.name});
|
||||
let ingredient = await Ingredient.findById(remote._id);
|
||||
if (!ingredient)
|
||||
ingredient = new Ingredient();
|
||||
|
||||
ingredient._id = remote._id;
|
||||
ingredient.name = remote.name;
|
||||
await ingredient.save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const requestDrinks = await axios.get("https://itender.iif.li/api/drinks");
|
||||
let serverDrinks = requestDrinks.data as IDrink[];
|
||||
log("Got " + serverDrinks.length + " drinks from server");
|
||||
@ -344,8 +343,7 @@ export class iTender {
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (!found) {
|
||||
Utils.deleteImage(local._id);
|
||||
await Drink.deleteOne({"_id": local._id});
|
||||
}
|
||||
@ -354,10 +352,11 @@ export class iTender {
|
||||
|
||||
|
||||
for (let remote of serverDrinks) {
|
||||
let drink = await Drink.findOne({name: remote.name});
|
||||
let drink = await Drink.findById(remote._id);
|
||||
if (!drink)
|
||||
drink = new Drink();
|
||||
|
||||
drink._id = remote._id;
|
||||
drink.name = remote.name;
|
||||
drink.ingredients = remote.ingredients;
|
||||
|
||||
@ -365,11 +364,14 @@ export class iTender {
|
||||
|
||||
|
||||
// Download thumbnail
|
||||
Utils.downloadImage("https://itender.iif.li/images/" + remote._id + ".png", "./public/images/" + drink._id + ".png").then(filepath => {
|
||||
log("Drink " + remote.name + "'s Thumbnail downloaded to " + filepath);
|
||||
}).catch(e => {
|
||||
if (!Utils.checkForImage(remote._id)) {
|
||||
try {
|
||||
await Utils.downloadImage("https://itender.iif.li/images/" + remote._id + ".png", "./public/images/" + drink._id + ".png")
|
||||
log("Drink " + remote.name + "'s Thumbnail downloaded");
|
||||
} catch (e) {
|
||||
log("Drink " + remote.name + " failed to download thumbnail!\n" + e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,6 @@ const wsApp = new WebsocketApp();
|
||||
function init(): Promise<void> {
|
||||
log("Initializing...");
|
||||
return new Promise(async resolve => {
|
||||
iTender.setStatus(iTenderStatus.STARTING);
|
||||
|
||||
setTimeout( async () => {
|
||||
// Network
|
||||
|
@ -40,7 +40,7 @@ export class WebHandler {
|
||||
drinkEle.append(drinkName);
|
||||
|
||||
drinkImg.alt = "Foto von " + drink.name;
|
||||
drinkImg.src = "/images/" + drink.name + ".png";
|
||||
drinkImg.src = "/images/" + drink._id + ".png";
|
||||
drinkName.innerText = drink.name;
|
||||
|
||||
|
||||
|
@ -7,7 +7,6 @@ import {WebHandler} from "./WebHandler";
|
||||
import {Setup} from "./Setup";
|
||||
import {Pane} from "./Pane";
|
||||
import {RequestType} from "../RequestType";
|
||||
import {IDrink} from "../database/IDrink";
|
||||
import {IJob} from "../database/IJob";
|
||||
|
||||
export class WebWebSocketHandler {
|
||||
@ -64,7 +63,8 @@ export class WebWebSocketHandler {
|
||||
case iTenderStatus.READY: {
|
||||
Modal.close("start");
|
||||
Modal.close("setup");
|
||||
Modal.close("fill");
|
||||
//Modal.close("fill");
|
||||
Modal.close("download");
|
||||
if (WebHandler.currentPane != Pane.MENU)
|
||||
WebHandler.openPane(Pane.MAIN);
|
||||
(document.getElementById("menuBtn") as HTMLButtonElement).disabled = false;
|
||||
@ -79,6 +79,15 @@ export class WebWebSocketHandler {
|
||||
modal.open();
|
||||
break;
|
||||
}
|
||||
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.`;
|
||||
modal.addContent(txt);
|
||||
modal.loader = true;
|
||||
modal.open();
|
||||
break;
|
||||
}
|
||||
case iTenderStatus.REFRESHING: {
|
||||
/* let modal = new Modal("refreshing", "Aktualisieren...");
|
||||
let txt = document.createElement("p");
|
||||
@ -111,10 +120,19 @@ export class WebWebSocketHandler {
|
||||
|
||||
modal.addContent(waterAnimDiv);
|
||||
|
||||
let seconds = document.createElement("p");
|
||||
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");
|
||||
@ -132,26 +150,51 @@ export class WebWebSocketHandler {
|
||||
};
|
||||
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.name}.png")`;
|
||||
waterAnimDiv.style.backgroundImage = `url("/images/${job.drink._id}.png")`;
|
||||
header.innerText = job.drink.name;
|
||||
seconds.innerText = job.estimatedTime + "s";
|
||||
let minus = 0;
|
||||
|
||||
let last = 0;
|
||||
let interval = setInterval(() => {
|
||||
minus++;
|
||||
if( minus+1 > (job.estimatedTime as number) )
|
||||
{
|
||||
if (minus + 1 > (job.estimatedTime as number)) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
seconds.innerText = (job.estimatedTime as number - minus) + "s";
|
||||
}, 1000 )
|
||||
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);
|
||||
});
|
||||
});
|
||||
break;
|
||||
@ -258,7 +301,10 @@ export class WebWebSocketHandler {
|
||||
resolve(payload);
|
||||
}
|
||||
});
|
||||
WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.REQUEST, false, {type: type, content: content}));
|
||||
WebWebSocketHandler.send(new WebSocketPayload(WebSocketEvent.REQUEST, false, {
|
||||
type: type,
|
||||
content: content
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ block menu
|
||||
|
||||
block settings
|
||||
// Settings
|
||||
button.btn.btn-primary#settings_refreshDrinks Getränke herunterladen
|
||||
|
||||
block main
|
||||
// Main is build dynamically
|
||||
|
10
yarn.lock
@ -1384,6 +1384,14 @@ buffer@^5.6.0:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
bytes@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||
@ -1960,7 +1968,7 @@ iconv-lite@0.4.23:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
ieee754@^1.1.13:
|
||||
ieee754@^1.1.13, ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|