mohのAI正在绞尽脑汁想思路ING···
mohのAI摘要
mohのAI-Lite

本文参考文档来自

一、前置知识

创建一个自定义文件[blogRoot]/source/css/june.css 将下文内容复制到文件中(注意: 记得引入到配置文件中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* 颜色 */
:root {
--june: #E68282;
--june-theme-op: #4259ef23;
--june-gray-op: #9999992b;
--june-white: #fff;
--june-black: #000;
--june-none: rgba(0, 0, 0, 0);
--june-purple: #E764FF;
--june-gray: #999999;
--june-light-grey: #F2F2F2;
--june-yellow: #ffc93e;
--june-orange: #ff9900;
--june-border-radius: 8px;
--june-main: var(--june-theme);
--june-main-op: var(--june-theme-op);
--june-shadow-theme: 0 8px 12px -3px var(--june-theme-op);
--june-shadow-main: 0 8px 12px -3px var(--june-main-op);
--june-shadow-blue: 0 8px 12px -3px rgba(40, 109, 234, 0.2);
--june-shadow-white: 0 8px 12px -3px rgba(255, 255, 255, 0.2);
--june-shadow-black: 0 0 12px 4px rgba(0, 0, 0, 0.05);
--june-shadow-yellow: 0px 38px 77px -26px rgba(255, 201, 62, 0.12);
--june-shadow-red: 0 8px 12px -3px #ee7d7936;
--june-shadow-green: 0 8px 12px -3px #87ee7936;
--june-shadow-border: 0 8px 16px -4px #2c2d300c;
--june-logo-color: linear-gradient(215deg, #4584ff 30%, #ff7676 70%);
--style-border: 1px solid var(--june-card-border);
--june-blue-main: #3b70fc;
--style-border-hover: 1px solid var(--june-main);
--style-border-dashed: 1px dashed var(--june-theme-op);
--style-border-avatar: 4px solid var(--june-background);
--style-border-always: 1px solid var(--june-card-border);
--june-white-acrylic1: #fefeff !important;
--june-white-acrylic2: #fcfdff !important;
--june-black-acrylic2: #08080a !important;
--june-black-acrylic1: #0b0b0e !important;
--middle-y-multiplier: 1.5; /* 假设元素在 Y 轴上的平移为原始位置的 1.5 倍 */
--middle-scale-multiplier: 1.2; /* 假设元素的纵向缩放为原始大小的 1.2 倍 */
--heo-theme: var(--june-border) !important;

/* 布局尺寸 */
--layout-width: 1400px;
--aside-width: 312px;

/* 圆角 */
--border-radius-small: 6px;
--border-radius-medium: 8px; /* = --june-border-radius */
--border-radius-large: 12px;
--border-radius-xlarge: 24px;

/* 动画 */
--transition-time: 0.3s;

/* 字体大小 */
--global-font-size: 16px;
}

[data-theme="light"] {
--june-theme: #E68282;
--june-theme-op: #4259ef23;
--june-blue: #3b70fc;
--june-red: #d8213c;
--june-pink: #ff7c7c;
--june-green: #57bd6a;
--june-fontcolor: #4c4948;
--june-background: #f7f9fe;
--june-reverse: #000;
--june-maskbg: rgba(255, 255, 255, 0.6);
--june-maskbgdeep: rgba(255, 255, 255, 0.85);
--june-hovertext: var(--june);
--june-ahoverbg: #f7f7fa;
--june-lighttext: var(--june-main);
--june-secondtext: rgba(60, 60, 67, 0.6);
--june-scrollbar: rgba(60, 60, 67, 0.4);
--june-card-btn-bg: #edf0f7;
--june-post-blockquote-bg: #fafcff;
--june-post-tabs-bg: #f2f5f8;
--june-secondbg: #f7f7f9;
--june-shadow-nav: 0 5px 12px -5px rgba(102, 68, 68, 0.05);
--june-card-bg: #fff;
--june-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
--june-shadow-light2black: 0 5px 12px -5px rgba(102, 68, 68, 0);
--june-card-border: #c0c6d8;
--june-copyright-bg: #eff1f3;
--june-border: #E68282
}

[data-theme="dark"] {
--june-theme: #333333;
--june-theme-op: #0084ff23;
--june-blue: #0084ff;
--june-red: #ff3842;
--june-pink: #ff7c7c;
--june-green: #57bd6a;
--june-fontcolor: #f7f7fa;
--june-background: #18171d;
--june-reverse: #fff;
--june-maskbg: rgba(0, 0, 0, 0.6);
--june-maskbgdeep: rgba(0, 0, 0, 0.85);
--june-hovertext: #0a84ff;
--june-ahoverbg: #fff;
--june-lighttext: #f2b94b;
--june-secondtext: #a1a2b8;
--june-scrollbar: rgba(200, 200, 223, 0.4);
--june-card-btn-bg: #30343f;
--june-post-blockquote-bg: #000;
--june-post-tabs-bg: #121212;
--june-secondbg: #30343f;
--june-shadow-nav: 0 5px 20px 0px rgba(28, 28, 28, 0.4);
--june-card-bg: #1b1c20;
--june-shadow-lightblack: 0 5px 12px -5px rgba(102, 68, 68, 0);
--june-shadow-light2black: 0 5px 12px -5px rgba(102, 68, 68, 0);
--june-card-border: #42444a;
--june-copyright-bg: #323335;
--june-border: #c8c8c8
}

二、复制

效果

未改造前的效果:
image-20260406192205694

改造后的效果:

image-20260406192301154

教程

1、将以下代码复制到june.css中即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.snackbar-container{
border-radius: 12px!important;
background-color: #000000aa!important;
}
.OwO-body{
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
background: #ffffff77!important;
}

.snackbar-container .action{
color:var(--june-theme)!important;
background-color: transparent!important;
}
.snackbar-container{
font-family: HYTMR,'PingFang SC','Ubuntu Mono','Noto Sans','Microsoft Yahei','SimSun'!important;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
@media screen and (max-width:640px) {
.snackbar-container {
border-radius: 0px !important;
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
-ms-border-radius: 0px !important;
-o-border-radius: 0px !important;
}
}

2、修改_config.butterfly.yml

1
2
3
4
5
6
7
8
9
# Snackbar (Toast Notification 彈窗)
# https://github.com/polonel/SnackBar
# position 彈窗位置
# 可選 top-left / top-center / top-right / bottom-left / bottom-center / bottom-right
snackbar:
enable: true
position: bottom-left
bg_light: '#49b1f5' # The background color of Toast Notification in light mode
bg_dark: '#1f1f1f' # The background color of Toast Notification in dark mode

扩展教程(一定要是https或者local、http不行)

只有点击代码复制按钮才有提示,复制文字该怎么添加?

修改[blogRoot]\themes\butterfly\layout\includes\head\config.pugcopyright部分,大概在第41行左右,直接复制下面代码替换即可

(查找方式 直接ctrl+f。输入copyright 后面将代码进行替换就好)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let copyright = 'undefined';
if (theme.copy.enable) {
copyright = JSON.stringify({
copy: theme.copy.enable,
copyrightEbable: theme.copy.copyright.enable,
limitCount: theme.copy.copyright.limit_count,
languages: {
author: _p("copy_copyright.author") + ': ' + config.author,
link: _p("copy_copyright.link") + ': ',
source: _p("copy_copyright.source") + ': ' + config.title,
info: _p("copy_copyright.info")
}
})
}

修改[blogRoot]\themes\butterfly\source\js\main.js中的addCopyright函数,直接复制下面代码替换即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 複製時加上版權信息
*/
const addCopyright = () => {
const { limitCount, languages, copy, copyrightEbable } = GLOBAL_CONFIG.copyright;

const handleCopy = e => {
if (copy) {
btf.snackbarShow(GLOBAL_CONFIG.copy.success,true);
}
if (copyrightEbable) {
e.preventDefault();
const copyFont = window.getSelection(0).toString();
let textFont = copyFont;
if (copyFont.length > limitCount) {
textFont = `${copyFont}\n\n\n${languages.author}\n${languages.link}${window.location.href}\n${languages.source}\n${languages.info}`;
}
if (e.clipboardData) {
return e.clipboardData.setData("text", textFont);
} else {
return window.clipboardData.setData("text", textFont);
}
}
};

document.body.addEventListener("copy", handleCopy);
}

修改[blogRoot]themes/butterfly/languages/zh-CN.yml中的以下代码, 其中 copy.success 就是弹窗中的内容

1
2
3
4
5
6
7
8
9
footer:
framework: 框架
theme: 主题

copy:
success: 复制成功,转载请标注本文地址
error: 复制失败
noSupport: 浏览器不支持

效果展示

image-20260406195805350

下面是佬的用法,带链接跳转

效果展示:

image-20260406200026411

找到[blogRoot]\themes\butterfly\source\js\utils.js中的snackbarShow函数,直接替换成以下的函数即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
snackbarShow: (text, showAction = false, duration = 2000) => {
const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar
const bg = document.documentElement.getAttribute('data-theme') === 'light' ? bgLight : bgDark
Snackbar.show({
text,
backgroundColor: bg,
showAction,
duration,
pos: position,
onActionClick: function (element) {
window.open("/copyright")
},
actionText: "版权声明",
customClass: 'snackbar-css'
})

},

三、欢迎与Cookie弹窗

效果:

image-20260406203140568

新建welcome.js 记得引入配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//首次访问弹窗
if (localStorage.getItem("popWelcomeWindow") !== "0") {
if (document.referrer === undefined || document.referrer.indexOf("blog.june_pj.cn") !== -1 || document.referrer.indexOf("www.blog.june_pj.cn") !== -1) { //改成自己域名,注意是referrer!!! qwq

} else {
localStorage.setItem("popWelcomeWindow", "0");
}
Snackbar.show({
text: '哎嘿,被发现了呢~ (~o ̄3 ̄)~ ',
pos: 'top-right',
onActionClick: function (element) {
window.open("/about")
},
actionText: "关于我",
});
}
if (sessionStorage.getItem("popCookieWindow") !== "0") {
setTimeout(function () {
Snackbar.show({
text: '本站使用Cookie和本地/会话存储保证浏览体验和网站统计',
pos: 'bottom-left',
actionText: "版权声明",
onActionClick: function (element) {
window.open("/privacy")
},
})
}, 3000)
}
//不在弹出Cookie提醒
sessionStorage.setItem("popCookieWindow", "0");

//自带上文浏览器提示

function browserTC() {
btf.snackbarShow("");
Snackbar.show({
text: '浏览器版本较低,网站样式可能错乱',
actionText: '关闭',
duration: '6000',
pos: 'bottom-left'
});
}

function browserVersion() {
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //Edge浏览器
var isFirefox = userAgent.indexOf("Firefox") > -1; //Firefox浏览器
var isOpera = userAgent.indexOf("Opera") > -1 || userAgent.indexOf("OPR") > -1; //Opera浏览器
var isChrome = userAgent.indexOf("Chrome") > -1 && userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Edge") === -1 && userAgent.indexOf("OPR") === -1; //Chrome浏览器
var isSafari = userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1 && userAgent.indexOf("Edge") === -1 && userAgent.indexOf("OPR") === -1; //Safari浏览器
if (isEdge) {
if (userAgent.split('Edge/')[1].split('.')[0] < 90) {
browserTC()
}
} else if (isFirefox) {
if (userAgent.split('Firefox/')[1].split('.')[0] < 90) {
browserTC()
}
} else if (isOpera) {
if (userAgent.split('OPR/')[1].split('.')[0] < 80) {
browserTC()
}
} else if (isChrome) {
if (userAgent.split('Chrome/')[1].split('.')[0] < 90) {
browserTC()
}
} else if (isSafari) {
//不知道Safari哪个版本是该淘汰的老旧版本
}
}

//2022-10-29修正了一个错误:过期时间应使用toGMTString(),而不是toUTCString(),否则实际过期时间在中国差了8小时
function setCookies(obj, limitTime) {
let data = new Date(new Date().getTime() + limitTime * 24 * 60 * 60 * 1000).toGMTString()
for (let i in obj) {
document.cookie = i + '=' + obj[i] + ';expires=' + data
}
}

function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}

if (getCookie('browsertc') !== 1) {
setCookies({
browsertc: 1,
}, 1);
browserVersion();
}

四、分类、标签页

效果:

image-20260406205751899

june.css中添加以下代码

追加分类页样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* 分类页 */
.category-lists .category-list {
text-align: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
flex-direction: row;
margin: 5em 0 3em;
}
.category-lists ul {
padding: 0;
}
.category-lists ul li {
display: flex;
width: fit-content;
font-size: 1.2em !important;
padding: 0.2em 0.5em;
background: var(--june-card-bg);
margin: 0.5em 0.5em;
border-radius: 12px;
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
border: var(--style-border-always);
box-shadow: var(--june-shadow-border);
align-items: center;
}
.category-lists .category-list a {
color: var(--june-fontcolor) !important;
}
.category-lists .category-list a:hover {
color: var(--june-blue) !important;
}
.category-lists ul li:before {
position: unset;
width: auto;
height: auto;
border: 0;
border-radius: 0;
background: 0;
color: var(--june-fontcolor) !important;
cursor: pointer;
content: "\e038" !important;
font-family: "iconfont" !important;
opacity: 0.4;
padding-top: 2px;
padding-right: 2px;
}
.category-lists .category-list .category-list-count {
background: var(--june-secondbg);
padding: 4px 4px;
border-radius: 6px;
color: var(--june-secondtext);
line-height: 1;
text-align: center;
min-width: 35px;
display: inline-block;
font-size: 1rem;
box-shadow: var(--june-shadow-border);
}
.category-lists .category-list .category-list-count:before,
.category-lists .category-list .category-list-count:after {
content: '';
}

追加标签页样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* 标签页 */
#page .tag-cloud-list {
margin: 5em 0 3em;
}
#page .tag-cloud-list a {
display: inline-flex;
color: var(--june-fontcolor) !important;
font-size: 1.2em !important;
padding: 0.2em 0.5em;
background: var(--june-card-bg);
margin: 0.5em 0.5em;
border-radius: 12px;
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
border: var(--style-border-always);
box-shadow: var(--june-shadow-border);
align-items: center;
}
#page .tag-cloud-list a:before {
color: var(--june-fontcolor) !important;
cursor: pointer;
content: "\e038" !important;
font-family: "iconfont" !important;
opacity: 0.4;
padding-top: 2px;
padding-right: 2px;
}
#page .tag-cloud-list a:hover {
background: var(--june-blue);
}
#page .tag-cloud-list a > sup{
top: auto;
background: var(--june-secondbg);
padding: 4px 4px;
margin-left: 8px;
border-radius: 6px;
color: var(--june-secondtext);
line-height: 1;
text-align: center;
min-width: 35px;
display: inline-block;
font-size: 1rem;
box-shadow: var(--june-shadow-border);
}

