Skip to content

Commit bbac569

Browse files
committed
Stabilize featured task carousel layout
1 parent 4421aa3 commit bbac569

File tree

2 files changed

+26
-52
lines changed

2 files changed

+26
-52
lines changed

src/app/page.tsx

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Link from "next/link";
22
import { FeaturedTaskCarousel } from "@/components/featured-task-carousel";
33
import { HomeHeroStats } from "@/components/home-hero-stats";
44
import { ResourceCard } from "@/components/resource-card";
5-
import { getIndex, type TaskIndexItem } from "@/lib/task-index";
5+
import { getIndex } from "@/lib/task-index";
66
import {
77
contributeResources,
88
frameworkHighlights,
@@ -11,41 +11,7 @@ import {
1111
tutorialResources
1212
} from "@/lib/site-content";
1313

14-
const FIXED_FEATURED_REPOS = ["T000002-bart", "T000012-sst", "T000006-mid"] as const;
15-
const FIXED_FEATURED_REPO_SET = new Set<string>(FIXED_FEATURED_REPOS);
16-
const RANDOM_FEATURED_COUNT = 2;
17-
18-
function buildSeed(seedSource: string): number {
19-
return Array.from(seedSource).reduce(
20-
(seed, character) => ((seed * 33) ^ character.charCodeAt(0)) >>> 0,
21-
5381
22-
);
23-
}
24-
25-
function seededShuffle<T>(items: T[], seedSource: string): T[] {
26-
const shuffled = [...items];
27-
let seed = buildSeed(seedSource);
28-
29-
for (let index = shuffled.length - 1; index > 0; index -= 1) {
30-
seed = (seed * 1664525 + 1013904223) >>> 0;
31-
const swapIndex = seed % (index + 1);
32-
[shuffled[index], shuffled[swapIndex]] = [shuffled[swapIndex], shuffled[index]];
33-
}
34-
35-
return shuffled;
36-
}
37-
38-
function uniqueTasks(tasks: TaskIndexItem[]): TaskIndexItem[] {
39-
const seen = new Set<string>();
40-
41-
return tasks.filter((task) => {
42-
if (!task.repo || seen.has(task.repo)) {
43-
return false;
44-
}
45-
seen.add(task.repo);
46-
return true;
47-
});
48-
}
14+
const FEATURED_REPOS = ["T000006-mid", "T000002-bart", "T000012-sst"] as const;
4915

5016
function TapsDiagram() {
5117
return (
@@ -130,18 +96,10 @@ function TapsDiagram() {
13096
export default function Page() {
13197
const index = getIndex();
13298
const tasks = index.tasks ?? [];
133-
const fixedFeaturedTasks = FIXED_FEATURED_REPOS.map((repo) =>
99+
const featuredTasks = FEATURED_REPOS.map((repo) =>
134100
tasks.find((task) => task.repo === repo)
135-
).filter((task): task is TaskIndexItem => Boolean(task));
136-
const randomFeaturedTasks = seededShuffle(
137-
tasks.filter((task) => !FIXED_FEATURED_REPO_SET.has(task.repo)),
138-
index.generated_at
139-
).slice(0, RANDOM_FEATURED_COUNT);
140-
const curatedFeaturedTasks = uniqueTasks([
141-
...fixedFeaturedTasks,
142-
...randomFeaturedTasks,
143-
...tasks
144-
]).slice(0, FIXED_FEATURED_REPOS.length + RANDOM_FEATURED_COUNT);
101+
).filter((task): task is (typeof tasks)[number] => Boolean(task));
102+
const curatedFeaturedTasks = featuredTasks.length > 0 ? featuredTasks : tasks.slice(0, 3);
145103

146104
return (
147105
<div className="space-y-20 pb-8">

src/components/featured-task-carousel.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ export function FeaturedTaskCarousel({
9999
))}
100100
</div>
101101

102-
<div className="tb-frame-soft flex min-h-[320px] flex-col bg-[#f8fcff] p-5 sm:min-h-[360px] sm:p-6">
103-
<div className="flex flex-wrap items-center gap-2 text-xs text-slate-600">
102+
<div className="tb-frame-soft flex h-[360px] flex-col bg-[#f8fcff] p-5 sm:h-[392px] sm:p-6">
103+
<div className="min-h-[3rem] content-start flex flex-wrap items-center gap-2 text-xs text-slate-600">
104104
<code className="rounded-full border-2 border-[#25314d] bg-white px-2.5 py-1 font-mono text-[11px] font-semibold text-[#25314d]">
105105
{taskHandle(activeTask)}
106106
</code>
@@ -115,15 +115,31 @@ export function FeaturedTaskCarousel({
115115
</span>
116116
</div>
117117

118-
<div className="mt-4 font-heading text-[2rem] font-bold leading-[1.02] text-[#25314d] sm:text-[2.45rem]">
118+
<div
119+
className="mt-4 min-h-[4.2rem] font-heading text-[2rem] font-bold leading-[1.02] text-[#25314d] sm:min-h-[5.1rem] sm:text-[2.45rem]"
120+
style={{
121+
display: "-webkit-box",
122+
WebkitLineClamp: 2,
123+
WebkitBoxOrient: "vertical",
124+
overflow: "hidden"
125+
}}
126+
>
119127
{taskTitle(activeTask)}
120128
</div>
121129

122-
<p className="mt-3 max-w-[38ch] text-sm leading-7 text-slate-700 sm:text-base">
130+
<p
131+
className="mt-3 min-h-[5.25rem] max-w-[38ch] text-sm leading-7 text-slate-700 sm:min-h-[5.75rem] sm:text-base"
132+
style={{
133+
display: "-webkit-box",
134+
WebkitLineClamp: 3,
135+
WebkitBoxOrient: "vertical",
136+
overflow: "hidden"
137+
}}
138+
>
123139
{activeTask.short_description}
124140
</p>
125141

126-
<div className="mt-6 flex flex-wrap gap-3 sm:mt-auto">
142+
<div className="mt-auto flex flex-col gap-3 sm:flex-row sm:flex-wrap">
127143
<button
128144
type="button"
129145
className="tb-focus-ring tb-button-primary"

0 commit comments

Comments
 (0)