feat(artalk): 增强评论系统功能与多语言支持
- 引入 Artalk 多语言包支持中英文切换 - 配置评论区域支持多语言提示与界面文本 - 优化编辑器功能,启用 Markdown、表情、@提醒等 - 改进评论时间显示逻辑,支持相对时间与本地化格式 - 添加管理员评论徽章标识 - 增强暗色模式与移动端适配样式 - 优化 CSS 样式,包括链接、输入框、工具栏等视觉效果 - 完善 Artalk 实例销毁逻辑,提升稳定性 - 移除旧版语言更新方法,统一通过配置管理 - 删除冗余 Avatar 样式以简化维护
This commit is contained in:
@@ -287,6 +287,9 @@
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
<script src="js/config.js?version=20251125"></script>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/artalk/2.9.1/Artalk.js"></script>
|
||||
<!-- 引入多语言包(按需) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/artalk@latest/dist/i18n/zh-cn.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/artalk@latest/dist/i18n/en.js"></script>
|
||||
<script src="js/about.js?version=20251125"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -124,7 +124,6 @@
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
/* 修改发送按钮默认显示为"发送" */
|
||||
.atk-send-btn:before {
|
||||
content: "发送" !important;
|
||||
}
|
||||
@@ -173,12 +172,6 @@
|
||||
border-bottom: 1px solid rgba(108, 92, 231, 0.2) !important;
|
||||
}
|
||||
|
||||
.atk-avatar {
|
||||
border-radius: 50% !important;
|
||||
box-shadow: 0 0 10px rgba(108, 92, 231, 0.2) !important;
|
||||
transition: all 0.3s ease;
|
||||
object-fit: cover; /* 修复头像拉伸问题 */
|
||||
}
|
||||
|
||||
.atk-comment .atk-header {
|
||||
padding: 0 !important;
|
||||
@@ -336,11 +329,6 @@
|
||||
color: #00cec9 !important;
|
||||
}
|
||||
|
||||
[data-theme="night"] .atk-avatar {
|
||||
border: 2px solid #00cec9 !important;
|
||||
box-shadow: 0 0 10px rgba(0, 206, 201, 0.3) !important;
|
||||
}
|
||||
|
||||
/* Mobile specific styles */
|
||||
.atk-mobile .atk-main-editor {
|
||||
border-radius: 16px !important;
|
||||
@@ -514,6 +502,33 @@
|
||||
color: #ef4444 !important;
|
||||
}
|
||||
|
||||
|
||||
/* 评论内容链接样式 */
|
||||
.atk-comment-content a {
|
||||
color: #3498db;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.atk-comment-content a:hover {
|
||||
color: #2980b9;
|
||||
}
|
||||
|
||||
/* 更圆润的输入框 */
|
||||
.atk-editor-wrap .atk-editor-textarea {
|
||||
border-radius: 12px !important;
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
/* 工具栏图标间距优化 */
|
||||
.atk-editor-toolbar .atk-btn {
|
||||
margin: 2px !important;
|
||||
}
|
||||
|
||||
/* 暗色模式下聚焦边框 */
|
||||
.atk-dark .atk-editor-textarea:focus {
|
||||
box-shadow: 0 0 0 2px rgba(66, 153, 225, 0.5) !important;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.atk-header {
|
||||
|
||||
141
js/about.js
141
js/about.js
@@ -528,31 +528,112 @@ class UIManager {
|
||||
initArtalk() {
|
||||
const isHttps = location.protocol === 'https:';
|
||||
const isLocal = !!(window.SiteConfig?.dev?.isLocal);
|
||||
const lang = getStoredLanguage();
|
||||
if (!isHttps || isLocal) {
|
||||
const lang = getStoredLanguage();
|
||||
const msg = lang === 'zh' ? '当前评论区已关闭' : 'Comments are closed';
|
||||
$('#artalk-container').html(`<div style="text-align:center;color:#999;padding:20px;">${msg}</div>`);
|
||||
return;
|
||||
}
|
||||
if (typeof Artalk !== 'undefined' && window.SiteConfig?.artalk) {
|
||||
try {
|
||||
Artalk.init({
|
||||
const artalkConfig = {
|
||||
el: '#artalk-container',
|
||||
pageKey: '/about.html',
|
||||
pageTitle: '关于我 - Honesty',
|
||||
server: window.SiteConfig.artalk.server,
|
||||
site: window.SiteConfig.artalk.site,
|
||||
darkMode: document.documentElement.getAttribute('data-theme') === 'night'
|
||||
});
|
||||
// 多语言支持
|
||||
locale: lang === 'zh' ? 'zh-CN' : 'en-US',
|
||||
|
||||
// 主题支持
|
||||
darkMode: document.documentElement.getAttribute('data-theme') === 'night',
|
||||
|
||||
// 编辑器增强配置
|
||||
editor: {
|
||||
// 启用 Markdown
|
||||
markdown: true,
|
||||
|
||||
// 自定义占位符(支持多语言)
|
||||
placeholder: lang === 'zh' ? '说点什么吧...支持 Markdown 语法,可 @用户、发送表情' : 'Leave a comment... Supports Markdown, @mentions, and Send 😊',
|
||||
|
||||
// 发送按钮文字(多语言)
|
||||
sendBtn: lang === 'zh' ? '发送' : 'Send',
|
||||
|
||||
// 表情面板
|
||||
emoji: {
|
||||
// 使用默认表情包
|
||||
preset: 'twemoji'
|
||||
},
|
||||
|
||||
// 启用 @ 用户提醒功能
|
||||
mention: true,
|
||||
|
||||
// 自动聚焦(仅桌面端)
|
||||
autoFocus: !('ontouchstart' in window),
|
||||
|
||||
// 限制编辑器高度
|
||||
maxHeight: 200,
|
||||
|
||||
// 工具栏
|
||||
toolbar: [
|
||||
'bold', 'italic', 'strike', 'link',
|
||||
'blockquote', 'code', 'codeblock',
|
||||
'ol', 'ul', 'hr',
|
||||
'emoji', 'mention'
|
||||
]
|
||||
},
|
||||
|
||||
// 评论格式化函数
|
||||
commentFormatter: (comment) => {
|
||||
// 美化时间显示
|
||||
const formatTime = (dateStr) => {
|
||||
const date = new Date(dateStr);
|
||||
const now = new Date();
|
||||
const diffSec = Math.floor((now - date) / 1000);
|
||||
|
||||
if (diffSec < 60) return lang === 'zh' ? '刚刚' : 'Just now';
|
||||
if (diffSec < 3600) return lang === 'zh' ? `${Math.floor(diffSec / 60)}分钟前` : `${Math.floor(diffSec / 60)} minutes ago`;
|
||||
if (diffSec < 86400) return lang === 'zh' ? `${Math.floor(diffSec / 3600)}小时前` : `${Math.floor(diffSec / 3600)} hours ago`;
|
||||
|
||||
const isToday = date.toDateString() === now.toDateString();
|
||||
if (isToday) return lang === 'zh' ?
|
||||
`今天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}` :
|
||||
`Today ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
|
||||
|
||||
const isYesterday = new Date(now - 86400000).toDateString() === date.toDateString();
|
||||
if (isYesterday) return lang === 'zh' ?
|
||||
`昨天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}` :
|
||||
`Yesterday ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
|
||||
|
||||
return date.toLocaleString(lang === 'zh' ? 'zh-CN' : 'en-US', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}).replace(/\//g, '-');
|
||||
};
|
||||
|
||||
// 如果是管理员,添加徽章
|
||||
if (comment.is_admin) {
|
||||
comment.nick = `👑${comment.nick}`;
|
||||
}
|
||||
|
||||
// 更新显示时间
|
||||
comment.create_date_formatted = formatTime(comment.date || comment.created_at || comment.create_date);
|
||||
|
||||
return comment;
|
||||
}
|
||||
};
|
||||
|
||||
Artalk.init(artalkConfig);
|
||||
this.enhanceArtalkUI();
|
||||
} catch (e) {
|
||||
console.error("Artalk Error", e);
|
||||
const lang = getStoredLanguage();
|
||||
const msg = lang === 'zh' ? '当前评论区已关闭' : 'Comments are closed';
|
||||
$('#artalk-container').html(`<div style="text-align:center;color:#999;padding:20px;">${msg}</div>`);
|
||||
}
|
||||
} else {
|
||||
const lang = getStoredLanguage();
|
||||
const msg = lang === 'zh' ? '当前评论区已关闭' : 'Comments are closed';
|
||||
$('#artalk-container').html(`<div style="text-align:center;color:#999;padding:20px;">${msg}</div>`);
|
||||
}
|
||||
@@ -562,7 +643,12 @@ class UIManager {
|
||||
reloadArtalk() {
|
||||
// 销毁现有的 Artalk 实例
|
||||
if (typeof Artalk !== 'undefined' && Artalk.instances) {
|
||||
Artalk.destroy();
|
||||
try {
|
||||
Artalk.destroy();
|
||||
} catch (e) {
|
||||
console.error("Artalk destroy Error", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 清空容器
|
||||
@@ -589,16 +675,7 @@ class UIManager {
|
||||
|
||||
// 获取当前主题
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
|
||||
// 设置主题
|
||||
if (typeof Artalk !== 'undefined') {
|
||||
try {
|
||||
Artalk.setDarkMode(currentTheme === 'night');
|
||||
} catch (e) {
|
||||
console.warn('Failed to set Artalk dark mode:', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 移动端增强功能
|
||||
if (isMobile) {
|
||||
this.enhanceMobileArtalk(container, lang);
|
||||
@@ -685,36 +762,6 @@ class UIManager {
|
||||
container.classList.add(`atk-theme-${theme || 'day'}`);
|
||||
}
|
||||
|
||||
updateArtalkLanguage(container, lang, isMobile) {
|
||||
// 更新展开/收起按钮文本
|
||||
if (isMobile) {
|
||||
const expandButtons = container.querySelectorAll('.atk-expand-btn');
|
||||
const expandText = lang === 'zh' ? '展开' : 'Expand';
|
||||
const collapseText = lang === 'zh' ? '收起' : 'Collapse';
|
||||
|
||||
expandButtons.forEach(btn => {
|
||||
// 如果按钮当前显示的是展开文本,保持不变
|
||||
// 如果显示的是收起文本,则更新为对应语言的收起文本
|
||||
if (btn.textContent === '展开' || btn.textContent === 'Expand') {
|
||||
btn.textContent = expandText;
|
||||
} else if (btn.textContent === '收起' || btn.textContent === 'Collapse') {
|
||||
btn.textContent = collapseText;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 如果有 Artalk 实例,可以在这里更新其实例的语言设置
|
||||
if (typeof Artalk !== 'undefined') {
|
||||
try {
|
||||
// 注意:Artalk 的语言设置通常在初始化时确定,
|
||||
// 动态更改语言需要重新初始化或者使用其API(如果支持)
|
||||
console.log('Would update Artalk language to:', lang);
|
||||
} catch (e) {
|
||||
console.warn('Failed to update Artalk language:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initTechCloud() {
|
||||
const container = document.getElementById('tech-container');
|
||||
if (!container) return;
|
||||
|
||||
Reference in New Issue
Block a user