五、在PC端文章右下角处即可查看评论弹窗

首先在在[主题目录]/layout/includes/layout.pug文件中,新增以下内容。 去掉加号即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      main#content-inner.layout(class=hideAside)
if body
div!= body
else
block content
if theme.aside.enable && page.aside !== false
include widget/index.pug

+ if page.comments !== undefined && page.comments !== false && theme.comments.use
+ #comment-barrage

- const footerBg = theme.footer_img
- const footer_bg = footerBg ? footerBg === true ? bg_img : getBgPath(footerBg) : ''
footer#footer(style=footer_bg)
!=partial('includes/footer', {}, {cache: true})

新建[主题目录]/source/css/_layout/barrage.styl样式文件,并新增以下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#comment-barrage
position fixed
bottom 40px
right calc(10px + 48px)
display flex
flex-direction column
justify-content flex-end
align-items flex-end
transform translateY(190px)
transition .3s
z-index 1

+maxWidth768()
display none

&.show
transform translateY(0)

.comment-barrage-item
min-width 320px
max-width 400px
width fit-content
min-height 60px
max-height 120px
margin 4px
padding 12px 16px
background #ffffff
border-radius 12px
color #333333
animation barrageIn .6s cubic-bezier(0.42, 0, 0.3, 1.11)
transition .3s
display flex
flex-direction column
outline 1px solid #e0e0e0
position fixed
box-shadow 0 2px 8px rgba(0, 0, 0, 0.08)
overflow hidden

