文章页优化
This commit is contained in:
1 parent
9d6de3158e
commit
39b15b4be9
12 files changed
+1015
-9
No files matched your search
@@ -0,0 +1,53 @@
|
||||
---
|
||||
type Props = {
|
||||
currentPage: number;
|
||||
totalPages: number;
|
||||
basePath?: string;
|
||||
};
|
||||
|
||||
const { currentPage, totalPages, basePath = '/' } = Astro.props;
|
||||
|
||||
const normalizedBasePath = basePath.endsWith('/') ? basePath : `${basePath}/`;
|
||||
const getPageHref = (page: number) => (page <= 1 ? normalizedBasePath : `${normalizedBasePath}page/${page}/`);
|
||||
const pages = Array.from({ length: totalPages }, (_, index) => index + 1);
|
||||
---
|
||||
|
||||
{
|
||||
totalPages > 1 && (
|
||||
<nav class="pagination" aria-label="分页导航">
|
||||
{currentPage > 1 ? (
|
||||
<a class="pagination-link pagination-prev" href={getPageHref(currentPage - 1)} aria-label="上一页">
|
||||
上一页
|
||||
</a>
|
||||
) : (
|
||||
<span class="pagination-link pagination-prev is-disabled" aria-disabled="true">
|
||||
上一页
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div class="pagination-pages" aria-label={`第 ${currentPage} 页,共 ${totalPages} 页`}>
|
||||
{pages.map((page) =>
|
||||
page === currentPage ? (
|
||||
<span class="pagination-number is-current" aria-current="page">
|
||||
{page}
|
||||
</span>
|
||||
) : (
|
||||
<a class="pagination-number" href={getPageHref(page)}>
|
||||
{page}
|
||||
</a>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
{currentPage < totalPages ? (
|
||||
<a class="pagination-link pagination-next" href={getPageHref(currentPage + 1)} aria-label="下一页">
|
||||
下一页
|
||||
</a>
|
||||
) : (
|
||||
<span class="pagination-link pagination-next is-disabled" aria-disabled="true">
|
||||
下一页
|
||||
</span>
|
||||
)}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
import type { BlogPost } from '@/lib/posts';
|
||||
|
||||
interface Props {
|
||||
post: BlogPost;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const author = 'biss';
|
||||
const licenseName = 'CC BY-NC-SA 4.0';
|
||||
const licenseHref = 'https://creativecommons.org/licenses/by-nc-sa/4.0/';
|
||||
const postUrl = new URL(post.href, Astro.site ?? Astro.url.origin).toString();
|
||||
const displayPath = post.href;
|
||||
const tags = post.tags;
|
||||
---
|
||||
|
||||
<section class="post-copyright-card" aria-label="文章版权信息">
|
||||
<div class="post-copyright-mark" aria-hidden="true">
|
||||
<span>CC</span>
|
||||
</div>
|
||||
|
||||
<div class="post-copyright-main">
|
||||
<h2>{post.title}</h2>
|
||||
<a class="post-copyright-link" href={post.href}>{displayPath}</a>
|
||||
|
||||
<dl class="post-copyright-meta">
|
||||
<div>
|
||||
<dt>作者</dt>
|
||||
<dd>{author}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>发布于</dt>
|
||||
<dd><time datetime={post.date.toISOString()}>{post.dateText}</time></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>许可协议</dt>
|
||||
<dd><a href={licenseHref} target="_blank" rel="noreferrer">{licenseName}</a></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="post-copyright-footer">
|
||||
{tags.length > 0 && (
|
||||
<div class="post-copyright-tags" aria-label="文章标签">
|
||||
{tags.map((tag) => <a href={`/tags/${encodeURIComponent(tag)}/`}>{tag}</a>)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="post-copyright-actions" aria-label="文章操作">
|
||||
<button
|
||||
class="post-copyright-action is-primary post-share-button"
|
||||
type="button"
|
||||
data-share-title={post.title}
|
||||
data-share-url={postUrl}
|
||||
title="分享文章"
|
||||
>
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7" />
|
||||
<path d="M12 16V4" />
|
||||
<path d="m7 9 5-5 5 5" />
|
||||
</svg>
|
||||
<span>分享</span>
|
||||
</button>
|
||||
<a class="post-copyright-action" href="/rss.xml" title="订阅 RSS">
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M5 5a14 14 0 0 1 14 14" />
|
||||
<path d="M5 11a8 8 0 0 1 8 8" />
|
||||
<path d="M6 18h.01" />
|
||||
</svg>
|
||||
<span>订阅</span>
|
||||
</a>
|
||||
<a class="post-copyright-action" href="/about/" title="打赏作者">
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M7 8h10" />
|
||||
<path d="M8 8V5h8v3" />
|
||||
<path d="M6 8h12l-1.5 11h-9L6 8Z" />
|
||||
<path d="M10 12h4" />
|
||||
</svg>
|
||||
<span>打赏</span>
|
||||
</a>
|
||||
<a class="post-copyright-icon" href={`https://twitter.com/intent/tweet?url=${encodeURIComponent(postUrl)}&text=${encodeURIComponent(post.title)}`} target="_blank" rel="noreferrer" title="分享到 X">
|
||||
<span aria-hidden="true">x</span>
|
||||
</a>
|
||||
<a class="post-copyright-icon" href={`https://service.weibo.com/share/share.php?url=${encodeURIComponent(postUrl)}&title=${encodeURIComponent(post.title)}`} target="_blank" rel="noreferrer" title="分享到微博">
|
||||
<span aria-hidden="true">微</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script is:inline>
|
||||
(() => {
|
||||
document.querySelectorAll('.post-share-button').forEach((button) => {
|
||||
button.addEventListener('click', async () => {
|
||||
const title = button.dataset.shareTitle || document.title;
|
||||
const url = button.dataset.shareUrl || window.location.href;
|
||||
const label = button.querySelector('span');
|
||||
const originalText = label?.textContent || '分享';
|
||||
|
||||
try {
|
||||
if (navigator.share) {
|
||||
await navigator.share({ title, url });
|
||||
return;
|
||||
}
|
||||
|
||||
await navigator.clipboard.writeText(url);
|
||||
if (label) label.textContent = '已复制';
|
||||
} catch {
|
||||
if (label) label.textContent = '复制失败';
|
||||
} finally {
|
||||
window.setTimeout(() => {
|
||||
if (label) label.textContent = originalText;
|
||||
}, 1800);
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
@@ -9,6 +9,7 @@ interface Props {
|
||||
const siteTitle = "Bi's Blog";
|
||||
const { title = siteTitle, description = 'Personal blog by biss.' } = Astro.props;
|
||||
const pageTitle = title === siteTitle ? siteTitle : `${title} | ${siteTitle}`;
|
||||
const currentYear = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
@@ -36,9 +37,81 @@ const pageTitle = title === siteTitle ? siteTitle : `${title} | ${siteTitle}`;
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
<footer class="site-footer">
|
||||
<span>© {new Date().getFullYear()} Bi's Blog</span>
|
||||
<a href="/rss.xml">RSS</a>
|
||||
<footer class="site-footer" aria-label="站点页脚">
|
||||
<div class="footer-inner">
|
||||
<section class="footer-top" aria-label="站点信息">
|
||||
<a class="footer-brand" href="/" aria-label="Bi's Blog 首页">
|
||||
<img src="/images/Bi.ico" alt="" loading="lazy" />
|
||||
<span>Bi's Blog</span>
|
||||
</a>
|
||||
<p class="footer-slogan">好奇心转化为代码的空间。</p>
|
||||
</section>
|
||||
|
||||
<section class="footer-contact" aria-label="联系方式">
|
||||
<p>联系方式</p>
|
||||
<div class="footer-socials">
|
||||
<a href="mailto:bishsh2006@gmail.com" aria-label="发送邮件" title="发送邮件">
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M4 6h16v12H4z" />
|
||||
<path d="m4 7 8 6 8-6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="/rss.xml" aria-label="订阅 RSS" title="订阅 RSS">
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M6 17h.01" />
|
||||
<path d="M6 7a11 11 0 0 1 11 11" />
|
||||
<path d="M6 12a6 6 0 0 1 6 6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://github.com/bishshi" target="_blank" rel="noreferrer" aria-label="GitHub" title="GitHub">
|
||||
<svg aria-hidden="true" viewBox="0 0 24 24">
|
||||
<path d="M12 3a9 9 0 0 0-3 17c.5.1.7-.2.7-.5v-1.8c-2.8.6-3.4-1.2-3.4-1.2-.4-1.1-1-1.4-1-1.4-.9-.6.1-.6.1-.6 1 0 1.5 1 1.5 1 .9 1.5 2.3 1.1 2.9.8.1-.6.3-1.1.6-1.3-2.2-.2-4.5-1.1-4.5-4.8 0-1.1.4-1.9 1-2.6-.1-.3-.4-1.3.1-2.6 0 0 .8-.3 2.7 1a9 9 0 0 1 4.9 0c1.8-1.3 2.6-1 2.6-1 .5 1.3.2 2.3.1 2.6.6.7 1 1.6 1 2.6 0 3.7-2.3 4.5-4.5 4.8.4.3.7 1 .7 2v2.5c0 .3.2.6.7.5A9 9 0 0 0 12 3Z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<nav class="footer-contact-links" aria-label="页脚链接">
|
||||
<a href="/archives/">发展历程</a>
|
||||
<span aria-hidden="true">|</span>
|
||||
<a href="/privacy/">隐私政策</a>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section class="footer-bottom" aria-label="版权信息">
|
||||
<div>
|
||||
<p>© 2025 - {currentYear} Bi's Blog</p>
|
||||
<p>blog.biss.click | 内容采用 CC BY-NC-SA 4.0 协议</p>
|
||||
</div>
|
||||
<div class="footer-meta">
|
||||
<p>本站已苟活:<span id="site-runtime">计算中...</span></p>
|
||||
<p>
|
||||
<a href="https://edgeone.ai/" target="_blank" rel="noreferrer">EdgeOne</a>
|
||||
<span aria-hidden="true">|</span>
|
||||
<a href="https://astro.build/" target="_blank" rel="noreferrer">ASTRO</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</footer>
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const runtime = document.getElementById('site-runtime');
|
||||
if (!runtime) return;
|
||||
|
||||
const start = new Date('2025-01-01T00:00:00+08:00').getTime();
|
||||
const pad = (value) => String(value).padStart(2, '0');
|
||||
|
||||
function updateRuntime() {
|
||||
const diff = Math.max(0, Date.now() - start);
|
||||
const days = Math.floor(diff / 86400000);
|
||||
const hours = Math.floor((diff / 3600000) % 24);
|
||||
const minutes = Math.floor((diff / 60000) % 60);
|
||||
const seconds = Math.floor((diff / 1000) % 60);
|
||||
runtime.textContent = `${days} 天 ${pad(hours)} 时 ${pad(minutes)} 分 ${pad(seconds)} 秒`;
|
||||
}
|
||||
|
||||
updateRuntime();
|
||||
window.setInterval(updateRuntime, 1000);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loaded 3 of 12 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user