@xingwangzhe/stalux 1.35.1 → 1.35.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/package.json +23 -23
- package/src/components/stalux/archives/archivesList.astro +58 -50
- package/src/components/stalux/categories/categoriesList.astro +4 -4
- package/src/components/stalux/layout/footer.astro +8 -4
- package/src/components/stalux/layout/head.astro +3 -3
- package/src/components/stalux/layout/navs.astro +15 -15
- package/src/components/stalux/links/linkList.astro +4 -4
- package/src/components/stalux/links/socialMedia.astro +35 -35
- package/src/components/stalux/posts/PostTaxonomy.astro +14 -10
- package/src/components/stalux/posts/postCC.astro +7 -7
- package/src/components/stalux/posts/postCard.astro +47 -41
- package/src/components/stalux/posts/postContent.astro +49 -49
- package/src/components/stalux/posts/postList.astro +4 -4
- package/src/components/stalux/posts/postToc.astro +16 -16
- package/src/components/stalux/tags/tagsCloud.astro +20 -20
- package/src/components/stalux/words/wordCard.astro +28 -28
- package/src/components/stalux/words/wordList.astro +17 -17
- package/src/index.ts +98 -20
- package/src/internal/font-slices.ts +56 -6
- package/src/internal/html-images.ts +23 -2
- package/src/internal/image-dimensions.ts +60 -33
- package/src/internal/page-output-cache.ts +78 -0
- package/src/layouts/PostLayout.astro +9 -7
- package/src/layouts/Stalux.astro +4 -4
- package/src/pages/about.astro +6 -6
- package/src/pages/categories/[category].astro +4 -4
- package/src/pages/tags/[tag].astro +5 -1
- package/src/plugins/feature-flags.ts +5 -17
package/README.md
CHANGED
|
@@ -116,6 +116,10 @@ The subset CSS uses an exact per-character `unicode-range` and `font-display: sw
|
|
|
116
116
|
|
|
117
117
|
The persistent BLAKE3 cache key includes font bytes, face index, normalized character set, and algorithm version. Cache files live under `node_modules/.astro/` and are reused across pages and incremental builds. Font inputs are read locally; builds do not fetch fonts from the network.
|
|
118
118
|
|
|
119
|
+
Multi-page builds reuse prepared font data and hashing state through `FontSubsetter`, with up to four native worker tasks for cold subsets. Font containers are decoded/extracted to SFNT before reusable HarfBuzz preprocessing preserves original outlines; Google Brotli encodes WOFF2 at quality 8. Image dimensions, image loading hints, linked CSS text, and font character extraction share one HTML parse. Shared image dimensions and CSS-generated text are also reused within each build, and image-tag edits are assembled in a single pass.
|
|
120
|
+
|
|
121
|
+
Processed pages are cached under `node_modules/.astro/stalux-page-output/`. The cache checks source HTML and page paths, referenced local CSS/image content, font inputs, and processing code. Changed inputs, missing font files, and corrupt records trigger reprocessing. Unchanged pages restore their processed output; Pagefind still rebuilds the full search index on every build. Preserve `node_modules/.astro/` to reuse caches across builds; removing it safely rebuilds them.
|
|
122
|
+
|
|
119
123
|
### Visibility-aware loading and updates
|
|
120
124
|
|
|
121
125
|
The desktop tag cloud loads dynamically near the viewport. Switching to mobile, leaving the viewport or hiding the document destroys it and stops animation scheduling; becoming visible recreates it. Tag clicks use Astro client navigation. Clocks and the footer runtime update only while visible, and the date changes only on a new day. Comments load within half a viewport (capped at 400px). Tag groups, archive months and category cards retain static HTML while deferring offscreen rendering.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xingwangzhe/stalux",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.3",
|
|
4
4
|
"description": "A powerful, modern Astro blog theme — use as template or install as plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -95,47 +95,47 @@
|
|
|
95
95
|
"styles:watch": "node scripts/build-styles.ts --watch"
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@astrojs/compiler": "
|
|
99
|
-
"@astrojs/markdown-satteri": "0.4.
|
|
100
|
-
"@astrojs/partytown": "2.1.8",
|
|
98
|
+
"@astrojs/compiler": "^4.0.0",
|
|
99
|
+
"@astrojs/markdown-satteri": "^0.4.3",
|
|
100
|
+
"@astrojs/partytown": "^2.1.8",
|
|
101
101
|
"@astrojs/rss": "^4.0.19",
|
|
102
102
|
"@astrojs/sitemap": "^3.7.4",
|
|
103
|
-
"@babel/parser": "
|
|
103
|
+
"@babel/parser": "^8.0.6",
|
|
104
104
|
"@expressive-code/plugin-line-numbers": "^0.44.2",
|
|
105
|
-
"@lucide/astro": "^1.
|
|
105
|
+
"@lucide/astro": "^1.52.0",
|
|
106
106
|
"@mcp-b/webmcp-polyfill": "^5.1.0",
|
|
107
107
|
"@pagefind/component-ui": "^1.5.2",
|
|
108
|
-
"@waline/client": "3.16.0",
|
|
109
|
-
"@xingwangzhe/cjk-font-split-native": "0.2
|
|
110
|
-
"@xingwangzhe/satteri-mermaid": "0.8.1",
|
|
111
|
-
"@xingwangzhe/satteri-photoswipe": "^0.2.
|
|
112
|
-
"@xingwangzhe/tags-cloud": "^1.2.
|
|
108
|
+
"@waline/client": "^3.16.0",
|
|
109
|
+
"@xingwangzhe/cjk-font-split-native": "^0.4.2",
|
|
110
|
+
"@xingwangzhe/satteri-mermaid": "^0.8.1",
|
|
111
|
+
"@xingwangzhe/satteri-photoswipe": "^0.2.6",
|
|
112
|
+
"@xingwangzhe/tags-cloud": "^1.2.9",
|
|
113
113
|
"astro-expressive-code": "^0.44.2",
|
|
114
114
|
"astro-seo": "^1.2.0",
|
|
115
115
|
"badge-maker": "^6.0.0",
|
|
116
|
-
"css-tree": "3.2.1",
|
|
117
|
-
"magic-string": "
|
|
116
|
+
"css-tree": "^3.2.1",
|
|
117
|
+
"magic-string": "^1.4.3",
|
|
118
118
|
"pagefind": "^1.5.2",
|
|
119
|
-
"parse5": "8.0.1",
|
|
119
|
+
"parse5": "^8.0.1",
|
|
120
120
|
"photoswipe": "^5.4.4",
|
|
121
121
|
"satteri": "^0.10.5",
|
|
122
|
-
"simple-icons": "^16.
|
|
122
|
+
"simple-icons": "^16.34.0",
|
|
123
123
|
"temml": "^0.13.5",
|
|
124
124
|
"yaml": "^2.9.1"
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
127
|
-
"@astrojs/check": "0.9.10",
|
|
128
|
-
"@biomejs/biome": "2.5.
|
|
127
|
+
"@astrojs/check": "^0.9.10",
|
|
128
|
+
"@biomejs/biome": "^2.5.15",
|
|
129
129
|
"@types/css-tree": "^3.2.0",
|
|
130
|
-
"@types/node": "^26.6.
|
|
130
|
+
"@types/node": "^26.6.4",
|
|
131
131
|
"@unocss/astro": "^66.10.5",
|
|
132
|
-
"@vitest/coverage-v8": "5.0.
|
|
133
|
-
"astro": "^7.3.
|
|
134
|
-
"knip": "^6.
|
|
132
|
+
"@vitest/coverage-v8": "^5.0.3",
|
|
133
|
+
"astro": "^7.3.6",
|
|
134
|
+
"knip": "^6.40.0",
|
|
135
135
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
136
136
|
"unocss": "^66.10.5",
|
|
137
|
-
"vite": "8.3.
|
|
138
|
-
"vitest": "5.0.
|
|
137
|
+
"vite": "^8.3.3",
|
|
138
|
+
"vitest": "^5.0.3"
|
|
139
139
|
},
|
|
140
140
|
"peerDependencies": {
|
|
141
141
|
"astro": "^7.3.5"
|
|
@@ -57,57 +57,65 @@ const archiveYears = [...archivesByYearMonth.entries()]
|
|
|
57
57
|
<div class="stalux-archive-page-header">
|
|
58
58
|
<div class="stalux-archive-timeline-container">
|
|
59
59
|
{archiveYears.length > 0 ? (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
datetime={post.data.date}
|
|
60
|
+
archiveYears.map((archiveYear) => (
|
|
61
|
+
<div class="stalux-archive-year-section" data-year={String(archiveYear.year)}>
|
|
62
|
+
<div class="stalux-archive-year-header">
|
|
63
|
+
<h2 class="stalux-archive-year-title">{archiveYear.year}</h2>
|
|
64
|
+
<div class="stalux-archive-year-count">
|
|
65
|
+
{t("archives.postCount", { n: archiveYear.count })}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
{archiveYear.months.map(({ month, posts: monthPosts }) => (
|
|
69
|
+
<div
|
|
70
|
+
class="stalux-archive-month-section"
|
|
71
|
+
data-archive-month
|
|
72
|
+
style={{
|
|
73
|
+
"--archive-estimate": `${Math.ceil(monthPosts.length / 12) * 12 * 48 + 40}px`,
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
<h3 class="stalux-archive-month-title">
|
|
77
|
+
{t("archives.month", { n: month })}
|
|
78
|
+
</h3>
|
|
79
|
+
{Array.from(
|
|
80
|
+
{ length: Math.ceil(monthPosts.length / 12) },
|
|
81
|
+
(_, index) => monthPosts.slice(index * 12, (index + 1) * 12),
|
|
82
|
+
).map((group) => (
|
|
83
|
+
<ul
|
|
84
|
+
class="stalux-archive-post-list"
|
|
85
|
+
style={{
|
|
86
|
+
"--archive-group-estimate": `${group.length * 48}px`,
|
|
87
|
+
}}
|
|
89
88
|
>
|
|
90
|
-
{
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
)}
|
|
89
|
+
{group.map((post) => (
|
|
90
|
+
<li class="stalux-archive-post-item">
|
|
91
|
+
<time
|
|
92
|
+
class="stalux-archive-post-date"
|
|
93
|
+
datetime={post.data.date}
|
|
94
|
+
>
|
|
95
|
+
{format(
|
|
96
|
+
parseDate(post.data.date),
|
|
97
|
+
"yyyy-MM-dd",
|
|
98
|
+
)}
|
|
99
|
+
</time>
|
|
100
|
+
<a
|
|
101
|
+
href={`/posts/${post.data.abbrlink}/`}
|
|
102
|
+
class="stalux-archive-post-link"
|
|
103
|
+
data-archive-description={post.data.desc || ""}
|
|
104
|
+
data-astro-prefetch="viewport"
|
|
105
|
+
>
|
|
106
|
+
{post.data.title}
|
|
107
|
+
</a>
|
|
108
|
+
</li>
|
|
109
|
+
))}
|
|
110
|
+
</ul>
|
|
111
|
+
))}
|
|
112
|
+
</div>
|
|
113
|
+
))}
|
|
114
|
+
</div>
|
|
115
|
+
))
|
|
116
|
+
) : (
|
|
117
|
+
<div class="stalux-archive-no-posts">{t("archives.noPosts")}</div>
|
|
118
|
+
)}
|
|
111
119
|
</div>
|
|
112
120
|
|
|
113
121
|
<slot name="main" />
|
|
@@ -9,8 +9,8 @@ const categoryList = await getCategoryCountList(Astro.logger);
|
|
|
9
9
|
|
|
10
10
|
<ul class="stalux-categories">
|
|
11
11
|
{categoryList.map((category) => (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
))}
|
|
12
|
+
<li>
|
|
13
|
+
<CategoriesCard category={category} />
|
|
14
|
+
</li>
|
|
15
|
+
))}
|
|
16
16
|
</ul>
|
|
@@ -55,8 +55,8 @@ const formattedWordCount = formatWordCount(totalWordCount, siteConfig.lang || "z
|
|
|
55
55
|
<div class="stalux-footer-content stalux-u-flex stalux-u-flex-col">
|
|
56
56
|
<!-- 版权信息 -->
|
|
57
57
|
{footerConfig?.copyright?.enabled && (
|
|
58
|
-
|
|
59
|
-
)}
|
|
58
|
+
<FooterCopyright author={author} startYear={footerConfig?.copyright?.startYear} />
|
|
59
|
+
)}
|
|
60
60
|
|
|
61
61
|
<!-- 徽章展示 -->
|
|
62
62
|
<FooterBadges badges={badges} />
|
|
@@ -64,8 +64,12 @@ const formattedWordCount = formatWordCount(totalWordCount, siteConfig.lang || "z
|
|
|
64
64
|
<!-- 备案信息 -->
|
|
65
65
|
<FooterBeian
|
|
66
66
|
icp={footerConfig?.beian?.icp?.enabled ? footerConfig?.beian?.icp?.number : undefined}
|
|
67
|
-
pubsec={footerConfig?.beian?.security?.enabled
|
|
68
|
-
|
|
67
|
+
pubsec={footerConfig?.beian?.security?.enabled
|
|
68
|
+
? footerConfig?.beian?.security?.text
|
|
69
|
+
: undefined}
|
|
70
|
+
pubsecNumber={footerConfig?.beian?.security?.enabled
|
|
71
|
+
? footerConfig?.beian?.security?.number
|
|
72
|
+
: undefined}
|
|
69
73
|
/>
|
|
70
74
|
|
|
71
75
|
<!-- 主题信息 -->
|
|
@@ -52,9 +52,9 @@ const ldJson = JSON.stringify(seo.schema).replace(/<\//g, "<\\/");
|
|
|
52
52
|
openGraph={seo.openGraph}
|
|
53
53
|
twitter={seo.twitter}
|
|
54
54
|
extend={{
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}}
|
|
55
|
+
link: seo.links,
|
|
56
|
+
meta: seo.meta,
|
|
57
|
+
}}
|
|
58
58
|
/>
|
|
59
59
|
<!-- 代码字体由 Astro Fonts API 注入;正文按页面生成 native CJK 子集。 -->
|
|
60
60
|
<Font cssVariable="--font-code" />
|
|
@@ -48,21 +48,21 @@ const navs = navsConfig?.items ?? [];
|
|
|
48
48
|
class="stalux-nav-list stalux-u-flex stalux-u-items-center stalux-u-justify-center stalux-u-flex-wrap stalux-u-w-full stalux-u-min-w-0"
|
|
49
49
|
>
|
|
50
50
|
{navs.map((item) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
})}
|
|
51
|
+
const NavIcon = item.icon ? getLucideIcon(item.icon, Astro.logger) : null;
|
|
52
|
+
return (
|
|
53
|
+
<li class="stalux-nav-item stalux-u-flex stalux-u-items-center">
|
|
54
|
+
<a
|
|
55
|
+
href={item.link}
|
|
56
|
+
class="stalux-nav-link"
|
|
57
|
+
data-ref="stalux-nav-link"
|
|
58
|
+
data-astro-prefetch
|
|
59
|
+
>
|
|
60
|
+
{NavIcon && <NavIcon size={20} stroke-width={2} class="nav-icon" />}
|
|
61
|
+
<span class="stalux-nav-text">{item.title}</span>
|
|
62
|
+
</a>
|
|
63
|
+
</li>
|
|
64
|
+
);
|
|
65
|
+
})}
|
|
66
66
|
<li class="stalux-nav-item stalux-u-flex stalux-u-items-center">
|
|
67
67
|
<a
|
|
68
68
|
href="#search"
|
|
@@ -12,8 +12,8 @@ const links = linksConfig?.sites ?? [];
|
|
|
12
12
|
|
|
13
13
|
<ul class="stalux-links">
|
|
14
14
|
{links.map((link) => (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
))}
|
|
15
|
+
<li class="stalux-link-list-item">
|
|
16
|
+
<LinkCard link={link} />
|
|
17
|
+
</li>
|
|
18
|
+
))}
|
|
19
19
|
</ul>
|
|
@@ -42,40 +42,40 @@ function getIconByTitle(iconName: string): SimpleIcon | undefined {
|
|
|
42
42
|
>
|
|
43
43
|
<ul>
|
|
44
44
|
{mediaLinks.map((item) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})}
|
|
45
|
+
const icon = item.icon ? getIconByTitle(item.icon) : undefined;
|
|
46
|
+
return (
|
|
47
|
+
<li class="social_icon">
|
|
48
|
+
<a
|
|
49
|
+
href={item.link}
|
|
50
|
+
target="_blank"
|
|
51
|
+
aria-label={item.icon}
|
|
52
|
+
rel="noopener noreferrer"
|
|
53
|
+
title={item.icon}
|
|
54
|
+
class="a-none"
|
|
55
|
+
>
|
|
56
|
+
{icon ? (
|
|
57
|
+
<div class="icon-container">
|
|
58
|
+
<svg
|
|
59
|
+
role="img"
|
|
60
|
+
viewBox="0 0 24 24"
|
|
61
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
62
|
+
width="24"
|
|
63
|
+
height="24"
|
|
64
|
+
fill="currentColor"
|
|
65
|
+
aria-hidden="true"
|
|
66
|
+
>
|
|
67
|
+
<title>{icon.title}</title>
|
|
68
|
+
<path d={icon.path} />
|
|
69
|
+
</svg>
|
|
70
|
+
</div>
|
|
71
|
+
) : (
|
|
72
|
+
<span class="custom-icon">
|
|
73
|
+
{item.icon ? item.icon.charAt(0).toUpperCase() : ""}
|
|
74
|
+
</span>
|
|
75
|
+
)}
|
|
76
|
+
</a>
|
|
77
|
+
</li>
|
|
78
|
+
);
|
|
79
|
+
})}
|
|
80
80
|
</ul>
|
|
81
81
|
</nav>
|
|
@@ -50,14 +50,18 @@ const cfg = {
|
|
|
50
50
|
>
|
|
51
51
|
{items.length > 0 && <h3 class="stalux-post-taxonomy-title">{title ?? cfg.heading}</h3>}
|
|
52
52
|
{items.length > 0 ? (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)}
|
|
53
|
+
<div class={cfg.listClass} transition:name={cfg.contentName}>
|
|
54
|
+
{items.map((item) => (
|
|
55
|
+
<a
|
|
56
|
+
href={`${cfg.prefix}${item}/`}
|
|
57
|
+
class={`${cfg.itemClass} a-none`}
|
|
58
|
+
data-astro-prefetch
|
|
59
|
+
>
|
|
60
|
+
{item}
|
|
61
|
+
</a>
|
|
62
|
+
))}
|
|
63
|
+
</div>
|
|
64
|
+
) : (
|
|
65
|
+
<div class="stalux-post-taxonomy-empty">{cfg.empty}</div>
|
|
66
|
+
)}
|
|
63
67
|
</nav>
|
|
@@ -30,13 +30,13 @@ const licenseName = buildCCName(cc, t);
|
|
|
30
30
|
<p class="stalux-license-title">{title}</p>
|
|
31
31
|
<p class="stalux-license-author">{t("post.author")}{author}</p>
|
|
32
32
|
{url && (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)}
|
|
33
|
+
<p class="stalux-license-url">
|
|
34
|
+
{t("post.articleLink")}
|
|
35
|
+
<a href={url} target="_blank" rel="noopener noreferrer">
|
|
36
|
+
{url}
|
|
37
|
+
</a>
|
|
38
|
+
</p>
|
|
39
|
+
)}
|
|
40
40
|
<p class="stalux-license-license">
|
|
41
41
|
{t("post.licensedUnder")}
|
|
42
42
|
<a href={licenseLink} target="_blank" rel="noopener noreferrer">
|
|
@@ -23,25 +23,25 @@ const description = post.data.desc || "";
|
|
|
23
23
|
<article class="stalux-post-card-shell block h-full text-inherit no-underline">
|
|
24
24
|
<div class="stalux-post-card stalux-u-flex stalux-u-flex-col stalux-u-w-full stalux-u-min-w-0">
|
|
25
25
|
{post.data.cover && (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)}
|
|
26
|
+
<a
|
|
27
|
+
href={`/posts/${post.data.abbrlink}/`}
|
|
28
|
+
class="a-none"
|
|
29
|
+
data-astro-prefetch="viewport"
|
|
30
|
+
aria-label={post.data.title}
|
|
31
|
+
>
|
|
32
|
+
<div class="stalux-card-post-cover stalux-u-w-full stalux-u-min-w-0">
|
|
33
|
+
<img
|
|
34
|
+
src={post.data.cover}
|
|
35
|
+
alt={post.data.title}
|
|
36
|
+
loading={priority ? "eager" : "lazy"}
|
|
37
|
+
decoding="async"
|
|
38
|
+
fetchpriority={priority ? "high" : "auto"}
|
|
39
|
+
width="640"
|
|
40
|
+
height="360"
|
|
41
|
+
/>
|
|
42
|
+
</div>
|
|
43
|
+
</a>
|
|
44
|
+
)}
|
|
45
45
|
<h2
|
|
46
46
|
class="stalux-card-post-title"
|
|
47
47
|
transition:name={priority ? getPostTitleTransitionName(post.data.abbrlink) : undefined}
|
|
@@ -52,21 +52,27 @@ const description = post.data.desc || "";
|
|
|
52
52
|
</h2>
|
|
53
53
|
<div class="stalux-card-time stalux-u-items-center stalux-u-flex-wrap">
|
|
54
54
|
{post.data.date && (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
<time
|
|
56
|
+
class="stalux-card-post-date"
|
|
57
|
+
datetime={
|
|
58
|
+
timezone ? toMachineDateTime(post.data.date, timezone) : post.data.date
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
{post.data.date}
|
|
62
|
+
</time>
|
|
63
|
+
)}
|
|
62
64
|
{post.data.updated && (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
<time
|
|
66
|
+
class="stalux-card-post-updated"
|
|
67
|
+
datetime={
|
|
68
|
+
timezone
|
|
69
|
+
? toMachineDateTime(post.data.updated, timezone)
|
|
70
|
+
: post.data.updated
|
|
71
|
+
}
|
|
72
|
+
>
|
|
73
|
+
{post.data.updated}
|
|
74
|
+
</time>
|
|
75
|
+
)}
|
|
70
76
|
</div>
|
|
71
77
|
<div class="stalux-card-post-description stalux-u-min-w-0">{description}</div>
|
|
72
78
|
<div class="stalux-card-post-meta stalux-u-flex stalux-u-flex-col">
|
|
@@ -74,19 +80,19 @@ const description = post.data.desc || "";
|
|
|
74
80
|
class="stalux-card-post-tags stalux-u-flex stalux-u-items-center stalux-u-flex-wrap"
|
|
75
81
|
>
|
|
76
82
|
{post.data.tags?.map((tag) => (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
))}
|
|
83
|
+
<a class="a-none" href={`/tags/${tag}`} data-astro-prefetch>
|
|
84
|
+
<span class="stalux-card-post-tag">{tag}</span>
|
|
85
|
+
</a>
|
|
86
|
+
))}
|
|
81
87
|
</div>
|
|
82
88
|
<div
|
|
83
89
|
class="stalux-card-post-categories stalux-u-flex stalux-u-items-center stalux-u-flex-wrap"
|
|
84
90
|
>
|
|
85
91
|
{post.data.categories?.map((category) => (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
))}
|
|
92
|
+
<a class="a-none" href={`/categories/${category}`} data-astro-prefetch>
|
|
93
|
+
<span class="stalux-card-post-category">{category}</span>
|
|
94
|
+
</a>
|
|
95
|
+
))}
|
|
90
96
|
</div>
|
|
91
97
|
</div>
|
|
92
98
|
<a
|