hexo-theme-solitude 2.1.6 → 2.1.8
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/CONTRIBUTING.md +1 -1
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/README_en-US.md +1 -1
- package/README_zh-Hant.md +1 -1
- package/SECURITY.md +1 -1
- package/_config.yml +16 -20
- package/languages/default.yml +173 -173
- package/layout/archive.pug +3 -1
- package/layout/category.pug +3 -1
- package/layout/includes/inject/body.pug +1 -1
- package/layout/includes/page/default.pug +1 -1
- package/layout/includes/page/links.pug +1 -1
- package/layout/includes/page/tlink.pug +1 -1
- package/layout/includes/rightmenu.pug +6 -5
- package/layout/includes/widgets/page/about/hobbies.pug +18 -17
- package/layout/includes/widgets/page/about/tenyear.pug +24 -25
- package/layout/includes/widgets/page/links/linksCard.pug +5 -2
- package/layout/includes/widgets/page/message/content.pug +1 -1
- package/layout/includes/widgets/third-party/hot/artalk.pug +56 -0
- package/layout/includes/widgets/third-party/hot/twikoo.pug +57 -0
- package/layout/includes/widgets/third-party/pjax.pug +2 -1
- package/layout/index.pug +1 -1
- package/layout/post.pug +1 -1
- package/layout/tag.pug +2 -0
- package/package.json +1 -1
- package/plugins.yml +10 -10
- package/scripts/event/init.js +0 -1
- package/scripts/event/merge_config.js +14 -39
- package/scripts/event/welcome.js +11 -7
- package/scripts/filter/default.js +20 -21
- package/scripts/filter/lazyload.js +2 -4
- package/scripts/filter/randomPosts.js +14 -3
- package/scripts/helper/getArchiveLength.js +9 -11
- package/scripts/helper/related_post.js +56 -56
- package/scripts/tags/article.js +53 -15
- package/scripts/tags/tabs.js +37 -46
- package/source/css/_comments/comment.styl +4 -3
- package/source/css/_comments/twikoo.styl +6 -7
- package/source/css/_global/animation.styl +0 -15
- package/source/css/_global/index.styl +19 -19
- package/source/css/_highlight/highlight/diff.styl +13 -1
- package/source/css/_highlight/index.styl +2 -2
- package/source/css/_highlight/prismjs/diff.styl +13 -1
- package/source/css/_highlight/prismjs/index.styl +1 -1
- package/source/css/_highlight/prismjs/line-number.styl +1 -1
- package/source/css/_layout/article-container.styl +1 -1
- package/source/css/_layout/console.styl +1 -0
- package/source/css/_layout/recent-post.styl +2 -2
- package/source/css/_page/_about/about.styl +1 -1
- package/source/css/_page/_about/game.styl +2 -17
- package/source/css/_page/error.styl +2 -3
- package/source/css/_page/links.styl +2 -2
- package/source/css/_page/other.styl +1 -0
- package/source/css/_page/says.styl +4 -3
- package/source/css/_tags/gallery.styl +1 -1
- package/source/css/_tags/tabs.styl +2 -2
- package/source/img/error_load.avif +0 -0
- package/source/js/covercolor/api.js +29 -14
- package/source/js/covercolor/ave.js +38 -24
- package/source/js/covercolor/local.js +60 -52
- package/source/js/main.js +253 -248
- package/source/js/music.js +21 -39
- package/source/js/right_menu.js +64 -127
- package/source/js/third_party/barrage.min.js +93 -1
- package/source/js/third_party/envelope.min.js +1 -1
- package/source/js/third_party/post_ai.min.js +184 -1
- package/source/js/tw_cn.js +17 -16
- package/source/js/utils.js +50 -57
- package/layout/includes/widgets/home/hot/artalk.pug +0 -45
- package/layout/includes/widgets/home/hot/twikoo.pug +0 -46
- package/source/img/loading.avif +0 -0
- /package/layout/includes/widgets/{home → third-party}/hot/index.pug +0 -0
@@ -1 +1,184 @@
|
|
1
|
-
class POST_AI
|
1
|
+
class POST_AI {
|
2
|
+
constructor() {
|
3
|
+
this.root = "https://summary.tianli0.top";
|
4
|
+
this.aiTalkMode = false;
|
5
|
+
this.aiPostExplanation = '';
|
6
|
+
this.config = GLOBAL_CONFIG.post_ai;
|
7
|
+
this.scoGPTIsRunning = false;
|
8
|
+
console.log('%c TianliGPT %c 文章摘要 %c https://postchat.zhheo.com',
|
9
|
+
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
|
10
|
+
'background:#ff9a9a ; padding: 1px; border-radius: 0 3px 3px 0; color: #fff',
|
11
|
+
'background:unset ; padding: 1px; border-radius: 0 3px 3px 0; color: #fff');
|
12
|
+
}
|
13
|
+
|
14
|
+
init() {
|
15
|
+
const explanationElement = document.querySelector(".ai-explanation");
|
16
|
+
if (!explanationElement) return;
|
17
|
+
|
18
|
+
this.scoGPTIsRunning = false;
|
19
|
+
this.aiPostExplanation = PAGE_CONFIG.ai_text || '';
|
20
|
+
|
21
|
+
if (!this.aiPostExplanation) {
|
22
|
+
this.generate();
|
23
|
+
} else {
|
24
|
+
this.aiShowAnimation(Promise.resolve(this.aiPostExplanation));
|
25
|
+
}
|
26
|
+
this.AIEngine();
|
27
|
+
}
|
28
|
+
|
29
|
+
getTitleAndContent() {
|
30
|
+
const articleContainer = document.querySelector(".article-container");
|
31
|
+
const title = document.title;
|
32
|
+
const paragraphs = articleContainer.getElementsByTagName("p");
|
33
|
+
const headers = articleContainer.querySelectorAll("h1, h2, h3, h4, h5");
|
34
|
+
|
35
|
+
return (title + " " + [...headers, ...paragraphs]
|
36
|
+
.map(element => element.innerText.replace(/https?:\/\/[^\s]+/g, ""))
|
37
|
+
.join(" ")).slice(0, 1000);
|
38
|
+
}
|
39
|
+
|
40
|
+
async generate() {
|
41
|
+
const title = document.title;
|
42
|
+
const content = this.getTitleAndContent();
|
43
|
+
const key = this.config.key;
|
44
|
+
this.aiShowAnimation(this.fetch(title, content, key));
|
45
|
+
}
|
46
|
+
|
47
|
+
async fetch(title, content, key) {
|
48
|
+
const url = `${this.root}/?content=${encodeURIComponent(content)}&title=${title}&key=${encodeURIComponent(key)}&url=${encodeURIComponent(window.location.href)}`;
|
49
|
+
try {
|
50
|
+
const response = await fetch(url);
|
51
|
+
const data = await response.json();
|
52
|
+
if (response.ok) {
|
53
|
+
this.aiPostExplanation = data.summary;
|
54
|
+
return data.summary;
|
55
|
+
} else {
|
56
|
+
console.error("Request failed:", data.err_msg);
|
57
|
+
return data.err_msg;
|
58
|
+
}
|
59
|
+
} catch (error) {
|
60
|
+
console.error("Fetch error:", error);
|
61
|
+
return "Error fetching data";
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
aiShowAnimation(promise, onComplete = false, delay = 0) {
|
66
|
+
const explanationElement = document.querySelector(".ai-explanation");
|
67
|
+
const tagElement = document.querySelector(".ai-tag");
|
68
|
+
if (!explanationElement || this.scoGPTIsRunning) return;
|
69
|
+
|
70
|
+
this.scoGPTIsRunning = true;
|
71
|
+
this.cleanSuggestions();
|
72
|
+
tagElement.classList.add("loadingAI");
|
73
|
+
explanationElement.style.display = "block";
|
74
|
+
explanationElement.innerHTML = '生成中...<span class="blinking-cursor"></span>';
|
75
|
+
|
76
|
+
setTimeout(() => {
|
77
|
+
let startTime, update, currentIndex = 0, isIntersecting = true, isInitial = true;
|
78
|
+
const observer = new IntersectionObserver(entries => {
|
79
|
+
isIntersecting = entries[0].isIntersecting;
|
80
|
+
if (isIntersecting) requestAnimationFrame(update);
|
81
|
+
}, { threshold: 0 });
|
82
|
+
|
83
|
+
promise.then(result => {
|
84
|
+
startTime = performance.now();
|
85
|
+
update = () => {
|
86
|
+
if (currentIndex < result.length && isIntersecting) {
|
87
|
+
const now = performance.now();
|
88
|
+
const timeElapsed = now - startTime;
|
89
|
+
const char = result.slice(currentIndex, currentIndex + 1);
|
90
|
+
const isPunctuation = /[,。!、?,.!?]/.test(char);
|
91
|
+
const isAlphaNumeric = /[a-zA-Z0-9]/.test(char);
|
92
|
+
const delay = isPunctuation ? 100 * Math.random() + 100 : (isAlphaNumeric ? 10 : 25);
|
93
|
+
|
94
|
+
if (timeElapsed >= delay) {
|
95
|
+
explanationElement.innerText = result.slice(0, currentIndex + 1);
|
96
|
+
startTime = now;
|
97
|
+
currentIndex++;
|
98
|
+
if (currentIndex < result.length) {
|
99
|
+
explanationElement.innerHTML = result.slice(0, currentIndex) + '<span class="blinking-cursor"></span>';
|
100
|
+
} else {
|
101
|
+
explanationElement.innerHTML = result;
|
102
|
+
explanationElement.style.display = "block";
|
103
|
+
this.scoGPTIsRunning = false;
|
104
|
+
tagElement.classList.remove("loadingAI");
|
105
|
+
observer.disconnect();
|
106
|
+
if (onComplete) this.createSuggestions();
|
107
|
+
}
|
108
|
+
}
|
109
|
+
if (isIntersecting) requestAnimationFrame(update);
|
110
|
+
}
|
111
|
+
};
|
112
|
+
if (isIntersecting && isInitial) {
|
113
|
+
requestAnimationFrame(update);
|
114
|
+
isInitial = false;
|
115
|
+
}
|
116
|
+
observer.observe(explanationElement);
|
117
|
+
}).catch(error => {
|
118
|
+
console.error("检索信息失败:", error);
|
119
|
+
explanationElement.innerHTML = "检索信息失败";
|
120
|
+
explanationElement.style.display = "block";
|
121
|
+
this.scoGPTIsRunning = false;
|
122
|
+
tagElement.classList.remove("loadingAI");
|
123
|
+
observer.disconnect();
|
124
|
+
});
|
125
|
+
}, delay);
|
126
|
+
}
|
127
|
+
|
128
|
+
AIEngine() {
|
129
|
+
const tagElement = document.querySelector(".ai-tag");
|
130
|
+
if (tagElement) {
|
131
|
+
tagElement.addEventListener("click", () => {
|
132
|
+
if (!this.scoGPTIsRunning) {
|
133
|
+
this.aiTalkMode = true;
|
134
|
+
this.aiShowAnimation(Promise.resolve(this.config.talk), true);
|
135
|
+
}
|
136
|
+
});
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
cleanSuggestions() {
|
141
|
+
const suggestionsElement = document.querySelector(".ai-suggestions");
|
142
|
+
if (suggestionsElement) {
|
143
|
+
suggestionsElement.innerHTML = "";
|
144
|
+
} else {
|
145
|
+
console.error("没有这个元素:'ai-suggestions'");
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
createSuggestions() {
|
150
|
+
if (this.aiTalkMode) {
|
151
|
+
this.cleanSuggestions();
|
152
|
+
this.createSuggestionItemWithAction("这篇文章讲了什么?", () => {
|
153
|
+
if (this.aiPostExplanation === "") {
|
154
|
+
setTimeout(() => {
|
155
|
+
this.generate();
|
156
|
+
}, 3000);
|
157
|
+
} else {
|
158
|
+
setTimeout(() => {
|
159
|
+
this.aiShowAnimation(Promise.resolve(this.aiPostExplanation), true);
|
160
|
+
}, 3000);
|
161
|
+
}
|
162
|
+
});
|
163
|
+
if (this.config.randomPost) {
|
164
|
+
this.createSuggestionItemWithAction("带我去看看其他文章", () => toRandomPost());
|
165
|
+
}
|
166
|
+
this.aiTalkMode = true;
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
createSuggestionItemWithAction(text, action) {
|
171
|
+
const suggestions = document.querySelector(".ai-suggestions");
|
172
|
+
if (!suggestions) {
|
173
|
+
console.error("无法找到具有class为ai-suggestions的元素");
|
174
|
+
return;
|
175
|
+
}
|
176
|
+
const item = document.createElement("div");
|
177
|
+
item.classList.add("ai-suggestions-item");
|
178
|
+
item.textContent = text;
|
179
|
+
item.addEventListener("click", action);
|
180
|
+
suggestions.appendChild(item);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
const ai = new POST_AI();
|
package/source/js/tw_cn.js
CHANGED
@@ -11,33 +11,34 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
11
11
|
|
12
12
|
function translateText(txt) {
|
13
13
|
if (!txt) return '';
|
14
|
-
|
15
|
-
if (currentEncoding === 2 && targetEncoding === 1) return Traditionalized(txt);
|
16
|
-
return txt;
|
14
|
+
return currentEncoding === targetEncoding ? txt : (currentEncoding === 1 ? Simplized(txt) : Traditionalized(txt));
|
17
15
|
}
|
18
16
|
|
19
17
|
function translateBody(fobj) {
|
20
|
-
const objs = fobj
|
18
|
+
const objs = fobj?.childNodes || document.body.childNodes;
|
21
19
|
|
22
20
|
objs.forEach(obj => {
|
23
21
|
if (['BR', 'HR'].includes(obj.tagName)) return;
|
24
|
-
|
22
|
+
|
25
23
|
if (obj.title) obj.title = translateText(obj.title);
|
26
24
|
if (obj.alt) obj.alt = translateText(obj.alt);
|
27
25
|
if (obj.placeholder) obj.placeholder = translateText(obj.placeholder);
|
28
26
|
if (obj.tagName === 'INPUT' && obj.value && !['text', 'hidden'].includes(obj.type)) {
|
29
27
|
obj.value = translateText(obj.value);
|
30
28
|
}
|
31
|
-
if (obj.nodeType === 3)
|
32
|
-
|
29
|
+
if (obj.nodeType === 3) {
|
30
|
+
obj.data = translateText(obj.data);
|
31
|
+
} else {
|
32
|
+
translateBody(obj);
|
33
|
+
}
|
33
34
|
});
|
34
35
|
}
|
35
36
|
|
36
|
-
function translatePage(
|
37
|
+
function translatePage(simplified, traditional, button) {
|
37
38
|
currentEncoding = targetEncoding;
|
38
39
|
targetEncoding = targetEncoding === 1 ? 2 : 1;
|
39
|
-
button.lastChild.textContent = targetEncoding === 1 ?
|
40
|
-
|
40
|
+
button.lastChild.textContent = targetEncoding === 1 ? simplified : traditional;
|
41
|
+
|
41
42
|
utils.snackbarShow(targetEncoding === 1 ? '你已切換為繁體' : '你已切换为简体');
|
42
43
|
utils.saveToLocal.set(targetEncodingCookie, targetEncoding, 2);
|
43
44
|
setLang();
|
@@ -58,7 +59,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
58
59
|
const tt = FTPYStr();
|
59
60
|
return Array.from(cc).map(char => {
|
60
61
|
const index = ss.indexOf(char);
|
61
|
-
return index
|
62
|
+
return index !== -1 ? tt.charAt(index) : char;
|
62
63
|
}).join('');
|
63
64
|
}
|
64
65
|
|
@@ -67,29 +68,29 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
67
68
|
const tt = FTPYStr();
|
68
69
|
return Array.from(cc).map(char => {
|
69
70
|
const index = tt.indexOf(char);
|
70
|
-
return index
|
71
|
+
return index !== -1 ? ss.charAt(index) : char;
|
71
72
|
}).join('');
|
72
73
|
}
|
73
74
|
|
74
75
|
function translateInitialization() {
|
75
|
-
|
76
|
+
const btn_1 = document.getElementById('menu-translate');
|
76
77
|
if (btn_1) {
|
77
78
|
btn_1.lastChild.textContent = targetEncoding === 1 ? '转为简体' : '转为繁体';
|
78
79
|
if (currentEncoding !== targetEncoding) {
|
79
80
|
setLang();
|
80
81
|
setTimeout(translateBody, translateDelay);
|
81
82
|
}
|
82
|
-
btn_1.addEventListener('click', () =>
|
83
|
+
btn_1.addEventListener('click', () => translatePage('转为简体', '转为繁体', btn_1), false);
|
83
84
|
}
|
84
85
|
|
85
|
-
|
86
|
+
const btn_2 = document.querySelector('.rs_hide .translate');
|
86
87
|
if (btn_2) {
|
87
88
|
btn_2.lastChild.textContent = targetEncoding === 1 ? '简' : '繁';
|
88
89
|
if (currentEncoding !== targetEncoding) {
|
89
90
|
setLang();
|
90
91
|
setTimeout(translateBody, translateDelay);
|
91
92
|
}
|
92
|
-
btn_2.addEventListener('click', () =>
|
93
|
+
btn_2.addEventListener('click', () => translatePage('简', '繁', btn_2), false);
|
93
94
|
}
|
94
95
|
}
|
95
96
|
|
package/source/js/utils.js
CHANGED
@@ -11,20 +11,21 @@
|
|
11
11
|
if (!previous && leading === false) previous = now;
|
12
12
|
const remaining = wait - (now - previous);
|
13
13
|
if (remaining <= 0 || remaining > wait) {
|
14
|
-
if (timeout)
|
15
|
-
clearTimeout(timeout);
|
16
|
-
timeout = null;
|
17
|
-
}
|
14
|
+
if (timeout) clearTimeout(timeout);
|
18
15
|
later(this, arguments);
|
19
16
|
} else if (!timeout && trailing !== false) {
|
20
17
|
timeout = setTimeout(() => later(this, arguments), remaining);
|
21
18
|
}
|
22
19
|
};
|
23
20
|
},
|
24
|
-
fadeIn: (ele, time) =>
|
21
|
+
fadeIn: (ele, time) => {
|
22
|
+
ele.style.display = 'block';
|
23
|
+
ele.style.animation = `to_show ${time}s`;
|
24
|
+
},
|
25
25
|
fadeOut: (ele, time) => {
|
26
26
|
const resetStyles = () => {
|
27
|
-
ele.style.
|
27
|
+
ele.style.display = 'none';
|
28
|
+
ele.style.animation = '';
|
28
29
|
ele.removeEventListener('animationend', resetStyles);
|
29
30
|
};
|
30
31
|
ele.addEventListener('animationend', resetStyles);
|
@@ -37,12 +38,7 @@
|
|
37
38
|
}
|
38
39
|
},
|
39
40
|
snackbarShow: (text, showAction = false, duration = 5000) => {
|
40
|
-
Snackbar.show({
|
41
|
-
text,
|
42
|
-
showAction,
|
43
|
-
duration,
|
44
|
-
pos: 'top-center'
|
45
|
-
});
|
41
|
+
Snackbar.show({ text, showAction, duration, pos: 'top-center' });
|
46
42
|
},
|
47
43
|
copy: async (text) => {
|
48
44
|
const message = await navigator.clipboard.writeText(text)
|
@@ -59,37 +55,27 @@
|
|
59
55
|
return actualTop;
|
60
56
|
},
|
61
57
|
siblings: (ele, selector) => {
|
62
|
-
return [...ele.parentNode.children].filter(
|
63
|
-
|
64
|
-
|
65
|
-
}
|
66
|
-
return child !== ele
|
67
|
-
})
|
68
|
-
},
|
69
|
-
randomNum: (length) => {
|
70
|
-
return Math.floor(Math.random() * length)
|
71
|
-
},
|
72
|
-
timeDiff: (timeObj, today) => {
|
73
|
-
const timeDiff = today.getTime() - timeObj.getTime();
|
74
|
-
return Math.floor(timeDiff / (1000 * 3600 * 24));
|
58
|
+
return [...ele.parentNode.children].filter(child =>
|
59
|
+
child !== ele && (!selector || child.matches(selector))
|
60
|
+
);
|
75
61
|
},
|
62
|
+
randomNum: length => Math.floor(Math.random() * length),
|
63
|
+
timeDiff: (timeObj, today) => Math.floor((today.getTime() - timeObj.getTime()) / (1000 * 3600 * 24)),
|
76
64
|
scrollToDest: (pos, time = 500) => {
|
77
65
|
const currentPos = window.pageYOffset;
|
78
66
|
const isNavFixed = document.getElementById('page-header').classList.contains('nav-fixed');
|
79
67
|
pos = currentPos > pos || isNavFixed ? pos - 70 : pos;
|
80
68
|
|
81
69
|
if ('scrollBehavior' in document.documentElement.style) {
|
82
|
-
window.scrollTo({top: pos, behavior: 'smooth'});
|
70
|
+
window.scrollTo({ top: pos, behavior: 'smooth' });
|
83
71
|
return;
|
84
72
|
}
|
85
73
|
|
86
74
|
const distance = pos - currentPos;
|
87
75
|
const step = currentTime => {
|
88
|
-
const
|
89
|
-
const progress = currentTime - start;
|
90
|
-
|
76
|
+
const progress = currentTime - (start || currentTime);
|
91
77
|
if (progress < time) {
|
92
|
-
window.scrollTo(0, currentPos + distance * progress / time);
|
78
|
+
window.scrollTo(0, currentPos + (distance * progress) / time);
|
93
79
|
window.requestAnimationFrame(step);
|
94
80
|
} else {
|
95
81
|
window.scrollTo(0, pos);
|
@@ -99,9 +85,9 @@
|
|
99
85
|
window.requestAnimationFrame(step);
|
100
86
|
},
|
101
87
|
isMobile: () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
|
102
|
-
isHidden: e =>
|
88
|
+
isHidden: e => e.offsetHeight === 0 && e.offsetWidth === 0,
|
103
89
|
animateIn: (ele, text) => {
|
104
|
-
Object.assign(ele.style, {display: 'block', animation: text});
|
90
|
+
Object.assign(ele.style, { display: 'block', animation: text });
|
105
91
|
},
|
106
92
|
animateOut: (ele, text) => {
|
107
93
|
const resetAnimation = () => {
|
@@ -113,12 +99,10 @@
|
|
113
99
|
ele.style.animation = text;
|
114
100
|
},
|
115
101
|
wrap: (selector, eleType, options) => {
|
116
|
-
const createEle = document.createElement(eleType)
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
selector.parentNode.insertBefore(createEle, selector)
|
121
|
-
createEle.appendChild(selector)
|
102
|
+
const createEle = document.createElement(eleType);
|
103
|
+
Object.entries(options).forEach(([key, value]) => createEle.setAttribute(key, value));
|
104
|
+
selector.parentNode.insertBefore(createEle, selector);
|
105
|
+
createEle.appendChild(selector);
|
122
106
|
},
|
123
107
|
lazyloadImg: () => {
|
124
108
|
window.lazyLoadInstance = new LazyLoad({
|
@@ -136,7 +120,7 @@
|
|
136
120
|
};
|
137
121
|
|
138
122
|
if (lightboxType === 'mediumZoom') {
|
139
|
-
mediumZoom && mediumZoom(selector, {background: "var(--efu-card-bg)"});
|
123
|
+
mediumZoom && mediumZoom(selector, { background: "var(--efu-card-bg)" });
|
140
124
|
} else if (lightboxType === 'fancybox') {
|
141
125
|
selector.forEach(i => {
|
142
126
|
if (i.parentNode.tagName !== 'A') {
|
@@ -150,9 +134,9 @@
|
|
150
134
|
Fancybox.bind('[data-fancybox]', {
|
151
135
|
Hash: false,
|
152
136
|
animated: true,
|
153
|
-
Thumbs: {showOnStart: false},
|
154
|
-
Images: {Panzoom: {maxScale: 4}},
|
155
|
-
Carousel: {transition: 'slide'},
|
137
|
+
Thumbs: { showOnStart: false },
|
138
|
+
Images: { Panzoom: { maxScale: 4 } },
|
139
|
+
Carousel: { transition: 'slide' },
|
156
140
|
Toolbar: {
|
157
141
|
display: {
|
158
142
|
left: ['infobar'],
|
@@ -173,18 +157,21 @@
|
|
173
157
|
const hour = 3600000;
|
174
158
|
const day = 86400000;
|
175
159
|
const month = 2592000000;
|
176
|
-
const {time} = GLOBAL_CONFIG.lang;
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
const
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
if (
|
186
|
-
if (
|
187
|
-
return time.
|
160
|
+
const { time } = GLOBAL_CONFIG.lang;
|
161
|
+
|
162
|
+
const dayCount = Math.floor(dateDiff / day);
|
163
|
+
if (!more) return dayCount;
|
164
|
+
|
165
|
+
const minuteCount = Math.floor(dateDiff / minute);
|
166
|
+
const hourCount = Math.floor(dateDiff / hour);
|
167
|
+
const monthCount = Math.floor(dateDiff / month);
|
168
|
+
|
169
|
+
if (monthCount > 12) return datePost.toISOString().slice(0, 10);
|
170
|
+
if (monthCount >= 1) return `${monthCount} ${time.month}`;
|
171
|
+
if (dayCount >= 1) return `${dayCount} ${time.day}`;
|
172
|
+
if (hourCount >= 1) return `${hourCount} ${time.hour}`;
|
173
|
+
if (minuteCount >= 1) return `${minuteCount} ${time.min}`;
|
174
|
+
return time.just;
|
188
175
|
},
|
189
176
|
loadComment: (dom, callback) => {
|
190
177
|
const observerItem = 'IntersectionObserver' in window ? new IntersectionObserver((entries) => {
|
@@ -192,10 +179,16 @@
|
|
192
179
|
callback();
|
193
180
|
observerItem.disconnect();
|
194
181
|
}
|
195
|
-
}, {threshold: [0]}) : null;
|
182
|
+
}, { threshold: [0] }) : null;
|
196
183
|
|
197
184
|
observerItem ? observerItem.observe(dom) : callback();
|
198
185
|
},
|
199
|
-
|
200
|
-
|
186
|
+
escapeHtml: unsafe => unsafe.replace(/[&<"']/g, m => ({
|
187
|
+
'&': '&',
|
188
|
+
'<': '<',
|
189
|
+
'"': '"',
|
190
|
+
"'": '''
|
191
|
+
}[m])),
|
192
|
+
};
|
193
|
+
window.utils = { ...window.utils, ...utilsFn };
|
201
194
|
})()
|
@@ -1,45 +0,0 @@
|
|
1
|
-
- const { server, site } = theme.artalk
|
2
|
-
|
3
|
-
script.
|
4
|
-
function updatePostsBasedOnComments() {
|
5
|
-
const location = window.location
|
6
|
-
const posts = Array.from(document.querySelectorAll('.recent-post-item[onclick] .post_cover a')).map(item => item.href.replace(location, GLOBAL_CONFIG.root))
|
7
|
-
|
8
|
-
function get() {
|
9
|
-
fetch(`!{server}/api/v2/stats/page_comment?page_keys=${posts.join(',')}&site_name=!{site}`).then(res => res.json())
|
10
|
-
.then(item => {
|
11
|
-
item = item.data
|
12
|
-
posts.forEach(post => {
|
13
|
-
const comment = item[post]
|
14
|
-
if (comment > !{count}) {
|
15
|
-
const postElement = document.querySelector(`.recent-post-item[onclick*="${post}"]`);
|
16
|
-
if (postElement) {
|
17
|
-
const infoTopTips = postElement.querySelector(".recent-post-info-top-tips"),
|
18
|
-
originalSpan = infoTopTips ? infoTopTips.querySelector(".original") : null;
|
19
|
-
if (originalSpan) {
|
20
|
-
const hotTip = createHotTipElement();
|
21
|
-
infoTopTips.insertBefore(hotTip, originalSpan);
|
22
|
-
}
|
23
|
-
}
|
24
|
-
}
|
25
|
-
})
|
26
|
-
})
|
27
|
-
.catch(error => console.error("Error fetching comments:", error));
|
28
|
-
}
|
29
|
-
|
30
|
-
function createHotTipElement() {
|
31
|
-
const hotTip = document.createElement("span");
|
32
|
-
hotTip.classList.add("hot-tip");
|
33
|
-
|
34
|
-
const icon = document.createElement("i");
|
35
|
-
icon.classList.add("solitude", "fas", "fa-fire-flame-curved");
|
36
|
-
hotTip.appendChild(icon);
|
37
|
-
|
38
|
-
const commentCount = document.createTextNode("!{_p('hot-tip')}");
|
39
|
-
hotTip.appendChild(commentCount);
|
40
|
-
|
41
|
-
return hotTip;
|
42
|
-
}
|
43
|
-
|
44
|
-
get()
|
45
|
-
}
|
@@ -1,46 +0,0 @@
|
|
1
|
-
script.
|
2
|
-
function updatePostsBasedOnComments() {
|
3
|
-
const location = window.location
|
4
|
-
const posts = Array.from(document.querySelectorAll('.recent-post-item[onclick] .post_cover a')).map(item => item.href.replace(location, '/'))
|
5
|
-
|
6
|
-
function get() {
|
7
|
-
twikoo.getCommentsCount({
|
8
|
-
envId: "!{theme.twikoo.envId}",
|
9
|
-
urls: posts,
|
10
|
-
includeReply: true
|
11
|
-
}).then(function (response) {
|
12
|
-
response.forEach(function (comment) {
|
13
|
-
if (comment.count > !{count}) {
|
14
|
-
const postElement = document.querySelector(`.recent-post-item[onclick*="${comment.url}"]`);
|
15
|
-
if (postElement) {
|
16
|
-
const infoTopTips = postElement.querySelector(".recent-post-info-top-tips"),
|
17
|
-
originalSpan = infoTopTips ? infoTopTips.querySelector(".original") : null;
|
18
|
-
if (originalSpan) {
|
19
|
-
const hotTip = createHotTipElement();
|
20
|
-
infoTopTips.insertBefore(hotTip, originalSpan);
|
21
|
-
}
|
22
|
-
}
|
23
|
-
}
|
24
|
-
});
|
25
|
-
}).catch(function (error) {
|
26
|
-
console.error("Error fetching comments:", error);
|
27
|
-
});
|
28
|
-
}
|
29
|
-
|
30
|
-
function createHotTipElement() {
|
31
|
-
const hotTip = document.createElement("span");
|
32
|
-
hotTip.classList.add("hot-tip");
|
33
|
-
|
34
|
-
const icon = document.createElement("i");
|
35
|
-
icon.classList.add("solitude", "fas", "fa-fire-flame-curved");
|
36
|
-
hotTip.appendChild(icon);
|
37
|
-
|
38
|
-
const commentCount = document.createTextNode("!{_p('hot-tip')}");
|
39
|
-
hotTip.appendChild(commentCount);
|
40
|
-
|
41
|
-
return hotTip;
|
42
|
-
}
|
43
|
-
|
44
|
-
if (typeof twikoo === 'object') get()
|
45
|
-
else utils.getScript('!{url_for(theme.cdn.twikoo)}').then(get)
|
46
|
-
}
|
package/source/img/loading.avif
DELETED
Binary file
|
File without changes
|