Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4c6e080c4d | |||
| b480c78344 | |||
| 0e216a2a2a | |||
| 5fa7c00a23 | |||
| 9a5d995ca5 | |||
| 5d8d1cbfc8 | |||
| b2bb437f59 | |||
| 907ade4b7f | |||
| a006880f58 | |||
| a065f44da4 | |||
| 372828a290 | |||
| 87be98f196 | |||
| 4ab2a62d99 | |||
| 1aad58e012 | |||
| 09e8e9e8a5 | |||
| ce9ae76e8a | |||
| d1e6567cc9 | |||
| 2b595583c1 | |||
| 296ea94340 | |||
| 0c72f67d8e | |||
| ffe4db83de | |||
| 65d780c01a | |||
| 6165bacaa9 | |||
| 5fb2e66399 | |||
| 30fcb2885b | |||
| 8e0e73b594 | |||
| 57fd7fe485 | |||
| 95c172b529 | |||
| 34276f132b | |||
| f26bc907d4 | |||
| e37ef68e30 | |||
| 1deff9afbf | |||
| 8543bc6fe1 | |||
| a88130d5c5 | |||
| e69663dad4 | |||
| fcd1fa1d67 | |||
| 2082a070a9 | |||
| a79b0ac312 | |||
| 40a20f585e | |||
| 6f23f1daae | |||
| f44fd96544 | |||
| 9d4433a74d | |||
| b4acf698a1 | |||
| dc59ba972e | |||
| 6473985801 | |||
| 4ba2c9ca76 | |||
| b52c2f0a23 | |||
| e8f4e79009 | |||
| 12ee26cdfe | |||
| ae64c25228 | |||
| beba961edf | |||
| d39023df8c | |||
| 6b8c0d0095 | |||
| 5a880c019d | |||
| ce1b8c4378 | |||
| aa30ed95f8 | |||
| bc3056bc4c | |||
| b9e3969134 | |||
| 65587efb0c | |||
| 0508d16c84 | |||
| 9f547244d3 | |||
| cf64160b75 | |||
| 7f69fd518d | |||
| f046a282c8 | |||
| 8f23486863 | |||
| bd3b384fde | |||
| e86e1afd66 | |||
| aec71a535b | |||
| f8fc4f293a | |||
| 21c75cdde2 | |||
| a99e370897 | |||
| 6456cb8521 | |||
| 041b559e97 | |||
| ab73d24361 | |||
| 5d3bd41e10 | |||
| cc3611d417 | |||
| 91743cbaad | |||
| 2aa42119dd | |||
| 2eff8ebd99 | |||
| 201bff5d11 | |||
| c91c5e54da | |||
| d6aaa9ac51 | |||
| 55724160cb | |||
| 4907670357 | |||
| bdd3eeb511 | |||
| 7b6154acad | |||
| fd639a1ffa | |||
| 496abfabb2 | |||
| d0d0a79064 |
@@ -4,9 +4,7 @@
|
||||
<section class="template--404">
|
||||
<div class="error--text">404</div>
|
||||
<div class="error--posts">
|
||||
|
||||
<article class="post--error" itemtype="http://schema.org/Article" itemscope="itemscope">
|
||||
|
||||
<div class="content">
|
||||
<h2 class="post--title" itemprop="headline">
|
||||
<a href="<?php $this->options->siteUrl(); ?>">
|
||||
@@ -19,11 +17,9 @@
|
||||
d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m0 73.142857C323.486476 170.666667 170.666667 323.486476 170.666667 512s152.81981 341.333333 341.333333 341.333333 341.333333-152.81981 341.333333-341.333333S700.513524 170.666667 512 170.666667z m36.571429 89.697523v229.86362h160.865523v73.142857H512a36.571429 36.571429 0 0 1-36.571429-36.571429V260.388571h73.142858z">
|
||||
</path>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
@@ -1,30 +1,56 @@
|
||||
## 说明
|
||||
|
||||
移植自`hugo-theme-farallon` 原汁原味,可以直接使用 原主题的CSS 和 JS.
|
||||
移植自 `bigfa `大大的 `hugo-theme-farallon` 原汁原味,可以直接使用 原主题的CSS
|
||||
精简部分 JS.
|
||||
|
||||
- 2024.7.4
|
||||
把分类图片以`mid`.jpg 的形式在主题`/dist/img`目录下,自动匹配
|
||||
|
||||
- 2024.6.12
|
||||
|
||||
更新豆瓣API获取方式
|
||||
[Docker 自动同步豆瓣书影音记录](https://fatesinger.com/103483)
|
||||
主题设置处填入API
|
||||
|
||||
- 2024.6.7
|
||||
|
||||
用自带评论做的说说页面,来自
|
||||
https://github.com/gogobody/typecho-whisper
|
||||
删减部分内容只能发表文字
|
||||
|
||||
- 2024.6.5 v0.5.3
|
||||
|
||||
新增了好物的页面 还是通过memos来获取
|
||||
|
||||
- 2024.6.4 v0.5.1
|
||||
|
||||
更改了设置memos的方式
|
||||
新增了Mastodon 的 说说 页面
|
||||
|
||||
- 2024.6.3 v0.5.0
|
||||
|
||||
还是抄了原版的豆瓣获取方式
|
||||
|
||||
- 2024.5.26 v0.4.1
|
||||
|
||||
抄了个网站统计页面
|
||||
|
||||
- 2024.5.24
|
||||
|
||||
新增了说说页面,基于memos 0.19 以下的版本
|
||||
在后台设置memos的地址和memoID即可
|
||||
默认获取最近20条公开的memo
|
||||
|
||||
|
||||
## 原项目地址
|
||||
https://github.com/bigfa/hugo-theme-farallon
|
||||
|
||||
## 进度
|
||||
|
||||
90%
|
||||
|
||||
由于typecho分类并无图片,所以默认使用
|
||||
`bigfa` 的 `https://static.fatesinger.com/2021/12/vhp6eou5x2wqh2zy.jpg`
|
||||
可以自行替换或者删除
|
||||
|
||||
|
||||
## 功能
|
||||
|
||||
### 豆瓣观影
|
||||
* 能力有限原项目功能无法实现 *
|
||||
|
||||
目前只能配合`DoubanBoard`插件使用
|
||||
|
||||
项目地址
|
||||
https://github.com/AlanDecode/Typecho-Plugin-DoubanBoard
|
||||
!!记得重命名文件夹为`DoubanBoard`
|
||||
更新 获取方式
|
||||
|
||||
### 友情链接
|
||||
|
||||
@@ -36,6 +62,32 @@ https://github.com/AlanDecode/Typecho-Plugin-DoubanBoard
|
||||
|
||||
若使用AI摘要插件则显示AI摘要,不使用则显示默认字数摘要
|
||||
|
||||
### 说说 by Memos
|
||||
|
||||
使用自定义字段设置memos
|
||||
|
||||
在自定义字段中填入`memos`值为memos地址,不带`/`
|
||||
|
||||
在自定义字段中填入`memosID`默认值为`1`,不为`1`时才需要设置
|
||||
|
||||
在自定义字段中填入`memosnum`默认值为`20`,默认获取20条最近的memo
|
||||
|
||||
### 说说 by Mastodon
|
||||
|
||||
根据 https://www.imsun.org/archives/1643.html
|
||||
获得API地址
|
||||
|
||||
在自定义字段中填入`tooot`值为Mastodon API 地址
|
||||
|
||||
### 好物 by memos
|
||||
|
||||
在自定义字段中填入`memos`值为memos地址
|
||||
在自定义字段中填入`memosID`默认值为`1`,不为`1`时才需要设置
|
||||
在自定义字段中填入`memostag`默认值为`好物`,不为`好物`时才需要设置
|
||||
## 预览地址
|
||||
|
||||
https://www.imsun.org
|
||||
https://www.imsun.org
|
||||
|
||||
## 感谢
|
||||
|
||||
[bigfa](https://github.com/bigfa/hugo-theme-farallon)
|
||||
@@ -12,7 +12,6 @@
|
||||
<h3 class="post--single__subtitle"><?php $this->categorydescription(); ?></h3>
|
||||
<?php while($this->next()): ?>
|
||||
</header>
|
||||
|
||||
<article class="post--item">
|
||||
<div class="content">
|
||||
<h2 class="post--title">
|
||||
@@ -41,7 +40,7 @@
|
||||
d="M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z">
|
||||
</path>
|
||||
</g>
|
||||
</svg><a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 评论', '%d 评论'); ?></a>
|
||||
</svg><a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('0 ', '1 ', '%d '); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
@@ -55,7 +54,7 @@
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'cat_pagination_page',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
@@ -63,8 +62,7 @@
|
||||
'nextClass' => 'next'
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
?>
|
||||
<!-- 搜索结果 -->
|
||||
<?php else: ?>
|
||||
<main class="site--main">
|
||||
@@ -76,5 +74,44 @@
|
||||
</header>
|
||||
</main>
|
||||
<?php endif; ?>
|
||||
|
||||
<style>
|
||||
/* 分页 */
|
||||
.pagination_page{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.pagination_page li.active a {
|
||||
background: var(--theme);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.pagination_page a{
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 50%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.pagination_page span.next{
|
||||
cursor: pointer;
|
||||
}
|
||||
.pagination_page li.active a:hover{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 分页 */
|
||||
</style>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -1,9 +1,48 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<style>
|
||||
/* 分页 */
|
||||
.pagination_page{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.pagination_page li.active a {
|
||||
background: var(--theme);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.pagination_page a{
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 50%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.pagination_page span.next{
|
||||
cursor: pointer;
|
||||
}
|
||||
.pagination_page li.active a:hover{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 分页 */
|
||||
</style>
|
||||
<div class="post--ingle__comments">
|
||||
<?php $this->comments()->to($comments); ?>
|
||||
<?php if($this->allow('comment')): ?>
|
||||
<?php if ($this->is('attachment')) : ?>
|
||||
<?php _e(''); ?>
|
||||
<?php else: ?>
|
||||
<h3 class="comments--title" id="comments">
|
||||
<svg viewBox="0 0 24 24" class="icon" aria-hidden="true" width="16" height="16">
|
||||
@@ -12,28 +51,10 @@
|
||||
d="M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z">
|
||||
</path>
|
||||
</g>
|
||||
</svg><?php $this->commentsNum(_t(''), _t('1'), _t('%d')); ?>
|
||||
</h3>
|
||||
<?php if ($comments->have()): ?>
|
||||
<?php $comments->listComments(); ?>
|
||||
<?php
|
||||
$comments->pageNav(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.1714 12.0007L8.22168 7.05093L9.63589 5.63672L15.9999 12.0007L9.63589 18.3646L8.22168 16.9504L13.1714 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'cat_pagination_page',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
'prevClass' => 'prev',
|
||||
'nextClass' => 'next'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php endif; ?>
|
||||
</svg>
|
||||
<?php $this->commentsNum(_t('0'), _t('1'), _t('%d')); ?>
|
||||
</h3>
|
||||
<ol class="commentlist sulliComment--list"></ol>
|
||||
<div id="<?php $this->respondId(); ?>" class="comment-respond">
|
||||
<div class="cancel-comment-reply cancel-comment-reply-link"><?php $comments->cancelReply(); ?></div>
|
||||
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form" class="comment-form">
|
||||
@@ -43,7 +64,6 @@
|
||||
<?php $this->user->screenName(); ?></a>.
|
||||
<a href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a></p>
|
||||
<?php else: ?>
|
||||
|
||||
<p class="comment-form-author">
|
||||
<input placeholder="称呼 *" type="text" name="author" id="author" class="text" value="" required />
|
||||
</p>
|
||||
@@ -57,7 +77,6 @@
|
||||
<p class="comment-form-comment">
|
||||
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea" onkeydown="if(event.ctrlKey&&event.keyCode==13){document.getElementById('misubmit').click();return false};" placeholder="<?php _e('评论审核后显示,请勿重复提交...'); ?>" required ><?php $this->remember('text'); ?></textarea>
|
||||
</p>
|
||||
|
||||
<p class="form-submit">
|
||||
<button type="submit" class="submit" id="misubmit"><?php _e('提交评论(Ctrl+Enter)'); ?></button>
|
||||
</p>
|
||||
@@ -65,8 +84,30 @@
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php _e(''); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php if ($comments->have()): ?>
|
||||
<?php $comments->listComments(); ?>
|
||||
<?php
|
||||
$comments->pageNav(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.1714 12.0007L8.22168 7.05093L9.63589 5.63672L15.9999 12.0007L9.63589 18.3646L8.22168 16.9504L13.1714 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
'prevClass' => 'prev',
|
||||
'nextClass' => 'next'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else: ?>
|
||||
<center><h3><?php _e('暂无评论'); ?></h3></center>
|
||||
<?php endif; ?>
|
||||
<?php $this->options->twikoo(); ?>
|
||||
</div>
|
||||
<?php
|
||||
@@ -97,7 +138,6 @@ function threadedComments($comments, $options) {
|
||||
<?php else: ?>
|
||||
<?php echo $comments->gravatar('40', ''); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
<div class="comment--meta">
|
||||
<div class="comment--author"><?php echo $comments->author; ?><span class="dot"></span>
|
||||
@@ -109,6 +149,7 @@ function threadedComments($comments, $options) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment-content">
|
||||
<?php if ($comments->parent) {echo getPermalinkFromCoid($comments->parent);}?>
|
||||
<?php $comments->content(); ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,8 +160,3 @@ function threadedComments($comments, $options) {
|
||||
<?php } ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<ol class="commentlist">
|
||||
<?php $this->comments()->to($comments); ?>
|
||||
<?php while($comments->next()): ?>
|
||||
<?php endwhile; ?>
|
||||
</ol>
|
||||
@@ -3803,302 +3803,4 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
||||
.notice--wrapper {
|
||||
width: 80%
|
||||
}
|
||||
}
|
||||
|
||||
.post-ai {
|
||||
background: #f5f5f5;
|
||||
border-radius: .5rem;
|
||||
padding: .5rem;
|
||||
line-height: 1.3;
|
||||
border: 1px solid #cfe6f3;
|
||||
margin: 1rem 0
|
||||
}
|
||||
|
||||
.ai-title {
|
||||
display: flex;
|
||||
color: #2d96bd;
|
||||
border-radius: .5rem;
|
||||
align-items: center;
|
||||
padding: 0 .25rem;
|
||||
cursor: default;
|
||||
user-select: none
|
||||
}
|
||||
|
||||
.ai-title-icon {
|
||||
width: 20px;
|
||||
height: auto;
|
||||
margin-right: .25rem
|
||||
}
|
||||
|
||||
.ai-title-text {
|
||||
font-weight: 700;
|
||||
margin-left: .25rem;
|
||||
line-height: 1
|
||||
}
|
||||
|
||||
.ai-explanation {
|
||||
margin-top: 1rem;
|
||||
padding: .5rem 1rem;
|
||||
background: #fff;
|
||||
border-radius: .5rem;
|
||||
border: 1px solid #cfe6f3;
|
||||
font-size: .95rem;
|
||||
line-height: 1.4;
|
||||
display: inline-block;
|
||||
width: 95%
|
||||
}
|
||||
|
||||
.ai-explanation span {
|
||||
margin-left: .5rem
|
||||
}
|
||||
|
||||
:root {
|
||||
--ht-main: #334155;
|
||||
--ht-day-bg: #ebedf0;
|
||||
--ht-tooltip: #24292f;
|
||||
--ht-tooltip-bg: #fff;
|
||||
--ht-lv-0: #ebedf0;
|
||||
--ht-lv-1: #9be9a8;
|
||||
--ht-lv-2: #40c463;
|
||||
--ht-lv-3: #30a14e;
|
||||
--ht-lv-4: #216e39
|
||||
}
|
||||
|
||||
[data-theme=dark] {
|
||||
--ht-main: #94a3b8;
|
||||
--ht-day-bg: #161b22;
|
||||
--ht-tooltip: #24292f;
|
||||
--ht-tooltip-bg: #fff;
|
||||
--ht-lv-0: #161b22;
|
||||
--ht-lv-1: #0e4429;
|
||||
--ht-lv-2: #006d32;
|
||||
--ht-lv-3: #26a641;
|
||||
--ht-lv-4: #39d353
|
||||
}
|
||||
|
||||
.heatmap_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
color: var(--ht-main)
|
||||
}
|
||||
|
||||
.heatmap_content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-end
|
||||
}
|
||||
|
||||
.heatmap_week {
|
||||
display: flex;
|
||||
margin-top: .25rem;
|
||||
margin-right: .25rem;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
text-align: right
|
||||
}
|
||||
|
||||
.heatmap_main {
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
}
|
||||
|
||||
.heatmap_month {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: .25rem
|
||||
}
|
||||
|
||||
.heatmap {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 84px
|
||||
}
|
||||
|
||||
.heatmap_footer {
|
||||
display: flex;
|
||||
margin-top: .5rem;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.heatmap_level {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
margin: 0 .25rem;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
height: 10px
|
||||
}
|
||||
|
||||
.heatmap_level_item {
|
||||
display: block;
|
||||
border-radius: .125rem;
|
||||
width: 10px;
|
||||
height: 10px
|
||||
}
|
||||
|
||||
.heatmap_level_0 {
|
||||
background: var(--ht-lv-0)
|
||||
}
|
||||
|
||||
.heatmap_level_1 {
|
||||
background: var(--ht-lv-1)
|
||||
}
|
||||
|
||||
.heatmap_level_2 {
|
||||
background: var(--ht-lv-2)
|
||||
}
|
||||
|
||||
.heatmap_level_3 {
|
||||
background: var(--ht-lv-3)
|
||||
}
|
||||
|
||||
.heatmap_level_4 {
|
||||
background: var(--ht-lv-4)
|
||||
}
|
||||
|
||||
.heatmap_day {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--ht-day-bg);
|
||||
margin: 1px;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.heatmap_tooltip {
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
left: 50%;
|
||||
width: max-content;
|
||||
color: var(--ht-tooltip);
|
||||
background-color: var(--ht-tooltip-bg);
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
padding: 8px;
|
||||
border-radius: 3px;
|
||||
white-space: pre-wrap;
|
||||
opacity: 1;
|
||||
transition: .3s;
|
||||
z-index: 1000;
|
||||
text-align: right;
|
||||
transform: translateX(-50%)
|
||||
}
|
||||
|
||||
.heatmap_tooltip_count,
|
||||
.heatmap_tooltip_post {
|
||||
display: inline-block
|
||||
}
|
||||
|
||||
.heatmap_tooltip_title,
|
||||
.heatmap_tooltip_date {
|
||||
display: block
|
||||
}
|
||||
|
||||
.heatmap_tooltip_date {
|
||||
margin: 0 .25rem
|
||||
}
|
||||
|
||||
.heatmap_day_level_0 {
|
||||
background-color: var(--ht-lv-0)
|
||||
}
|
||||
|
||||
.heatmap_day_level_1 {
|
||||
background-color: var(--ht-lv-1)
|
||||
}
|
||||
|
||||
.heatmap_day_level_2 {
|
||||
background-color: var(--ht-lv-2)
|
||||
}
|
||||
|
||||
.heatmap_day_level_3 {
|
||||
background-color: var(--ht-lv-3)
|
||||
}
|
||||
|
||||
.heatmap_day_level_4 {
|
||||
background-color: var(--ht-lv-4)
|
||||
}
|
||||
/* 分页 */
|
||||
.cat_pagination_page{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.cat_pagination_page li.active a {
|
||||
background: var(--theme);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.cat_pagination_page a{
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 50%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.cat_pagination_page span.next{
|
||||
cursor: pointer;
|
||||
}
|
||||
.cat_pagination_page li.active a:hover{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 分页 */
|
||||
.cat_archive_next {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
}
|
||||
.cat_archive_next .next{
|
||||
color: var(--C);
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 0.9rem;
|
||||
background: var(--background);
|
||||
border-radius: 1rem;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
letter-spacing: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cat_archive_next .over{
|
||||
font-size: small;
|
||||
color: var(--A);
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
.cat_categorymenu{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
.cat_categorymenu a:last-child {
|
||||
margin-right: auto;
|
||||
}
|
||||
.cat_categorymenu a {
|
||||
display: inline-block;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 244 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -17,7 +17,7 @@
|
||||
is_single = false;
|
||||
post_id = 0;
|
||||
is_archive = false;
|
||||
VERSION = "0.4.1";
|
||||
VERSION = "0.5.6";
|
||||
constructor() {
|
||||
super();
|
||||
this.initCopyright();
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
class Douban {
|
||||
constructor(config) {
|
||||
this.container = config.container;
|
||||
this.types = config.types ?? [
|
||||
"movie",
|
||||
"book",
|
||||
"music",
|
||||
"game",
|
||||
"drama",
|
||||
];
|
||||
this.baseAPI = config.baseAPI;
|
||||
this.ver = "1.0.6";
|
||||
this.type = "movie";
|
||||
this.status = "done";
|
||||
this.finished = false;
|
||||
this.paged = 1;
|
||||
this.genre_list = [
|
||||
{
|
||||
name: "已看",
|
||||
value: "done",
|
||||
},
|
||||
{
|
||||
name: "在看",
|
||||
value: "doing",
|
||||
},
|
||||
{
|
||||
name: "想看",
|
||||
value: "mark",
|
||||
},
|
||||
];
|
||||
this.subjects = [];
|
||||
this._create();
|
||||
}
|
||||
|
||||
on(event, element, callback) {
|
||||
const nodeList = document.querySelectorAll(element);
|
||||
nodeList.forEach((item) => {
|
||||
item.addEventListener(event, callback);
|
||||
});
|
||||
}
|
||||
|
||||
_handleGenreClick() {
|
||||
this.on("click", ".db--genreItem", (t) => {
|
||||
const self = t.currentTarget;
|
||||
if (self.classList.contains("is-active")) {
|
||||
return;
|
||||
}
|
||||
document.querySelector(".db--list").innerHTML = "";
|
||||
document.querySelector(".lds-ripple").classList.remove("u-hide");
|
||||
|
||||
this.status = self.dataset.status || ""; // Provide a default value of an empty string if self.dataset.status is undefined
|
||||
this._renderGenre();
|
||||
this.paged = 1;
|
||||
this.finished = false;
|
||||
this.subjects = [];
|
||||
this._fetchData();
|
||||
});
|
||||
}
|
||||
|
||||
_reanderTypes() {
|
||||
document.querySelector(".db--nav").innerHTML = this.types
|
||||
.map((item) => {
|
||||
return `<span class="db--navItem JiEun${
|
||||
this.type == item ? " current" : ""
|
||||
}" data-type="${item}">${item}</span>`;
|
||||
})
|
||||
.join("");
|
||||
this._handleNavClick();
|
||||
}
|
||||
|
||||
_renderGenre() {
|
||||
document.querySelector(".db--genres").innerHTML = this.genre_list
|
||||
.map((item) => {
|
||||
return `<span class="db--genreItem${
|
||||
this.status == item.value ? " is-active" : ""
|
||||
}" data-status="${item.value}">${item.name}</span>`;
|
||||
})
|
||||
.join("");
|
||||
this._handleGenreClick();
|
||||
}
|
||||
|
||||
_fetchData() {
|
||||
const params = new URLSearchParams({
|
||||
paged: this.paged.toString(),
|
||||
type: this.type,
|
||||
status: this.status,
|
||||
});
|
||||
fetch(this.baseAPI + "list?" + params.toString())
|
||||
.then((response) => response.json())
|
||||
.then((t) => {
|
||||
console.log(t.results);
|
||||
if (t.results.length) {
|
||||
if (
|
||||
document
|
||||
.querySelector(".db--list")
|
||||
.classList.contains("db--list__card")
|
||||
) {
|
||||
this.subjects = [...this.subjects, ...t.results];
|
||||
this._randerDateTemplate();
|
||||
} else {
|
||||
this.subjects = [...this.subjects, ...t.results];
|
||||
this._randerListTemplate();
|
||||
}
|
||||
document
|
||||
.querySelector(".lds-ripple")
|
||||
.classList.add("u-hide");
|
||||
} else {
|
||||
this.finished = true;
|
||||
document
|
||||
.querySelector(".lds-ripple")
|
||||
.classList.add("u-hide");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_randerDateTemplate() {
|
||||
const result = this.subjects.reduce((result, item) => {
|
||||
const date = new Date(item.create_time);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const key = `${year}-${month.toString().padStart(2, "0")}`;
|
||||
if (Object.prototype.hasOwnProperty.call(result, key)) {
|
||||
result[key].push(item);
|
||||
} else {
|
||||
result[key] = [item];
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
let html = ``;
|
||||
for (let key in result) {
|
||||
const date = key.split("-");
|
||||
html += `<div class="db--listBydate"><div class="db--titleDate"><div class="db--titleDate__day">${date[1]}</div><div class="db--titleDate__month">${date[0]}</div></div><div class="db--dateList__card">`;
|
||||
html += result[key]
|
||||
.map((movie) => {
|
||||
return `<div class="db--item${
|
||||
this.type == "music" ? " db--item__music" : ""
|
||||
}"><img src="${
|
||||
movie.poster
|
||||
}" referrerpolicy="no-referrer" class="db--image"><div class="db--score ">${
|
||||
movie.douban_score > 0
|
||||
? '<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" ><path d="M12 20.1l5.82 3.682c1.066.675 2.37-.322 2.09-1.584l-1.543-6.926 5.146-4.667c.94-.85.435-2.465-.799-2.567l-6.773-.602L13.29.89a1.38 1.38 0 0 0-2.581 0l-2.65 6.53-6.774.602C.052 8.126-.453 9.74.486 10.59l5.147 4.666-1.542 6.926c-.28 1.262 1.023 2.26 2.09 1.585L12 20.099z"></path></svg>' +
|
||||
movie.douban_score
|
||||
: ""
|
||||
}${
|
||||
movie.year > 0 ? " · " + movie.year : ""
|
||||
}</div><div class="db--title"><a href="${
|
||||
movie.link
|
||||
}" target="_blank">${movie.name}</a></div></div>`;
|
||||
})
|
||||
.join("");
|
||||
html += `</div></div>`;
|
||||
}
|
||||
document.querySelector(".db--list").innerHTML = html;
|
||||
}
|
||||
|
||||
_randerListTemplate() {
|
||||
document.querySelector(".db--list").innerHTML = this.subjects
|
||||
.map((item) => {
|
||||
return `<div class="db--item"><img src="${
|
||||
item.poster
|
||||
}" referrerpolicy="no-referrer" class="db--image"><div class="ipc-signpost ">${
|
||||
item.create_time
|
||||
}</div><div class="db--score ">${
|
||||
item.douban_score
|
||||
? '<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" ><path d="M12 20.1l5.82 3.682c1.066.675 2.37-.322 2.09-1.584l-1.543-6.926 5.146-4.667c.94-.85.435-2.465-.799-2.567l-6.773-.602L13.29.89a1.38 1.38 0 0 0-2.581 0l-2.65 6.53-6.774.602C.052 8.126-.453 9.74.486 10.59l5.147 4.666-1.542 6.926c-.28 1.262 1.023 2.26 2.09 1.585L12 20.099z"></path></svg>' +
|
||||
item.douban_score
|
||||
: ""
|
||||
}${
|
||||
item.year ? " · " + item.year : ""
|
||||
}</div><div class="db--title"><a href="${
|
||||
item.link
|
||||
}" target="_blank">${item.name}</a></div>
|
||||
</div>
|
||||
</div>`;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
_handleScroll() {
|
||||
window.addEventListener("scroll", () => {
|
||||
var t = window.scrollY || window.pageYOffset;
|
||||
const moreElement = document.querySelector(
|
||||
".block-more"
|
||||
);
|
||||
if (
|
||||
moreElement.offsetTop + -window.innerHeight < t &&
|
||||
document
|
||||
.querySelector(".lds-ripple")
|
||||
.classList.contains("u-hide") &&
|
||||
!this.finished
|
||||
) {
|
||||
document
|
||||
.querySelector(".lds-ripple")
|
||||
.classList.remove("u-hide");
|
||||
this.paged++;
|
||||
this._fetchData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_handleNavClick() {
|
||||
this.on("click", ".db--navItem", (t) => {
|
||||
const self = t.currentTarget;
|
||||
if (self.classList.contains("current")) return;
|
||||
this.status = "done";
|
||||
this.type = self.dataset.type;
|
||||
this._renderGenre();
|
||||
document.querySelector(".db--list").innerHTML = "";
|
||||
document.querySelector(".lds-ripple").classList.remove("u-hide");
|
||||
document
|
||||
.querySelector(".db--navItem.current")
|
||||
.classList .remove("current");
|
||||
self.classList.add("current");
|
||||
this.paged = 1;
|
||||
this.finished = false;
|
||||
this.subjects = [];
|
||||
this._fetchData();
|
||||
});
|
||||
}
|
||||
|
||||
_create() {
|
||||
if (document.querySelector(".db--container")) {
|
||||
const container = document.querySelector(
|
||||
this.container
|
||||
);
|
||||
if (!container) return;
|
||||
container.innerHTML = `<nav class="db--nav">
|
||||
</nav>
|
||||
<div class="db--genres">
|
||||
</div>
|
||||
<div class="db--list db--list__card">
|
||||
</div>
|
||||
<div class="block-more block-more__centered">
|
||||
<div class="lds-ripple">
|
||||
</div>
|
||||
</div>`;
|
||||
this._renderGenre();
|
||||
this._reanderTypes();
|
||||
this._fetchData();
|
||||
this._handleScroll();
|
||||
}
|
||||
|
||||
if (document.querySelector(".js-db")) {
|
||||
document.querySelectorAll(".js-db").forEach((item) => {
|
||||
const db = item;
|
||||
const id = db.dataset.id;
|
||||
const type = db.dataset.type;
|
||||
const nodeParent = db.parentNode;
|
||||
fetch(this.baseAPI + `${type}/${id}`).then((response) => {
|
||||
response.json().then((t) => {
|
||||
if (t.data) {
|
||||
const data = t.data;
|
||||
const node = document.createElement("div");
|
||||
node.classList.add("doulist-item");
|
||||
node.innerHTML = `<div class="doulist-subject">
|
||||
<div class="doulist-post"><img decoding="async" referrerpolicy="no-referrer" src="${data.poster}"></div>
|
||||
<div class="doulist-content">
|
||||
<div class="doulist-title"><a href="${data.link}" class="cute" target="_blank" rel="external nofollow">${data.name}</a></div>
|
||||
<div class="rating"><span class="allstardark"><span class="allstarlight" style="width:55%"></span></span><span class="rating_nums"> ${data.douban_score} </span></div>
|
||||
<div class="abstract">${data.card_subtitle}</div>
|
||||
</div>
|
||||
</div>`;
|
||||
nodeParent.replaceWith(node);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (document.querySelector(".db--collection")) {
|
||||
document
|
||||
.querySelectorAll(".db--collection")
|
||||
.forEach((item) => {
|
||||
this._fetchCollection(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_fetchCollection(item) {
|
||||
const type = item.dataset.style ? item.dataset.style : "card";
|
||||
fetch(
|
||||
this.baseAPI +
|
||||
"/list?type=" +
|
||||
item.dataset.type +
|
||||
"&paged=1&start_time=" +
|
||||
item.dataset.start +
|
||||
"&end_time=" +
|
||||
item.dataset.end
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((t) => {
|
||||
if (t.length) {
|
||||
if (type == "card") {
|
||||
item.innerHTML += t
|
||||
.map((movie) => {
|
||||
return `<div class="doulist-item">
|
||||
<div class="doulist-subject">
|
||||
<div class="db--viewTime ">Marked ${movie.create_time}</div>
|
||||
<div class="doulist-post"><img referrerpolicy="no-referrer" src="${movie.poster}"></div><div class="doulist-content"><div class="doulist-title"><a href="${movie.link}" class="cute" target="_blank" rel="external nofollow">${movie.name}</a></div><div class="rating"><span class="allstardark"><span class="allstarlight" style="width:75%"></span></span><span class="rating_nums">${movie.douban_score}</span></div><div class="abstract">${movie.card_subtitle}</div></div></div></div>`;
|
||||
})
|
||||
.join("");
|
||||
} else {
|
||||
const result = t.reduce(
|
||||
(result, item) => {
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(
|
||||
result,
|
||||
item.create_time
|
||||
)
|
||||
) {
|
||||
result[item.create_time].push(item);
|
||||
} else {
|
||||
result[item.create_time] = [item];
|
||||
}
|
||||
return result;
|
||||
},
|
||||
{}
|
||||
);
|
||||
let html = ``;
|
||||
for (let key in result) {
|
||||
html += `<div class="db--date">${key}</div><div class="db--dateList">`;
|
||||
html += result[key]
|
||||
.map((movie) => {
|
||||
return `<div class="db--card__list">
|
||||
<img referrerpolicy="no-referrer" src="${
|
||||
movie.poster
|
||||
}">
|
||||
<div>
|
||||
<div class="title"><a href="${
|
||||
movie.link
|
||||
}" class="cute" target="_blank" rel="external nofollow">${
|
||||
movie.name
|
||||
}</a></div>
|
||||
<div class="rating"><span class="allstardark"><span class="allstarlight" style="width:75%"></span></span><span class="rating_nums">${
|
||||
movie.douban_score
|
||||
}</span></div>
|
||||
${movie.remark || movie.card_subtitle}
|
||||
</div>
|
||||
</div>`;
|
||||
})
|
||||
.join("");
|
||||
html += `</div>`;
|
||||
}
|
||||
item.innerHTML = html;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
|
||||
<footer class="site--footer">
|
||||
<div class="site--footer__content">
|
||||
<div class=site--footer__sns>
|
||||
<?php $this->need('sns.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php if($this->options->sitemapurl): ?>
|
||||
<?php //sitemap填入
|
||||
if($this->options->sitemapurl): ?>
|
||||
<a href="<?php $this->options->sitemapurl() ?>" target="_blank">💗</a>
|
||||
<?php endif; ?>
|
||||
<a href="https://www.typecho.org">Typecho</a>驱动 <a href="https://www.imsun.org">Made with 老孙</a>💗 加载耗时
|
||||
<?php echo timer_stop();?> 💗
|
||||
<?php endif; ?>
|
||||
<a href="https://www.typecho.org" target="_blank">Typecho驱动</a>
|
||||
<a href="https://www.imsun.org" target="_blank"> Made with Sun</a>
|
||||
<?php //添加加载时间控制
|
||||
if ($this->options->showtime): ?>
|
||||
页面加载耗时<?php echo timer_stop();?>
|
||||
<?php endif; ?>
|
||||
<div class="copyright">
|
||||
<a href="<?php $this->options->siteUrl(); ?>">
|
||||
<?php $this->options->title(); ?>
|
||||
@@ -22,13 +25,9 @@
|
||||
p-id="4007"></path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php $this->options->tongji(); ?>
|
||||
|
||||
<?php $this->options->tongji(); ?>
|
||||
</footer>
|
||||
|
||||
<div class="backToTop">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="svgIcon" viewBox="0 0 14 14" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
@@ -36,7 +35,6 @@
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/bundle.js'); ?>"></script>
|
||||
<?php $this->footer(); ?>
|
||||
</div>
|
||||
|
||||
@@ -5,37 +5,38 @@ function themeConfig($form) {
|
||||
$form->addInput($logoUrl);
|
||||
$icoUrl = new Typecho_Widget_Helper_Form_Element_Text('icoUrl', NULL, NULL, _t('站点 Favicon 地址'));
|
||||
$form->addInput($icoUrl);
|
||||
$jzyear = new Typecho_Widget_Helper_Form_Element_Text('jzyear', NULL, NULL, _t('建站年份 eg. 2006'));
|
||||
$sticky = new Typecho_Widget_Helper_Form_Element_Text('sticky', NULL, NULL, _t('置顶文章cid'), _t('多篇文章以`|`符号隔开'), _t('会在首页展示置顶文章。'));
|
||||
$form->addInput($sticky);
|
||||
$jzyear = new Typecho_Widget_Helper_Form_Element_Text('jzyear', NULL, NULL, _t('建站年份'), _t('eg. 2006'), _t('会在页脚显示。'));
|
||||
$form->addInput($jzyear);
|
||||
$instagramurl = new Typecho_Widget_Helper_Form_Element_Text('instagramurl', NULL, NULL, _t('ins'));
|
||||
$form->addInput($instagramurl);
|
||||
$telegramurl = new Typecho_Widget_Helper_Form_Element_Text('telegramurl', NULL, NULL, _t('电报'));
|
||||
$form->addInput($telegramurl);
|
||||
$githuburl = new Typecho_Widget_Helper_Form_Element_Text('githuburl', NULL, NULL, _t('github'));
|
||||
$form->addInput($githuburl);
|
||||
$twitterurl = new Typecho_Widget_Helper_Form_Element_Text('twitterurl', NULL, NULL, _t('twitter'));
|
||||
$form->addInput($twitterurl);
|
||||
$mastodonurl = new Typecho_Widget_Helper_Form_Element_Text('mastodonurl', NULL, NULL, _t('mastodon'));
|
||||
$form->addInput($mastodonurl);
|
||||
$sitemapurl = new Typecho_Widget_Helper_Form_Element_Text('sitemapurl', NULL, NULL, _t('sitemap'));
|
||||
$form->addInput($sitemapurl);
|
||||
$cnavatar = new Typecho_Widget_Helper_Form_Element_Text('cnavatar', NULL, 'https://cravatar.cn/avatar/', _t('自定义Gravatar镜像服务器,默认https://cravatar.cn/avatar/'));
|
||||
$form->addInput($cnavatar);
|
||||
$donate = new Typecho_Widget_Helper_Form_Element_Text('donate', NULL, 'https://blogcdn.loliko.cn/donate/wx.png', _t('赞赏二维码'));
|
||||
$form->addInput($donate);
|
||||
|
||||
|
||||
$twikoo = new Typecho_Widget_Helper_Form_Element_Textarea('twikoo', NULL, NULL, _t('引用第三方评论'));
|
||||
$form->addInput($twikoo);
|
||||
|
||||
$addhead = new Typecho_Widget_Helper_Form_Element_Textarea('addhead', NULL, NULL, _t('添加head'));
|
||||
$form->addInput($addhead);
|
||||
$tongji = new Typecho_Widget_Helper_Form_Element_Textarea('tongji', NULL, NULL, _t('统计代码'));
|
||||
$form->addInput($tongji);
|
||||
$showProfile = new Typecho_Widget_Helper_Form_Element_Radio('showProfile',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否在文章页面显示显示作者信息'), _t('选择“是”将在文章页面包含显示作者信息。'));
|
||||
$form->addInput($showProfile);
|
||||
$instagramurl = new Typecho_Widget_Helper_Form_Element_Text('instagramurl', NULL, NULL, _t('Instagram'), _t('会在个人信息显示'));
|
||||
$form->addInput($instagramurl);
|
||||
$telegramurl = new Typecho_Widget_Helper_Form_Element_Text('telegramurl', NULL, NULL, _t('电报'), _t('会在个人信息显示'));
|
||||
$form->addInput($telegramurl);
|
||||
$githuburl = new Typecho_Widget_Helper_Form_Element_Text('githuburl', NULL, NULL, _t('github'), _t('会在个人信息显示'));
|
||||
$form->addInput($githuburl);
|
||||
$twitterurl = new Typecho_Widget_Helper_Form_Element_Text('twitterurl', NULL, NULL, _t('twitter'), _t('会在个人信息显示'));
|
||||
$form->addInput($twitterurl);
|
||||
$mastodonurl = new Typecho_Widget_Helper_Form_Element_Text('mastodonurl', NULL, NULL, _t('mastodon'), _t('会在个人信息显示'));
|
||||
$form->addInput($mastodonurl);
|
||||
$sitemapurl = new Typecho_Widget_Helper_Form_Element_Text('sitemapurl', NULL, NULL, _t('sitemap'), _t('会在页脚显示'));
|
||||
$form->addInput($sitemapurl);
|
||||
$cnavatar = new Typecho_Widget_Helper_Form_Element_Text('cnavatar', NULL, 'https://cravatar.cn/avatar/', _t('Gravatar镜像'), _t('默认https://cravatar.cn/avatar/,建议保持默认'));
|
||||
$form->addInput($cnavatar);
|
||||
$donate = new Typecho_Widget_Helper_Form_Element_Text('donate', NULL, 'https://blogcdn.loliko.cn/donate/wx.png', _t('赞赏二维码'), _t('不填写则不显示'));
|
||||
$form->addInput($donate);
|
||||
$doubanID = new Typecho_Widget_Helper_Form_Element_Text('doubanID', NULL, 'https://db.imsun.org/', _t('豆瓣页面必需API,包含"/"'), _t(' '));
|
||||
$form->addInput($doubanID);
|
||||
$twikoo = new Typecho_Widget_Helper_Form_Element_Textarea('twikoo', NULL, NULL, _t('引用第三方评论'), _t('不填写则不显示'));
|
||||
$form->addInput($twikoo);
|
||||
$addhead = new Typecho_Widget_Helper_Form_Element_Textarea('addhead', NULL, NULL, _t('添加head'), _t('支持HTML'));
|
||||
$form->addInput($addhead);
|
||||
$tongji = new Typecho_Widget_Helper_Form_Element_Textarea('tongji', NULL, NULL, _t('统计代码'), _t('支持HTML'));
|
||||
$form->addInput($tongji);
|
||||
$showallwords = new Typecho_Widget_Helper_Form_Element_Radio('showallwords',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示归档字数统计'), _t('选择“是”将在归档页面显示全站总字数。'));
|
||||
@@ -44,6 +45,18 @@ function themeConfig($form) {
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示相关文章'), _t('选择“是”将在文章页面显示相关文章。'));
|
||||
$form->addInput($showrelated);
|
||||
$showshare = new Typecho_Widget_Helper_Form_Element_Radio('showshare',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示复制链接'), _t('选择“是”将在文章页面显示复制链接。'));
|
||||
$form->addInput($showshare);
|
||||
$showtime = new Typecho_Widget_Helper_Form_Element_Radio('showtime',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示页面加载时间'), _t('选择“是”将在页脚显示加载时间。'));
|
||||
$form->addInput($showtime);
|
||||
$qqboturl = new Typecho_Widget_Helper_Form_Element_Text('qqboturl', NULL, 'https://bot.asbid.cn', _t('QQ机器人API,保持默认则需添加 2280858259 为好友'), _t('基于cqhttp,有评论时QQ通知'));
|
||||
$form->addInput($qqboturl);
|
||||
$qqnum = new Typecho_Widget_Helper_Form_Element_Text('qqnum', NULL, '80116747', _t('QQ号码'), _t('用于接收QQ通知的号码'));
|
||||
$form->addInput($qqnum);
|
||||
}
|
||||
function get_post_view($archive) {
|
||||
$cid = $archive->cid;
|
||||
@@ -164,11 +177,349 @@ function allwords() {
|
||||
elseif ($chars>1000000){
|
||||
echo '全站共 '.$chars.' 字,已写一本列夫·托尔斯泰的《战争与和平》了!';}
|
||||
}
|
||||
function show_first_image($content) {
|
||||
preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches);
|
||||
// 检查是否找到了图片
|
||||
if(isset($matches[1][0])){
|
||||
return $matches[1][0];
|
||||
function img_postthumb($cid) {
|
||||
$db = Typecho_Db::get();
|
||||
$rs = $db->fetchRow($db->select('table.contents.text')
|
||||
->from('table.contents')
|
||||
->where('table.contents.cid=?', $cid)
|
||||
->order('table.contents.cid', Typecho_Db::SORT_ASC)
|
||||
->limit(1));
|
||||
// 检查是否获取到结果
|
||||
if (!$rs) {
|
||||
return "";
|
||||
}
|
||||
return false; // 没有找到图片,返回 false
|
||||
preg_match_all("/https?:\/\/[^\s]*.(png|jpeg|jpg|gif|bmp|webp)/", $rs['text'], $thumbUrl); //通过正则式获取图片地址
|
||||
// 检查是否匹配到图片URL
|
||||
if (count($thumbUrl[0]) > 0) {
|
||||
return $thumbUrl[0][0]; // 返回第一张图片的URL
|
||||
} else {
|
||||
return ""; // 没有匹配到图片URL,返回空字符串
|
||||
}
|
||||
}
|
||||
//回复加上@
|
||||
function getPermalinkFromCoid($coid) {
|
||||
$db = Typecho_Db::get();
|
||||
$row = $db->fetchRow($db->select('author')->from('table.comments')->where('coid = ? AND status = ?', $coid, 'approved'));
|
||||
if (empty($row)) return '';
|
||||
return '<a href="#comment-'.$coid.'" style="text-decoration: none;">@'.$row['author'].'</a>';
|
||||
}
|
||||
// 评论提交通知函数
|
||||
function notifyQQBot($comment) {
|
||||
$options = Helper::options();
|
||||
// 检查评论是否已经审核通过
|
||||
if ($comment->status != "approved") {
|
||||
error_log('Comment is not approved.');
|
||||
return;
|
||||
}
|
||||
// 获取配置中的QQ机器人API地址
|
||||
$cq_url = $options->qqboturl;
|
||||
// 检查API地址是否为空
|
||||
if (empty($cq_url)) {
|
||||
error_log('QQ Bot URL is empty. Using default URL.');
|
||||
$cq_url = 'https://bot.asbid.cn';
|
||||
}
|
||||
// 获取QQ号码
|
||||
$qqnum = $options->qqnum;
|
||||
// 检查QQ号码是否为空
|
||||
if (empty($qqnum)) {
|
||||
error_log('QQ number is empty.');
|
||||
return;
|
||||
}
|
||||
// 如果是管理员自己发的评论则不发送通知
|
||||
if ($comment->authorId === $comment->ownerId) {
|
||||
error_log('This comment is by the post owner.');
|
||||
return;
|
||||
}
|
||||
// 构建消息内容
|
||||
$msg = '「' . $comment->author . '」在文章《' . $comment->title . '》中发表了评论!';
|
||||
$msg .= "\n评论内容:\n{$comment->text}\n永久链接地址:{$comment->permalink}";
|
||||
// 准备发送消息的数据
|
||||
$_message_data_ = [
|
||||
'user_id' => (int) trim($qqnum),
|
||||
'message' => str_replace(["\r\n", "\r", "\n"], "\r\n", htmlspecialchars_decode(strip_tags($msg)))
|
||||
];
|
||||
// 输出调试信息
|
||||
error_log('Sending message to QQ Bot: ' . print_r($_message_data_, true));
|
||||
// 初始化Curl请求
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => "{$cq_url}/send_msg?" . http_build_query($_message_data_, '', '&'),
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => 0
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
error_log('Curl error: ' . curl_error($ch));
|
||||
} else {
|
||||
error_log('Response: ' . $response);
|
||||
}
|
||||
curl_close($ch);
|
||||
}
|
||||
Typecho_Plugin::factory('Widget_Feedback')->finishComment = 'notifyQQBot';
|
||||
//开始增加某些奇怪的东西
|
||||
// 获取月份
|
||||
function getMonth() {
|
||||
$path = $_SERVER['PHP_SELF']; // 获取路劲
|
||||
preg_match('/\d{4}\/\d{2}\/\d{2}|\d{4}\/\d{2}/', $path, $date); // 匹配路劲中的日期
|
||||
if (is_array($date) && count($date)) {
|
||||
$date = explode('/', $date[0]); // 如果匹配到就分割日期
|
||||
}else {
|
||||
$date = date('Y/m/d', time()); // 如果没有匹配到就获取当前月
|
||||
$date = explode('/', $date); // 分割日期
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
// 获取指定月份的文章
|
||||
function getMonthPost() {
|
||||
$date = getMonth(); // 获取要查询文章的月份
|
||||
|
||||
$start = $date[0] . '-' . $date[1] . '-01 00:00:00'; // 月的第一天
|
||||
$end = date('Y-m-t', strtotime($date[0] . '-' . $date[1] . '-' . '1 23:59:59')); // 月最后一天
|
||||
$start = strtotime($start); // 把月的第一天转换为时间戳
|
||||
$end = strtotime($end . ' 23:59:59'); // 把月的最后一天转换为时间戳
|
||||
$db = Typecho_Db::get();
|
||||
// 按照提供的月份查询出文件的时间
|
||||
$post = $db->fetchAll($db->select('table.contents.created')->from('table.contents')->where('created >= ?', $start)->where('created <= ?', $end)->where('type = ?', 'post')->where('status = ?', 'publish'));
|
||||
// 按照提供的月份查询前一个月的文章
|
||||
$previous = $db->fetchAll($db->select('table.contents.created')->from('table.contents')->where('created < ?', $start)->where('type = ?', 'post')->where('status = ?', 'publish')->offset(0)->limit(1)->order('created', Typecho_Db::SORT_DESC));
|
||||
// 按照提供的月份查询后一个月的文章
|
||||
$next = $db->fetchAll($db->select('table.contents.created')->from('table.contents')->where('created > ?', $end)->where('type = ?', 'post')->where('status = ?', 'publish')->offset(0)->limit(1)->order('created', Typecho_Db::SORT_ASC));
|
||||
|
||||
if (count($next)) {
|
||||
$next = date('Y/m/', $next[0]['created']); // 格式化前一个月的文章时间
|
||||
}
|
||||
|
||||
if (count($previous)) {
|
||||
$previous = date('Y/m/', $previous[0]['created']); // 格式化后一个月的文章时间
|
||||
}
|
||||
|
||||
$day = array();
|
||||
foreach ($post as $val) {
|
||||
array_push($day, date('j', $val['created'])); // 把查询出的文章日加入数组
|
||||
}
|
||||
return array(
|
||||
'post'=> $day,
|
||||
'previous' => $previous,
|
||||
'next' => $next
|
||||
);
|
||||
}
|
||||
// 生成日历
|
||||
function calendar($month, $url, $rewrite) {
|
||||
$monthArr = getMonth(); // 获取月份
|
||||
$post = getMonthPost(); // 获取文章日期
|
||||
|
||||
// 判断是否启用了地址重写功能
|
||||
if ($rewrite) {
|
||||
$monthUrl = $url . $monthArr[0] . '/' . $monthArr[1] . '/'; // 生成日期链接前缀
|
||||
$previousUrl = is_array($post['previous'])?'':$url . $post['previous']; // 生成前一个月的跳转链接地址
|
||||
$nextUrl = is_array($post['next'])?'':$url . $post['next']; // 生成后一个月的跳转链接地址
|
||||
}else {
|
||||
$monthUrl = $url . 'index.php/' . $monthArr[0] . '/' . $monthArr[1] . '/'; // 生成日期链接前缀
|
||||
$previousUrl = is_array($post['previous'])?'':$url . 'index.php/' . $post['previous']; // 生成前一个月的跳转链接地址
|
||||
$nextUrl = is_array($post['next'])?'':$url . 'index.php/' . $post['next']; // 生成后一个月的跳转链接地址
|
||||
}
|
||||
|
||||
$postCount = array_count_values($post['post']); // 统计每天的文章数量
|
||||
|
||||
$calendar = ''; // 初始化
|
||||
$week_arr = ['日', '一', '二', '三', '四', '五', '六']; // 表头
|
||||
$this_month_days = (int)date('t', strtotime($month)); // 本月共多少天
|
||||
$this_month_one_n = (int)date('w', strtotime($month)); // 本月1号星期几
|
||||
$calendar .= '<table aria-label="' . $monthArr[0] . '年' . $monthArr[1] . '月日历" class="table table-bordered table-sm m-0"><thead><tr>'; // 表头
|
||||
|
||||
foreach ($week_arr as $k => $v){
|
||||
if($k == 0){
|
||||
$class = ' class="sunday"';
|
||||
}elseif ($k == 6){
|
||||
$class = ' class="saturday"';
|
||||
}else{
|
||||
$class = '';
|
||||
}
|
||||
$calendar .= '<th class="text-center py-2">' . $v . '</th>';
|
||||
}
|
||||
$calendar .= '</tr></thead><tbody>';
|
||||
// 表身
|
||||
// 计算本月共几行数据
|
||||
$total_rows = ceil(($this_month_days - (7 - $this_month_one_n)) / 7) + 1;
|
||||
$number = 1;
|
||||
$flag = 0;
|
||||
for ($row = 1;$row <= $total_rows;$row++){
|
||||
$calendar .= '<tr>';
|
||||
for ($week = 0;$week <= 6;$week ++){
|
||||
if($number < 10){
|
||||
$numbera = '0' . $number;
|
||||
}else{
|
||||
$numbera = $number;
|
||||
}
|
||||
|
||||
if($number <= $this_month_days){
|
||||
if ($number < 10) {
|
||||
$zero = '0';
|
||||
}else {
|
||||
$zero = '';
|
||||
}
|
||||
|
||||
if($row == 1){
|
||||
if($week >= $this_month_one_n){
|
||||
if (in_array($number, $post['post'])) {
|
||||
$calendar .= '<td class="active text-center py-2">' . '<a rel="archives" href="' . $monthUrl . $zero . $number . '/' . '" class="p-0" title="' . $postCount[$number] . '篇文章" data-toggle="tooltip" data-placement="top"><b>' . $number . '</b></a>' . '</td>';
|
||||
}else {
|
||||
$calendar .= '<td class="text-center py-2">' . $number . '</td>';
|
||||
}
|
||||
$flag = 1;
|
||||
}else{
|
||||
$calendar .= '<td></td>';
|
||||
}
|
||||
}else{
|
||||
if (in_array($number, $post['post'])) {
|
||||
$calendar .= '<td class="active text-center py-2">' . '<a rel="archives" href="' . $monthUrl . $zero . $number . '/' . '" class="p-0" title="' . $postCount[$number] . '篇文章" data-toggle="tooltip" data-placement="top"><b>' . $number . '</b></a>' . '</td>';
|
||||
}else {
|
||||
$calendar .= '<td class="text-center py-2">' . $number . '</td>';
|
||||
}
|
||||
}
|
||||
if($flag){
|
||||
$number ++;
|
||||
}
|
||||
}else{
|
||||
$calendar .= '<td></td>';
|
||||
}
|
||||
}
|
||||
$calendar .= '</tr>';
|
||||
}
|
||||
|
||||
$calendar .= '</tbody></table>';
|
||||
|
||||
return array(
|
||||
'calendar' => $calendar,
|
||||
'previous' => is_array($post['previous'])?false:$post['previous'],
|
||||
'next' => is_array($post['next'])?false:$post['next'],
|
||||
'previousUrl' => $previousUrl,
|
||||
'nextUrl' => $nextUrl
|
||||
);
|
||||
}
|
||||
// 获取分类数量
|
||||
function categoryCount() {
|
||||
$db = Typecho_Db::get();
|
||||
$count = $db->fetchRow($db->select('COUNT(*)')->from('table.metas')->where('type = ?', 'category'));
|
||||
return $count['COUNT(*)'];
|
||||
}
|
||||
|
||||
// 获取标签数量
|
||||
function tagCount() {
|
||||
$db = Typecho_Db::get();
|
||||
$count = $db->fetchRow($db->select('COUNT(*)')->from('table.metas')->where('type = ?', 'tag'));
|
||||
return $count['COUNT(*)'];
|
||||
}
|
||||
|
||||
// 获取总阅读量
|
||||
function viewsCount() {
|
||||
$db = Typecho_Db::get();
|
||||
$count = $db->fetchRow($db->select('SUM(views) AS viewsCount')->from('table.contents'));
|
||||
return $count['viewsCount'];
|
||||
}
|
||||
|
||||
// 获取阅读量排名前 5 的 5 篇文章的信息
|
||||
function top5post() {
|
||||
$db = Typecho_Db::get();
|
||||
$top5Post = $db->fetchAll($db->select()->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish')->order('views', Typecho_Db::SORT_DESC)->offset(0)->limit(5));
|
||||
$postList =array();
|
||||
foreach ($top5Post as $post) {
|
||||
$post = Typecho_Widget::widget('Widget_Abstract_Contents')->filter($post);
|
||||
array_push($postList, array(
|
||||
'title' => $post['title'],
|
||||
'link' => $post['permalink'],
|
||||
'views' => $post['views']
|
||||
));
|
||||
}
|
||||
return $postList;
|
||||
}
|
||||
|
||||
// 获取评论数排名前 5 的 5 篇文章的信息
|
||||
function top5CommentPost() {
|
||||
$db = Typecho_Db::get();
|
||||
$top5Post = $db->fetchAll($db->select()->from('table.contents')->where('type = ?', 'post')->where('status = ?', 'publish')->order('commentsNum', Typecho_Db::SORT_DESC)->offset(0)->limit(5));
|
||||
$postList = array();
|
||||
foreach ($top5Post as $post) {
|
||||
$post = Typecho_Widget::widget('Widget_Abstract_Contents')->filter($post);
|
||||
array_push($postList, array(
|
||||
'title' => $post['title'],
|
||||
'link' => $post['permalink'],
|
||||
'commentsNum' => $post['commentsNum']
|
||||
));
|
||||
}
|
||||
return $postList;
|
||||
}
|
||||
// 获取 ECharts 格式要求的文章更新日历
|
||||
function postCalendar($start, $end) {
|
||||
$db = Typecho_Db::get();
|
||||
$dateList = $db->fetchAll($db->select('created')->from('table.contents')->where('created > ?', $start)->where('created < ?', $end));
|
||||
if (count($dateList) < 1) {
|
||||
return array();
|
||||
}
|
||||
$dateList2 = array();
|
||||
foreach ($dateList as $val) {
|
||||
array_push($dateList2, date('Y-m-d', $val['created']));
|
||||
}
|
||||
$dateList2 = array_count_values($dateList2);
|
||||
$key = array_keys($dateList2);
|
||||
$dateList = array();
|
||||
|
||||
for ($i = 0;$i < count($dateList2);$i ++) {
|
||||
array_push($dateList, array(
|
||||
$key[$i],
|
||||
$dateList2[$key[$i]]
|
||||
));
|
||||
}
|
||||
|
||||
return $dateList;
|
||||
}
|
||||
|
||||
// 获取 ECharts 格式要求的评论更新日历
|
||||
function commentCalendar($start, $end) {
|
||||
$db = Typecho_Db::get();
|
||||
$dateList = $db->fetchAll($db->select('created')->from('table.comments')->where('created > ?', $start)->where('created < ?', $end));
|
||||
if (count($dateList) < 1) {
|
||||
return array();
|
||||
}
|
||||
$dateList2 = array();
|
||||
foreach ($dateList as $val) {
|
||||
array_push($dateList2, date('Y-m-d', $val['created']));
|
||||
}
|
||||
$dateList2 = array_count_values($dateList2);
|
||||
$key = array_keys($dateList2);
|
||||
$dateList = array();
|
||||
|
||||
for ($i = 0;$i < count($dateList2);$i ++) {
|
||||
array_push($dateList, array(
|
||||
$key[$i],
|
||||
$dateList2[$key[$i]]
|
||||
));
|
||||
}
|
||||
|
||||
return $dateList;
|
||||
}
|
||||
// 获取个分类的文章数量
|
||||
function categoryPostCount() {
|
||||
$db = Typecho_Db::get();
|
||||
$count = $db->fetchAll($db->select('name', 'count AS value')->from('table.metas')->where('type = ?', 'category'));
|
||||
if (count($count) < 1) {
|
||||
return array();
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
// 获取父分类的名称
|
||||
function getParentCategory($categoryId) {
|
||||
$db = Typecho_Db::get();
|
||||
$category = $db->fetchRow($db->select()->from('table.metas')->where('mid = ?', $categoryId));
|
||||
return $category['name'];
|
||||
}
|
||||
|
||||
// 计算两个时间之间相差的天数
|
||||
function getDays($time1, $time2) {
|
||||
return floor(($time2 - $time1) / 86400);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php ini_set('display_errors', 1);
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
error_reporting(E_ALL);
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
@@ -15,12 +17,12 @@ error_reporting(E_ALL);if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
'date' => _t('在<span> %s </span>发布的文章'),
|
||||
'author' => _t('%s 发布的文章')
|
||||
), '', ' - '); ?><?php if ($this->is('post')) $this->category(',', false);?><?php if ($this->is('post')) echo ' - ';?><?php $this->options->title(); ?><?php if ($this->is('index')) echo ' - '; ?><?php if ($this->is('index')) $this->options->description() ?></title>
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('/dist/css/style.css'); ?>">
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('/dist/css/style.min.css'); ?>">
|
||||
<?php if ($this->options->icoUrl): ?>
|
||||
<link rel='icon' href='<?php $this->options->icoUrl() ?>' type='image/x-icon' />
|
||||
<?php endif; ?>
|
||||
<?php $this->header("generator=&template=&pingback=&wlw=&xmlrpc=&rss1=&atom=&rss2=/feed"); ?>
|
||||
<?php $this->options->addhead(); ?>
|
||||
<?php $this->options->addhead(); ?>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
@@ -50,26 +52,21 @@ error_reporting(E_ALL);if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="inner">
|
||||
<nav>
|
||||
<ul>
|
||||
<li class="whome"><a <?php if($this->is('index')): ?> class="current"<?php endif; ?> href="<?php $this->options->siteUrl(); ?>"><?php _e('首页'); ?></a></li>
|
||||
|
||||
<?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
|
||||
<?php while($pages->next()): ?>
|
||||
<li><a <?php if($this->is('page', $pages->slug)): ?> class="current"<?php endif; ?> href="<?php $pages->permalink(); ?>" title="<?php $pages->title(); ?>"><?php $pages->title(); ?></a></li>
|
||||
<?php endwhile; ?>
|
||||
|
||||
<?php endwhile; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- 这年头谁会用站内的搜索啊 -->
|
||||
<!-- 这年头谁会用站内的搜索啊 -->
|
||||
<div class="search--area">
|
||||
<form id="search" method="post" action="./" role="search" class="search-form">
|
||||
<label>
|
||||
<input type="text" name="s" class="search-field text" placeholder="Search" required/>
|
||||
</label>
|
||||
<button type="submit" class="search-submit submit">搜索</button>
|
||||
</form>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<svg class="svgIcon" width="25" height="25" data-action="show-search">
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* 移植自HUGO主题`farallon`原作者`bigfa`
|
||||
* @package farallon
|
||||
* 移植自HUGO主题 farallon 原作者 bigfa
|
||||
* @package Farallon
|
||||
* @author 老孙
|
||||
* @version 0.4.1
|
||||
* @link https://imsun.org
|
||||
* @version 0.5.7
|
||||
* @link https://www.imsun.org
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$this->need('header.php');
|
||||
?>
|
||||
<main class="site--main">
|
||||
|
||||
<div class="articleList">
|
||||
<?php $this->need('postlist.php'); ?>
|
||||
</div>
|
||||
</main>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 无评论页面
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<main class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
</header>
|
||||
<article class="post--single">
|
||||
<div class="graph u-marginBottom30">
|
||||
<?php $this->content(); ?>
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
@@ -10,41 +10,54 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<?php Typecho_Widget::widget('Widget_Stat')->to($quantity); ?>
|
||||
<h2 class="archive--title__year">共包含 <?php $quantity->publishedPostsNum(); ?> 篇文章</h2>
|
||||
<h2 class="post--single__subtitle">共包含 <?php $quantity->publishedPostsNum(); ?> 篇文章</h2>
|
||||
<?php if ($this->options->showallwords): ?>
|
||||
<h3><?php echo allwords(); ?></h3>
|
||||
<?php endif; ?>
|
||||
<h3><?php echo allwords(); ?></h3>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
<div class="page--archive" >
|
||||
<?php
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=' . $stat->publishedPostsNum)->to($archives);
|
||||
$year = 0;
|
||||
$mon = 0;
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
$output = '<div class="archives">';
|
||||
while ($archives->next()) {
|
||||
<div class="page--archive">
|
||||
<?php
|
||||
$stat = Typecho_Widget::widget('Widget_Stat');
|
||||
Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=' . $stat->publishedPostsNum)->to($archives);
|
||||
$year = 0; $mon = 0;
|
||||
$output = '<div class="archives">'; // Start archives container
|
||||
while ($archives->next()) {
|
||||
$year_tmp = date('Y', $archives->created);
|
||||
$mon_tmp = date('m', $archives->created);
|
||||
$y = $year;
|
||||
$m = $mon;
|
||||
if ($year > $year_tmp || $mon > $mon_tmp) {
|
||||
$output .= '</ul>';
|
||||
$mon_tmp = date('m', $archives->created);
|
||||
// 检查是否需要新的年份标题
|
||||
if ($year != $year_tmp) {
|
||||
if ($year > 0) {
|
||||
$output .= '</ul></div>'; // 结束上一个年份的月份列表和包裹的div
|
||||
}
|
||||
$year = $year_tmp;
|
||||
$mon = 0; // 重置月份
|
||||
$output .= '<div class="archive-year"><h2 class="archive--title__year">' . $year . '</h2>'; // 开始新的年份div
|
||||
}
|
||||
// 检查是否需要新的月份标题
|
||||
if ($mon != $mon_tmp) {
|
||||
if ($mon > 0) {
|
||||
$output .= '</ul>'; // 结束上一个月份的列表
|
||||
}
|
||||
$mon = $mon_tmp;
|
||||
$output .= '<h3 class="archive--title__month"></h3>';// '. $mon . '
|
||||
$output .= '<ul class="archive--list">'; // 开始新的月份列表
|
||||
}
|
||||
// 输出文章项
|
||||
$output .= '<li class="archive--item">';
|
||||
$output .= '<div class="archive--title"><a href="' . $archives->permalink . '">' . $archives->title . '</a></div>';
|
||||
$output .= '<div class="archive--meta">' . date('m月d日', $archives->created) . '</div></li>';
|
||||
}
|
||||
if ($year != $year_tmp || $mon != $mon_tmp) {
|
||||
$year = $year_tmp;
|
||||
$mon = $mon_tmp;
|
||||
$output .= '<h2 class="archive--title__year">' . date('Y年', $archives->created) . '</h2>
|
||||
<h3 class="archive--title__month">'. date('m月', $archives->created) .'</h3><ul class="archive--list" aria-label="' . date('Y年m月', $archives->created) . '">
|
||||
'; //输出年份
|
||||
// 循环后,确保所有标签都已经关闭
|
||||
if ($mon > 0) {
|
||||
$output .= '</ul>'; // 结束最后一个月份的列表
|
||||
}
|
||||
$output .= '<li class="archive--item"><div class="archive--title"><a href="' . $archives->permalink . '">' . $archives->title . '</a></div>
|
||||
<div class="archive--meta">' . date('m月d日', $archives->created) . '</div> </li>'; //输出文章
|
||||
if ($year > 0) {
|
||||
$output .= '</div>'; // 结束最后一个年份的div
|
||||
}
|
||||
$output .= ' </ul></div>';
|
||||
echo $output;?>
|
||||
</div>
|
||||
$output .= '</div>'; // End archives container
|
||||
echo $output;
|
||||
?>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
|
||||
@@ -9,19 +9,29 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<section class="category--list">
|
||||
<?php $this->widget('Widget_Metas_Category_List')->parse('
|
||||
<div class="category--item">
|
||||
<img src="https://static.fatesinger.com/2021/12/vhp6eou5x2wqh2zy.jpg" class="category--cover"/>
|
||||
<div class="category--content">
|
||||
<a href="{permalink}" class="category--card">{name}
|
||||
<span>({count})</span>
|
||||
</a>
|
||||
<div class="category--desc">{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
'); ?>
|
||||
<?php $this->widget('Widget_Metas_Category_List')->to($categories); ?>
|
||||
<?php while($categories->next()): ?>
|
||||
<?php
|
||||
// 获取分类 ID
|
||||
$categoryId = $categories->mid;
|
||||
// 获取主题URL
|
||||
$themeUrl = $this->options->themeUrl;
|
||||
// 为每个分类生成图片地址
|
||||
$categoryImage = $themeUrl . '/dist/img/' . $categoryId . '.jpg';
|
||||
?>
|
||||
<div class="category--item">
|
||||
<img class="category--cover" src="<?php echo $categoryImage; ?>" loading="lazy" alt="<?php $categories->name(); ?>">
|
||||
<div class="category--content">
|
||||
<a class="category--card" href="<?php $categories->permalink(); ?>"><?php $categories->name(); ?>
|
||||
<span>(<?php $categories->count(); ?>)</span></a>
|
||||
<div class="category--desc"> <?php $categories->description(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</section>
|
||||
</div>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
/**
|
||||
* 网站数据
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$this->need('header.php');
|
||||
?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<article class="post--single">
|
||||
<div class="graph u-marginBottom30">
|
||||
<div data-target="<?php $this->options->postLinkOpen(); ?>" class="post-content">
|
||||
<h2>分类占比</h2>
|
||||
<p>下面是个分类的文章占比:</p>
|
||||
<div id="category-chart" style="height: 390px;"></div>
|
||||
<h2>文章更新</h2>
|
||||
<p>下面是 <?php echo date('Y年m月d日', time() - 20736000); ?> 到 <?php echo date('Y年m月d日', time()); ?> 的文章更新情况</p>
|
||||
<div id="post-chart" style="height: 250px;"></div>
|
||||
<h2>评论动态</h2>
|
||||
<p>下面是 <?php echo date('Y年m月d日', time() - 20736000); ?> 到 <?php echo date('Y年m月d日', time()); ?> 的评论动态</p>
|
||||
<div id="comment-chart" style="height: 250px;"></div>
|
||||
<h2>最多阅读的文章</h2>
|
||||
<?php $top5Post = top5post(); ?>
|
||||
<p>下面是阅读量排名前 <?php echo count($top5Post); ?> 的文章</p>
|
||||
<table class="pure-table pure-table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>排名</th>
|
||||
<th>文章</th>
|
||||
<th>阅读量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $top = 1; ?>
|
||||
<?php foreach ($top5Post as $post): ?>
|
||||
<tr>
|
||||
<td><?php echo $top; ?></td>
|
||||
<td><a href="<?php echo $post['link']; ?>"><?php echo $post['title']; ?></a></td>
|
||||
<td><?php echo $post['views']; ?></td>
|
||||
</tr>
|
||||
<?php $top ++; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2>最多评论的文章</h2>
|
||||
<?php $top5CommentPost = top5CommentPost(); ?>
|
||||
<p>下面是评论数排名前 <?php echo count($top5CommentPost); ?> 的文章:</p>
|
||||
<table class="pure-table pure-table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>排名</th>
|
||||
<th>文章</th>
|
||||
<th>评论数</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $top = 1; ?>
|
||||
<?php foreach ($top5CommentPost as $post): ?>
|
||||
<tr>
|
||||
<td><?php echo $top; ?></td>
|
||||
<td><a href="<?php echo $post['link']; ?>"><?php echo $post['title']; ?></a></td>
|
||||
<td><?php echo $post['commentsNum']; ?></td>
|
||||
</tr>
|
||||
<?php $top ++; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<script type="text/javascript">
|
||||
var data = {
|
||||
post: <?php echo json_encode(postCalendar(time() - 20736000, time())); ?>,
|
||||
comment: <?php echo json_encode(commentCalendar(time() - 20736000, time())); ?>,
|
||||
category: <?php echo json_encode(categoryPostCount()); ?>
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/jkjoy/typecho-theme-farallon@0.5.0/dist/js/chart.js"></script>
|
||||
<script id="MathJax-script" async src="https://jsd.onmicrosoft.cn/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
||||
<script>
|
||||
// 配置 MathJax
|
||||
MathJax = {
|
||||
tex: {
|
||||
inlineMath: [['$', '$']],
|
||||
displayMath: [['$$', '$$']],
|
||||
processEscapes: true,
|
||||
processEnvironments: true,
|
||||
},
|
||||
options: {
|
||||
skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
||||
},
|
||||
};
|
||||
// 刷新预时重新渲染
|
||||
document.addEventListener('pjax:complete', () => {
|
||||
MathJax.typesetPromise();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
td,th {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.pure-table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
empty-cells: show;
|
||||
border: 1px solid #cbcbcb;
|
||||
}
|
||||
|
||||
.pure-table caption {
|
||||
color: #000;
|
||||
font: italic 85%/1 arial,sans-serif;
|
||||
padding: 1em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pure-table td,.pure-table th {
|
||||
border-left: 1px solid #cbcbcb;
|
||||
border-width: 0 0 0 1px;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
padding: .5em 1em;
|
||||
}
|
||||
|
||||
.pure-table thead {
|
||||
background-color: #e0e0e0;
|
||||
color: #000;
|
||||
text-align: left;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.pure-table td {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.pure-table-bordered td {
|
||||
border-bottom: 1px solid #cbcbcb;
|
||||
}
|
||||
|
||||
.pure-table-bordered tbody>tr:last-child>td {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
</style>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -6,13 +6,20 @@
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/db.js'); ?>"></script>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle">观影数据来源于豆瓣</h2>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?></h2>
|
||||
</header>
|
||||
|
||||
<div data-status="watched" class="douban-movie-list doubanboard-list"></div>
|
||||
|
||||
<div class="site--main">
|
||||
<div class="db--container"></div>
|
||||
<script>
|
||||
new Douban({
|
||||
baseAPI: '<?php $this->options->doubanID() ?>', // api
|
||||
container: ".db--container", // 容器名
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</section>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* 好物页面
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main site--main__gears">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?></h2>
|
||||
</header>
|
||||
<div id=goods class="good--list"></div>
|
||||
</div>
|
||||
<style>
|
||||
.img40 {
|
||||
height: 137px;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
// 检查是否存在自定义字段 'memos' 和 'memosID'
|
||||
$memos = $this->fields->memos ? $this->fields->memos : 'https://memos.imsun.org';
|
||||
$memosID = $this->fields->memosID ? $this->fields->memosID : '1';
|
||||
$memostag = $this->fields->memostag ? $this->fields->memostag : '好物';
|
||||
?>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
memoGoods();
|
||||
});
|
||||
function memoGoods(e) {
|
||||
let t = e || 12;
|
||||
var n = "<?php echo $memos; ?>",
|
||||
s = n + "/api/v1/memo?creatorId=<?php echo $memosID; ?>&limit=" + t + "&tag=<?php echo $memostag; ?>";
|
||||
let i = 1;
|
||||
const o = /\n/;
|
||||
fetch(s).then(e => e.json()).then(e => {
|
||||
let c = "";
|
||||
for (var t, s, i, a, d, u, h, m, r = 0; r < e.length; r++) {
|
||||
a = e[r].content.replace(`#好物 \n`, ""),
|
||||
t = a.split(o),
|
||||
i = t[0].replace(/!\[.*?\]\((.*?)\)/g, "$1"), // 图片链接
|
||||
s = t[0].replace(/!\[(.*?)\]\(.*?\)/g, "$1"),
|
||||
d = s.split(",")[0], // 商品名称
|
||||
u = s.split(",")[1], // 价格
|
||||
h = t[1].replace(/\[.*?\]\((.*?)\)/g, "$1"), // 商品链接
|
||||
m = t[1].replace(/\[(.*?)\]\(.*?\)/g, "$1"), // 推荐理由
|
||||
c +=
|
||||
'<div class="good--item"><div class="img-spacer"><a href="'
|
||||
+ h +
|
||||
'" target="_blank"><img src="'
|
||||
+ i +
|
||||
'" class="img40"></a></div><div class="good--name"><div class="brand">'
|
||||
+ d + '·' + m +'</div>'
|
||||
+ u +
|
||||
'</div></div>';
|
||||
}
|
||||
let f = document.querySelector("#goods");
|
||||
f.innerHTML = c;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -9,9 +9,8 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="archive--title__year"> </h2>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
|
||||
<div class="graph u-marginBottom30">
|
||||
<?php $this->content(); ?>
|
||||
</div>
|
||||
@@ -30,5 +29,4 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<?php $this->need('footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* 说说页面 - Mastodon
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<article class="post--single">
|
||||
<?php $tooot = $this->fields->tooot ? $this->fields->tooot : 'https://bbapi.ima.cm'; ?>
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
|
||||
<div id="tooot"></div>
|
||||
<div class="nav-links" id="loadmore">
|
||||
<span class="loadmore">加载更多</span>
|
||||
</div>
|
||||
</article>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
let offset = 0; // 初始偏移量
|
||||
const limit = 20; // 每次加载的数量
|
||||
function formatHTML(toots) {
|
||||
let htmlString = '';
|
||||
toots.forEach(toot => {
|
||||
const { content, account, url, created_at, media_attachments} = toot;
|
||||
let mediaHTML = ''; // 初始化资源相关HTML为空字符串
|
||||
// 处理媒体附件
|
||||
if (media_attachments.length > 0) {
|
||||
media_attachments.forEach(attachment => {
|
||||
if (attachment.type === 'image') {
|
||||
mediaHTML += `<a href="${attachment.url}" target="_blank"><img src="${attachment.preview_url}" data-fancybox="img" class="thumbnail-image img"></a>`;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 使用 marked 转换 markdown 内容为 HTML
|
||||
const htmlContent = marked.parse(content);
|
||||
// 创建 HTML 字符串
|
||||
htmlString += `
|
||||
<article class='post--item post--item__status'>
|
||||
<div class='content'>
|
||||
<header>
|
||||
<img src="${account.avatar}" class="avatar" width="48" height="48" />
|
||||
<a class="humane--time" href="${url}" target="_blank">${new Date(created_at).toLocaleString()}</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
${htmlContent}
|
||||
<div class="resimg">${mediaHTML}</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>`;
|
||||
});
|
||||
return htmlString;
|
||||
}
|
||||
function fetchToots() {
|
||||
return fetch('<?php echo $tooot; ?>')
|
||||
.then(response => response.json())
|
||||
.catch(error => {
|
||||
console.error('Error fetching toots:', error);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
function fetchAndDisplayToots() {
|
||||
fetchToots().then(data => {
|
||||
const memosContainer = document.getElementById('tooot');
|
||||
const tootsToShow = data.slice(offset, offset + limit); // 选择要显示的toots
|
||||
memosContainer.innerHTML += formatHTML(tootsToShow);
|
||||
offset += limit; // 更新偏移量
|
||||
// 如果没有更多的toots,隐藏“加载更多”按钮
|
||||
if (offset >= data.length) {
|
||||
document.getElementById('loadmore').style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
// 在页面加载完成后获取并展示 toots
|
||||
fetchAndDisplayToots();
|
||||
// 绑定“加载更多”按钮的点击事件
|
||||
document.getElementById('loadmore').addEventListener('click', fetchAndDisplayToots);
|
||||
};
|
||||
Fancybox.bind("[data-fancybox]", {
|
||||
// Your custom options
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
div pre code {
|
||||
/* 迫使文字断行 */
|
||||
white-space: pre-wrap; /* CSS3 */
|
||||
word-wrap: break-word; /* 老版本的浏览器 */
|
||||
overflow-wrap: break-word;
|
||||
/* 指定如何断行 */
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
div p a {
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
.resimg {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
}
|
||||
/* 单个缩略图的样式 */
|
||||
.thumbnail-image {
|
||||
width: 100%; /* 确保其宽度填满父容器 */
|
||||
height: 200px; /* 固定高度 */
|
||||
display: flex; /* 使用 flexbox 居中 */
|
||||
align-items: center; /* 垂直居中 */
|
||||
justify-content: center; /* 水平居中 */
|
||||
overflow: hidden; /* 确保容器内的多余内容不会显示出来 */
|
||||
border-radius: 4px; /* 圆角 */
|
||||
transition: transform .3s ease; /* 鼠标悬停时的过渡效果 */
|
||||
cursor: zoom-in; /* 鼠标指针变为放大镜 */
|
||||
}
|
||||
img {
|
||||
object-fit: cover; /* 保持图片的纵横比,但会将图片裁剪以填充容器 */
|
||||
object-position: center; /* 保证中央部分 */
|
||||
}
|
||||
/* 缩略图内的图片样式 */
|
||||
.thumbnail-image img {
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
}
|
||||
/* 当屏幕宽度小于732px时 */
|
||||
@media (max-width: 732px) {
|
||||
.resimg {
|
||||
grid-template-columns: repeat(2, 1fr); /* 修改为两列 */
|
||||
}
|
||||
}
|
||||
/* 当屏幕宽度小于400px时 */
|
||||
@media (max-width: 400px) {
|
||||
.resimg {
|
||||
grid-template-columns: 1fr; /* 修改为一列 */
|
||||
}
|
||||
.thumbnail-image img {
|
||||
width: 100%;
|
||||
height: 480px;
|
||||
}
|
||||
}
|
||||
.load-more-btn {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
padding: 10px 20px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.load-more-btn:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.nav-links .loadmore {
|
||||
border: 1px solid var(--farallon-border-color);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding: 5px 30px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
color: var(--farallon-text-gray)
|
||||
}
|
||||
|
||||
.nav-links .loadmore:hover {
|
||||
border-color: var(--farallon-hover-color);
|
||||
color: var(--farallon-hover-color)
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* 说说页面 - memos
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<div class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<?php
|
||||
// 检查是否存在自定义字段 'memos' 和 'memosID'
|
||||
$memos = $this->fields->memos ? $this->fields->memos : 'https://memos.loliko.cn';
|
||||
$memosID = $this->fields->memosID ? $this->fields->memosID : '1';
|
||||
$memosnum = $this->fields->memosnum ? $this->fields->memosnum : '20';
|
||||
?>
|
||||
<article class="post--single">
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
|
||||
<div id="talk"></div>
|
||||
</article>
|
||||
<script>
|
||||
if (99) {
|
||||
let url = '<?php echo $memos; ?>';
|
||||
fetch(url + '/api/v1/memo?creatorId=<?php echo $memosID; ?>&rowStatus=NORMAL&limit=<?php echo $memosnum; ?>')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
let html = '';
|
||||
data.forEach(item => {
|
||||
let data = Format(item);
|
||||
let memoURL = url + '/m/' + item.id;
|
||||
let mdContent = marked.parse(data.content);
|
||||
html += `
|
||||
<article class='post--item post--item__status'>
|
||||
<div class='content'>
|
||||
<header>
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" width="48" height="48" />
|
||||
<a class="humane--time" href="${memoURL}" target="_blank">${data.date}</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
${mdContent}
|
||||
<span class="tag--list"><a>${data.tag}</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
`;
|
||||
});
|
||||
document.getElementById('talk').innerHTML = html;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
// 这里可以添加一些用户提示错误发生的 HTML 更新
|
||||
});
|
||||
function Format(item) {
|
||||
let date = getTime(new Date(item.createdTs * 1000).toString()),
|
||||
content = item.content,
|
||||
tag = item.content.match(/#([^\s#]+?) /g),
|
||||
imgs = content.match(/!\[.*\]\(.*?\)/g),
|
||||
text = ''
|
||||
if (imgs) imgs = imgs.map(item => { return item.replace(/!\[.*\]\((.*?)\)/, '$1') })
|
||||
if (item.resourceList.length) {
|
||||
if (!imgs) imgs = []
|
||||
item.resourceList.forEach(t => {
|
||||
if (t.externalLink) imgs.push(t.externalLink)
|
||||
else imgs.push(`${url}/o/r/${t.id}/${t.publicId}/${t.filename}`)
|
||||
})
|
||||
}
|
||||
text = content.replace(/#(.*?)\s/g, '').replace(/\!?\[(.*?)\]\((.*?)\)/g, '').replace(/\{(.*?)\}/g, '')
|
||||
content = text.replace(/\[(.*?)\]\((.*?)\)/g, `<a href="$2" target="_blank">$1</a>`);
|
||||
if (imgs) {
|
||||
content += `<div class="resimg">`
|
||||
imgs.forEach(e => content += `<a href="${e}" data-fancybox="gallery" class="fancybox img" data-thumb="${e}"><img class="no-lazyload thumbnail-image" src="${e}"></a>`
|
||||
)
|
||||
content += '</div>'
|
||||
}
|
||||
return {
|
||||
content: content,
|
||||
tag: tag ? tag[0].replace(/#([^\s#]+?) /,'$1') : '日常',
|
||||
date: date,
|
||||
text: text.replace(/\[(.*?)\]\((.*?)\)/g, '[链接]' + `${imgs?'[图片]':''}`)
|
||||
}
|
||||
}
|
||||
// 页面时间格式化
|
||||
function getTime(time) {
|
||||
let d = new Date(time),
|
||||
ls = [d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
|
||||
for (let i = 0; i < ls.length; i++) {
|
||||
ls[i] = ls[i] <= 9 ? '0' + ls[i] : ls[i] + ''
|
||||
}
|
||||
if (new Date().getFullYear() == ls[0]) return ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
||||
else return ls[0] + '年' + ls[1] + '月' + ls[2] + '日 ' + ls[3] +':'+ ls[4]
|
||||
}
|
||||
}
|
||||
Fancybox.bind("[data-fancybox]", {
|
||||
// Your custom options
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
div pre code {
|
||||
/* 迫使文字断行 */
|
||||
white-space: pre-wrap; /* CSS3 */
|
||||
word-wrap: break-word; /* 老版本的浏览器 */
|
||||
overflow-wrap: break-word;
|
||||
/* 指定如何断行 */
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
div p a {
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
.thumbnail-image {
|
||||
width:100%;
|
||||
height: 200px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
border-radius:4px;
|
||||
transition:transform .3s ease;
|
||||
cursor:zoom-in;
|
||||
}
|
||||
.resimg {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
column-gap: 10px;
|
||||
row-gap: 10px;
|
||||
}
|
||||
.thumbnail-image img {
|
||||
width:100%;
|
||||
min-height: 200px;
|
||||
object-fit:cover;
|
||||
}
|
||||
img {
|
||||
object-fit: cover; /* 保持图片的纵横比,但会将图片裁剪以填充容器 */
|
||||
object-position: center; /* 保证中央部分 */
|
||||
}
|
||||
/* 当屏幕宽度小于732px时 */
|
||||
@media (max-width: 732px) {
|
||||
.resimg {
|
||||
grid-template-columns: repeat(2, 1fr); /* 修改为两列 */
|
||||
}
|
||||
}
|
||||
/* 当屏幕宽度小于400px时 */
|
||||
@media (max-width: 400px) {
|
||||
.resimg {
|
||||
grid-template-columns: 1fr; /* 修改为一列 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -9,6 +9,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<div class="post-content">
|
||||
<?php $this->widget('Widget_Metas_Tag_Cloud', 'sort=mid&ignoreZeroCount=1&desc=0')->to($tags); ?>
|
||||
@@ -24,6 +25,5 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<p class="text-center pb-2"><?php _e('没有任何标签'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* 说说页面 - 时光机
|
||||
*
|
||||
* @package custom
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<section class="site--main">
|
||||
<header class="archive--header">
|
||||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<article class="post--single">
|
||||
<?php $this->need('times/dycomment.php'); ?>
|
||||
</article>
|
||||
</section>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -8,7 +8,6 @@
|
||||
<div class="graph u-marginBottom30">
|
||||
<?php $this->content(); ?>
|
||||
</div>
|
||||
|
||||
<!-- 判断如果禁止评论则不显示评论的div -->
|
||||
<?php if ($this->allow('comment')): ?>
|
||||
<?php $this->need('comments.php'); ?>
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php $this->need('header.php'); ?>
|
||||
<style>
|
||||
#toc {font-size:14px;padding:10px 15px;background-color:var(--farallon-background-gray);border-radius:10px;margin-bottom:20px}
|
||||
#toc summary{cursor:pointer}
|
||||
#toc toc-title{font-weight:600}
|
||||
#toc ul{padding-left:10px;margin-bottom:10px}
|
||||
#toc ul li::before{content:"·";margin-right:5px}
|
||||
#toc ul li>ul{margin-left:10px;font-size:12px}
|
||||
</style>
|
||||
<main class="site--main">
|
||||
<article class="post--single">
|
||||
<ul class="meta">
|
||||
@@ -19,21 +27,26 @@
|
||||
d="M12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9ZM11 12C11 11.4477 11.4477 11 12 11C12.5523 11 13 11.4477 13 12C13 12.5523 12.5523 13 12 13C11.4477 13 11 12.5523 11 12Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M21.83 11.2807C19.542 7.15186 15.8122 5 12 5C8.18777 5 4.45796 7.15186 2.17003 11.2807C1.94637 11.6844 1.94361 12.1821 2.16029 12.5876C4.41183 16.8013 8.1628 19 12 19C15.8372 19 19.5882 16.8013 21.8397 12.5876C22.0564 12.1821 22.0536 11.6844 21.83 11.2807ZM12 17C9.06097 17 6.04052 15.3724 4.09173 11.9487C6.06862 8.59614 9.07319 7 12 7C14.9268 7 17.9314 8.59614 19.9083 11.9487C17.9595 15.3724 14.939 17 12 17Z" />
|
||||
</svg><span class="article--views"><a><?php get_post_view($this) ?></a></span> 阅读
|
||||
</svg><span class="article--views"><a><?php get_post_view($this) ?></a></span>
|
||||
<svg viewBox="0 0 24 24" class="icon" aria-hidden="true" width="16" height="16">
|
||||
<g>
|
||||
<path
|
||||
d="M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01zm8.005-6c-3.317 0-6.005 2.69-6.005 6 0 3.37 2.77 6.08 6.138 6.01l.351-.01h1.761v2.3l5.087-2.81c1.951-1.08 3.163-3.13 3.163-5.36 0-3.39-2.744-6.13-6.129-6.13H9.756z">
|
||||
</path>
|
||||
</g>
|
||||
</svg> <a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 评论', '%d 评论'); ?></a>
|
||||
</svg> <a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('0 ', '1 ', '%d '); ?></a>
|
||||
<?php if($this->user->hasLogin() && $this->user->pass('editor', true)): ?>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16">
|
||||
<path
|
||||
d="M362.7 19.3L314.3 67.7 444.3 197.7l48.4-48.4c25-25 25-65.5 0-90.5L453.3 19.3c-25-25-65.5-25-90.5 0zm-71 71L58.6 323.5c-10.4 10.4-18 23.3-22.2 37.4L1 481.2C-1.5 489.7 .8 498.8 7 505s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L421.7 220.3 291.7 90.3z"/>
|
||||
</svg><a href="<?php $this->options->adminUrl('write-post.php?cid=' . $this->cid); ?>" target="_blank" title="编辑文章">Edit</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<h2 class="post--single__title"><?php $this->title() ?></h2>
|
||||
<div class="post--single__content graph" ><?php $this->content(); ?></div>
|
||||
|
||||
<div class="post--single">
|
||||
<?php if($this->options->donate): ?>
|
||||
<!--打赏 -->
|
||||
<?php if($this->options->donate): ?>
|
||||
<!--打赏 -->
|
||||
<div class="post--single__action">
|
||||
<link rel="stylesheet" href="<?php $this->options->themeUrl('/dist/css/donate.css'); ?>">
|
||||
<script type="text/javascript" src="<?php $this->options->themeUrl('/dist/js/donate.js'); ?>"></script>
|
||||
<div class="donate-panel">
|
||||
@@ -56,11 +69,65 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!--打赏结束 -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- TAG -->
|
||||
<?php endif; ?>
|
||||
<!-- 复制链接 -->
|
||||
<?php if($this->options->showshare): ?>
|
||||
<div class="post--share">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<g>
|
||||
<path d="M18.36 5.64c-1.95-1.96-5.11-1.96-7.07 0L9.88 7.05 8.46 5.64l1.42-1.42c2.73-2.73 7.16-2.73 9.9 0 2.73 2.74 2.73 7.17 0 9.9l-1.42 1.42-1.41-1.42 1.41-1.41c1.96-1.96 1.96-5.12 0-7.07zm-2.12 3.53l-7.07 7.07-1.41-1.41 7.07-7.07 1.41 1.41zm-12.02.71l1.42-1.42 1.41 1.42-1.41 1.41c-1.96 1.96-1.96 5.12 0 7.07 1.95 1.96 5.11 1.96 7.07 0l1.41-1.41 1.42 1.41-1.42 1.42c-2.73 2.73-7.16 2.73-9.9 0-2.73-2.74-2.73-7.17 0-9.9z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="text">复制链接</span>
|
||||
<span class="link" @click="copy" data-link="<?php $this->permalink(); ?>"><?php $this->permalink(); ?></span>
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/vue.min.js'); ?>"></script>
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/clipboard.min.js'); ?>"></script>
|
||||
<script>
|
||||
var app = new Vue({
|
||||
el: '.post--share',
|
||||
data() {
|
||||
return {
|
||||
msg: "<?php $this->permalink(); ?>",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//复制方法
|
||||
copy: function () {
|
||||
var that = this;
|
||||
//注意vue umd版本ClipboardJS,而ES包请使用Clipboard
|
||||
var clipboard = new ClipboardJS(".link",{
|
||||
text: function (trigger) {
|
||||
//返回字符串
|
||||
return that.msg;
|
||||
}});
|
||||
clipboard.on("success", (e) => {
|
||||
//复制成功,显示提示
|
||||
this.showCopySuccessToast();
|
||||
clipboard.destroy();
|
||||
});
|
||||
clipboard.on("error", (e) => {
|
||||
//复制失败
|
||||
clipboard.destroy();
|
||||
});
|
||||
},
|
||||
showCopySuccessToast: function() {
|
||||
const toast = document.createElement("div");
|
||||
toast.textContent = "复制成功!";
|
||||
toast.className = "notice--wrapper";
|
||||
document.body.appendChild(toast);
|
||||
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(toast);
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- TAG -->
|
||||
<div class="tag--list artile--tag">
|
||||
<?php $this->tags(' ', true, ' '); ?>
|
||||
</div>
|
||||
@@ -72,21 +139,18 @@
|
||||
<?php if ($this->options->showrelated): ?>
|
||||
<?php $this->need('related.php'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 判断如果禁止评论则不显示评论的div -->
|
||||
<?php if ($this->allow('comment')): ?>
|
||||
<?php $this->need('comments.php'); ?>
|
||||
<?php endif; ?>
|
||||
<!-- 可以使用第三方评论-->
|
||||
<?php $this->options->twikoo(); ?>
|
||||
<!-- 如果设置了第三方评论系统则使用第三方评论 -->
|
||||
<?php if($this->options->twikoo): ?>
|
||||
<?php $this->options->twikoo(); ?>
|
||||
<?php else: ?>
|
||||
<?php $this->need('comments.php'); ?>
|
||||
<?php endif; ?>
|
||||
<!--翻页-->
|
||||
<nav class="navigation post-navigation is-active">
|
||||
<div class="nav-links">
|
||||
|
||||
<div class="nav-previous">
|
||||
<span class="meta-nav"> 上一篇: <?php $this->thePrev('%s','没有了'); ?></span>
|
||||
</div>
|
||||
|
||||
<div class="nav-next">
|
||||
<span class="meta-nav"> 下一篇: <?php $this->theNext('%s','没有了'); ?></span>
|
||||
</div>
|
||||
@@ -94,88 +158,76 @@
|
||||
</nav>
|
||||
</ul>
|
||||
</article>
|
||||
<!--TOC 在宽度大于1400px时才会显示-->
|
||||
</main>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
const targetClassElement = document.querySelector('.post--single__title');
|
||||
const postContent = document.querySelector('.post--single__content');
|
||||
if (!postContent) return;
|
||||
|
||||
const postContent = document.querySelector('.post--single__content');
|
||||
if (!postContent) return;
|
||||
|
||||
// 依次查找从h1到h6,直到找到存在的标题级别
|
||||
let found = false;
|
||||
for (let i = 1; i <= 6 && !found; i++) {
|
||||
if (postContent.querySelector(`h${i}`)) {
|
||||
found = true;
|
||||
let found = false;
|
||||
for (let i = 1; i <= 6 &&!found; i++) {
|
||||
if (postContent.querySelector(`h${i}`)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) return;
|
||||
|
||||
if (!found) return; // 如果没有标题,则不继续执行
|
||||
const heads = postContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||
const toc = document.createElement('div');
|
||||
toc.id = 'toc';
|
||||
toc.innerHTML = '<details class="toc" open><summary class="toc-title">目录</summary><nav id="TableOfContents"><ul></ul></nav></details>';
|
||||
|
||||
const heads = postContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||
const toc = document.createElement('div');
|
||||
toc.id = 'toc';
|
||||
toc.innerHTML = '<strong>目录</strong><ul></ul>';
|
||||
document.body.appendChild(toc);
|
||||
|
||||
let currentLevel = 0;
|
||||
let currentList = toc.querySelector('ul ');
|
||||
|
||||
heads.forEach((head, index) => {
|
||||
const level = parseInt(head.tagName.substring(1)); // 提取标题级别
|
||||
|
||||
if (currentLevel === 0) { // 设置初次的级别
|
||||
currentLevel = level;
|
||||
// 插入到指定 class 元素之后
|
||||
if (targetClassElement) {
|
||||
targetClassElement.parentNode.insertBefore(toc, targetClassElement.nextSibling);
|
||||
}
|
||||
|
||||
while (level > currentLevel) { // 如果标题级别增加,则创建新的子列表
|
||||
let newList = document.createElement('ul');
|
||||
if(!currentList.lastElementChild) { // 如果当前列表为空,则直接在其中添加元素
|
||||
currentList.appendChild(newList);
|
||||
} else {
|
||||
currentList.lastElementChild.appendChild(newList); // 否则,添加到最后一个列表项中
|
||||
}
|
||||
currentList = newList;
|
||||
currentLevel++;
|
||||
}
|
||||
let currentLevel = 0;
|
||||
let currentList = toc.querySelector('ul');
|
||||
let levelCounts = [0];
|
||||
|
||||
while (level < currentLevel) { // 如果标题级别降低,则向上回溯列表层级
|
||||
currentList = currentList.parentElement;
|
||||
if(currentList.tagName.toLowerCase() === 'li') { // 确保回到上一层列表
|
||||
currentList = currentList.parentElement;
|
||||
}
|
||||
currentLevel--;
|
||||
}
|
||||
|
||||
const item = document.createElement('li');
|
||||
const anchor = `toc${index}`;
|
||||
head.id = anchor;
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = `#${anchor}`;
|
||||
link.textContent = head.textContent;
|
||||
|
||||
item.appendChild(link);
|
||||
currentList.appendChild(item);
|
||||
});
|
||||
heads.forEach((head, index) => {
|
||||
const level = parseInt(head.tagName.substring(1));
|
||||
if (levelCounts[level] === undefined) {
|
||||
levelCounts[level] = 1;
|
||||
} else {
|
||||
levelCounts[level]++;
|
||||
}
|
||||
// 重置下级标题的计数器
|
||||
levelCounts = levelCounts.slice(0, level + 1);
|
||||
if (currentLevel === 0) {
|
||||
currentLevel = level;
|
||||
}
|
||||
while (level > currentLevel) {
|
||||
let newList = document.createElement('ul');
|
||||
if (!currentList.lastElementChild) {
|
||||
currentList.appendChild(newList);
|
||||
} else {
|
||||
currentList.lastElementChild.appendChild(newList);
|
||||
}
|
||||
currentList = newList;
|
||||
currentLevel++;
|
||||
levelCounts[currentLevel] = 1;
|
||||
}
|
||||
while (level < currentLevel) {
|
||||
currentList = currentList.parentElement;
|
||||
if (currentList.tagName.toLowerCase() === 'li') {
|
||||
currentList = currentList.parentElement;
|
||||
}
|
||||
currentLevel--;
|
||||
}
|
||||
const anchor = head.textContent.trim().replace(/\s+/g, '-');
|
||||
head.id = anchor;
|
||||
const item = document.createElement('li');
|
||||
const link = document.createElement('a');
|
||||
link.href = `#${anchor}`;
|
||||
link.textContent = `${head.textContent}`;
|
||||
link.style.textDecoration = 'none';
|
||||
item.appendChild(link);
|
||||
currentList.appendChild(item);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 100px;
|
||||
right: 50px;
|
||||
max-width: 200px;
|
||||
background-color: var(--farallon-background-gray);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
/* 其他样式... */
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
#toc {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</main>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
<?php $this->need('footer.php'); ?>
|
||||
@@ -1,11 +1,76 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php
|
||||
//确保退出安全
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
/** 文章置顶 */
|
||||
$sticky = $this->options->sticky ; //置顶的文章id,多个用|隔开
|
||||
|
||||
if ($sticky) {
|
||||
$sticky_cids = array_filter(explode('|', $sticky)); //分割文本并过滤空值
|
||||
$sticky_html = " <span class=sticky--post> 置顶 </span> "; //置顶标题的 html
|
||||
|
||||
$db = Typecho_Db::get();
|
||||
$pageSize = $this->options->pageSize;
|
||||
|
||||
// 构建置顶文章的查询
|
||||
$selectSticky = $this->select()->where('type = ?', 'post');
|
||||
foreach ($sticky_cids as $i => $cid) {
|
||||
if($i == 0)
|
||||
$selectSticky->where('cid = ?', $cid);
|
||||
else
|
||||
$selectSticky->orWhere('cid = ?', $cid);
|
||||
}
|
||||
|
||||
// 清空原有文章的列队
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
|
||||
// 只在首页第一页展示置顶文章
|
||||
if (($this->_currentPage || $this->currentPage) == 1) {
|
||||
$stickyPosts = $db->fetchAll($selectSticky);
|
||||
foreach ($stickyPosts as $stickyPost) {
|
||||
$stickyPost['title'] = $stickyPost['title'] . $sticky_html;
|
||||
$this->push($stickyPost); //压入列队
|
||||
}
|
||||
}
|
||||
|
||||
// 构建普通文章的查询,排除置顶文章的 CID
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page($this->_currentPage, $pageSize);
|
||||
|
||||
foreach ($sticky_cids as $cid) {
|
||||
$selectNormal->where('table.contents.cid != ?', $cid);
|
||||
}
|
||||
|
||||
// 登录用户显示私密文章
|
||||
if ($this->user->hasLogin()) {
|
||||
$uid = $this->user->uid;
|
||||
if ($uid) {
|
||||
$selectNormal->orWhere('authorId = ? AND status = ?', $uid, 'private');
|
||||
}
|
||||
}
|
||||
|
||||
$normalPosts = $db->fetchAll($selectNormal);
|
||||
foreach ($normalPosts as $normalPost) {
|
||||
$this->push($normalPost); //压入列队
|
||||
}
|
||||
|
||||
// 设置总数(减去置顶文章数量,以进行正确的分页)
|
||||
$total = $this->getTotal() - count($sticky_cids);
|
||||
$this->setTotal(max($total, 0)); // 确保总数不为负数
|
||||
}
|
||||
?>
|
||||
<?php while($this->next()): ?>
|
||||
<article class="post--item">
|
||||
<div class="content">
|
||||
<h2 class="post--title">
|
||||
<a href="<?php $this->permalink() ?>">
|
||||
<!--三天内显示火苗-->
|
||||
<?php $this->title() ?>
|
||||
<?php $this->title() ?>
|
||||
<?php if((time() - $this->created) < 60*60*24*3): ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
class="icon--sticky" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
@@ -53,16 +118,18 @@
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
<a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('评论', '1 评论', '%d 评论'); ?></a>
|
||||
<a href="<?php $this->permalink() ?>#comments"><?php $this->commentsNum('0 ', '1 ', '%d '); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php $firstImage = show_first_image($this->content); ?>
|
||||
<?php if($firstImage): ?>
|
||||
<img src="<?php echo $firstImage; ?>" alt="文章图片" class="cover"/>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$firstImage = img_postthumb($this->cid);
|
||||
$cover = $this->fields->cover;
|
||||
$imageToDisplay = !empty($cover) ? $cover : $firstImage;
|
||||
if($imageToDisplay): ?>
|
||||
<img src="<?php echo $imageToDisplay; ?>" alt="文章图片" class="cover"/>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
<?php endwhile; ?>
|
||||
|
||||
<?php
|
||||
$this->pagenav(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
@@ -71,7 +138,7 @@
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'cat_pagination_page',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
@@ -80,5 +147,43 @@
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
|
||||
<style>
|
||||
/* 分页 */
|
||||
.pagination_page{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.pagination_page li.active a {
|
||||
background: var(--theme);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.pagination_page a{
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 50%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.pagination_page span.next{
|
||||
cursor: pointer;
|
||||
}
|
||||
.pagination_page li.active a:hover{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 分页 */
|
||||
</style>
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="author--card">
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" height="64" width="64" decoding="async">
|
||||
<div class="author--name">
|
||||
<?php $this->options->author() ?>
|
||||
<?php $this->author(); ?>
|
||||
</div>
|
||||
<div class="author--description">
|
||||
<?php $this->options->description() ?>
|
||||
@@ -10,5 +10,4 @@
|
||||
<div class="author--sns">
|
||||
<?php $this->need('sns.php'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<div class="related--content">
|
||||
<h3 class="related--posts__title">相关文章</h3>
|
||||
<div class="post--single__related">
|
||||
<?php $this->related(6)->to($relatedPosts); ?>
|
||||
|
||||
<?php while ($relatedPosts->next()): ?>
|
||||
<div class="post--single__related__item">
|
||||
<a href="<?php $relatedPosts->permalink(); ?>">
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
class Content
|
||||
{
|
||||
public static function postCommentContent($content, $isLogin, $rememberEmail, $currentEmail, $parentEmail, $isTime = false)
|
||||
{
|
||||
//解析私密评论
|
||||
$flag = true;
|
||||
if (strpos($content, '[secret]') !== false) {//提高效率,避免每篇文章都要解析
|
||||
$pattern = self::get_shortcode_regex(array('secret'));
|
||||
$content = preg_replace_callback("/$pattern/", array('Content', 'secretContentParseCallback'), $content);
|
||||
if ($isLogin || ($currentEmail == $rememberEmail && $currentEmail != "") || ($parentEmail == $rememberEmail && $rememberEmail != "")) {
|
||||
$flag = true;
|
||||
} else {
|
||||
$flag = false;
|
||||
}
|
||||
}
|
||||
if ($flag) {
|
||||
$content = Content::parseContentPublic($content);
|
||||
return $content;
|
||||
} else {
|
||||
if ($isTime) {
|
||||
return '<div class="hideContent">此条为私密说说,仅发布者可见</div>';
|
||||
} else {
|
||||
return '<div class="hideContent">该评论仅登录用户及评论双方可见</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 解析时光机页面的评论内容
|
||||
* @param $content
|
||||
* @return string
|
||||
*/
|
||||
public static function timeMachineCommentContent($content)
|
||||
{
|
||||
return Content::parseContentPublic($content);
|
||||
}
|
||||
/**
|
||||
* 一些公用的解析,文章、评论、时光机公用的,与用户状态无关
|
||||
* @param $content
|
||||
* @return null|string|string[]
|
||||
*/
|
||||
public static function parseContentPublic($content)
|
||||
{
|
||||
$options = Helper::options();
|
||||
//倒计时
|
||||
if (strpos($content, '[countdown') !== false) {
|
||||
$pattern = self::get_shortcode_regex(array('countdown'));
|
||||
$content = preg_replace_callback("/$pattern/", array('Content', 'countdownParseCallback'),
|
||||
$content);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
class UA{
|
||||
public $ua;
|
||||
public function __construct($ua = '')
|
||||
{
|
||||
$this->ua = $ua;
|
||||
}
|
||||
public function returnBrowser(){
|
||||
$ua = $this->ua;
|
||||
if(preg_match('/rv:(11.0)/i', $ua, $matches)){
|
||||
$title = 'Internet Explorer '. $matches[1];
|
||||
$icon = 'fa fa-internet-explorer';//ie11
|
||||
}elseif (preg_match('#MSIE ([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Internet Explorer '. $matches[1];
|
||||
|
||||
if ( strpos($matches[1], '7') !== false || strpos($matches[1], '8') !== false)
|
||||
$icon = 'fa fa-internet-explorer';//ie8
|
||||
elseif ( strpos($matches[1], '9') !== false)
|
||||
$icon = 'fa fa-internet-explorer';//ie9
|
||||
elseif ( strpos($matches[1], '10') !== false)
|
||||
$icon = 'fa fa-internet-explorer';//ie10
|
||||
}elseif (preg_match('#Edge/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Edge '. $matches[1];
|
||||
$icon = 'fa fa-edge';
|
||||
}elseif (preg_match('#TheWorld ([a-zA-Z0-9.]+)#i', $ua, $matches)){
|
||||
$title = 'TheWorld(世界之窗) '. $matches[1];
|
||||
$icon = 'iconfont icon-theworld';
|
||||
}elseif (preg_match('#JuziBrowser#i', $ua, $matches)){
|
||||
$title = 'Juzi(桔子) '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#KBrowser#i', $ua, $matches)){
|
||||
$title = 'KBrowser(超快) '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#MyIE#i', $ua, $matches)){
|
||||
$title = 'MyIE(蚂蚁) '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#(Firefox|Phoenix|Firebird|BonEcho|GranParadiso|Minefield|Iceweasel)/([a-zA-Z0-9.]+)#i', $ua, $matches)){
|
||||
$title = 'Firefox '. $matches[1];
|
||||
$icon = 'fa fa-firefox';
|
||||
}elseif (preg_match('#CriOS/([a-zA-Z0-9.]+)#i', $ua, $matches)){
|
||||
$title = 'Chrome for iOS '. $matches[1];
|
||||
$icon = 'fa fa-chrome';
|
||||
} elseif (preg_match('#LBBROWSER#i', $ua, $matches)) {
|
||||
$title = '猎豹';
|
||||
$icon = 'iconfont icon-liebaoliulanqi';
|
||||
}elseif (preg_match('#Opera.(.*)Version[ /]([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Opera '. $matches[2];
|
||||
$icon = 'fa fa-opera';
|
||||
if (preg_match('#opera mini#i', $ua))
|
||||
$title = 'Opera Mini '. $matches[2];
|
||||
}elseif (preg_match('#Maxthon( |\/)([a-zA-Z0-9.]+)#i', $ua,$matches)) {
|
||||
$title = 'Maxthon(遨游) '. $matches[2];
|
||||
$icon = 'iconfont icon-liulanqi-aoyou';
|
||||
}elseif (preg_match('#360([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '360 Browser '. $matches[1];
|
||||
$icon = 'iconfont icon-liulanqi-jisu';
|
||||
}elseif (preg_match('#SE 2([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'SouGou Browser 2 '.$matches[1];
|
||||
$icon = 'iconfont icon-liulanqi-sougou';
|
||||
}elseif (preg_match('#QQBrowser/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'QQBrowser '.$matches[1];
|
||||
$icon = 'iconfont icon-QQliulanqi';
|
||||
if (preg_match('#Mobile MQQBrowser/([a-zA-Z0-9.]+)#i', $ua,$matches)) {
|
||||
$title = 'Mobile MQQBrowser '. $matches[1];
|
||||
$icon = 'fa fa-qq';
|
||||
}elseif (preg_match('#MicroMessenger/([a-zA-Z0-9.]+)#i', $ua,$matches)) {
|
||||
$title = 'Wechat Browser '. $matches[1];
|
||||
$icon = 'weixin';
|
||||
}
|
||||
}elseif (preg_match('#QQ/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'QQ '.$matches[1];
|
||||
$icon = 'fa fa-qq';
|
||||
}elseif (preg_match('#YYE/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'YYE '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#115Browser/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '115 '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#37abc/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '37abc '.$matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#TheWorld ([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '世界之窗 '.$matches[1];
|
||||
$icon = 'iconfont icon-theworld';
|
||||
}elseif (preg_match('#UCWEB([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'UCWEB '. $matches[1];
|
||||
$icon = 'icon-win8 icon-ucliulanqi';
|
||||
}elseif (preg_match('#UBrowser/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'UBrowser '. $matches[1];
|
||||
$icon = 'iconfont icon-ucliulanqi';
|
||||
}elseif (preg_match('#Quark/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Quark '. $matches[1];
|
||||
$icon = 'iconfont icon-ucliulanqi'; //
|
||||
}elseif (preg_match('#2345Explorer/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '2345Explorer '. $matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('#XiaoMi/MiuiBrowser/([0-9.]+)#i', $ua, $matches)) {
|
||||
$title = '小米 '. $matches[1];
|
||||
$icon = 'iconfont icon-xiaomi';
|
||||
}elseif (preg_match('/WeiBo/i', $ua, $matches)) {
|
||||
$title = '微博 '. $matches[1];
|
||||
$icon = 'iconfont icon-weibo';
|
||||
}elseif (preg_match('/BIDU/i', $ua, $matches)) {
|
||||
$title = '百度 '. $matches[1];
|
||||
$icon = 'iconfont icon-setting';
|
||||
}elseif (preg_match('/mailapp/i', $ua, $matches)) {
|
||||
$title = 'EmailApp '. $matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('/Sleipnir/i', $ua, $matches)) {
|
||||
$title = '神马 '. $matches[1];
|
||||
$icon = 'iconfont icon-weibiaoti--';
|
||||
}elseif (preg_match('/MZBrowser/i', $ua, $matches)) {
|
||||
$title = '魅族 '. $matches[1];
|
||||
$icon = 'iconfont icon-meizu';
|
||||
}elseif (preg_match('/VivoBrowser/i', $ua, $matches)) {
|
||||
$title = 'Vivo '. $matches[1];
|
||||
$icon = 'iconfont icon-VIVO';
|
||||
}elseif (preg_match('/mixia/i', $ua, $matches)) {
|
||||
$title = '米侠 '. $matches[1];
|
||||
$icon = 'fa fa-globe';
|
||||
}elseif (preg_match('/CoolMarket/i', $ua, $matches)) {
|
||||
$title = '酷安 '. $matches[1];
|
||||
$icon = 'iconfont icon-coolapk';
|
||||
}elseif (preg_match('/YaBrowser/i', $ua, $matches)) {
|
||||
$title = 'Yandex '. $matches[1];
|
||||
$icon = 'iconfont icon-yandex';
|
||||
}elseif (preg_match('/Kraitnabo\/([^\s|;]+)/i', $ua, $matches)) {
|
||||
$title = '南博 '. $matches[1];
|
||||
$icon = 'anzhuo';
|
||||
}elseif (preg_match('#Chrome/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Google Chrome '. $matches[1];
|
||||
$icon = 'fa fa-chrome';
|
||||
if (preg_match('#OPR/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Opera '. $matches[1];
|
||||
$icon = 'fa fa-opera';
|
||||
}
|
||||
}elseif (preg_match('#Safari/([a-zA-Z0-9.]+)#i', $ua, $matches)) {
|
||||
$title = 'Safari '. $matches[1];
|
||||
$icon = 'fa fa-safari';
|
||||
}
|
||||
return array("title"=>$title,
|
||||
"icon"=>$icon);
|
||||
}
|
||||
public function returnOS(){
|
||||
$ua = $this->ua;
|
||||
$title = "未知浏览器";
|
||||
$icon = "";
|
||||
if (preg_match('/win/i', $ua)) {
|
||||
if (preg_match('/Windows NT 6.1/i', $ua)) {
|
||||
$title = "Windows 7";
|
||||
$icon = "iconfont icon-win";
|
||||
}elseif (preg_match('/Windows 98/i', $ua)) {
|
||||
$title = "Windows 98";
|
||||
$icon = "iconfont icon-win2";
|
||||
}elseif (preg_match('/Windows NT 5.0/i', $ua)) {
|
||||
$title = "Windows 2000";
|
||||
$icon = "iconfont icon-win2";
|
||||
}elseif (preg_match('/Windows NT 5.1/i', $ua)) {
|
||||
$title = "Windows XP";
|
||||
$icon = "iconfont icon-win";
|
||||
}elseif (preg_match('/Windows NT 5.2/i', $ua)) {
|
||||
if (preg_match('/Win64/i', $ua)) {
|
||||
$title = "Windows XP 64 bit";
|
||||
} else {
|
||||
$title = "Windows Server 2003";
|
||||
}
|
||||
$icon = 'iconfont icon-win';
|
||||
}elseif (preg_match('/Windows NT 6.0/i', $ua)) {
|
||||
$title = "Windows Vista";
|
||||
$icon = "fa fa-windows";
|
||||
}elseif (preg_match('/Windows NT 6.2/i', $ua)) {
|
||||
$title = "Windows 8";
|
||||
$icon = "iconfont icon-win8";
|
||||
}elseif (preg_match('/Windows NT 6.3/i', $ua)) {
|
||||
$title = "Windows 8.1";
|
||||
$icon = "iconfont icon-win8";
|
||||
}elseif (preg_match('/Windows NT 10.0/i', $ua)) {
|
||||
$title = "Windows 10";
|
||||
$icon = "iconfont icon-win3";
|
||||
}elseif (preg_match('/Windows Phone/i', $ua)) {
|
||||
$matches = explode(';',$ua);
|
||||
$title = $matches[2];
|
||||
$icon = "iconfont icon-winphone";
|
||||
}
|
||||
} elseif (preg_match('#iPod.*.CPU.([a-zA-Z0-9.( _)]+)#i', $ua, $matches)) {
|
||||
$title = "iPod ";//.$matches[1]
|
||||
$icon = "iconfont icon-ipod";
|
||||
} elseif (preg_match('/iPhone OS ([_0-9]+)/i', $ua, $matches)) {
|
||||
$title = "Iphone ";//.$matches[1]
|
||||
$icon = "iconfont icon-iphone";
|
||||
} elseif (preg_match('/iPad; CPU OS ([_0-9]+)/i', $ua, $matches)) {
|
||||
$title = "iPad ";//.$matches[1]
|
||||
$icon = "iconfont icon-ipad";
|
||||
} elseif (preg_match('/Mac OS X ([0-9_]+)/i', $ua, $matches)) {
|
||||
if(count(explode(7,$matches[1]))>1) $matches[1] = 'Lion '.$matches[1];
|
||||
elseif(count(explode(8,$matches[1]))>1) $matches[1] = 'Mountain Lion '.$matches[1];
|
||||
$title = "Mac OSX";
|
||||
$icon = "iconfont icon-macosdeicon";
|
||||
} elseif (preg_match('/Macintosh/i', $ua)) {
|
||||
$title = "Mac OS";
|
||||
$icon = "iconfont icon-iconmacos";
|
||||
} elseif (preg_match('/CrOS/i', $ua)){
|
||||
$title = "Google Chrome OS";
|
||||
$icon = "iconfont icon-iconchromeos";
|
||||
} elseif (preg_match('/Linux/i', $ua)) {
|
||||
$title = 'Linux';
|
||||
$icon = 'fa fa-linux';
|
||||
if (preg_match('/Ubuntu/i', $ua)) {
|
||||
$title = "Ubuntu Linux";
|
||||
$icon = "iconfont icon-ubuntu";
|
||||
}elseif(preg_match('#Debian#i', $ua)) {
|
||||
$title = "Debian GNU/Linux";
|
||||
$icon = "iconfont icon-debian";
|
||||
}elseif (preg_match('#Fedora#i', $ua)) {
|
||||
$title = "Fedora Linux";
|
||||
$icon = "iconfont icon-fedora";
|
||||
}elseif (preg_match('/Kraitnabo\/([^\s|;]+)/i', $ua, $matches)) {
|
||||
$title = '南博app '. $matches[1];
|
||||
$icon = 'anzhuo';
|
||||
}elseif (preg_match('/Android.([0-9. _]+)/i',$ua, $matches)) {
|
||||
$title= "Android";
|
||||
$icon = "iconfont icon-android";
|
||||
}
|
||||
} elseif (preg_match('/Android.([0-9. _]+)/i',$ua, $matches)) {
|
||||
$title= "Android";
|
||||
$icon = "iconfont icon-android";
|
||||
}
|
||||
return array("title"=>$title,
|
||||
"icon"=>$icon);
|
||||
}
|
||||
/**
|
||||
* 时光机页面ua,如果是手机设备,只显示设备类型,如果是电脑设备只显示电脑设备类型,如果是扩展发送,显示发送自「扩展」,如果是微信公众号,显示
|
||||
*/
|
||||
public function returnTimeUa(){
|
||||
if ($this->ua == "weixin" || $this->ua == "weChat"){
|
||||
return array("title"=>("微信公众号"),
|
||||
"icon"=>"weixin");
|
||||
}elseif ($this->ua == "crx"){
|
||||
return array("title"=>("Chrome扩展"),
|
||||
"icon"=>"liulanqi");
|
||||
}elseif ($this->ua == "yearcross"){
|
||||
return array("title"=>("YearCross"),
|
||||
"icon"=>"QQ");
|
||||
}elseif ($this->ua == "Kraitnabo"){
|
||||
return array("title"=>("南博app"),
|
||||
"icon"=>"anzhuo");
|
||||
}elseif ($this->ua == "python"){
|
||||
return array("title"=>("python脚本"),
|
||||
"icon"=>"python");
|
||||
}else{
|
||||
$ua = $this->returnOS();
|
||||
$ua["icon"] = "anzhuo";
|
||||
return $ua;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
require_once 'UA.php';
|
||||
require_once 'Content.php';
|
||||
if ($this->user->hasLogin()){
|
||||
$GLOBALS['isLogin'] = true;
|
||||
}else{
|
||||
$GLOBALS['isLogin'] = false;
|
||||
}
|
||||
function threadedComments($comments, $options)
|
||||
{
|
||||
$db = Typecho_Db::get();
|
||||
?>
|
||||
<article class='post--item post--item__status'>
|
||||
<div class='content'>
|
||||
<header>
|
||||
<?php $ua = new UA($comments->agent); ?>
|
||||
<div class="comment--avatar"><?php echo $comments->gravatar('48', ''); ?></div>
|
||||
<?php $comments->author(); ?>
|
||||
<span class="dot"></span>
|
||||
<p class="humane--time"><?php $comments->date('Y年m月d日 H:i'); ?></p>
|
||||
<span class="dot"></span>
|
||||
<?php echo "发自" . $ua->returnTimeUa()['title'];?>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
<?php echo Content::postCommentContent(Content::timeMachineCommentContent($comments->text),$GLOBALS['isLogin'] ,"","","",true); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php } ?>
|
||||
<?php $this->comments()->to($comments); ?>
|
||||
<input type="hidden" class="j-comment-url" value="<?php $this->commentUrl() ?>">
|
||||
<?php if ($this->user->hasLogin()) : ?>
|
||||
<div class="respond" id="comments">
|
||||
<div class="comments--title">有什么新鲜事想告诉大家?</div>
|
||||
<form method="post" id="textarea" class="comment-form" action="<?php $this->commentUrl() ?>">
|
||||
<p class="comment-form-comment">
|
||||
<textarea name="text" id="j-dynamic-form-text" class="textarea" autocomplete="off" rows="3" placeholder="发表您的新鲜事儿..."></textarea>
|
||||
<input type="hidden" value="<?php $this->user->screenName(); ?>" name="author" />
|
||||
<input type="hidden" value="<?php $this->user->mail(); ?>" name="mail" />
|
||||
<input type="hidden" value="<?php $this->options->siteUrl(); ?>" name="url" />
|
||||
<input type="hidden" name="_" value="<?php Typecho_Widget::widget('Widget_Security')->to($security);
|
||||
echo $security->getToken($this->request->getRequestUrl()); ?>">
|
||||
</p>
|
||||
<p class="form-submit">
|
||||
<button type="submit" class="submit"><?php _e('发表(Ctrl+Enter)'); ?></button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php $comments->listComments(['commentUrl'=>$this->commentUrl,'class'=>$this]); ?>
|
||||
<?php
|
||||
$comments->pageNav(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13.1714 12.0007L8.22168 7.05093L9.63589 5.63672L15.9999 12.0007L9.63589 18.3646L8.22168 16.9504L13.1714 12.0007Z" fill="var(--main)"></path></svg>',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
'prevClass' => 'prev',
|
||||
'nextClass' => 'next'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<style>
|
||||
/* 分页 */
|
||||
.pagination_page{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: var(--margin);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.pagination_page li.active a {
|
||||
background: var(--theme);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
.pagination_page a{
|
||||
display: flex;
|
||||
padding: 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 50%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
transition: 0.2s;
|
||||
-webkit-transition: 0.2s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.pagination_page span.next{
|
||||
cursor: pointer;
|
||||
}
|
||||
.pagination_page li.active a:hover{
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 分页 */
|
||||
</style>
|
||||