added ai评论
This commit is contained in:
1 parent
ec6f05539e
commit
0f7be7d270
152 files changed
+2323
-1277
No files matched your search
@@ -3860,3 +3860,53 @@ html[data-theme="light"] .atk-loading-spinner svg circle {
|
||||
|
||||
|
||||
|
||||
/* AI Comment (Embedded in Artalk) */
|
||||
.atk-comment.atk-ai-comment {
|
||||
/* Subtle distinction background */
|
||||
/* background: var(--bankuai-color); */
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 5px;
|
||||
/* border: 1px solid transparent; Prepare for dark mode */
|
||||
}
|
||||
|
||||
/* Ensure avatar size matches Artalk but with AI flair */
|
||||
.atk-comment.atk-ai-comment .atk-avatar img {
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.atk-comment.atk-ai-comment:hover .atk-avatar img {
|
||||
transform: rotate(10deg);
|
||||
}
|
||||
|
||||
/* Custom AI Badge */
|
||||
.atk-comment.atk-ai-comment .atk-badge {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
font-size: 11px;
|
||||
line-height: 1.4;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #60a5fa, #3b82f6);
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
margin-left: 5px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
/* Dark Mode Adaptation */
|
||||
[data-theme="dark"] .atk-comment.atk-ai-comment {
|
||||
/* background: rgba(255, 255, 255, 0.03); */
|
||||
/* border: 1px solid rgba(255, 255, 255, 0.05); */
|
||||
}
|
||||
|
||||
[data-theme="dark"] .atk-comment.atk-ai-comment .atk-avatar img {
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .ai-comment-card .atk-content p {
|
||||
color: var(--text-content-dark-color);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,89 @@ if (typeof lazyLoadInit === 'function') {
|
||||
|
||||
// 异步初始化 Artalk 并获取评论数据 (Moved to barrage.js)
|
||||
|
||||
// Global Artalk Initialization Function (Supports PJAX)
|
||||
window.initArtalk = function() {
|
||||
if (!document.querySelector("#Comments")) return;
|
||||
|
||||
// Check if configuration exists
|
||||
if (!window.artalkConfig) {
|
||||
console.warn('window.artalkConfig is not defined. Skipping Artalk init.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Artalk library is loaded
|
||||
if (typeof Artalk === 'undefined') {
|
||||
console.warn('Artalk library is not loaded yet. Waiting for bundle...');
|
||||
// Optional: Retry logic could be added here if needed, but usually bundle is loaded by now
|
||||
return;
|
||||
}
|
||||
|
||||
var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
|
||||
// Initialize Artalk
|
||||
window.artalk = Artalk.init({
|
||||
el: window.artalkConfig.el || '#Comments',
|
||||
server: window.artalkConfig.server,
|
||||
site: window.artalkConfig.site,
|
||||
pageKey: window.artalkConfig.pageKey, // Dynamic pageKey from config
|
||||
flatMode: true,
|
||||
darkMode: isDark,
|
||||
emoticons: window.artalkConfig.emoticons
|
||||
});
|
||||
|
||||
// Inject AI Comment
|
||||
window.artalk.on('list-loaded', function() {
|
||||
if (window.artalkConfig.aiComment && !document.querySelector('.atk-ai-comment')) {
|
||||
var listBody = document.querySelector('.atk-list-body') || document.querySelector('.atk-list');
|
||||
if (listBody) {
|
||||
var aiData = window.artalkConfig.aiComment;
|
||||
var aiDiv = document.createElement('div');
|
||||
aiDiv.className = 'atk-comment atk-ai-comment';
|
||||
// Initially empty content for typewriter effect
|
||||
aiDiv.innerHTML = `
|
||||
<div class="atk-avatar">
|
||||
<img src="${aiData.avatar}">
|
||||
</div>
|
||||
<div class="atk-main">
|
||||
<div class="atk-header">
|
||||
<span class="atk-nick">${aiData.name}</span>
|
||||
<span class="atk-badge">BOT</span>
|
||||
<span class="atk-date" title="${aiData.date}">${aiData.date}</span>
|
||||
</div>
|
||||
<div class="atk-body">
|
||||
<div class="atk-content">
|
||||
<p class="ai-content-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
listBody.prepend(aiDiv);
|
||||
|
||||
// Typewriter Effect
|
||||
const contentEl = aiDiv.querySelector('.ai-content-text');
|
||||
const text = aiData.content;
|
||||
let i = 0;
|
||||
|
||||
function type() {
|
||||
if (i < text.length) {
|
||||
contentEl.textContent += text.charAt(i);
|
||||
i++;
|
||||
// Random delay for more natural typing (20-50ms)
|
||||
setTimeout(type, Math.random() * 30 + 20);
|
||||
}
|
||||
}
|
||||
|
||||
// Start typing after a short delay
|
||||
setTimeout(type, 500);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Artalk 初始化完成后,再加载弹幕 (If available)
|
||||
if (typeof isMobile === 'function' && !isMobile() && window.loadBarrager) {
|
||||
window.loadBarrager();
|
||||
}
|
||||
};
|
||||
|
||||
async function fetchHitokoto() {
|
||||
try {
|
||||
|
||||
@@ -176,37 +176,8 @@ document.addEventListener("pjax:complete", function () {
|
||||
// 初始化代码复制
|
||||
initCodeCopy()
|
||||
// 重载评论
|
||||
if (document.querySelector("#Comments")) {
|
||||
var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
// 默认配置作为后备
|
||||
var serverUrl = 'https://artalk.usj.cc';
|
||||
var siteName = '优世界';
|
||||
var emoticons = '/emotion/OwO.json';
|
||||
|
||||
// 尝试从 window.siteConfig 获取配置
|
||||
if (window.siteConfig && window.siteConfig.artalk) {
|
||||
serverUrl = window.siteConfig.artalk.server || serverUrl;
|
||||
siteName = window.siteConfig.artalk.site || siteName;
|
||||
emoticons = window.siteConfig.artalk.emoticons || emoticons;
|
||||
}
|
||||
|
||||
// 保存实例到全局变量 window.artalk
|
||||
window.artalk = Artalk.init({
|
||||
el: '#Comments', // 绑定元素的 Selector
|
||||
server: serverUrl, // 后端地址
|
||||
site: siteName, // 你的站点名
|
||||
// 使用全局变量或 DOM 读取 pageKey
|
||||
// 必须动态获取当前页面的 pid (RelPermalink)
|
||||
pageKey: document.getElementById('data-pid')?.textContent?.trim() || location.pathname,
|
||||
flatMode: true,
|
||||
darkMode: isDark,
|
||||
emoticons: emoticons
|
||||
})
|
||||
|
||||
// Artalk 初始化完成后,再加载弹幕
|
||||
if (!isMobile() && window.loadBarrager) {
|
||||
window.loadBarrager();
|
||||
}
|
||||
if (typeof window.initArtalk === 'function') {
|
||||
window.initArtalk();
|
||||
}
|
||||
// 重载不蒜子统计
|
||||
if (typeof window.bsz_fetch === 'function') {
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
{{ end }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="post-content" id="post-writing" itemprop="articleBody" uk-scrollspy="target: > h2,h3,h4,blockquote,img,table,figure; cls: uk-animation-slide-bottom-small; delay: 100">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
@@ -29,6 +32,7 @@
|
||||
<hr class="uk-divider-icon">
|
||||
<div id="comments" class="comments-area">
|
||||
<!-- 评论区内容 -->
|
||||
|
||||
{{ if or (eq .Type "about") (eq .Type "post") }}
|
||||
{{ partial "artalk.html" . }}
|
||||
{{ end }}
|
||||
|
||||
@@ -21,25 +21,32 @@
|
||||
<!-- JS -->
|
||||
<!-- <script src="/js/Artalk.js"></script> -->
|
||||
<script>
|
||||
// 等待 DOM 加载完成,确保 Artalk.js (在 footer 的 bundle.js 中) 已加载
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (document.querySelector("#Comments")) {
|
||||
// 检查 Artalk 是否已定义
|
||||
if (typeof Artalk !== 'undefined') {
|
||||
var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||
// 保存实例到全局变量 window.artalk
|
||||
window.artalk = Artalk.init({
|
||||
el: '#Comments',
|
||||
server: '{{ .Site.Params.artalk.server }}',
|
||||
site: '{{ .Site.Params.artalk.site }}',
|
||||
pageKey: '{{ .RelPermalink }}',
|
||||
flatMode: true,
|
||||
darkMode: isDark,
|
||||
emoticons: '{{ .Site.Params.artalk.emoticons | relURL }}'
|
||||
});
|
||||
} else {
|
||||
console.error('Artalk is not defined. Bundle js may not be loaded yet.');
|
||||
}
|
||||
// Configuration for Artalk and AI Comment
|
||||
window.artalkConfig = {
|
||||
el: '#Comments',
|
||||
server: '{{ .Site.Params.artalk.server }}',
|
||||
site: '{{ .Site.Params.artalk.site }}',
|
||||
pageKey: '{{ .RelPermalink }}',
|
||||
emoticons: '{{ .Site.Params.artalk.emoticons | relURL }}',
|
||||
aiComment: {{ if .Params.ai_comment }}
|
||||
{{ $avatar := .Site.Params.ai.avatar }}
|
||||
{{ if not $avatar }}{{ $avatar = .Site.Params.author.avatar }}{{ end }}
|
||||
{{ if not $avatar }}{{ $avatar = "https://cravatar.cn/avatar/unknown?d=mp" }}{{ end }}
|
||||
{{ dict "content" .Params.ai_comment "avatar" $avatar "name" (.Site.Params.ai.name | default "AI Assistant") "date" (.Date.Format "2006-01-02") | jsonify | safeJS }}
|
||||
{{ else }}null{{ end }}
|
||||
};
|
||||
|
||||
// Execute Initialization immediately if function exists (PJAX re-execution),
|
||||
// otherwise wait for DOMContentLoaded (Initial load)
|
||||
(function() {
|
||||
if (typeof window.initArtalk === 'function') {
|
||||
window.initArtalk();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
if (typeof window.initArtalk === 'function') {
|
||||
window.initArtalk();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
Reference in new issue
Block a user