&:hover
outline 1px solid #409eff
box-shadow 0 4px 12px rgba(64, 158, 255, 0.15)

&.out
opacity 0
animation barrageOut 0.6s cubic-bezier(0.42, 0, 0.3, 1.11)

pre, li, blockquote, br
display none

.barrageHead
height auto
padding 0
line-height 1
font-size 12px
border-bottom 1px solid #f0f0f0
display flex
justify-content space-between
align-items center
font-weight normal
padding-bottom 8px
gap 8px

.barrageNick
display flex
align-items center
gap 6px
flex 1
min-width 0
color #333333

&::before
content '热评'
background #ff6b6b
color #fff
padding 2px 6px
border-radius 4px
font-size 11px
font-weight bold
white-space nowrap

.barrageAvatar
width 20px
height 20px
margin 0
border-radius 50%
background var(--icat-theme)
order 1

.barrageTime
margin-left 0
color #999999
font-size 12px
order 2
flex 1
min-width 0
overflow hidden
text-overflow ellipsis
white-space nowrap

.barrageClose
color #999999
cursor pointer
line-height 1
margin-left auto
order 3
font-size 16px
width 24px
height 24px
display flex
align-items center
justify-content center
border-radius 50%
transition .3s

&:hover
color #ff4444
background #f5f5f5

