Grotti 2.2.6: Wand-Vorschau, dichterer 3D-Pfad, ASCII-Dateinamen.

Kacheln zeigen Moonraker-Thumbnails; Toolpath-Thinning behält ganze Schichten; Nicht-ASCII-Namen vermeiden 10115 beim Senden.
This commit is contained in:
Dominic Gundel committed 2026-10-17 11:22:43 +02:00
1 parent 7da895bbcd
commit b277ca48aa
16 files changed
+302 -50

No files matched your search

+41 -5
View File
@@ -86,7 +86,7 @@
{% endblock %}
{% block script %}
<script src="{{ url_for('static', filename='three.min.js') }}?v=1"></script>
<script src="{{ url_for('static', filename='gcode-viewer.js') }}?v=8"></script>
<script src="{{ url_for('static', filename='gcode-viewer.js') }}?v=10"></script>
<script>
const labels = STATE_LABELS;
const rank = { printing: 0, paused: 1, error: 2, heating: 3, complete: 4, cancelled: 5, standby: 6, offline: 7 };
@@ -490,7 +490,14 @@ function buildCard(printer) {
<div data-role="bar"></div>
<div class="stats" data-role="stats"></div>
<div data-role="temps"></div>
<div class="job-line" data-role="jobline">${icon("cube")}<span class="name" data-role="job"></span><span class="swatches" data-role="swatches"></span></div>
<div class="job-line" data-role="jobline">
<img class="job-thumb" data-role="thumb" alt="" hidden>
<span class="job-ico" data-role="jobico">${icon("cube")}</span>
<div class="job-meta">
<span class="name" data-role="job"></span>
<span class="swatches" data-role="swatches"></span>
</div>
</div>
<div data-role="flow"></div>
<div data-role="strips"></div>
<div class="card-actions" data-role="controls"></div>
@@ -551,7 +558,36 @@ function patchCard(article, printer) {
setHtml(role("stats"), statsHtml(printer, state));
setHtml(role("temps"), tempbarsHtml(printer, state));
const jobline = role("jobline");
if (jobline) jobline.hidden = !jobLineVisible(printer, state);
const jobVisible = jobLineVisible(printer, state);
const hasThumb = !!(jobVisible && printer.preview);
if (jobline) {
jobline.hidden = !jobVisible;
jobline.classList.toggle("has-thumb", hasThumb);
}
const thumb = role("thumb");
const jobico = role("jobico");
if (thumb) {
if (hasThumb) {
const next = withToken(printer.preview);
if (thumb.dataset.srcKey !== next) {
thumb.dataset.srcKey = next;
thumb.src = next;
}
thumb.hidden = false;
thumb.onerror = () => {
thumb.hidden = true;
thumb.dataset.srcKey = "";
if (jobline) jobline.classList.remove("has-thumb");
if (jobico) jobico.hidden = false;
};
if (jobico) jobico.hidden = true;
} else {
thumb.hidden = true;
thumb.removeAttribute("src");
thumb.dataset.srcKey = "";
if (jobico) jobico.hidden = false;
}
}
const job = role("job");
if (job) {
job.textContent = jobName(printer.filename) || "";
@@ -762,10 +798,10 @@ async function syncDeskViewer(printer) {
}
try {
let data = toolpathCache.get(file.id);
const needLoad = !data || data.version !== 5 || deskViewerFileId !== file.id;
const needLoad = !data || data.version !== 8 || deskViewerFileId !== file.id;
if (needLoad) {
if (caption) caption.textContent = "wird gelesen …";
data = await api("/dateien/" + file.id + "/pfad");
data = await api("/dateien/" + file.id + "/pfad?tp=8");
toolpathCache.set(file.id, data);
const sameFile = deskViewerFileId === file.id;
deskViewer.setPath(data, { keepView: sameFile });