Compare commits

..

No commits in common. "main" and "v1.0.0" have entirely different histories.
main ... v1.0.0

24 changed files with 12492 additions and 20787 deletions

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
release
/release/

View File

@ -1,56 +1,3 @@
<div align="center"> # halo-theme-hao
<!-- 主题Logo -->
<img width="100px" src="https://api.minio.yyds.pink/moony/files/2024/04/halo-theme-hao-sbxqdmuv.png">
<!-- 主题名称 -->
<h1>Halo-Theme-Hao</h1>
</div>
## 🔥 预览 基于halo-theme-hao的1.4.9-beta2版本进行修改。
| 站点名称 | 站点地址 |
|:--------------:|:------------------------:|
| 小小笔记大大用处 | https://blog.uptoz.cn |
## 👋 简介
[Halo-Theme-Hao](https://gitea.uptoz.cn/UPToZ/halo-theme-hao)
是一款适用于 [Halo2.x](https://github.com/halo-dev/halo) 的博客主题。
移植自 [Hexo](https://hexo.io/zh-cn/index.html) 社区中 [张洪 Heo](https://blog.zhheo.com/)
对 [Hexo-Theme-hao](https://github.com/chengzhongxue/halo-theme-hao)主题1.4.9-beta2的魔改版本。
## 🚨 注意事项(看我看我)
1. **建站时间必填**
2. 如果安装主题后报错,请仔细查阅[主题说明](https://gitea.uptoz.cn/UPToZ/halo-theme-hao)
与[更新说明](https://gitea.uptoz.cn/UPToZ/halo-theme-hao/releases)
3. 如果还未解决,可以加群求助!!!
4. 如果群友也解决不了再考虑提ISSUE
5. `1.0.0`及以上版本需要`Halo`版本>=`2.14.0`
6. **若安装主题后出现500错误请到主题设置页面将每个设置项都保存一下**
7. **`beta`版本主题必须使用`本地资源`,正式版本才会存在`在线资源`**
### 🔌 插件依赖
> 所有插件均为可选,不安装则不会出现对应功能。
> 部分插件可能已经预设在 Halo 内。
> 部分插件主题尚未适配。
- 评论功能 [plugin-comment-widget](https://github.com/halo-sigs/plugin-comment-widget/releases)
- 搜索功能 [plugin-search-widget](https://github.com/halo-sigs/plugin-search-widget/releases)
- 友链页面 [plugin-links](https://github.com/halo-sigs/plugin-links)
- 瞬间页面 [plugin-moments](https://github.com/halo-sigs/plugin-moments)
- 追番插件 [plugin-bilibili-bangumi](https://github.com/Roozenlz/plugin-bilibili-bangumi)
- 图库插件 [plugin-photos](https://github.com/halo-sigs/plugin-photos)
- katex插件 [plugin-katex](https://github.com/chengzhongxue/plugin-katex/releases/)
- 我的装备 [plugin-equipments](https://github.com/chengzhongxue/plugin-equipments)
- Markdown / HTML 内容块插件 [plugin-hybrid-edit-block](https://www.halo.run/store/apps/app-NgHnY)
- 爱发电 [plugin-afdian](https://www.halo.run/store/apps/app-oXvZp)
> 更多插件请参见https://github.com/halo-sigs/awesome-halo
## 📝 使用
[点我查看](https://www.yuque.com/liuzhihangs/halo-theme-hao)

View File

@ -750,7 +750,8 @@ spec:
label: 爱发电赞助 label: 爱发电赞助
value: value:
powerLink: / powerLink: /
url: /apis/api.plugin.halo.run/v1alpha1/plugins/plugin-afdian/afdian/getSponsorList url: https://api.afdian.cnkj.site/api/creator/get-top-sponsors?user_id=
userId:
showNum: 3 showNum: 3
children: children:
- $formkit: url - $formkit: url
@ -759,7 +760,9 @@ spec:
- $formkit: text - $formkit: text
name: url name: url
label: 接口地址 label: 接口地址
help: 需要安装爱发电插件 - $formkit: text
name: userId
label: 用户ID
- $formkit: number - $formkit: number
name: showNum name: showNum
label: 最大展示条数 label: 最大展示条数

View File

@ -1,90 +1,87 @@
.timeline { .timeline {
width: 100%; width: 100%;
height: 2rem; height: 20px;
background-color: var(--heo-background); background-color: var(--heo-background);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
margin-bottom: 20px; margin-bottom: 20px;
border-radius: 1.5rem; border-radius: 0.5rem;
height: 2.5rem;
} }
.progress { .progress {
width: 0; width: 0;
height: 100%; height: 100%;
background-color: var(--heo-main); background-color: var(--heo-main);
position: absolute; position: absolute;
animation: progressAnimation 2s linear forwards; animation: progressAnimation 2s linear forwards;
animation-delay: -0.1s; animation-delay: -0.1s;
border-radius: 1.5rem border-radius: 0.5rem
} }
.past-time { .past-time {
width: 2px; width: 2px;
height: 20px; height: 20px;
background-color: #3498db; background-color: #3498db;
position: absolute; position: absolute;
transform-origin: left; transform-origin: left;
animation: pastTimeAnimation 3s linear forwards; animation: pastTimeAnimation 3s linear forwards;
} }
.percentage-label { .percentage-label {
position: absolute; position: absolute;
left: 0; left: 0;
font-size: 14px; font-size: 14px;
color: var(--heo-card-bg); color: var(--heo-card-bg);
font-weight: bold; font-weight: bold;
top: 10px; top: 10px;
white-space: nowrap; white-space: nowrap;
transition: left 0.5s linear; transition: left 0.5s linear;
visibility: hidden; visibility: hidden;
} }
.time-labels { .time-labels {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
} }
.time-labels>div { .time-labels>div {
font-size: 14px; font-size: 14px;
color: var(--heo-fontcolor); color: var(--heo-fontcolor);
} }
@keyframes progressAnimation { @keyframes progressAnimation {
0% { 0% {
width: 0; width: 0;
} }
100% {
100% { width: var(--progress-percentage, 0);
width: var(--progress-percentage, 0); }
}
} }
@keyframes pastTimeAnimation { @keyframes pastTimeAnimation {
0% { 0% {
transform: scaleX(0); transform: scaleX(0);
} }
100% {
100% { transform: scaleX(var(--past-time-percentage, 0));
transform: scaleX(var(--past-time-percentage, 0)); }
}
} }
.timeline:hover { .timeline:hover {
animation: btn31-eff 3s linear infinite; animation: btn31-eff 3s linear infinite;
cursor: pointer; cursor: pointer;
} }
@keyframes btn31-eff { @keyframes btn31-eff {
0% { 0% {
box-shadow: 0 0 2px var(--heo-main); box-shadow: 0 0 2px var(--heo-main);
} }
50% {
50% { box-shadow: 0 0 40px var(--heo-main);
box-shadow: 0 0 40px var(--heo-main); }
} 100% {
box-shadow: 0 0 2px var(--heo-main);
100% { }
box-shadow: 0 0 2px var(--heo-main);
}
} }

View File

@ -18,6 +18,7 @@ let halo = {
var e = document.querySelector("link[data-code-theme=light]"), var e = document.querySelector("link[data-code-theme=light]"),
o = document.querySelector("link[data-code-theme=dark]"); o = document.querySelector("link[data-code-theme=dark]");
(o || e) && ("light" === t ? (o.disabled = !0, e.disabled = !1) : (e.disabled = !0, o.disabled = !1)) (o || e) && ("light" === t ? (o.disabled = !0, e.disabled = !1) : (e.disabled = !0, o.disabled = !1))
}, },
/** /**
@ -31,6 +32,7 @@ let halo = {
if (!Prism.plugins.toolbar) { if (!Prism.plugins.toolbar) {
console.warn('Copy to Clipboard plugin loaded before Toolbar plugin.'); console.warn('Copy to Clipboard plugin loaded before Toolbar plugin.');
return; return;
} }
@ -320,8 +322,7 @@ let halo = {
'limit': '100' 'limit': '100'
}); });
fetch(GLOBAL_CONFIG.source.artalk.artalkUrl + 'api/v2/stats/latest_comments?' + queryParams fetch(GLOBAL_CONFIG.source.artalk.artalkUrl + 'api/v2/stats/latest_comments?' + queryParams.toString(),
.toString(),
statheaderList) statheaderList)
.then((e => e.json())).then((({ .then((e => e.json())).then((({
data: t data: t
@ -374,44 +375,20 @@ let halo = {
}, },
getTopSponsors() { getTopSponsors() {
var show_num = GLOBAL_CONFIG.source.power.showNum; var user_id = GLOBAL_CONFIG.source.power.userId
var url = GLOBAL_CONFIG.source.power.url; var show_num = GLOBAL_CONFIG.source.power.showNum
function getPower() { function getPower() {
const url = GLOBAL_CONFIG.source.power.url; const url = GLOBAL_CONFIG.source.power.url + user_id
let powerStar = document.getElementById("power-star")
powerStar.href = GLOBAL_CONFIG.source.power.powerLink
fetch(url) fetch(url)
.then(response => { .then(res => res.json())
// 检查响应状态码
if (!response.ok) {
// 如果响应状态码不是 200抛出一个错误
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')">
</div>
<div class="power-star-body">
<div id="power-star-title">还没有人赞助</div>
<div id="power-star-desc">为爱发电点击赞助</div>
</div>`;
}
return response.json(); // 只有在状态码为 200 时才解析 JSON
})
.then(data => { .then(data => {
if (200 === data["ec"]) { if (200 === data["ec"]) {
const values = data["data"]["list"]; var values = data["data"]["list"]
saveToLocal.set('power-data', JSON.stringify(values), 10 / (60 * 24)) saveToLocal.set('power-data', JSON.stringify(values), 10 / (60 * 24))
renderer(values); renderer(values);
} }
})
.catch(error => {
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')">
</div>
<div class="power-star-body">
<div id="power-star-title">还没有人赞助</div>
<div id="power-star-desc">为爱发电点击赞助</div>
</div>`;
console.error(error);
}) })
} }
@ -421,22 +398,22 @@ let halo = {
if (values.length === 0) { if (values.length === 0) {
powerStar.href = GLOBAL_CONFIG.source.power.powerLink powerStar.href = GLOBAL_CONFIG.source.power.powerLink
powerStar.innerHTML = ` powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')"> <div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')">
</div> </div>
<div class="power-star-body"> <div class="power-star-body">
<div id="power-star-title">还没有人赞助</div> <div id="power-star-title">还没有人赞助</div>
<div id="power-star-desc">为爱发电点击赞助</div> <div id="power-star-desc">为爱发电点击赞助</div>
</div>`; </div>`;
} else { } else {
if (powerStar) { if (powerStar) {
powerStar.href = "https://afdian.net/u/" + data[0]["user"].user_id powerStar.href = "https://afdian.net/u/" + data[0].user_id
powerStar.innerHTML = ` powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url(${data[0]["user"].avatar})"> <div id="power-star-image" style="background-image: url(${data[0].avatar})">
</div> </div>
<div class="power-star-body"> <div class="power-star-body">
<div id="power-star-title">${data[0]["user"].name}</div> <div id="power-star-title">${data[0].name}</div>
<div id="power-star-desc">更多支持为爱发电</div> <div id="power-star-desc">更多支持为爱发电</div>
</div>`; </div>`;
} }
if (values.length > 1) { if (values.length > 1) {
@ -447,7 +424,7 @@ let halo = {
break; break;
} }
htmlText += htmlText +=
` <a href="${"https://afdian.net/u/" + value["user"]["user_id"]}" rel="external nofollow" target="_blank" th:title="${value["user"]["name"]}">${value["user"]["name"]}</a>`; ` <a href="${"https://afdian.net/u/" + value["user_id"]}" rel="external nofollow" target="_blank" th:title="${value["name"]}">${value["name"]}</a>`;
i = i + 1; i = i + 1;
} }
if (document.getElementById("power-item-link")) { if (document.getElementById("power-item-link")) {
@ -462,7 +439,7 @@ let halo = {
if (data) { if (data) {
renderer(JSON.parse(data)) renderer(JSON.parse(data))
} else { } else {
getPower(); getPower()
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -2,358 +2,352 @@ var btf = {
// 修改时间显示"最近" // 修改时间显示"最近"
diffDateExact: function(d, more = false) { diffDateExact: function (d, more = false) {
const dateNow = new Date(); const dateNow = new Date();
const datePost = new Date(d); const datePost = new Date(d);
const dateDiff = dateNow.getTime() - datePost.getTime(); const dateDiff = dateNow.getTime() - datePost.getTime();
const minute = 1000 * 60; const minute = 1000 * 60;
const hour = minute * 60; const hour = minute * 60;
const day = hour * 24; const day = hour * 24;
const month = day * 30; const month = day * 30;
let result; let result;
if (more) { if (more) {
const monthCount = dateDiff / month; const monthCount = dateDiff / month;
const dayCount = dateDiff / day; const dayCount = dateDiff / day;
const hourCount = dateDiff / hour; const hourCount = dateDiff / hour;
const minuteCount = dateDiff / minute; const minuteCount = dateDiff / minute;
if (monthCount >= 1) { if (monthCount >= 1) {
result = datePost.toLocaleDateString().replace(/\//g, "-"); result = datePost.toLocaleDateString().replace(/\//g, "-");
} else if (dayCount >= 1) { } else if (dayCount >= 1) {
result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day; result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day;
} else if (hourCount >= 1) { } else if (hourCount >= 1) {
result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour; result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour;
} else if (minuteCount >= 1) { } else if (minuteCount >= 1) {
result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min; result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min;
} else { } else {
result = GLOBAL_CONFIG.date_suffix.just; result = GLOBAL_CONFIG.date_suffix.just;
} }
} else { } else {
result = parseInt(dateDiff / day); result = parseInt(dateDiff / day);
} }
return result; return result;
}, },
loadLightbox: ele => { loadLightbox: ele => {
const jqLoadAndRun = () => { const jqLoadAndRun = () => {
const $fancyboxEle = GLOBAL_CONFIG.lightbox === 'fancybox' ? const $fancyboxEle = GLOBAL_CONFIG.lightbox === 'fancybox'
ele : ? ele
[] : []
const fbLengthNoZero = $fancyboxEle.length > 0 const fbLengthNoZero = $fancyboxEle.length > 0
if (fbLengthNoZero) { if (fbLengthNoZero) {
btf.isJqueryLoad(() => { btf.isJqueryLoad(() => {
fbLengthNoZero && addFancybox($fancyboxEle) fbLengthNoZero && addFancybox($fancyboxEle)
}) })
} }
} }
/** /**
* fancybox * fancybox
*/ */
const addFancybox = function(ele) { const addFancybox = function (ele) {
const runFancybox = (ele) => { const runFancybox = (ele) => {
ele.each(function(i, o) { ele.each(function (i, o) {
const $this = $(o) const $this = $(o)
const lazyloadSrc = $this.attr('data-lazy-src') || $this.attr('src') const lazyloadSrc = $this.attr('data-lazy-src') || $this.attr('src')
const dataCaption = $this.attr('alt') || '' const dataCaption = $this.attr('alt') || ''
$this.wrap( $this.wrap(`<a href="${lazyloadSrc}" data-fancybox="images" data-caption="${dataCaption}" class="fancybox" data-srcset="${lazyloadSrc}"></a>`)
`<a href="${lazyloadSrc}" data-fancybox="images" data-caption="${dataCaption}" class="fancybox" data-srcset="${lazyloadSrc}"></a>` })
)
})
$().fancybox({ $().fancybox({
selector: '[data-fancybox]', selector: '[data-fancybox]',
loop: true, loop: true,
transitionEffect: 'slide', transitionEffect: 'slide',
protect: true, protect: true,
buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'], buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'],
hash: false hash: false
}) })
} }
if (typeof $.fancybox === 'undefined') { if (typeof $.fancybox === 'undefined') {
// $('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.fancybox.css}">`) // $('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.fancybox.css}">`)
$.getScript(`${GLOBAL_CONFIG.source.fancybox.js}`, function() { $.getScript(`${GLOBAL_CONFIG.source.fancybox.js}`, function () {
runFancybox($(ele)) runFancybox($(ele))
}) })
} else { } else {
runFancybox($(ele)) runFancybox($(ele))
} }
} }
jqLoadAndRun() jqLoadAndRun()
}, },
debounce: function(func, wait, immediate) { debounce: function (func, wait, immediate) {
let timeout let timeout
return function() { return function () {
const context = this const context = this
const args = arguments const args = arguments
const later = function() { const later = function () {
timeout = null timeout = null
if (!immediate) func.apply(context, args) if (!immediate) func.apply(context, args)
} }
const callNow = immediate && !timeout const callNow = immediate && !timeout
clearTimeout(timeout) clearTimeout(timeout)
timeout = setTimeout(later, wait) timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args) if (callNow) func.apply(context, args)
} }
}, },
throttle: function(func, wait, options) { throttle: function (func, wait, options) {
let timeout, context, args let timeout, context, args
let previous = 0 let previous = 0
if (!options) options = {} if (!options) options = {}
const later = function() { const later = function () {
previous = options.leading === false ? 0 : new Date().getTime() previous = options.leading === false ? 0 : new Date().getTime()
timeout = null timeout = null
func.apply(context, args) func.apply(context, args)
if (!timeout) context = args = null if (!timeout) context = args = null
} }
const throttled = function() { const throttled = function () {
const now = new Date().getTime() const now = new Date().getTime()
if (!previous && options.leading === false) previous = now if (!previous && options.leading === false) previous = now
const remaining = wait - (now - previous) const remaining = wait - (now - previous)
context = this context = this
args = arguments args = arguments
if (remaining <= 0 || remaining > wait) { if (remaining <= 0 || remaining > wait) {
if (timeout) { if (timeout) {
clearTimeout(timeout) clearTimeout(timeout)
timeout = null timeout = null
} }
previous = now previous = now
func.apply(context, args) func.apply(context, args)
if (!timeout) context = args = null if (!timeout) context = args = null
} else if (!timeout && options.trailing !== false) { } else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining) timeout = setTimeout(later, remaining)
} }
} }
return throttled return throttled
}, },
sidebarPaddingR: () => { sidebarPaddingR: () => {
const innerWidth = window.innerWidth const innerWidth = window.innerWidth
const clientWidth = document.body.clientWidth const clientWidth = document.body.clientWidth
const paddingRight = innerWidth - clientWidth const paddingRight = innerWidth - clientWidth
if (innerWidth !== clientWidth) { if (innerWidth !== clientWidth) {
document.body.style.paddingRight = paddingRight + 'px' document.body.style.paddingRight = paddingRight + 'px'
} }
}, },
snackbarShow: (text, showActionFunction = false, duration = 2000, actionText = false) => { snackbarShow: (text, showActionFunction = false, duration = 2000, actionText = false) => {
const { const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar;
position, const bg = document.documentElement.getAttribute("data-theme") === "light" ? bgLight : bgDark;
bgLight, const root = document.querySelector(":root");
bgDark root.style.setProperty("--heo-snackbar-time", duration + "ms");
} = GLOBAL_CONFIG.Snackbar;
const bg = document.documentElement.getAttribute("data-theme") === "light" ? bgLight : bgDark;
const root = document.querySelector(":root");
root.style.setProperty("--heo-snackbar-time", duration + "ms");
Snackbar.show({ Snackbar.show({
text: text, text: text,
backgroundColor: bg, backgroundColor: bg,
onActionClick: showActionFunction, onActionClick: showActionFunction,
actionText: actionText, actionText: actionText,
showAction: actionText, showAction: actionText,
duration: duration, duration: duration,
pos: position, pos: position,
customClass: "snackbar-css", customClass: "snackbar-css",
}); });
}, },
initJustifiedGallerys: function(selector) { initJustifiedGallerys: function (selector) {
selector.forEach((function(t) { selector.forEach((function(t) {
btf.isHidden(t) || fjGallery(t, { btf.isHidden(t) || fjGallery(t, {
itemSelector: ".fj-gallery-item", itemSelector: ".fj-gallery-item",
rowHeight: 240, rowHeight: 240,
gutter: 4, gutter: 4,
onJustify: function() { onJustify: function() {
this.$container.style.opacity = "1" this.$container.style.opacity = "1"
} }
}) })
})) }
document.querySelectorAll('#article-container .loadings')[0]?.classList.remove("loadings"); ))
}, document.querySelectorAll('#article-container .loadings')[0]?.classList.remove("loadings");
},
diffDate: (d, more = false) => { diffDate: (d, more = false) => {
const dateNow = new Date() const dateNow = new Date()
const datePost = new Date(d) const datePost = new Date(d)
const dateDiff = dateNow.getTime() - datePost.getTime() const dateDiff = dateNow.getTime() - datePost.getTime()
const minute = 1000 * 60 const minute = 1000 * 60
const hour = minute * 60 const hour = minute * 60
const day = hour * 24 const day = hour * 24
const month = day * 30 const month = day * 30
let result let result
if (more) { if (more) {
const monthCount = dateDiff / month const monthCount = dateDiff / month
const dayCount = dateDiff / day const dayCount = dateDiff / day
const hourCount = dateDiff / hour const hourCount = dateDiff / hour
const minuteCount = dateDiff / minute const minuteCount = dateDiff / minute
if (monthCount > 12) { if (monthCount > 12) {
// result = datePost.toLocaleDateString().replace(/\//g, '-') // result = datePost.toLocaleDateString().replace(/\//g, '-')
result = datePost.toLocaleDateString() result = datePost.toLocaleDateString()
} else if (dayCount >= 7) { } else if (dayCount >= 7) {
// } else if (monthCount >= 1) { // } else if (monthCount >= 1) {
result = datePost.toLocaleDateString().substr(5) result = datePost.toLocaleDateString().substr(5)
// result = parseInt(monthCount) + ' ' + GLOBAL_CONFIG.date_suffix.month // result = parseInt(monthCount) + ' ' + GLOBAL_CONFIG.date_suffix.month
} else if (dayCount >= 1) { } else if (dayCount >= 1) {
result = parseInt(dayCount) + '' + GLOBAL_CONFIG.date_suffix.day result = parseInt(dayCount) + '' + GLOBAL_CONFIG.date_suffix.day
} else if (hourCount >= 1) { } else if (hourCount >= 1) {
// result = '最近' // result = '最近'
result = parseInt(hourCount) + ' ' + GLOBAL_CONFIG.date_suffix.hour result = parseInt(hourCount) + ' ' + GLOBAL_CONFIG.date_suffix.hour
} else if (minuteCount >= 1) { } else if (minuteCount >= 1) {
// result = '最近' // result = '最近'
result = parseInt(minuteCount) + ' ' + GLOBAL_CONFIG.date_suffix.min result = parseInt(minuteCount) + ' ' + GLOBAL_CONFIG.date_suffix.min
} else { } else {
result = GLOBAL_CONFIG.date_suffix.just result = GLOBAL_CONFIG.date_suffix.just
} }
} else { } else {
result = parseInt(dateDiff / day) result = parseInt(dateDiff / day)
} }
return result return result
}, },
loadComment: (dom, callback) => { loadComment: (dom, callback) => {
if ('IntersectionObserver' in window) { if ('IntersectionObserver' in window) {
const observerItem = new IntersectionObserver((entries) => { const observerItem = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) { if (entries[0].isIntersecting) {
callback() callback()
observerItem.disconnect() observerItem.disconnect()
} }
}, { }, {threshold: [0]})
threshold: [0] observerItem.observe(dom)
}) } else {
observerItem.observe(dom) callback()
} else { }
callback() },
}
},
scrollToDest: (e, t) => { scrollToDest: (e,t)=>{
if (e < 0 || t < 0) if (e < 0 || t < 0)
return; return;
const n = window.scrollY || window.screenTop; const n = window.scrollY || window.screenTop;
if (e -= 70, if (e -= 70,
"CSS" in window && CSS.supports("scroll-behavior", "smooth")) "CSS"in window && CSS.supports("scroll-behavior", "smooth"))
return void window.scrollTo({ return void window.scrollTo({
top: e, top: e,
behavior: "smooth" behavior: "smooth"
}); });
let o = null; let o = null;
t = t || 500, t = t || 500,
window.requestAnimationFrame((function i(s) { window.requestAnimationFrame((function i(s) {
if (o = o || s, if (o = o || s,
n < e) { n < e) {
const r = s - o; const r = s - o;
window.scrollTo(0, (e - n) * r / t + n), window.scrollTo(0, (e - n) * r / t + n),
r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e) r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e)
} else { } else {
const r = s - o; const r = s - o;
window.scrollTo(0, n - (n - e) * r / t), window.scrollTo(0, n - (n - e) * r / t),
r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e) r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e)
} }
})) }
}, ))
},
fadeIn: (ele, time) => { fadeIn: (ele, time) => {
ele.style.cssText = `display:block;animation: to_show ${time}s` ele.style.cssText = `display:block;animation: to_show ${time}s`
}, },
fadeOut: (ele, time) => { fadeOut: (ele, time) => {
ele.addEventListener('animationend', function f() { ele.addEventListener('animationend', function f() {
ele.style.cssText = "display: none; animation: '' " ele.style.cssText = "display: none; animation: '' "
ele.removeEventListener('animationend', f) ele.removeEventListener('animationend', f)
}) })
ele.style.animation = `to_hide ${time}s` ele.style.animation = `to_hide ${time}s`
}, },
getParents: (elem, selector) => { getParents: (elem, selector) => {
for (; elem && elem !== document; elem = elem.parentNode) { for (; elem && elem !== document; elem = elem.parentNode) {
if (elem.matches(selector)) return elem if (elem.matches(selector)) return elem
} }
return null return null
}, },
siblings: (ele, selector) => { siblings: (ele, selector) => {
return [...ele.parentNode.children].filter((child) => { return [...ele.parentNode.children].filter((child) => {
if (selector) { if (selector) {
return child !== ele && child.matches(selector) return child !== ele && child.matches(selector)
} }
return child !== ele return child !== ele
}) })
}, },
/** /**
* *
* @param {*} selector * @param {*} selector
* @param {*} eleType the type of create element * @param {*} eleType the type of create element
* @param {*} id id * @param {*} id id
* @param {*} cn class name * @param {*} cn class name
*/ */
wrap: function(selector, eleType, id = '', cn = '') { wrap: function (selector, eleType, id = '', cn = '') {
const creatEle = document.createElement(eleType) const creatEle = document.createElement(eleType)
if (id) creatEle.id = id if (id) creatEle.id = id
if (cn) creatEle.className = cn if (cn) creatEle.className = cn
selector.parentNode.insertBefore(creatEle, selector) selector.parentNode.insertBefore(creatEle, selector)
creatEle.appendChild(selector) creatEle.appendChild(selector)
}, },
unwrap: function(el) { unwrap: function (el) {
const elParentNode = el.parentNode const elParentNode = el.parentNode
if (elParentNode !== document.body) { if (elParentNode !== document.body) {
elParentNode.parentNode.insertBefore(el, elParentNode) elParentNode.parentNode.insertBefore(el, elParentNode)
elParentNode.parentNode.removeChild(elParentNode) elParentNode.parentNode.removeChild(elParentNode)
} }
}, },
isJqueryLoad: (fn) => { isJqueryLoad: (fn) => {
if (typeof jQuery === 'undefined') { if (typeof jQuery === 'undefined') {
getScript(GLOBAL_CONFIG.source.jQuery).then(fn) getScript(GLOBAL_CONFIG.source.jQuery).then(fn)
} else { } else {
fn() fn()
} }
}, },
isHidden: (ele) => ele.offsetHeight === 0 && ele.offsetWidth === 0, isHidden: (ele) => ele.offsetHeight === 0 && ele.offsetWidth === 0,
getEleTop: (ele) => { getEleTop: (ele) => {
let actualTop = ele.offsetTop let actualTop = ele.offsetTop
let current = ele.offsetParent let current = ele.offsetParent
while (current !== null) { while (current !== null) {
actualTop += current.offsetTop actualTop += current.offsetTop
current = current.offsetParent current = current.offsetParent
} }
return actualTop return actualTop
}, },
//过滤标签 //过滤标签
changeContent: (content, length = null) => { changeContent: (content,length = null)=>{
if (content === '') return content if (content === '') return content
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
content = content.replace(/<[^>]+>/g, "") // remove html tag content = content.replace(/<[^>]+>/g, "") // remove html tag
if (length != null) { if (length!=null){
if (content.length > length) { if (content.length > length) {
content = content.substring(0, length) + '...' content = content.substring(0, length) + '...'
} }
} }
return content return content
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -279,37 +279,10 @@ i.haofont.hao-icon-arrow-right.banner-righticon{
--hao-gl-size: 16px !important; --hao-gl-size: 16px !important;
} }
#aside-content .card-announcement .item-headline i{ #aside-content .card-announcement .item-headline i{
color: palevioletred; color: red;
margin-left: -6px;
} }
/* 小板报 */ /* 小板报 */
#aside-content .card-ad .item-headline i{
color: orangered;
margin-left: -6px;
}
#aside-content .card-power .item-headline i{
color: mediumpurple;
margin-right: 5px;
}
#aside-content .card-categories .item-headline i{
color: burlywood;
margin-right: 2px;
}
#aside-content .card-toc .item-headline i{
color: green;
}
#aside-content .card-comment .item-headline i{
color: rosybrown;
}
#aside-content .card-article .item-headline i{
color: cornflowerblue;
}
/* Steam卡片 */ /* Steam卡片 */
#aside-content .item-headline-steam { #aside-content .item-headline-steam {

