--- /** * The `PageFooter` slot: an Obsidian-style backlinks list under a topic landing * or guide page — every problem page that points at it, as ` ` * rows in LeetCode-number order. Pages nothing points at (problem pages, the * overview, the changelog) render nothing. * * A problem points at a page when either * - one of its topic badges links there — the same `tagTarget()` answer * `ProblemBadges.astro` renders, so this list and the badges cannot drift * (a DFS problem is a backlink of the one DFS landing its badge picks); or * - it lives under the page's route (`/hybrid-structures/lru-cache` under * `/hybrid-structures`), so a topic no LeetCode tag names still lists its * own problems. * * Problem pages are recognised by their `. ` title, the shape * `apps/cli/sync.ts` writes. * * The list is a native `
`, open on load: the chevron at the top * right of the header row collapses it like an accordion, with no JS. */ import { getEntry } from "astro:content"; import data from "blume:data"; import { withBase } from "blume/components/islands/base-path.ts"; import Icon from "blume/components/Icon.astro"; import { tagTarget, type TopicTag } from "../topic-landings.ts"; interface Props { route: string; } interface Route { path: string; title: string; collection: string; entryId: string; } const { route } = Astro.props; const routes: Route[] = data.routes; const served = new Set(routes.map((r) => r.path)); const problems = routes.flatMap((r) => { const m = r.title.match(/^(\d+)\.\s+(.+)$/); return m ? [{ route: r, num: Number(m[1]), name: m[2]! }] : []; }); // A problem page is never a backlink target: skip the per-problem lookups there. const backlinks = problems.some((p) => p.route.path === route) ? [] : ( await Promise.all( problems.map(async (p) => { if (p.route.path.startsWith(`${route}/`)) return p; const entry = await getEntry(p.route.collection, p.route.entryId); const tags: TopicTag[] = entry?.data.topics ?? []; const page = { route: p.route.path, tags }; return tags.some((tag) => tagTarget(tag, page, served).href === route) ? p : undefined; }), ) ) .filter((p) => p !== undefined) .sort((a, b) => a.num - b.num); --- { backlinks.length > 0 && (
) }