なごみ commited on
Commit
ab20366
·
unverified ·
2 Parent(s): cec19d85d91810

Merge pull request #35 from nagomi-sugarheart/claude/add-comment-count-time-afn6i

Browse files
Files changed (2) hide show
  1. main.py +7 -2
  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="flex flex-col items-center gap-1 px-8 py-4 rounded-2xl border-2 border-[#e09099] dark:border-[#c07080] hover:bg-[#fdf0f2] dark:hover:bg-[#3d1a20] transition group">
88
- <span id="like-icon" class="text-3xl transition-transform group-hover:scale-110">♡</span>
89
- <span id="like-count" class="text-sm font-bold text-[#bf283a] dark:text-[#f08090]">{{ article.get("likes", 0) or 0 }}</span>
90
  </button>
91
  </div>
92
 
@@ -166,16 +166,25 @@ function toggleReplyForm(commentId) {
166
 
167
  async function likeArticle(articleId) {
168
  const key = `liked_${articleId}`;
169
- if (localStorage.getItem(key)) return;
170
  const btn = document.getElementById('like-btn');
171
  btn.disabled = true;
172
- const res = await fetch(`/api/like/${articleId}`, { method: 'POST' });
 
 
 
173
  const data = await res.json();
174
  if (data.success) {
175
- localStorage.setItem(key, '1');
176
- document.getElementById('like-icon').textContent = '❤️';
 
 
 
 
 
 
 
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
  }