hexo-theme-solitude 3.0.11 → 3.0.12

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 CHANGED
@@ -977,34 +977,34 @@ CDN:
977
977
  custom_format: https://fastly.jsdelivr.net/npm/${name}@${version}/${min_file} # 自定义格式
978
978
  # 直接覆盖默认 CDN 链接(优先级最高)
979
979
  options:
980
- # algolia_search
981
- # aplayer_css
982
- # aplayer_js
983
- # artalk_css
984
- # artalk_js
985
- # blueimp_md5
986
- # busuanzi_js
987
- # chart_js
988
- # color_thief
989
- # fancyapps_css
990
- # fancyapps_ui
991
- # fontawesome
992
- # instantsearch
993
- # katex
994
- # katex_copytex
995
- # lazyload
996
- # medium_zoom
997
- # mermaid_js
998
- # meting_js
999
- # pace_js
1000
- # pjax
1001
- # qrcode
1002
- # snackbar
1003
- # swiper_css
1004
- # swiper_js
1005
- # twikoo
1006
- # typeit_js
1007
- # valine
1008
- # waline_css
1009
- # waline_js
980
+ # algolia_search:
981
+ # aplayer_css:
982
+ # aplayer_js:
983
+ # artalk_css:
984
+ # artalk_js:
985
+ # blueimp_md5:
986
+ # busuanzi_js:
987
+ # chart_js:
988
+ # color_thief:
989
+ # fancyapps_css:
990
+ # fancyapps_ui:
991
+ # fontawesome:
992
+ # instantsearch:
993
+ # katex:
994
+ # katex_copytex:
995
+ # lazyload:
996
+ # medium_zoom:
997
+ # mermaid_js:
998
+ # meting_js:
999
+ # pace_js:
1000
+ # pjax:
1001
+ # qrcode:
1002
+ # snackbar:
1003
+ # swiper_css:
1004
+ # swiper_js:
1005
+ # twikoo:
1006
+ # typeit_js:
1007
+ # valine:
1008
+ # waline_css:
1009
+ # waline_js:
1010
1010
  # --------------------------- end ---------------------------
package/languages/en.yml CHANGED
File without changes
File without changes
File without changes
@@ -18,7 +18,7 @@ if site.data.about.rewardList && site.data.about.award.enable
18
18
  if reward.icon
19
19
  i.solitude(class=reward.icon)
20
20
  | ¥ #{reward.money}
21
- time.datatime.reward-list-item-time(datetime=moment(reward.time).format())
21
+ time.datetime.reward-list-item-time(datetime=moment(reward.time).format())
22
22
  if theme.post.award.enable
23
23
  .post-reward
24
24
  .post-reward(onclick="AddRewardMask()")
@@ -8,6 +8,6 @@ script(pjax).
8
8
  const searchParams = new URLSearchParams({'site_name': "!{site}", 'limit': '-1'})
9
9
  await fetch(`!{server}/api/v2/stats/latest_comments?${searchParams}`, {method: 'GET'}).then(async res => res.json())
10
10
  .then(async data => {
11
- document.querySelector('#artalk_allcount').innerHTML = data.length
11
+ document.querySelector('#artalk_allcount').innerHTML = data.data.length;
12
12
  })
13
13
  })()
package/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "hexo-theme-solitude",
3
- "version": "3.0.11",
3
+ "version": "3.0.12",
4
4
  "description": "A beautiful, powerful, and efficient Hexo theme developed by everfu.",
5
5
  "main": "package.json",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
6
  "keywords": [
10
7
  "hexo",
11
8
  "theme",
@@ -29,5 +26,8 @@
29
26
  },
30
27
  "homepage": "https://solitude.js.org",
31
28
  "author": "Hexo-Theme-Solitude<o@efu.me>",
32
- "license": "Apache-2.0"
33
- }
29
+ "license": "Apache-2.0",
30
+ "scripts": {
31
+ "test": "echo \"Error: no test specified\" && exit 1"
32
+ }
33
+ }
package/plugins.yml CHANGED
@@ -7,12 +7,12 @@ instantsearch:
7
7
  file: dist/instantsearch.production.min.js
8
8
  version: 4.75.7
9
9
  docsearch_css:
10
- name: '@docsearch/css'
10
+ name: "@docsearch/css"
11
11
  other_name: docsearch-css
12
12
  file: dist/style.css
13
13
  version: 3.8.2
14
14
  docsearch_js:
15
- name: '@docsearch/js'
15
+ name: "@docsearch/js"
16
16
  other_name: docsearch-js
17
17
  file: dist/umd/index.js
18
18
  version: 3.8.2
@@ -25,12 +25,12 @@ twikoo:
25
25
  file: dist/twikoo.all.min.js
26
26
  version: 1.6.41
27
27
  waline_js:
28
- name: '@waline/client'
28
+ name: "@waline/client"
29
29
  file: dist/waline.js
30
30
  other_name: waline
31
31
  version: 3.4.3
32
32
  waline_css:
33
- name: '@waline/client'
33
+ name: "@waline/client"
34
34
  file: dist/waline.css
