hexo-theme-stellar 1.29.0 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_config.yml +29 -9
- package/_data/chat_users.yml +0 -0
- package/_data/widgets.yml +7 -0
- package/languages/zh-TW.yml +2 -2
- package/layout/_partial/head.ejs +2 -1
- package/layout/_partial/main/navbar/nav_tabs_blog.ejs +10 -10
- package/layout/_partial/scripts/defines.ejs +3 -0
- package/layout/_partial/scripts/services.ejs +91 -0
- package/layout/_partial/scripts/theme.ejs +5 -0
- package/layout/_partial/scripts/utils.ejs +67 -7
- package/layout/_partial/scripts.ejs +1 -1
- package/layout/_plugins/mermaid.ejs +1 -1
- package/layout/_plugins/scrollreveal.ejs +1 -0
- package/layout/_plugins/search/algolia_search.ejs +11 -12
- package/layout/layout.ejs +1 -1
- package/package.json +1 -1
- package/scripts/events/lib/config.js +3 -0
- package/scripts/events/lib/doc_tree.js +1 -6
- package/scripts/filters/index.js +26 -0
- package/scripts/generators/notebooks.js +1 -1
- package/scripts/generators/search.js +21 -2
- package/scripts/helpers/dynamic_color.js +138 -0
- package/scripts/tags/index.js +1 -0
- package/scripts/tags/lib/box.js +1 -1
- package/scripts/tags/lib/chat.js +515 -0
- package/scripts/tags/lib/folders.js +1 -1
- package/scripts/tags/lib/folding.js +2 -2
- package/scripts/tags/lib/sites.js +1 -1
- package/scripts/tags/lib/video.js +7 -2
- package/source/css/_components/tag-plugins/chat.styl +621 -0
- package/source/css/_components/tag-plugins/friends.styl +10 -0
- package/source/css/_components/tag-plugins/sites.styl +12 -0
- package/source/css/_components/tag-plugins/tabs.styl +5 -2
- package/source/css/_custom.styl +1 -0
- package/source/css/_defines/func.styl +7 -6
- package/source/css/_defines/theme.styl +38 -0
- package/source/css/_plugins/katex.styl +0 -1
- package/source/js/plugins/download-file.js +198 -0
- package/source/js/plugins/video.js +65 -0
- package/source/js/plugins/voice.js +438 -0
- package/source/js/search/algolia-search.js +63 -61
- package/source/js/services/artalk_latest_comment.js +33 -0
- package/source/js/services/friends.js +4 -0
- package/source/js/services/giscus_latest_comment.js +36 -0
- package/source/js/services/memos.js +91 -69
- package/source/js/services/sites.js +4 -0
- package/source/js/services/twikoo_latest_comment.js +47 -0
- package/source/js/services/waline_latest_comment.js +32 -0
|
@@ -1,73 +1,95 @@
|
|
|
1
1
|
utils.jq(() => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
cell += `<div class="image-bg"><img src="https://${host}/o/r/${img.id}" data-fancybox="memos"></div>`;
|
|
62
|
-
}
|
|
2
|
+
const els = Array.from(document.getElementsByClassName('ds-memos'));
|
|
3
|
+
|
|
4
|
+
els.forEach(el => {
|
|
5
|
+
const api = el.getAttribute('api');
|
|
6
|
+
if (!api) return;
|
|
7
|
+
|
|
8
|
+
const default_avatar = el.getAttribute('avatar') || def.avatar;
|
|
9
|
+
const limit = el.getAttribute('limit');
|
|
10
|
+
const host = api.match(/https:\/\/(.*?)\/(.*)/i)[1];
|
|
11
|
+
|
|
12
|
+
utils.request(el, api, async data => {
|
|
13
|
+
let memos = versionHandlers.identify(data);
|
|
14
|
+
if (memos.version === "feature" )return;
|
|
15
|
+
|
|
16
|
+
const users = el.getAttribute('user')?.split(",") || [];
|
|
17
|
+
const hide = el.getAttribute('hide')?.split(",") || [];
|
|
18
|
+
|
|
19
|
+
await Promise.all(memos.data.slice(0, limit || memos.data.length).map(item =>
|
|
20
|
+
createMemoCell(item, memos, users, hide, default_avatar, host).then(cell => $(el).append(cell))
|
|
21
|
+
));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
async function createMemoCell(item, memos, users, hide, default_avatar, host) {
|
|
25
|
+
const versionHandler = versionHandlers[memos.version] || versionHandlers["feature"];
|
|
26
|
+
return `<div class="timenode">
|
|
27
|
+
<div class="header">${!users.length && !hide.includes('user') ? await versionHandler.buildUser(item, memos, default_avatar) : ''}
|
|
28
|
+
<span>${versionHandler.buildDate(item).toLocaleString()}</span></div>
|
|
29
|
+
<div class="body">${marked.parse(item.content || '')}
|
|
30
|
+
<div class="tag-plugin image">${versionHandler.buildImages(item, host).join('')}</div>
|
|
31
|
+
</div></div>`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Memos版本管理
|
|
35
|
+
const versionHandlers = {
|
|
36
|
+
"22-": {
|
|
37
|
+
buildUser: async (item, memos, default_avatar) =>
|
|
38
|
+
`<div class="user-info">${default_avatar ? `<img src="${default_avatar}">` : ''}<span>${item.creatorName}</span></div>`,
|
|
39
|
+
buildDate: item => new Date(item.createdTs * 1000),
|
|
40
|
+
buildImages: (item, host) => (item.resourceList || []).filter(res => res.type?.includes('image/')).map(res =>
|
|
41
|
+
`<div class="image-bg"><img src="${res.externalLink || `https://${host}/o/r/${res.id}`}"></div>`
|
|
42
|
+
)
|
|
43
|
+
},
|
|
44
|
+
"22+": {
|
|
45
|
+
buildUser: async (item, memos, default_avatar) => {
|
|
46
|
+
const creatorId = item?.creator.split('/')[1];
|
|
47
|
+
let user = memos.users.find(user => user.id === parseInt(creatorId));
|
|
48
|
+
if (!user) {
|
|
49
|
+
if (!memos.requests[creatorId]) {
|
|
50
|
+
memos.requests[creatorId] = fetch(`${memos.site}/api/v1/users/${creatorId}`)
|
|
51
|
+
.then(response => response.json())
|
|
52
|
+
.then(data => {
|
|
53
|
+
if (data.username) {
|
|
54
|
+
user = data;
|
|
55
|
+
memos.users.push(data);
|
|
56
|
+
} else {
|
|
57
|
+
user = null;
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
.finally(() => delete memos.requests[creatorId]);
|
|
63
61
|
}
|
|
64
|
-
|
|
62
|
+
await memos.requests[creatorId];
|
|
63
|
+
user = memos.users.find(user => user.id === parseInt(creatorId));
|
|
65
64
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
$
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
const name = user ? user.nickname || user.username : 'memos';
|
|
66
|
+
const avatarUrl = user?.avatarUrl ? `${memos.site}${user.avatarUrl}` : default_avatar || '';
|
|
67
|
+
return `<div class="user-info">${avatarUrl ? `<img src="${avatarUrl}">` : ''}<span>${name}</span></div>`;
|
|
68
|
+
},
|
|
69
|
+
buildDate: item => new Date(item.createTime),
|
|
70
|
+
buildImages: (item) => (item.resources || []).filter(res => res.type?.includes('image/')).map(res =>
|
|
71
|
+
`<div class="image-bg"><img src="${res.externalLink || `https://${host}/o/r/${res.id}`}"></div>`
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
"feature": {
|
|
75
|
+
buildUser: async () => "memos",
|
|
76
|
+
buildDate: () => new Date(),
|
|
77
|
+
buildImages: () => []
|
|
78
|
+
},
|
|
79
|
+
identify: (data) => {
|
|
80
|
+
let memos = { version: "feature", users: [], site: api.split('/api/v1')[0], requests: {}, data: [] }
|
|
81
|
+
if (Array.isArray(data)) {
|
|
82
|
+
memos.version = "22-";
|
|
83
|
+
memos.data = data;
|
|
84
|
+
} else if (data.memos) {
|
|
85
|
+
memos.version = "22+";
|
|
86
|
+
memos.data = data.memos;
|
|
87
|
+
} else {
|
|
88
|
+
memos.version = "feature";
|
|
89
|
+
console.log("当前Memos版本过高,请到Stellar社区反馈");
|
|
90
|
+
}
|
|
91
|
+
return memos
|
|
92
|
+
}
|
|
93
|
+
};
|
|
72
94
|
});
|
|
73
|
-
});
|
|
95
|
+
});
|
|
@@ -19,6 +19,10 @@ utils.jq(() => {
|
|
|
19
19
|
cell += `<img src="${item.icon || item.avatar || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
|
20
20
|
cell += `<span class="title">${item.title}</span>`;
|
|
21
21
|
cell += `<span class="desc">${item.description || item.url}</span>`;
|
|
22
|
+
if (item.labels && item.labels.length > 0) {
|
|
23
|
+
let label = item.labels[0];
|
|
24
|
+
cell += `<span class="label" style="background:#${label.color};">${label.name}</span>`;
|
|
25
|
+
}
|
|
22
26
|
cell += `</div>`;
|
|
23
27
|
cell += `</a>`;
|
|
24
28
|
cell += `</div>`;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
utils.jq(() => {
|
|
2
|
+
$(function () {
|
|
3
|
+
const el = document.querySelector('.ds-twikoo');
|
|
4
|
+
utils.onLoading(el); // 加载动画
|
|
5
|
+
|
|
6
|
+
const api = el.getAttribute('api');
|
|
7
|
+
const limit = parseInt(el.getAttribute('limit')) || 10;
|
|
8
|
+
const reply = el.getAttribute('hide') !== 'reply';
|
|
9
|
+
if (!api) return;
|
|
10
|
+
|
|
11
|
+
fetch(api, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
body: JSON.stringify({
|
|
14
|
+
"event": "GET_RECENT_COMMENTS",
|
|
15
|
+
"envId": api,
|
|
16
|
+
"pageSize": limit,
|
|
17
|
+
"includeReply": reply
|
|
18
|
+
}),
|
|
19
|
+
headers: { 'Content-Type': 'application/json' }
|
|
20
|
+
})
|
|
21
|
+
.then(res => res.json())
|
|
22
|
+
.then(({ data }) => {
|
|
23
|
+
utils.onLoadSuccess(el); // 移除动画
|
|
24
|
+
data.forEach((comment, j) => {
|
|
25
|
+
let commentText = comment.commentText;
|
|
26
|
+
if (!commentText || commentText.trim() === '') return; // 跳过空评论
|
|
27
|
+
// 转义字符
|
|
28
|
+
commentText = commentText.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
29
|
+
commentText = commentText.length > 50 ? commentText.substring(0, 50) + '...' : commentText;
|
|
30
|
+
var cell = '<div class="timenode" index="' + j + '">';
|
|
31
|
+
cell += '<div class="header">';
|
|
32
|
+
cell += '<div class="user-info">';
|
|
33
|
+
cell += '<span>' + comment.nick + '</span>';
|
|
34
|
+
cell += '</div>';
|
|
35
|
+
cell += '<span>' + new Date(comment.created).toLocaleString('zh-CN', {month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hour12: false}) + '</span>';
|
|
36
|
+
cell += '</div>';
|
|
37
|
+
cell += '<a class="body" href="' + comment.url + '#' + comment.id + '">';
|
|
38
|
+
cell += commentText;
|
|
39
|
+
cell += '</a>';
|
|
40
|
+
cell += '</div>';
|
|
41
|
+
$(el).append(cell);
|
|
42
|
+
});
|
|
43
|
+
})
|
|
44
|
+
.catch(() => utils.onLoadFailure(el));
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
utils.jq(() => {
|
|
2
|
+
$(function () {
|
|
3
|
+
const els = document.getElementsByClassName('ds-waline');
|
|
4
|
+
for (var i = 0; i < els.length; i++) {
|
|
5
|
+
const el = els[i];
|
|
6
|
+
const limit = parseInt(el.getAttribute('limit')) || 10;
|
|
7
|
+
const apiBase = el.getAttribute('api');
|
|
8
|
+
if (apiBase == null) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const api = apiBase + '/comment?type=recent&count=' + limit;
|
|
12
|
+
const default_avatar = def.avatar;
|
|
13
|
+
utils.request(el, api, function(data) {
|
|
14
|
+
data.forEach((item, i) => {
|
|
15
|
+
var cell = '<div class="timenode" index="' + i + '">';
|
|
16
|
+
cell += '<div class="header">';
|
|
17
|
+
cell += '<div class="user-info">';
|
|
18
|
+
cell += '<img src="' + (item.avatar || default_avatar) + '" onerror="javascript:this.src=\'' + default_avatar + '\';">';
|
|
19
|
+
cell += '<span>' + item.nick + '</span>';
|
|
20
|
+
cell += '</div>';
|
|
21
|
+
cell += '<span>' + new Date(item.time).toLocaleString() + '</span>';
|
|
22
|
+
cell += '</div>';
|
|
23
|
+
cell += '<a class="body" href="' + item.url + '#' + item.objectId + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
24
|
+
cell += item.comment.replace(/<a\b[^>]*>(.*?)<\/a>/g, '$1');
|
|
25
|
+
cell += '</a>';
|
|
26
|
+
cell += '</div>';
|
|
27
|
+
$(el).append(cell);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|