hexo-theme-solitude 3.0.11 → 3.0.13

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
  })()
@@ -8,6 +8,4 @@ case use[0]
8
8
  when 'Valine'
9
9
  !=partial('includes/widgets/sidebar/valine', {}, {cache: true})
10
10
  when 'Artalk'
11
- !=partial('includes/widgets/sidebar/artalk', {}, {cache: true})
12
- when 'Giscus'
13
- !=partial('includes/widgets/sidebar/giscus', {}, {cache: true})
11
+ !=partial('includes/widgets/sidebar/artalk', {}, {cache: true})
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.13",
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:
@@ -2,7 +2,6 @@
2
2
  overflow-wrap break-word
3
3
  +maxWidth768()
4
4
  overflow hidden
5
- padding .5rem
6
5
 
7
6
  .post &
8
7
  padding 1rem 2rem
@@ -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%
@@ -1,100 +1,103 @@
1
+ galleryHeight = 250px
2
+ transitionTime = 0.35s
3
+ easeTransition = 375ms ease-in 0.2s
4
+
1
5
  .article-container
2
6
  figure.gallery-group
3
- position: relative
4
- overflow: hidden
5
- margin: 0
6
- width: calc(50% - 8px)
7
- height: 250px
8
- border-radius: 8px
9
- background: var(--efu-black)
10
- -webkit-transform: translate3d(0, 0, 0)
7
+ position relative
8
+ overflow hidden
9
+ margin 0
10
+ width calc(50% - 8px)
11
+ height galleryHeight
12
+ border-radius 8px
13
+ background var(--efu-black)
14
+ -webkit-transform translate3d(0, 0, 0)
11
15
 
12
16
  +maxWidth600()
13
- width: calc(100% - 8px)
17
+ width calc(100% - 8px)
14
18
 
15
19
  &:hover
16
20
  img
17
- opacity: .4
18
- transform: translate3d(0, 0, 0)
19
-
21
+ opacity 0.4
22
+ transform translate3d(0, 0, 0)
20
23
  .gallery-group-name::after
21
- transform: translate3d(0, 0, 0)
22
-
24
+ transform translate3d(0, 0, 0)
23
25
  p
24
- opacity: 1
25
- transform: translate3d(0, 0, 0)
26
+ opacity 1
27
+ transform translate3d(0, 0, 0)
26
28
 
27
29
  img
28
- position: relative
29
- margin: 0
30
- max-width: none
31
- width: calc(100% + 20px)
32
- height: 250px
33
- backface-visibility: hidden
34
- opacity: .8
35
- transition: all .3s, filter 375ms ease-in .2s
36
- transform: translate3d(-10px, 0, 0)
37
- object-fit: cover
30
+ position relative
31
+ margin 0
32
+ max-width none
33
+ width calc(100% + 20px)
34
+ height galleryHeight
35
+ backface-visibility hidden
36
+ opacity 0.8
37
+ transition all 0.3s, filter easeTransition
38
+ transform translate3d(-10px, 0, 0)
39
+ object-fit cover
38
40
  border none
39
41
 
40
42
  figcaption
41
- position: absolute
42
- top: 0
43
- left: 0
44
- padding: 30px
45
- width: 100%
46
- height: 100%
47
- color: var(--efu-white)
48
- text-transform: uppercase
49
- backface-visibility: hidden
43
+ position absolute
44
+ top 0
45
+ left 0
46
+ padding 30px
47
+ width 100%
48
+ height 100%
49
+ color var(--efu-white)
50
+ text-transform uppercase
51
+ backface-visibility hidden
50
52
 
51
53
  & > a
52
- position: absolute
53
- top: 0
54
- right: 0
55
- bottom: 0
56
- left: 0
57
- z-index: 1000
58
- opacity: 0
54
+ position absolute
55
+ top 0
56
+ right 0
57
+ bottom 0
58
+ left 0
59
+ z-index 1000
60
+ opacity 0
59
61
 
60
62
  p
61
63
  @extend .limit-more-line
62
- margin: 0
63
- padding: 8px 0 0
64
- letter-spacing: 1px
65
- font-size: 1.1em
66
- line-height: 1.5
67
- opacity: 0
68
- transition: opacity .35s, transform .35s
69
- transform: translate3d(100%, 0, 0)
70
- -webkit-line-clamp: 4
64
+ margin 0
65
+ padding 8px 0 0
66
+ letter-spacing 1px
67
+ font-size 1.1em
68
+ line-height 1.5
69
+ opacity 0
70
+ transition opacity transitionTime, transform transitionTime
71
+ transform translate3d(100%, 0, 0)
72
+ -webkit-line-clamp 4
71
73
 
72
74
  .gallery-group-name
73
75
  @extend .limit-more-line
74
- position: relative
75
- margin: 0
76
- padding: 8px 0
77
- font-weight: bold
78
- font-size: 1.65em
79
- line-height: 1.5
80
- -webkit-line-clamp: 2
76
+ position relative
77
+ margin 0
78
+ padding 8px 0
79
+ font-weight bold
80
+ font-size 1.65em
81
+ line-height 1.5
82
+ -webkit-line-clamp 2
81
83
 
82
84
  &:after
83
- position: absolute
84
- bottom: 0
85
- left: 0
86
- width: 100%
87
- height: 2px
88
- background: var(--efu-white)
89
- content: ''
90
- transition: transform .35s
91
- transform: translate3d(-100%, 0, 0)
85
+ position absolute
86
+ bottom 0
87
+ left 0
88
+ width 100%
89
+ height 2px
90
+ background var(--efu-white)
91
+ content ''
92
+ transition transform transitionTime
93
+ transform translate3d(-100%, 0, 0)
92
94
 
93
95
  .gallery-group-main
94
96
  overflow auto
95
97
  display flex
96
- gap .5rem
97
- margin-top .5rem
98
+ gap 0.5rem
99
+ margin-top 0.5rem
100
+ flex-wrap wrap
98
101
 
99
102
  .gallery-item
100
103
  min-height 5rem
@@ -103,21 +106,18 @@
103
106
  position relative
104
107
 
105
108
  +maxWidth1200()
106
- width 32.97%
109
+ width 32.97%
107
110
 
108
111
  +maxWidth768()
109
112
  width 49.97%
110
113
 
111
114
  img
112
- max-width: 100%;
113
- border-radius: 0;
115
+ max-width 100%
116
+ border-radius 0
114
117
  margin 0
115
118
 
116
- / #page &
117
- border-radius 8px
118
-
119
119
  .waterfall
120
120
  opacity 0
121
- transition .3s
121
+ transition 0.3s
122
122
  &.show
123
123
  opacity 1
@@ -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
@@ -24,7 +25,7 @@
24
25
  &.active
25
26
  background var(--light-grey)
26
27
  i,button
27
- color var(--efu-card-bg)
28
+ color var(--efu-main)
28
29
 
29
30
  i
30
31
  font-size 14px
@@ -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();