hexo-theme-solitude 3.0.17 → 3.0.19

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/SECURITY.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Reporting a Vulnerability
4
4
 
5
- If you discover a vulnerability, please report it privately through the [GitHub Security tab](https://github.com/everfu/hexo-theme-solitude/security/advisories/new) on the appropriate repository. For detailed instructions, refer to this [documentation](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability). If you're unable to report via GitHub, you can email us at [o@everfu.org](mailto:o@everfu.org).
5
+ If you discover a vulnerability, please report it privately through the [GitHub Security tab](https://github.com/everfu/hexo-theme-solitude/security/advisories/new) on the appropriate repository. For detailed instructions, refer to this [documentation](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability). If you're unable to report via GitHub, you can email us at [o@everfu.org](mailto:o@efu.me).
6
6
 
7
7
  We take security seriously and will verify and resolve any reported vulnerabilities promptly.
8
8
 
package/languages/en.yml CHANGED
File without changes
File without changes
File without changes
@@ -54,6 +54,18 @@ div#footer-bar
54
54
  a.footer-bar-link(href=url_for("/"))
55
55
  img.author-avatar(src=url_for(theme.site.icon))
56
56
  = config.author
57
+ .beian-group
58
+ if theme.footer.beian
59
+ - var beian = theme.footer.beian || []
60
+ each item in beian
61
+ a.footer-bar-link(href=url_for(item.url), title=item.name)
62
+ if item.icon
63
+ img.beian-icon(src=url_for(item.icon), alt=item.name)
64
+ span.beian-name= item.name
65
+ a.footer-bar-link(href=_p('hexo'))
66
+ = _p('framework_by') + 'Hexo'
67
+ a.footer-bar-link(href=_p('repo'))
68
+ = _p('theme_by') + 'Solitude'
57
69
  else
58
70
  div.copyright © #{moment(theme.aside.siteinfo.runtime).year()} - #{new Date().getFullYear()} By 
59
71
  a.footer-bar-link(href=url_for("/"))
@@ -22,17 +22,38 @@ if games
22
22
  .tips= game.tips_right
23
23
 
24
24
  if site.data.about.likes
25
- - const likes = site.data.about.likes
26
- .author-content
27
- each like in likes
28
- .author-content-item(class=like.type, style=`background: url(${like.bg}) no-repeat center; background-size: cover;`)
29
- .card-content
30
- .author-content-item-tips= like.tips
31
- span.author-content-item-title= like.title
32
- .content-bottom
33
- .tips= like.subtips
34
- if like.button
35
- .banner-button-group
36
- a.banner-button(href=url_for(like.button_link))
37
- i.solitude.fas.fa-circle-chevron-right
38
- span.banner-button-text= like.button_text
25
+ - const likes = site.data.about.likes
26
+ .author-content
27
+ each like in likes
28
+ if like.type === 'comic'
29
+ .author-content-item.comic
30
+ .card-content
31
+ .author-content-item-tips= like.tips
32
+ span.author-content-item-title= like.title
33
+ .content-bottom
34
+ if like.subtips
35
+ .tips= like.subtips
36
+ if like.button
37
+ .banner-button-group
38
+ a.banner-button(href=url_for(like.button_link))
39
+ i.solitude.fas.fa-circle-chevron-right
40
+ span.banner-button-text= like.button_text
41
+ .comic-box
42
+ each item in like.list
43
+ a.comic-item(href=item.href target="_blank", rel="noopener noreferrer", title=item.name)
44
+ .comic-item-cover
45
+ img.nolazyload(src=item.cover, alt=item.name)
46
+
47
+ else
48
+ .author-content-item(class=like.type style=`background: url(${like.bg}) no-repeat center/cover`)
49
+ .card-content
50
+ .author-content-item-tips= like.tips
51
+ span.author-content-item-title= like.title
52
+ .content-bottom
53
+ if like.subtips
54
+ .tips= like.subtips
55
+ if like.button
56
+ .banner-button-group
57
+ a.banner-button(href=url_for(like.button_link))
58
+ i.solitude.fas.fa-circle-chevron-right
59
+ span.banner-button-text= like.button_text
@@ -57,10 +57,10 @@ script(pjax).
57
57
  ${i.title}</div>
58
58
  </div>
59
59
  `).join('') : `#{__("console.newest_comment.empty")}`
60
- if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
60
+ if (typeof utils !== 'undefined') utils.diffDateFormat(document.querySelectorAll('.comment-time'))
61
61
  else {
62
- document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
63
- document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
62
+ document.addEventListener('pjax:complete', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
63
+ document.addEventListener('DOMContentLoaded', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
64
64
  }
65
65
  }
66
66
 
@@ -64,10 +64,10 @@ script(pjax).
64
64
  ${i.title}</div>
65
65
  </div>
66
66
  `).join('') : `#{__("console.newest_comment.empty")}`
67
- if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
67
+ if (typeof utils !== 'undefined') utils.diffDateFormat(document.querySelectorAll('.comment-time'))
68
68
  else {
69
- document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
70
- document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
69
+ document.addEventListener('pjax:complete', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
70
+ document.addEventListener('DOMContentLoaded', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
71
71
  }
72
72
  }
73
73
 
@@ -62,10 +62,10 @@ script(pjax).
62
62
  ${i.title}</div>
63
63
  </div>
64
64
  `).join('') : `#{__("console.newest_comment.empty")}`
65
- if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
65
+ if (typeof utils !== 'undefined') utils.diffDateFormat(document.querySelectorAll('.comment-time'))
66
66
  else {
67
- document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
68
- document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
67
+ document.addEventListener('pjax:complete', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
68
+ document.addEventListener('DOMContentLoaded', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
69
69
  }
70
70
  }
71
71
 
@@ -53,10 +53,10 @@ script(pjax).
53
53
  ${i.title}</div>
54
54
  </div>
55
55
  `).join('') : `#{__("console.newest_comment.empty")}`
56
- if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
56
+ if (typeof utils !== 'undefined') utils.diffDateFormat(document.querySelectorAll('.comment-time'))
57
57
  else {
58
- document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
59
- document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
58
+ document.addEventListener('pjax:complete', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
59
+ document.addEventListener('DOMContentLoaded', () => utils.diffDateFormat(document.querySelectorAll('.comment-time')))
60
60
  }
61
61
  }
62
62
 
@@ -1,3 +1,8 @@
1
1
  div.needEndHide#nav-music
2
- #nav-music-hoverTips(onclick='sco.musicToggle()')= __('music.hit')
2
+ #nav-music-hoverTips
3
+ i#music-prev.music-control-btn.fas.fa-backward-step(onclick='sco.musicSkipBack()')
4
+ i#music-pause.music-control-btn.fas.fa-pause(onclick='sco.musicToggle()')
5
+ i#music-play.music-control-btn.fas.fa-play(onclick='sco.musicToggle()')
6
+ i#music-next.music-control-btn.fas.fa-forward-step(onclick='sco.musicSkipForward()')
7
+
3
8
  meting-js(id=theme.capsule.id server=theme.capsule.server type=theme.capsule.type mutex="true" preload="none" theme="var(--efu-main)" data-lrctype="0" order="random" volume=theme.capsule.volume)
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "hexo-theme-solitude",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
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
+ },
6
9
  "keywords": [
7
10
  "hexo",
8
11
  "theme",
@@ -26,8 +29,5 @@
26
29
  },
27
30
  "homepage": "https://solitude.js.org",
28
31
  "author": "Hexo-Theme-Solitude<o@efu.me>",
29
- "license": "Apache-2.0",
30
- "scripts": {
31
- "test": "echo \"Error: no test specified\" && exit 1"
32
- }
33
- }
32
+ "license": "Apache-2.0"
33
+ }
@@ -3,10 +3,10 @@
3
3
  * inject is to head
4
4
  */
5
5
 
6
- 'use strict';
6
+ "use strict";
7
7
 
8
- hexo.extend.helper.register('inject_head_js', function () {
9
- const createJS = () => `
8
+ hexo.extend.helper.register("inject_head_js", function () {
9
+ const createJS = () => `
10
10
  const saveToLocal = {
11
11
  set: function setWithExpiry(key, value, ttl) {
12
12
  if (ttl === 0)
@@ -85,13 +85,19 @@ hexo.extend.helper.register('inject_head_js', function () {
85
85
  utils.addGlobalFn('pjax', () => {
86
86
  ele.removeEventListener(event, fn, option)
87
87
  })
88
- },
88
+ },
89
+ diffDateFormat: (selector) => {
90
+ selector.forEach(item => {
91
+ const date = new Date(item.getAttribute('datetime') || item.textContent);
92
+ item.textContent = (date.getMonth() + 1).toString()+'/'+date.getDate().toString();
93
+ });
94
+ },
89
95
  }
90
- `
91
- return `<script>(()=>{${createJS()}})()</script>`
92
- })
96
+ `;
97
+ return `<script>(()=>{${createJS()}})()</script>`;
98
+ });
93
99
 
94
- hexo.extend.helper.register('packageVersion', function () {
95
- const {version} = require('../../package.json')
96
- return version
97
- })
100
+ hexo.extend.helper.register("packageVersion", function () {
101
+ const { version } = require("../../package.json");
102
+ return version;
103
+ });
@@ -10,7 +10,7 @@
10
10
  0%, 100%
11
11
  box-shadow: 0 0px 12px -3px var(--efu-none)
12
12
  50%
13
- box-shadow: 0 0px 12px 0px var(--efu-main)
13
+ box-shadow: 0 0px 12px 0px var(--efu-music)
14
14
 
15
15
  @keyframes lightBar
16
16
  0%, 100%
@@ -34,15 +34,12 @@
34
34
  cursor: pointer
35
35
  transition: all 0.5s, left 0s
36
36
  transform-origin: left bottom
37
- box-shadow: var(--efu-shadow-border)
38
37
  border-radius: 40px
39
38
  overflow: hidden
40
-
41
- &:active
42
- transform: scale(0.97)
39
+ .aplayer-button
40
+ display none
43
41
 
44
42
  &.playing
45
- border: var(--style-border)
46
43
  box-shadow: 0 0px 12px -3px var(--efu-none)
47
44
  animation: playingShadow 5s linear infinite
48
45
 
@@ -56,20 +53,38 @@
56
53
  .aplayer-info
57
54
  color: var(--efu-white)
58
55
 
59
- #nav-music-hoverTips
60
- width: 0
61
-
62
56
  .aplayer
63
- background: var(--efu-main)
64
- border: var(--style-border-hover)
57
+ background: var(--efu-music)
65
58
  backdrop-filter: saturate(180%) blur(20px)
66
59
  transform: translateZ(0)
67
60
 
68
61
  .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played
69
62
  animation-play-state: running
70
63
 
71
- &:hover:not(.playing) #nav-music-hoverTips
64
+ &:hover #nav-music-hoverTips
72
65
  opacity: 1
66
+
67
+ &:hover:not(.playing)
68
+ #nav-music-hoverTips
69
+ justify-content: center
70
+ padding-right: 0
71
+ #music-play
72
+ display: flex
73
+ padding 5px 10px
74
+ width 100%
75
+ height 100%
76
+ justify-content center
77
+ align-items center
78
+
79
+ &.playing
80
+ #nav-music-hoverTips
81
+ width 180px
82
+ right 0
83
+ left auto
84
+ background linear-gradient(to left,var(--efu-music) 60%,transparent)
85
+ &:hover
86
+ #nav-music-hoverTips > i:not(#music-play)
87
+ display: block
73
88
 
74
89
  .aplayer.aplayer-withlrc
75
90
  .aplayer-pic
@@ -86,14 +101,15 @@
86
101
  .aplayer-info
87
102
  height: 100%
88
103
  color: var(--efu-fontcolor)
89
- margin: 0
104
+ margin 0
105
+ margin-right 8px
90
106
  padding: 0
91
107
  display: flex
92
108
  align-items: center
93
109
 
94
110
  #nav-music-hoverTips
95
111
  color: var(--efu-white)
96
- background: var(--efu-main)
112
+ background: var(--efu-music)
97
113
  width: 100%
98
114
  height: 100%
99
115
  position: absolute
@@ -107,15 +123,22 @@
107
123
  font-size: 12px
108
124
  z-index: 2
109
125
  transition: 0.3s
126
+ justify-content flex-end
127
+ gap 1rem
128
+ padding-right 1rem
129
+
130
+ i
131
+ font-size: 16px
132
+ display none
133
+ cursor pointer
110
134
 
111
135
  .aplayer
112
- background: var(--efu-card-bg)
136
+ background: var(--efu-music)
113
137
  border-radius: 60px
114
138
  height: 41px
115
139
  display: flex
116
140
  margin: 0
117
141
  transition: 0.3s
118
- border: var(--style-border)
119
142
  box-shadow: none
120
143
 
121
144
  .aplayer-notice,
@@ -133,7 +156,8 @@
133
156
  margin: 0
134
157
  display: flex
135
158
  align-items: center
136
- padding: 0 12px 0 8px
159
+ padding-bottom 0
160
+ padding-left 8px
137
161
  cursor: pointer
138
162
  z-index: 1
139
163
  height: 100%
@@ -148,13 +172,14 @@
148
172
  text-overflow: ellipsis
149
173
  transition: 0.3s
150
174
  user-select: none
175
+ color var(--efu-white)
151
176
 
152
177
  .aplayer-controller
153
- position: absolute
154
- width: 100%
155
- height: 100%
156
- top: 0
157
- left: 0
178
+ // position: absolute
179
+ // width: 100%
180
+ // height: 100%
181
+ // top: 0
182
+ // left: 0
158
183
 
159
184
  .aplayer-bar-wrap
160
185
  margin: 0
@@ -220,7 +245,6 @@
220
245
 
221
246
  &.stretch .aplayer.aplayer-withlrc .aplayer-lrc
222
247
  width: 200px
223
- margin-left: 8px
224
248
  opacity: 1
225
249
 
226
250
  .aplayer-thumb
@@ -57,6 +57,7 @@
57
57
  --hlscrollbar-bg #121212
58
58
  --gap .5rem
59
59
  --radius 12px
60
+ --efu-music var(--efu-main)
60
61
 
61
62
  body
62
63
  position relative
@@ -1,10 +1,5 @@
1
1
  .article-container
2
2
  overflow-wrap break-word
3
- #post &
4
- border var(--style-border)
5
- border-radius var(--radius)
6
- box-shadow var(--efu-shadow-border)
7
- background var(--efu-card-bg)
8
3
  +maxWidth768()
9
4
  overflow hidden
10
5
 
@@ -30,10 +30,11 @@
30
30
  display flex
31
31
  justify-content center
32
32
  align-items center
33
- margin 0 30px
34
33
  transform translateY(20px)
35
34
  transition .3s
36
- max-width 1400px
35
+ gap .5rem
36
+ max-height calc(100dvh - 180px)
37
+ max-width calc(100% - 64px)
37
38
 
38
39
  +maxWidth1300()
39
40
  justify-content center
@@ -50,10 +51,8 @@
50
51
  transform translateY(0)
51
52
  opacity 1
52
53
  transition-delay .1s
53
- max-height 80%
54
54
 
55
55
  .console-card-group-left
56
- margin-right .5rem
57
56
  width 40%
58
57
  height 100%
59
58
 
@@ -77,7 +76,7 @@
77
76
  overflow hidden
78
77
  border var(--style-border)
79
78
  box-shadow var(--efu-shadow-border)
80
- padding 40px
79
+ padding 32px 36px 36px 36px
81
80
  gap 24px
82
81
  display: flex
83
82
  flex-direction: column
@@ -8,10 +8,8 @@
8
8
  padding 0
9
9
 
10
10
  #tag-page-tags+#recent-posts
11
- margin-top: calc(64px - 0.5rem)
12
-
13
- +maxWidth768()
14
- margin-top: calc(74px - 0.5rem)
11
+ +minWidth768()
12
+ margin-top calc(64px - 0.5rem)
15
13
 
16
14
  if hexo-config('index_post_list.direction') == "column"
17
15
  .recent-post-item
@@ -29,8 +27,6 @@ if hexo-config('index_post_list.direction') == "column"
29
27
 
30
28
  +maxWidth1300()
31
29
  margin-bottom .5rem
32
- #tag &:first-child
33
- margin-top: 2.5rem
34
30
 
35
31
  +maxWidth768()
36
32
  border-radius 12px
@@ -3,7 +3,6 @@
3
3
  background-size cover
4
4
  min-height 230px
5
5
  color var(--efu-white)
6
-
7
6
  &::after
8
7
  box-shadow 0 -69px 203px 11px #050b20 inset
9
8
  position absolute
@@ -18,7 +17,6 @@
18
17
  min-height 400px
19
18
  color var(--efu-white)
20
19
  overflow hidden
21
-
22
20
  &::after
23
21
  box-shadow 0 -69px 203px 11px #0e0e0e inset
24
22
  position absolute
@@ -26,4 +24,69 @@
26
24
  width 100%
27
25
  height 100%
28
26
  top 0
29
- left 0
27
+ left 0
28
+
29
+ .author-content-item.comic
30
+ min-height 400px
31
+ color var(--efu-white)
32
+ position relative
33
+
34
+ .comic-box
35
+ width 110%
36
+ height 100%
37
+ display flex
38
+ position absolute
39
+ left 50%
40
+ top 0
41
+ transform translateX(-50%)
42
+ &::after
43
+ box-shadow 0 -69px 203px 11px #04120f inset
44
+ position absolute
45
+ content ''
46
+ width 100%
47
+ height 100%
48
+ top 0
49
+ left 0
50
+ pointer-events: none;
51
+
52
+ .author-content-item-tips,
53
+ .author-content-item-title,
54
+ .content-bottom
55
+ z-index 3
56
+ color var(--efu-white)
57
+
58
+ .comic-item
59
+ height 100%
60
+ color var(--efu-white)
61
+ width 20%
62
+ transform skew(-10deg, 0deg)
63
+ transition 0.8s
64
+ position relative
65
+ overflow hidden
66
+ &:hover
67
+ width 46%
68
+ .comic-item-cover
69
+ left 16%
70
+ transform skew(10deg, 0deg) scale(1.6)
71
+
72
+ .comic-item-cover
73
+ position absolute
74
+ top 0
75
+ left -50%
76
+ height 100%
77
+ transform skew(10deg, 0deg)
78
+ object-fit cover
79
+ transition scale 0.2s, all 0.8s
80
+ img
81
+ height 100%
82
+ max-width none
83
+ transition 0.8s
84
+
85
+ .author-content-item.comic
86
+ .comic-box
87
+ +maxWidth1400()
88
+ width 120%
89
+ height 100%
90
+ +maxWidth768()
91
+ width 109%
92
+ height 100%
@@ -1,13 +1,11 @@
1
1
  div.console_recentcomments
2
2
  display flex
3
3
  flex-wrap wrap
4
- gap 12px
4
+ gap 8px
5
5
  min-height 100px
6
6
  width 100%
7
-
8
- +maxWidth1300()
9
- overflow-y scroll
10
- scrollbar-width none
7
+ overflow-y scroll
8
+ scrollbar-width none
11
9
 
12
10
  .comment-card
13
11
  position relative
@@ -24,7 +22,12 @@ div.console_recentcomments
24
22
  flex-direction column
25
23
 
26
24
  .console-card &
27
- width calc(100% / 2 - 8px)
25
+ width calc(100% / 2 - 4px)
26
+ min-width 140px
27
+ min-height calc(100% / 3 - 6px)
28
+
29
+ +maxWidth1200()
30
+ width 100%
28
31
 
29
32
  +maxWidth1300()
30
33
  min-width 100%
@@ -18,6 +18,8 @@
18
18
  transition .1s ease-out
19
19
  border-radius 12px
20
20
  border var(--style-border-always)
21
+ +maxWidth768()
22
+ display none
21
23
 
22
24
  &:hover
23
25
  max-height 1000px
@@ -114,4 +114,9 @@ if hexo-config('post.ai.enable')
114
114
  100%
115
115
  opacity 1
116
116
  transform translateY(0)
117
-
117
+
118
+ #post
119
+ border var(--style-border)
120
+ border-radius var(--radius)
121
+ box-shadow var(--efu-shadow-border)
122
+ background var(--efu-card-bg)
@@ -1,36 +1,60 @@
1
- const coverColor = () => {
2
- const pageColor = PAGE_CONFIG.color;
3
- if (pageColor) {
4
- setThemeColors(pageColor);
5
- return;
1
+ const coverColor = (music = false) => {
2
+ if (music) {
3
+ var coverPath = document.querySelector("#nav-music .aplayer-pic").style.backgroundImage;
4
+ const coverPathMatch = /url\("([^"]+)"\)/.exec(coverPath);
5
+ coverPath = coverPathMatch ? coverPathMatch[1] : '';
6
+ if (coverPath) {
7
+ handleApiColor(coverPath,music);
8
+ }
6
9
  }
7
-
8
- const path = document.getElementById("post-cover")?.src;
9
- if (path) {
10
- handleApiColor(path);
11
- } else {
12
- setDefaultThemeColors();
10
+ else {
11
+ const pageColor = PAGE_CONFIG.color;
12
+ if (pageColor) {
13
+ setThemeColors(pageColor);
14
+ return;
15
+ }
16
+
17
+ const path = document.getElementById("post-cover")?.src;
18
+ if (path) {
19
+ handleApiColor(path);
20
+ } else {
21
+ setDefaultThemeColors();
22
+ }
13
23
  }
14
24
  }
15
25
 
16
- function handleApiColor(path) {
26
+ function handleApiColor(path, music = false) {
17
27
  const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
18
28
  if (cacheGroup.postcolor?.[path]) {
19
29
  setThemeColors(cacheGroup.postcolor[path].value);
20
30
  } else {
21
31
  img2color(path);
22
32
  }
33
+ if (music) {
34
+ img2color(path, music);
35
+ }
36
+ }
37
+
38
+ function setMusicColor(value) {
39
+ if (!value) return setDefaultThemeColors();
40
+ const item = document.querySelector("#nav-music")
41
+ item.style.setProperty('--efu-music', value);
23
42
  }
24
43
 
25
- function img2color(src) {
44
+ function img2color(src, music = false) {
26
45
  fetch(`${coverColorConfig.api}${encodeURIComponent(src)}`)
27
46
  .then(response => {
28
47
  if (!response.ok) throw new Error('Network response was not ok');
29
48
  return response.json();
30
49
  })
31
50
  .then(data => {
32
- setThemeColors(data.RGB);
33
- cacheColor(src, data.RGB);
51
+ if(music) {
52
+ setMusicColor(data.RGB);
53
+ }
54
+ else {
55
+ setThemeColors(data.RGB);
56
+ cacheColor(src, data.RGB);
57
+ }
34
58
  })
35
59
  .catch(error => console.error('Error fetching color:', error));
36
60
  }
@@ -1,9 +1,19 @@
1
- const coverColor = () => {
2
- const pageColor = PAGE_CONFIG.color || document.getElementById("post-cover")?.src;
3
- if (pageColor) {
4
- localColor(pageColor);
5
- } else {
6
- setDefaultThemeColors();
1
+ const coverColor = (music = false) => {
2
+ if (music) {
3
+ var coverPath = document.querySelector("#nav-music .aplayer-pic").style.backgroundImage;
4
+ const coverPathMatch = /url\("([^"]+)"\)/.exec(coverPath);
5
+ coverPath = coverPathMatch ? coverPathMatch[1] : '';
6
+ if (coverPath) {
7
+ localColor(coverPath,music);
8
+ }
9
+ }
10
+ else {
11
+ const pageColor = PAGE_CONFIG.color || document.getElementById("post-cover")?.src;
12
+ if (pageColor) {
13
+ localColor(pageColor);
14
+ } else {
15
+ setDefaultThemeColors();
16
+ }
7
17
  }
8
18
  }
9
19
 
@@ -20,13 +30,18 @@ const setDefaultThemeColors = () => {
20
30
  initThemeColor();
21
31
  }
22
32
 
23
- const localColor = (path) => {
33
+ const localColor = (path, music = false) => {
24
34
  const colorThief = new ColorThief();
25
35
  const img = new Image();
26
36
  img.crossOrigin = "Anonymous";
27
37
  img.onload = () => {
28
38
  const color = colorThief.getColor(img);
29
- setThemeColors(rgbToHex(color), ...color);
39
+ if(music) {
40
+ setMusicColor(rgbToHex(color));
41
+ }
42
+ else{
43
+ setThemeColors(rgbToHex(color), ...color);
44
+ }
30
45
  };
31
46
  img.onerror = () => console.error('Image Error');
32
47
  img.src = path;
@@ -36,6 +51,13 @@ const rgbToHex = ([r, g, b]) => {
36
51
  return '#' + [r, g, b].map(x => Math.floor(x * 0.8).toString(16).padStart(2, '0')).join('');
37
52
  }
38
53
 
54
+ const setMusicColor = (value) => {
55
+ if (!value) return setDefaultThemeColors();
56
+ const item = document.querySelector("#nav-music")
57
+ item.style.setProperty('--efu-music', value);
58
+ }
59
+
60
+
39
61
  const setThemeColors = (value, r = null, g = null, b = null) => {
40
62
  if (!value) return setDefaultThemeColors();
41
63
 
package/source/js/main.js CHANGED
@@ -199,48 +199,47 @@ const sco = {
199
199
  window.scroll({ top: targetPosition, behavior: "smooth" });
200
200
  }
201
201
  },
202
- musicToggle(isMeting = true) {
203
- if (!this.isMusicBind) {
204
- this.musicBind();
202
+ musicBind() {
203
+ const $music = document.querySelector("#nav-music meting-js");
204
+ if ($music && $music.aplayer) {
205
+ this.isMusicBind = true;
206
+ $music.onclick = () => this.musicPlaying && this.musicToggle(false);
207
+ $music.aplayer.on('loadeddata', () =>{
208
+ coverColor(true);
209
+ })
205
210
  }
211
+ },
212
+ musicToggle(isMeting = true) {
213
+ if (!this.isMusicBind) this.musicBind();
214
+
206
215
  const $music = document.querySelector("#nav-music");
207
216
  const $meting = document.querySelector("meting-js");
208
217
  const $console = document.getElementById("consoleMusic");
209
- const $rmText = document.querySelector("#menu-music-toggle span");
210
- const $rmIcon = document.querySelector("#menu-music-toggle i");
211
-
218
+
212
219
  this.musicPlaying = !this.musicPlaying;
220
+
213
221
  $music.classList.toggle("playing", this.musicPlaying);
214
222
  $music.classList.toggle("stretch", this.musicPlaying);
215
223
  $console?.classList.toggle("on", this.musicPlaying);
216
-
224
+
217
225
  if (typeof rm !== "undefined" && rm?.menuItems.music[0]) {
218
- $rmText.textContent = this.musicPlaying
226
+ const $rmText = document.querySelector("#menu-music-toggle span");
227
+ const $rmIcon = document.querySelector("#menu-music-toggle i");
228
+ $rmText.textContent = this.musicPlaying
219
229
  ? GLOBAL_CONFIG.right_menu.music.stop
220
230
  : GLOBAL_CONFIG.right_menu.music.start;
221
- $rmIcon.className = this.musicPlaying
222
- ? "solitude fas fa-pause"
223
- : "solitude fas fa-play";
231
+ $rmIcon.className = `solitude fas ${this.musicPlaying ? 'fa-pause' : 'fa-play'}`;
224
232
  }
225
233
 
226
- if (isMeting) {
234
+ if (isMeting && $meting) {
227
235
  this.musicPlaying ? $meting.aplayer.play() : $meting.aplayer.pause();
228
236
  }
229
237
  },
230
- musicBind() {
231
- const $music = document.querySelector("#nav-music");
232
- const $name = document.querySelector("#nav-music .aplayer-music");
233
- const $button = document.querySelector("#nav-music .aplayer-button");
234
-
235
- $name?.addEventListener("click", () => {
236
- $music.classList.toggle("stretch");
237
- });
238
-
239
- $button?.addEventListener("click", () => {
240
- this.musicToggle(false);
241
- });
242
-
243
- this.isMusicBind = true;
238
+ musicSkipBack() {
239
+ document.querySelector("meting-js")?.aplayer?.skipBack();
240
+ },
241
+ musicSkipForward() {
242
+ document.querySelector("meting-js")?.aplayer?.skipForward();
244
243
  },
245
244
  switchCommentBarrage() {
246
245
  const commentBarrageElement = document.querySelector(".comment-barrage");
@@ -870,10 +869,6 @@ const scrollFnToDo = () => {
870
869
  if (toc) {
871
870
  const $cardTocLayout = document.getElementById("card-toc");
872
871
  const $cardToc = $cardTocLayout.querySelector(".toc-content");
873
- const $tocLink = $cardToc.querySelectorAll(".toc-link");
874
- const $tocPercentage = $cardTocLayout.querySelector(".toc-percentage");
875
- const isExpand = $cardToc.classList.contains("is-expand");
876
-
877
872
  const tocItemClickFn = (e) => {
878
873
  const target = e.target.closest(".toc-link");
879
874
  if (!target) return;
@@ -915,6 +910,7 @@ window.refreshFn = () => {
915
910
  sco.tagPageActive,
916
911
  sco.categoriesBarActive,
917
912
  sco.listenToPageInputPress,
913
+ sco.musicBind,
918
914
  sco.addNavBackgroundInit,
919
915
  sco.refreshWaterFall,
920
916
  ].forEach((fn) => fn());
@@ -1,188 +1,218 @@
1
1
  (() => {
2
- const utilsFn = {
3
- throttle: (func, wait, {leading = true, trailing = true} = {}) => {
4
- let timeout, previous = 0;
5
- const later = (context, args) => {
6
- timeout = previous = leading === false ? 0 : Date.now();
7
- func.apply(context, args);
8
- };
9
- return function () {
10
- const now = Date.now();
11
- if (!previous && leading === false) previous = now;
12
- const remaining = wait - (now - previous);
13
- if (remaining <= 0 || remaining > wait) {
14
- if (timeout) clearTimeout(timeout);
15
- later(this, arguments);
16
- } else if (!timeout && trailing !== false) {
17
- timeout = setTimeout(() => later(this, arguments), remaining);
18
- }
19
- };
20
- },
21
- fadeIn: (ele, time) => {
22
- ele.style.display = 'block';
23
- ele.style.animation = `to_show ${time}s`;
24
- },
25
- fadeOut: (ele, time) => {
26
- const resetStyles = () => {
27
- ele.style.display = 'none';
28
- ele.style.animation = '';
29
- ele.removeEventListener('animationend', resetStyles);
30
- };
31
- ele.addEventListener('animationend', resetStyles);
32
- ele.style.animation = `to_hide ${time}s`;
33
- },
34
- snackbarShow: (text, showAction = false, duration = 5000) => {
35
- Snackbar.show({ text, showAction, duration, pos: 'top-center' });
36
- },
37
- copy: async (text) => {
38
- const message = await navigator.clipboard.writeText(text)
39
- .then(() => GLOBAL_CONFIG.lang.copy.success)
40
- .catch(() => GLOBAL_CONFIG.lang.copy.error);
41
- utils.snackbarShow(message, false, 2000);
42
- },
43
- getEleTop: ele => {
44
- let actualTop = ele.offsetTop;
45
- while (ele.offsetParent) {
46
- ele = ele.offsetParent;
47
- actualTop += ele.offsetTop;
48
- }
49
- return actualTop;
50
- },
51
- siblings: (ele, selector) => {
52
- return [...ele.parentNode.children].filter(child =>
53
- child !== ele && (!selector || child.matches(selector))
54
- );
55
- },
56
- randomNum: length => Math.floor(Math.random() * length),
57
- timeDiff: (timeObj, today) => Math.floor((today.getTime() - timeObj.getTime()) / (1000 * 3600 * 24)),
58
- scrollToDest: (pos, time = 500) => {
59
- const currentPos = window.pageYOffset;
60
- const isNavFixed = document.getElementById('page-header').classList.contains('nav-fixed');
61
- pos = currentPos > pos || isNavFixed ? pos - 70 : pos;
2
+ const utilsFn = {
3
+ throttle: (func, wait, { leading = true, trailing = true } = {}) => {
4
+ let timeout,
5
+ previous = 0;
6
+ const later = (context, args) => {
7
+ timeout = previous = leading === false ? 0 : Date.now();
8
+ func.apply(context, args);
9
+ };
10
+ return function () {
11
+ const now = Date.now();
12
+ if (!previous && leading === false) previous = now;
13
+ const remaining = wait - (now - previous);
14
+ if (remaining <= 0 || remaining > wait) {
15
+ if (timeout) clearTimeout(timeout);
16
+ later(this, arguments);
17
+ } else if (!timeout && trailing !== false) {
18
+ timeout = setTimeout(() => later(this, arguments), remaining);
19
+ }
20
+ };
21
+ },
22
+ fadeIn: (ele, time) => {
23
+ ele.style.display = "block";
24
+ ele.style.animation = `to_show ${time}s`;
25
+ },
26
+ fadeOut: (ele, time) => {
27
+ const resetStyles = () => {
28
+ ele.style.display = "none";
29
+ ele.style.animation = "";
30
+ ele.removeEventListener("animationend", resetStyles);
31
+ };
32
+ ele.addEventListener("animationend", resetStyles);
33
+ ele.style.animation = `to_hide ${time}s`;
34
+ },
35
+ snackbarShow: (text, showAction = false, duration = 5000) => {
36
+ Snackbar.show({ text, showAction, duration, pos: "top-center" });
37
+ },
38
+ copy: async (text) => {
39
+ const message = await navigator.clipboard
40
+ .writeText(text)
41
+ .then(() => GLOBAL_CONFIG.lang.copy.success)
42
+ .catch(() => GLOBAL_CONFIG.lang.copy.error);
43
+ utils.snackbarShow(message, false, 2000);
44
+ },
45
+ getEleTop: (ele) => {
46
+ let actualTop = ele.offsetTop;
47
+ while (ele.offsetParent) {
48
+ ele = ele.offsetParent;
49
+ actualTop += ele.offsetTop;
50
+ }
51
+ return actualTop;
52
+ },
53
+ siblings: (ele, selector) => {
54
+ return [...ele.parentNode.children].filter(
55
+ (child) => child !== ele && (!selector || child.matches(selector))
56
+ );
57
+ },
58
+ randomNum: (length) => Math.floor(Math.random() * length),
59
+ timeDiff: (timeObj, today) =>
60
+ Math.floor((today.getTime() - timeObj.getTime()) / (1000 * 3600 * 24)),
61
+ scrollToDest: (pos, time = 500) => {
62
+ const currentPos = window.pageYOffset;
63
+ const isNavFixed = document
64
+ .getElementById("page-header")
65
+ .classList.contains("nav-fixed");
66
+ pos = currentPos > pos || isNavFixed ? pos - 70 : pos;
62
67
 
63
- if ('scrollBehavior' in document.documentElement.style) {
64
- window.scrollTo({ top: pos, behavior: 'smooth' });
65
- return;
66
- }
68
+ if ("scrollBehavior" in document.documentElement.style) {
69
+ window.scrollTo({ top: pos, behavior: "smooth" });
70
+ return;
71
+ }
67
72
 
68
- const distance = pos - currentPos;
69
- const step = currentTime => {
70
- const progress = currentTime - (start || currentTime);
71
- if (progress < time) {
72
- window.scrollTo(0, currentPos + (distance * progress) / time);
73
- window.requestAnimationFrame(step);
74
- } else {
75
- window.scrollTo(0, pos);
76
- }
77
- };
73
+ const distance = pos - currentPos;
74
+ const step = (currentTime) => {
75
+ const progress = currentTime - (start || currentTime);
76
+ if (progress < time) {
77
+ window.scrollTo(0, currentPos + (distance * progress) / time);
78
+ window.requestAnimationFrame(step);
79
+ } else {
80
+ window.scrollTo(0, pos);
81
+ }
82
+ };
78
83
 
79
- window.requestAnimationFrame(step);
80
- },
81
- isMobile: () => /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
82
- isHidden: e => e.offsetHeight === 0 && e.offsetWidth === 0,
83
- animateIn: (ele, text) => {
84
- Object.assign(ele.style, { display: 'block', animation: text });
85
- },
86
- animateOut: (ele, text) => {
87
- const resetAnimation = () => {
88
- ele.style.display = '';
89
- ele.style.animation = '';
90
- ele.removeEventListener('animationend', resetAnimation);
91
- };
92
- ele.addEventListener('animationend', resetAnimation);
93
- ele.style.animation = text;
94
- },
95
- wrap: (selector, eleType, options) => {
96
- const createEle = document.createElement(eleType);
97
- Object.entries(options).forEach(([key, value]) => createEle.setAttribute(key, value));
98
- selector.parentNode.insertBefore(createEle, selector);
99
- createEle.appendChild(selector);
100
- },
101
- lazyloadImg: () => {
102
- window.lazyLoadInstance = new LazyLoad({
103
- elements_selector: 'img',
104
- threshold: 0,
105
- data_src: 'lazy-src',
106
- callback_error: img => img.src = GLOBAL_CONFIG.lazyload.error
107
- });
108
- },
109
- lightbox: function (selector) {
110
- const lightboxType = GLOBAL_CONFIG.lightbox;
111
- const options = {
112
- class: 'fancybox',
113
- 'data-fancybox': 'gallery',
114
- };
84
+ window.requestAnimationFrame(step);
85
+ },
86
+ isMobile: () =>
87
+ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
88
+ navigator.userAgent
89
+ ),
90
+ isHidden: (e) => e.offsetHeight === 0 && e.offsetWidth === 0,
91
+ animateIn: (ele, text) => {
92
+ Object.assign(ele.style, { display: "block", animation: text });
93
+ },
94
+ animateOut: (ele, text) => {
95
+ const resetAnimation = () => {
96
+ ele.style.display = "";
97
+ ele.style.animation = "";
98
+ ele.removeEventListener("animationend", resetAnimation);
99
+ };
100
+ ele.addEventListener("animationend", resetAnimation);
101
+ ele.style.animation = text;
102
+ },
103
+ wrap: (selector, eleType, options) => {
104
+ const createEle = document.createElement(eleType);
105
+ Object.entries(options).forEach(([key, value]) =>
106
+ createEle.setAttribute(key, value)
107
+ );
108
+ selector.parentNode.insertBefore(createEle, selector);
109
+ createEle.appendChild(selector);
110
+ },
111
+ lazyloadImg: () => {
112
+ window.lazyLoadInstance = new LazyLoad({
113
+ elements_selector: "img",
114
+ threshold: 0,
115
+ data_src: "lazy-src",
116
+ callback_error: (img) => (img.src = GLOBAL_CONFIG.lazyload.error),
117
+ });
118
+ },
119
+ lightbox: function (selector) {
120
+ const lightboxType = GLOBAL_CONFIG.lightbox;
121
+ const options = {
122
+ class: "fancybox",
123
+ "data-fancybox": "gallery",
124
+ };
115
125
 
116
- if (lightboxType === 'mediumZoom') {
117
- mediumZoom && mediumZoom(selector, { background: "var(--efu-card-bg)" });
118
- } else if (lightboxType === 'fancybox') {
119
- selector.forEach(i => {
120
- if (i.parentNode.tagName !== 'A') {
121
- options.href = options['data-thumb'] = i.dataset.lazySrc || i.src;
122
- options['data-caption'] = i.title || i.alt || '';
123
- utils.wrap(i, 'a', options);
124
- }
125
- });
126
+ if (lightboxType === "mediumZoom") {
127
+ mediumZoom &&
128
+ mediumZoom(selector, { background: "var(--efu-card-bg)" });
129
+ } else if (lightboxType === "fancybox") {
130
+ selector.forEach((i) => {
131
+ if (i.parentNode.tagName !== "A") {
132
+ options.href = options["data-thumb"] = i.dataset.lazySrc || i.src;
133
+ options["data-caption"] = i.title || i.alt || "";
134
+ utils.wrap(i, "a", options);
135
+ }
136
+ });
126
137
 
127
- if (!window.fancyboxRun) {
128
- Fancybox.bind('[data-fancybox]', {
129
- Hash: false,
130
- animated: true,
131
- Thumbs: { showOnStart: false },
132
- Images: { Panzoom: { maxScale: 4 } },
133
- Carousel: { transition: 'slide' },
134
- Toolbar: {
135
- display: {
136
- left: ['infobar'],
137
- middle: ['zoomIn', 'zoomOut', 'toggle1to1', 'rotateCCW', 'rotateCW', 'flipX', 'flipY'],
138
- right: ['slideshow', 'thumbs', 'close']
139
- }
140
- },
141
- });
142
- window.fancyboxRun = true;
143
- }
144
- }
145
- },
146
- diffDate: (d, more = false) => {
147
- const dateNow = new Date();
148
- const datePost = new Date(d);
149
- const dateDiff = dateNow - datePost;
150
- const minute = 60000;
151
- const hour = 3600000;
152
- const day = 86400000;
153
- const month = 2592000000;
154
- const { time } = GLOBAL_CONFIG.lang;
138
+ if (!window.fancyboxRun) {
139
+ Fancybox.bind("[data-fancybox]", {
140
+ Hash: false,
141
+ animated: true,
142
+ Thumbs: { showOnStart: false },
143
+ Images: { Panzoom: { maxScale: 4 } },
144
+ Carousel: { transition: "slide" },
145
+ Toolbar: {
146
+ display: {
147
+ left: ["infobar"],
148
+ middle: [
149
+ "zoomIn",
150
+ "zoomOut",
151
+ "toggle1to1",
152
+ "rotateCCW",
153
+ "rotateCW",
154
+ "flipX",
155
+ "flipY",
156
+ ],
157
+ right: ["slideshow", "thumbs", "close"],
158
+ },
159
+ },
160
+ });
161
+ window.fancyboxRun = true;
162
+ }
163
+ }
164
+ },
165
+ diffDate: (d, more = false) => {
166
+ const dateNow = new Date();
167
+ const datePost = new Date(d);
168
+ const dateDiff = dateNow - datePost;
169
+ const minute = 60000;
170
+ const hour = 3600000;
171
+ const day = 86400000;
172
+ const month = 2592000000;
173
+ const { time } = GLOBAL_CONFIG.lang;
155
174
 
156
- const dayCount = Math.floor(dateDiff / day);
157
- if (!more) return dayCount;
175
+ const dayCount = Math.floor(dateDiff / day);
176
+ if (!more) return dayCount;
158
177
 
159
- const minuteCount = Math.floor(dateDiff / minute);
160
- const hourCount = Math.floor(dateDiff / hour);
161
- const monthCount = Math.floor(dateDiff / month);
178
+ const minuteCount = Math.floor(dateDiff / minute);
179
+ const hourCount = Math.floor(dateDiff / hour);
180
+ const monthCount = Math.floor(dateDiff / month);
162
181
 
163
- if (monthCount > 12) return datePost.toISOString().slice(0, 10);
164
- if (monthCount >= 1) return `${monthCount} ${time.month}`;
165
- if (dayCount >= 1) return `${dayCount} ${time.day}`;
166
- if (hourCount >= 1) return `${hourCount} ${time.hour}`;
167
- if (minuteCount >= 1) return `${minuteCount} ${time.min}`;
168
- return time.just;
169
- },
170
- loadComment: (dom, callback) => {
171
- const observerItem = 'IntersectionObserver' in window ? new IntersectionObserver((entries) => {
182
+ if (monthCount > 12) return datePost.toISOString().slice(0, 10);
183
+ if (monthCount >= 1) return `${monthCount} ${time.month}`;
184
+ if (dayCount >= 1) return `${dayCount} ${time.day}`;
185
+ if (hourCount >= 1) return `${hourCount} ${time.hour}`;
186
+ if (minuteCount >= 1) return `${minuteCount} ${time.min}`;
187
+ return time.just;
188
+ },
189
+ loadComment: (dom, callback) => {
190
+ const observerItem =
191
+ "IntersectionObserver" in window
192
+ ? new IntersectionObserver(
193
+ (entries) => {
172
194
  if (entries[0].isIntersecting) {
173
- callback();
174
- observerItem.disconnect();
195
+ callback();
196
+ observerItem.disconnect();
175
197
  }
176
- }, { threshold: [0] }) : null;
198
+ },
199
+ { threshold: [0] }
200
+ )
201
+ : null;
177
202
 
178
- observerItem ? observerItem.observe(dom) : callback();
179
- },
180
- escapeHtml: unsafe => unsafe.replace(/[&<"']/g, m => ({
181
- '&': '&amp;',
182
- '<': '&lt;',
183
- '"': '&quot;',
184
- "'": '&#039;'
185
- }[m])),
186
- };
187
- window.utils = { ...window.utils, ...utilsFn };
188
- })()
203
+ observerItem ? observerItem.observe(dom) : callback();
204
+ },
205
+ escapeHtml: (unsafe) =>
206
+ unsafe.replace(
207
+ /[&<"']/g,
208
+ (m) =>
209
+ ({
210
+ "&": "&amp;",
211
+ "<": "&lt;",
212
+ '"': "&quot;",
213
+ "'": "&#039;",
214
+ }[m])
215
+ ),
216
+ };
217
+ window.utils = { ...window.utils, ...utilsFn };
218
+ })();