Add solitude

This commit is contained in:
IF-chan
2024-07-05 21:01:19 +08:00
parent 26d71c4fbc
commit 71758b9fce
289 changed files with 23277 additions and 0 deletions
@@ -0,0 +1,13 @@
- const authorinfo = site.data.about.authorinfo
if authorinfo
.author-info
.author-tag-left
each tag in authorinfo.leftTags
span.author-tag= tag
.author-img
img(src=authorinfo.image)
.author-tag-right
each tag in authorinfo.rightTags
span.author-tag= tag
.author-title= site.data.about.title
@@ -0,0 +1,39 @@
- award = site.data.about.award
- var sum = 0
if site.data.about.rewardList
.author-content
.author-content-item.single.reward
.author-content-item-tips= _p('award.thanks')
span.author-content-item-title= _p('award.title')
.author-content-item-description
!= award.description
.reward-list-all
each reward in site.data.about.rewardList
- sum += reward.money
.reward-list-item
.reward-list-item-name= reward.name
.reward-list-bottom-group
.reward-list-item-money(style=(reward.vip ? "background: var(--efu-vip);color: var(--efu-white)" : ""))
if reward.icon
i.solitude(class=reward.icon)
| ¥ #{reward.money}
time.datatime.reward-list-item-time(datetime=moment(reward.time).format())
if theme.post.award.enable
.post-reward
.post-reward(onclick="AddRewardMask()")
.reward-button(title=_p('award.tipping'))
i.solitude.st-hand-heart-fill
= _p('award.tipping')
.reward-main
ul.reward-all
span.reward-title= theme.post.award.title
ul.reward-group
- var rewards = theme.post.award.list
each reward in rewards
li.reward-item
a(href=url_for(reward.url))
img.post-qr-code-img(alt=reward.name, src=reward.qcode, style="border-color:" + reward.color)
.post-qr-code-desc= reward.name
.reward-list-tips
p= award.tips.replace('{sum}', sum.toFixed(2))
@@ -0,0 +1,39 @@
- const contentinfo = site.data.about.contentinfo
if contentinfo
.author-content
.author-content-item.myInfoAndSayHello
.title1= contentinfo.sup
.title2
span.inline-word= contentinfo.name
.title1= contentinfo.title
.aboutsiteTips.author-content-item
.author-content-item-tips= contentinfo.tip
h2
span.inline-word!= contentinfo.slogan
.mask
each item,index in contentinfo.mask
if index === 0
span.first-tips(data-show='')= item
else if index === contentinfo.mask.length - 1
span(data-up='')= item
else
span= item
script.
var pursuitInterval = null;
pursuitInterval = setInterval(function () {
const show = document.querySelector('span[data-show]')
const next = show.nextElementSibling || document.querySelector('.first-tips')
const up = document.querySelector('span[data-up]')
if (up) {
up.removeAttribute('data-up')
}
show.removeAttribute('data-show')
show.setAttribute('data-up', '')
next.setAttribute('data-show', '')
}, 2000)
document.addEventListener('pjax:send', function () {
clearInterval(pursuitInterval);
});
@@ -0,0 +1,37 @@
- var game1 = site.data.about.game1
- var game2 = site.data.about.game2
if game1 || game2
.author-content
if game1
.author-content-item.game-apex(style=`background: url(${game1.img}) no-repeat top; background-size: cover;`)
.card-content
.author-content-item-tips= game1.title
span.author-content-item-title= game1.subtitle
.content-bottom
.tips= game1.tips_left
.tips= game1.tips_right
if game2
.author-content-item.game-jl(style=`background: url(${game2.img}) no-repeat top; background-size: cover;`)
.card-content
.author-content-item-tips= game2.title
span.author-content-item-title= game2.subtitle
.content-bottom
.tips= game2.tips_left
.tips= game2.tips_right
if site.data.about.likes
- const likes = site.data.about.likes
.author-content
each like in likes
.author-content-item(class=like.type, style=`background: url(${like.bg}) no-repeat center;`)
.card-content
.author-content-item-tips= like.tips
span.author-content-item-title= like.title
.content-bottom
.tips= like.subtips
if like.button
.banner-button-group
a.banner-button(href=url_for(like.button_link))
i.solitude.st-right-btn-fill
span.banner-button-text= like.button_text
@@ -0,0 +1,22 @@
- const motto = site.data.about.motto
- const expertise = site.data.about.expertise
if motto || expertise
.author-content
if motto
.author-content-item.maxim
.author-content-item-tips= motto.title
span.maxim-title
span= motto.prefix
span= motto.content
if expertise
.author-content-item.buff
.card-content
.author-content-item-tips= expertise.title
span.buff-title
span
| #{expertise.prefix}
span.inline-word= expertise.specialist
span
| #{expertise.content}
span.inline-word= expertise.level
@@ -0,0 +1,89 @@
- var tj = site.data.about.tj
- var oneself = site.data.about.oneself
if tj || oneself
.author-content
if tj
.about-statistic.author-content-item(style=`background: url(${tj.img});`)
.card-content
.author-content-item-tips=_p('about.other.tj.tip')
span.author-content-item-title=_p('about.other.tj.title')
#statistic
.post-tips
= _p('about.other.tj.post_tip')
case tj.provider
when '51la'
a(href="https://v6.51.la/") 51la网站统计
when 'baidu'
a(href="https://tongji.baidu.com/") 百度统计
if tj.button
.banner-button-group
a.banner-button(href=url_for(tj.button_link))
i.solitude.st-right-btn-fill
span.banner-button-text= tj.button_text
case tj.provider
when '51la'
script.
fetch("#{tj.url}")
.then(res => res.text())
.then(data => {
const title = ["最近活跃", "今日人数", "今日访问", "昨日人数", "昨日访问", "本月访问", "总访问量"];
let num = data.match(/(<\/span><span>).*?(\/span><\/p>)/g);
num = num.map(el => {
let val = el.replace(/(<\/span><span>)/g, "");
return val.replace(/(<\/span><\/p>)/g, "");
});
const s = document.getElementById("statistic");
let html = '';
for (let i = 0; i < num.length; i++) {
if (i === 0 || i === num.length - 1) continue;
html += `<div><span>${title[i]}</span><span id="${title[i]}">${num[i]}</span></div>`;
}
s.innerHTML = html;
});
when 'baidu'
script.
fetch("#{tj.url}")
.then(res => res.json())
.then(data => {
const title = {"today_uv": "今日人数", "today_pv": "今日访问", "yesterday_uv": "昨日人数", "yesterday_pv": "昨日访问", "last_month_pv": "最近月访问", "last_year_pv": "最近年访问"};
let s = document.getElementById("statistic");
for (let key in data) {
if (data.hasOwnProperty(key) && title[key]) {
s.innerHTML += `<div><span>${title[key]}</span><span id="${key}">${data[key]}</span></div>`;
}
}
});
if oneself
style.
:root {
--site-about-oneself-map--light: url(#{oneself.map.light});
--site-about-oneself-map--dark: url(#{oneself.map.dark});
}
.author-content-item-group.column.mapAndInfo
.author-content-item.map.single
span.map-title=_p('about.other.oneself.map_title') + oneself.location
.author-content-item.selfInfo.single
div
span.selfInfo-title=_p('about.other.oneself.info_title1')
span.selfInfo-content(style="color: #43a6c6;")= oneself.birthYear
div
span.selfInfo-title= oneself.university
span.selfInfo-content(style="color: #c69043;")= oneself.major
div
span.selfInfo-title=_p('about.other.oneself.info_title2')
span.selfInfo-content(style="color: #b04fe6;")= oneself.occupation
- var cause = site.data.about.cause
if cause
.author-content
.create-site-post.author-content-item.single
.author-content-item-tips= cause.tip
span.author-content-item-title= cause.title
!= cause.content
@@ -0,0 +1,17 @@
- const personalities = site.data.about.personalities
if personalities
.author-content
.author-content-item.personalities
.author-content-item-tips= personalities.tips
span.author-content-item-title= personalities.title
.title2(style=`color:${personalities.color}`)= personalities.type
.image
img.nolazyload(src=personalities.image)
.post-tips
= _p('about.personalities.tip1') + ' '
a(href='https://www.16personalities.com/')= personalities.linkText + ' '
= _p('about.personalities.tip2') + ' '
a(href=personalities.typeLink)= personalities.typeName
.author-content-item.myphoto
img.author-content-img(src=personalities.myphoto, alt="my photo")
@@ -0,0 +1,42 @@
- var skills = site.data.about.skills
- var careers = site.data.about.careers
if skills || careers
.author-content
if skills
.author-content-item.skills
.card-content
.author-content-item-tips= skills.title
span.author-content-item-title= skills.subtitle
.skills-style-group
.tags-group-all
.tags-group-wrapper
each i in [1,2]
- var pair = []
each tag, index in skills.tags
- pair.push(tag)
if pair.length === 2 || index === skills.tags.length - 1
.tags-group-icon-pair
each item in pair
.tags-group-icon(style=`background:${item.color}`)
img(src=item.icon, title=item.title)
- pair = []
.skills-list
each tag in skills.tags
.skill-info
.skill-icon(style=`background:${tag.color}`)
img(src=tag.icon, title=tag.title)
.skill-name
span= tag.title
.etc ...
if careers
.author-content-item.careers
.card-content
.author-content-item-tips= careers.title
span.author-content-item-title= careers.subtitle
.careers-group
each item in careers.items
.careers-item
.circle(style=`background:${item.color}`)
.name= `${item.school}, ${item.major}`
img.author-content-img(src=careers.image, alt=careers.title)
@@ -0,0 +1,48 @@
- var tenyear = site.data.about.tenyear
if tenyear
.author-content#tenyear
.create-site-post.author-content-item.single
.author-content-item-tips=tenyear.tips
.author-content-item-title=tenyear.title
p=tenyear.text
.tenyear-timeline
.progress
.past-time
.percentage-label
.time-labels
.start-time#tenyear-start-time= tenyear.start
.end-time#tenyear-end-time= tenyear.end
script.
function parseDateString(e) {
return e.replace(/年|月/g, '-').replace(/日/g, '');
}
function tenYear() {
let progressElement = document.querySelector(".progress");
let pastTimeElement = document.querySelector(".past-time");
let percentageLabelElement = document.querySelector(".percentage-label");
let startTimeElement = document.getElementById("tenyear-start-time");
let endTimeElement = document.getElementById("tenyear-end-time");
let startTime = new Date(parseDateString(startTimeElement.textContent)).getTime();
let endTime = new Date(parseDateString(endTimeElement.textContent)).getTime();
function updateProgress() {
let currentTime = new Date().getTime();
let progress = ((currentTime - startTime) / (endTime - startTime) * 100);
let progressPercentage = progress <= 100 ? progress + "%" : "100%";
pastTimeElement.style.setProperty("--past-time-percentage", progress + "%");
progressElement.style.setProperty("--progress-percentage", progressPercentage);
if(progress > 5){
percentageLabelElement.textContent = `${progress.toFixed(0)}%`;
percentageLabelElement.style.left = `calc(${progress}% - 35px)`;
}
}
percentageLabelElement.style.visibility = "visible";
updateProgress();
}
document.getElementById("tenyear") && tenYear() && window.Pjax.on('complete', tenYear)
@@ -0,0 +1,15 @@
.author-content.author-content-item.single.sharePage(style=`background: url(${page.cover}) no-repeat center; background-size: cover;`)
.card-content
.author-content-item-tips= page.desc
span.author-content-item-title= page.title
.content-bottom
if page.leftend
.tips= page.leftend
if page.rightend
.tips= page.rightend
if page.rightbtn
.banner-button-group
- const isInternalLink = page.rightbtnlink.startsWith('/')
a.banner-button(onclick=isInternalLink ? `pjax.loadUrl("${page.rightbtnlink}")`: null, href=isInternalLink ? null : url_for(page.rightbtnlink), target=isInternalLink ? null : "_blank")
i.solitude.st-right-btn-fill
span.banner-button-text= page.rightbtn
@@ -0,0 +1,23 @@
#equipment
if site.data.equipment
each i in site.data.equipment
.equipment-item
h2.equipment-item-title= i.class_name
.equipment-item-description= i.description
.equipment-item-content
each item in i.equipment_list
.equipment-item-content-item
.equipment-item-content-item-cover
img.equipment-item-content-item-image(src=item.image, alt=item.name)
.equipment-item-content-item-info
.equipment-item-content-item-name(onclick='utils.copy("' + item.name + '")')= item.name
.equipment-item-content-item-specification= item.specification
.equipment-item-content-item-description= item.description
if item.link
.equipment-item-content-item-toolbar
if item.link.includes('https://') || item.link.includes('http://')
a.equipment-item-content-item-link(href=item.link, target="_blank") 详情
else
a.equipment-item-content-item-link(href=item.link, target="_blank") 查看文章
a.bber-reply(onclick=`sco.toTalk('${item.description}')`)
i.solitude.st-chat-fill(style="font-size: 1rem;")
@@ -0,0 +1,31 @@
.banners-title
.banners-title-small= page.title
.banners-title-big= page.desc
.banner-button-group
if theme.footer.randomlink
a.banner-button.secondary(onclick="travelling()")
i.solitude.st-signal-tower-fill
span.banner-button-text=_p('link.banner.random')
if theme.comment.use
a.banner-button(onclick="sco.scrollToComment()")
i.solitude.st-right-btn-fill
span.solitude.banner-button-text=_p('link.banner.toComment')
.tags-group-all.nowrapMove
.tags-group-wrapper
- const data = site.data.links.links
- for (let i = 0; i < 2; i++)
each x in data
if x.type === "item"
- var pairs = []
each y, index in x.link_list
if (index % 2 === 0)
- pairs.push([y])
else
- pairs[pairs.length - 1].push(y)
each pair in pairs
.tags-group-icon-pair
each y in pair
a.tags-group-icon(href=url_for(y.link), title=y.name)
img(src=y.avatar + (site.data.links.banner_suffix || ''), title=y.name)
@@ -0,0 +1,15 @@
.site-card-group
each item in data.link_list
.site-card
if item.tag
span.site-card-tag(class=item.color)= item.tag
i.light
a.img(title=item.name, href=url_for(item.link))
img.flink-avatar(src=item.topimg + (data.topimg_suffix || ''), alt=item.name)
a.info.cf-friends-link(title=item.name, href=url_for(item.link))
.site-card-avatar
img.flink-avatar.cf-friends-avatar(src=item.avatar + (data.suffix || ''), alt=item.name)
.img-alt.is-center= item.name
.site-card-text
span.title.cf-friends-name= item.name
span.desc(title=item.descr)= item.descr
@@ -0,0 +1,8 @@
.flink-list.cf-friends-lost-contact.mini
each item in data.link_list
.flink-list-item
a.cf-friends-link(href="javascript:void(0);", title=item.name)
img.flink-avatar.cf-friends-avatar(alt=item.name, src=item.avatar + (data.suffix || ''))
.flink-item-info
span.flink-item-name.cf-friends-name= item.name
span.flink-item-desc(title=item.descr)= item.descr
@@ -0,0 +1,11 @@
.flink-list
each item in data.link_list
.flink-list-item
if item.tag
span.site-card-tag(class=item.color)= item.tag
i.light
a.cf-friends-link(href=url_for(item.link), title=item.name)
img.flink-avatar.cf-friends-avatar(alt=item.name, src=item.avatar + (data.suffix || ''))
.flink-item-info
span.flink-item-name.cf-friends-name= item.name
span.flink-item-desc(title=item.descr)= item.descr
@@ -0,0 +1,45 @@
- const { server, site, option } = theme.artalk
script(pjax).
(async () => {
const emojiReg = /<img [^>]+ atk-emoticon="[^"]+">/g
if (typeof EasyDanmaku === "undefined") await utils.getScript('!{url_for(theme.cdn.envelope_js)}')
const envel = new EasyDanmaku({
page: '!{theme.envelope.page}',
el: '#barrage',
line: !{line},
speed: !{speed},
hover: !{hover},
loop: !{loop},
})
const data = utils.saveToLocal.get('enevlope')
if (data) {
envel.batchSend(data, true)
return
}
const searchParams = new URLSearchParams({'site_name': "!{site}", 'limit': '100'})
await fetch(`!{server}/api/v2/stats/latest_comments?${searchParams}`, {method: 'GET'}).then(async res => res.json())
.then(async data => {
let ls = []
for (const i of data.data) {
ls.push({
content: i.nick + ': ' + formatDanmaku(i.content),
avatar: '!{avatar}' + '/avatar/' + i.email_encrypted,
url: i.page_key + '#atk-comment-' + i.id,
})
}
envel.batchSend(ls, true)
utils.saveToLocal.set('enevlope', ls, .02)
}).catch(error => {
console.error("An error occurred while fetching comments: ", error)
})
function formatDanmaku(str) {
str = str.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
str = str.replace(/!\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.image")}]')
str = str.replace(/\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.link")}]')
str = str.replace(/```.*?```/g, '[!{__("console.newest_comment.code")}]')
return str
}
})()
@@ -0,0 +1,9 @@
#article-container
!= page.content
if theme.envelope.enable
.switch_message
button.open(type='button' onclick="document.getElementById('barrage').classList.remove('hide')")
span(aria-hidden='true')= __('message.open')
button.close(type='button' onclick="document.getElementById('barrage').classList.add('hide')")
span(aria-hidden='true')= __('message.close')
#barrage
@@ -0,0 +1,12 @@
- const {use,avatar} = theme.comment
if use
case use[0]
when "Valine"
include ./valine
when "Twikoo"
include ./twikoo
when "Waline"
include ./waline
when "Artalk"
include ./artalk
@@ -0,0 +1,47 @@
- const {envId} = theme.twikoo
script(pjax).
(async () => {
const emojiReg = /<img class="tk-owo-emotion" [^>]+>/g
if (typeof EasyDanmaku === "undefined") await utils.getScript('!{url_for(theme.cdn.envelope_js)}')
const Danmaku = new EasyDanmaku({
page: '!{theme.envelope.page}',
el: '#barrage',
line: !{line},
speed: !{speed},
hover: !{hover},
loop: !{loop},
})
const data = utils.saveToLocal.get('enevlope')
if (data) {
Danmaku.batchSend(data, true)
return
}
let ls = []
fetch('!{envId}/', {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"includeReply": false,
"pageSize": 100
}),
headers: {'Content-Type': 'application/json'}
}).then(res => res.json()).then(({data}) => {
for (const i of data) {
if (i.avatar === undefined) i.avatar = '!{avatar}/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp'
ls.push({avatar: i.avatar, content: i.nick + ': ' + formatDanmaku(i.comment), url: i.url + '#' + i.id})
}
Danmaku.batchSend(ls, true);
utils.saveToLocal.set('envelope', ls, 0.02)
});
function formatDanmaku(str) {
str = str.replace(emojiReg, '!{__("console.newest_comment.emoji")}')
str = str.replace(/<\/*br>|[\s\uFEFF\xA0]+/g, '');
str = str.replace(/<img.*?>/g, '[!{__("console.newest_comment.image")}]');
str = str.replace(/<a.*?>.*?<\/a>/g, '[!{__("console.newest_comment.link")}]');
str = str.replace(/<pre.*?>.*?<\/pre>/g, '[!{__("console.newest_comment.code")}]');
str = str.replace(/<.*?>/g, '');
return str
}
})()
@@ -0,0 +1,57 @@
- const {serverURLs,appId,appKey} = theme.valine
script(pjax).
(async () => {
const emojiReg = /:[a-z0-9_\u4e00-\u9fa5]+:/g
if(typeof EasyDanmaku === "undefined") await utils.getScript('!{url_for(theme.cdn.envelope_js)}')
const envel = new EasyDanmaku({
page: '!{theme.envelope.page}',
el: '#barrage',
line: !{line},
speed: !{speed},
hover: !{hover},
loop: !{loop},
})
const data = utils.saveToLocal.get('enevlope')
if(data){
envel.batchSend(data,true)
return
}
const url = new URL('!{serverURLs}/1.1/classes/Comment')
const params = {
url: window.location.pathname,
order: '-createdAt'
}
Object.entries(params).forEach(([key, value]) => url.searchParams.append(key, value))
try {
const res = await fetch(url, {
method: "GET",
headers: {
"X-LC-Id": "#{appId}",
"X-LC-Key": "#{appKey}",
"Content-Type": "application/json"
},
})
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`)
const data = await res.json()
const init = () =>
data.results.map(item => ({
content: item.nick + ': ' + formatDanmaku(item.comment),
avatar: '!{avatar}/avatar/'+md5(item.mail),
url: item.url
}))
if (typeof md5 === "undefined") await utils.getScript('!{url_for(theme.cdn.blueimp_md5)}')
envel.batchSend(init(),true)
utils.saveToLocal.set('enevlope',init(),.02)
} catch (error) {
console.error("An error occurred while fetching comments: ", error)
}
function formatDanmaku(str) {
str = str.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
str = str.replace(/!\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.image")}]')
str = str.replace(/\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.link")}]')
str = str.replace(/```.*?```/g, '[!{__("console.newest_comment.code")}]')
return str
}
})()
@@ -0,0 +1,42 @@
script(pjax).
(async () => {
const emojiReg = /<img [^>]+ class="wl-emoji">/g
if(typeof EasyDanmaku === "undefined") await utils.getScript('!{url_for(theme.cdn.envelope_js)}')
const envel = new EasyDanmaku({
page: '!{theme.envelope.page}',
el: '#barrage',
line: !{line},
speed: !{speed},
hover: !{hover},
loop: !{loop},
})
const data = utils.saveToLocal.get('enevlope')
if(data){
envel.batchSend(data,true)
return
}
await fetch('!{theme.waline.envId}/api/comment?type=recent&count=50', {method: 'GET'}).then(async res => res.json())
.then(async data => {
let ls = []
for (const i of data.data) {
ls.push({
content: i.nick + ': ' + formatContent(i.comment),
avatar: i.avatar,
url: i.url
})
}
envel.batchSend(ls,true)
utils.saveToLocal.set('enevlope',ls,.02)
}).catch(error => {
console.error("An error occurred while fetching comments: ", error)
})
function formatContent(content) {
content = content.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
content = content.replace(/<img.*?>/g, '[!{__("console.newest_comment.image")}]');
content = content.replace(/<a.*?>.*?<\/a>/g, '[!{__("console.newest_comment.link")}]');
content = content.replace(/<pre.*?>.*?<\/pre>/g, '[!{__("console.newest_comment.code")}]');
content = content.replace(/<.*?>/g, '');
return content
}
})()
@@ -0,0 +1,78 @@
- const { server, site, option } = theme.artalk
script(pjax).
(async () => {
document.querySelector('#comments-page').textContent = `#{__("loading")}`
const emojiReg = /<img [^>]+ atk-emoticon="[^"]+">/g
let cache = utils.saveToLocal.get('artalk-recent-comments')
if (cache) {
setHtml(document.querySelector('#comments-page'), cache)
return
}
let ls = []
const searchParams = new URLSearchParams({'site_name': "!{site}", 'limit': '!{limit}'})
await fetch(`!{server}/api/v2/stats/latest_comments?${searchParams}`, {method: 'GET'}).then(async res => res.json())
.then(async data => {
for (const i of data.data) {
if (checkEmoji(i.content)) continue
let title = ''
if (i.page_key) {
await fetch(i.page_key).then(res => res.text()).then(html => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
title = doc.querySelector('title').innerText
}).catch(() => {
title = i.page_key
})
}
if (title.indexOf('|') > 0) {
title = title.split('|')[0]
}
ls.push({
title: title,
url: i.page_key + '#atk-comment-' + i.id,
nick: i.nick,
avatar: '!{avatar}' + '/avatar/' + i.email_encrypted,
time: i.date,
content: formatContent(i.content)
})
}
setHtml(document.querySelector('#comments-page'), ls)
utils.saveToLocal.set('artalk-recent-comments', ls, !{cache})
})
function setHtml(el, data) {
el.innerHTML = data.map(i => `
<div class="comment-card" title="${i.title}" onclick="pjax.loadUrl('${i.url}')">
<div class="comment-info">
<img src="${i.avatar}" class="nolazyload" alt="${i.nick}">
<div>
<span class="comment-user">${i.nick}</span>
</div>
<time class="comment-time" datetime="${i.time}"></time>
</div>
<div class="comment-content">${i.content}</div>
<div class="comment-title">
<i class="solitude st-chat-fill"></i>
${i.title}</div>
</div>
`).join('')
if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
else {
document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
}
}
function checkEmoji(content) {
return emojiReg.test(content)
}
function formatContent(content) {
content = content.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
content = content.replace(/!\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.image")}]')
content = content.replace(/\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.link")}]')
content = content.replace(/```.*?```/g, '[!{__("console.newest_comment.code")}]')
return content
}
})()
@@ -0,0 +1,83 @@
- const {envId} = theme.twikoo
script(pjax).
(async () => {
document.querySelector('#comments-page').textContent = `#{__("loading")}`
const emojiReg = /<img class="tk-owo-emotion" [^>]+>/g
let cache = utils.saveToLocal.get('twikoo-recent-comments')
if (cache) {
setHtml(document.querySelector('#comments-page'), cache)
return
}
let ls = []
await fetch('!{envId}', {
method: "POST",
body: JSON.stringify({
"event": "GET_RECENT_COMMENTS",
"includeReply": true,
"pageSize": !{limit}
}),
headers: {'Content-Type': 'application/json'}
}).then(res => res.json()).then(async ({data}) => {
for (const i of data) {
if (i.avatar === undefined) i.avatar = '!{avatar}/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp'
let title = ''
if (i.url) {
await fetch(i.url).then(res => res.text()).then(html => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
title = doc.querySelector('title').innerText
}).catch(() => {
title = i.url
})
}
if (title.indexOf('|') > 0) {
title = title.split('|')[0]
}
ls.push({
avatar: i.avatar,
nick: i.nick,
title: title,
content: i.comment,
url: i.url + '#' + i.id,
time: i.created
})
}
setHtml(document.querySelector('#comments-page'), ls)
utils.saveToLocal.set('twikoo-recent-comments', ls, !{cache})
});
function setHtml(el, data) {
el.innerHTML = data.map(i => `
<div class="comment-card" title="${i.title}" onclick="pjax.loadUrl('${i.url}')">
<div class="comment-info">
<img src="${i.avatar}" class="nolazyload" alt="${i.nick}">
<div>
<span class="comment-user">${i.nick}</span>
</div>
<time class="comment-time" datetime="${new Date(i.time)}"></time>
</div>
<div class="comment-content">${formatContent(i.content)}</div>
<div class="comment-title">
<i class="solitude st-chat-fill"></i>
${i.title}</div>
</div>
`).join('')
if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
else {
document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
}
}
function formatContent(content) {
content = content.replace(emojiReg, '!{__("console.newest_comment.emoji")}')
content = content.replace(/<\/*br>|[\s\uFEFF\xA0]+/g, '');
content = content.replace(/<img.*?>/g, '[!{__("console.newest_comment.image")}]');
content = content.replace(/<a.*?>.*?<\/a>/g, '[!{__("console.newest_comment.link")}]');
content = content.replace(/<pre.*?>.*?<\/pre>/g, '[!{__("console.newest_comment.code")}]');
content = content.replace(/<.*?>/g, '');
return content
}
})()
@@ -0,0 +1,79 @@
- const { appId, appKey, serverURLs } = theme.valine
script(pjax).
(async () => {
document.querySelector('#comments-page').textContent = `#{__("loading")}`
const emojiReg = /:[a-z0-9_\u4e00-\u9fa5]+:/g
let cache = utils.saveToLocal.get('valine-recent-comments')
if (cache) {
setHtml(document.querySelector('#comments-page'), cache)
return
}
let ls = []
if (typeof md5 === "undefined") await utils.getScript('!{url_for(theme.cdn.blueimp_md5)}')
await fetch('!{serverURLs}/1.1/classes/Comment?limit=8&order=-createdAt', {
method: "GET",
headers: {
"X-LC-Id": '!{appId}',
"X-LC-Key": '!{appKey}',
"Content-Type": "application/json"
}
}).then(async res => res.json()).then(async results => {
for (const i of results.results) {
let title = ''
if (i.url) {
await fetch(i.url).then(res => res.text()).then(html => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
title = doc.querySelector('title').innerText
}).catch(() => {
title = i.url
})
}
if (title.indexOf('|') > 0) {
title = title.split('|')[0]
}
ls.push({
title: title,
url: i.url,
nick: i.nick,
avatar: '!{avatar}' + '/avatar/' + md5(i.mail.trim().toLowerCase()),
time: i.createdAt,
content: formatContent(i.comment)
})
}
setHtml(document.querySelector('#comments-page'), ls)
utils.saveToLocal.set('valine-recent-comments', ls, !{cache})
})
function setHtml(el, data) {
el.innerHTML = data.map(i => `
<div class="comment-card" title="${i.title}" onclick="pjax.loadUrl('${i.url}')">
<div class="comment-info">
<img src="${i.avatar}" class="nolazyload" alt="${i.nick}">
<div>
<span class="comment-user">${i.nick}</span>
</div>
<time class="comment-time" datetime="${i.time}"></time>
</div>
<div class="comment-content">${i.content}</div>
<div class="comment-title">
<i class="solitude st-chat-fill"></i>
${i.title}</div>
</div>
`).join('')
if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
else {
document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
}
}
function formatContent(content) {
content = content.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
content = content.replace(/!\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.image")}]')
content = content.replace(/\[.*?\]\((.*?)\)/g, '[!{__("console.newest_comment.link")}]')
content = content.replace(/```.*?```/g, '[!{__("console.newest_comment.code")}]')
return content
}
})()
@@ -0,0 +1,72 @@
script(pjax).
(async () => {
document.querySelector('#comments-page').textContent = `#{__("loading")}`
const emojiReg = /<img [^>]+ class="wl-emoji">/g
let cache = utils.saveToLocal.get('waline-recent-comments')
if (cache) {
setHtml(document.querySelector('#comments-page'), cache)
return
}
let ls = []
await fetch('!{theme.waline.envId}/api/comment?type=recent&count=!{limit}', {method: 'GET'}).then(async res => res.json())
.then(async data => {
console.log(data)
for (const i of data.data) {
let title = ''
if (i.url) {
await fetch(i.url).then(res => res.text()).then(html => {
const parser = new DOMParser()
const doc = parser.parseFromString(html, 'text/html')
title = doc.querySelector('title').innerText
}).catch(() => {
title = i.url
})
}
if (title.indexOf('|') > 0) {
title = title.split('|')[0]
}
ls.push({
title: title,
url: i.url,
nick: i.nick,
avatar: i.avatar,
time: new Date(i.time),
content: formatContent(i.comment)
})
}
setHtml(document.querySelector('#comments-page'), ls)
utils.saveToLocal.set('waline-recent-comments', ls, !{cache})
})
function setHtml(el, data) {
el.innerHTML = data.map(i => `
<div class="comment-card" title="${i.title}" onclick="pjax.loadUrl('${i.url}')">
<div class="comment-info">
<img src="${i.avatar}" class="nolazyload" alt="${i.nick}">
<div>
<span class="comment-user">${i.nick}</span>
</div>
<time class="comment-time" datetime="${i.time}"></time>
</div>
<div class="comment-content">${i.content}</div>
<div class="comment-title">
<i class="solitude st-chat-fill"></i>
${i.title}</div>
</div>
`).join('')
if (typeof sco !== 'undefined') sco.changeTimeFormat(document.querySelectorAll('.comment-time'))
else {
document.addEventListener('pjax:complete', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
document.addEventListener('DOMContentLoaded', () => sco.changeTimeFormat(document.querySelectorAll('.comment-time')))
}
}
function formatContent(content) {
content = content.replace(emojiReg, '[!{__("console.newest_comment.emoji")}]')
content = content.replace(/<img.*?>/g, '[!{__("console.newest_comment.image")}]');
content = content.replace(/<a.*?>.*?<\/a>/g, '[!{__("console.newest_comment.link")}]');
content = content.replace(/<pre.*?>.*?<\/pre>/g, '[!{__("console.newest_comment.code")}]');
content = content.replace(/<.*?>/g, '');
return content
}
})()