Files
blog/themes/Ying/layouts/partials/artalk.html
T
zqlit c837d72b1a feat(评论): 最近表情改为分组 tab + 提交后面板收起 + 小编徽章配色 + 走心评论 20 条
- emoticon-recent.js: 「最近使用」从面板顶部独立栏重构为分组切换条最左侧的
  同构 tab(data-index="recent"),无记录时整个 tab 隐藏;复用 Artalk 原生
  .atk-grp[data-type=image] 网格样式,零自定义布局。
- artalk.js:
  · 新建评论成功(res.ok)后,对当前激活的插件按钮派发 click(),收起仍展开的
    表情面板(Artalk 上游只 reset 输入内容、不关面板),内部 openedPlug 状态同步复位。
  · 徽章处理末尾把徽章文字镜像到 data-badge 属性,供 CSS 按名字配色。
- artalk.html: 新增 .atk-badge[data-badge="小编"] 玫红实底规则(含暗色模式),
  特异性高于博主规则,两者互不覆盖。
- featured-comments.html: 走心评论 limit 8 → 20(后端上限)。
- main.css: 移除旧 .atk-recent-emoticons 相关样式。
2026-10-05 17:34:18 +08:00

299 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{ $artalkCss := resources.Get "css/libs/Artalk.css" | resources.Minify | resources.Fingerprint }}
<link id="artalk-css" rel="stylesheet" href="{{ $artalkCss.RelPermalink }}">
<style>
.atk-loading{
background: #FFFFFF;
}
.atk-loading-editor-box {
margin-bottom: 30px;
border: 1px solid var(--frame-color);
border-radius: 4px;
padding: 10px;
background: #fff;
}
[data-theme="dark"] .atk-loading-editor-box {
border-color: var(--frame-dark-color);
background: transparent;
}
/* ================= 评论徽章统一规格(单一来源) =================
几何沿用原设计:inline-block + margin-left:4px + padding 0 6px + 12px/500
+ line-height:18px + 1px 描边 + 3px 圆角。
artalk.js 会把所有徽章(博主/置顶/头衔/友链/友圈/官职)都挂上 .atk-cmt-badge
并拆掉 Artalk 的 .atk-badge-wrap 包装层,所以几何只在这里定义一次,
不会再出现两种 DOM / 两种尺寸。各类型只保留配色差异。
注:margin-right 清零是为了不叠加 Artalk 给"非最后一个徽章"的 6px 右间距
(否则 徽章→徽章 间距一宽一窄,看起来不齐)。 */
.atk-comment .atk-cmt-badge,
.atk-fl-card .atk-cmt-badge,
.atk-comment .atk-badge,
.atk-fl-card .atk-badge,
.atk-comment .atk-pinned-badge,
.atk-fl-card .atk-pinned-badge,
.atk-comment .atk-title-badge,
.atk-fl-card .atk-title-badge,
.atk-comment .atk-link-badge,
.atk-fl-card .atk-link-badge,
.atk-comment .atk-feed-badge,
.atk-fl-card .atk-feed-badge,
.atk-comment .atk-rank-badge,
.atk-fl-card .atk-rank-badge {
display: inline-block !important;
margin-left: 4px !important;
margin-right: 0 !important;
padding: 0 6px !important;
font-size: 12px !important;
font-weight: 600 !important;
border-radius: 3px !important;
line-height: 18px !important;
vertical-align: middle !important;
pointer-events: none;
white-space: nowrap;
}
.atk-link-badge {
color: #059669;
background: rgba(5,150,105,0.08);
border: 1px solid rgba(5,150,105,0.15);
}
.atk-feed-badge {
color: #d97706;
background: rgba(217,119,6,0.08);
border: 1px solid rgba(217,119,6,0.15);
}
.atk-rank-badge {
color: #6b7280;
background: rgba(107,114,128,0.08);
border: 1px solid rgba(107,114,128,0.15);
}
.atk-title-badge {
color: #b8860b;
background: rgba(184,134,11,0.08);
border: 1px solid rgba(184,134,11,0.22);
}
/* 博主(.atk-badge):实底 —— 白字 + 浅黑底
(!important 是为了盖掉 Artalk 写在元素上的内联背景色) */
.atk-comment .atk-badge,
.atk-fl-card .atk-badge {
border: 1px solid #333333;
color: #ffffff !important;
background: #333333 !important;
}
/* 小编(.atk-badge[data-badge="小编"]):实底 —— 白字 + 玫红底。
data-badge 由 artalk.js 按徽章文字镜像上来(badge_color 是 Artalk 写的内联
样式,会被上面博主规则的 !important 盖掉,所以只能按文字做钩子)。
选择器比博主默认规则多一个属性、特异性更高,所以两种徽章各自成色不互压。 */
.atk-comment .atk-badge[data-badge="小编"],
.atk-fl-card .atk-badge[data-badge="小编"] {
border-color: #d94f7a;
color: #ffffff !important;
background: #d94f7a !important;
}
/* 置顶徽章:实底 —— 白字 + 浅红底(比 #d9534f / #ff6262 更浅,不刺眼) */
.atk-comment .atk-pinned-badge,
.atk-fl-card .atk-pinned-badge {
border: 1px solid #e05a5a;
color: #ffffff !important;
background: #e05a5a !important;
}
/* ---- 暗色模式配色 ---- */
[data-theme="dark"] .atk-link-badge {
color: #34d399;
background: rgba(52,211,153,0.12);
border-color: rgba(52,211,153,0.2);
}
[data-theme="dark"] .atk-feed-badge {
color: #fbbf24;
background: rgba(251,191,36,0.12);
border-color: rgba(251,191,36,0.2);
}
[data-theme="dark"] .atk-rank-badge {
color: rgb(148,163,184);
background: rgba(148,163,184,0.1);
border-color: rgba(148,163,184,0.18);
}
[data-theme="dark"] .atk-title-badge {
color: #fbbf24;
background: rgba(251,191,36,0.12);
border-color: rgba(251,191,36,0.2);
}
/* ================= 友链申请入口卡片 =================
PJAX 下每次切页评论区都会重建卡片 → 入场动画与打字机自然重播;
打字机定时器在 artalk.js 里会检测卡片是否还在文档中(切页后自动停)。 */
/* 被转换成卡片的评论:整条从列表里隐藏(卡片已移到列表上方单独显示,
用 class + !important 声明式隐藏,Artalk 重渲染也压得住) */
.atk-comment-wrap.atk-fl-apply {
display: none !important;
}
/* 卡片容器:固定在评论列表最上方 */
.atk-fl-card-wrap {
margin: 0 0 6px;
}
/* ---- 移动端:卡片更紧凑(隐藏头像 + 昵称行 + 收紧间距 + 微调字号) ----
窄屏把「头像 + 昵称(小赵) + 博主徽章」整行去掉:这三个元素在手机宽度下
会把打字机文案挤成一两行、按钮也跟着缩小,观感很差。去掉之后卡片只剩
「说明文案 + 申请友链按钮」,信息密度反而更合理。
昵称与徽章都在 .atk-fl-nick 这一行里(徽章是 artalk.js 克隆后 append 进去的),
所以按 .atk-fl-nick 隐藏即可;徽章再多写一条做兜底(Webkit 老版本对
父级 display:none 的继承没问题,这里只是防御式写法)。 */
@media (max-width: 640px) {
.atk-fl-card {
gap: 8px !important;
padding: 10px 12px !important;
}
.atk-fl-card .atk-fl-avatar {
display: none !important; /* 窄屏省掉头像,把宽度让给文字 */
}
.atk-fl-card .atk-fl-nick,
.atk-fl-card .atk-fl-nick .atk-badge,
.atk-fl-card .atk-fl-nick .atk-cmt-badge {
display: none !important; /* 昵称(小赵)+ 博主徽章:移动端不显示 */
}
.atk-fl-card .atk-fl-desc {
font-size: 12.5px !important;
letter-spacing: 0.2px !important;
margin-top: 0 !important; /* 昵称行没了,上间距一并去掉 */
}
.atk-fl-card .atk-fl-btn {
font-size: 12.5px !important;
padding: 5px 11px !important;
letter-spacing: 0.2px !important;
}
}
.atk-fl-card {
animation: flApplyIn .5s cubic-bezier(.22, 1, .36, 1) both;
}
@keyframes flApplyIn {
from { opacity: 0; transform: translateY(12px) scale(.98); }
to { opacity: 1; transform: none; }
}
.atk-fl-card:hover {
border-color: var(--theme-main-30, rgba(7,193,96,.3)) !important;
}
/* 打字机光标 */
.atk-fl-card .atk-fl-caret {
display: inline-block;
width: 1px;
height: 1em;
margin-left: 2px;
vertical-align: -2px;
background: currentColor;
animation: flCaret .9s steps(1, end) infinite;
}
@keyframes flCaret {
0%, 49% { opacity: 1; }
50%, 100% { opacity: 0; }
}
/* 申请友链按钮:轻微上浮 + 主题色投影 */
.atk-fl-card .atk-fl-btn {
transition: transform .2s ease, box-shadow .2s ease;
}
.atk-fl-card:hover .atk-fl-btn {
transform: translateY(-1px);
box-shadow: 0 4px 12px var(--theme-main-20, rgba(7,193,96,.2));
}
.atk-fl-card .atk-fl-btn:active {
transform: translateY(0);
}
/* 尊重系统"减弱动态效果":只关掉入场动画和按钮位移,
打字机与光标保留(打字机是文字渐显,不属于会造成不适的位移类动效) */
@media (prefers-reduced-motion: reduce) {
.atk-fl-card { animation: none; }
.atk-fl-card .atk-fl-btn { transition: none; }
.atk-fl-card:hover .atk-fl-btn { transform: none; box-shadow: none; }
}
.atk-main {
backface-visibility: hidden;
will-change: transform;
-webkit-font-smoothing: antialiased;
}
</style>
<!-- Artalk -->
<div id="Comments" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
<!-- Loading Skeleton -->
<div class="atk-loading-placeholder">
<!-- Editor Skeleton -->
<div class="atk-loading-editor-box">
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
</div>
<div class="atk-loading-line" style="width: 100%; height: 120px; border-radius: 4px; margin-bottom: 10px;"></div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<div class="atk-loading-line" style="width: 120px; height: 20px; margin-bottom: 0;"></div>
<div class="atk-loading-line" style="width: 80px; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
</div>
</div>
<!-- Comment List Skeleton -->
<div class="atk-loading-item">
<div class="atk-loading-avatar"></div>
<div class="atk-loading-content">
<div class="atk-loading-line width-name"></div>
<div class="atk-loading-line width-80"></div>
<div class="atk-loading-line width-60"></div>
</div>
</div>
<div class="atk-loading-item">
<div class="atk-loading-avatar"></div>
<div class="atk-loading-content">
<div class="atk-loading-line width-name"></div>
<div class="atk-loading-line width-60"></div>
</div>
</div>
</div>
</div>
<!-- JS -->
<!-- <script src="/js/Artalk.js"></script> -->
<!-- ── /api/v2/conf 内联快照 ─────────────────────────────────────────────
构建期由 .cnb.yml 拉一次 /api/v2/conf 落到 data/artalk_conf.json,这里原样内联。
artalk.js 对匿名 /conf 请求直接本地合成响应,省掉一次跨境 RTT ——
Artalk 内部 conf 与评论列表是「严格串行」的,去掉这一跳首屏即少一整个往返。
文件不存在时(本地预览 / 拉取失败)不输出,前端自动回退到远程请求。 -->
{{ with site.Data.artalk_conf }}
{{- $snapJson := . | jsonify }}
{{- $snapJson = replace $snapJson "</" "<\\/" }}
<script>window.__artalkConfSnapshot = {{ $snapJson | safeJS }};</script>
{{ end }}
<script>
// Configuration for Artalk and AI Comment
window.artalkConfig = {
el: '#Comments',
server: '{{ .Site.Params.artalk.server }}',
site: '{{ .Site.Params.artalk.site }}',
pageKey: '{{ .RelPermalink }}',
{{/* pageTitle 必须显式传:Artalk 不传时会读 document.title,而 PJAX 切页
早期脚本执行时 document.title 还是上一个页面的(经典竞态),历史上
数据库里一堆文章页的标题被污染成「留言」就是这么来的。head.html 的
<title> 就是纯 .Title,这里与它保持一致。
★ 必须 safeJS:这段在 <script> 里,Go 模板按 JS 上下文再转义一层,
`jsonify` 的结果会被二次编码 —— 标题 留言 会变成 "\"留言\"",
评论入库/邮件标题就带上了一对引号(《"留言"》)。safeJS 明确告诉
模板「这就是最终 JS 字面量」,不再二次转义;`</` 仍按惯例转义兜底。 */}}
{{ $t := .Title | jsonify }}
pageTitle: {{ replace $t "</" "<\\/" | safeJS }},
// 文章作者的 user id:评论提交时由 artalk.js 的 fetch 拦截器塞进请求体,
// 服务端据此把「有新评论」的邮件发给文章作者本人 —— 编辑角色(女朋友)
// 写的文章就不再打扰博主了。老文章没有 author_id → 0,服务端回退到原行为。
pageAuthorId: {{ .Params.author_id | default 0 | int }},
emoticons: '{{ .Site.Params.artalk.emoticons | absURL }}',
aiComment: null
};
// 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>