35
35
  version: 3.4.3
36
36
  other_name: waline
@@ -96,7 +96,7 @@ snackbar:
96
96
  file: dist/snackbar.min.js
97
97
  version: 0.1.16
98
98
  fontawesome:
99
- name: '@fortawesome/fontawesome-free'
99
+ name: "@fortawesome/fontawesome-free"
100
100
  file: css/all.min.css
101
101
  version: 6.7.2
102
102
  other_name: font-awesome
@@ -105,12 +105,12 @@ medium_zoom:
105
105
  file: dist/medium-zoom.min.js
106
106
  version: 1.1.0
107
107
  fancyapps_ui:
108
- name: '@fancyapps/ui'
108
+ name: "@fancyapps/ui"
109
109
  file: dist/fancybox/fancybox.umd.js
110
110
  version: 5.0.36
111
111
  other_name: fancyapps-ui
112
112
  fancyapps_css:
113
- name: '@fancyapps/ui'
113
+ name: "@fancyapps/ui"
114
114
  file: dist/fancybox/fancybox.css
115
115
  version: 5.0.36
116
116
  other_name: fancyapps-ui
@@ -125,7 +125,7 @@ chart_js:
125
125
  other_name: Chart.js
126
126
  typeit_js:
127
127
  name: typeit
128
- file: dist/index.umd.min.js
128
+ file: dist/index.umd.js
129
129
  version: 8.8.7
130
130
  other_name: typeit
131
131
  blueimp_md5:
@@ -18,12 +18,12 @@
18
18
  display flex
19
19
  flex-wrap wrap
20
20
  flex-direction row
21
- margin 1rem -.25rem .5rem
21
+ margin 1rem -.125rem .5rem
22
22
 
23
23
  .post-reward
24
24
  position absolute
25
- right 2rem
26
- top 2rem
25
+ right 1rem
26
+ top 1rem
27
27
 
28
28
  .reward-main
29
29
  top 60px
@@ -57,26 +57,27 @@
57
57
  padding 1rem
58
58
  border-radius 12px
59
59
  border var(--style-border-always)
60
- width calc((100% / 6) - .5rem)
61
- margin 0 .25rem .5rem .25rem
60
+ width calc((100% / 6) - .25rem)
61
+ margin 0 .125rem .5rem .125rem
62
62
  box-shadow var(--efu-shadow-border)
63
+ display flex
63
64
  flex-direction column
64
65
  justify-content space-between
65
66
 
66
67
  +maxWidth1200()
67
- width calc((100% / 4) - .5rem)
68
+ width calc((100% / 4) - .25rem)
68
69
 
69
70
  +maxWidth900()
70
- width calc((100% / 2) - .5rem)
71
+ width calc((100% / 2) - .25rem)
71
72
 
72
73
  +maxWidth768()
73
- width 100%
74
+ width calc((100% / 2) - .25rem)
74
75
 
75
76
  .reward-list-item-name
76
77
  font-size 1rem
77
78
  font-weight 700
78
79
  line-height 1
79
- margin-bottom .5rem
80
+ margin-bottom .25rem
80
81
  white-space nowrap
81
82
  overflow hidden
82
83
  text-overflow ellipsis
@@ -96,12 +97,12 @@
96
97
  align-items center
97
98
  justify-content center
98
99
  border-radius 4px
99
- margin-right 4px
100
+ margin-right 2px
100
101
  white-space nowrap
101
102
 
102
103
  .solitude
103
104
  font-size 14px
104
- margin-right 4px
105
+ margin-right 2px
105
106
  color var(--efu-card-bg)
106
107
 
107
108
  .reward-list-item-time
@@ -112,4 +113,4 @@
112
113
  .reward-list-tips
113
114
  p
114
115
  font-size 12px
115
- color var(--efu-secondtext)
116
+ color var (--efu-secondtext)
@@ -104,8 +104,8 @@ if hexo-config('post.ai.enable')
104
104
 
105
105
  .char
106
106
  display inline-block
107
- opacity 0ai-explanation
108
- animation chat-float .3s ease forwards;
107
+ opacity 0
108
+ animation chat-float .5s ease forwards;
109
109
 
110
110
  @keyframes chat-float
111
111
  0%
@@ -95,6 +95,7 @@
95
95
  display flex
96
96
  gap .5rem
97
97
  margin-top .5rem
98
+ flex-wrap wrap
98
99
 
99
100
  .gallery-item
100
101
  min-height 5rem
@@ -10,6 +10,7 @@
10
10
  margin-bottom .5rem
11
11
  padding .3rem .5rem
12
12
  gap .5rem
13
+ flex-wrap wrap
13
14
 
14
15
  .tab
15
16
  border-radius 6px
@@ -43,4 +44,4 @@
43
44
  .tab-item-content
44
45
  display none
45
46
  opacity 0
