fix: stabilize desktop recommendation layouts

This commit is contained in:
TerryM
2026-05-28 17:31:32 +08:00
parent 5fec82dbba
commit 5036c930bb
3 changed files with 23 additions and 11 deletions

View File

@@ -16,8 +16,13 @@ function isPlaceholderAsset(path: string | undefined | null) {
return !path || path.includes("placeholder-cover"); return !path || path.includes("placeholder-cover");
} }
const CARD_CLASS = const CARD_BASE_CLASS =
"group flex w-[208px] shrink-0 flex-col overflow-hidden rounded-xl border bg-[#1D1E23] transition hover:border-ark-gold/55 md:w-[240px] lg:w-[246.4px] min-[1100px]:max-xl:w-[273px] xl:w-[246.4px]"; "group flex shrink-0 flex-col overflow-hidden rounded-xl border bg-[#1D1E23] transition hover:border-ark-gold/55";
const CARD_CAROUSEL_SIZE_CLASS =
"w-[208px] md:w-[240px] lg:w-[246.4px] min-[1100px]:max-xl:w-[273px] xl:w-[246.4px]";
const CARD_GRID_SIZE_CLASS = "w-full max-w-[360px] md:max-w-none";
type RecommendedResource = Resource & { type RecommendedResource = Resource & {
downloadPostId?: string; downloadPostId?: string;
@@ -28,10 +33,12 @@ export function RecommendedCard({
r, r,
visualIndex = 0, visualIndex = 0,
useFigmaDesign = false, useFigmaDesign = false,
layout = "carousel",
}: { }: {
r: RecommendedResource; r: RecommendedResource;
visualIndex?: number; visualIndex?: number;
useFigmaDesign?: boolean; useFigmaDesign?: boolean;
layout?: "carousel" | "grid";
}) { }) {
const { t } = useI18n(); const { t } = useI18n();
const [isDownloading, setIsDownloading] = useState(false); const [isDownloading, setIsDownloading] = useState(false);
@@ -78,7 +85,9 @@ export function RecommendedCard({
return ( return (
<article <article
className={`${CARD_CLASS} ${ className={`${CARD_BASE_CLASS} ${
layout === "grid" ? CARD_GRID_SIZE_CLASS : CARD_CAROUSEL_SIZE_CLASS
} ${
useFigmaDesign useFigmaDesign
? "border-[#27292E]" ? "border-[#27292E]"
: "border-transparent md:border-ark-line md:bg-ark-panel" : "border-transparent md:border-ark-line md:bg-ark-panel"
@@ -86,7 +95,7 @@ export function RecommendedCard({
> >
<Link <Link
to={`/resource/${r.id}`} to={`/resource/${r.id}`}
className="relative block h-[108px] overflow-hidden bg-[#111116] md:aspect-[246.4/138.6] md:h-auto" className="relative block aspect-[208/108] overflow-hidden bg-[#111116]"
> >
{cover ? ( {cover ? (
<img <img
@@ -202,7 +211,7 @@ export function ComingSoonRecommendedCard({
return ( return (
<article <article
className={`${CARD_CLASS} cursor-default border-transparent opacity-95 md:border-ark-line md:bg-ark-panel`} className={`${CARD_BASE_CLASS} ${CARD_CAROUSEL_SIZE_CLASS} cursor-default border-transparent opacity-95 md:border-ark-line md:bg-ark-panel`}
aria-label="即将到来" aria-label="即将到来"
> >
<div className="relative block h-[108px] overflow-hidden bg-black md:aspect-[246.4/138.6] md:h-auto"> <div className="relative block h-[108px] overflow-hidden bg-black md:aspect-[246.4/138.6] md:h-auto">

View File

@@ -69,7 +69,7 @@ export function Home() {
getJSON<{ items: Post[] }>(`/api/posts/recommended${postQ}&limit=12`), getJSON<{ items: Post[] }>(`/api/posts/recommended${postQ}&limit=12`),
getJSON<{ items: Post[] }>(`/api/posts${postQ}&sort=latest&limit=5`), getJSON<{ items: Post[] }>(`/api/posts${postQ}&sort=latest&limit=5`),
getJSON<{ items: Post[] }>( getJSON<{ items: Post[] }>(
`/api/posts${postQ}&sort=popular&limit=5`, `/api/posts${postQ}&tag=popular&limit=5`,
).catch((): { items: Post[] } => ({ items: [] })), ).catch((): { items: Post[] } => ({ items: [] })),
]) ])
.then(([c, r, l, p]) => { .then(([c, r, l, p]) => {
@@ -375,7 +375,7 @@ export function Home() {
<MessageBubble key={post.id} post={post} /> <MessageBubble key={post.id} post={post} />
))} ))}
</div> </div>
<div className="mt-7 hidden gap-3 min-[576px]:grid-cols-2 md:grid md:gap-4 lg:grid-cols-3 xl:grid-cols-5"> <div className="mt-7 hidden grid-cols-1 gap-3 min-[576px]:grid-cols-2 md:grid md:grid-cols-2 md:gap-4 lg:grid-cols-3 xl:grid-cols-5">
{latest.map((r) => ( {latest.map((r) => (
<LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} /> <LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} />
))} ))}
@@ -392,7 +392,7 @@ export function Home() {
<div className="px-4 md:px-0"> <div className="px-4 md:px-0">
<SectionHeader <SectionHeader
title={t("popularSection")} title={t("popularSection")}
viewAllTo="/browse?sort=popular" viewAllTo="/browse?tag=popular"
viewAllLabel={t("viewAll")} viewAllLabel={t("viewAll")}
/> />
</div> </div>
@@ -401,7 +401,7 @@ export function Home() {
<MessageBubble key={post.id} post={post} /> <MessageBubble key={post.id} post={post} />
))} ))}
</div> </div>
<div className="mt-7 hidden gap-3 min-[576px]:grid-cols-2 md:grid md:gap-4 lg:grid-cols-3 xl:grid-cols-5"> <div className="mt-7 hidden grid-cols-1 gap-3 min-[576px]:grid-cols-2 md:grid md:grid-cols-2 md:gap-4 lg:grid-cols-3 xl:grid-cols-5">
{popular.map((r) => ( {popular.map((r) => (
<LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} /> <LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} />
))} ))}

View File

@@ -45,14 +45,17 @@ export function OfficialRecommendationsPage() {
return ( return (
<section> <section>
<div className="mx-auto max-w-full px-4 md:max-w-[820px] md:px-0 lg:max-w-[1080px] xl:max-w-[1180px]">
<SectionHeader title={t("officialSection")} /> <SectionHeader title={t("officialSection")} />
<div className="mt-7 grid grid-cols-[repeat(auto-fill,208px)] justify-center gap-3 md:grid-cols-[repeat(auto-fill,240px)] md:justify-start md:gap-4 lg:grid-cols-[repeat(auto-fill,246.4px)]"> </div>
<div className="mx-auto mt-7 grid max-w-full grid-cols-1 justify-items-center gap-3 px-4 min-[560px]:grid-cols-2 md:max-w-[820px] md:grid-cols-3 md:px-0 lg:max-w-[1080px] lg:grid-cols-4 xl:max-w-[1180px]">
{items.map((item, index) => ( {items.map((item, index) => (
<RecommendedCard <RecommendedCard
key={item.id} key={item.id}
r={item} r={item}
visualIndex={index} visualIndex={index}
useFigmaDesign useFigmaDesign
layout="grid"
/> />
))} ))}
</div> </div>