Remove duplicate images table; single card list; CSS background-image icons (no broken img); fix manualMount

This commit is contained in:
KarnerF committed 2026-08-30 13:30:33 +02:00
1 parent 2734b79267
commit 68c761d6b5
1 file changed
+16 -38
+16 -38
View File
@@ -1607,8 +1607,6 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
"<pre id='sm-raw-pre' style='background:#0a0f1a;border:1px solid var(--border);border-radius:6px;"
"padding:10px;font-size:.65rem;color:var(--dim);overflow:auto;max-height:200px;white-space:pre-wrap;'></pre></div>");
H("<div id='games-list'><p class='hint'>%s</p></div>",L(LS_LOADING));
H("<div class='sublist-title' style='margin-top:20px;'>%s</div>",L(LS_IMAGES));
H("<div id='images-list'><p class='hint'>%s</p></div>",L(LS_LOADING));
H("</div></div>");
/* Panel: Debug Log */
@@ -1775,9 +1773,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
H("var _gpR=0;"
"function loadGamePanel(retry){_gpR=(retry||0);"
"var gl=document.getElementById('games-list');"
"var il=document.getElementById('images-list');"
"if(gl)gl.innerHTML='<p class=\"hint\">Lade...</p>';"
"if(il)il.innerHTML='';"
"var gp=fetch('/api/sm/games',{method:'POST'}).then(function(r){return r.json();}).catch(function(){return null;});"
"var ip=fetch('/api/sm/images',{method:'POST'}).then(function(r){return r.json();}).catch(function(){return null;});"
"Promise.all([gp,ip]).then(function(res){"
@@ -1801,45 +1797,27 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
"var ba=img.mounted"
"?'<button onclick=\"_smUnmount('+i+')\" style=\"background:transparent;border:1px solid #f87171;border-radius:4px;color:#f87171;padding:3px 10px;cursor:pointer;font-size:.75rem;\">Unmount</button>'"
":'<button onclick=\"_smMount('+i+')\" style=\"background:transparent;border:1px solid var(--accent);border-radius:4px;color:var(--accent);padding:3px 10px;cursor:pointer;font-size:.75rem;white-space:nowrap;\">Mount</button>';"
"h+='<div style=\"display:flex;align-items:center;gap:10px;padding:8px 4px;border-bottom:1px solid var(--border);\">';"
"h+=(tid?'<img src=\"/api/game/icon?title_id='+tid+'\" width=\"48\" height=\"48\" style=\"border-radius:8px;object-fit:cover;flex-shrink:0;background:#1e2a42;\" onerror=\"this.style.display=\\'none\\'\">':\"\");"
/* CSS background-image: loads silently, no broken image icon if missing */
"var icbg=tid?'background-image:url(/api/game/icon?title_id='+tid+');background-size:cover;':'';"
"var ic='<div style=\"width:48px;height:48px;border-radius:8px;background:#1e2a42;'+icbg+'flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:.55rem;color:#64748b;font-family:monospace;\">'+(!img.mounted&&tid?tid.substring(0,4):'')+'</div>';"
"h+='<div style=\"display:flex;align-items:center;gap:10px;padding:8px 4px;border-bottom:1px solid var(--border);\">'+ic;"
"h+='<div style=\"flex:1;min-width:0;\">';"
"h+='<div style=\"font-size:.83rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;\">'+fn+'</div>';"
"h+='<div style=\"font-family:var(--mono);font-size:.7rem;color:var(--dim);\">'+(tid||'')+'<span style=\"font-size:.65rem;\"> &mdash; '+sz+'</span></div>';"
"h+='<div style=\"font-family:var(--mono);font-size:.7rem;color:var(--dim);\">'+(tid||'–')+'<span style=\"font-size:.65rem;\"> &mdash; '+sz+'</span></div>';"
"h+='</div><div style=\"display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex-shrink:0;\">'+mn+ba+'</div></div>';"
"});gl.innerHTML=h;"
"}else{"
"gl.innerHTML=((!gd||gd.error||gd.status)?'<p class=\"hint\" style=\"color:#f87171;\">SM API nicht erreichbar</p>':'<p class=\"hint\">Keine Spiele gefunden</p>');"
"}"
"if(!il)return;"
"if(!id||id.error||id.status){il.innerHTML='<p class=\"hint\" style=\"color:#f87171;\">'+(id&&id.error?id.error:'nicht erreichbar')+'</p>';return;}"
"if(!id.images||!id.images.length){il.innerHTML='<p class=\"hint\">Keine Image-Dateien gefunden</p>';return;}"
"var ih='<table style=\"width:100%%;border-collapse:collapse;font-size:.78rem;\">';"
"ih+='<tr style=\"border-bottom:1px solid var(--border);color:var(--dim);font-size:.7rem;\">';"
"ih+='<th style=\"text-align:left;padding:4px 8px;\">Datei / Pfad</th>';"
"ih+='<th style=\"padding:4px 8px;\">Typ</th><th style=\"padding:4px 8px;\">Gr\\u00f6\\u00dfe</th>';"
"ih+='<th style=\"padding:4px 8px;\">Mount</th></tr>';"
"id.images.forEach(function(img,i){"
"var parts=(img.path||'').split('/');"
"var fn=parts.pop()||img.path;"
"var dir=parts.join('/')||'/';"
"var ext=fn.indexOf('.')>-1?fn.split('.').pop().toUpperCase():'';"
"var sz=img.size?(img.size>1073741824?(img.size/1073741824).toFixed(2)+' GB':(img.size/1048576).toFixed(0)+' MB'):'?';"
"var st=img.mounted?'<span style=\"color:#10b981;\">&#9679; aktiv</span>':'<span style=\"color:var(--dim);\">&#9675;</span>';"
"var iba=img.mounted"
"?'<button onclick=\"_smUnmount('+i+')\" style=\"background:transparent;border:1px solid #f87171;border-radius:4px;color:#f87171;padding:2px 8px;cursor:pointer;font-size:.7rem;\">Unmount</button>'"
":'<button onclick=\"_smMount('+i+')\" style=\"background:transparent;border:1px solid var(--accent);border-radius:4px;color:var(--accent);padding:2px 8px;cursor:pointer;font-size:.7rem;\">Mount</button>';"
"ih+='<tr style=\"border-bottom:1px solid var(--border);\">';"
"ih+='<td style=\"padding:6px 8px;\"><span style=\"font-family:var(--mono);font-size:.76rem;\">'+fn+'</span>';"
"ih+='<br><span style=\"font-family:var(--mono);font-size:.65rem;color:var(--dim);\">'+dir+'</span></td>';"
"ih+='<td style=\"padding:6px 8px;text-align:center;font-family:var(--mono);font-size:.7rem;\">'+ext+'</td>';"
"ih+='<td style=\"padding:6px 8px;text-align:center;\">'+sz+'</td>';"
"ih+='<td style=\"padding:6px 8px;text-align:center;\">'+st+' '+iba+'</td></tr>';"
"});ih+='</table>';il.innerHTML=ih;});}"
"gl.innerHTML=((!gd||gd.error||gd.status)?'<p class=\"hint\" style=\"color:#f87171;\">SM API nicht erreichbar &mdash; l\\u00e4uft ShadowMountPlus?</p>':'<p class=\"hint\">Keine Spiele gefunden</p>');"
"}});}"
"function loadGames(){loadGamePanel(0);}"
"function _smMount(i){var g=window._smG&&window._smG[i];if(!g)return;"
"var gl=document.getElementById('games-list');"
"if(gl)gl.innerHTML='<p class=\"hint\">Mounting...</p>';"
"if(g.tid)mountGame(g.tid);else manualMount(g.path);}"
"function _smUnmount(i){var g=window._smG&&window._smG[i];if(g&&g.tid)unmountGame(g.tid);}");
"function _smUnmount(i){var g=window._smG&&window._smG[i];if(!g)return;"
"var gl=document.getElementById('games-list');"
"if(gl)gl.innerHTML='<p class=\"hint\">Unmounting...</p>';"
"if(g.tid)unmountGame(g.tid);}");
H("function smRawDebug(){"
"var dbg=document.getElementById('sm-raw-dbg');"
"var pre=document.getElementById('sm-raw-pre');"
@@ -1853,12 +1831,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
"pre.textContent='=== /api/v1/games ===\\n'+res[0]+'\\n\\n=== /api/v1/images ===\\n'+res[1];"
"});}"
"function manualMount(path){"
"var il=document.getElementById('images-list');"
"if(il)il.innerHTML='<p class=\"hint\">Mounting...</p>';"
"var gl=document.getElementById('games-list');"
"if(gl)gl.innerHTML='<p class=\"hint\">Mounting...</p>';"
"fetch('/api/manual/add?path='+encodeURIComponent(path),{method:'POST'})"
".then(function(r){return r.json();})"
".then(function(d){"
"if(d.error&&il)il.innerHTML='<p class=\"hint\" style=\"color:#f87171;\">'+d.error+'</p>';"
"if(d.error&&gl)gl.innerHTML='<p class=\"hint\" style=\"color:#f87171;\">'+d.error+'</p>';"
"setTimeout(function(){loadGamePanel(0);},4000);})"
".catch(function(){setTimeout(function(){loadGamePanel(0);},4000);});}"
"function renderGamesList(el,games){"