Files
P-Touch-Web/app/static/mobile.js
T

129 lines
4.6 KiB
JavaScript

const fields = {
text: document.getElementById("mobileText"),
tape: document.getElementById("mobileTape"),
margin: document.getElementById("mobileMargin"),
font: document.getElementById("mobileFont"),
copies: document.getElementById("mobileCopies"),
align: document.getElementById("mobileAlign"),
bold: document.getElementById("mobileBold"),
frame: document.getElementById("mobileFrame"),
tapeInfo: document.getElementById("mobileTapeInfo"),
tapeInfoType: document.getElementById("mobileTapeInfoType"),
tapeBgSwatch: document.getElementById("mobileTapeBgSwatch"),
tapeBgText: document.getElementById("mobileTapeBgText"),
tapeTextSwatch: document.getElementById("mobileTapeTextSwatch"),
tapeTextText: document.getElementById("mobileTapeTextText"),
preview: document.getElementById("mobilePreview"),
message: document.getElementById("mobileMessage"),
};
function estimateTextLengthMm(text, fontSize, margin, frame) {
const lines = String(text || " ").split("\n");
const longest = lines.reduce((max, line) => Math.max(max, line.length), 0);
const textWidth = Math.max(8, longest * fontSize * 0.62);
return Math.min(300, Math.max(20, Math.ceil(textWidth + margin * 2 + (frame ? 4 : 0))));
}
function setMessage(text, type = "") {
fields.message.textContent = text;
fields.message.className = `message ${type}`;
}
function updateTapeInfo(info) {
fields.tapeInfo.hidden = !info;
if (!info) return;
const media = info.mediaType?.name || "Unbekannt";
const bg = info.tapeColor || { name: "Unbekannt", css: "#d1d5db" };
const text = info.textColor || { name: "Unbekannt", css: "#111111" };
fields.tapeInfoType.textContent = `${info.width} mm · ${media}${info.mediaType?.code ? ` (${info.mediaType.code})` : ""}`;
fields.tapeBgText.textContent = `${bg.name}${bg.code ? ` (${bg.code})` : ""}`;
fields.tapeBgSwatch.style.background = bg.css;
fields.tapeTextText.textContent = `${text.name}${text.code ? ` (${text.code})` : ""}`;
fields.tapeTextSwatch.style.background = text.css;
}
function mobileDesign() {
const tapeWidth = Number(fields.tape.value);
const margin = Number(fields.margin.value);
const text = fields.text.value.trim() || " ";
const fontSize = Number(fields.font.value);
const length = estimateTextLengthMm(text, fontSize, margin, fields.frame.checked);
const objects = [];
if (fields.frame.checked) {
objects.push({
id: "frame",
type: "shape",
x: margin,
y: margin,
w: Math.max(2, length - margin * 2),
h: Math.max(2, tapeWidth - margin * 2),
lineMm: 0.25,
fill: false,
});
}
objects.push({
id: "text",
type: "text",
x: margin + (fields.frame.checked ? 1 : 0),
y: margin,
w: Math.max(2, length - margin * 2 - (fields.frame.checked ? 2 : 0)),
h: Math.max(2, tapeWidth - margin * 2),
text,
fontSizeMm: fontSize,
bold: fields.bold.checked,
align: fields.align.value,
valign: "middle",
});
return {
tapeWidthMm: tapeWidth,
lengthMm: length,
autoLength: true,
marginMm: margin,
orientation: "landscape",
cutMode: "auto",
halfcut: "off",
objects,
};
}
async function send(url) {
setMessage("Rendere Etikett...");
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ design: mobileDesign(), copies: Number(fields.copies.value) || 1 }),
});
const payload = await response.json();
if (!payload.ok) {
setMessage(payload.error || "Fehler", "error");
return;
}
fields.preview.src = `${payload.image}?t=${Date.now()}`;
setMessage(payload.message || "Vorschau erstellt.", "success");
}
document.getElementById("mobilePreviewBtn").addEventListener("click", () => send("/api/preview"));
document.getElementById("mobilePrintBtn").addEventListener("click", () => send("/api/print"));
document.getElementById("mobileDetect").addEventListener("click", async () => {
setMessage("Erkenne Band...");
const response = await fetch("/api/tape-info");
const payload = await response.json();
if (!payload.ok) {
setMessage(payload.error || "Band konnte nicht erkannt werden.", "error");
return;
}
fields.tape.value = String(payload.width);
updateTapeInfo(payload);
const bg = payload.tapeColor?.name ? `, ${payload.tapeColor.name}` : "";
const text = payload.textColor?.name ? ` / ${payload.textColor.name}` : "";
setMessage(`Band erkannt: ${payload.width} mm${bg}${text}`, "success");
});
["text", "font", "margin", "frame", "bold", "align", "tape"].forEach((name) => {
fields[name].addEventListener("input", () => {
mobileDesign();
});
});
mobileDesign();