diff --git a/app.py b/app.py index 3e85cfa..5b0d89e 100644 --- a/app.py +++ b/app.py @@ -2882,7 +2882,7 @@ def public_frontend():
""" + str(r['views'] or 0) + """ """ + str(r['comment_count'] or 0) + """ - +
""" + type_emoji + """ @@ -2902,7 +2902,7 @@ def public_frontend():
""" + str(r['views'] or 0) + """ """ + str(r['comment_count'] or 0) + """ - +
""" + type_emoji + """ @@ -3514,7 +3514,7 @@ def public_frontend(): .then(function(data) { if (!data.already) { this.classList.add('liked'); - this.innerHTML = ' ' + data.likes; + this.innerHTML = ' ' + data.likes; this.setAttribute('data-likes', data.likes); likedPosts.push(parseInt(id)); localStorage.setItem('likedPosts', JSON.stringify(likedPosts)); @@ -4643,7 +4643,7 @@ def public_detail(sub_id: int): # Comments comment_rows = db.execute( - "SELECT id, author_name, content, created_at, parent_id FROM comments WHERE submission_id = ? AND status='published' ORDER BY created_at ASC", + "SELECT id, author_name, content, created_at, parent_id, likes FROM comments WHERE submission_id = ? AND status='published' ORDER BY created_at ASC", (sub_id,), ).fetchall() @@ -4668,7 +4668,10 @@ def public_detail(sub_id: int): html += f"""
{c_author} {c_date}

{c["content"]}

- +
+ + +
""" # Recursively render children if c["id"] in children: @@ -4736,6 +4739,11 @@ def public_detail(sub_id: int): .comment-submit-btn:disabled {{ opacity:0.6; pointer-events:none; }} .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); }} + .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:hover {{ border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.05); }} + .comment-like-btn.liked {{ background:#20228a; color:#fff; border-color:#20228a; font-weight:600; }} + .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; }} .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:focus, .comment-phone:focus {{ outline:none; border-color:#20228a; }} @@ -4775,7 +4783,7 @@ def public_detail(sub_id: int): {"".join([f'
{content}
' if content else ''])}
{row['views'] or 0} Aufrufe - +
@@ -4822,7 +4830,7 @@ def public_detail(sub_id: int): .then(function(data) {{ if (!data.already) {{ btn.classList.add('liked'); - btn.innerHTML = ' ' + data.likes; + btn.innerHTML = ' ' + data.likes; btn.style.background = '#20228a'; btn.style.color = '#fff'; btn.style.borderColor = '#20228a'; @@ -4905,6 +4913,34 @@ function submitComment(event, subId) {{ }}); return false; }} + +// ── Comment Like Buttons ──────────────────────────────────── +(function() {{ + var likedComments = JSON.parse(localStorage.getItem('likedComments') || '[]'); + document.querySelectorAll('.comment-like-btn').forEach(function(btn) {{ + var cid = parseInt(btn.getAttribute('data-cid')); + if (likedComments.indexOf(cid) !== -1) {{ + btn.classList.add('liked'); + }} + btn.addEventListener('click', function() {{ + var id = parseInt(this.getAttribute('data-cid')); + if (likedComments.indexOf(id) !== -1) return; + fetch('/api/comment-like/' + id, {{method:'POST'}}) + .then(function(r) {{ return r.json(); }}) + .then(function(data) {{ + if (!data.already) {{ + this.classList.add('liked'); + var count = this.querySelector('.clike-count'); + if (count) count.textContent = data.likes; + this.setAttribute('data-clikes', data.likes); + likedComments.push(id); + localStorage.setItem('likedComments', JSON.stringify(likedComments)); + }} + }}.bind(this)) + .catch(function() {{}}); + }}); + }}); +}})();
@@ -5018,6 +5054,30 @@ def api_like(sub_id: int): return resp +@app.route("/api/comment-like/", methods=["POST"]) +def api_comment_like(comment_id: int): + """Like a comment (cookie-based dedup).""" + db = get_db() + row = db.execute( + "SELECT id, likes FROM comments WHERE id = ? AND status='published'", + (comment_id,), + ).fetchone() + if not row: + return jsonify({"error": "Nicht gefunden"}), 404 + + liked = request.cookies.get(f"cliked_{comment_id}", "") + if liked == "1": + return jsonify({"likes": row["likes"] or 0, "already": True}) + + db.execute("UPDATE comments SET likes = likes + 1 WHERE id = ?", (comment_id,)) + db.commit() + new_likes = db.execute("SELECT likes FROM comments WHERE id = ?", (comment_id,)).fetchone()[0] + + resp = jsonify({"likes": new_likes or 0, "already": False}) + resp.set_cookie(f"cliked_{comment_id}", "1", max_age=365*24*60*60, httponly=True, samesite="Lax") + return resp + + @app.route("/api/comment/", methods=["POST"]) def api_comment(sub_id: int): db = get_db()