.barrageContent
font-size 14px
font-weight normal
height auto
overflow hidden
width 100%
max-height none
margin-top 4px

a
pointer-events none
font-size 13px
color #333333
line-height 1.6
display -webkit-box
-webkit-line-clamp 3
-webkit-box-orient vertical
overflow hidden
text-overflow ellipsis

&:-webkit-scrollbar
height 0
width 4px

&-button
display none

p
color #333333
margin 0
max-width 100%
line-height 1.6
-webkit-line-clamp 3
display -webkit-box
-webkit-box-orient vertical
font-size 13px
font-weight normal
overflow hidden
text-overflow ellipsis
transition .3s

&:hover
color #409eff

img
&:not(.tk-owo-emotion)
display none

&.tk-owo-emotion
width 16px
padding 0
margin 0
transform translateY(2px)

[data-theme="dark"]
.comment-barrage-item
background #1f1f1f
color #ffffff
outline 1px solid #4a4a4a
box-shadow 0 2px 8px rgba(0, 0, 0, 0.3)

&:hover
outline 1px solid #409eff
box-shadow 0 4px 12px rgba(64, 158, 255, 0.2)

.barrageHead
border-bottom 1px solid #3a3a3a

.barrageNick
color #ffffff

&::before
background #ff6b6b
color #fff