46
- transform translateY(-10px)
47
+ transform translateY(-10px)
@@ -3,58 +3,116 @@ class AIPostRenderer {
3
3
  static AI_EXPLANATION_SELECTOR = ".ai-explanation";
4
4
  static AI_TAG_SELECTOR = ".ai-tag";
5
5
 
6
+ constructor() {
7
+ this.startTextAnimation = this.startTextAnimation.bind(this);
8
+ this.animationFrame = null;
9
+ }
10
+
6
11
  init() {
7
- this.tagElement = document.querySelector(AIPostRenderer.AI_TAG_SELECTOR);
8
- this.isAnimating = false;
9
- this.aiContent = PAGE_CONFIG?.ai_text || "";
10
- this.explanationElement = document.querySelector(
11
- AIPostRenderer.AI_EXPLANATION_SELECTOR
12
- );
13
- this.renderAIContent();
12
+ if (document.readyState === "loading") {
13
+ document.addEventListener("DOMContentLoaded", this.initialize.bind(this));
14
+ } else {
15
+ this.initialize();
16
+ }
14
17
  }
15
18
 
16
- renderAIContent() {
17
- if (!this.validateElements() || !this.aiContent) return;
19
+ initialize() {
20
+ this.cacheElements();
21
+ this.validateContent() && this.renderAIContent();
22
+ }
18
23
 
19
- this.prepareAnimation();
20
- this.startTextAnimation();
24
+ cacheElements() {
25
+ this.refs = new WeakMap();
26
+ this.refs.set(document, {
27
+ explanationElement: document.querySelector(
28
+ AIPostRenderer.AI_EXPLANATION_SELECTOR
29
+ ),
30
+ tagElement: document.querySelector(AIPostRenderer.AI_TAG_SELECTOR),
31
+ });
32
+
33
+ const { explanationElement, tagElement } = this.refs.get(document) || {};
34
+ this.explanationElement = explanationElement;
35
+ this.tagElement = tagElement;
21
36
  }
22
37
 
23
- validateElements() {
24
- return this.explanationElement && this.tagElement && !this.isAnimating;
38
+ validateContent() {
39
+ return !!(
40
+ this.explanationElement &&
41
+ this.tagElement &&
42
+ this.aiContent.length &&
43
+ !this.isAnimating
44
+ );
45
+ }
46
+
47
+ renderAIContent() {
48
+ this.prepareAnimation();
49
+ this.animationFrame = requestAnimationFrame(() =>
50
+ this.startTextAnimation(0)
51
+ );
25
52
  }
26
53
 
27
54
  prepareAnimation() {
28
55
  this.isAnimating = true;
29
56
  this.tagElement.classList.add("loadingAI");
30
- this.explanationElement.innerHTML = "";
57
+ this.explanationElement.textContent = "";
31
58
  }
32
59
 
33
- startTextAnimation() {
34
- const animate = (index) => {
35
- if (index >= this.aiContent.length) {
36
- this.completeAnimation();
37
- return;
38
- }
39
-
40
- this.appendCharacter(this.aiContent[index]);
41
- setTimeout(() => animate(index + 1), AIPostRenderer.ANIMATION_DELAY_MS);
42
- };
60
+ startTextAnimation(index) {
61
+ if (index >= this.aiContent.length) {
62
+ this.completeAnimation();
63
+ return;
64
+ }
43
65
 
44
- animate(0);
66
+ this.appendCharacter(this.aiContent[index]);
67
+ this.animationFrame = requestAnimationFrame(() =>
68
+ this.startTextAnimation(index + 1)
69
+ );
45
70
  }
46
71
 
47
72
  appendCharacter(char) {
73
+ if (!this.fragment) this.fragment = document.createDocumentFragment();
74
+
48
75
  const charElement = document.createElement("span");
49
76
  charElement.className = "char";
50
77
  charElement.textContent = char;
51
- this.explanationElement.appendChild(charElement);
78
+ this.fragment.appendChild(charElement);
79
+
80
+ if (this.fragment.childNodes.length % 1 === 0) {
81
+ this.explanationElement.appendChild(this.fragment);
82
+ this.fragment = null;
83
+ }
52
84
  }
53
85
 
54
86
  completeAnimation() {
87
+ if (this.fragment) {
88
+ this.explanationElement.appendChild(this.fragment);
89
+ this.fragment = null;
90
+ }
91
+
92
+ cancelAnimationFrame(this.animationFrame);
55
93
  this.isAnimating = false;
56
94
  this.tagElement.classList.remove("loadingAI");
95
+
96
+ const event = new CustomEvent("aiRenderComplete", {
97
+ detail: { element: this.explanationElement },
98
+ });
99
+ document.dispatchEvent(event);
100
+ }
101
+
102
+ get aiContent() {
103
+ return PAGE_CONFIG?.ai_text || "";
57
104
  }
58
105
  }
59
106
 
60
- const ai = new AIPostRenderer();
107
+ const aiPostRenderer = (() => {
108
+ let instance;
109
+ return () => {
110
+ if (!instance) {
111
+ instance = new AIPostRenderer();
112
+ instance.init();
113
+ }
114
+ return instance;
115
+ };
116
+ })();
117
+
118
+ const ai = aiPostRenderer();