From c1fd3108f0be9d53f86c5f8f8e4a4e84aca9c2a9 Mon Sep 17 00:00:00 2001 From: Gangoke Date: Sun, 24 May 2026 15:33:05 -1000 Subject: [PATCH] feat: implement GCode file upload functionality with drag-and-drop support --- docker-compose.yml | 4 ++-- web/themes/default/app.js | 32 ++++++++++++++++++++++++++++++++ web/themes/default/index.html | 10 ++++++++++ web/themes/default/style.css | 16 ++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 21fa90c..374b4fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ services: kx-bridge: - image: gitea.it-drui.de/viewit/kx-bridge:latest + # image: gitea.it-drui.de/viewit/kx-bridge:latest # Selbst bauen statt das Registry-Image zu pullen? # Dann image-Zeile auskommentieren und folgende aktivieren: - # build: . + build: . volumes: - ./config:/app/config - ./data:/app/data diff --git a/web/themes/default/app.js b/web/themes/default/app.js index ec9bd7a..685c13e 100644 --- a/web/themes/default/app.js +++ b/web/themes/default/app.js @@ -1536,6 +1536,38 @@ function loadStore(){ }).catch(function(e){clog('Store-Fehler: '+e,'msg-err')}); } +function uploadGcode(file){ + if(!file) return; + var zone=document.getElementById('store-upload-zone'); + var status=document.getElementById('store-upload-status'); + var label=document.getElementById('store-upload-label'); + if(status) { status.textContent='⏳ Hochladen…'; status.style.display=''; status.className='upload-status-busy'; } + if(label) label.style.display='none'; + if(zone) zone.style.pointerEvents='none'; + var fd=new FormData(); + fd.append('file', file); + fetch(_apiUrl('/api/files/local'),{method:'POST',body:fd}) + .then(function(r){ + if(!r.ok) return r.text().then(function(t){throw new Error(r.status+': '+t);}); + return r.json(); + }) + .then(function(){ + if(status){ status.textContent='✓ '+file.name; status.className='upload-status-ok'; } + loadStore(); + setTimeout(function(){ + if(status){status.style.display='none'; status.className='';} + if(label) label.style.display=''; + if(zone) zone.style.pointerEvents=''; + }, 3000); + }) + .catch(function(e){ + if(status){ status.textContent='✗ '+e.message; status.className='upload-status-err'; } + if(label) label.style.display=''; + if(zone) zone.style.pointerEvents=''; + clog('Upload-Fehler: '+e,'msg-err'); + }); +} + function renderStore(){ var grid=document.getElementById('store-grid'); var empty=document.getElementById('store-empty'); diff --git a/web/themes/default/index.html b/web/themes/default/index.html index 84b33f0..6a1c94d 100644 --- a/web/themes/default/index.html +++ b/web/themes/default/index.html @@ -400,6 +400,16 @@ +
+ + + GCode hierher ziehen oder durchsuchen + +
diff --git a/web/themes/default/style.css b/web/themes/default/style.css index 4c77d83..a2a4572 100644 --- a/web/themes/default/style.css +++ b/web/themes/default/style.css @@ -212,6 +212,22 @@ canvas.tchart{width:100%;height:60px;display:block;border-radius:6px;background: .panel{display:none} .panel.active{display:block} +/* ── FILE BROWSER UPLOAD ZONE ── */ +#store-upload-zone{ + display:flex;flex-direction:column;align-items:center;justify-content:center; + gap:6px;padding:18px 12px;margin-bottom:14px; + border:2px dashed var(--border);border-radius:10px; + background:var(--raised);color:var(--txt2); + cursor:pointer;transition:border-color .15s,background .15s; + font-size:13px;text-align:center;user-select:none; +} +#store-upload-zone:hover{border-color:var(--accent);background:rgba(0,200,255,.06);color:var(--txt)} +#store-upload-zone.drag-over{border-color:var(--accent);background:rgba(0,200,255,.12);color:var(--accent)} +#store-upload-icon{font-size:22px;line-height:1} +.upload-status-busy{color:var(--txt2)} +.upload-status-ok{color:var(--ok)} +.upload-status-err{color:var(--err)} + /* ── MODAL ── */ .modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6); z-index:200;align-items:center;justify-content:center;padding:16px}