mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
Create TwikooComments.astro
This commit is contained in:
@@ -0,0 +1,245 @@
|
|||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
envId: string;
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { envId, path } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="mt-8">
|
||||||
|
<h2 class="mb-4 text-lg font-medium text-zinc-900 dark:text-zinc-100">评论</h2>
|
||||||
|
<div
|
||||||
|
id="tcomment"
|
||||||
|
class="twikoo-container rounded-lg border p-4 dark:border-zinc-700"
|
||||||
|
data-env-id={envId}
|
||||||
|
data-path={path || 'auto'}
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-center py-8 text-zinc-500 dark:text-zinc-400">
|
||||||
|
<div class="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mr-2"></div>
|
||||||
|
正在加载评论...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 使用 defer 属性延迟执行,确保 DOM 就绪 -->
|
||||||
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/twikoo@1.6.32/dist/twikoo.all.min.js"
|
||||||
|
defer
|
||||||
|
></script>
|
||||||
|
|
||||||
|
<!-- 内联脚本处理初始化 -->
|
||||||
|
<script is:inline>
|
||||||
|
// 全局变量存储重试次数
|
||||||
|
window.twikooRetryCount = 0;
|
||||||
|
window.maxRetries = 20; // 最大重试次数
|
||||||
|
|
||||||
|
function waitForTwikoo(callback, retryCount = 0) {
|
||||||
|
if (typeof window.twikoo !== 'undefined') {
|
||||||
|
callback();
|
||||||
|
} else if (retryCount < window.maxRetries) {
|
||||||
|
setTimeout(() => waitForTwikoo(callback, retryCount + 1), 200);
|
||||||
|
} else {
|
||||||
|
console.error('Twikoo failed to load after maximum retries');
|
||||||
|
showErrorMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showErrorMessage() {
|
||||||
|
const containers = document.querySelectorAll('#tcomment');
|
||||||
|
containers.forEach(container => {
|
||||||
|
if (container) {
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="text-center py-8 text-red-500">
|
||||||
|
<p>评论系统加载失败</p>
|
||||||
|
<button onclick="location.reload()" class="mt-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 text-sm">
|
||||||
|
重新加载
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeTwikoo() {
|
||||||
|
const container = document.getElementById('tcomment');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
console.warn('Twikoo container (#tcomment) not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const envId = container.getAttribute('data-env-id');
|
||||||
|
const path = container.getAttribute('data-path');
|
||||||
|
|
||||||
|
if (!envId) {
|
||||||
|
console.error('Twikoo envId not provided');
|
||||||
|
container.innerHTML = '<div class="text-center py-8 text-red-500">评论系统配置错误</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 清理容器
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
// 初始化 Twikoo
|
||||||
|
window.twikoo.init({
|
||||||
|
envId: envId,
|
||||||
|
el: '#tcomment',
|
||||||
|
path: path === 'auto' ? location.pathname : path,
|
||||||
|
lang: 'zh-CN'
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Twikoo initialized successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to initialize Twikoo:', error);
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="text-center py-8 text-red-500">
|
||||||
|
<p>评论系统初始化失败</p>
|
||||||
|
<p class="text-sm mt-1">${error.message}</p>
|
||||||
|
<button onclick="location.reload()" class="mt-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 text-sm">
|
||||||
|
重新加载
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePageInit() {
|
||||||
|
// 重置重试计数
|
||||||
|
window.twikooRetryCount = 0;
|
||||||
|
|
||||||
|
// 等待 Twikoo 脚本加载完成后初始化
|
||||||
|
waitForTwikoo(initializeTwikoo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首次加载处理
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', handlePageInit);
|
||||||
|
} else {
|
||||||
|
// DOM 已经准备就绪,延迟一点执行以确保所有脚本都加载完成
|
||||||
|
setTimeout(handlePageInit, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Astro ViewTransitions 支持
|
||||||
|
document.addEventListener('astro:after-swap', () => {
|
||||||
|
console.log('Page swapped, reinitializing Twikoo');
|
||||||
|
setTimeout(handlePageInit, 150);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 页面可见性变化处理(可选)
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (!document.hidden) {
|
||||||
|
const container = document.getElementById('tcomment');
|
||||||
|
if (container && container.children.length === 0) {
|
||||||
|
console.log('Page became visible, checking Twikoo');
|
||||||
|
setTimeout(handlePageInit, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
.twikoo-container {
|
||||||
|
font-family: inherit;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .twikoo-container {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框样式 */
|
||||||
|
.dark .tk-content textarea,
|
||||||
|
.dark .tk-input input {
|
||||||
|
background-color: rgb(39 39 42) !important;
|
||||||
|
border-color: rgb(63 63 70) !important;
|
||||||
|
color: rgb(228 228 231) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tk-content textarea:focus,
|
||||||
|
.dark .tk-input input:focus {
|
||||||
|
border-color: rgb(96 165 250) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.dark .tk-submit {
|
||||||
|
background-color: rgb(24 24 27) !important;
|
||||||
|
border-color: rgb(63 63 70) !important;
|
||||||
|
color: rgb(228 228 231) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tk-submit:hover {
|
||||||
|
background-color: rgb(39 39 42) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 评论区域样式 */
|
||||||
|
.dark .tk-comment,
|
||||||
|
.dark .tk-replies-wrap {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border-color: rgb(63 63 70) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tk-comment .tk-main {
|
||||||
|
color: rgb(228 228 231) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tk-comment .tk-meta span {
|
||||||
|
color: rgb(161 161 170) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 链接样式 */
|
||||||
|
.dark .tk-comment a {
|
||||||
|
color: rgb(96 165 250) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .tk-comment a:hover {
|
||||||
|
color: rgb(147 197 253) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表情包容器 */
|
||||||
|
.dark .tk-owo-container {
|
||||||
|
background-color: rgb(39 39 42) !important;
|
||||||
|
border-color: rgb(63 63 70) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签和额外信息 */
|
||||||
|
.dark .tk-tag,
|
||||||
|
.dark .tk-extras {
|
||||||
|
color: rgb(161 161 170) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 字体和边框圆角 */
|
||||||
|
.tk-comment,
|
||||||
|
.tk-content,
|
||||||
|
.tk-input {
|
||||||
|
font-family: 'Geist', system-ui, sans-serif !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tk-content textarea,
|
||||||
|
.tk-input input,
|
||||||
|
.tk-submit,
|
||||||
|
.tk-comment,
|
||||||
|
.tk-owo-container {
|
||||||
|
border-radius: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tk-comment {
|
||||||
|
margin-bottom: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载状态 */
|
||||||
|
.dark .tk-loading {
|
||||||
|
color: rgb(161 161 170) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载动画 */
|
||||||
|
.animate-spin {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user