完善页脚

This commit is contained in:
nxxy335top
2026-05-19 14:18:09 +08:00
parent 1bf7107966
commit 93dc21e69b
18 changed files with 550 additions and 137 deletions
+3 -3
View File
@@ -4,14 +4,14 @@ import Layout from "../layouts/Layout.astro";
<Layout>
<Fragment slot="head">
<title th:text="|归档 - ${site.title}|"></title>
<title th:text="|${theme.config?.basic?.label_archives_title ?: '归档'} - ${site.title}|"></title>
</Fragment>
<div class="wi-archives">
<header class="wi-archives__header">
<h1 class="wi-archives__title">归档</h1>
<h1 class="wi-archives__title" th:text="${theme.config?.basic?.label_archives_title ?: '归档'}">归档</h1>
<span class="wi-page-accent"></span>
<p class="wi-archives__subtitle" th:text="|共 ${archives.total} 篇文章|"></p>
<p class="wi-archives__subtitle" th:text="${#strings.replace(theme.config?.home?.home_label_post_count ?: '共 {total} 篇文章', '{total}', #strings.toString(archives.total))}"></p>
</header>
<section class="wi-archives__timeline" aria-label="Archive timeline">
+76 -29
View File
@@ -20,21 +20,41 @@ import Layout from "../layouts/Layout.astro";
class="wi-categories__item"
th:href="@{${category.status.permalink}}"
>
<div
class="wi-categories__cover"
th:if="${category.spec.cover != null and !#strings.isEmpty(category.spec.cover)}"
>
<img
th:src="${category.spec.cover}"
th:alt="${category.spec.displayName}"
class="wi-categories__cover-img"
loading="lazy"
decoding="async"
/>
</div>
<div
class="wi-categories__cover wi-categories__cover--placeholder"
th:if="${category.spec.cover == null or #strings.isEmpty(category.spec.cover)}"
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="24" height="24"><path d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
</div>
<div class="wi-categories__item-content">
<span
class="wi-categories__name"
th:text="${category.spec.displayName}"
></span>
<div class="wi-categories__name-row">
<span
class="wi-categories__name"
th:text="${category.spec.displayName}"
></span>
<span
class="wi-categories__count"
th:text="${category.postCount}"
></span>
</div>
<p
th:if="${not #strings.isEmpty(category.spec.description)}"
class="wi-categories__desc"
th:text="${category.spec.description}"
></p>
</div>
<span
class="wi-categories__count"
th:text="${category.postCount}"
></span>
</a>
</nav>
</div>
@@ -76,35 +96,67 @@ import Layout from "../layouts/Layout.astro";
.wi-categories__list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: var(--space-md);
}
.wi-categories__item {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: var(--space-lg);
display: flex;
gap: var(--space-md);
padding: var(--space-lg);
border-radius: $border-radius-sm;
border-radius: 16px;
border: 1px solid var(--rule);
background: var(--bg);
background: var(--bg-raised);
text-decoration: none;
color: inherit;
align-items: start;
align-items: center;
transition: all var(--duration-fast) var(--ease-out-quart);
}
.wi-categories__item:hover {
border-color: var(--accent);
background: var(--bg-raised);
transform: translateY(-2px);
box-shadow: var(--shadow-sm);
box-shadow: var(--shadow-md);
}
.wi-categories__cover {
flex-shrink: 0;
width: 56px;
height: 56px;
border-radius: 12px;
overflow: hidden;
background: var(--bg);
}
.wi-categories__cover-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.wi-categories__cover--placeholder {
display: flex;
align-items: center;
justify-content: center;
background: var(--accent-bg);
color: var(--accent);
}
.wi-categories__item-content {
display: grid;
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.wi-categories__name-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-sm);
}
.wi-categories__name {
font-family: var(--font-sans);
font-size: var(--text-lg);
@@ -128,14 +180,14 @@ import Layout from "../layouts/Layout.astro";
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 2rem;
height: 2rem;
padding: 0 0.5rem;
min-width: 1.75rem;
height: 1.75rem;
padding: 0 0.4rem;
border-radius: 999px;
background: var(--bg-raised);
background: var(--bg);
border: 1px solid var(--rule);
color: var(--ink-3);
font-size: var(--text-sm);
font-size: var(--text-xs);
font-weight: 600;
white-space: nowrap;
flex-shrink: 0;
@@ -147,14 +199,9 @@ import Layout from "../layouts/Layout.astro";
border-color: var(--accent);
}
@media (max-width: 768px) {
.wi-categories__item {
@media (max-width: 640px) {
.wi-categories__list {
grid-template-columns: 1fr;
gap: var(--space-sm);
}
.wi-categories__count {
align-self: flex-start;
}
}
</style>
+51 -46
View File
@@ -15,62 +15,96 @@ import Layout from "../layouts/Layout.astro";
</div>
<div class="wi-douban__filters">
<th:block th:with="urlType = ${param.type}, isDefaultType = ${urlType == null or #strings.isEmpty(urlType.toString())}, currentType = ${isDefaultType ? 'movie' : urlType.toString()}">
<th:block th:with="urlType = ${param.type}, isDefaultType = ${urlType == null or #strings.isEmpty(urlType.toString())}, currentType = ${isDefaultType ? 'music' : urlType.toString()}, urlStatus = ${param.status}, hasStatus = ${urlStatus != null and !#strings.isEmpty(urlStatus.toString())}, currentStatus = ${hasStatus ? urlStatus.toString() : (isDefaultType ? 'done' : null)}">
<div class="wi-douban__filter-group" th:if="${types != null and !#lists.isEmpty(types)}">
<a
th:each="t : ${types}"
class="wi-douban__filter-tag"
th:href="@{/douban(type=${t.key})}"
th:text="${t.name}"
th:classappend="${(isDefaultType and t.key == 'movie') or (!isDefaultType and urlType.toString() == t.key) ? 'wi-douban__filter-tag--active' : ''}"
th:classappend="${(isDefaultType and t.key == 'music') or (!isDefaultType and urlType.toString() == t.key) ? 'wi-douban__filter-tag--active' : ''}"
></a>
</div>
<div class="wi-douban__filter-group wi-douban__status-filters">
<th:block th:if="${currentType == 'movie'}">
<th:block th:if="${currentType == 'movie' or currentType == 'drama'}">
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='movie',status='wish')}"
th:classappend="${param.status != null and param.status.toString() == 'wish' ? 'wi-douban__filter-tag--active' : ''}"
th:href="@{/douban(type=${currentType},status='wish')}"
th:classappend="${hasStatus and currentStatus == 'wish'} ? 'wi-douban__filter-tag--active' : ''"
>想看</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='movie',status='done')}"
th:classappend="${param.status != null and param.status.toString() == 'done' ? 'wi-douban__filter-tag--active' : ''}"
th:href="@{/douban(type=${currentType},status='done')}"
th:classappend="${(!hasStatus and isDefaultType) or (hasStatus and currentStatus == 'done')} ? 'wi-douban__filter-tag--active' : ''"
>看过</a>
</th:block>
<th:block th:if="${currentType == 'book'}">
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='book',status='wish')}"
th:classappend="${param.status != null and param.status.toString() == 'wish' ? 'wi-douban__filter-tag--active' : ''}"
>想</a>
th:classappend="${hasStatus and currentStatus == 'wish'} ? 'wi-douban__filter-tag--active' : ''"
>想</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='book',status='doing')}"
th:classappend="${param.status != null and param.status.toString() == 'doing' ? 'wi-douban__filter-tag--active' : ''}"
>在</a>
th:classappend="${hasStatus and currentStatus == 'doing'} ? 'wi-douban__filter-tag--active' : ''"
>在</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='book',status='done')}"
th:classappend="${param.status != null and param.status.toString() == 'done' ? 'wi-douban__filter-tag--active' : ''}"
>过</a>
th:classappend="${(!hasStatus and isDefaultType) or (hasStatus and currentStatus == 'done')} ? 'wi-douban__filter-tag--active' : ''"
>过</a>
</th:block>
<th:block th:if="${currentType == 'music'}">
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='music',status='wish')}"
th:classappend="${hasStatus and currentStatus == 'wish'} ? 'wi-douban__filter-tag--active' : ''"
>想听</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='music',status='doing')}"
th:classappend="${hasStatus and currentStatus == 'doing'} ? 'wi-douban__filter-tag--active' : ''"
>在听</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='music',status='done')}"
th:classappend="${(!hasStatus and isDefaultType) or (hasStatus and currentStatus == 'done')} ? 'wi-douban__filter-tag--active' : ''"
>听过</a>
</th:block>
<th:block th:if="${currentType == 'game'}">
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='game',status='wish')}"
th:classappend="${hasStatus and currentStatus == 'wish'} ? 'wi-douban__filter-tag--active' : ''"
>想玩</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='game',status='doing')}"
th:classappend="${hasStatus and currentStatus == 'doing'} ? 'wi-douban__filter-tag--active' : ''"
>在玩</a>
<a
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type='game',status='done')}"
th:classappend="${(!hasStatus and isDefaultType) or (hasStatus and currentStatus == 'done')} ? 'wi-douban__filter-tag--active' : ''"
>玩过</a>
</th:block>
</div>
<div class="wi-douban__filter-group" th:if="${genres != null and !#lists.isEmpty(genres)}">
<th:block th:each="g : ${genres}" th:with="urlStatus = ${param.status}, hasStatus = ${urlStatus != null and !#strings.isEmpty(urlStatus.toString())}">
<th:block th:each="g : ${genres}">
<a
th:if="${hasStatus}"
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type=${currentType}, status=${urlStatus.toString()}, genre=${g.name})}"
th:href="@{/douban(type=${currentType}, status=${currentStatus}, genre=${g.name})}"
th:text="|${g.name}(${g.doubanCount})|"
th:classappend="${param.genre != null and param.genre.toString() == g.name ? 'wi-douban__filter-tag--active' : ''}"
></a>
<a
th:unless="${hasStatus}"
class="wi-douban__filter-tag wi-douban__filter-tag--sm"
th:href="@{/douban(type=${currentType}, genre=${g.name})}"
th:href="@{/douban(type=${currentType}, status='done', genre=${g.name})}"
th:text="|${g.name}(${g.doubanCount})|"
th:classappend="${param.genre != null and param.genre.toString() == g.name ? 'wi-douban__filter-tag--active' : ''}"
></a>
@@ -79,7 +113,7 @@ import Layout from "../layouts/Layout.astro";
</th:block>
</div>
<th:block th:with="urlType = ${param.type}, isDefaultType = ${urlType == null or #strings.isEmpty(urlType.toString())}, currentType = ${isDefaultType ? 'movie' : urlType.toString()}, urlStatus = ${param.status}, hasStatus = ${urlStatus != null and !#strings.isEmpty(urlStatus.toString())}, currentStatus = ${hasStatus ? urlStatus.toString() : null}, urlGenre = ${param.genre}, hasGenre = ${urlGenre != null and !#strings.isEmpty(urlGenre.toString())}, currentGenre = ${hasGenre ? urlGenre.toString() : null}, doubans = ${hasStatus ? doubanFinder.list(1, 100, currentType, currentStatus) : doubanFinder.listByType(1, 100, currentType)}">
<th:block th:with="urlType = ${param.type}, isDefaultType = ${urlType == null or #strings.isEmpty(urlType.toString())}, currentType = ${isDefaultType ? 'music' : urlType.toString()}, urlStatus = ${param.status}, hasStatus = ${urlStatus != null and !#strings.isEmpty(urlStatus.toString())}, currentStatus = ${hasStatus ? urlStatus.toString() : 'done'}, urlGenre = ${param.genre}, hasGenre = ${urlGenre != null and !#strings.isEmpty(urlGenre.toString())}, currentGenre = ${hasGenre ? urlGenre.toString() : null}, doubans = ${doubanFinder.list(1, 100, currentType, currentStatus)}">
<div class="wi-douban__grid">
<article
@@ -134,11 +168,6 @@ import Layout from "../layouts/Layout.astro";
th:if="${!#strings.isEmpty(item.spec?.year)}"
th:text="${item.spec?.year}"
></span>
<span
class="wi-douban__type-badge"
th:if="${!#strings.isEmpty(item.spec?.type)}"
th:text="${item.spec?.type}"
></span>
</div>
<div class="wi-douban__tags" th:if="${item.spec?.genres != null and !#sets.isEmpty(item.spec?.genres)}">
<span
@@ -152,11 +181,6 @@ import Layout from "../layouts/Layout.astro";
th:if="${!#strings.isEmpty(item.faves?.remark)}"
th:text="${item.faves?.remark}"
></p>
<span
class="wi-douban__status"
th:if="${!#strings.isEmpty(item.faves?.status)}"
th:text="${item.faves?.status == 'done' ? '看过' : (item.faves?.status == 'doing' ? '在看' : '想看')}"
></span>
</div>
</article>
</div>
@@ -343,14 +367,6 @@ import Layout from "../layouts/Layout.astro";
font-weight: 500;
}
.wi-douban__type-badge {
padding: 1px 6px;
border-radius: 4px;
background: var(--accent-bg);
color: var(--accent);
font-weight: 500;
}
.wi-douban__tags {
display: flex;
flex-wrap: wrap;
@@ -379,17 +395,6 @@ import Layout from "../layouts/Layout.astro";
z-index: 2;
}
.wi-douban__status {
display: inline-block;
font-size: 11px;
padding: 2px 8px;
border-radius: 4px;
background: color-mix(in srgb, var(--accent) 10%, transparent);
color: var(--accent);
font-weight: 500;
width: fit-content;
}
@media (max-width: 640px) {
.wi-douban__grid {
grid-template-columns: 1fr;
+3 -2
View File
@@ -33,7 +33,7 @@ import HeroSection from "../components/HeroSection.astro";
class="wi-pinned__cover"
th:if="${!#strings.isEmpty(post.spec.cover)}"
>
<img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-pinned__image" />
<img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-pinned__image" loading="lazy" decoding="async" />
</div>
<div class="wi-pinned__body">
<div class="wi-pinned__meta">
@@ -137,7 +137,7 @@ import HeroSection from "../components/HeroSection.astro";
class="wi-flow__cover"
th:if="${!#strings.isEmpty(post.spec.cover)}"
>
<img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-flow__image" />
<img th:src="${post.spec.cover}" th:alt="${post.spec.title}" class="wi-flow__image" loading="lazy" decoding="async" />
</div>
</article>
</div>
@@ -196,6 +196,7 @@ import HeroSection from "../components/HeroSection.astro";
var grid = document.getElementById("wi-post-grid");
var loading = false;
var nextUrl = sentinel.getAttribute("data-next-url");
var allLoadedText = sentinel.getAttribute("data-all-loaded-text") || "已加载全部文章";
var observer = new IntersectionObserver(
function (entries) {
+27
View File
@@ -10,6 +10,7 @@ import Layout from "../layouts/Layout.astro";
<section
class="wi-links"
th:if="${pluginFinder.available('PluginLinks')}"
th:attr="data-style=${theme.config?.links?.links_style ?: 'cards'}"
>
<div class="wi-container">
<div class="wi-links__header">
@@ -121,6 +122,32 @@ import Layout from "../layouts/Layout.astro";
margin-bottom: var(--space-2xl);
}
.wi-links[data-style="list"] .wi-links__grid {
grid-template-columns: 1fr;
max-width: 720px;
}
.wi-links[data-style="list"] .wi-links__card-inner {
border-radius: 12px;
padding: var(--space-md) var(--space-lg);
}
.wi-links[data-style="grid"] .wi-links__grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: var(--space-sm);
}
.wi-links[data-style="grid"] .wi-links__card-inner {
flex-direction: column;
align-items: center;
text-align: center;
padding: var(--space-xl) var(--space-lg);
}
.wi-links[data-style="grid"] .wi-links__arrow {
display: none;
}
.wi-links__card {
position: relative;
border-radius: 16px;
+151 -1
View File
@@ -18,7 +18,7 @@ import LightGallery from "../components/LightGallery.astro";
<th:block th:if="${pluginFinder.available('PluginMoments')}">
<div class="wi-moments-page__content">
<th:block th:if="${momentFinder != null}">
<th:block th:with="momentsResult = ${momentFinder.list(1, 50)}">
<th:block th:with="pageSize = ${theme.config?.moments?.moments_page_size ?: 10}, momentsResult = ${momentFinder.list(1, pageSize)}">
<div
class="wi-moments-page__timeline"
th:if="${theme.config?.moments?.moments_style == 'timeline' or theme.config?.moments?.moments_style == null}"
@@ -195,6 +195,29 @@ import LightGallery from "../components/LightGallery.astro";
</div>
</th:block>
</th:block>
<nav
class="wi-moments-page__pagination"
th:if="${theme.config?.moments?.moments_loading_mode == 'pagination' and momentsResult != null and momentsResult.hasPrevious()}"
>
<a
class="wi-moments-page__page-btn"
th:if="${momentsResult.hasPrevious()}"
th:href="${momentsResult.prevUrl}"
>← 较新</a>
<span class="wi-moments-page__page-spacer" th:if="${momentsResult.hasPrevious() and momentsResult.hasNext()}"></span>
<a
class="wi-moments-page__page-btn"
th:if="${momentsResult.hasNext()}"
th:href="${momentsResult.nextUrl}"
>较旧 →</a>
</nav>
<div
class="wi-moments-page__infinite-sentinel"
th:if="${theme.config?.moments?.moments_loading_mode != 'pagination' and momentsResult != null and momentsResult.hasNext()}"
th:attr="data-next-url=${momentsResult.nextUrl}"
></div>
<th:block th:if="${momentFinder == null}">
<div class="wi-moments-page__empty">
<p>瞬间插件加载异常,请检查插件状态</p>
@@ -315,6 +338,98 @@ import LightGallery from "../components/LightGallery.astro";
}
loadMomentStats();
var sentinel = document.querySelector(".wi-moments-page__infinite-sentinel");
if (sentinel) {
var momentsContent = document.querySelector(".wi-moments-page__content");
var infiniteLoading = false;
var infiniteNextUrl = sentinel.getAttribute("data-next-url");
var infiniteObserver = new IntersectionObserver(
function (entries) {
if (entries[0].isIntersecting && !infiniteLoading && infiniteNextUrl) {
infiniteLoading = true;
fetch(infiniteNextUrl)
.then(function (res) {
if (!res.ok) throw new Error("Fetch failed");
return res.text();
})
.then(function (html) {
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
var style = sentinel.closest(".wi-moments-page__content")
? sentinel.closest(".wi-moments-page__content").querySelector(
sentinel.previousElementSibling
? sentinel.previousElementSibling.className.split(" ")[0]
: ".wi-moments-page__timeline"
)
: null;
var container = null;
var selectors = [
".wi-moments-page__timeline",
".wi-moments-page__cards",
".wi-moments-page__masonry"
];
for (var s = 0; s < selectors.length; s++) {
container = doc.querySelector(selectors[s]);
if (container) break;
}
if (!container) {
infiniteLoading = false;
return;
}
var currentContainer = document.querySelector(selectors[0]) ||
document.querySelector(selectors[1]) ||
document.querySelector(selectors[2]);
if (!currentContainer) {
infiniteLoading = false;
return;
}
var newItems = container.children;
for (var i = 0; i < newItems.length; i++) {
var item = newItems[i].cloneNode(true);
item.style.opacity = "0";
item.style.transform = "translateY(20px)";
currentContainer.appendChild(item);
(function (el) {
requestAnimationFrame(function () {
el.style.transition = "opacity 0.4s ease, transform 0.4s ease";
el.style.opacity = "1";
el.style.transform = "translateY(0)";
});
})(item);
}
var newSentinel = doc.querySelector(".wi-moments-page__infinite-sentinel");
if (newSentinel && newSentinel.getAttribute("data-next-url")) {
infiniteNextUrl = newSentinel.getAttribute("data-next-url");
sentinel.setAttribute("data-next-url", infiniteNextUrl);
} else {
infiniteNextUrl = null;
infiniteObserver.disconnect();
sentinel.style.display = "none";
var endMsg = document.createElement("div");
endMsg.className = "wi-moments-page__empty";
endMsg.innerHTML = "<p>已加载全部瞬间</p>";
sentinel.parentNode.appendChild(endMsg);
}
infiniteLoading = false;
})
.catch(function () {
infiniteLoading = false;
});
}
},
{ rootMargin: "300px" }
);
infiniteObserver.observe(sentinel);
}
})();
</script>
@@ -693,6 +808,41 @@ import LightGallery from "../components/LightGallery.astro";
letter-spacing: var(--tracking-wide);
}
.wi-moments-page__pagination {
display: flex;
justify-content: center;
align-items: center;
gap: var(--space-lg);
margin-top: var(--space-3xl);
}
.wi-moments-page__page-btn {
display: inline-block;
padding: 10px 24px;
border-radius: 12px;
background: var(--bg-raised);
border: 1px solid var(--rule);
color: var(--ink);
font-size: var(--text-sm);
text-decoration: none;
transition: border-color var(--duration-fast) var(--ease-out-quart),
color var(--duration-fast) var(--ease-out-quart);
}
.wi-moments-page__page-btn:hover {
border-color: var(--accent);
color: var(--accent);
}
.wi-moments-page__page-spacer {
flex: 1;
}
.wi-moments-page__infinite-sentinel {
height: 1px;
width: 100%;
}
@media (max-width: 768px) {
.wi-moments-page__timeline {
padding-left: var(--space-xl);
+1 -1
View File
@@ -30,7 +30,7 @@ import Layout from "../layouts/Layout.astro";
></div>
</div>
<div class="wi-messageboard__comment">
<div class="wi-messageboard__comment" th:attr="data-comment-style=${theme.config?.comment?.comment_style ?: 'warm'},data-show-avatar=${theme.config?.comment?.comment_show_avatar != false}">
<halo:comment
th:if="${haloCommentEnabled}"
group="content.halo.run"
+64 -11
View File
@@ -13,13 +13,15 @@ import LightGallery from "../components/LightGallery.astro";
<article class="wi-post">
<header class="wi-post__header">
<div
th:if="${!#strings.isEmpty(post.spec.cover)}"
th:if="${theme.config?.article?.article_show_cover != false and !#strings.isEmpty(post.spec.cover)}"
class="wi-post__cover-wrap"
>
<img
class="wi-post__cover"
th:src="${post.spec.cover}"
th:alt="${post.spec.title}"
loading="lazy"
decoding="async"
/>
</div>
@@ -31,7 +33,7 @@ import LightGallery from "../components/LightGallery.astro";
<div class="wi-post__meta">
<time
th:if="${theme.config?.article?.article_show_date}"
th:if="${theme.config?.article?.article_show_date != false}"
th:datetime="${post.spec.publishTime}"
th:text="${#dates.format(post.spec.publishTime, 'yyyy-MM-dd')}"
></time>
@@ -48,7 +50,7 @@ import LightGallery from "../components/LightGallery.astro";
</span>
</th:block>
<th:block
th:if="${theme.config?.article?.article_show_category && post.categories != null && post.categories.size() > 0}"
th:if="${theme.config?.article?.article_show_category != false && post.categories != null && post.categories.size() > 0}"
>
<span class="wi-post__meta-sep">·</span>
<span class="wi-post__meta-categories">
@@ -60,7 +62,7 @@ import LightGallery from "../components/LightGallery.astro";
</span>
</th:block>
<th:block
th:if="${theme.config?.article?.article_show_tags && post.tags != null && post.tags.size() > 0}"
th:if="${theme.config?.article?.article_show_tags != false && post.tags != null && post.tags.size() > 0}"
>
<span class="wi-post__meta-sep">·</span>
<span class="wi-post__meta-tags">
@@ -126,7 +128,7 @@ import LightGallery from "../components/LightGallery.astro";
</button>
</div>
<th:block th:if="${theme.config?.article?.article_show_nav}">
<th:block th:if="${theme.config?.article?.article_show_nav == true}">
<nav class="wi-post__nav" aria-label="Post navigation">
<th:block
th:with="cursor = ${postFinder.cursor(post.metadata.name)}"
@@ -165,7 +167,7 @@ import LightGallery from "../components/LightGallery.astro";
</nav>
</th:block>
<div class="wi-post__comment">
<div class="wi-post__comment" th:attr="data-comment-style=${theme.config?.comment?.comment_style ?: 'warm'},data-show-avatar=${theme.config?.comment?.comment_show_avatar != false}">
<halo:comment
th:if="${haloCommentEnabled}"
group="content.halo.run"
@@ -204,6 +206,35 @@ import LightGallery from "../components/LightGallery.astro";
<LightGallery />
<link
th:if="${theme.config?.article?.article_code_theme == 'cold'}"
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.min.css"
/>
<link
th:if="${theme.config?.article?.article_code_theme != 'cold'}"
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"
/>
<script is:inline src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
<script is:inline src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<script is:inline>
(function () {
if (typeof Prism !== "undefined") {
Prism.plugins.autoloader.languages_path = "https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/";
var body = document.getElementById("wi-post-body");
if (body) {
body.querySelectorAll("pre code").forEach(function (block) {
if (!block.classList.contains("language-")) {
Prism.highlightElement(block);
}
});
}
}
})();
</script>
<script is:inline>
(function () {
var progressBar = document.getElementById("wi-reading-progress");
@@ -603,6 +634,32 @@ import LightGallery from "../components/LightGallery.astro";
overflow-x: auto;
}
.wi-post__body pre {
margin-block: 1.5em;
padding: 1.25em;
border-radius: 12px;
border: 1px solid var(--rule);
background: var(--bg-raised);
font-size: 0.875em;
line-height: 1.6;
}
.wi-post__body pre code {
background: none;
padding: 0;
border: none;
border-radius: 0;
font-size: inherit;
}
.wi-post__body code {
background: var(--bg-raised);
padding: 0.15em 0.4em;
border-radius: 4px;
font-size: 0.875em;
border: 1px solid var(--rule);
}
.wi-post__body :is(h1, h2, h3, h4, h5, h6) {
font-family: var(--font-sans);
margin-top: 1.8em;
@@ -652,10 +709,6 @@ import LightGallery from "../components/LightGallery.astro";
margin-block-end: 0.6em;
}
.wi-post__body pre {
margin-block: 1.5em;
}
.wi-post__body blockquote {
margin-block: 2em;
}
@@ -956,7 +1009,7 @@ import LightGallery from "../components/LightGallery.astro";
color: #545164;
font-size: 0.875rem;
text-align: center;
margin-top: -0.8em;
margin-top: 0.5em;
margin-bottom: 1.2em;
line-height: 1.5;
}
+66 -16
View File
@@ -16,15 +16,23 @@ import Layout from "../layouts/Layout.astro";
<th:block th:with="profile = ${steamFinder.getProfile()}, stats = ${steamFinder.getStats()}, badges = ${steamFinder.getBadges()}, recentGames = ${steamFinder.getRecentGames(recentGamesLimit)}">
<div class="wi-steam__profile" th:if="${profile != null and profile.summary != null}">
<div class="wi-steam__profile" th:if="${profile != null}">
<div class="wi-steam__avatar">
<img
th:if="${profile.summary != null and !#strings.isEmpty(profile.summary?.avatarFull) and !#strings.contains(profile.summary?.avatarFull, '00000000000000000')}"
th:src="${profile.summary?.avatarFull}"
th:alt="${profile.summary?.personaName}"
th:alt="${profile.summary?.personaName ?: 'Steam'}"
class="wi-steam__avatar-img"
loading="lazy"
decoding="async"
/>
<span
class="wi-steam__avatar-placeholder"
th:if="${profile.summary == null or #strings.isEmpty(profile.summary?.avatarFull) or #strings.contains(profile.summary?.avatarFull, '00000000000000000')}"
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="36" height="36">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>
</svg>
</span>
<span
class="wi-steam__status-dot wi-steam__status-dot--playing"
th:if="${profile.playing}"
@@ -39,11 +47,11 @@ import Layout from "../layouts/Layout.astro";
></span>
</div>
<div class="wi-steam__info">
<h2 class="wi-steam__name" th:text="${profile.summary?.personaName}"></h2>
<span class="wi-steam__status-text" th:text="${profile.statusText}"></span>
<h2 class="wi-steam__name" th:if="${profile.summary != null}" th:text="${profile.summary?.personaName}"></h2>
<span class="wi-steam__status-text" th:if="${!#strings.isEmpty(profile.statusText)}" th:text="${profile.statusText}"></span>
<a
class="wi-steam__profile-link"
th:if="${!#strings.isEmpty(profile.summary?.profileUrl)}"
th:if="${profile.summary != null and !#strings.isEmpty(profile.summary?.profileUrl)}"
th:href="${profile.summary?.profileUrl}"
target="_blank"
rel="noopener noreferrer"
@@ -57,19 +65,19 @@ import Layout from "../layouts/Layout.astro";
<div class="wi-steam__stats" th:if="${stats != null}">
<div class="wi-steam__stat-card">
<span class="wi-steam__stat-value" th:text="${stats.totalGames}"></span>
<span class="wi-steam__stat-value" th:text="${stats.totalGames} ?: 0">0</span>
<span class="wi-steam__stat-label">拥有游戏</span>
</div>
<div class="wi-steam__stat-card">
<span class="wi-steam__stat-value" th:text="${stats.totalPlaytimeFormatted}"></span>
<span class="wi-steam__stat-value" th:text="${stats.totalPlaytimeFormatted} ?: '0 小时'">0 小时</span>
<span class="wi-steam__stat-label">总游玩时长</span>
</div>
<div class="wi-steam__stat-card">
<span class="wi-steam__stat-value" th:text="${stats.recentPlaytimeFormatted}"></span>
<span class="wi-steam__stat-value" th:text="${stats.recentPlaytimeFormatted} ?: '0 小时'">0 小时</span>
<span class="wi-steam__stat-label">近两周</span>
</div>
<div class="wi-steam__stat-card" th:if="${badges != null}">
<span class="wi-steam__stat-value" th:text="${badges.totalBadges}"></span>
<div class="wi-steam__stat-card">
<span class="wi-steam__stat-value" th:text="${badges != null and badges.totalBadges != null ? badges.totalBadges : 0}">0</span>
<span class="wi-steam__stat-label">徽章</span>
</div>
</div>
@@ -99,7 +107,7 @@ import Layout from "../layouts/Layout.astro";
<div class="wi-steam__recent-body">
<h4 class="wi-steam__recent-name" th:text="${game.name}"></h4>
<div class="wi-steam__recent-meta">
<span class="wi-steam__recent-time" th:text="${game.playtime2WeeksFormatted}"></span>
<span class="wi-steam__recent-time" th:text="${game.playtime2WeeksFormatted} ?: '0 小时'"></span>
<span
class="wi-steam__recent-achievements"
th:if="${game.achievementProgressText != null}"
@@ -138,7 +146,7 @@ import Layout from "../layouts/Layout.astro";
<div class="wi-steam__game-body">
<h4 class="wi-steam__game-name" th:text="${game.name}"></h4>
<div class="wi-steam__game-meta">
<span class="wi-steam__game-time" th:text="${game.playtimeFormatted}"></span>
<span class="wi-steam__game-time" th:text="${game.playtimeFormatted} ?: '0 小时'"></span>
<span
class="wi-steam__game-last"
th:if="${!#strings.isEmpty(game.lastPlayedFormatted)}"
@@ -216,6 +224,19 @@ import Layout from "../layouts/Layout.astro";
border-radius: 50%;
object-fit: cover;
border: 3px solid var(--rule);
display: block;
}
.wi-steam__avatar-placeholder {
display: flex;
align-items: center;
justify-content: center;
width: 80px;
height: 80px;
border-radius: 50%;
background: var(--accent-bg);
border: 3px solid var(--rule);
color: var(--ink-3);
}
.wi-steam__status-dot {
@@ -340,6 +361,7 @@ import Layout from "../layouts/Layout.astro";
font-size: var(--text-xs);
color: var(--ink-3);
margin-top: 4px;
white-space: nowrap;
}
.wi-steam__section {
@@ -450,7 +472,7 @@ import Layout from "../layouts/Layout.astro";
.wi-steam__games-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-template-columns: repeat(4, 1fr);
gap: var(--space-md);
}
@@ -499,6 +521,7 @@ import Layout from "../layouts/Layout.astro";
display: flex;
flex-direction: column;
gap: 4px;
min-height: 72px;
}
.wi-steam__game-name {
@@ -513,13 +536,26 @@ import Layout from "../layouts/Layout.astro";
.wi-steam__game-meta {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
font-size: var(--text-xs);
color: var(--ink-3);
flex-wrap: wrap;
}
.wi-steam__game-time {
color: var(--accent);
font-weight: 500;
white-space: nowrap;
flex-shrink: 0;
}
.wi-steam__game-last {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
min-width: 0;
}
.wi-steam__pagination {
@@ -552,10 +588,20 @@ import Layout from "../layouts/Layout.astro";
flex: 1;
}
@media (max-width: 1200px) {
.wi-steam__games-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 1024px) {
.wi-steam__stats {
grid-template-columns: repeat(2, 1fr);
}
.wi-steam__games-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
@@ -565,7 +611,8 @@ import Layout from "../layouts/Layout.astro";
padding: var(--space-lg);
}
.wi-steam__avatar-img {
.wi-steam__avatar-img,
.wi-steam__avatar-placeholder {
width: 64px;
height: 64px;
}
@@ -584,7 +631,7 @@ import Layout from "../layouts/Layout.astro";
}
.wi-steam__games-grid {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-template-columns: repeat(2, 1fr);
gap: var(--space-sm);
}
@@ -598,6 +645,9 @@ import Layout from "../layouts/Layout.astro";
.wi-steam__game-meta {
font-size: 10px;
flex-direction: column;
align-items: flex-start;
gap: 2px;
}
.wi-steam__recent-card {
+14
View File
@@ -20,6 +20,7 @@ import Layout from "../layouts/Layout.astro";
class="wi-tags__pill"
role="listitem"
th:href="@{${tag.status.permalink}}"
th:style="${tag.postCount > 10 ? 'font-size:1.25em' : (tag.postCount > 5 ? 'font-size:1.1em' : '')}"
>
<span class="wi-tags__pill-name" th:text="${tag.spec.displayName}"></span>
<span class="wi-tags__pill-count" th:text="${tag.postCount}"></span>
@@ -66,6 +67,8 @@ import Layout from "../layouts/Layout.astro";
display: flex;
flex-wrap: wrap;
gap: var(--space-sm);
justify-content: center;
padding: var(--space-lg) 0;
}
.wi-tags__pill {
@@ -116,4 +119,15 @@ import Layout from "../layouts/Layout.astro";
background: rgba(255, 255, 255, 0.2);
color: var(--bg);
}
@media (max-width: 640px) {
.wi-tags__cloud {
gap: 8px;
}
.wi-tags__pill {
padding: 0.4rem 0.8rem;
font-size: var(--text-xs);
}
}
</style>