Spaces:
Running
Running
Merge pull request #35 from nagomi-sugarheart/claude/add-comment-count-time-afn6i
Browse files- main.py +7 -2
- templates/blog_detail.html +17 -8
main.py
CHANGED
|
@@ -662,12 +662,17 @@ async def api_comment(request: Request):
|
|
| 662 |
return JSONResponse({"success": ok})
|
| 663 |
|
| 664 |
@app.post("/api/like/{article_id}")
|
| 665 |
-
async def api_like(article_id: str):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 666 |
article = get_article(article_id)
|
| 667 |
if not article:
|
| 668 |
return JSONResponse({"success": False, "likes": 0})
|
| 669 |
current = int(article.get("likes", 0) or 0)
|
| 670 |
-
new_count = current + 1
|
| 671 |
r = http_requests.patch(cms_url(f"blog/{article_id}"), headers=CMS_HEADERS_POST(),
|
| 672 |
json={"likes": new_count})
|
| 673 |
return JSONResponse({"success": r.status_code in [200, 201], "likes": new_count})
|
|
|
|
| 662 |
return JSONResponse({"success": ok})
|
| 663 |
|
| 664 |
@app.post("/api/like/{article_id}")
|
| 665 |
+
async def api_like(article_id: str, request: Request):
|
| 666 |
+
try:
|
| 667 |
+
body = await request.json()
|
| 668 |
+
action = body.get("action", "add")
|
| 669 |
+
except Exception:
|
| 670 |
+
action = "add"
|
| 671 |
article = get_article(article_id)
|
| 672 |
if not article:
|
| 673 |
return JSONResponse({"success": False, "likes": 0})
|
| 674 |
current = int(article.get("likes", 0) or 0)
|
| 675 |
+
new_count = max(0, current + (1 if action == "add" else -1))
|
| 676 |
r = http_requests.patch(cms_url(f"blog/{article_id}"), headers=CMS_HEADERS_POST(),
|
| 677 |
json={"likes": new_count})
|
| 678 |
return JSONResponse({"success": r.status_code in [200, 201], "likes": new_count})
|
templates/blog_detail.html
CHANGED
|
@@ -84,9 +84,9 @@
|
|
| 84 |
<!-- いいね -->
|
| 85 |
<div class="flex justify-center mb-8">
|
| 86 |
<button id="like-btn" onclick="likeArticle('{{ article_id }}')"
|
| 87 |
-
class="
|
| 88 |
-
<span id="like-icon" class="text-
|
| 89 |
-
<span id="like-count" class="text-
|
| 90 |
</button>
|
| 91 |
</div>
|
| 92 |
|
|
@@ -166,16 +166,25 @@ function toggleReplyForm(commentId) {
|
|
| 166 |
|
| 167 |
async function likeArticle(articleId) {
|
| 168 |
const key = `liked_${articleId}`;
|
| 169 |
-
|
| 170 |
const btn = document.getElementById('like-btn');
|
| 171 |
btn.disabled = true;
|
| 172 |
-
const res = await fetch(`/api/like/${articleId}`, {
|
|
|
|
|
|
|
|
|
|
| 173 |
const data = await res.json();
|
| 174 |
if (data.success) {
|
| 175 |
-
|
| 176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
document.getElementById('like-count').textContent = data.likes;
|
| 178 |
-
btn.classList.add('bg-[#fdf0f2]', 'dark:bg-[#3d1a20]');
|
| 179 |
}
|
| 180 |
btn.disabled = false;
|
| 181 |
}
|
|
|
|
| 84 |
<!-- いいね -->
|
| 85 |
<div class="flex justify-center mb-8">
|
| 86 |
<button id="like-btn" onclick="likeArticle('{{ article_id }}')"
|
| 87 |
+
class="w-20 h-20 rounded-full border-2 border-[#e09099] dark:border-[#c07080] flex flex-col items-center justify-center gap-0.5 hover:bg-[#fdf0f2] dark:hover:bg-[#3d1a20] transition group">
|
| 88 |
+
<span id="like-icon" class="text-2xl transition-transform group-hover:scale-110 leading-none">♡</span>
|
| 89 |
+
<span id="like-count" class="text-xs font-bold text-[#bf283a] dark:text-[#f08090] leading-none">{{ article.get("likes", 0) or 0 }}</span>
|
| 90 |
</button>
|
| 91 |
</div>
|
| 92 |
|
|
|
|
| 166 |
|
| 167 |
async function likeArticle(articleId) {
|
| 168 |
const key = `liked_${articleId}`;
|
| 169 |
+
const isLiked = !!localStorage.getItem(key);
|
| 170 |
const btn = document.getElementById('like-btn');
|
| 171 |
btn.disabled = true;
|
| 172 |
+
const res = await fetch(`/api/like/${articleId}`, {
|
| 173 |
+
method: 'POST', headers: {'Content-Type': 'application/json'},
|
| 174 |
+
body: JSON.stringify({action: isLiked ? 'remove' : 'add'})
|
| 175 |
+
});
|
| 176 |
const data = await res.json();
|
| 177 |
if (data.success) {
|
| 178 |
+
if (isLiked) {
|
| 179 |
+
localStorage.removeItem(key);
|
| 180 |
+
document.getElementById('like-icon').textContent = '♡';
|
| 181 |
+
btn.classList.remove('bg-[#fdf0f2]', 'dark:bg-[#3d1a20]');
|
| 182 |
+
} else {
|
| 183 |
+
localStorage.setItem(key, '1');
|
| 184 |
+
document.getElementById('like-icon').textContent = '❤️';
|
| 185 |
+
btn.classList.add('bg-[#fdf0f2]', 'dark:bg-[#3d1a20]');
|
| 186 |
+
}
|
| 187 |
document.getElementById('like-count').textContent = data.likes;
|
|
|
|
| 188 |
}
|
| 189 |
btn.disabled = false;
|
| 190 |
}
|