.barrageTime
color #999999

.barrageClose
color #999999

&:hover
color #ff4444
background #3a3a3a

.barrageContent a
color #ffffff

p
color #ffffff

&:hover
color #409eff

@keyframes barrageIn
0%
transform translateY(20px)
opacity 0

100%
transform translateY(0)
opacity 1

@keyframes barrageOut
0%
transform translateY(0)
opacity 1

100%
transform translateY(20px)
opacity 0

创建[博客根目录]/source/js/meuicat.js文件. 记得引入 且修改对应啊pai和token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const changeTime = (time, more = false) => {
const currentDate = new Date()

const formatTimestamp = (date) => {
const d = new Date(date)
const pad = (num) => String(num).padStart(2, '0')
return `${pad(d.getFullYear())}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} `
}

const calculateDiff = (date1, date2, unit) => {
const units = { day: 24 * 60 * 60 * 1000, hour: 60 * 60 * 1000 }
return Math.floor(Math.abs(date1 - date2) / units[unit])
}

const describeTime = (datetime) => {
const timeObj = new Date(datetime)
const diffDays = calculateDiff(timeObj, currentDate, 'day')
const diffHours = calculateDiff(timeObj, currentDate, 'hour')

if (diffHours < 1) return `最近`
if (diffHours <= 24) return `${diffHours}小时前`
if (diffDays === 1) return `昨天`
if (diffDays === 2) return `前天`
if (diffDays <= 7) return `${diffDays}天前`

const year = timeObj.getFullYear()
const month = timeObj.getMonth() + 1
const date = timeObj.getDate()
return year !== currentDate.getFullYear() ? `${year}/${month}/${date}` : `${month}/${date}`
}

if (more) return formatTimestamp(time)
if (time) return describeTime(time)

document.querySelectorAll('time.datatime').forEach((e) => { e.textContent = describeTime(e.getAttribute('datetime')) })
}


