fix: einheitliche rote Herzen überall — kein Blau, keine Invertierung
Quality Gate / 🛡️ Lint + Type Check + Tests (push) Failing after 13m20s

- .detail-like-btn: SVG fill=#EF4444, liked kein background
- .comment-like-btn: SVG fill=#EF4444, border entfernt, liked kein background
- Alle drei Button-Typen (.stat-like, .detail-like, .comment-like) jetzt identisch:
  Default: rote gefüllte Herzen ohne Border
  Liked: nur rote Herzen, kein Hintergrundwechsel
- media_path-Check: os.path.exists(path) → (MEDIA_DIR / basename).exists()
This commit is contained in:
Hermes Agent
2026-07-15 22:47:20 +02:00
parent 6ab03fbe85
commit eda106849e
+18 -16
View File
@@ -1809,8 +1809,9 @@ def submission_detail(sub_id: int):
} }
for i, path in enumerate(paths): for i, path in enumerate(paths):
checked = "checked" if flags[i] == "1" else "" checked = "checked" if flags[i] == "1" else ""
if not os.path.exists(path): basename = os.path.basename(path)
media_html += f'<p style="color:#888;">📁 Datei nicht gefunden: {os.path.basename(path)}</p>' if not (MEDIA_DIR / basename).exists():
media_html += f'<p style="color:#888;">📁 Datei nicht gefunden: {basename}</p>'
continue continue
_, ext = os.path.splitext(path) _, ext = os.path.splitext(path)
mime = mime_map.get(ext.lower(), "application/octet-stream") mime = mime_map.get(ext.lower(), "application/octet-stream")
@@ -2725,9 +2726,9 @@ def public_frontend():
# Skip media not marked for publishing # Skip media not marked for publishing
if flags[i] != "1": if flags[i] != "1":
continue continue
if not os.path.exists(path):
continue
basename = os.path.basename(path) basename = os.path.basename(path)
if not (MEDIA_DIR / basename).exists():
continue
_, ext = os.path.splitext(path) _, ext = os.path.splitext(path)
mime = mime_map.get(ext.lower(), "application/octet-stream") mime = mime_map.get(ext.lower(), "application/octet-stream")
try: try:
@@ -2956,8 +2957,8 @@ def public_frontend():
.stat-like-btn { background:none; border:none; border-radius:999px; padding:0.25rem 0.6rem; font-size:0.72rem; cursor:pointer; color:#9CA3AF; font-family:inherit; transition:all 0.15s; display:flex; align-items:center; gap:0.2rem; -webkit-tap-highlight-color:transparent; min-width:44px; min-height:36px; justify-content:center; } .stat-like-btn { background:none; border:none; border-radius:999px; padding:0.25rem 0.6rem; font-size:0.72rem; cursor:pointer; color:#9CA3AF; font-family:inherit; transition:all 0.15s; display:flex; align-items:center; gap:0.2rem; -webkit-tap-highlight-color:transparent; min-width:44px; min-height:36px; justify-content:center; }
.stat-like-btn svg, .stat-like-btn svg path { stroke:#EF4444 !important; fill:#EF4444 !important; } .stat-like-btn svg, .stat-like-btn svg path { stroke:#EF4444 !important; fill:#EF4444 !important; }
.stat-like-btn:hover { border-color:#9CA3AF; color:#6B7280; } .stat-like-btn:hover { border-color:#9CA3AF; color:#6B7280; }
.stat-like-btn.liked { background:#EF4444; color:#fff; border-color:#EF4444; } .stat-like-btn.liked { background:none; }
.stat-like-btn.liked svg, .stat-like-btn.liked svg path { stroke:#fff !important; fill:#fff !important; } .stat-like-btn.liked svg, .stat-like-btn.liked svg path { stroke:#EF4444 !important; fill:#EF4444 !important; }
.stat-like-btn:active { transform:scale(0.96); } .stat-like-btn:active { transform:scale(0.96); }
/* Filter bar */ /* Filter bar */
@@ -4515,7 +4516,8 @@ def public_detail(sub_id: int):
for i, path in enumerate(paths): for i, path in enumerate(paths):
if flags[i] != "1": if flags[i] != "1":
continue continue
if not os.path.exists(path): basename = os.path.basename(path)
if not (MEDIA_DIR / basename).exists():
continue continue
_, ext = os.path.splitext(path) _, ext = os.path.splitext(path)
mime = mime_map.get(ext.lower(), "application/octet-stream") mime = mime_map.get(ext.lower(), "application/octet-stream")
@@ -4585,7 +4587,7 @@ def public_detail(sub_id: int):
<div class="comment-header"><strong class="comment-author">{c_author}</strong> <span class="comment-date">{c_date}</span></div> <div class="comment-header"><strong class="comment-author">{c_author}</strong> <span class="comment-date">{c_date}</span></div>
<p class="comment-text">{c["content"]}</p> <p class="comment-text">{c["content"]}</p>
<div class="comment-actions"> <div class="comment-actions">
<button class="comment-like-btn" data-cid="{c['id']}" data-clikes="{c['likes'] or 0}"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:3px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> <span class="clike-count">{c['likes'] or 0}</span></button> <button class="comment-like-btn" data-cid="{c['id']}" data-clikes="{c['likes'] or 0}"><svg width="14" height="14" viewBox="0 0 24 24" fill="#EF4444" stroke="#EF4444" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:3px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> <span class="clike-count">{c['likes'] or 0}</span></button>
<button class="reply-btn" onclick="replyTo({c['id']}, '{c_author}')"> Antworten</button> <button class="reply-btn" onclick="replyTo({c['id']}, '{c_author}')"> Antworten</button>
</div> </div>
</div>""" </div>"""
@@ -4657,10 +4659,10 @@ def public_detail(sub_id: int):
.reply-btn {{ background:none; border:1px solid #ccc; border-radius:6px; padding:0.2rem 0.6rem; font-size:0.72rem; color:#666; cursor:pointer; margin-top:0.3rem; font-family:inherit; transition:all 0.15s; }} .reply-btn {{ background:none; border:1px solid #ccc; border-radius:6px; padding:0.2rem 0.6rem; font-size:0.72rem; color:#666; cursor:pointer; margin-top:0.3rem; font-family:inherit; transition:all 0.15s; }}
.reply-btn:hover {{ border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.04); }} .reply-btn:hover {{ border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.04); }}
.comment-actions {{ display:flex; align-items:center; gap:0.4rem; margin-top:0.4rem; }} .comment-actions {{ display:flex; align-items:center; gap:0.4rem; margin-top:0.4rem; }}
.comment-like-btn {{ background:none; border:1.5px solid #e0dcd3; border-radius:999px; padding:0.15rem 0.5rem; font-size:0.68rem; cursor:pointer; color:#888; font-family:inherit; transition:all 0.15s; display:inline-flex; align-items:center; -webkit-tap-highlight-color:transparent; }} .comment-like-btn {{ background:none; border:none; border-radius:999px; padding:0.15rem 0.5rem; font-size:0.68rem; cursor:pointer; color:#888; font-family:inherit; transition:all 0.15s; display:inline-flex; align-items:center; -webkit-tap-highlight-color:transparent; }}
.comment-like-btn:hover {{ border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.05); }} .comment-like-btn:hover {{ opacity:0.8; }}
.comment-like-btn.liked {{ background:#20228a; color:#fff; border-color:#20228a; font-weight:600; }} .comment-like-btn.liked {{ background:none; }}
.comment-like-btn.liked svg, .comment-like-btn.liked svg path {{ stroke:#fff !important; }} .comment-like-btn.liked svg, .comment-like-btn.liked svg path {{ stroke:#EF4444 !important; fill:#EF4444 !important; }}
.comment-like-btn:active {{ transform:scale(0.94); }} .comment-like-btn:active {{ transform:scale(0.94); }}
.reply-info {{ font-size:0.75rem; color:#20228a; margin-bottom:0.3rem; font-weight:600; display:none; }} .reply-info {{ font-size:0.75rem; color:#20228a; margin-bottom:0.3rem; font-weight:600; display:none; }}
.comment-email, .comment-phone {{ padding:0.6rem 0.9rem; border:1.5px solid #ddd; border-radius:10px; font-size:0.85rem; font-family:inherit; }} .comment-email, .comment-phone {{ padding:0.6rem 0.9rem; border:1.5px solid #ddd; border-radius:10px; font-size:0.85rem; font-family:inherit; }}
@@ -4676,9 +4678,9 @@ def public_detail(sub_id: int):
.site-header {{ padding:0.8rem 1rem; }} .site-header {{ padding:0.8rem 1rem; }}
}} }}
.detail-like-btn:hover {{ border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.05); }} .detail-like-btn:hover {{ opacity:0.8; }}
.detail-like-btn.liked {{ background:#20228a; color:#fff; border-color:#20228a; font-weight:600; }} .detail-like-btn.liked {{ background:none; }}
.detail-like-btn.liked svg, .detail-like-btn.liked svg path {{ stroke:#fff !important; }} .detail-like-btn.liked svg, .detail-like-btn.liked svg path {{ stroke:#EF4444 !important; fill:#EF4444 !important; }}
.detail-like-btn:active {{ transform:scale(0.94); }}</style> .detail-like-btn:active {{ transform:scale(0.94); }}</style>
</head> </head>
<body> <body>
@@ -4702,7 +4704,7 @@ def public_detail(sub_id: int):
{"".join([f'<div class="detail-content">{content}</div>' if content else ''])} {"".join([f'<div class="detail-content">{content}</div>' if content else ''])}
<div style="display:flex;align-items:center;gap:1rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid #f0ede6;"> <div style="display:flex;align-items:center;gap:1rem;margin-top:1.5rem;padding-top:1rem;border-top:1px solid #f0ede6;">
<span style="font-size:0.8rem;color:#999;"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> {row['views'] or 0} Aufrufe</span> <span style="font-size:0.8rem;color:#999;"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> {row['views'] or 0} Aufrufe</span>
<button id="detail-like-btn" data-id="{sub_id}" class="detail-like-btn"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:2px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> {row['likes'] or 0}</button> <button id="detail-like-btn" data-id="{sub_id}" class="detail-like-btn"><svg width="16" height="16" viewBox="0 0 24 24" fill="#EF4444" stroke="#EF4444" stroke-width="0.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:2px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> {row['likes'] or 0}</button>
</div> </div>
</article> </article>
<section class="comments-section"> <section class="comments-section">