/** * OSS Community - 文章抽屉交互逻辑 */ document.addEventListener('DOMContentLoaded', () => { initPostDrawer(); }); let drawerInitialized = false; let currentDrawerPostId = null; let drawerPollTimer = null; function initPostDrawer() { if (drawerInitialized) return; drawerInitialized = true; createDrawerElements(); // 全局点击事件委托 document.addEventListener('click', (e) => { const postCard = e.target.closest('.post-card'); if (postCard && postCard.dataset.postId) { e.preventDefault(); e.stopPropagation(); openPostDrawer(postCard.dataset.postId); } }); const overlay = document.getElementById('postDrawerOverlay'); if (overlay) overlay.addEventListener('click', closePostDrawer); const closeBtn = document.getElementById('postDrawerClose'); if (closeBtn) closeBtn.addEventListener('click', closePostDrawer); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closePostDrawer(); }); // 监听轮询数据更新抽屉内的 views/likes if (window.Polling) { window.Polling.on('posts', (data) => { if (!data.posts || !currentDrawerPostId) return; const post = data.posts.find(p => p.id == currentDrawerPostId); if (post) updateDrawerStats(post); }); } } function createDrawerElements() { if (document.getElementById('postDrawerOverlay')) return; // 创建遮罩层 const overlay = document.createElement('div'); overlay.id = 'postDrawerOverlay'; overlay.className = 'post-drawer-overlay'; // 创建抽屉 const drawer = document.createElement('div'); drawer.id = 'postDrawer'; drawer.className = 'post-drawer'; drawer.innerHTML = `

`; document.body.appendChild(overlay); document.body.appendChild(drawer); // 绑定关闭按钮 document.getElementById('postDrawerClose').addEventListener('click', closePostDrawer); } async function openPostDrawer(postId) { const drawer = document.getElementById('postDrawer'); const overlay = document.getElementById('postDrawerOverlay'); const titleEl = document.getElementById('postDrawerTitle'); const metaEl = document.getElementById('postDrawerMeta'); const contentEl = document.getElementById('postDrawerContent'); const footerEl = document.getElementById('postDrawerFooter'); if (!drawer || !overlay) return; // 显示加载状态 titleEl.textContent = '加载中...'; metaEl.innerHTML = ''; contentEl.innerHTML = '
正在加载文章内容...
'; footerEl.innerHTML = ''; // 显示抽屉(先滑入,再加载内容) overlay.classList.add('active'); drawer.classList.add('active'); document.body.style.overflow = 'hidden'; try { const response = await fetch(`api/index.php?action=post&id=${postId}`); if (!response.ok) throw new Error('加载失败'); const data = await response.json(); if (!data.post) throw new Error('帖子不存在'); const post = data.post; const replies = data.replies || []; currentDrawerPostId = post.id; // 更新标题和元信息 titleEl.textContent = post.title; metaEl.innerHTML = `
${post.username.charAt(0).toUpperCase()}
${escapeHtml(post.username)}
${formatDate(post.created_at)}
${escapeHtml(post.category_name)} `; // 更新内容(使用 marked 解析 Markdown) if (typeof marked !== 'undefined') { contentEl.innerHTML = marked.parse(post.content); } else { contentEl.innerHTML = escapeHtml(post.content).replace(/\n/g, '
'); } // 更新底部统计 footerEl.innerHTML = `
${post.views} 浏览
${post.likes} 点赞
${replies.length} 回复
`; // 如果有回复,在内容下方显示 if (replies.length > 0) { contentEl.innerHTML += `

回复 (${replies.length})

${replies.map(reply => `
${reply.username.charAt(0).toUpperCase()}
${escapeHtml(reply.username)} ${formatDate(reply.created_at)}
${escapeHtml(reply.content).replace(/\n/g, '
')}
`).join('')} `; } } catch (error) { console.error('Failed to load post:', error); contentEl.innerHTML = `

加载失败

${error.message || '未知错误,请稍后重试'}

`; } } function closePostDrawer() { const drawer = document.getElementById('postDrawer'); const overlay = document.getElementById('postDrawerOverlay'); if (drawer) drawer.classList.remove('active'); if (overlay) overlay.classList.remove('active'); document.body.style.overflow = ''; currentDrawerPostId = null; } function updateDrawerStats(post) { const footerEl = document.getElementById('postDrawerFooter'); if (!footerEl || !currentDrawerPostId) return; footerEl.innerHTML = `
${post.views} 浏览
${post.likes} 点赞
${post.reply_count || 0} 回复
`; } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function formatDate(dateString) { const date = new Date(dateString); const now = new Date(); const diff = now - date; const minutes = Math.floor(diff / 60000); const hours = Math.floor(diff / 3600000); const days = Math.floor(diff / 86400000); if (minutes < 1) return '刚刚'; if (minutes < 60) return `${minutes} 分钟前`; if (hours < 24) return `${hours} 小时前`; if (days < 7) return `${days} 天前`; return date.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }); }