fix(archives): 置顶文章不再把整月拽到顶部——置顶浮出分组流自成首节
用户实测:某月有一篇置顶时,该月全部文章跟着上浮。根因:sortPosts 置顶优先后,年/月分组按顺次建桶——置顶文章让所在月提前建桶到顶部。 修复:置顶文章单独渲染为分组流之前的一节(带徽标与计数),年/月分组 只对非置顶文章按自然时序建桶,月份各归各位。 验证: pnpm astro build exit 0;产物断言分组头顺序=置顶,2026-11,2026-04,2026-03,2026-02 且置顶文仅出现一次;E2E 61/61 Spec: none (用户实测报告的排序分组 bug 紧急修复) Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
3ec7e48727
commit
9b11070dd4
1 file changed
+66
-1
@@ -33,8 +33,13 @@ const TRACK_LABEL: Record<PostCategory, string> = {
|
|||||||
};
|
};
|
||||||
const hrefOf = (id: string) => (locale === 'en' ? `/en/archives/${id}/` : `/archives/${id}/`);
|
const hrefOf = (id: string) => (locale === 'en' ? `/en/archives/${id}/` : `/archives/${id}/`);
|
||||||
|
|
||||||
|
// 置顶浮出分组流(2026-11-05 用户实测修复):置顶文章若留在分组流里,
|
||||||
|
// 它所在月会因「顺次建桶」被提前建到顶部,整月文章跟着上浮——
|
||||||
|
// 所以置顶单独一节渲染在年/月分组之前,分组只对非置顶文章按自然时序建桶。
|
||||||
|
const pinned = visible.filter((p) => p.data.pinned);
|
||||||
|
const flow = visible.filter((p) => !p.data.pinned);
|
||||||
const byYear = new Map<number, CollectionEntry<'posts'>[]>();
|
const byYear = new Map<number, CollectionEntry<'posts'>[]>();
|
||||||
for (const post of visible) {
|
for (const post of flow) {
|
||||||
const year = post.data.pubDate.getUTCFullYear();
|
const year = post.data.pubDate.getUTCFullYear();
|
||||||
const bucket = byYear.get(year);
|
const bucket = byYear.get(year);
|
||||||
if (bucket) bucket.push(post);
|
if (bucket) bucket.push(post);
|
||||||
@@ -107,6 +112,37 @@ const byMonth = (list: CollectionEntry<'posts'>[]) => {
|
|||||||
</div>
|
</div>
|
||||||
) : fold ? (
|
) : fold ? (
|
||||||
<div class="post-list post-list-fold">
|
<div class="post-list post-list-fold">
|
||||||
|
{pinned.length > 0 && (
|
||||||
|
<section class="month-block pinned-block">
|
||||||
|
<h3 class="month-head">
|
||||||
|
<span>{t('pinned_label', locale)}</span>
|
||||||
|
<span class="mono month-count">· {pinned.length} {units}</span>
|
||||||
|
</h3>
|
||||||
|
<ul>
|
||||||
|
{pinned.map((post) => (
|
||||||
|
<li>
|
||||||
|
<a class="row tap" href={hrefOf(post.id)}>
|
||||||
|
{post.data.category === 'reading' && (
|
||||||
|
<i
|
||||||
|
class="emo"
|
||||||
|
style={`background:${post.data.mood ?? 'var(--mood)'}`}
|
||||||
|
title="情绪色"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span class="row-title">{titleOverrides?.[post.id] ?? post.data.title}</span>
|
||||||
|
<span class="pin" title={t('pinned_label', locale)}>{t('pinned_label', locale)}</span>
|
||||||
|
{post.data.category !== 'reading' &&
|
||||||
|
post.data.tags.map((tag) => <code class="tag">{`#${tag}`}</code>)}
|
||||||
|
<time class="row-date" datetime={post.data.pubDate.toISOString()}>
|
||||||
|
{mmdd(post.data.pubDate)}
|
||||||
|
</time>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
{[...byYear.entries()].map(([year, list], i) => (
|
{[...byYear.entries()].map(([year, list], i) => (
|
||||||
<details class="year-fold" open={i === 0}>
|
<details class="year-fold" open={i === 0}>
|
||||||
<summary class="year-summary">
|
<summary class="year-summary">
|
||||||
@@ -153,6 +189,33 @@ const byMonth = (list: CollectionEntry<'posts'>[]) => {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class="post-list">
|
<div class="post-list">
|
||||||
|
{pinned.length > 0 && (
|
||||||
|
<section class="year-block pinned-block" aria-label={t('pinned_label', locale)}>
|
||||||
|
<h2 class="year">{t('pinned_label', locale)}</h2>
|
||||||
|
<ul>
|
||||||
|
{pinned.map((post) => (
|
||||||
|
<li>
|
||||||
|
<a class="row tap" href={hrefOf(post.id)}>
|
||||||
|
{post.data.category === 'reading' && (
|
||||||
|
<i
|
||||||
|
class="emo"
|
||||||
|
style={`background:${post.data.mood ?? 'var(--mood)'}`}
|
||||||
|
title="情绪色"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span class="row-title">{titleOverrides?.[post.id] ?? post.data.title}</span>
|
||||||
|
{post.data.category !== 'reading' &&
|
||||||
|
post.data.tags.map((tag) => <code class="tag">{`#${tag}`}</code>)}
|
||||||
|
<time class="row-date" datetime={post.data.pubDate.toISOString()}>
|
||||||
|
{mmdd(post.data.pubDate)}
|
||||||
|
</time>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
{[...byYear.entries()].map(([year, list]) => (
|
{[...byYear.entries()].map(([year, list]) => (
|
||||||
<section class="year-block" aria-label={`${year} 年文章`}>
|
<section class="year-block" aria-label={`${year} 年文章`}>
|
||||||
<h2 class="year">{year}</h2>
|
<h2 class="year">{year}</h2>
|
||||||
@@ -363,6 +426,8 @@ const byMonth = (list: CollectionEntry<'posts'>[]) => {
|
|||||||
.year-count { font-size: 12px; color: var(--ink-4); }
|
.year-count { font-size: 12px; color: var(--ink-4); }
|
||||||
.year-body { padding-bottom: var(--space-2); }
|
.year-body { padding-bottom: var(--space-2); }
|
||||||
.month-block + .month-block { margin-top: var(--space-3); }
|
.month-block + .month-block { margin-top: var(--space-3); }
|
||||||
|
/* 置顶节与第一个年折叠块之间的间隔 */
|
||||||
|
.pinned-block + .year-fold { margin-top: var(--space-4); }
|
||||||
.month-head {
|
.month-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
|||||||
Reference in new issue
Block a user