From 1f76329140d03b09dce3fbfc2877a2c09615b407 Mon Sep 17 00:00:00 2001 From: 0310700 Date: Wed, 1 Jul 2026 10:12:38 +0900 Subject: [PATCH] =?UTF-8?q?fix(reactions):=20=EC=A2=8B=EC=95=84=EC=9A=94?= =?UTF-8?q?=C2=B7=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20=EA=B0=92=EC=9D=84?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=C2=B7=ED=86=B5=EA=B3=84=C2=B7=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=EC=97=90=EC=84=9C=20=EC=A0=84=EC=97=AD=20=EB=8F=99?= =?UTF-8?q?=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 같은 프로젝트가 피드 카드 버튼·내 프로젝트 통계 줄·상세 모달(template) 세 곳에 렌더되는데, 기존 syncReaction 은 라이브 data-react 버튼만 갱신해 통계 줄과 모달(inert template 스냅샷)이 옛 값으로 남아 서로 달라졌다. - reactions.js: 프로젝트별 {on,count} 를 단일 store(Map)로 관리. 로드 시 detailStore 템플릿에서 서버 원본값을 시드하고, 변경 시 그 값을 그리는 모든 라이브 DOM(버튼·통계 줄·data-pop)을 자동으로 다시 칠함. - modals.js: 모달 마운트 직후 applyReactions 로 현재 store 값을 덮어써 템플릿 스냅샷의 옛 값 대신 최신 값을 표시. - dashboard.ejs: 내 프로젝트 통계 숫자에 data-rcount/data-id/data-kind 바인딩 추가. Co-Authored-By: Claude Opus 4.8 --- public/js/modals.js | 4 +++ public/js/reactions.js | 76 ++++++++++++++++++++++++++++++++++++++---- views/dashboard.ejs | 4 +-- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/public/js/modals.js b/public/js/modals.js index fa99775..dc458fb 100644 --- a/public/js/modals.js +++ b/public/js/modals.js @@ -1,5 +1,6 @@ // 상세 모달 · 공유(등록) 모달 — 열기/닫기 및 공개범위 토글. import { $, $$ } from "./util.js"; +import { applyReactions } from "./reactions.js"; export function openDetail(id) { const tpl = $('#detailStore template[data-detail-id="' + id + '"]'); @@ -7,6 +8,9 @@ export function openDetail(id) { if (!tpl || !overlay) { window.location.href = "/projects/" + id; return; } const mount = $(".modal", overlay) || overlay; mount.innerHTML = tpl.innerHTML; + // 템플릿은 로드 시점 스냅샷이라 그동안 바뀐 반응 수가 반영돼 있지 않다. + // 마운트 직후 현재 store 값으로 덮어써 카드와 항상 같은 값을 보이게 한다. + applyReactions(mount); overlay.hidden = false; document.body.style.overflow = "hidden"; // 주의: 열기 감지 셀렉터가 [data-open-id] 라서 같은 이름을 쓰면 모달 내부 클릭(닫기/삭제)이 diff --git a/public/js/reactions.js b/public/js/reactions.js index 52c0af2..2573d85 100644 --- a/public/js/reactions.js +++ b/public/js/reactions.js @@ -1,17 +1,81 @@ -// ❤️ 좋아요 / ⭐ 즐겨찾기 — fetch 로 토글하고 카운트를 즉시 반영(점진적 향상). +// ❤️ 좋아요 / ⭐ 즐겨찾기 — 반응 상태를 한 곳(store)에서 관리한다. +// 같은 프로젝트가 여러 위치(피드 카드 버튼·내 프로젝트 통계 줄·상세 모달)에 렌더되므로, +// 값이 바뀌면 그 프로젝트를 그리는 '모든' DOM 을 자동으로 다시 칠해 항상 같은 값을 유지한다. +// 프레임워크 없이: 프로젝트별 {on,count} 를 Map 에 두고 변경 시 관련 DOM 만 갱신(점진적 향상). import { $, $$, toast, burstSparkle } from "./util.js"; let starTaps = []; -function syncReaction(id, kind, on, count) { +// key = id + "|" + kind → { id, kind, on:boolean, count:number } +const store = new Map(); +const keyOf = (id, kind) => id + "|" + kind; +function getState(id, kind) { + return store.get(keyOf(id, kind)) || { id, kind, on: false, count: 0 }; +} + +// 한 (프로젝트, 종류)의 현재 상태를 그것을 표시하는 모든 라이브 DOM 에 반영. +// document 조회라