diff --git a/app.py b/app.py index 21acdec..a9683bd 100644 --- a/app.py +++ b/app.py @@ -1074,13 +1074,10 @@ def submission_detail(sub_id: int): with open(path, "rb") as f: b64 = base64.b64encode(f.read()).decode() src = f"data:{mime};base64,{b64}" - media_html += f'
' - # Checkbox overlay - media_html += f'' + media_html += f'
' + # Media element if mime.startswith("image/"): - media_html += f'' + media_html += f'' elif mime.startswith("video/"): # Generate thumbnail for poster thumb = generate_video_thumbnail(path) @@ -1092,16 +1089,32 @@ def submission_detail(sub_id: int): poster_attr = f' poster="data:image/jpeg;base64,{thumb_b64}"' except Exception: pass - media_html += f'' + media_html += f'' elif mime.startswith("audio/"): - media_html += f'' + media_html += f'' else: - media_html += f'

πŸ“Ž {os.path.basename(path)}

' + media_html += f'

πŸ“Ž {os.path.basename(path)}

' + # Toggle bar + media_html += f'
' + media_html += f'' + media_html += f'VerΓΆffentlichen' + media_html += f'
' media_html += f'
' except Exception as e: media_html += f'

Fehler: {e}

' - type_emoji = {"text": "πŸ’¬", "image": "πŸ–ΌοΈ", "audio": "🎀", "video": "🎬", "document": "πŸ“Ž"}.get(row["type"], "πŸ“Œ") + # SVG type icons (16x16, BSN blue) + _svg_icons = { + "text": '', + "image": '', + "audio": '', + "video": '', + "document": '', + } + type_emoji = _svg_icons.get(row["type"], _svg_icons["document"]) return f""" @@ -1137,6 +1150,14 @@ def submission_detail(sub_id: int): .btn-done:hover {{ background:rgba(48,209,88,0.28); }} .btn-delete {{ background:rgba(255,69,58,0.12); color:#ff453a; border:1px solid rgba(255,69,58,0.2); }} .btn-delete:hover {{ background:rgba(255,69,58,0.2); }} + + /* Toggle switch β€” publish bar */ + .toggle-switch {{ position:relative; display:inline-block; width:40px; height:22px; flex-shrink:0; }} + .toggle-switch input {{ opacity:0; width:0; height:0; }} + .toggle-slider {{ position:absolute; cursor:pointer; top:0; left:0; right:0; bottom:0; background:var(--surface2); border-radius:22px; transition:all 0.25s ease; border:1.5px solid var(--border); }} + .toggle-slider:before {{ content:""; position:absolute; height:16px; width:16px; left:2px; bottom:2px; background:#fff; border-radius:50%; transition:all 0.25s ease; box-shadow:0 1px 3px rgba(0,0,0,0.2); }} + .toggle-switch input:checked + .toggle-slider {{ background:var(--accent); border-color:var(--accent); }} + .toggle-switch input:checked + .toggle-slider:before {{ transform:translateX(18px); }} .btn-flag {{ background:rgba(255,69,58,0.1); color:#ff453a; }} .btn-flag:hover {{ background:rgba(255,69,58,0.2); }} .btn-publish {{ background:rgba(32,34,138,0.2); color:var(--accent2); border:1px solid var(--accent); }} @@ -1290,8 +1311,15 @@ if (_delBtn) {{ _status.style.display = 'inline'; _status.textContent = '⏳'; fetch('/submission/' + {row['id']} + '/delete', {{method:'POST'}}) - .then(function(r) {{ return r.text(); }}) - .then(function(html) {{ document.body.innerHTML = html; }}) + .then(function(r) {{ + if (!r.ok) throw new Error('Server-Fehler'); + // Redirect directly β€” the server now returns JSON + document.body.innerHTML = '
πŸ—‘οΈ Beitrag #' + {row['id']} + ' gelΓΆscht
'; + var style = document.createElement('style'); + style.textContent = '@keyframes fadeInOut{{0%{{opacity:0;transform:scale(0.9)}}15%{{opacity:1;transform:scale(1)}}75%{{opacity:1;transform:scale(1)}}100%{{opacity:0;transform:scale(0.95)}}}}'; + document.head.appendChild(style); + setTimeout(function(){{ window.location='/admin'; }}, 1800); + }}) .catch(function(err) {{ _status.textContent = 'Fehler: ' + err.message; _delBtn.disabled = false; @@ -1683,7 +1711,14 @@ def public_frontend(): except Exception: pass - type_emoji = {"text": "\U0001f4ac", "image": "\U0001f5bc\ufe0f", "audio": "\U0001f3a4", "video": "\U0001f3ac", "document": "\U0001f4ce"}.get(r["type"], "\U0001f4cc") + _fe_svg_icons = { + "text": '', + "image": '', + "audio": '', + "video": '', + "document": '', + } + type_emoji = _fe_svg_icons.get(r["type"], _fe_svg_icons["document"]) name = (r["publish_name"] or r["sender_name"] or "Anonym").strip() if not name or name.lower() in ("unknown", "anonym"): name = "Anonym" @@ -1870,7 +1905,7 @@ def public_frontend(): /* ── Submit Overlay ────────────────────────────────────────── */ .submit-bubble { position:fixed; bottom:1.5rem; right:5.5rem; z-index:9999; - width:56px; height:56px; border-radius:50%; background:#28a745; + width:56px; height:56px; border-radius:50%; background:#20228a; color:#fff; border:none; cursor:pointer; font-size:1.8rem; font-weight:300; line-height:1; box-shadow:0 6px 24px rgba(0,0,0,0.25); transition:transform 0.2s,box-shadow 0.2s; display:flex; align-items:center; justify-content:center; } @@ -1882,7 +1917,7 @@ def public_frontend(): background:#fff; border-radius:18px; box-shadow:0 12px 48px rgba(0,0,0,0.22); display:none; flex-direction:column; overflow:hidden; } .submit-overlay.open { display:flex; } - .submit-header { background:#28a745; color:#fff; padding:0.9rem 1.2rem; + .submit-header { background:#20228a; color:#fff; padding:0.9rem 1.2rem; font-weight:700; font-size:0.9rem; display:flex; align-items:center; justify-content:space-between; } .submit-header button { background:none; border:none; color:#fff; font-size:1.3rem; cursor:pointer; opacity:0.8; padding:0; line-height:1; } @@ -1895,13 +1930,13 @@ def public_frontend(): .submit-body input, .submit-body textarea { width:100%; border:1.5px solid #ddd; border-radius:10px; padding:0.55rem 0.8rem; font-size:0.82rem; font-family:inherit; outline:none; transition:border-color 0.15s; } - .submit-body input:focus, .submit-body textarea:focus { border-color:#28a745; } .submit-body textarea { resize:vertical; min-height:70px; } + .submit-body input:focus, .submit-body textarea:focus { border-color:#20228a; } .submit-body input[type="file"] { padding:0.4rem 0; border:none; font-size:0.78rem; } - .submit-body .submit-btn { width:100%; background:#28a745; color:#fff; border:none; + .submit-body .submit-btn { width:100%; background:#20228a; color:#fff; border:none; border-radius:10px; padding:0.7rem; font-weight:700; font-size:0.88rem; cursor:pointer; margin-top:1rem; transition:background 0.15s; font-family:inherit; } - .submit-body .submit-btn:hover { background:#1e7e34; } + .submit-body .submit-btn:hover { background:#161e6e; } .submit-body .submit-btn:disabled { opacity:0.5; cursor:default; } .submit-body .status-msg { text-align:center; font-size:0.8rem; margin-top:0.6rem; min-height:1.2rem; } @@ -2031,7 +2066,7 @@ def public_frontend(): const data = await r.json(); if (r.ok) { sStatus.textContent = data.message; - sStatus.style.color = '#28a745'; + sStatus.style.color = '#20228a'; document.getElementById('subName').value = ''; document.getElementById('subText').value = ''; fileInput.value = '';