let commentData
let commentInterval = null

const comment = {
fetchData: async (option) => {
const res = await fetch('{envId}', {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"accessToken": "{YOUR_TOKEN}",
"includeReply": true,
"pageSize": 20,
...option
}),
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json())

return res.data
},


barrage: async () => {
const tlol = btf.saveToLocal.get('comment-pop')
const barrage = document.getElementById('comment-barrage')
if (tlol === 'off' || !barrage) return

const ScrollBarrage = () => {
const scrollResidue = (window.scrollY + document.documentElement.clientHeight) >= (document.getElementById("post-comment") || document.getElementById("footer")).offsetTop
barrage.classList.toggle('show', !scrollResidue)
}

let box = []
const BarrageBox = (data) => {
const time = changeTime(new Date(data.created).toISOString(), true)

let barrages = document.createElement('div')
barrages.className = 'comment-barrage-item'
barrages.innerHTML = `<div class="barrageHead"><div class="barrageNick"><div class="barrageAvatar" style="background-image: url('${data.avatar}'); width: 20px; height: 20px; border-radius: 50%; background-size: cover;"></div><span>${data.nick}</span></div><div class="barrageTime">${time} 曾评论</div><a class="barrageClose" href="javascript:comment.closeBarrage(true)"><i class="fas fa-times"></i></a></div><a class="barrageContent" href="javascript:void(0)" onclick="const el=document.getElementById('${data.id}');if(el){btf.scrollToDest(btf.getEleTop(el),300)}else{btf.scrollToDest(btf.getEleTop(document.getElementById('post-comment')),300)}"><p>${data.commentText.trim()}</p></a>`

box.push(barrages)
barrage.append(barrages)
}

btf.addEventListenerPjax(window, 'scroll', ScrollBarrage, { passive: true })

let hoverBarrage = false, index = 0
const url = window.location.pathname
const allComments = await comment.fetchData({url})
const data = allComments.filter(comment => comment.url === url)
if (!data.length) return

BarrageBox(data[index])

barrage.addEventListener('mouseenter', () => hoverBarrage = true)
barrage.addEventListener('mouseleave', () => hoverBarrage = false)

clearInterval(commentInterval)
commentInterval = setInterval(() => {
if (!hoverBarrage) {
index = (index + 1) % data.length
BarrageBox(data[index])
}
}, 5000)
},

closeBarrage: (state = false) => {
const removeBarrage = () => {
const $comment = document.querySelector('#comment-barrage')
$comment.className = 'out'
setTimeout(() => { $comment.innerHTML = '', $comment.className = 'show' }, 1000)
}

if (state) return clearInterval(commentInterval), removeBarrage()

const comments = btf.saveToLocal.get('comment-pop')
btf.saveToLocal.set('comment-pop', comments === 'off' ? 'on' : 'off', 2)
comments === 'off' ? comment.barrage() : (clearInterval(commentInterval), removeBarrage())
}
}
// btf.addGlobalFn('pjaxComplete', comment.new(), 'comment')
btf.addGlobalFn('pjaxComplete', comment.barrage(), 'barrage')