[feat] latest comment widgets (#530)

* [feat] comment new widgets
- twikoo
- giscus
- waline @luoxue03
- artalk @thun888

* [opt] rename script

* Update widgets.yml

---------

Co-authored-by: xaoxuu <16400144+xaoxuu@users.noreply.github.com>
This commit is contained in:
星日语 2024-10-21 17:44:48 +08:00 committed by GitHub
parent 85eae414cb
commit 81cb63a52c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 166 additions and 0 deletions

View File

@ -452,6 +452,15 @@ data_services:
js: /js/services/weibo.js
memos:
js: /js/services/memos.js
# 最新评论获取类
twikoo:
js: /js/services/twikoo_latest_comment.js
waline:
js: /js/services/waline_latest_comment.js
artalk:
js: /js/services/artalk_latest_comment.js
giscus:
js: /js/services/giscus_latest_comment.js
# 扩展插件接入方法:(插件名下面用 #plugin# 代替)

View File

@ -71,6 +71,13 @@ timeline:
type: # 默认不用写,如果是友链朋友圈数据请写 fcircle
limit: # 默认通过 api 上增加 per_page 来设置,如果是友链朋友圈,可通过这个设置数量
latest_comment:
layout: timeline
title: 最新评论
api: # 参照文档获取服务对应的api
type: # 选择评论服务
limit: 16 # 限制获取数量
tagtree:
layout: tagtree
expand_all: false # 是否展开所有节点

View File

@ -0,0 +1,33 @@
utils.jq(() => {
$(function () {
const els = document.getElementsByClassName('ds-artalk');
for (var i = 0; i < els.length; i++) {
const el = els[i];
const limit = parseInt(el.getAttribute('limit')) || 10;
const api = el.getAttribute('api') + '&limit=' + limit;
if (api == null) {
continue;
}
utils.request(el, api, function (data) {
data = data.data || [];
data.forEach((item, i) => {
var cell = '<div class="timenode" index="' + i + '">';
cell += '<div class="header">';
cell += '<div class="user-info">';
// cell += '<img src="https://cravatar.cn/avatar/' + (item.email_encrypted) + '?d=mp&s=240">';
cell += '<span>' + item.nick + '</span>';
cell += '</div>';
cell += '<span>' + new Date(item.date).toLocaleString() + '</span>';
cell += '</div>';
cell += '<a class="body" href="' + item.page_url + '#atk-comment-' + item.id + '" target="_blank" rel="external nofollow noopener noreferrer">';
cell += item.content_marked;
cell += '</a>';
cell += '</div>';
$(el).append(cell);
});
});
}
});
});

View File

@ -0,0 +1,37 @@
utils.jq(() => {
$(function () {
const els = document.getElementsByClassName('ds-giscus');
for (var i = 0; i < els.length; i++) {
const el = els[i];
const api = el.getAttribute('api');
if (api == null) {
continue;
}
const default_avatar = def.avatar;
// layout
utils.request(el, api, function(data) {
const limit = el.getAttribute('limit');
data.forEach((item, i) => {
if (limit && i >= limit) {
return;
}
comment = item.body.length > 50 ? item.body.substring(0, 50) + '...' : item.body;
var cell = '<div class="timenode" index="' + i + '">';
cell += '<div class="header">';
cell += '<div class="user-info">';
cell += '<img src="' + (item.author.avatarUrl || default_avatar) + '" onerror="javascript:this.src=\\'' + default_avatar + '\\';">';
cell += '<span>' + item.author.login + '</span>';
cell += '</div>';
cell += '<span>' + new Date(item.createdAt).toLocaleString() + '</span>';
cell += '</div>';
cell += '<a class="body" href="' + item.url + '" target="_blank" rel="external nofollow noopener noreferrer">';
cell += comment;
cell += '</a>';
cell += '</div>';
$(el).append(cell);
});
});
}
});
});

View File

@ -0,0 +1,47 @@
utils.jq(() => {
$(function () {
const el = document.querySelector('.ds-twikoo');
utils.onLoading(el); // 加载动画
const api = el.getAttribute('api');
const limit = parseInt(el.getAttribute('limit')) || 10;
const reply = el.getAttribute('hide') !== 'reply';
if (!api) return;
fetch(api, {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"envId": api,
"pageSize": limit,
"includeReply": reply
}),
headers: { 'Content-Type': 'application/json' }
})
.then(res => res.json())
.then(({ data }) => {
utils.onLoadSuccess(el); // 移除动画
data.forEach((comment, j) => {
let commentText = comment.commentText;
if (!commentText || commentText.trim() === '') return; // 跳过空评论
// 转义字符
commentText = commentText.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
commentText = commentText.length > 50 ? commentText.substring(0, 50) + '...' : commentText;
var cell = '<div class="timenode" index="' + j + '">';
cell += '<div class="header">';
cell += '<div class="user-info">';
cell += '<span>' + comment.nick + '</span>';
cell += '</div>';
cell += '<span>' + new Date(comment.created).toLocaleString('zh-CN', {month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false}) + '</span>';
cell += '</div>';
cell += '<a class="body" href="' + comment.url + '#' + comment.id + '">';
cell += commentText;
cell += '</a>';
cell += '</div>';
$(el).append(cell);
});
})
.catch(() => utils.onLoadFailure(el));
});
});

View File

@ -0,0 +1,33 @@
utils.jq(() => {
$(function () {
const els = document.getElementsByClassName('ds-waline');
for (var i = 0; i < els.length; i++) {
const el = els[i];
const limit = parseInt(el.getAttribute('limit')) || 10;
const apiBase = el.getAttribute('api');
if (apiBase == null) {
continue;
}
const api = apiBase + '/comment?type=recent&count=' + limit;
const default_avatar = def.avatar;
utils.request(el, api, function(data) {
data.forEach((item, i) => {
var cell = '<div class="timenode" index="' + i + '">';
cell += '<div class="header">';
cell += '<div class="user-info">';
cell += '<img src="' + (item.avatar || default_avatar) + '" onerror="javascript:this.src=\\'' + default_avatar + '\\';">';
cell += '<span>' + item.nick + '</span>';
cell += '</div>';
cell += '<span>' + new Date(item.time).toLocaleString() + '</span>';
cell += '</div>';
cell += '<a class="body" href="' + item.url + '#' + item.objectId + '" target="_blank" rel="external nofollow noopener noreferrer">';
cell += item.comment.replace(/<a\\b[^>]*>(.*?)<\\/a>/g, '$1');
cell += '</a>';
cell += '</div>';
$(el).append(cell);
});
});
}
});
});