fix(comment-cards): 복사 버튼 제거, 카드 클릭으로 복사
복사 버튼이 캡처 이미지에 함께 찍히던 문제 해결. 버튼을 없애고 카드 자체 클릭으로 복사하도록 변경, 완료 피드백은 카드 밖 토스트로 표시(캡처에 미포함). JS 캐시버스터 갱신. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ee5a13163b
commit
7de8f954ad
@ -63,13 +63,11 @@
|
|||||||
head.querySelector('.cc-time').textContent = timeAgo(c.publishedAt);
|
head.querySelector('.cc-time').textContent = timeAgo(c.publishedAt);
|
||||||
head.querySelector('.cc-text').textContent = toPlainText(c.text);
|
head.querySelector('.cc-text').textContent = toPlainText(c.text);
|
||||||
|
|
||||||
const copyBtn = document.createElement('button');
|
// 카드 자체를 클릭하면 복사 (버튼이 캡처 이미지에 찍히지 않도록 버튼 제거)
|
||||||
copyBtn.className = 'cc-btn secondary cc-copy';
|
card.title = '클릭하면 이미지 복사';
|
||||||
copyBtn.textContent = '복사';
|
card.addEventListener('click', () => window.copyCard(card));
|
||||||
copyBtn.addEventListener('click', () => window.copyCard(card, copyBtn)); // Task 5에서 정의
|
|
||||||
|
|
||||||
card.appendChild(head);
|
card.appendChild(head);
|
||||||
card.appendChild(copyBtn);
|
|
||||||
grid.appendChild(card);
|
grid.appendChild(card);
|
||||||
});
|
});
|
||||||
if (window.lucide) window.lucide.createIcons();
|
if (window.lucide) window.lucide.createIcons();
|
||||||
@ -91,29 +89,44 @@
|
|||||||
URL.revokeObjectURL(a.href);
|
URL.revokeObjectURL(a.href);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.copyCard = async function (cardEl, btnEl) {
|
let toastTimer = null;
|
||||||
const original = btnEl.textContent;
|
function showToast(msg) {
|
||||||
btnEl.disabled = true; btnEl.textContent = '복사 중…';
|
let t = document.getElementById('ccToast');
|
||||||
|
if (!t) {
|
||||||
|
t = document.createElement('div');
|
||||||
|
t.id = 'ccToast';
|
||||||
|
t.className = 'cc-toast';
|
||||||
|
document.body.appendChild(t);
|
||||||
|
}
|
||||||
|
t.textContent = msg;
|
||||||
|
t.classList.add('show');
|
||||||
|
if (toastTimer) clearTimeout(toastTimer);
|
||||||
|
toastTimer = setTimeout(() => t.classList.remove('show'), 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.copyCard = async function (cardEl) {
|
||||||
|
if (cardEl.dataset.copying === '1') return; // 중복 클릭 방지
|
||||||
|
cardEl.dataset.copying = '1';
|
||||||
try {
|
try {
|
||||||
const blob = await captureBlob(cardEl);
|
const blob = await captureBlob(cardEl);
|
||||||
if (navigator.clipboard && window.ClipboardItem) {
|
if (navigator.clipboard && window.ClipboardItem) {
|
||||||
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
|
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);
|
||||||
btnEl.textContent = '복사됨 ✓';
|
showToast('복사됨 ✓');
|
||||||
} else {
|
} else {
|
||||||
downloadBlob(blob);
|
downloadBlob(blob);
|
||||||
btnEl.textContent = '다운로드됨';
|
showToast('다운로드됨');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 클립보드 권한 거부 등 → 다운로드 폴백
|
// 클립보드 권한 거부 등 → 다운로드 폴백
|
||||||
try {
|
try {
|
||||||
const blob = await captureBlob(cardEl);
|
const blob = await captureBlob(cardEl);
|
||||||
downloadBlob(blob);
|
downloadBlob(blob);
|
||||||
btnEl.textContent = '다운로드됨';
|
showToast('다운로드됨');
|
||||||
} catch (e2) {
|
} catch (e2) {
|
||||||
btnEl.textContent = '실패';
|
showToast('복사 실패');
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setTimeout(() => { btnEl.disabled = false; btnEl.textContent = original; }, 1500);
|
setTimeout(() => { delete cardEl.dataset.copying; }, 600);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,12 @@
|
|||||||
.cc-time { font-size:11.5px; color:var(--text-3); margin-left:.4rem; }
|
.cc-time { font-size:11.5px; color:var(--text-3); margin-left:.4rem; }
|
||||||
.cc-text { font-size:14px; color:var(--text); margin-top:.35rem; white-space:pre-wrap; word-break:break-word; line-height:1.45; }
|
.cc-text { font-size:14px; color:var(--text); margin-top:.35rem; white-space:pre-wrap; word-break:break-word; line-height:1.45; }
|
||||||
.cc-stats { font-size:12px; color:var(--text-3); margin-top:.5rem; display:flex; gap:1rem; }
|
.cc-stats { font-size:12px; color:var(--text-3); margin-top:.5rem; display:flex; gap:1rem; }
|
||||||
.cc-copy { position:absolute; top:.6rem; right:.6rem; }
|
.comment-card { cursor:pointer; }
|
||||||
|
/* 복사 완료 토스트 — 카드 밖(body)에 떠서 캡처 이미지에 안 찍힘 */
|
||||||
|
.cc-toast { position:fixed; left:50%; bottom:2rem; transform:translateX(-50%) translateY(1rem);
|
||||||
|
background:var(--text); color:var(--surface); padding:.6rem 1.1rem; border-radius:999px;
|
||||||
|
font-size:14px; font-weight:600; opacity:0; pointer-events:none; transition:opacity .15s, transform .15s; z-index:9999; }
|
||||||
|
.cc-toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
|
||||||
/* 모자이크 */
|
/* 모자이크 */
|
||||||
.comment-card.mosaic .cc-avatar { filter: blur(6px); }
|
.comment-card.mosaic .cc-avatar { filter: blur(6px); }
|
||||||
.comment-card.mosaic .cc-author { filter: blur(5px); }
|
.comment-card.mosaic .cc-author { filter: blur(5px); }
|
||||||
@ -37,7 +42,7 @@
|
|||||||
<div layout:fragment="content">
|
<div layout:fragment="content">
|
||||||
<h1 style="font-size:1.5rem;font-weight:700;margin-bottom:.3rem;">댓글 카드</h1>
|
<h1 style="font-size:1.5rem;font-weight:700;margin-bottom:.3rem;">댓글 카드</h1>
|
||||||
<p style="color:var(--text-3);margin-bottom:1.2rem;font-size:14px;">
|
<p style="color:var(--text-3);margin-bottom:1.2rem;font-size:14px;">
|
||||||
유튜브 링크의 댓글을 가져와 카드로 만들고, 프로필·아이디를 모자이크해 영상 소스로 복사하세요.
|
유튜브 링크의 댓글을 가져와 카드로 만들고, 프로필·아이디를 모자이크하세요. <b>카드를 클릭하면 이미지가 복사</b>됩니다(캡컷 등에 Ctrl+V).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="cc-toolbar">
|
<div class="cc-toolbar">
|
||||||
@ -66,7 +71,7 @@
|
|||||||
<th:block layout:fragment="script">
|
<th:block layout:fragment="script">
|
||||||
<!-- DOM→이미지 캡처 (Task 5에서 사용). blur 필터 지원 위해 modern-screenshot 사용. -->
|
<!-- DOM→이미지 캡처 (Task 5에서 사용). blur 필터 지원 위해 modern-screenshot 사용. -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/modern-screenshot@4/dist/index.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/modern-screenshot@4/dist/index.js"></script>
|
||||||
<script th:src="@{/js/comment-cards.js(v=20260629b)}"></script>
|
<script th:src="@{/js/comment-cards.js(v=20260629c)}"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user