heissepreise/site/misc.js

240 lines
7.6 KiB
JavaScript

const alasql = require("alasql");
const UNITS = {
"stk.": { unit: "stk", factor: 1 },
stück: { unit: "stk", factor: 1 },
blatt: { unit: "stk", factor: 1 },
paar: { unit: "stk", factor: 1 },
stk: { unit: "stk", factor: 1 },
st: { unit: "stk", factor: 1 },
teebeutel: { unit: "stk", factor: 1 },
tücher: { unit: "stk", factor: 1 },
rollen: { unit: "stk", factor: 1 },
tabs: { unit: "stk", factor: 1 },
mm: { unit: "cm", factor: 0.1 },
cm: { unit: "cm", factor: 1 },
zentimeter: { unit: "cm", factor: 1 },
m: { unit: "cm", factor: 100 },
meter: { unit: "cm", factor: 100 },
g: { unit: "g", factor: 1 },
gramm: { unit: "g", factor: 1 },
dag: { unit: "g", factor: 10 },
kg: { unit: "g", factor: 1000 },
kilogramm: { unit: "g", factor: 1000 },
ml: { unit: "ml", factor: 1 },
milliliter: { unit: "ml", factor: 1 },
dl: { unit: "ml", factor: 10 },
cl: { unit: "ml", factor: 100 },
l: { unit: "ml", factor: 1000 },
liter: { unit: "ml", factor: 1000 },
wg: { unit: "wg", factor: 1 },
};
if (typeof window !== "undefined") {
function setupLiveEdit() {
if (window.location.host.indexOf("localhost") < 0 && window.location.host.indexOf("127.0.0.1") < 0) return;
var script = document.createElement("script");
script.type = "text/javascript";
script.onload = () => {
let lastChangeTimestamp = null;
let socket = io({ transports: ["websocket"] });
socket.on("message", (timestamp) => {
if (lastChangeTimestamp != timestamp) {
setTimeout(() => location.reload(), 100);
lastChangeTimestamp = timestamp;
}
});
};
script.src = "js/socket.io.js";
document.body.appendChild(script);
}
setupLiveEdit();
}
exports.isMobile = () => {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
};
exports.today = () => {
const currentDate = new Date();
const year = currentDate.getFullYear();
const month = String(currentDate.getMonth() + 1).padStart(2, "0");
const day = String(currentDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
};
exports.fetchJSON = async (url) => {
const response = await fetch(url);
return await response.json();
};
exports.downloadJSON = (filename, content) => {
const json = JSON.stringify(content, null, 2);
const blob = new Blob([json], { type: "text/plain" });
const element = document.createElement("a");
element.href = URL.createObjectURL(blob);
element.download = filename;
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
URL.revokeObjectURL(element.href);
};
exports.dom = (element, innerHTML) => {
const el = document.createElement(element);
el.innerHTML = innerHTML;
return el;
};
exports.getQueryParameter = (name) => {
const url = new URL(window.location.href);
const params = url.searchParams.getAll(name);
return params.length > 1 ? params : params?.[0];
};
exports.getBooleanAttribute = (element, name) => {
return element.hasAttribute(name) && (element.getAttribute(name).length == 0 || element.getAttribute(name) === "true");
};
exports.parseNumber = (value, defaultValue) => {
try {
return Number.parseFloat(value);
} catch (e) {
return defaultValue;
}
};
exports.queryItems = (query, items, exactWord) => {
if (query.charAt(0) == "!") {
query = query.substring(1);
try {
return alasql("select * from ? where " + query, [items]);
} catch (e) {
console.error(e);
return [];
}
}
let tokens = query.split(/\s+/).map((token) => token.toLowerCase().replace(",", "."));
// Find quantity/unit query
let newTokens = [];
let unitQueries = [];
const operators = ["<", "<=", ">", ">="];
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
let unit = UNITS[token];
if (unit && i > 0 && /^\d+(\.\d+)?$/.test(tokens[i - 1])) {
newTokens.pop();
let operator = "=";
if (i > 1 && operators.includes(tokens[i - 2])) {
newTokens.pop();
operator = tokens[i - 2];
}
unitQueries.push({
operator,
quantity: Number.parseFloat(tokens[i - 1]) * unit.factor,
unit: unit.unit,
});
} else {
newTokens.push(token);
}
}
tokens = newTokens;
let hits = [];
for (const item of items) {
let allFound = true;
for (let token of tokens) {
if (token.length === 0) continue;
let not = false;
if (token.startsWith("-") && token.length > 1) {
not = true;
token = token.substring(1);
}
const index = item.search.indexOf(token);
if ((!not && index < 0) || (not && index >= 0)) {
allFound = false;
break;
}
if (exactWord) {
if (index > 0 && item.search.charAt(index - 1) != " " && item.search.charAt(index - 1) != "-") {
allFound = false;
break;
}
if (index + token.length < item.search.length && item.search.charAt(index + token.length) != " ") {
allFound = false;
break;
}
}
}
if (allFound) {
let allUnitsMatched = true;
for (const query of unitQueries) {
if (query.unit != item.unit) {
allUnitsMatched = false;
break;
}
if (query.operator == "=" && !(item.quantity == query.quantity)) {
allUnitsMatched = false;
break;
}
if (query.operator == "<" && !(item.quantity < query.quantity)) {
allUnitsMatched = false;
break;
}
if (query.operator == "<=" && !(item.quantity <= query.quantity)) {
allUnitsMatched = false;
break;
}
if (query.operator == ">" && !(item.quantity > query.quantity)) {
allUnitsMatched = false;
break;
}
if (query.operator == ">=" && !(item.quantity >= query.quantity)) {
allUnitsMatched = false;
break;
}
}
if (allUnitsMatched) hits.push(item);
}
}
return hits;
};
exports.onVisibleOnce = (target, callback) => {
let isTargetVisible = false;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.target === target && entry.isIntersecting) {
if (!isTargetVisible) {
isTargetVisible = true;
callback();
}
observer.unobserve(target);
}
});
});
observer.observe(target);
};
exports.log = (message) => {
const now = new Date();
const hours = String(now.getHours()).padStart(2, "0");
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
console.log(`${hours}:${minutes}:${seconds}: ${message}`);
};
exports.deltaTime = (start) => {
return (performance.now() - start) / 1000;
};