Compare commits
72 Commits
Author | SHA1 | Date |
---|---|---|
|
18bf403848 | |
|
b0b20298b5 | |
|
15b7523b18 | |
|
59f1d27e27 | |
|
b3c8ea001f | |
|
5c3fd36980 | |
|
c9be23aea0 | |
|
9c40556f6e | |
|
8c9dd30c52 | |
|
74b7bcecff | |
|
b4c55168b4 | |
|
0e343d704f | |
|
e8b1f941b4 | |
|
044fff9185 | |
|
c5c5b94f4f | |
|
5dd748cb53 | |
|
f205c3f37e | |
|
1c18ec0593 | |
|
52f8e45de0 | |
|
acb3f7e9e5 | |
|
92cf4296f2 | |
|
19a3934e6b | |
|
c7d947e313 | |
|
98defefd96 | |
|
53b3cf13a2 | |
|
6ee130ce3d | |
|
8c696e028c | |
|
641c487916 | |
|
2970fc745e | |
|
70979cdb94 | |
|
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 |
62
README.md
62
README.md
|
@ -1,57 +1,21 @@
|
|||
|
||||
## 说明
|
||||
|
||||
移植自 `bigfa `大大的 `hugo-theme-farallon` 原汁原味,可以直接使用 原主题的CSS
|
||||
精简部分 JS.
|
||||
移植自 `bigfa `大大的 `hugo-theme-farallon`
|
||||
|
||||
- 2024.6.5
|
||||
新增了好物的页面 还是通过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
|
||||
|
||||
## 移植进度
|
||||
|
||||
96%
|
||||
https://www.imsun.org/archives/1640.html
|
||||
|
||||
## 功能
|
||||
|
||||
### 已知问题
|
||||
|
||||
由于typecho分类并无图片,所以默认使用
|
||||
`bigfa` 的 `https://static.fatesinger.com/2021/12/vhp6eou5x2wqh2zy.jpg`
|
||||
可以自行替换或者删除
|
||||
|
||||
|
||||
### 豆瓣观影
|
||||
|
||||
使用原版的获取方式
|
||||
更新豆瓣API获取方式
|
||||
|
||||
>豆瓣收藏使用方法
|
||||
微信扫码登录https://node.wpista.com/
|
||||
输入你的豆瓣数字 id,点击保存即可自动同步豆瓣记录。
|
||||
点击 Get integration token 会生成一个 token。
|
||||
[Docker 自动同步豆瓣书影音记录](https://fatesinger.com/103483)
|
||||
|
||||
获取`token`之后填入主题设置项中
|
||||
主题设置处填入API
|
||||
|
||||
### 友情链接
|
||||
|
||||
|
@ -66,20 +30,26 @@ https://github.com/bigfa/hugo-theme-farallon
|
|||
### 说说 by Memos
|
||||
|
||||
使用自定义字段设置memos
|
||||
|
||||
在自定义字段中填入`memos`值为memos地址,不带`/`
|
||||
|
||||
在自定义字段中填入`memosID`默认值为`1`,不为`1`时才需要设置
|
||||
|
||||
在自定义字段中填入`memosnum`默认值为`20`,默认获取20条最近的memo
|
||||
|
||||
### 说说 by Mastodon
|
||||
|
||||
根据 https://www.imsun.org/archives/1643.html#toc3
|
||||
根据 https://www.imsun.org/archives/1643.html
|
||||
获得API地址
|
||||
|
||||
在自定义字段中填入`tooot`值为Mastodon API 地址
|
||||
|
||||
## 预览地址
|
||||
### 好物 by memos
|
||||
|
||||
在自定义字段中填入`memos`值为memos地址
|
||||
在自定义字段中填入`memosID`默认值为`1`,不为`1`时才需要设置
|
||||
在自定义字段中填入`memostag`默认值为`好物`,不为`好物`时才需要设置
|
||||
|
||||
https://www.imsun.org
|
||||
|
||||
## 感谢
|
||||
|
||||
|
|
63
archive.php
63
archive.php
|
@ -40,26 +40,27 @@
|
|||
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>
|
||||
<?php endwhile; ?>
|
||||
</main>
|
||||
<?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>',
|
||||
'<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>',
|
||||
<?php
|
||||
$this->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links nav-links__comment',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
'prevClass' => 'prev',
|
||||
'nextClass' => 'next'
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
@ -74,44 +75,4 @@
|
|||
</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'); ?>
|
135
comments.php
135
comments.php
|
@ -1,49 +1,8 @@
|
|||
<?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->allow('comment') && stripos($_SERVER['HTTP_ACCEPT_LANGUAGE'], 'zh') > -1): ?>
|
||||
<?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">
|
||||
|
@ -52,33 +11,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('0'), _t('1'), _t('%d')); ?>
|
||||
</svg>
|
||||
<?php $this->commentsNum(_t('0'), _t('1'), _t('%d')); ?>
|
||||
</h3>
|
||||
<ol class="commentlist sulliComment--list"></ol>
|
||||
<?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; ?>
|
||||
<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">
|
||||
|
@ -88,7 +24,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>
|
||||
|
@ -102,7 +37,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>
|
||||
|
@ -110,8 +44,32 @@
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php _e(''); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php if ($comments->have()): ?>
|
||||
<?php $comments->listComments(); ?>
|
||||
|
||||
<?php
|
||||
$comments->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links nav-links__comment',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php else: ?>
|
||||
<center><h3></h3></center>
|
||||
<?php endif; ?>
|
||||
<?php $this->options->twikoo(); ?>
|
||||
</div>
|
||||
<?php
|
||||
|
@ -142,10 +100,14 @@ 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>
|
||||
<div class="comment--author"><?php echo $comments->author; ?>
|
||||
|
||||
<?php if ($comments->authorId == $comments->ownerId): ?>
|
||||
<span class="dot"></span> <span class="custom-span">作者</span>
|
||||
<?php endif; ?>
|
||||
<span class="dot"></span>
|
||||
<div class="comment--time"><?php $comments->date('Y-m-d H:i'); ?></div>
|
||||
<span class="comment-reply-link u-cursorPointer">
|
||||
<?php $comments->reply('<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" class="" ><g><path d="M12 3.786c-4.556 0-8.25 3.694-8.25 8.25s3.694 8.25 8.25 8.25c1.595 0 3.081-.451 4.341-1.233l1.054 1.7c-1.568.972-3.418 1.534-5.395 1.534-5.661 0-10.25-4.589-10.25-10.25S6.339 1.786 12 1.786s10.25 4.589 10.25 10.25c0 .901-.21 1.77-.452 2.477-.592 1.731-2.343 2.477-3.917 2.334-1.242-.113-2.307-.74-3.013-1.647-.961 1.253-2.45 2.011-4.092 1.78-2.581-.363-4.127-2.971-3.76-5.578.366-2.606 2.571-4.688 5.152-4.325 1.019.143 1.877.637 2.519 1.342l1.803.258-.507 3.549c-.187 1.31.761 2.509 2.079 2.629.915.083 1.627-.356 1.843-.99.2-.585.345-1.224.345-1.83 0-4.556-3.694-8.25-8.25-8.25zm-.111 5.274c-1.247-.175-2.645.854-2.893 2.623-.249 1.769.811 3.143 2.058 3.319 1.247.175 2.645-.854 2.893-2.623.249-1.769-.811-3.144-2.058-3.319z"></path></g></svg>'); ?>
|
||||
|
@ -154,6 +116,7 @@ function threadedComments($comments, $options) {
|
|||
</div>
|
||||
</div>
|
||||
<div class="comment-content">
|
||||
<?php if ($comments->parent) {echo getPermalinkFromCoid($comments->parent);}?>
|
||||
<?php $comments->content(); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -164,8 +127,26 @@ function threadedComments($comments, $options) {
|
|||
<?php } ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<ol class="commentlist">
|
||||
<?php $this->comments()->to($comments); ?>
|
||||
<?php while($comments->next()): ?>
|
||||
<?php endwhile; ?>
|
||||
</ol>
|
||||
<style>.custom-span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-weight: 500; /* Equivalent to font-medium */
|
||||
border-radius: 0.375rem; /* Equivalent to rounded-md */
|
||||
font-size: 0.75rem; /* Equivalent to text-xs */
|
||||
padding-left: 1.5px; /* Equivalent to px-1.5 */
|
||||
padding-right: 1.5px; /* Equivalent to px-1.5 */
|
||||
padding-top: 0.5px; /* Equivalent to py-0.5 */
|
||||
padding-bottom: 0.5px; /* Equivalent to py-0.5 */
|
||||
border: 1px solid var(--farallon-border-color); /* ring-1 and ring-inset with ring-gray-300 */
|
||||
color: var(--farallon-text-gray); /* text-gray-700 */
|
||||
background: var(--farallon-background-gray); /* bg-gray-50 */
|
||||
}
|
||||
|
||||
/* Dark mode styles */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.custom-span {
|
||||
border-color: var(--farallon-hover-color); /* ring-gray-700 */
|
||||
color: var(--farallon-hover-color); /* text-gray-200 */
|
||||
background-color: var(--farallon-background-gray); /* bg-gray-800 */
|
||||
}
|
||||
}</style>
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
$movie_id = $_GET['id'];
|
||||
$api_url = "https://api.loliko.cn/movies/{$movie_id}";
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'ignore_errors' => true,
|
||||
'timeout' => 10 // 设置10秒超时
|
||||
]
|
||||
]);
|
||||
|
||||
$response = file_get_contents($api_url, false, $context);
|
||||
|
||||
if ($response === FALSE) {
|
||||
header("HTTP/1.1 500 Internal Server Error");
|
||||
echo json_encode(['error' => 'Failed to fetch data from API']);
|
||||
} else {
|
||||
$responseData = json_decode($response, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
header('Content-Type: application/json');
|
||||
echo $response;
|
||||
} else {
|
||||
header("HTTP/1.1 500 Internal Server Error");
|
||||
echo json_encode(['error' => 'Invalid JSON response from API']);
|
||||
}
|
||||
}
|
|
@ -118,6 +118,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.post--title .sticky--post {
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
font-weight: 400;
|
||||
background: linear-gradient(90deg, #8a63d2, #f81ce5);
|
||||
padding: 3px 5px;
|
||||
border-radius: 5px;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
.dark {
|
||||
--farallon-main-color: rgba(253, 186, 116, 1);
|
||||
--farallon-hover-color: rgba(255, 237, 213, 1);
|
||||
|
@ -223,7 +235,6 @@
|
|||
border-color: #3f3f46
|
||||
}
|
||||
|
||||
|
||||
/*!normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css*/
|
||||
html {
|
||||
line-height: 1.15;
|
||||
|
@ -251,9 +262,7 @@ hr {
|
|||
|
||||
pre {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
overflow: hide;
|
||||
text-overflow: ellipsis
|
||||
font-size: 1em
|
||||
}
|
||||
|
||||
a {
|
||||
|
@ -1049,6 +1058,11 @@ textarea {
|
|||
position: relative
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
padding: 20px;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.nav-links .page-numbers:hover,
|
||||
.nav-links .post-page-numbers:hover {
|
||||
color: var(--farallon-hover-color)
|
||||
|
@ -1075,6 +1089,14 @@ textarea {
|
|||
left: 0
|
||||
}
|
||||
|
||||
.nav-links span {
|
||||
color: var(--farallon-text-gray)
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.nav-links .page-numbers.dots,
|
||||
.nav-links .post-page-numbers.dots {
|
||||
color: var(--farallon-text-gray)
|
||||
|
@ -1722,8 +1744,7 @@ textarea {
|
|||
font-size: 75%;
|
||||
padding: 2px 4px;
|
||||
word-break: break-word;
|
||||
color: var(--farallon-text-light);
|
||||
overflow: hidden;
|
||||
color: var(--farallon-text-light)
|
||||
}
|
||||
|
||||
.graph pre {
|
||||
|
@ -1737,18 +1758,14 @@ textarea {
|
|||
line-height: 1.4;
|
||||
color: var(--farallon-text-light);
|
||||
margin-left: -3.5%;
|
||||
margin-right: -3.5%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis
|
||||
margin-right: -3.5%
|
||||
}
|
||||
|
||||
.graph pre code {
|
||||
background-color: transparent;
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.graph--mixtapeEmbed {
|
||||
|
@ -2011,9 +2028,7 @@ textarea {
|
|||
|
||||
.graph pre {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis
|
||||
margin-right: 0
|
||||
}
|
||||
|
||||
.graph h2,
|
||||
|
@ -2250,15 +2265,7 @@ textarea {
|
|||
border-radius: 100%
|
||||
}
|
||||
|
||||
|
||||
div.cancel-comment-reply.cancel-comment-reply-link {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.comment-content {
|
||||
word-wrap: break-word !important;
|
||||
overflow-wrap: break-word !important;
|
||||
white-space: normal !important;
|
||||
color: var(--farallon-text-light)
|
||||
}
|
||||
|
||||
|
@ -2596,6 +2603,18 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
}
|
||||
}
|
||||
|
||||
.db--container {
|
||||
--db-item-width: 150px;
|
||||
--db-item-height: 215px;
|
||||
--db-music-width: 150px;
|
||||
--db-music-height: 150px;
|
||||
--db-primary-color: var(--farallon-hover-color);
|
||||
--db-background-white: var(--farallon-background-white);
|
||||
--db-background-gray: var(--farallon-background-gray);
|
||||
--db-border-color: var(--farallon-border-color);
|
||||
--db-text-light: var(--farallon-text-light)
|
||||
}
|
||||
|
||||
.db--nav {
|
||||
padding: 30px 0 20px;
|
||||
display: flex;
|
||||
|
@ -2631,14 +2650,14 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
}
|
||||
|
||||
.db--image {
|
||||
width: 150px;
|
||||
height: 215px;
|
||||
width: var(--db-item-width);
|
||||
height: var(--db-item-height);
|
||||
object-fit: cover;
|
||||
border-radius: 4px
|
||||
}
|
||||
|
||||
.db--image:hover {
|
||||
box-shadow: 0 0 10px var(--farallon-border-color)
|
||||
box-shadow: 0 0 10px var(--db-border-color)
|
||||
}
|
||||
|
||||
.db--title {
|
||||
|
@ -2648,12 +2667,12 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
}
|
||||
|
||||
.db--title a:hover {
|
||||
color: var(--farallon-hover-color);
|
||||
color: var(--db-primary-color);
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.db--genreItem {
|
||||
background: var(--farallon-background-gray);
|
||||
background: var(--db-background-gray);
|
||||
font-size: 12px;
|
||||
padding: 5px 12px;
|
||||
border-radius: 4px;
|
||||
|
@ -2664,13 +2683,13 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
}
|
||||
|
||||
.db--genreItem.is-active {
|
||||
background-color: var(--farallon-main-color);
|
||||
color: var(--farallon-background-white)
|
||||
background-color: var(--db-primary-color);
|
||||
color: var(--db-background-white)
|
||||
}
|
||||
|
||||
.db--genreItem:hover {
|
||||
background-color: var(--farallon-hover-color);
|
||||
color: var(--farallon-background-white)
|
||||
background-color: var(--db-primary-color);
|
||||
color: var(--db-background-white)
|
||||
}
|
||||
|
||||
.db--genres {
|
||||
|
@ -2687,52 +2706,22 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
color: var(--text-gray-lightest)
|
||||
color: var(--db-text-light)
|
||||
}
|
||||
|
||||
.db--item {
|
||||
width: 150px;
|
||||
width: var(--db-item-width);
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.db--item__music img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
width: var(--db-music-width);
|
||||
height: var(--db-music-height);
|
||||
object-fit: cover
|
||||
}
|
||||
|
||||
.db--item .top250 {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: #f5c518;
|
||||
color: #000;
|
||||
border-radius: 4px 4px 4px 0;
|
||||
line-height: 1;
|
||||
padding: 3px 10px 3px 5px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 900
|
||||
}
|
||||
|
||||
.db--item .top250:after {
|
||||
content: "";
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
margin-right: -.2rem;
|
||||
border-radius: 0 0 4px 4px;
|
||||
background: inherit;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: .75rem;
|
||||
transform: skewX(-20deg)
|
||||
}
|
||||
|
||||
.ipc-signpost {
|
||||
position: relative;
|
||||
background: #f5c518;
|
||||
|
@ -3003,77 +2992,6 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
}
|
||||
}
|
||||
|
||||
.project--headline {
|
||||
font-size: 32px;
|
||||
margin-top: 50px;
|
||||
line-height: 1.5;
|
||||
font-weight: 900
|
||||
}
|
||||
|
||||
.project--subtitle {
|
||||
font-size: 18px;
|
||||
font-weight: 200;
|
||||
color: var(--farallon-text-light)
|
||||
}
|
||||
|
||||
.theme--item {
|
||||
padding: 25px 0;
|
||||
font-size: 20px;
|
||||
border-bottom: 1px solid var(--farallon-border-color-light)
|
||||
}
|
||||
|
||||
.theme--item:last-child {
|
||||
border-bottom: 0
|
||||
}
|
||||
|
||||
.theme--item h3 {
|
||||
line-height: 1;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.theme--tags {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px
|
||||
}
|
||||
|
||||
.theme--tags a {
|
||||
border: 1px solid var(--farallon-main-color);
|
||||
color: var(--farallon-main-color);
|
||||
line-height: 1.2;
|
||||
font-size: 12px;
|
||||
padding: 3px 12px;
|
||||
border-radius: 4px;
|
||||
margin-right: 20px;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
.theme--tags a:hover {
|
||||
border-color: var(--farallon-hover-color);
|
||||
background-color: var(--farallon-hover-color);
|
||||
color: var(--farallon-background-white)
|
||||
}
|
||||
|
||||
.plugin--item {
|
||||
padding: 15px 0;
|
||||
font-size: 20px;
|
||||
border-bottom: 1px solid var(--farallon-border-color-light)
|
||||
}
|
||||
|
||||
.plugin--item:last-child {
|
||||
border-bottom: 0
|
||||
}
|
||||
|
||||
.plugin--item a:hover {
|
||||
color: var(--farallon-main-color);
|
||||
text-decoration: underline
|
||||
}
|
||||
|
||||
.plugin--item .desc {
|
||||
font-size: 14px;
|
||||
color: var(--faraallon-text-gray)
|
||||
}
|
||||
|
||||
.category--list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
@ -3804,3 +3722,8 @@ div.cancel-comment-reply.cancel-comment-reply-link {
|
|||
width: 80%
|
||||
}
|
||||
}
|
||||
/* 留言url 强制换行 */
|
||||
.comment-body a {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
is_single = false;
|
||||
post_id = 0;
|
||||
is_archive = false;
|
||||
VERSION = "0.5.0";
|
||||
VERSION = "0.6.1";
|
||||
constructor() {
|
||||
super();
|
||||
this.initCopyright();
|
||||
|
@ -45,8 +45,8 @@
|
|||
}
|
||||
}
|
||||
initCopyright() {
|
||||
const copyright = `<div class="site--footer__info">
|
||||
Theme <a href="https://fatesinger.com/101971" target="_blank">farallon</a> by bigfa / version ${this.VERSION}
|
||||
const copyright = `<div class="site--footer__info">由<a href="https://www.typecho.org" target="_blank">Typecho</a> 驱动 <br>
|
||||
Theme <a href="https://fatesinger.com/101971" target="_blank">farallon</a> by bigfa <br>Made with<a href="https://www.imsun.org" target="_blank"> Sun</a> / version ${this.VERSION}
|
||||
</div>`;
|
||||
document.querySelector(".site--footer__content").insertAdjacentHTML("afterend", copyright);
|
||||
document.querySelector(".icon--copryrights").addEventListener("click", () => {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* ViewImage.min.js 2.0.2
|
||||
* MIT License - http://www.opensource.org/licenses/mit-license.php
|
||||
* https://tokinx.github.io/ViewImage/
|
||||
*/
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(b){return b.raw=b};$jscomp.createTemplateTagFirstArgWithRaw=function(b,a){b.raw=a;return b};$jscomp.arrayIteratorImpl=function(b){var a=0;return function(){return a<b.length?{done:!1,value:b[a++]}:{done:!0}}};$jscomp.arrayIterator=function(b){return{next:$jscomp.arrayIteratorImpl(b)}};$jscomp.makeIterator=function(b){var a="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];return a?a.call(b):$jscomp.arrayIterator(b)};
|
||||
$jscomp.arrayFromIterator=function(b){for(var a,d=[];!(a=b.next()).done;)d.push(a.value);return d};$jscomp.arrayFromIterable=function(b){return b instanceof Array?b:$jscomp.arrayFromIterator($jscomp.makeIterator(b))};
|
||||
(function(){window.ViewImage=new function(){var b=this;this.target="[view-image] img";this.listener=function(a){if(!(a.ctrlKey||a.metaKey||a.shiftKey||a.altKey)){var d=String(b.target.split(",").map(function(g){return g.trim()+":not([no-view])"})),c=a.target.closest(d);if(c){var e=c.closest("[view-image]")||document.body;d=[].concat($jscomp.arrayFromIterable(e.querySelectorAll(d))).map(function(g){return g.href||g.src});b.display(d,c.href||c.src);a.stopPropagation();a.preventDefault()}}};this.init=
|
||||
function(a){a&&(b.target=a);["removeEventListener","addEventListener"].forEach(function(d){document[d]("click",b.listener,!1)})};this.display=function(a,d){var c=a.indexOf(d),e=(new DOMParser).parseFromString('\n <div class="view-image">\n <style>.view-image{position:fixed;inset:0;z-index:500;padding:1rem;display:flex;flex-direction:column;animation:view-image-in 300ms;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.view-image__out{animation:view-image-out 300ms}@keyframes view-image-in{0%{opacity:0}}@keyframes view-image-out{100%{opacity:0}}.view-image-btn{width:32px;height:32px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:3px;background-color:rgba(255,255,255,0.2)}.view-image-btn:hover{background-color:rgba(255,255,255,0.5)}.view-image-close__full{position:absolute;inset:0;background-color:rgba(48,55,66,0.3);z-index:unset;cursor:zoom-out;margin:0}.view-image-container{height:0;flex:1;display:flex;align-items:center;justify-content:center;}.view-image-lead{display:contents}.view-image-lead img{position:relative;z-index:1;max-width:100%;max-height:100%;object-fit:contain;border-radius:3px}.view-image-lead__in img{animation:view-image-lead-in 300ms}.view-image-lead__out img{animation:view-image-lead-out 300ms forwards}@keyframes view-image-lead-in{0%{opacity:0;transform:translateY(-20px)}}@keyframes view-image-lead-out{100%{opacity:0;transform:translateY(20px)}}[class*=__out] ~ .view-image-loading{display:block}.view-image-loading{position:absolute;inset:50%;width:8rem;height:2rem;color:#aab2bd;overflow:hidden;text-align:center;margin:-1rem -4rem;z-index:1;display:none}.view-image-loading::after{content:"";position:absolute;inset:50% 0;width:100%;height:3px;background:rgba(255,255,255,0.5);transform:translateX(-100%) translateY(-50%);animation:view-image-loading 800ms -100ms ease-in-out infinite}@keyframes view-image-loading{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}.view-image-tools{position:relative;display:flex;justify-content:space-between;align-content:center;color:#fff;max-width:600px;position: absolute; bottom: 5%; left: 1rem; right: 1rem; backdrop-filter: blur(10px);margin:0 auto;padding:10px;border-radius:5px;background:rgba(0,0,0,0.1);margin-bottom:constant(safe-area-inset-bottom);margin-bottom:env(safe-area-inset-bottom);z-index:1}.view-image-tools__count{width:60px;display:flex;align-items:center;justify-content:center}.view-image-tools__flip{display:flex;gap:10px}.view-image-tools [class*=-close]{margin:0 10px}</style>\n <div class="view-image-container">\n <div class="view-image-lead"></div>\n <div class="view-image-loading"></div>\n <div class="view-image-close view-image-close__full"></div>\n </div>\n <div class="view-image-tools">\n <div class="view-image-tools__count">\n <span><b class="view-image-index">'+
|
||||
(c+1)+"</b>/"+a.length+'</span>\n </div>\n <div class="view-image-tools__flip">\n <div class="view-image-btn view-image-tools__flip-prev">\n <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M31 36L19 24L31 12" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n <div class="view-image-btn view-image-tools__flip-next">\n <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M19 12L31 24L19 36" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n </div>\n <div class="view-image-btn view-image-close">\n <svg width="16" height="16" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M8 8L40 40" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 40L40 8" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n </div>\n </div>\n ',
|
||||
"text/html").body.firstChild,g=function(f){var h={Escape:"close",ArrowLeft:"tools__flip-prev",ArrowRight:"tools__flip-next"};h[f.key]&&e.querySelector(".view-image-"+h[f.key]).click()},l=function(f){var h=new Image,k=e.querySelector(".view-image-lead");k.className="view-image-lead view-image-lead__out";setTimeout(function(){k.innerHTML="";h.onload=function(){setTimeout(function(){k.innerHTML='<img src="'+h.src+'" alt="ViewImage" no-view/>';k.className="view-image-lead view-image-lead__in"},100)};
|
||||
h.src=f},300)};document.body.appendChild(e);l(d);window.addEventListener("keydown",g);e.onclick=function(f){f.target.closest(".view-image-close")?(window.removeEventListener("keydown",g),e.onclick=null,e.classList.add("view-image__out"),setTimeout(function(){return e.remove()},290)):f.target.closest(".view-image-tools__flip")&&(c=f.target.closest(".view-image-tools__flip-prev")?0===c?a.length-1:c-1:c===a.length-1?0:c+1,l(a[c]),e.querySelector(".view-image-index").innerHTML=c+1)}}}})();
|
||||
|
22
footer.php
22
footer.php
|
@ -3,19 +3,18 @@
|
|||
<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 Sun</a>
|
||||
页面加载耗时
|
||||
<?php echo timer_stop();?>
|
||||
<div class="copyright">
|
||||
<a href="<?php $this->options->siteUrl(); ?>">
|
||||
<?php $this->options->title(); ?>
|
||||
</a> ©
|
||||
<?php $this->options->jzyear() ?>-<?php echo date('Y'); ?>
|
||||
</div>
|
||||
<?php //添加加载时间控制
|
||||
if ($this->options->showtime): ?>
|
||||
页面加载耗时<?php echo timer_stop();?>
|
||||
<?php endif; ?>
|
||||
<?php $this->options->tongji(); ?>
|
||||
<div class="copyright"> © <?php echo date('Y'); ?>
|
||||
<?php $this->options->title(); ?>
|
||||
<svg class="icon icon--copryrights" viewBox="0 0 1040 1024" width="16" height="16">
|
||||
<path
|
||||
d="M717.056236 383.936299l-51.226708 0c-28.2893 0-51.226708 22.936385-51.226708 51.225685l0 128.062678c0 28.2893 22.937408 51.225685 51.226708 51.225685l51.226708 0c28.2893 0 51.225685-22.936385 51.225685-51.225685L768.281921 435.161984C768.281921 406.872684 745.345536 383.936299 717.056236 383.936299zM717.056236 537.611308c0 14.158465-11.480472 25.612331-25.613354 25.612331-14.132882 0-25.612331-11.453866-25.612331-25.612331l0-76.835969c0-14.158465 11.480472-25.613354 25.612331-25.613354 14.133905 0 25.613354 11.453866 25.613354 25.613354L717.056236 537.611308zM1013.977739 426.580538 859.776751 165.30079c-8.888438-15.063067-22.294772-25.975605-37.57171-32.080649-32.708959-34.856879-79.187527-56.638975-130.762159-56.638975L332.862064 76.581166c-51.575656 0-98.0532 21.782096-130.761136 56.639998-15.276938 6.105045-28.683273 17.017582-37.572734 32.079626L10.327206 426.580538c-21.26021 36.069497-8.655124 82.217537 28.239158 103.028515l115.00836 64.967664 0 199.163015c0 99.024318 80.264045 153.678078 179.287339 153.678078l358.580818 0c99.024318 0 179.290409-80.266092 179.290409-179.290409L870.733291 594.575694l115.00836-64.966641C1022.63184 508.798075 1035.238972 462.650035 1013.977739 426.580538zM153.574724 536.518417l-67.058278-37.875632c-24.589025-13.907755-33.019021-44.647873-18.809391-68.684312l85.86767-145.555074L153.574724 536.518417zM646.620024 127.807874c0 56.5786-60.205197 102.45137-134.467551 102.45137-74.261331 0-134.466528-45.873794-134.466528-102.45137L646.620024 127.807874zM819.507606 742.515071c0 84.893482-68.810179 153.677055-153.678078 153.677055L358.475418 896.192126c-84.8679 0-153.675008-68.783573-153.675008-153.677055l0-461.030142c0-76.150354 55.402821-139.361001 128.093377-151.545508 1.332345 83.883479 81.06734 151.545508 179.258687 151.545508 98.19237 0 177.926342-67.662029 179.25971-151.545508 72.690556 12.183484 128.096447 75.394131 128.096447 151.545508L819.508629 742.515071zM937.791569 498.642784l-67.058278 37.875632 0-252.111948 85.86767 145.552004C970.807521 453.995935 962.377524 484.736053 937.791569 498.642784z"
|
||||
|
@ -23,7 +22,6 @@
|
|||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<?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">
|
||||
|
|
219
functions.php
219
functions.php
|
@ -5,29 +5,31 @@ 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('建站年份'), _t('eg. 2006'));
|
||||
$form->addInput($jzyear);
|
||||
$sticky = new Typecho_Widget_Helper_Form_Element_Text('sticky', NULL, NULL, _t('置顶文章cid'), _t('多篇文章以`|`符号隔开'), _t('会在首页展示置顶文章。'));
|
||||
$form->addInput($sticky);
|
||||
$showProfile = new Typecho_Widget_Helper_Form_Element_Radio('showProfile',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否在文章页面显示显示作者信息'), _t('选择“是”将在文章页面包含显示作者信息。'));
|
||||
'0', _t('是否在文章页面显示作者信息'), _t('选择“是”将在文章页面包含显示作者信息。'));
|
||||
$form->addInput($showProfile);
|
||||
$instagramurl = new Typecho_Widget_Helper_Form_Element_Text('instagramurl', NULL, NULL, _t('Instagram'), _t('会在个人信息显示'));
|
||||
$instagramurl = new Typecho_Widget_Helper_Form_Element_Text('instagramurl', NULL, 'https://Instagram.com/', _t('Instagram'), _t('会在个人信息显示'));
|
||||
$form->addInput($instagramurl);
|
||||
$telegramurl = new Typecho_Widget_Helper_Form_Element_Text('telegramurl', NULL, NULL, _t('电报'), _t('会在个人信息显示'));
|
||||
$telegramurl = new Typecho_Widget_Helper_Form_Element_Text('telegramurl', NULL, 'https://t.me/', _t('电报'), _t('会在个人信息显示'));
|
||||
$form->addInput($telegramurl);
|
||||
$githuburl = new Typecho_Widget_Helper_Form_Element_Text('githuburl', NULL, NULL, _t('github'), _t('会在个人信息显示'));
|
||||
$githuburl = new Typecho_Widget_Helper_Form_Element_Text('githuburl', NULL, 'https://github.com/', _t('github'), _t('会在个人信息显示'));
|
||||
$form->addInput($githuburl);
|
||||
$twitterurl = new Typecho_Widget_Helper_Form_Element_Text('twitterurl', NULL, NULL, _t('twitter'), _t('会在个人信息显示'));
|
||||
$twitterurl = new Typecho_Widget_Helper_Form_Element_Text('twitterurl', NULL, 'https://x.com/', _t('twitter'), _t('会在个人信息显示'));
|
||||
$form->addInput($twitterurl);
|
||||
$mastodonurl = new Typecho_Widget_Helper_Form_Element_Text('mastodonurl', NULL, NULL, _t('mastodon'), _t('会在个人信息显示'));
|
||||
$mastodonurl = new Typecho_Widget_Helper_Form_Element_Text('mastodonurl', NULL,'https://jiong.us/', _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);
|
||||
$midimg = new Typecho_Widget_Helper_Form_Element_Text('midimg', NULL, './img/', _t('填写分类图片路径,以"/"结尾'), _t('可以使用本地目录或者CDN地址,自动匹配路径下以mid.jpg格式的图片,使用分类页面时需要设置'));
|
||||
$form->addInput($midimg);
|
||||
$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, '322dba2a3a27524b97c06d941d9631d153fc', _t('豆瓣页面必需Token'), _t('从<a href="https://node.wpista.com/" target="_blank">https://node.wpista.com/</a>获得token'));
|
||||
$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);
|
||||
|
@ -35,6 +37,10 @@ function themeConfig($form) {
|
|||
$form->addInput($addhead);
|
||||
$tongji = new Typecho_Widget_Helper_Form_Element_Textarea('tongji', NULL, NULL, _t('统计代码'), _t('支持HTML'));
|
||||
$form->addInput($tongji);
|
||||
$showcate = new Typecho_Widget_Helper_Form_Element_Radio('showcate',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否在文章页面显示文章分类'), _t('选择“是”将在文章页面显示文章的分类信息。'));
|
||||
$form->addInput($showcate);
|
||||
$showallwords = new Typecho_Widget_Helper_Form_Element_Radio('showallwords',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示归档字数统计'), _t('选择“是”将在归档页面显示全站总字数。'));
|
||||
|
@ -47,10 +53,14 @@ function themeConfig($form) {
|
|||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示复制链接'), _t('选择“是”将在文章页面显示复制链接。'));
|
||||
$form->addInput($showshare);
|
||||
$showtoc = new Typecho_Widget_Helper_Form_Element_Radio('showtoc',
|
||||
$showtime = new Typecho_Widget_Helper_Form_Element_Radio('showtime',
|
||||
array('0'=> _t('否'), '1'=> _t('是')),
|
||||
'0', _t('是否显示文章目录'), _t('选择“是”将在文章页面显示文章目录(仅在宽度大于1400px的设备中显示)。'));
|
||||
$form->addInput($showtoc);
|
||||
'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;
|
||||
|
@ -190,6 +200,70 @@ function img_postthumb($cid) {
|
|||
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() {
|
||||
|
@ -453,3 +527,124 @@ function getParentCategory($categoryId) {
|
|||
function getDays($time1, $time2) {
|
||||
return floor(($time2 - $time1) / 86400);
|
||||
}
|
||||
|
||||
//获取文章卡片
|
||||
function get_article_info($atts) {
|
||||
$default_atts = array(
|
||||
'id' => '',
|
||||
'url' => ''
|
||||
);
|
||||
$atts = array_merge($default_atts, $atts);
|
||||
$db = Typecho_Db::get();
|
||||
if (!empty($atts['id'])) {
|
||||
$post = $db->fetchRow($db->select()->from('table.contents')
|
||||
->where('cid = ?', $atts['id'])
|
||||
->limit(1));
|
||||
} elseif (!empty($atts['url'])) {
|
||||
$post = $db->fetchRow($db->select()->from('table.contents')
|
||||
->where('permalink = ?', $atts['url'])
|
||||
->limit(1));
|
||||
} else {
|
||||
return '请提供文章ID或URL';
|
||||
}
|
||||
if (!$post) {
|
||||
return '未找到文章';
|
||||
}
|
||||
$post = Typecho_Widget::widget('Widget_Abstract_Contents')->push($post);
|
||||
|
||||
// 获取缩略图
|
||||
$imageToDisplay = img_postthumb($post['cid']);
|
||||
if (empty($imageToDisplay)) {
|
||||
$imageToDisplay = '//pic.0tz.top/api'; // 设置一个默认图片路径
|
||||
}
|
||||
|
||||
$output = '<div class="graph--mixtapeEmbed">';
|
||||
$output .= '<a class="mixtapeContent" href="' . $post['permalink'] . '" target="_blank">';
|
||||
$output .= '<span class="markup--strong markup--mixtapeEmbed-strong">' . $post['title'] . '</span>';
|
||||
$output .= '<em class="markup--em markup--mixtapeEmbed-em">' . Typecho_Common::subStr(strip_tags($post['text']), 0, 100, '...') . '</em>';
|
||||
$output .= '</a>';
|
||||
$output .= '<a class="mixtapeImage" href="' . $post['permalink'] . '" target="_blank" style="background-image:url(' . $imageToDisplay . ')"></a>';
|
||||
$output .= '</div>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
// 创建一个新的类来处理内容过滤
|
||||
class ContentFilter
|
||||
{
|
||||
public static function filterContent($content, $widget, $lastResult)
|
||||
{
|
||||
// 首先运行之前的过滤器结果
|
||||
$content = empty($lastResult) ? $content : $lastResult;
|
||||
|
||||
// 然后处理我们的文章短代码
|
||||
$content = preg_replace_callback('/\[article\s+([^\]]+)\]/', function($matches) {
|
||||
$atts = self::parse_atts($matches[1]);
|
||||
return get_article_info($atts);
|
||||
}, $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
// 解析短代码属性
|
||||
private static function parse_atts($text) {
|
||||
$atts = array();
|
||||
$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
|
||||
$text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);
|
||||
if (preg_match_all($pattern, $text, $match, PREG_SET_ORDER)) {
|
||||
foreach ($match as $m) {
|
||||
if (!empty($m[1]))
|
||||
$atts[strtolower($m[1])] = stripcslashes($m[2]);
|
||||
elseif (!empty($m[3]))
|
||||
$atts[strtolower($m[3])] = stripcslashes($m[4]);
|
||||
elseif (!empty($m[5]))
|
||||
$atts[strtolower($m[5])] = stripcslashes($m[6]);
|
||||
elseif (isset($m[7]) && strlen($m[7]))
|
||||
$atts[] = stripcslashes($m[7]);
|
||||
elseif (isset($m[8]))
|
||||
$atts[] = stripcslashes($m[8]);
|
||||
}
|
||||
}
|
||||
return $atts;
|
||||
}
|
||||
}
|
||||
|
||||
// 注册钩子
|
||||
Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('ContentFilter', 'filterContent');
|
||||
|
||||
// 编辑器按钮类
|
||||
class EditorButton {
|
||||
public static function render()
|
||||
{
|
||||
echo <<<EOF
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#wmd-button-row').append('<li class="wmd-button" id="wmd-article-button" title="插入文章引用"><span style="background: none;"><svg t="1687164718203" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4158" width="20" height="20"><path d="M810.666667 213.333333H213.333333c-46.933333 0-85.333333 38.4-85.333333 85.333334v426.666666c0 46.933333 38.4 85.333333 85.333333 85.333334h597.333334c46.933333 0 85.333333-38.4 85.333333-85.333334V298.666667c0-46.933333-38.4-85.333333-85.333333-85.333334z m0 512H213.333333V298.666667h597.333334v426.666666z" p-id="4159"></path><path d="M298.666667 384h426.666666v85.333333H298.666667zM298.666667 554.666667h426.666666v85.333333H298.666667z" p-id="4160"></path></svg></span></li>');
|
||||
|
||||
$('#wmd-article-button').click(function() {
|
||||
var articleId = prompt("请输入要引用的文章ID:");
|
||||
if (articleId) {
|
||||
var text = "[article id=\"" + articleId + "\"]";
|
||||
var textarea = $('#text')[0];
|
||||
var start = textarea.selectionStart;
|
||||
var end = textarea.selectionEnd;
|
||||
var value = textarea.value;
|
||||
|
||||
textarea.value = value.substring(0, start) + text + value.substring(end);
|
||||
|
||||
// 将光标移动到插入的文本之后
|
||||
textarea.setSelectionRange(start + text.length, start + text.length);
|
||||
textarea.focus();
|
||||
|
||||
// 触发change事件,确保编辑器更新
|
||||
$('#text').trigger('change');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
|
||||
// 注册编辑器按钮钩子
|
||||
Typecho_Plugin::factory('admin/write-post.php')->bottom = array('EditorButton', 'render');
|
||||
Typecho_Plugin::factory('admin/write-page.php')->bottom = array('EditorButton', 'render');
|
||||
|
|
|
@ -17,7 +17,7 @@ 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; ?>
|
||||
|
@ -42,7 +42,10 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
|||
<?php if ($this->options->logoUrl): ?>
|
||||
<a href="<?php $this->options->siteUrl(); ?>" class="site--url">
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" alt="<?php $this->options->title() ?>" />
|
||||
</a>
|
||||
</a>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="u-xs-show">
|
||||
<a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title() ?></a>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* 移植自HUGO主题 farallon 原作者 bigfa
|
||||
* @package farallon
|
||||
* 一款单栏主题. 移植自HUGO主题 Farallon 原作者 bigfa
|
||||
* @package Farallon
|
||||
* @author 老孙
|
||||
* @version 0.5.1
|
||||
* @link https://imsun.org
|
||||
* @version 0.6.1
|
||||
* @link https://www.imsun.org
|
||||
*/
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
$this->need('header.php');
|
||||
|
|
|
@ -12,17 +12,25 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
|||
<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;
|
||||
$themeUrl = $this->options->midimg;
|
||||
// 为每个分类生成图片地址
|
||||
$categoryImage = $themeUrl . $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'); ?>
|
|
@ -79,8 +79,8 @@ $this->need('header.php');
|
|||
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 type="text/javascript" src="<?php $this->options->themeUrl('/dist/js/chart.js'); ?>"></script>
|
||||
<script id="MathJax-script" async src="<?php $this->options->themeUrl('/dist/js/tex-mml-chtml.js'); ?>"></script>
|
||||
<script>
|
||||
// 配置 MathJax
|
||||
MathJax = {
|
||||
|
|
331
page-douban.php
331
page-douban.php
|
@ -6,333 +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 class="site--main">
|
||||
<div class="db--container" data-token="<?php $this->options->doubanID() ?>">
|
||||
<nav class="db--nav">
|
||||
<div class="db--navItem JiEun current" data-type="movie">Movie</div>
|
||||
<div class="db--navItem JiEun" data-type="book">Book</div>
|
||||
<div class="db--navItem JiEun" data-type="music">Music</div>
|
||||
</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>
|
||||
</div>
|
||||
<div class="db--container"></div>
|
||||
<script>
|
||||
new Douban({
|
||||
baseAPI: '<?php $this->options->doubanID() ?>', // api
|
||||
container: ".db--container", // 容器名
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<script>
|
||||
class APIHandler {
|
||||
constructor(token) {
|
||||
this.ver = "1.0.1";
|
||||
this.type = "movie";
|
||||
this.finished = false;
|
||||
this.paged = 1;
|
||||
this.genre_list = [];
|
||||
this.genre = [];
|
||||
this.subjects = [];
|
||||
this.baseAPI = "https://node.wpista.com/v1/outer/";
|
||||
this.token = token;
|
||||
this._create();
|
||||
}
|
||||
on(event, selector, handler) {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach(element => {
|
||||
element.addEventListener(event, handler);
|
||||
});
|
||||
}
|
||||
_fetchGenres() {
|
||||
document.querySelector(".db--genres").innerHTML = "";
|
||||
fetch(`${this.baseAPI}genres?token=${this.token}&type=${this.type}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.data.length) {
|
||||
this.genre_list = data.data;
|
||||
this._renderGenre();
|
||||
}
|
||||
});
|
||||
}
|
||||
_handleGenreClick() {
|
||||
this.on("click", ".db--genreItem", event => {
|
||||
const target = event.currentTarget;
|
||||
if (target.classList.contains("is-active")) {
|
||||
const index = this.genre.indexOf(target.innerText);
|
||||
target.classList.remove("is-active");
|
||||
this.genre.splice(index, 1);
|
||||
this.paged = 1;
|
||||
this.finished = false;
|
||||
this.subjects = [];
|
||||
this._fetchData();
|
||||
return;
|
||||
}
|
||||
document.querySelector(".db--list").innerHTML = "";
|
||||
document.querySelector(".lds-ripple").classList.remove("u-hide");
|
||||
target.classList.add("is-active");
|
||||
this.genre.push(target.innerText);
|
||||
this.paged = 1;
|
||||
this.finished = false;
|
||||
this.subjects = [];
|
||||
this._fetchData();
|
||||
});
|
||||
}
|
||||
_renderGenre() {
|
||||
document.querySelector(".db--genres").innerHTML = this.genre_list.map(genre =>
|
||||
`<span class="db--genreItem${this.genre.includes(genre.name) ? " is-active" : ""}">${genre.name}</span>`
|
||||
).join("");
|
||||
this._handleGenreClick();
|
||||
}
|
||||
_fetchData() {
|
||||
fetch(`${this.baseAPI}faves?token=${this.token}&type=${this.type}&paged=${this.paged}&genre=${JSON.stringify(this.genre)}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.data.length) {
|
||||
if (document.querySelector(".db--list").classList.contains("db--list__card"))
|
||||
{
|
||||
this.subjects = [...this.subjects, ...data.data];
|
||||
this._randerDateTemplate();
|
||||
} else {
|
||||
this.subjects = [...this.subjects, ...data.data];
|
||||
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(subject => {
|
||||
return `<div class="db--item">${
|
||||
subject.is_top250
|
||||
? '<span class="top250">Top 250</span>'
|
||||
: ""
|
||||
}<img src="${
|
||||
subject.poster
|
||||
}" referrerpolicy="no-referrer" class="db--image"><div class="db--score ">${
|
||||
subject.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>' +
|
||||
subject.douban_score
|
||||
: ""
|
||||
}${
|
||||
subject.year > 0 ? " · " + subject.year : ""
|
||||
}</div><div class="db--title"><a href="${
|
||||
subject.link
|
||||
}" target="_blank">${subject.name}</a></div></div>`;
|
||||
})
|
||||
.join("");
|
||||
html += `</div></div>`;
|
||||
}
|
||||
document.querySelector(".db--list").innerHTML = html;
|
||||
}
|
||||
_renderListTemplate() {
|
||||
document.querySelector(".db--list").innerHTML = this.subjects.map(subject =>
|
||||
`<div class="db--item">
|
||||
${subject.is_top250 ? '<span class="top250">Top 250</span>' : ""}
|
||||
<img src="${subject.poster}" referrerpolicy="no-referrer" class="db--image">
|
||||
<div class="ipc-signpost">${subject.create_time}</div>
|
||||
<div class="db--score">${subject.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>` + subject.douban_score : ""}
|
||||
${subject.year > 0 ? " · " + subject.year : ""}
|
||||
</div>
|
||||
<div class="db--title"><a href="${subject.link}" target="_blank">${subject.name}</a></div>
|
||||
</div>`
|
||||
).join("");
|
||||
}
|
||||
_handleScroll() {
|
||||
window.addEventListener("scroll", () => {
|
||||
const scrollY = window.scrollY || window.pageYOffset;
|
||||
const blockMoreOffsetTop = document.querySelector(".block-more").offsetTop;
|
||||
if (blockMoreOffsetTop - window.innerHeight < scrollY && 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", event => {
|
||||
if (event.currentTarget.classList.contains("current")) return;
|
||||
this.genre = [];
|
||||
this.type = event.currentTarget.dataset.type;
|
||||
if (this.type != "book") {
|
||||
this._fetchGenres();
|
||||
document.querySelector(".db--genres").classList.remove("u-hide");
|
||||
} else {
|
||||
document.querySelector(".db--genres").classList.add("u-hide");
|
||||
}
|
||||
document.querySelector(".db--list").innerHTML = "";
|
||||
document.querySelector(".lds-ripple").classList.remove("u-hide");
|
||||
document.querySelector(".db--navItem.current").classList.remove("current");
|
||||
event.target.classList.add("current");
|
||||
this.paged = 1;
|
||||
this.finished = false;
|
||||
this.subjects = [];
|
||||
this._fetchData();
|
||||
});
|
||||
}
|
||||
_create() {
|
||||
if (document.querySelector(".db--container")) {
|
||||
const container = document.querySelector(".db--container");
|
||||
if (container.dataset.token) {
|
||||
this.token = container.dataset.token;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const currentNavItem = document.querySelector(".db--navItem.current");
|
||||
if (currentNavItem instanceof HTMLElement) {
|
||||
this.type = currentNavItem.dataset.type;
|
||||
}
|
||||
const list = document.querySelector(".db--list");
|
||||
if (list.dataset.type) {
|
||||
this.type = list.dataset.type;
|
||||
}
|
||||
if (this.type == "movie") {
|
||||
document.querySelector(".db--genres").classList.remove("u-hide");
|
||||
}
|
||||
this._fetchGenres();
|
||||
this._fetchData();
|
||||
this._handleScroll();
|
||||
this._handleNavClick();
|
||||
}
|
||||
if (document.querySelector(".js-db")) {
|
||||
document.querySelectorAll(".js-db").forEach(element => {
|
||||
const id = element.dataset.id;
|
||||
const type = element.dataset.type;
|
||||
const parentNode = element.parentNode;
|
||||
fetch(`${this.baseAPI}${type}/${id}?token=${this.token}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.data) {
|
||||
const itemData = data.data;
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("doulist-item");
|
||||
div.innerHTML = `
|
||||
<div class="doulist-subject">
|
||||
<div class="doulist-post">
|
||||
<img decoding="async" referrerpolicy="no-referrer" src="${itemData.poster}">
|
||||
</div>
|
||||
<div class="doulist-content">
|
||||
<div class="doulist-title">
|
||||
<a href="${itemData.link}" class="cute" target="_blank" rel="external nofollow">${itemData.name}</a>
|
||||
</div>
|
||||
<div class="rating">
|
||||
<span class="allstardark">
|
||||
<span class="allstarlight" style="width:55%"></span>
|
||||
</span>
|
||||
<span class="rating_nums"> ${itemData.douban_score} </span>
|
||||
</div>
|
||||
<div class="abstract">${itemData.card_subtitle}</div>
|
||||
</div>
|
||||
</div>`;
|
||||
parentNode.replaceWith(div);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
if (document.querySelector(".db--collection")) {
|
||||
document.querySelectorAll(".db--collection").forEach(collection => {
|
||||
this._fetchCollection(collection);
|
||||
});
|
||||
}
|
||||
}
|
||||
_fetchCollection(collection) {
|
||||
const style = collection.dataset.style ? collection.dataset.style : "card";
|
||||
fetch(`${this.baseAPI}v1/movies?type=${collection.dataset.type}&paged=1&genre=&start_time=${collection.dataset.start}&end_time=${collection.dataset.end}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.length) {
|
||||
if (style === "card") {
|
||||
collection.innerHTML += data.map(item => `
|
||||
<div class="doulist-item">
|
||||
<div class="doulist-subject">
|
||||
<div class="db--viewTime">Marked ${item.create_time}</div>
|
||||
<div class="doulist-post">
|
||||
<img referrerpolicy="no-referrer" src="${item.poster}">
|
||||
</div>
|
||||
<div class="doulist-content">
|
||||
<div class="doulist-title">
|
||||
<a href="${item.link}" class="cute" target="_blank" rel="external nofollow">${item.name}</a>
|
||||
</div>
|
||||
<div class="rating">
|
||||
<span class="allstardark">
|
||||
<span class="allstarlight" style="width:75%"></span>
|
||||
</span>
|
||||
<span class="rating_nums">${item.douban_score}</span>
|
||||
</div>
|
||||
<div class="abstract">${item.remark || item.card_subtitle}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`).join("");
|
||||
} else {
|
||||
const groupedData = data.reduce((acc, item) => {
|
||||
if (acc[item.create_time]) {
|
||||
acc[item.create_time].push(item);
|
||||
} else {
|
||||
acc[item.create_time] = [item];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
let html = "";
|
||||
for (const date in groupedData) {
|
||||
html += `<div class="db--date">${date}</div><div class="db--dateList">`;
|
||||
html += groupedData[date].map(item => `
|
||||
<div class="db--card__list">
|
||||
<img referrerpolicy="no-referrer" src="${item.poster}">
|
||||
<div>
|
||||
<div class="title">
|
||||
<a href="${item.link}" class="cute" target="_blank" rel="external nofollow">${item.name}</a>
|
||||
</div>
|
||||
<div class="rating">
|
||||
<span class="allstardark">
|
||||
<span class="allstarlight" style="width:75%"></span>
|
||||
</span>
|
||||
<span class="rating_nums">${item.douban_score}</span>
|
||||
</div>
|
||||
${item.remark || item.card_subtitle}
|
||||
</div>
|
||||
</div>`).join("");
|
||||
html += "</div>";
|
||||
}
|
||||
collection.innerHTML = html;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// 在页面加载完成后实例化APIHandler类
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const token = "<?php $this->options->doubanID() ?>"; // 替换为你的API令牌
|
||||
new APIHandler(token);
|
||||
});
|
||||
</script>
|
||||
</section>
|
||||
<?php $this->need('footer.php'); ?>
|
|
@ -11,9 +11,6 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
|||
<h1 class="post--single__title"><?php $this->title() ?></h1>
|
||||
<h2 class="post--single__subtitle"><?php $this->content(); ?> </h2>
|
||||
</header>
|
||||
<div class="graph u-marginBottom30">
|
||||
<?php $this->content(); ?>
|
||||
</div>
|
||||
<div class="template--linksWrap">
|
||||
<ul class="link-items">
|
||||
<?php
|
||||
|
|
|
@ -13,9 +13,8 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
|||
</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" />
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/marked.min.js'); ?>"></script>
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/view-image.min.js'); ?>"></script>
|
||||
<div id="tooot"></div>
|
||||
<div class="nav-links" id="loadmore">
|
||||
<span class="loadmore">加载更多</span>
|
||||
|
@ -34,7 +33,7 @@ window.onload = function() {
|
|||
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>`;
|
||||
mediaHTML += `<a href="${attachment.url}" target="_blank"><img src="${attachment.preview_url}" class="thumbnail-image img" ></a>`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -45,7 +44,7 @@ window.onload = function() {
|
|||
<article class='post--item post--item__status'>
|
||||
<div class='content'>
|
||||
<header>
|
||||
<img src="${account.avatar}" class="avatar" width="48" height="48" />
|
||||
<img src="${account.avatar}" class="avatar" width="48" height="48" no-view />
|
||||
<a class="humane--time" href="${url}" target="_blank">${new Date(created_at).toLocaleString()}</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
|
@ -82,9 +81,7 @@ window.onload = function() {
|
|||
// 绑定“加载更多”按钮的点击事件
|
||||
document.getElementById('loadmore').addEventListener('click', fetchAndDisplayToots);
|
||||
};
|
||||
Fancybox.bind("[data-fancybox]", {
|
||||
// Your custom options
|
||||
});
|
||||
window.ViewImage && ViewImage.init('.content img');
|
||||
</script>
|
||||
<style>
|
||||
div pre code {
|
||||
|
@ -92,7 +89,6 @@ div pre code {
|
|||
white-space: pre-wrap; /* CSS3 */
|
||||
word-wrap: break-word; /* 老版本的浏览器 */
|
||||
overflow-wrap: break-word;
|
||||
/* 指定如何断行 */
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
@ -100,26 +96,32 @@ 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;
|
||||
}
|
||||
.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%;
|
||||
height:170px;
|
||||
object-fit:cover;
|
||||
border-radius:4px;
|
||||
transition:transform .3s ease;
|
||||
cursor:zoom-in
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
}
|
||||
/* 当屏幕宽度小于732px时 */
|
||||
@media (max-width: 732px) {
|
||||
|
@ -132,6 +134,10 @@ div p a {
|
|||
.resimg {
|
||||
grid-template-columns: 1fr; /* 修改为一列 */
|
||||
}
|
||||
.thumbnail-image img {
|
||||
width: 100%;
|
||||
height: 480px;
|
||||
}
|
||||
}
|
||||
.load-more-btn {
|
||||
display: block;
|
||||
|
|
156
page-memos.php
156
page-memos.php
|
@ -18,20 +18,26 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
|||
$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" />
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/marked.min.js'); ?>"></script>
|
||||
<script src="<?php $this->options->themeUrl('/dist/js/view-image.min.js'); ?>"></script>
|
||||
<div id="talk"></div>
|
||||
<div class="nav-links" id="loadmore">
|
||||
<span class="loadmore">加载更多</span>
|
||||
</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; ?>')
|
||||
let currentPage = 1; // 当前页码
|
||||
const limit = 10; // 每页条数
|
||||
let url = '<?php echo $memos; ?>';
|
||||
let memosID = '<?php echo $memosID; ?>';
|
||||
let memosnum = '<?php echo $memosnum; ?>';
|
||||
|
||||
function loadMemos(page) {
|
||||
fetch(`${url}/api/v1/memo?creatorId=${memosID}&rowStatus=NORMAL&limit=${limit}&offset=${(page - 1) * limit}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
let html = '';
|
||||
data.forEach(item => {
|
||||
// 假设这里的 Format 函数能正确地格式化每个 item,并确保它返回有 `date` 和 `tag` 的对象
|
||||
let data = Format(item);
|
||||
let memoURL = url + '/m/' + item.id;
|
||||
let mdContent = marked.parse(data.content);
|
||||
|
@ -39,67 +45,76 @@ if (99) {
|
|||
<article class='post--item post--item__status'>
|
||||
<div class='content'>
|
||||
<header>
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" width="48" height="48" />
|
||||
<img src="<?php $this->options->logoUrl() ?>" class="avatar" width="48" height="48" no-view />
|
||||
<a class="humane--time" href="${memoURL}" target="_blank">${data.date}</a>
|
||||
</header>
|
||||
<div class="description" itemprop="about">
|
||||
<span class="talk_tag"># ${data.tag}</span><br>
|
||||
${mdContent}
|
||||
<span class="tag--list"><a>${data.tag}</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
`;
|
||||
});
|
||||
document.getElementById('talk').innerHTML = html;
|
||||
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 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}`)
|
||||
})
|
||||
}
|
||||
// 页面时间格式化
|
||||
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]
|
||||
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}" class="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?'[图片]':''}`)
|
||||
}
|
||||
}
|
||||
Fancybox.bind("[data-fancybox]", {
|
||||
// Your custom options
|
||||
|
||||
// 页面时间格式化
|
||||
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]
|
||||
}
|
||||
|
||||
// 初始加载第一页
|
||||
loadMemos(currentPage);
|
||||
|
||||
// 点击“加载更多”按钮时加载下一页
|
||||
document.getElementById('loadmore').addEventListener('click', function() {
|
||||
currentPage++;
|
||||
loadMemos(currentPage);
|
||||
});
|
||||
|
||||
window.ViewImage && ViewImage.init('.content img');
|
||||
</script>
|
||||
<style>
|
||||
div pre code {
|
||||
|
@ -112,7 +127,7 @@ div pre code {
|
|||
word-break: break-word;
|
||||
}
|
||||
div p a {
|
||||
word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
}
|
||||
.thumbnail-image {
|
||||
|
@ -121,6 +136,9 @@ div p a {
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
border-radius:4px;
|
||||
transition:transform .3s ease;
|
||||
cursor:zoom-in;
|
||||
}
|
||||
.resimg {
|
||||
display: grid;
|
||||
|
@ -130,11 +148,12 @@ div p a {
|
|||
}
|
||||
.thumbnail-image img {
|
||||
width:100%;
|
||||
height:170px;
|
||||
min-height: 200px;
|
||||
object-fit:cover;
|
||||
border-radius:4px;
|
||||
transition:transform .3s ease;
|
||||
cursor:zoom-in
|
||||
}
|
||||
img {
|
||||
object-fit: cover; /* 保持图片的纵横比,但会将图片裁剪以填充容器 */
|
||||
object-position: center; /* 保证中央部分 */
|
||||
}
|
||||
/* 当屏幕宽度小于732px时 */
|
||||
@media (max-width: 732px) {
|
||||
|
@ -148,6 +167,33 @@ div p a {
|
|||
grid-template-columns: 1fr; /* 修改为一列 */
|
||||
}
|
||||
}
|
||||
.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'); ?>
|
283
post.php
283
post.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">
|
||||
|
@ -26,19 +34,19 @@
|
|||
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('0', '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)): ?>
|
||||
<a href="<?php $this->options->adminUrl('write-post.php?cid=' . $this->cid); ?>" target="_blank" title="编辑文章">
|
||||
<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>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
|
||||
<path d="M16.7574 2.99677L14.7574 4.99677H5V18.9968H19V9.23941L21 7.23941V19.9968C21 20.5491 20.5523 20.9968 20 20.9968H4C3.44772 20.9968 3 20.5491 3 19.9968V3.99677C3 3.44448 3.44772 2.99677 4 2.99677H16.7574ZM20.4853 2.09727L21.8995 3.51149L12.7071 12.7039L11.2954 12.7063L11.2929 11.2897L20.4853 2.09727Z">
|
||||
</path>
|
||||
</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>
|
||||
<!--打赏 -->
|
||||
<?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>
|
||||
|
@ -128,6 +136,43 @@
|
|||
<?php if ($this->options->showProfile): ?>
|
||||
<?php $this->need('profile.php'); ?>
|
||||
<?php endif; ?>
|
||||
<!-- 分类-->
|
||||
<?php if ($this->options->showcate): ?>
|
||||
<?php
|
||||
// 初始化分类图片地址为空
|
||||
$categoryImage = '';
|
||||
|
||||
// 检查文章是否有分类
|
||||
if ($this->categories) {
|
||||
// 获取第一个分类的信息
|
||||
$category = $this->categories[0];
|
||||
$categoryId = $category['mid'];
|
||||
$categoryName = $category['name'];
|
||||
$categoryDescription = $category['description']; // 如果分类有说明(描述)
|
||||
|
||||
// 获取主题选项中的分类图片基本 URL
|
||||
$themeUrl = $this->options->midimg;
|
||||
|
||||
// 生成分类图片地址
|
||||
$categoryImage = $themeUrl . $categoryId . '.jpg';
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- 显示分类信息 -->
|
||||
<?php if ($category): ?>
|
||||
<div class="category--card__list">
|
||||
<a href="<?php echo $category['permalink']; ?>" class="category--card">
|
||||
<div class="category--card__image">
|
||||
<img src="<?php echo htmlspecialchars($categoryImage); ?>" alt="<?php echo htmlspecialchars($categoryName); ?>">
|
||||
</div>
|
||||
<div class="category--card__content">
|
||||
<div class="category--card__title"><?php echo htmlspecialchars($categoryName); ?></div>
|
||||
<div class="category--card__description"><?php echo htmlspecialchars($categoryDescription); ?></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<!-- 相关文章-->
|
||||
<?php if ($this->options->showrelated): ?>
|
||||
<?php $this->need('related.php'); ?>
|
||||
|
@ -151,90 +196,162 @@
|
|||
</nav>
|
||||
</ul>
|
||||
</article>
|
||||
<?php if($this->options->showtoc): ?>
|
||||
<!--TOC 在宽度大于1400px时才会显示-->
|
||||
</main>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
const postContent = document.querySelector('.post--single__content');
|
||||
if (!postContent) return;
|
||||
const targetClassElement = document.querySelector('.post--single__title');
|
||||
const postContent = document.querySelector('.post--single__content');
|
||||
if (!postContent) return;
|
||||
|
||||
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;
|
||||
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');
|
||||
let levelCounts = [0]; // 初始化层级计数器
|
||||
if (!found) return;
|
||||
|
||||
heads.forEach((head, index) => {
|
||||
const level = parseInt(head.tagName.substring(1));
|
||||
if (levelCounts[level] === undefined) {
|
||||
levelCounts[level] = 1; // 初始化该层级计数
|
||||
} else {
|
||||
levelCounts[level]++;
|
||||
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>';
|
||||
|
||||
// 插入到指定 class 元素之后
|
||||
if (targetClassElement) {
|
||||
targetClassElement.parentNode.insertBefore(toc, targetClassElement.nextSibling);
|
||||
}
|
||||
// 重置下级标题的计数器
|
||||
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 numbers = levelCounts.slice(1, level + 1).join(' ') ;
|
||||
const item = document.createElement('li');
|
||||
item.classList.add('toc-item'); // 添加基本类
|
||||
item.classList.add(`level-${level}`); // 根据级别添加类
|
||||
const anchor = `toc${index}`;
|
||||
head.id = anchor;
|
||||
const link = document.createElement('a');
|
||||
link.href = `#${anchor}`;
|
||||
link.textContent = `${numbers}. ${head.textContent}`; // 序号+标题文本
|
||||
item.appendChild(link);
|
||||
currentList.appendChild(item);
|
||||
});
|
||||
|
||||
let currentLevel = 0;
|
||||
let currentList = toc.querySelector('ul');
|
||||
let levelCounts = [0];
|
||||
|
||||
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;
|
||||
/* 其他样式... */
|
||||
<script>
|
||||
function fetchWithRetry(url, retries = 3) {
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return response.text(); // 首先获取文本响应
|
||||
})
|
||||
.then(text => {
|
||||
try {
|
||||
return JSON.parse(text); // 尝试解析 JSON
|
||||
} catch (e) {
|
||||
console.error('Invalid JSON:', text);
|
||||
throw new Error('Invalid JSON response');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (retries > 0) {
|
||||
console.log(`Retrying... (${retries} attempts left)`);
|
||||
return new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
|
||||
.then(() => fetchWithRetry(url, retries - 1));
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
@media screen and (max-width: 1400px) {
|
||||
#toc {
|
||||
display: none;
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const doubanLinks = document.querySelectorAll('a[href^="https://movie.douban.com/subject/"]');
|
||||
|
||||
doubanLinks.forEach(link => {
|
||||
const url = link.href;
|
||||
const movieId = url.match(/subject\/(\d+)/)[1];
|
||||
|
||||
link.innerHTML += ' <span class="loading">(加载中...)</span>';
|
||||
|
||||
fetchWithRetry(`<?php $this->options->themeUrl('db.php'); ?>?id=${movieId}`)
|
||||
.then(data => {
|
||||
const movieInfo = createMovieInfoHTML(data, url);
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = movieInfo;
|
||||
link.parentNode.replaceChild(wrapper, link);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching movie data:', error);
|
||||
// 显示错误消息给用户
|
||||
link.innerHTML = `<span style="color: red;">加载失败</span> <a href="${url}" target="_blank">查看豆瓣电影详情</a>`;
|
||||
})
|
||||
.finally(() => {
|
||||
const loadingSpan = link.querySelector('.loading');
|
||||
if (loadingSpan) {
|
||||
loadingSpan.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createMovieInfoHTML(data, originalUrl) {
|
||||
if (!data || data.error || Object.keys(data).length === 0) {
|
||||
return `<a href="${originalUrl}" target="_blank">查看豆瓣电影详情</a>`;
|
||||
}
|
||||
|
||||
return `
|
||||
<div class=doulist-item>
|
||||
<div class=doulist-subject>
|
||||
<div class=doulist-post>
|
||||
<img decoding=async referrerpolicy=no-referrer src=${data.img}>
|
||||
</div>
|
||||
<div class=doulist-content>
|
||||
<div class=doulist-title>
|
||||
<a href="${originalUrl}" class=cute target="_blank" rel="external nofollow"> ${data.name} </a>
|
||||
</div>
|
||||
<div class=rating>
|
||||
<span class=rating_nums>豆瓣评分 : ${data.rating}</span>
|
||||
</div>
|
||||
<div class=abstract>
|
||||
${data.year}年 · ${data.country} · ${data.genre} · 导演: ${data.director} · 演员 : ${data.actor}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
</script>
|
||||
|
||||
<?php $this->need('footer.php'); ?>
|
165
postlist.php
165
postlist.php
|
@ -1,11 +1,109 @@
|
|||
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
|
||||
<?php
|
||||
// 确保退出安全
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
/** 文章置顶 */
|
||||
$sticky = $this->options->sticky; // 置顶的文章id,多个用|隔开
|
||||
$db = Typecho_Db::get();
|
||||
$pageSize = $this->options->pageSize;
|
||||
|
||||
if ($sticky && !empty(trim($sticky))) {
|
||||
$sticky_cids = array_filter(explode('|', $sticky)); // 分割文本并过滤空值
|
||||
if (!empty($sticky_cids)) {
|
||||
$sticky_html = " <span class='sticky--post'> 置顶 </span> "; // 置顶标题的 html
|
||||
|
||||
// 清空原有文章的队列
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
|
||||
// 获取总数,并排除置顶文章数量
|
||||
if (isset($this->currentPage) && $this->currentPage == 1) {
|
||||
$totalOriginal = $this->getTotal();
|
||||
$stickyCount = count($sticky_cids);
|
||||
$this->setTotal(max($totalOriginal - $stickyCount, 0));
|
||||
|
||||
// 构建置顶文章的查询
|
||||
$selectSticky = $this->select()->where('type = ?', 'post');
|
||||
foreach ($sticky_cids as $i => $cid) {
|
||||
if ($i == 0)
|
||||
$selectSticky->where('cid = ?', $cid);
|
||||
else
|
||||
$selectSticky->orWhere('cid = ?', $cid);
|
||||
}
|
||||
|
||||
// 获取置顶文章
|
||||
$stickyPosts = $db->fetchAll($selectSticky);
|
||||
|
||||
// 压入置顶文章到文章队列
|
||||
foreach ($stickyPosts as &$stickyPost) {
|
||||
$stickyPost['title'] .= $sticky_html;
|
||||
$this->push($stickyPost);
|
||||
}
|
||||
|
||||
$standardPageSize = $pageSize - count($stickyPosts);
|
||||
} else {
|
||||
$standardPageSize = $pageSize;
|
||||
}
|
||||
|
||||
// 构建正常文章查询,排除置顶文章
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $standardPageSize);
|
||||
|
||||
foreach ($sticky_cids as $cid) {
|
||||
$selectNormal->where('table.contents.cid != ?', $cid);
|
||||
}
|
||||
} else {
|
||||
// 如果sticky_cids为空,使用默认查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
} else {
|
||||
// 如果没有置顶文章,使用默认查询
|
||||
$selectNormal = $this->select()
|
||||
->where('type = ?', 'post')
|
||||
->where('status = ?', 'publish')
|
||||
->where('created < ?', time())
|
||||
->order('created', Typecho_Db::SORT_DESC)
|
||||
->page(isset($this->currentPage) ? $this->currentPage : 1, $pageSize);
|
||||
}
|
||||
|
||||
// 登录用户显示私密文章
|
||||
if ($this->user->hasLogin()) {
|
||||
$uid = $this->user->uid;
|
||||
if ($uid) {
|
||||
$selectNormal->orWhere('authorId = ? AND status = ?', $uid, 'private');
|
||||
}
|
||||
}
|
||||
|
||||
$normalPosts = $db->fetchAll($selectNormal);
|
||||
|
||||
// 如果之前没有清空队列(没有置顶文章的情况),现在清空
|
||||
if (empty($sticky) || empty(trim($sticky)) || empty($sticky_cids)) {
|
||||
$this->row = [];
|
||||
$this->stack = [];
|
||||
$this->length = 0;
|
||||
}
|
||||
|
||||
// 压入正常文章到文章队列
|
||||
foreach ($normalPosts as $normalPost) {
|
||||
$this->push($normalPost);
|
||||
}
|
||||
?>
|
||||
<?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,7 +151,7 @@
|
|||
</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
|
||||
|
@ -66,59 +164,20 @@
|
|||
</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>',
|
||||
'<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>',
|
||||
$this->pageNav(
|
||||
' ',
|
||||
' ',
|
||||
1,
|
||||
'...',
|
||||
array(
|
||||
'wrapTag' => 'div',
|
||||
'wrapClass' => 'pagination_page',
|
||||
'wrapTag' => 'nav',
|
||||
'wrapClass' => 'nav-links nav-links__comment',
|
||||
'itemTag' => '',
|
||||
'textTag' => 'a',
|
||||
'currentClass' => 'active',
|
||||
'prevClass' => 'prev',
|
||||
'nextClass' => 'next'
|
||||
'textTag' => 'span',
|
||||
'itemClass' => 'page-numbers',
|
||||
'currentClass' => 'page-numbers current',
|
||||
'prevClass' => 'hidden',
|
||||
'nextClass' => 'hidden'
|
||||
)
|
||||
);
|
||||
?>
|
||||
<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>
|
|
@ -2,7 +2,7 @@
|
|||
<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() ?>
|
||||
|
|
Loading…
Reference in New Issue