View File

@ -3,26 +3,26 @@ let rm = {};
//禁止图片拖拽 //禁止图片拖拽
rm.stopdragimg = $("img"); rm.stopdragimg = $("img");
rm.stopdragimg.on("dragstart", function() { rm.stopdragimg.on("dragstart", function () {
return false; return false;
}); });
// 显示菜单 // 显示菜单
rm.showRightMenu = function(isTrue, x = 0, y = 0) { rm.showRightMenu = function (isTrue, x = 0, y = 0) {
let $rightMenu = $('#rightMenu'); let $rightMenu = $('#rightMenu');
$rightMenu.css('top', x + 'px').css('left', y + 'px'); $rightMenu.css('top', x + 'px').css('left', y + 'px');
if (isTrue) { if (isTrue) {
$rightMenu.show(); $rightMenu.show();
stopMaskScroll() stopMaskScroll()
} else { } else {
$rightMenu.hide(); $rightMenu.hide();
} }
} }
// 隐藏菜单 // 隐藏菜单
rm.hideRightMenu = function() { rm.hideRightMenu = function () {
rm.showRightMenu(false); rm.showRightMenu(false);
$('#rightmenu-mask').attr('style', 'display: none'); $('#rightmenu-mask').attr('style', 'display: none');
} }
// 尺寸 // 尺寸
@ -30,9 +30,9 @@ let rmWidth = $('#rightMenu').width();
let rmHeight = $('#rightMenu').height(); let rmHeight = $('#rightMenu').height();
// 重新定义尺寸 // 重新定义尺寸
rm.reloadrmSize = function() { rm.reloadrmSize = function () {
rmWidth = $('#rightMenu').width(); rmWidth = $('#rightMenu').width();
rmHeight = $('#rightMenu').height(); rmHeight = $('#rightMenu').height();
} }
// 获取点击的href // 获取点击的href
@ -41,227 +41,225 @@ let domImgSrc = '';
let globalEvent = null; let globalEvent = null;
// 监听右键初始化 // 监听右键初始化
window.oncontextmenu = function(event) { window.oncontextmenu = function (event) {
if (document.body.clientWidth > 768) { if (document.body.clientWidth > 768) {
let pageX = event.clientX + 10; //加10是为了防止显示时鼠标遮在菜单上 let pageX = event.clientX + 10; //加10是为了防止显示时鼠标遮在菜单上
let pageY = event.clientY; let pageY = event.clientY;
// console.log(event); // console.log(event);
//其他额外菜单 //其他额外菜单
let $rightMenuOther = $('.rightMenuOther'); let $rightMenuOther = $('.rightMenuOther');
let $rightMenuPlugin = $('.rightMenuPlugin'); let $rightMenuPlugin = $('.rightMenuPlugin');
let $rightMenuCopyText = $('#menu-copytext'); let $rightMenuCopyText = $('#menu-copytext');
let $rightMenuPasteText = $('#menu-pastetext'); let $rightMenuPasteText = $('#menu-pastetext');
let $rightMenuCommentText = $('#menu-commenttext'); let $rightMenuCommentText = $('#menu-commenttext');
let $rightMenuNewWindow = $('#menu-newwindow'); let $rightMenuNewWindow = $('#menu-newwindow');
let $rightMenuNewWindowImg = $('#menu-newwindowimg'); let $rightMenuNewWindowImg = $('#menu-newwindowimg');
let $rightMenuCopyLink = $('#menu-copylink'); let $rightMenuCopyLink = $('#menu-copylink');
let $rightMenuCopyImg = $('#menu-copyimg'); let $rightMenuCopyImg = $('#menu-copyimg');
let $rightMenuDownloadImg = $('#menu-downloadimg'); let $rightMenuDownloadImg = $('#menu-downloadimg');
let $rightMenuSearch = $('#menu-search'); let $rightMenuSearch = $('#menu-search');
let $rightMenuSearchBaidu = $('#menu-searchBaidu'); let $rightMenuSearchBaidu = $('#menu-searchBaidu');
let $rightMenuMusicToggle = $('#menu-music-toggle'); let $rightMenuMusicToggle = $('#menu-music-toggle');
let $rightMenuMusicBack = $('#menu-music-back'); let $rightMenuMusicBack = $('#menu-music-back');
let $rightMenuMusicForward = $('#menu-music-forward'); let $rightMenuMusicForward = $('#menu-music-forward');
let $rightMenuMusicPlaylist = $('#menu-music-playlist'); let $rightMenuMusicPlaylist = $('#menu-music-playlist');
let $rightMenuMusicCopyMusicName = $('#menu-music-copyMusicName'); let $rightMenuMusicCopyMusicName = $('#menu-music-copyMusicName');
let href = event.target.href; let href = event.target.href;
let imgsrc = event.target.currentSrc; let imgsrc = event.target.currentSrc;
// 判断模式 扩展模式为有事件 // 判断模式 扩展模式为有事件
let pluginMode = false; let pluginMode = false;
$rightMenuOther.show(); $rightMenuOther.show();
globalEvent = event; globalEvent = event;
// 检查是否需要复制 是否有选中文本 // 检查是否需要复制 是否有选中文本
if (selectTextNow && window.getSelection()) { if (selectTextNow && window.getSelection()) {
pluginMode = true; pluginMode = true;
$rightMenuCopyText.show(); $rightMenuCopyText.show();
$rightMenuCommentText.show(); $rightMenuCommentText.show();
$rightMenuSearch.show(); $rightMenuSearch.show();
$rightMenuSearchBaidu.show(); $rightMenuSearchBaidu.show();
} else { } else {
$rightMenuCopyText.hide(); $rightMenuCopyText.hide();
$rightMenuCommentText.hide(); $rightMenuCommentText.hide();
$rightMenuSearchBaidu.hide(); $rightMenuSearchBaidu.hide();
$rightMenuSearch.hide(); $rightMenuSearch.hide();
} }
//检查是否右键点击了链接a标签 //检查是否右键点击了链接a标签
if (href) { if (href) {
pluginMode = true; pluginMode = true;
$rightMenuNewWindow.show(); $rightMenuNewWindow.show();
$rightMenuCopyLink.show(); $rightMenuCopyLink.show();
domhref = href; domhref = href;
} else { } else {
$rightMenuNewWindow.hide(); $rightMenuNewWindow.hide();
$rightMenuCopyLink.hide(); $rightMenuCopyLink.hide();
} }
//检查是否需要复制图片 //检查是否需要复制图片
if (imgsrc) { if (imgsrc) {
pluginMode = true; pluginMode = true;
$rightMenuCopyImg.show(); $rightMenuCopyImg.show();
$rightMenuDownloadImg.show(); $rightMenuDownloadImg.show();
$rightMenuNewWindowImg.show(); $rightMenuNewWindowImg.show();
domImgSrc = imgsrc; domImgSrc = imgsrc;
} else { } else {
$rightMenuCopyImg.hide(); $rightMenuCopyImg.hide();
$rightMenuDownloadImg.hide(); $rightMenuDownloadImg.hide();
$rightMenuNewWindowImg.hide(); $rightMenuNewWindowImg.hide();
} }
// 判断是否为输入框 // 判断是否为输入框
if (event.target.tagName.toLowerCase() === 'input' || event.target.tagName.toLowerCase() === 'textarea') { if (event.target.tagName.toLowerCase() === 'input' || event.target.tagName.toLowerCase() === 'textarea') {
console.log('这是一个输入框') console.log('这是一个输入框')
pluginMode = true; pluginMode = true;
$rightMenuPasteText.show(); $rightMenuPasteText.show();
} else { } else {
$rightMenuPasteText.hide(); $rightMenuPasteText.hide();
} }
//判断是否是音乐 //判断是否是音乐
const navMusicEl = document.querySelector("#nav-music"); const navMusicEl = document.querySelector("#nav-music");
if (navMusicEl && navMusicEl.contains(event.target)) { if (navMusicEl && navMusicEl.contains(event.target)) {
pluginMode = true; pluginMode = true;
$rightMenuMusicToggle.show(); $rightMenuMusicToggle.show();
$rightMenuMusicBack.show(); $rightMenuMusicBack.show();
$rightMenuMusicForward.show(); $rightMenuMusicForward.show();
$rightMenuMusicPlaylist.show(); $rightMenuMusicPlaylist.show();
$rightMenuMusicCopyMusicName.show(); $rightMenuMusicCopyMusicName.show();
} else { } else {
$rightMenuMusicToggle.hide(); $rightMenuMusicToggle.hide();
$rightMenuMusicBack.hide(); $rightMenuMusicBack.hide();
$rightMenuMusicForward.hide(); $rightMenuMusicForward.hide();
$rightMenuMusicPlaylist.hide(); $rightMenuMusicPlaylist.hide();
$rightMenuMusicCopyMusicName.hide() $rightMenuMusicCopyMusicName.hide()
} }
// 如果不是扩展模式则隐藏扩展模块 // 如果不是扩展模式则隐藏扩展模块
if (pluginMode) { if (pluginMode) {
$rightMenuOther.hide(); $rightMenuOther.hide();
$rightMenuPlugin.show(); $rightMenuPlugin.show();
} else { } else {
$rightMenuPlugin.hide() $rightMenuPlugin.hide()
} }
rm.reloadrmSize() rm.reloadrmSize()
// 鼠标默认显示在鼠标右下方,当鼠标靠右或考下时,将菜单显示在鼠标左方\上方 // 鼠标默认显示在鼠标右下方,当鼠标靠右或考下时,将菜单显示在鼠标左方\上方
if (pageX + rmWidth > window.innerWidth) { if (pageX + rmWidth > window.innerWidth) {
pageX -= rmWidth + 10; pageX -= rmWidth + 10;
} }
if (pageY + rmHeight > window.innerHeight) { if (pageY + rmHeight > window.innerHeight) {
pageY -= pageY + rmHeight - window.innerHeight; pageY -= pageY + rmHeight - window.innerHeight;
} }
rm.showRightMenu(true, pageY, pageX); rm.showRightMenu(true, pageY, pageX);
$('#rightmenu-mask').attr('style', 'display: flex'); $('#rightmenu-mask').attr('style', 'display: flex');
return false; return false;
} }
}; };
// 下载图片状态 // 下载图片状态
rm.downloadimging = false; rm.downloadimging = false;
// 复制图片到剪贴板 // 复制图片到剪贴板
rm.writeClipImg = function(imgsrc) { rm.writeClipImg = function (imgsrc) {
console.log('按下复制'); console.log('按下复制');
rm.hideRightMenu(); rm.hideRightMenu();
btf.snackbarShow('正在下载中,请稍后', false, 10000) btf.snackbarShow('正在下载中,请稍后', false, 10000)
if (rm.downloadimging == false) { if (rm.downloadimging == false) {
rm.downloadimging = true; rm.downloadimging = true;
setTimeout(function() { setTimeout(function () {
copyImage(imgsrc); copyImage(imgsrc);
btf.snackbarShow('复制成功!图片已添加盲水印,请遵守版权协议'); btf.snackbarShow('复制成功!图片已添加盲水印,请遵守版权协议');
rm.downloadimging = false; rm.downloadimging = false;
}, "10000") }, "10000")
} }
} }
function imageToBlob(imageURL) { function imageToBlob(imageURL) {
const img = new Image; const img = new Image;
const c = document.createElement("canvas"); const c = document.createElement("canvas");
const ctx = c.getContext("2d"); const ctx = c.getContext("2d");
img.crossOrigin = ""; img.crossOrigin = "";
img.src = imageURL; img.src = imageURL;
return new Promise(resolve => { return new Promise(resolve => {
img.onload = function() { img.onload = function () {
c.width = this.naturalWidth; c.width = this.naturalWidth;
c.height = this.naturalHeight; c.height = this.naturalHeight;
ctx.drawImage(this, 0, 0); ctx.drawImage(this, 0, 0);
c.toBlob((blob) => { c.toBlob((blob) => {
// here the image is a blob // here the image is a blob
resolve(blob) resolve(blob)
}, "image/png", 0.75); }, "image/png", 0.75);
}; };
}) })
} }
async function copyImage(imageURL) { async function copyImage(imageURL) {
const blob = await imageToBlob(imageURL) const blob = await imageToBlob(imageURL)
const item = new ClipboardItem({ const item = new ClipboardItem({"image/png": blob});
"image/png": blob navigator.clipboard.write([item]);
});
navigator.clipboard.write([item]);
} }
rm.switchDarkMode = function() { rm.switchDarkMode = function () {
navFn.switchDarkMode(); navFn.switchDarkMode();
rm.hideRightMenu(); rm.hideRightMenu();
//halo.darkComment(); //halo.darkComment();
} }
rm.copyUrl = function(id) { rm.copyUrl = function (id) {
$("body").after("<input id='copyVal'></input>"); $("body").after("<input id='copyVal'></input>");
var text = id; var text = id;
var input = document.getElementById("copyVal"); var input = document.getElementById("copyVal");
input.value = text; input.value = text;
input.select(); input.select();
input.setSelectionRange(0, input.value.length); input.setSelectionRange(0, input.value.length);
document.execCommand("copy"); document.execCommand("copy");
$("#copyVal").remove(); $("#copyVal").remove();
} }
function stopMaskScroll() { function stopMaskScroll() {
if (document.getElementById("rightmenu-mask")) { if (document.getElementById("rightmenu-mask")) {
let xscroll = document.getElementById("rightmenu-mask"); let xscroll = document.getElementById("rightmenu-mask");
xscroll.addEventListener("mousewheel", function(e) { xscroll.addEventListener("mousewheel", function (e) {
//阻止浏览器默认方法 //阻止浏览器默认方法
rm.hideRightMenu(); rm.hideRightMenu();
// e.preventDefault(); // e.preventDefault();
}, false); }, false);
} }
if (document.getElementById("rightMenu")) { if (document.getElementById("rightMenu")) {
let xscroll = document.getElementById("rightMenu"); let xscroll = document.getElementById("rightMenu");
xscroll.addEventListener("mousewheel", function(e) { xscroll.addEventListener("mousewheel", function (e) {
//阻止浏览器默认方法 //阻止浏览器默认方法
rm.hideRightMenu(); rm.hideRightMenu();
// e.preventDefault(); // e.preventDefault();
}, false); }, false);
} }
} }
rm.rightmenuCopyText = function(txt) { rm.rightmenuCopyText = function (txt) {
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard.writeText(txt); navigator.clipboard.writeText(txt);
} }
rm.hideRightMenu(); rm.hideRightMenu();
} }
rm.copyPageUrl = function() { rm.copyPageUrl = function () {
var url = window.location.href; var url = window.location.href;
rm.copyUrl(url); rm.copyUrl(url);
btf.snackbarShow('复制本页链接地址成功', false, 2000); btf.snackbarShow('复制本页链接地址成功', false, 2000);
rm.hideRightMenu(); rm.hideRightMenu();
} }
rm.sharePage = function() { rm.sharePage = function () {
var content = window.location.href; var content = window.location.href;
rm.copyUrl(url); rm.copyUrl(url);
btf.snackbarShow('复制本页链接地址成功', false, 2000); btf.snackbarShow('复制本页链接地址成功', false, 2000);
rm.hideRightMenu(); rm.hideRightMenu();
} }
// 复制当前选中文本 // 复制当前选中文本
@ -269,161 +267,160 @@ var selectTextNow = '';
document.onmouseup = document.ondbclick = selceText; document.onmouseup = document.ondbclick = selceText;
function selceText() { function selceText() {
var txt; var txt;
if (document.selection) { if (document.selection) {
txt = document.selection.createRange().text; txt = document.selection.createRange().text;
} else { } else {
txt = window.getSelection() + ''; txt = window.getSelection() + '';
} }
if (txt) { if (txt) {
selectTextNow = txt; selectTextNow = txt;
// console.log(selectTextNow); // console.log(selectTextNow);
} else { } else {
selectTextNow = ''; selectTextNow = '';
} }
} }
// 读取剪切板 // 读取剪切板
rm.readClipboard = function() { rm.readClipboard = function () {
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard.readText().then(clipText => rm.insertAtCaret(globalEvent.target, clipText)); navigator.clipboard.readText().then(clipText => rm.insertAtCaret(globalEvent.target, clipText));
} }
} }
// 粘贴文本到焦点 // 粘贴文本到焦点
rm.insertAtCaret = function(elemt, value) { rm.insertAtCaret = function (elemt, value) {
const startPos = elemt.selectionStart, const startPos = elemt.selectionStart,
endPos = elemt.selectionEnd; endPos = elemt.selectionEnd;
if (document.selection) { if (document.selection) {
elemt.focus(); elemt.focus();
var sel = document.selection.createRange(); var sel = document.selection.createRange();
sel.text = value; sel.text = value;
elemt.focus(); elemt.focus();
} else { } else {
if (startPos || startPos == '0') { if (startPos || startPos == '0') {
var scrollTop = elemt.scrollTop; var scrollTop = elemt.scrollTop;
elemt.value = elemt.value.substring(0, startPos) + value + elemt.value.substring(endPos, elemt.value elemt.value = elemt.value.substring(0, startPos) + value + elemt.value.substring(endPos, elemt.value.length);
.length); elemt.focus();
elemt.focus(); elemt.selectionStart = startPos + value.length;
elemt.selectionStart = startPos + value.length; elemt.selectionEnd = startPos + value.length;
elemt.selectionEnd = startPos + value.length; elemt.scrollTop = scrollTop;
elemt.scrollTop = scrollTop; } else {
} else { elemt.value += value;
elemt.value += value; elemt.focus();
elemt.focus(); }
} }
}
} }
//粘贴文本 //粘贴文本
rm.pasteText = function() { rm.pasteText = function () {
const result = rm.readClipboard() || ''; const result = rm.readClipboard() || '';
rm.hideRightMenu(); rm.hideRightMenu();
} }
//引用到评论 //引用到评论
rm.rightMenuCommentText = function(txt) { rm.rightMenuCommentText = function (txt) {
rm.hideRightMenu(); rm.hideRightMenu();
var input = document.getElementsByClassName(GLOBAL_CONFIG.source.comments.textarea)[0]; var input = document.getElementsByClassName(GLOBAL_CONFIG.source.comments.textarea)[0];
let evt = document.createEvent('HTMLEvents'); let evt = document.createEvent('HTMLEvents');
evt.initEvent('input', true, true); evt.initEvent('input', true, true);
let inputValue = replaceAll(txt, '\n', '\n> ') let inputValue = replaceAll(txt, '\n', '\n> ')
input.value = '> ' + inputValue + '\n\n'; input.value = '> ' + inputValue + '\n\n';
input.dispatchEvent(evt); input.dispatchEvent(evt);
var domTop = document.querySelector("#post-comment").offsetTop; var domTop = document.querySelector("#post-comment").offsetTop;
window.scrollTo(0, domTop - 80); window.scrollTo(0, domTop - 80);
input.focus(); input.focus();
input.setSelectionRange(-1, -1); input.setSelectionRange(-1, -1);
if (document.getElementById("comment-tips")) { if (document.getElementById("comment-tips")) {
document.getElementById("comment-tips").classList.add("show"); document.getElementById("comment-tips").classList.add("show");
} }
} }
//替换所有内容 //替换所有内容
function replaceAll(string, search, replace) { function replaceAll(string, search, replace) {
return string.split(search).join(replace); return string.split(search).join(replace);
} }
// 百度搜索 // 百度搜索
rm.searchBaidu = function() { rm.searchBaidu = function () {
btf.snackbarShow('即将跳转到百度搜索', false, 2000); btf.snackbarShow('即将跳转到百度搜索', false, 2000);
setTimeout(function() { setTimeout(function () {
window.open('https://www.baidu.com/s?wd=' + selectTextNow); window.open('https://www.baidu.com/s?wd=' + selectTextNow);
}, "2000"); }, "2000");
rm.hideRightMenu(); rm.hideRightMenu();
} }
//分享链接 //分享链接
rm.copyLink = function() { rm.copyLink = function () {
rm.rightmenuCopyText(domhref); rm.rightmenuCopyText(domhref);
btf.snackbarShow('已复制链接地址'); btf.snackbarShow('已复制链接地址');
} }
function addRightMenuClickEvent() { function addRightMenuClickEvent() {
// 添加点击事件 // 添加点击事件
$('#menu-backward').on('click', function() { $('#menu-backward').on('click', function () {
window.history.back(); window.history.back();
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('#menu-forward').on('click', function() { $('#menu-forward').on('click', function () {
window.history.forward(); window.history.forward();
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('#menu-refresh').on('click', function() { $('#menu-refresh').on('click', function () {
window.location.reload(); window.location.reload();
}); });
$('#menu-top').on('click', function() { $('#menu-top').on('click', function () {
btf.scrollToDest(0, 500); btf.scrollToDest(0, 500);
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('.menu-link').on('click', rm.hideRightMenu); $('.menu-link').on('click', rm.hideRightMenu);
$('#menu-darkmode').on('click', rm.switchDarkMode); $('#menu-darkmode').on('click', rm.switchDarkMode);
$('#menu-home').on('click', function() { $('#menu-home').on('click', function () {
window.location.href = window.location.origin; window.location.href = window.location.origin;
}); });
$('#menu-randomPost').on('click', function() { $('#menu-randomPost').on('click', function () {
toRandomPost() toRandomPost()
}); });
$('#menu-commentBarrage').on('click', heo.switchCommentBarrage); $('#menu-commentBarrage').on('click', heo.switchCommentBarrage);
$('#rightmenu-mask').on('click', rm.hideRightMenu); $('#rightmenu-mask').on('click', rm.hideRightMenu);
$('#rightmenu-mask').contextmenu(function() { $('#rightmenu-mask').contextmenu(function () {
rm.hideRightMenu(); rm.hideRightMenu();
return false; return false;
}); });
$('#menu-translate').on('click', function() { $('#menu-translate').on('click', function () {
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('#menu-copy').on('click', rm.copyPageUrl); $('#menu-copy').on('click', rm.copyPageUrl);
$('#menu-pastetext').on('click', rm.pasteText); $('#menu-pastetext').on('click', rm.pasteText);
$('#menu-copytext').on('click', function() { $('#menu-copytext').on('click', function () {
rm.rightmenuCopyText(selectTextNow); rm.rightmenuCopyText(selectTextNow);
btf.snackbarShow('复制成功,复制和转载请标注本文地址'); btf.snackbarShow('复制成功,复制和转载请标注本文地址');
}); });
$('#menu-commenttext').on('click', function() { $('#menu-commenttext').on('click', function () {
rm.rightMenuCommentText(selectTextNow); rm.rightMenuCommentText(selectTextNow);
}); });
$('#menu-newwindow').on('click', function() { $('#menu-newwindow').on('click', function () {
window.open(domhref); window.open(domhref);
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('#menu-copylink').on('click', rm.copyLink); $('#menu-copylink').on('click', rm.copyLink);
$('#menu-downloadimg').on('click', function() { $('#menu-downloadimg').on('click', function () {
heo.downloadImage(domImgSrc, 'hao'); heo.downloadImage(domImgSrc, 'hao');
}); });
$('#menu-newwindowimg').on('click', function() { $('#menu-newwindowimg').on('click', function () {
window.open(domImgSrc, "_blank"); window.open(domImgSrc, "_blank");
rm.hideRightMenu(); rm.hideRightMenu();
}); });
$('#menu-copyimg').on('click', function() { $('#menu-copyimg').on('click', function () {
rm.writeClipImg(domImgSrc); rm.writeClipImg(domImgSrc);
}); });
$('#menu-searchBaidu').on('click', rm.searchBaidu); $('#menu-searchBaidu').on('click', rm.searchBaidu);
//音乐 //音乐
$('#menu-music-toggle').on('click', heo.musicToggle); $('#menu-music-toggle').on('click', heo.musicToggle);
$('#menu-music-back').on('click', heo.musicSkipBack); $('#menu-music-back').on('click', heo.musicSkipBack);
$('#menu-music-forward').on('click', heo.musicSkipForward); $('#menu-music-forward').on('click', heo.musicSkipForward);
$('#menu-music-copyMusicName').on('click', function() { $('#menu-music-copyMusicName').on('click', function () {
rm.rightmenuCopyText(heo.musicGetName()); rm.rightmenuCopyText(heo.musicGetName());
btf.snackbarShow('复制歌曲名称成功', false, 3000); btf.snackbarShow('复制歌曲名称成功', false, 3000);
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@ -152,8 +152,6 @@
<script th:src="${assets_link + '/libs/pjax/pjax.min.js'}"></script> <script th:src="${assets_link + '/libs/pjax/pjax.min.js'}"></script>
<script th:src="${assets_link + '/libs/crypto/crypto-js.min.js'}"></script>
<!-- swiper 在瞬间滚动时会使用 --> <!-- swiper 在瞬间滚动时会使用 -->
<script th:if="${theme.config.top.moment}" data-pjax <script th:if="${theme.config.top.moment}" data-pjax
src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/6.6.2/swiper-bundle.min.js"></script> src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/6.6.2/swiper-bundle.min.js"></script>

View File

@ -58,6 +58,7 @@
power: { power: {
powerLink: [[${theme.config.sidebar.power.powerLink}]], powerLink: [[${theme.config.sidebar.power.powerLink}]],
url: [[${theme.config.sidebar.power.url}]], url: [[${theme.config.sidebar.power.url}]],
userId: [[${theme.config.sidebar.power.userId}]],
showNum: [[${theme.config.sidebar.power.showNum}]] showNum: [[${theme.config.sidebar.power.showNum}]]
}, },
links: { links: {

View File

@ -1,90 +1,84 @@
<div class="author-content" th:if="${theme.config.aboutReward.aboutRewardEnable}" <div class="author-content" th:if="${theme.config.aboutReward.aboutRewardEnable}"
xmlns:th="http://www.w3.org/1999/xhtml"> xmlns:th="http://www.w3.org/1999/xhtml">
<div class="author-content-item single reward" id="about-reward"> <div class="author-content-item single reward" id="about-reward">
<div class="author-content-item-tips">致谢</div> <div class="author-content-item-tips">致谢</div>
<span class="author-content-item-title">[[${theme.config.aboutReward.title}]]</span> <span class="author-content-item-title">[[${theme.config.aboutReward.title}]]</span>
<div class="author-content-item-description"> <div class="author-content-item-description">
[[${theme.config.aboutReward.content}]] [[${theme.config.aboutReward.content}]]
</div> </div>
<div th:if="${theme.config.aboutReward.reward.enable_reward}" class="about-reward"> <div th:if="${theme.config.aboutReward.reward.enable_reward}" class="about-reward">
<div id="con"></div> <div id="con"></div>
<div id="TA-con" onclick="heo.rewardShowConsole()"> <div id="TA-con" onclick="heo.rewardShowConsole()">
<div id="text-con"> <div id="text-con">
<div id="linght"></div> <div id="linght"></div>
<div id="TA">[[${theme.config.aboutReward.reward.name}]]</div> <div id="TA">[[${theme.config.aboutReward.reward.name}]]</div>
</div>
</div>
<div id="tube-con">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#e5e9ef" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#e5e9ef"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
<div id="mask">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#f25d8e" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#f25d8e" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#f25d8e"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
</div>
<div id="orange-mask">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#ffd52b" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#ffd52b" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#ffd52b"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
</div>
<p id="people"><b>[[${theme.config.aboutReward.reward_list.size()}]]</b></p>
</div>
</div>
<div class="reward-list-all" th:if="${not #lists.isEmpty(theme.config.aboutReward.reward_list)}"
th:with="authorRewardList = ${theme.config.aboutReward.reward_list}">
<div class="reward-list-item" th:each="authorReward : ${authorRewardList}">
<div th:if="${not #strings.isEmpty(authorReward.avatar)}">
<div class="reward-list-item-container">
<!-- 头像 -->
<div class="reward-list-item-avatar">
<img th:src="${authorReward.avatar}" th:alt="${authorReward.name}">
</div>
<div class="reward-list-item-content">
<!-- 名称 -->
<div style="z-index:20;float: left;" class="reward-list-item-avatar-group">
<div class="reward-list-item-name">[[${authorReward.name}]]</div>
</div>
<!-- 金额及时间 -->
<div class="reward-list-bottom-group">
<div th:if="${#conversions.convert(authorReward.amount, 'java.math.BigDecimal') < #conversions.convert(theme.config.aboutReward.rewardNumber, 'java.math.BigDecimal')}" class="reward-list-item-money">¥
[[${authorReward.amount}]]
</div>
<div th:if="${#conversions.convert(authorReward.amount, 'java.math.BigDecimal') >= #conversions.convert(theme.config.aboutReward.rewardNumber, 'java.math.BigDecimal')}" class="reward-list-item-money"
style="background: var(--heo-vip);">¥ [[${authorReward.amount}]]
</div>
<time class="datatime reward-list-item-time">[[${authorReward.datatime}]]</time>
</div>
</div>
</div>
</div> </div>
</div>
<div id="tube-con">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#e5e9ef" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#e5e9ef" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#e5e9ef"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#e5e9ef"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
<div id="mask">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#f25d8e" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#f25d8e" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#f25d8e" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#f25d8e"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#f25d8e"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
</div>
<div id="orange-mask">
<svg viewBox="0 0 1028 385" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 77H234.226L307.006 24H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 140H233.035L329.72 71H1028" stroke="#ffd52b" stroke-width="20"></path>
<path d="M1 255H234.226L307.006 307H790" stroke="#ffd52b" stroke-width="20"></path>
<path d="M0 305H233.035L329.72 375H1028" stroke="#ffd52b" stroke-width="20"></path>
<rect y="186" width="236" height="24" fill="#ffd52b"></rect>
<ellipse cx="790" cy="25.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 25)" fill="white"></circle>
<ellipse cx="790" cy="307.5" rx="25" ry="25.5" fill="#ffd52b"></ellipse>
<circle r="14" transform="matrix(1 0 0 -1 790 308)" fill="white"></circle>
</svg>
</div>
<p id="people"><b>[[${theme.config.aboutReward.reward_list.size()}]]</b></p>
</div>
</div>
<div class="reward-list-all" th:if="${not #lists.isEmpty(theme.config.aboutReward.reward_list)}"
th:with="authorRewardList = ${theme.config.aboutReward.reward_list}">
<div class="reward-list-item" th:each="authorReward : ${authorRewardList}">
<div th:if="${not #strings.isEmpty(authorReward.avatar)}">
<div>
<div class="reward-list-item-avatar">
<img th:src="${authorReward.avatar}" th:alt="${authorReward.name}">
</div>
<div style="z-index:20;float: left;" class="reward-list-item-avatar-group">
<div class="reward-list-item-name">[[${authorReward.name}]]</div>
</div>
</div>
<div class="reward-list-bottom-group">
<div th:if="${#conversions.convert(authorReward.amount, 'java.math.BigDecimal') < #conversions.convert(theme.config.aboutReward.rewardNumber, 'java.math.BigDecimal')}" class="reward-list-item-money">¥
[[${authorReward.amount}]]
</div>
<div th:if="${#conversions.convert(authorReward.amount, 'java.math.BigDecimal') >= #conversions.convert(theme.config.aboutReward.rewardNumber, 'java.math.BigDecimal')}" class="reward-list-item-money"
style="background: var(--heo-vip);">¥ [[${authorReward.amount}]]
</div>
<time class="datatime reward-list-item-time">[[${authorReward.datatime}]]</time>
</div>
</div>
<div th:if="${#strings.isEmpty(authorReward.avatar)}"> <div th:if="${#strings.isEmpty(authorReward.avatar)}">
<div class="reward-list-item-name">[[${authorReward.name}]]</div> <div class="reward-list-item-name">[[${authorReward.name}]]</div>
<div class="reward-list-bottom-group"> <div class="reward-list-bottom-group">

View File

@ -1,180 +1,187 @@
<!-- 数据统计&作者相关信息 --> <!-- 数据统计&作者相关信息 -->
<div class="author-content"> <div class="author-content">
<div class="about-statistic author-content-item" <div class="about-statistic author-content-item"
style="background: url(https://bu.dusays.com/2023/03/12/640dc8c72f623.webp);"> style="background: url(https://bu.dusays.com/2023/03/12/640dc8c72f623.webp);">
<div class="card-content"> <div class="card-content">
<div class="author-content-item-tips">数据</div> <div class="author-content-item-tips">数据</div>
<span class="author-content-item-title">访问统计</span> <span class="author-content-item-title">访问统计</span>
<div id="statistic"></div> <div id="statistic"></div>
<div class="post-tips">统计信息来自 <a href="https://v6.51.la/" rel="noopener nofollow" <div class="post-tips">统计信息来自 <a href="https://invite.51.la/1NzKqTeb?target=V6"
target="_blank">51la网站统计</a></div> rel="noopener nofollow"
<div class="banner-button-group"> target="_blank">51la网站统计</a></div>
<a class="banner-button" onclick="pjax.loadUrl('/archives')" data-pjax-state=""> <div class="banner-button-group">
<i class="haofont hao-icon-circle-arrow-up-right-1"></i> <a class="banner-button" onclick="pjax.loadUrl('/archives')" data-pjax-state="">
<span class="banner-button-text">文章隧道</span> <i class="haofont hao-icon-circle-arrow-up-right-1"></i>
</a> <span class="banner-button-text">文章隧道</span>
</div> </a>
</div> </div>
</div> </div>
</div>
<div class="author-content-item-group column mapAndInfo"> <div class="author-content-item-group column mapAndInfo">
<div class="author-content-item map single"> <div class="author-content-item map single">
<span class="map-title">我现在住在 <span class="map-title">我现在住在
<b>[[${theme.config.about.map.StrengthenTitle}]]</b> <b>[[${theme.config.about.map.StrengthenTitle}]]</b>
</span> </span>
</div> </div>
<div class="author-content-item selfInfo single" <div class="author-content-item selfInfo single"
th:if="${not #lists.isEmpty(theme.config.about.map.authorInfo)}" th:if="${not #lists.isEmpty(theme.config.about.map.authorInfo)}"
th:with="texts = ${theme.config.about.map.authorInfo}"> th:with="texts = ${theme.config.about.map.authorInfo}">
<div th:if="${theme.config.about.map.authorInfo.size()}>'0'"> <div th:if="${theme.config.about.map.authorInfo.size()}>'0'">
<span class="selfInfo-title" th:text="${texts[0].authorInfoTitle}">生于</span><span <span class="selfInfo-title"
class="selfInfo-content" id="selfInfo-content-year" th:text="${texts[0].authorInfoTitle}">生于</span><span
th:style="'color:' + ${texts[0].authorInfoColor}" class="selfInfo-content"
th:text="${texts[0].authorInfoContent}">2000</span> id="selfInfo-content-year" th:style="'color:' + ${texts[0].authorInfoColor}"
</div> th:text="${texts[0].authorInfoContent}">2000</span>
<div th:if="${theme.config.about.map.authorInfo.size()}>'1'"> </div>
<span class="selfInfo-title" th:text="${texts[1].authorInfoTitle}">太原理工大学</span><span <div th:if="${theme.config.about.map.authorInfo.size()}>'1'">
class="selfInfo-content" th:style="'color:' + ${texts[1].authorInfoColor}" <span class="selfInfo-title"
th:text="${texts[1].authorInfoContent}">计算机科学</span> th:text="${texts[1].authorInfoTitle}">太原理工大学</span><span
</div> class="selfInfo-content"
<div th:if="${theme.config.about.map.authorInfo.size()}>'2'"> th:style="'color:' + ${texts[1].authorInfoColor}"
<span class="selfInfo-title" th:text="${texts[2].authorInfoTitle}">现在职业</span><span th:text="${texts[1].authorInfoContent}">计算机科学</span>
class="selfInfo-content" th:style="'color:' + ${texts[2].authorInfoColor}" </div>
th:text="${texts[2].authorInfoContent}">BI工程师</span> <div th:if="${theme.config.about.map.authorInfo.size()}>'2'">
</div> <span class="selfInfo-title"
</div> th:text="${texts[2].authorInfoTitle}">现在职业</span><span
</div> class="selfInfo-content"
<style> th:style="'color:' + ${texts[2].authorInfoColor}"
.author-content-item.map { th:text="${texts[2].authorInfoContent}">BI工程师</span>
background: url([[${theme.config.about.map.background}]]) no-repeat center; </div>
min-height: 160px; </div>
max-height: 400px; </div>
position: relative; <style>
overflow: hidden; .author-content-item.map {
margin-bottom: 0.5rem; background: url([[${theme.config.about.map.background}]]) no-repeat center;
height: 60%; min-height: 160px;
background-size: 100%; max-height: 400px;
transition: 1s ease-in-out; position: relative;
} overflow: hidden;
margin-bottom: 0.5rem;
height: 60%;
background-size: 100%;
transition: 1s ease-in-out;
}
[data-theme=dark] .author-content-item.map { [data-theme=dark] .author-content-item.map {
background: url([[${theme.config.about.map.backgroundDark}]]) no-repeat center; background: url([[${theme.config.about.map.backgroundDark}]]) no-repeat center;
background-size: 100%; background-size: 100%;
} }
.author-content-item.map:hover { .author-content-item.map:hover {
background-size: 120%; background-size: 120%;
transition: 4s ease-in-out; transition: 4s ease-in-out;
background-position-x: 0; background-position-x: 0;
background-position-y: 36%; background-position-y: 36%;
} }
.author-content-item.map .map-title { .author-content-item.map .map-title {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
left: 0px; left: 0px;
width: 100%; width: 100%;
background: var(--heo-maskbg); background: var(--heo-maskbg);
padding: 0.5rem 2rem; padding: 0.5rem 2rem;
backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
transition: 1s ease-in-out; transition: 1s ease-in-out;
font-size: 20px; font-size: 20px;
border-radius: 0 0 1rem 1rem; border-radius: 0 0 1rem 1rem;
} }
.author-content-item.map:hover .map-title { .author-content-item.map:hover .map-title {
bottom: -100%; bottom: -100%;
border-radius: 0 0 1rem 1rem; border-radius: 0 0 1rem 1rem;
} }
.author-content-item.map .map-title b { .author-content-item.map .map-title b {
color: var(--heo-fontcolor); color: var(--heo-fontcolor);
} }
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
.author-content-item.map.myphoto { .author-content-item.map.myphoto {
background-size: cover !important; background-size: cover !important;
} }
.author-content-item.map .map-title { .author-content-item.map .map-title {
padding: 1rem; padding: 1rem;
} }
} }
</style> </style>
<!-- 关于统计--> <!-- 关于统计-->
<script defer> <script defer>
// 链接替换即可,不需要后面的参数 // 链接替换即可,不需要后面的参数
function initAboutPage() { function initAboutPage() {
fetch("https://v6-widget.51.la/v6/[[${theme.config.about.LingQueMonitorID}]]/quote.js") fetch("https://v6-widget.51.la/v6/[[${theme.config.about.LingQueMonitorID}]]/quote.js")
.then(res => res.text()) .then(res => res.text())
.then(data => { .then(data => {
let title = ["最近活跃", "今日人数", "今日访问", "昨日人数", "昨日访问", "本月访问", "总访问量"]; let title = ["最近活跃", "今日人数", "今日访问", "昨日人数", "昨日访问", "本月访问", "总访问量"];
// let num = data.match(/(?<=<\/span><span>).*?(?=<\/span><\/p>)/g) // let num = data.match(/(?<=<\/span><span>).*?(?=<\/span><\/p>)/g)
let num = data.match(/(<\/span><span>).*?(\/span><\/p>)/g); let num = data.match(/(<\/span><span>).*?(\/span><\/p>)/g);
num = num.map(el => { num = num.map(el => {
let val = el.replace(/(<\/span><span>)/g, ""); let val = el.replace(/(<\/span><span>)/g, "");
let str = val.replace(/(<\/span><\/p>)/g, ""); let str = val.replace(/(<\/span><\/p>)/g, "");
return str; return str;
}); });
let statisticEl = document.getElementById("statistic"); let statisticEl = document.getElementById("statistic");
// 自定义不显示哪个或者显示哪个,如下为不显示 最近活跃访客 和 总访问量 // 自定义不显示哪个或者显示哪个,如下为不显示 最近活跃访客 和 总访问量
let statistic = []; let statistic = [];
for (let i = 0; i < num.length; i++) { for (let i = 0; i < num.length; i++) {
if (!statisticEl) return; if (!statisticEl) return;
if (i == 0) continue; if (i == 0) continue;
statisticEl.innerHTML += statisticEl.innerHTML +=
"<div><span>" + title[i] + "</span><span id=" + title[i] + ">" + num[i] + "</span></div>"; "<div><span>" + title[i] + "</span><span id=" + title[i] + ">" + num[i] + "</span></div>";
queueMicrotask(() => { queueMicrotask(() => {
statistic.push( statistic.push(
new CountUp(title[i], 0, num[i], 0, 2, { new CountUp(title[i], 0, num[i], 0, 2, {
useEasing: true, useEasing: true,
useGrouping: true, useGrouping: true,
separator: ",", separator: ",",
decimal: ".", decimal: ".",
prefix: "", prefix: "",
suffix: "", suffix: "",
}) })
); );
}); });
} }
let statisticElement = document.querySelector(".about-statistic.author-content-item"); let statisticElement = document.querySelector(".about-statistic.author-content-item");
function statisticUP() { function statisticUP() {
if (!statisticElement) return; if (!statisticElement) return;
const callback = (entries, observer) => { const callback = (entries, observer) => {
entries.forEach(entry => { entries.forEach(entry => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
for (let i = 0; i < num.length; i++) { for (let i = 0; i < num.length; i++) {
if (i == 0) continue; if (i == 0) continue;
queueMicrotask(() => { queueMicrotask(() => {
statistic[i - 1].start(); statistic[i - 1].start();
}); });
} }
observer.disconnect(); // 停止观察元素,因为不再需要触发此回调 observer.disconnect(); // 停止观察元素,因为不再需要触发此回调
} }
}); });
}; };
const options = { const options = {
root: null, root: null,
rootMargin: "0px", rootMargin: "0px",
threshold: 0 threshold: 0
}; };
const observer = new IntersectionObserver(callback, options); const observer = new IntersectionObserver(callback, options);
observer.observe(statisticElement); observer.observe(statisticElement);
} }
statisticUP() statisticUP()
}); });
} }
initAboutPage(); initAboutPage();
</script>
</script>
</div> </div>

View File

@ -1,24 +1,25 @@
<!-- 广告 --> <!-- 广告 -->
<div class="card-widget" th:if="${theme.config.sidebar.adbox.adType=='google'}"> <div class="card-widget" th:if="${theme.config.sidebar.adbox.adType=='google'}">
<div class="item-headline"><span>广告</span></div> <div class="item-headline"><span>广告</span></div>
<script async th:src="${'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' + theme.config.sidebar.adbox.ad_google.ad_client}"
<script async crossorigin="anonymous"></script>
th:src="${'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=' + theme.config.sidebar.adbox.ad_google.ad_client}" <!-- 广告2 -->
crossorigin="anonymous"></script> <ins class="adsbygoogle"
<!-- 广告2 --> style="display:block"
<ins class="adsbygoogle" style="display:block" th:data-ad-client="${theme.config.sidebar.adbox.ad_google.ad_client}" th:data-ad-client="${theme.config.sidebar.adbox.ad_google.ad_client}"
th:data-ad-slot="${theme.config.sidebar.adbox.ad_google.ad_slot}" th:data-ad-slot="${theme.config.sidebar.adbox.ad_google.ad_slot}"
th:data-ad-format="${theme.config.sidebar.adbox.ad_google.ad_format}" th:data-ad-format="${theme.config.sidebar.adbox.ad_google.ad_format}"
th:data-full-width-responsive="${theme.config.sidebar.adbox.ad_google.full_width_responsive}"></ins> th:data-full-width-responsive="${theme.config.sidebar.adbox.ad_google.full_width_responsive}"></ins>
<script> <script>
(adsbygoogle = window.adsbygoogle || []).push({}); (adsbygoogle = window.adsbygoogle || []).push({});
</script> </script>
</div> </div>
<div class="card-widget card-ad" th:if="${theme.config.sidebar.adbox.adType=='customAd'}"> <div class="card-widget" th:if="${theme.config.sidebar.adbox.adType=='customAd'}">
<div class="item-headline"><i class="haofont hao-icon-fire"></i><span>广告</span></div> <div class="item-headline"><span>广告</span></div>
<a th:href="${theme.config.sidebar.adbox.ad_custom.ad_redirect_url}" target="_blank" title="立即前往"> <a th:href="${theme.config.sidebar.adbox.ad_custom.ad_redirect_url}" target="_blank">
<img class="ad-img" th:src="${theme.config.sidebar.adbox.ad_custom.ad_pic_url}" alt="自定义广告"> <img th:src="${theme.config.sidebar.adbox.ad_custom.ad_pic_url}" alt="自定义广告">
</a> </a>
</div> </div>

View File

@ -1,5 +1,5 @@
<!-- 最新评论 --> <!-- 最新评论 -->
<div class="card-widget card-recent-post card-comment" > <div class="card-widget card-recent-post" >
<a th:if="${not #strings.isEmpty(theme.config.sidebar.newcomment.newcommentUrl)}" <a th:if="${not #strings.isEmpty(theme.config.sidebar.newcomment.newcommentUrl)}"
th:onclick="pjax.loadUrl([[${theme.config.sidebar.newcomment.newcommentUrl}]])" th:onclick="pjax.loadUrl([[${theme.config.sidebar.newcomment.newcommentUrl}]])"
title="查看更多" title="查看更多"

View File

@ -1,11 +1,11 @@
<!-- 爱发电赞助 --> <!-- 爱发电赞助 -->
<div> <div>
<div class="card-widget card-power"> <div class="card-widget card-power">
<div class="item-headline"><i class="haofont hao-icon-aifadian-line"></i><span>爱发电</span> <div class="item-headline"><i class="haofont hao-icon-aifadian-line"></i><span>爱发电赞助</span>
<a class="power-charge" th:href="${theme.config.sidebar.power.powerLink}" target="_blank" title="赞助博主">赞助 <a class="power-charge" th:href="${theme.config.sidebar.power.powerLink}" target="_blank" title="赞助博主">赞助
</a> </a>
</div> </div>
<a id="power-star" rel="external nofollow" target="_blank" title="感谢赞助博主"> <a id="power-star" rel="external nofollow" target="_blank" title="推荐博主">
</a> </a>
<div class="power-list"> <div class="power-list">

View File

@ -1,4 +1,4 @@
<div class="card-widget card-recent-post card-article" th:with='posts = ${postFinder.list(1,theme.config.sidebar.recentPost)}, <div class="card-widget card-recent-post" th:with='posts = ${postFinder.list(1,theme.config.sidebar.recentPost)},
postRandomImg=${#strings.contains(theme.config.layout.postRandomImg,"?") ? theme.config.layout.postRandomImg+"&" : theme.config.layout.postRandomImg+"?"}'> postRandomImg=${#strings.contains(theme.config.layout.postRandomImg,"?") ? theme.config.layout.postRandomImg+"&" : theme.config.layout.postRandomImg+"?"}'>
<div class="item-headline"><i class="haofont hao-icon-eicon_map-2-line1"></i><span>最近发布</span></div> <div class="item-headline"><i class="haofont hao-icon-eicon_map-2-line1"></i><span>最近发布</span></div>
<div class="aside-list"> <div class="aside-list">

View File

@ -1,5 +1,5 @@
<!-- 目录 --> <!-- 目录 -->
<div class="card-widget card-toc" id="card-toc"> <div class="card-widget" id="card-toc">
<div class="item-headline"> <div class="item-headline">
<i class="haofont hao-icon-bars"></i> <i class="haofont hao-icon-bars"></i>
<span>文章目录</span> <span>文章目录</span>

View File

@ -1,81 +1,81 @@
<!-- 导航栏菜单栏 --> <!-- 导航栏菜单栏 -->
<div id="nav-right"> <div id="nav-right">
<!-- 功能都需要添加开关 --> <!-- 功能都需要添加开关 -->
<!-- 随机前往一个开往项目网站 --> <!-- 随机前往一个开往项目网站 -->
<div class="nav-button only-home" id="travellings_button" title="随机前往一个开往项目网站" <div class="nav-button only-home" id="travellings_button" title="随机前往一个开往项目网站" th:if="${theme.config.nav.right.travelling}">
th:if="${theme.config.nav.right.travelling}"> <a class="site-page" href="https://www.travellings.cn/go.html" rel="external nofollow"
<a class="site-page" href="https://www.travellings.cn/go.html" rel="external nofollow" title="随机前往一个开往项目网站"> title="随机前往一个开往项目网站">
<i class="haofont hao-icon-eicon_train-line"></i> <i class="haofont hao-icon-eicon_train-line"></i>
</a> </a>
</div> </div>
<div class="nav-button" id="randomPost_button" th:if="${theme.config.nav.right.article}"> <div class="nav-button" id="randomPost_button" th:if="${theme.config.nav.right.article}">
<a class="site-page" href="javascript:void(0);" onclick="toRandomPost()" title="随机文章"> <a class="site-page" href="javascript:void(0);" onclick="toRandomPost()" title="随机文章">
<i class="haofont hao-icon-signal-tower-fill"></i> <i class="haofont hao-icon-signal-tower-fill"></i>
</a> </a>
</div> </div>
<!-- 切换模式 --> <!-- 切换模式 -->
<div class="nav-button" id="darkmode_button" th:if="${theme.config.nav.right.darkMode}"> <div class="nav-button" id="darkmode_button" th:if="${theme.config.nav.right.darkMode}">
<a class="console_switchbutton" href="javascript:void(0);" onclick="navFn.switchDarkMode();" <a class="console_switchbutton" href="javascript:void(0);" onclick="navFn.switchDarkMode();" rel="external nofollow"
rel="external nofollow" title="切换模式 - 日夜交替,黑白互换。"> title="切换模式 - 日夜交替,黑白互换。">
<i class="haofont hao-icon-moon-clear-fill" style="font-size: 1rem;"></i> <i class="haofont hao-icon-moon-clear-fill" style="font-size: 1rem;"></i>
</a> </a>
</div> </div>
<!-- 搜索使用搜索插件 --> <!-- 搜索使用搜索插件 -->
<div class="nav-button" id="search-button" th:if="${pluginFinder.available('PluginSearchWidget')}"> <div class="nav-button" id="search-button" th:if="${pluginFinder.available('PluginSearchWidget')}">
<a class="site-page social-icon search" href="javascript:SearchWidget.open();" rel="external nofollow" <a class="site-page social-icon search" href="javascript:SearchWidget.open();" rel="external nofollow"
title="站内搜索"> title="站内搜索">
<i class="haofont hao-icon-search--line"></i> <i class="haofont hao-icon-search--line"></i>
</a> </a>
</div> </div>
<div th:if="${theme.config.nav.right.navLogin}" class="console-button" tabindex="-1" <div th:if="${theme.config.nav.right.navLogin}" class="console-button" tabindex="-1"
th:with="currentUser = ${contributorFinder.getContributor(#authentication.name)}"> th:with="currentUser = ${contributorFinder.getContributor(#authentication.name)}">
<span class="site-page nav-login"> <span class="site-page nav-login">
<i sec:authorize="isAnonymous()" class="haofont hao-icon-zhanghao1 " style="font-size: 19.5px;"></i> <i sec:authorize="isAnonymous()" class="haofont hao-icon-zhanghao1 " style="font-size: 19.5px;"></i>
<img sec:authorize="isAuthenticated()" th:src="${currentUser.avatar}" th:alt="${currentUser.displayName}" <img sec:authorize="isAuthenticated()" th:src="${currentUser.avatar}"
style=" width: 24px; height: 24px; border-radius: 9999px" /> th:alt="${currentUser.displayName}"
</span> style=" width: 24px; height: 24px; border-radius: 9999px" />
<div class="back-menu-list-groups"> </span>
<div class="back-menu-list-group" style="margin: -4px -9px -4px -18px"> <div class="back-menu-list-groups">
<div class="back-menu-list"> <div class="back-menu-list-group" style="margin: -4px -9px -4px -18px">
<th:block sec:authorize="isAuthenticated()"> <div class="back-menu-list">
<a class="back-menu-item" rel="external nofollow" target="_blank" href="/console"> <th:block sec:authorize="isAuthenticated()">
<span class="back-menu-item-text">控制台</span> <a class="back-menu-item" rel="external nofollow" target="_blank" href="/console">
</a> <span class="back-menu-item-text">控制台</span>
<a class="back-menu-item" rel="external nofollow" </a>
href="javascript:$.ajax({type: 'post',url:'/logout',headers:{'X-Xsrf-Token':document.cookie.split('; ').find((row) => row.startsWith('XSRF-TOKEN'))?.split('=')[1] || ''},success: function() {window.location.reload();},error: function(xhr, status, error) {console.error('退出登录时发生错误:', error);}});"> <a class="back-menu-item" rel="external nofollow"
<span class="back-menu-item-text">退出登录</span> href="javascript:$.ajax({type: 'post',url:'/logout'});window.location.reload()">
</a> <span class="back-menu-item-text">退出登录</span>
</th:block> </a>
<a sec:authorize="isAnonymous()" class="back-menu-item" rel="external nofollow" target="_blank" </th:block>
href="/console/login"> <a sec:authorize="isAnonymous()" class="back-menu-item" rel="external nofollow" target="_blank" href="/console/login">
<span class="back-menu-item-text">登录</span> <span class="back-menu-item-text">登录</span>
</a> </a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div th:if="${theme.config.nav.right.console.consoleEnable}" class="nav-button" id="nav-console"> <div th:if="${theme.config.nav.right.console.consoleEnable}" class="nav-button" id="nav-console">
<a class="console_switchbutton" href="javascript:void(0);" onclick="heo.showConsole()" rel="external nofollow" <a class="console_switchbutton" href="javascript:void(0);" onclick="heo.showConsole()" rel="external nofollow"
title="显示中控台"> title="显示中控台">
<i class="haofont hao-icon-dashboard"></i> <i class="haofont hao-icon-dashboard"></i>
</a> </a>
</div> </div>
<div class="nav-button" id="nav-totop" onclick="btf.scrollToDest(0,500)"> <div class="nav-button" id="nav-totop" onclick="btf.scrollToDest(0,500)">
<a class="totopbtn"> <a class="totopbtn">
<i class="haofont hao-icon-arrow-up" style="font-size: 1rem;"></i><span id="percent">0</span> <i class="haofont hao-icon-arrow-up" style="font-size: 1rem;"></i><span id="percent">0</span>
</a> </a>
</div> </div>
<div id="toggle-menu"> <div id="toggle-menu">
<a class="site-page"> <a class="site-page">
<i class="haofont hao-icon-bars"></i> <i class="haofont hao-icon-bars"></i>
</a> </a>
</div> </div>
</div> </div>

View File

@ -48,8 +48,8 @@ spec:
description: Halo 2.x Theme base on Thymeleaf, Referring to Butterfly and Heo description: Halo 2.x Theme base on Thymeleaf, Referring to Butterfly and Heo
logo: /themes/theme-hao/assets/images/hao-logo.jpg logo: /themes/theme-hao/assets/images/hao-logo.jpg
website: https://blog.uptoz.cn website: https://blog.uptoz.cn
repo: https://gitea.uptoz.cn/UPToZ/halo-theme-hao repo: https://githubfast.com/liuzhihang/halo-theme-hao
settingName: "theme-hao-setting" settingName: "theme-hao-setting"
configMapName: "theme-hao-configMap" configMapName: "theme-hao-configMap"
version: "1.0.2-ce" version: "1.4.9-CommemorativeEdition"
require: ">=2.10.0" require: ">=2.10.0"