/** * AKSRT Comment Actions client * * REST aksrt/v1: like / delete / moderate / pin. * Edit uses moveForm (#respond) via comment-move-form.js — not inline textarea. * Submit owned by assets/js/core/comments.js (single submit contract). * * Markup (aksrt_comment_callback): * li.aksrt-comment[data-comment-id] * .comment-header .aksrt-comment__like[data-comment-action=like] * .comment-content#comment-content-{id} * .comt-meta [data-comment-action=pin|approve|hold|spam|delete] * * @package AKSRT */ (function () { 'use strict'; if (!window.aksrtData) return; var COMMENT_SELECTOR = '.aksrt-comment, .comment'; var CONTENT_SELECTOR = '.aksrt-comment__text, .comment-content'; var REST_BASE = (aksrtData.siteUrl || '').replace(/\/$/, '') + '/wp-json/aksrt/v1'; var REST_NONCE = aksrtData.restNonce || ''; function restPost(endpoint, body) { return fetch(REST_BASE + endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': REST_NONCE }, body: JSON.stringify(body), credentials: 'same-origin' }).then(function (r) { return r.json(); }); } function notify(message, type) { if (typeof window.AksrtToast === 'function') { window.AksrtToast(message, type || 'info'); return; } if (typeof window.aksrtToast === 'function') { window.aksrtToast(message, type || 'info'); return; } if (typeof window.showToast === 'function') { window.showToast(message, type || 'info'); return; } if (type === 'error') { window.alert(message); } } function getCommentId(el) { return parseInt(el.getAttribute('data-comment-id') || (el.id || '').replace('comment-', ''), 10) || 0; } // ── Comment actions (event delegation) ─────────────────────────── document.addEventListener('click', function (e) { var actionBtn = e.target.closest('[data-comment-action]'); if (!actionBtn) return; var action = actionBtn.getAttribute('data-comment-action'); var commentEl = actionBtn.closest(COMMENT_SELECTOR); if (!commentEl) return; var commentId = getCommentId(commentEl); if (!commentId) return; // edit is handled by comment-move-form.js (moveForm into #respond). switch (action) { case 'like': handleLike(actionBtn, commentId); break; case 'edit': break; case 'delete': handleDelete(commentEl, commentId); break; case 'pin': handlePin(commentEl, actionBtn, commentId); break; case 'approve': case 'hold': case 'spam': handleModerate(commentEl, commentId, action); break; } }); function handleLike(btn, commentId) { if (btn.dataset.busy === '1') return; btn.dataset.busy = '1'; var nextActive = btn.getAttribute('data-active') !== '1'; restPost('/comment/like', { comment_id: commentId, active: nextActive }) .then(function (result) { if (!result.success) { notify((result.data && result.data.message) || result.message || '操作失败', 'error'); return; } var active = !!(result.data && result.data.active); var count = (result.data && result.data.count) || 0; btn.setAttribute('data-active', active ? '1' : '0'); btn.setAttribute('aria-pressed', active ? 'true' : 'false'); btn.classList.toggle('is-active', active); var icon = btn.querySelector('i'); if (icon) { icon.classList.toggle('fas', active); icon.classList.toggle('far', !active); } var countEl = btn.querySelector('.aksrt-comment__like-count'); if (countEl) { countEl.textContent = String(count); if (count > 0) { countEl.removeAttribute('hidden'); } else { countEl.setAttribute('hidden', ''); } } }) .catch(function () { notify('网络错误', 'error'); }) .finally(function () { btn.dataset.busy = ''; }); } function handleDelete(commentEl, commentId) { var msg = (window.aksrt && aksrt.__) ? aksrt.__('comment_confirm_delete', '确定要删除这条评论吗?') : '确定要删除这条评论吗?'; var doDelete = function () { restPost('/comment/delete', { comment_id: commentId }) .then(function (result) { if (result.success) { commentEl.style.transition = 'opacity 0.3s, max-height 0.3s'; commentEl.style.maxHeight = commentEl.scrollHeight + 'px'; requestAnimationFrame(function () { commentEl.style.opacity = '0'; commentEl.style.maxHeight = '0'; commentEl.style.overflow = 'hidden'; }); setTimeout(function () { commentEl.remove(); var countEl = document.querySelector('.comments-count'); if (countEl) { var m = (countEl.textContent || '').match(/(\d+)/); if (m) { var n = Math.max(0, parseInt(m[1], 10) - 1); countEl.textContent = (countEl.textContent || '').replace(m[1], String(n)); } } }, 300); } else { notify((result.data && result.data.message) || result.message || '删除失败', 'error'); } }) .catch(function () { notify('网络错误', 'error'); }); }; if (window.aksrt && aksrt.confirm) { aksrt.confirm(msg).then(function (ok) { if (ok) doDelete(); }); } else if (window.confirm(msg)) { doDelete(); } } function handlePin(commentEl, btn, commentId) { var nextPinned = btn.getAttribute('data-pinned') !== '1'; restPost('/comment/pin', { comment_id: commentId, pinned: nextPinned }) .then(function (result) { if (!result.success) { notify((result.data && result.data.message) || result.message || '操作失败', 'error'); return; } var pinned = !!(result.data && result.data.pinned); btn.setAttribute('data-pinned', pinned ? '1' : '0'); btn.innerHTML = ' ' + (pinned ? '取消置顶' : '置顶'); commentEl.classList.toggle('aksrt-comment--pinned', pinned); syncPinnedBadge(commentEl, pinned); notify(result.message || (pinned ? '评论已置顶。' : '已取消置顶。'), 'success'); }) .catch(function () { notify('网络错误', 'error'); }); } function syncPinnedBadge(commentEl, pinned) { var header = commentEl.querySelector('.aksrt-comment__header, .comment-header'); if (!header) return; var badge = header.querySelector('.aksrt-comment__badge--pinned'); if (pinned && !badge) { badge = document.createElement('span'); badge.className = 'aksrt-comment__badge aksrt-comment__badge--pinned'; badge.innerHTML = ' 置顶'; var time = header.querySelector('.aksrt-comment__time'); header.insertBefore(badge, time || null); } else if (!pinned && badge) { badge.remove(); } } function handleModerate(commentEl, commentId, action) { restPost('/comment/moderate', { comment_id: commentId, status: action }) .then(function (result) { if (result.success) { commentEl.setAttribute('data-comment-status', result.data.status === 'approved' ? '1' : (result.data.status === 'spam' ? 'spam' : '0')); commentEl.style.opacity = '0.6'; setTimeout(function () { commentEl.style.opacity = '1'; }, 400); if (action === 'approve') { var note = commentEl.querySelector('.awaiting-moderation'); if (note) note.remove(); } notify(result.message || '操作成功。', 'success'); } else { notify((result.data && result.data.message) || result.message || '操作失败', 'error'); } }) .catch(function () { notify('网络错误', 'error'); }); } })();