@@ -5,6 +5,9 @@ import I18nKey from "@i18n/i18nKey";
55import { i18n } from " @i18n/translation" ;
66import { formatDateToYYYYMMDD } from " @utils/date-utils" ;
77import { Icon } from " astro-icon/components" ;
8+ import NoteImageWrapper from " @components/misc/NoteImageWrapper.astro" ;
9+ import path from " node:path" ;
10+ import { getDir } from " @utils/url-utils" ;
811
912interface Props {
1013 class? : string ;
@@ -17,6 +20,11 @@ const className = Astro.props.class;
1720
1821const noteTitle = entry .data .title ?.trim () || i18n (I18nKey .untitled );
1922
23+ const images: string [] = entry .data .images ?? [];
24+ const tags: string [] = entry .data .tags ?? [];
25+ const mood: string = entry .data .mood ?? " " ;
26+ const location: string = entry .data .location ?? " " ;
27+
2028const { Content } = await entry .render ();
2129---
2230
@@ -35,11 +43,22 @@ const { Content } = await entry.render();
3543 </span >
3644 <span class =" note-card__heading" >{ noteTitle } </span >
3745 { entry .data .pinned && (
38- <span class = " note-pin-badge" >
39- <Icon name = " material-symbols:push-pin" class = " note-pin-badge__icon " />
46+ <span class = " note-pin-badge inline-flex items-center gap-1 px-2.5 py-1 rounded-full bg-[color-mix(in_srgb,var(--primary)_15%,transparent)] text-xs text-[var(--primary)] font-bold tracking-wider uppercase " >
47+ <Icon name = " material-symbols:push-pin" class = " text-[0.85rem] " />
4048 <span >{ i18n (I18nKey .pinned )} </span >
4149 </span >
4250 )}
51+ { mood && (
52+ <span class = " inline-flex items-center gap-1 px-2.5 py-1 rounded-lg bg-[color-mix(in_srgb,var(--primary)_12%,transparent)] text-sm text-[var(--primary)] font-medium" >
53+ { mood }
54+ </span >
55+ )}
56+ { location && (
57+ <span class = " inline-flex items-center gap-1 text-sm text-black/50 dark:text-white/50" >
58+ <Icon name = " material-symbols:location-on-outline" class = " text-[1rem]" />
59+ { location }
60+ </span >
61+ )}
4362 </div >
4463 <div class =" note-card__meta" >
4564 <span class =" note-card__meta-item" >
@@ -62,6 +81,40 @@ const { Content } = await entry.render();
6281 <Markdown class =" text-sm md:text-base" >
6382 <Content />
6483 </Markdown >
84+
85+ { /* 图片网格 */ }
86+ { images .length > 0 && (
87+ <div class :list = { [
88+ " note-images mt-4" ,
89+ images .length === 1 && " note-images--single" ,
90+ images .length === 2 && " note-images--double" ,
91+ images .length === 3 && " note-images--triple" ,
92+ images .length >= 4 && " note-images--grid" ,
93+ ]} >
94+ { images .map ((src , imgIndex ) => (
95+ <a href = { src .startsWith (' http' ) ? src : undefined } data-fancybox = { ` note-card-${entry .slug }-${imgIndex } ` } class = " note-img-wrap block w-full h-full" >
96+ <NoteImageWrapper
97+ src = { src }
98+ basePath = { path .join (" content/notes/" , getDir (entry .id ))}
99+ class = " note-img w-full h-full object-cover transition-transform duration-300 hover:scale-105"
100+ />
101+ </a >
102+ ))}
103+ </div >
104+ )}
105+
106+ { /* 标签网格 */ }
107+ { tags .length > 0 && (
108+ <div class = " note-tags-container mt-4" >
109+ <div class = " flex flex-wrap gap-2" >
110+ { tags .map ((tag : string ) => (
111+ <span class = " btn-regular h-7 text-sm px-3 rounded-lg flex items-center justify-center font-medium" >
112+ #{ tag }
113+ </span >
114+ ))}
115+ </div >
116+ </div >
117+ )}
65118 </div >
66119 </div >
67120 </div >
@@ -192,21 +245,35 @@ const { Content } = await entry.render();
192245}
193246
194247.note-pin-badge {
195- display: inline-flex;
196- align-items: center;
197- gap: 0.25rem;
198- background: color-mix(in srgb, var(--primary) 15%, transparent);
199- color: var(--primary);
200- font-size: 0.625rem;
201- font-weight: 600;
202- padding: 0.15rem 0.5rem;
203- border-radius: 9999px;
204- text-transform: uppercase;
205- letter-spacing: 0.05em;
206- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 35%, transparent);
248+ /* Styles are handled by Tailwind classes in the component */
207249}
208250
251+
209252.note-pin-badge__icon {
210253 font-size: 0.85rem;
211254}
255+
256+ /* 图片网格 */
257+ .note-images { display: grid; gap: 0.5rem; }
258+ .note-images--single { grid-template-columns: 1fr; max-width: 400px; }
259+ .note-images--double { grid-template-columns: repeat(2, 1fr); max-width: 500px; }
260+ .note-images--triple { grid-template-columns: repeat(2, 1fr); max-width: 500px; }
261+ .note-images--triple .note-img-wrap:first-child { grid-row: span 2; }
262+ .note-images--grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); max-width: 600px; }
263+ @media (min-width: 768px) {
264+ .note-images--single { max-width: 500px; }
265+ .note-images--double { max-width: 560px; }
266+ .note-images--grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); max-width: 700px; }
267+ }
268+ @media (max-width: 480px) {
269+ .note-images--triple .note-img-wrap:first-child { grid-row: span 1; }
270+ }
271+ .note-img-wrap {
272+ display: block;
273+ aspect-ratio: 1;
274+ border-radius: 0.5rem;
275+ overflow: hidden;
276+ background: color-mix(in srgb, var(--foreground, currentColor) 4%, transparent);
277+ }
278+ .note-img { width: 100%; height: 100%; object-fit: cover; }
212279</style >
0 commit comments