// ❤️ 좋아요 / ⭐ 즐겨찾기 — fetch 로 토글하고 카운트를 즉시 반영(점진적 향상). import { $, $$, toast, burstSparkle } from "./util.js"; let starTaps = []; function syncReaction(id, kind, on, count) { $$('[data-react][data-id="' + id + '"][data-kind="' + kind + '"]').forEach((b) => { b.classList.toggle("on", !!on); const c = $(".count", b); if (c) c.textContent = count; }); } export function initReactions() { document.addEventListener("click", (e) => { const btn = e.target.closest("[data-react]"); if (!btn) return; e.preventDefault(); e.stopPropagation(); const id = btn.getAttribute("data-id"); const kind = btn.getAttribute("data-kind"); // heart | star if (kind === "star") { starTaps = starTaps.filter((t) => Date.now() - t < 1400); starTaps.push(Date.now()); if (starTaps.length >= 4) burstSparkle(e.clientX, e.clientY); } fetch("/projects/" + id + "/" + kind, { method: "POST", headers: { "X-Requested-With": "fetch", "Accept": "application/json" }, }) .then((r) => (r.ok ? r.json() : Promise.reject(r.status))) .then((data) => syncReaction(id, kind, data.on, data.count)) .catch(() => toast("처리에 실패했습니다. 다시 시도해 주세요.")); }); }