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:
1 parent
7da895bbcd
commit
b277ca48aa
16 files changed
+302
-50
No files matched your search
+4
-1
@@ -910,7 +910,10 @@ def create_app(cfg):
|
||||
pass
|
||||
data["file_id"] = file_id
|
||||
data["name"] = row["name"]
|
||||
return jsonify(data)
|
||||
data["version"] = TOOLPATH_VERSION
|
||||
resp = jsonify(data)
|
||||
resp.headers["Cache-Control"] = "no-store"
|
||||
return resp
|
||||
|
||||
@app.patch("/api/v1/dateien/<int:file_id>")
|
||||
def file_patch(file_id):
|
||||
|
||||
@@ -10,8 +10,8 @@ window.GrottiGcodeViewer = (function () {
|
||||
const COLOR_OBJ_EX = 0xef4444;
|
||||
const COLOR_OBJ_CUR = 0xfbbf24;
|
||||
const GRID_STEP = 10;
|
||||
// Nur leichte Doppelung — starke Offsets + Punkte wirkten wie Vollkörper mit Löchern
|
||||
const FAT_OFFSETS = [0, -0.22, 0.22];
|
||||
// Keine Parallel-Offsets: bei ausgedünnten Pfaden wirkten sie gesprenkelt
|
||||
const FAT_OFFSETS = [0];
|
||||
|
||||
function create(canvas) {
|
||||
const wrap = document.createElement("div");
|
||||
|
||||
+34
-3
@@ -620,12 +620,44 @@ article.machine.offline:hover { opacity: 1; }
|
||||
.job-line {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.45rem;
|
||||
gap: 0.55rem;
|
||||
min-width: 0;
|
||||
color: var(--muted);
|
||||
font-size: var(--t-sm);
|
||||
padding: 0.45rem 0.5rem;
|
||||
border-radius: 10px;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
.job-thumb {
|
||||
width: 4.5rem;
|
||||
height: 4.5rem;
|
||||
object-fit: contain;
|
||||
border-radius: 9px;
|
||||
border: 1px solid var(--line);
|
||||
background: var(--card-2);
|
||||
flex: none;
|
||||
}
|
||||
.job-thumb[hidden] { display: none; }
|
||||
.job-ico { display: inline-flex; flex: none; color: var(--faint); }
|
||||
.job-ico .ico { width: 1.1rem; height: 1.1rem; }
|
||||
.job-line.has-thumb .job-ico { display: none; }
|
||||
.job-meta {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.job-line .name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
color: var(--ink);
|
||||
font-weight: 650;
|
||||
}
|
||||
.job-line .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; color: var(--ink); }
|
||||
.job-line .swatches { padding: 0; min-height: 0; flex: none; }
|
||||
.badge {
|
||||
font-size: 0.65rem;
|
||||
@@ -1874,7 +1906,6 @@ body.desk-on main {
|
||||
.summary-text b { color: var(--ink); }
|
||||
.page-head-side { display: flex; align-items: center; gap: 0.75rem 1rem; flex-wrap: wrap; }
|
||||
.page-head-side .check { margin: 0; font-size: var(--t-sm); color: var(--muted); }
|
||||
.job-line > .ico { color: var(--faint); }
|
||||
.job-line[hidden] { display: none; }
|
||||
article.machine.flash { animation: flash 2s var(--ease); }
|
||||
@keyframes flash { 0%, 40% { box-shadow: 0 0 0 2px var(--accent), var(--shadow); } }
|
||||
|
||||
@@ -146,7 +146,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 src="{{ url_for('static', filename='sweep-viewer.js') }}?v=1"></script>
|
||||
<script>
|
||||
const families = { kobra_s1: "Kobra S1", kobra_3: "Kobra 3" };
|
||||
@@ -198,7 +198,7 @@ async function showToolpath(file, progress) {
|
||||
if (viewerFileId !== file.id) {
|
||||
meta.textContent = "Pfad wird gelesen …";
|
||||
try {
|
||||
const data = await api("/dateien/" + file.id + "/pfad");
|
||||
const data = await api("/dateien/" + file.id + "/pfad?tp=8");
|
||||
viewer.setPath(data);
|
||||
viewerFileId = file.id;
|
||||
meta.textContent = (data.count || 0).toLocaleString("de-DE") + " Punkte";
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='brand/favicon-32.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="512x512" href="{{ url_for('static', filename='brand/favicon.png') }}">
|
||||
<link rel="apple-touch-icon" href="{{ url_for('static', filename='brand/apple-touch-icon.png') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='grotti.css') }}?v=39">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='grotti.css') }}?v=41">
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
|
||||
+41
-5
@@ -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 });
|
||||
|
||||
Reference in new issue
Block a user