refactor: posts/show.html 内联 JS 拆分为独立文件
- 拆分 926 行内联 JS 为 5 个独立模块文件 - post-view.js: Vditor 渲染 + 提交审核按钮 (~50 行) - post-energize.js: 赋能按钮 + 弹窗 (~76 行) - post-reactions.js: 赞/踩系统 (~71 行) - post-favorite.js: 收藏按钮 + 收藏夹弹窗 (~218 行) - post-comments.js: 评论系统 (~456 行) - show.html 从 1080 行缩减至 159 行
This commit is contained in:
218
templates/MetaLab-2026/static/js/post-favorite.js
Normal file
218
templates/MetaLab-2026/static/js/post-favorite.js
Normal file
@ -0,0 +1,218 @@
|
||||
// 收藏按钮(弹窗选择收藏夹)
|
||||
(function() {
|
||||
var favBtn = document.getElementById('favBtn');
|
||||
var favCountEl = document.getElementById('favCount');
|
||||
var container = document.getElementById('postReactions');
|
||||
var overlay = document.getElementById('favOverlay');
|
||||
var closeBtn = document.getElementById('favClose');
|
||||
var folderListEl = document.getElementById('favFolderCheckList');
|
||||
var newInput = document.getElementById('favNewInput');
|
||||
var newBtn = document.getElementById('favNewConfirm');
|
||||
if (!favBtn || !container) return;
|
||||
|
||||
var postId = container.dataset.postId;
|
||||
var isFavorited = false;
|
||||
var currentFolderId = null;
|
||||
var loading = false;
|
||||
|
||||
function updateBtn(favorited) {
|
||||
isFavorited = favorited;
|
||||
if (favorited) {
|
||||
favBtn.classList.add('active');
|
||||
} else {
|
||||
favBtn.classList.remove('active');
|
||||
currentFolderId = null;
|
||||
}
|
||||
}
|
||||
|
||||
function loadStatus() {
|
||||
return fetch('/api/posts/' + postId + '/folder-status')
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
if (d.success && d.data && d.data.favorited) {
|
||||
currentFolderId = d.data.folder_id;
|
||||
updateBtn(true);
|
||||
}
|
||||
})
|
||||
.catch(function() {});
|
||||
}
|
||||
|
||||
function renderFolderList(folders) {
|
||||
if (!folders || folders.length === 0) {
|
||||
folderListEl.innerHTML = '<div class="fav-empty">暂无收藏夹,请在下方创建</div>';
|
||||
return;
|
||||
}
|
||||
var html = '';
|
||||
folders.forEach(function(f) {
|
||||
var isActive = currentFolderId === f.id;
|
||||
html += '<div class="fav-folder-option' + (isActive ? ' active' : '') + '" data-id="' + f.id + '">'
|
||||
+ '<span class="fav-folder-opt-name">' + escapeHtml(f.name) + (f.is_default ? ' <small>(默认)</small>' : '') + '</span>'
|
||||
+ '<span class="fav-folder-opt-count">' + (f.item_count || 0) + ' 篇</span>'
|
||||
+ '</div>';
|
||||
});
|
||||
folderListEl.innerHTML = html;
|
||||
}
|
||||
|
||||
function showModal() {
|
||||
if (!overlay) { handleNoModal(); return; }
|
||||
loading = true;
|
||||
overlay.style.display = 'flex';
|
||||
folderListEl.innerHTML = '<div class="fav-loading">加载中...</div>';
|
||||
|
||||
api('GET', '/api/folders')
|
||||
.then(function(d) {
|
||||
var folders = (d.success && d.data && d.data.folders) ? d.data.folders : [];
|
||||
renderFolderList(folders);
|
||||
loading = false;
|
||||
})
|
||||
.catch(function() {
|
||||
folderListEl.innerHTML = '<div class="fav-loading fav-error">加载失败,请重试</div>';
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function hideModal() {
|
||||
if (overlay) overlay.style.display = 'none';
|
||||
loading = false;
|
||||
}
|
||||
|
||||
function handleNoModal() {
|
||||
if (!getCSRFToken()) {
|
||||
window.location.href = '/auth/login?redirect=/posts/' + postId;
|
||||
return;
|
||||
}
|
||||
favBtn.disabled = true;
|
||||
api('POST', '/api/posts/' + postId + '/favorite')
|
||||
.then(function(d) {
|
||||
favBtn.disabled = false;
|
||||
if (d.success) {
|
||||
var f = d.data && d.data.favorited;
|
||||
updateBtn(f);
|
||||
if (favCountEl && d.data && typeof d.data.favorites_count === 'number') {
|
||||
favCountEl.textContent = d.data.favorites_count;
|
||||
} else if (favCountEl) {
|
||||
var cur = parseInt(favCountEl.textContent) || 0;
|
||||
favCountEl.textContent = f ? cur + 1 : Math.max(0, cur - 1);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(function() { favBtn.disabled = false; });
|
||||
}
|
||||
|
||||
function addToFolder(folderId) {
|
||||
if (loading) return;
|
||||
loading = true;
|
||||
api('POST', '/api/folders/' + folderId + '/posts', { post_id: parseInt(postId) })
|
||||
.then(function(d) {
|
||||
loading = false;
|
||||
if (d.success) {
|
||||
currentFolderId = folderId;
|
||||
updateBtn(true);
|
||||
if (favCountEl) favCountEl.textContent = (parseInt(favCountEl.textContent) || 0) + 1;
|
||||
hideModal();
|
||||
} else {
|
||||
alert(d.message || '操作失败');
|
||||
}
|
||||
})
|
||||
.catch(function() { loading = false; });
|
||||
}
|
||||
|
||||
function removeFromFolder(folderId) {
|
||||
if (loading) return;
|
||||
if (!confirm('确定取消收藏吗?')) return;
|
||||
loading = true;
|
||||
api('DELETE', '/api/folders/' + folderId + '/posts/' + postId)
|
||||
.then(function(d) {
|
||||
loading = false;
|
||||
if (d.success) {
|
||||
currentFolderId = null;
|
||||
updateBtn(false);
|
||||
if (favCountEl) favCountEl.textContent = Math.max(0, (parseInt(favCountEl.textContent) || 0) - 1);
|
||||
hideModal();
|
||||
} else {
|
||||
alert(d.message || '操作失败');
|
||||
}
|
||||
})
|
||||
.catch(function() { loading = false; });
|
||||
}
|
||||
|
||||
function createAndAdd(name) {
|
||||
if (loading) return;
|
||||
loading = true;
|
||||
newBtn.disabled = true;
|
||||
newBtn.textContent = '创建中...';
|
||||
api('POST', '/api/folders', { name: name, description: '', is_public: false })
|
||||
.then(function(d) {
|
||||
if (!d.success) {
|
||||
loading = false;
|
||||
newBtn.disabled = false;
|
||||
newBtn.textContent = '创建并收藏';
|
||||
alert(d.message || '创建失败');
|
||||
return;
|
||||
}
|
||||
var newId = d.data && d.data.id;
|
||||
return api('POST', '/api/folders/' + newId + '/posts', { post_id: parseInt(postId) })
|
||||
.then(function(d2) {
|
||||
loading = false;
|
||||
newBtn.disabled = false;
|
||||
newBtn.textContent = '创建并收藏';
|
||||
if (d2.success) {
|
||||
currentFolderId = newId;
|
||||
updateBtn(true);
|
||||
if (favCountEl) favCountEl.textContent = (parseInt(favCountEl.textContent) || 0) + 1;
|
||||
hideModal();
|
||||
} else {
|
||||
alert(d2.message || '操作失败');
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function() {
|
||||
loading = false;
|
||||
newBtn.disabled = false;
|
||||
newBtn.textContent = '创建并收藏';
|
||||
});
|
||||
}
|
||||
|
||||
// 事件:点击收藏按钮 → 打开弹窗
|
||||
favBtn.addEventListener('click', function() {
|
||||
if (!getCSRFToken()) { window.location.href = '/auth/login?redirect=/posts/' + postId; return; }
|
||||
showModal();
|
||||
});
|
||||
|
||||
// 事件:关闭弹窗
|
||||
if (closeBtn) closeBtn.addEventListener('click', hideModal);
|
||||
if (overlay) overlay.addEventListener('click', function(e) {
|
||||
if (e.target === overlay) hideModal();
|
||||
});
|
||||
|
||||
// 事件:点击收藏夹选项
|
||||
if (folderListEl) {
|
||||
folderListEl.addEventListener('click', function(e) {
|
||||
var option = e.target.closest('.fav-folder-option');
|
||||
if (!option) return;
|
||||
var folderId = parseInt(option.getAttribute('data-id'));
|
||||
if (isNaN(folderId)) return;
|
||||
if (currentFolderId === folderId) {
|
||||
removeFromFolder(folderId);
|
||||
} else {
|
||||
addToFolder(folderId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 事件:新建收藏夹
|
||||
if (newBtn && newInput) {
|
||||
newBtn.addEventListener('click', function() {
|
||||
var name = newInput.value.trim();
|
||||
if (!name) { alert('请输入收藏夹名称'); return; }
|
||||
if (name.length > 50) { alert('收藏夹名称不能超过 50 个字符'); return; }
|
||||
createAndAdd(name);
|
||||
});
|
||||
newInput.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') newBtn.click();
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化
|
||||
loadStatus();
|
||||
})();
|
||||
Reference in New Issue
Block a user