diff --git a/website/src/components/DownloadButtons.astro b/website/src/components/DownloadButtons.astro index 4f16c21..edbfd08 100644 --- a/website/src/components/DownloadButtons.astro +++ b/website/src/components/DownloadButtons.astro @@ -1,10 +1,12 @@ --- import { site, platforms } from "../data/site"; +import { getRelease } from "../data/release"; interface Props { large?: boolean; } const { large = false } = Astro.props; +const release = await getRelease(); ---
@@ -26,7 +28,7 @@ const { large = false } = Astro.props; platforms.map((p) => ( [p.id, p.match])); --- - diff --git a/website/src/components/Footer.astro b/website/src/components/Footer.astro index ac1e3a8..3cdfa5a 100644 --- a/website/src/components/Footer.astro +++ b/website/src/components/Footer.astro @@ -1,14 +1,17 @@ --- import { site } from "../data/site"; +import { getRelease } from "../data/release"; import Logo from "./Logo.astro"; +const release = await getRelease(); + const cols = [ { title: "Get Margin", links: [ - { label: "Download for macOS", href: site.releasesUrl, os: "mac" }, - { label: "Download for Windows", href: site.releasesUrl, os: "windows" }, - { label: "Download for Linux", href: site.releasesUrl, os: "linux" }, + { label: "Download for macOS", href: release.urls.mac, os: "mac" }, + { label: "Download for Windows", href: release.urls.windows, os: "windows" }, + { label: "Download for Linux", href: release.urls.linux, os: "linux" }, ], }, { diff --git a/website/src/components/Hero.astro b/website/src/components/Hero.astro index b39211f..9bbbf39 100644 --- a/website/src/components/Hero.astro +++ b/website/src/components/Hero.astro @@ -1,7 +1,7 @@ --- import AppWindow from "./AppWindow.astro"; +import DownloadButtons from "./DownloadButtons.astro"; import OfferBadge from "./OfferBadge.astro"; -import { site, platforms } from "../data/site"; ---
@@ -21,25 +21,7 @@ import { site, platforms } from "../data/site";
-
- { - platforms.map((p) => ( - - - Download for {p.label} - - )) - } -
-

- v0.1.2 · Works offline · No account -

+
@@ -75,62 +57,9 @@ import { site, platforms } from "../data/site"; margin-top: clamp(24px, 3vw, 32px); scroll-margin-top: 96px; } - .hero__buttons { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 12px; - } - .osbtn { - display: inline-flex; - align-items: center; - gap: 10px; - padding: 0.82em 1.35em; - background: #ffffff; - border: 1px solid var(--line-strong); - border-radius: 999px; - color: #23201b; - font-family: var(--font-ui); - font-size: 1rem; - font-weight: 600; - box-shadow: var(--shadow-page); - transition: - transform 0.18s var(--ease), - box-shadow 0.18s var(--ease), - border-color 0.18s var(--ease); - } - .osbtn:hover { - transform: translateY(-1px); - box-shadow: var(--shadow-pop); - } - .osbtn.is-detected { - border-color: var(--ink); - } - .osbtn__icon { - width: 18px; - height: 18px; - flex: none; - object-fit: contain; - } - .hero__meta { - margin: 16px 0 0; - font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; - font-size: 0.8rem; - color: var(--ink-faint); - text-align: center; - } .hero__offer { display: flex; justify-content: center; margin-top: 22px; } - @media (max-width: 480px) { - .hero__buttons { - flex-direction: column; - align-items: stretch; - } - .osbtn { - justify-content: center; - } - } diff --git a/website/src/data/release.ts b/website/src/data/release.ts new file mode 100644 index 0000000..f3e1b13 --- /dev/null +++ b/website/src/data/release.ts @@ -0,0 +1,52 @@ +// Resolves the latest GitHub release to a direct download URL per OS, at build +// time. The picked file follows each platform's `match` order in site.ts. +// Falls back to the releases page if the release can't be read. + +import { site, platforms } from "./site"; + +type Asset = { name: string; browser_download_url: string }; + +export type Release = { + version: string; + urls: Record; +}; + +function pickAsset(assets: Asset[], match: string[]): string | null { + for (const sfx of match) { + const hit = assets.find((a) => a.name.toLowerCase().endsWith(sfx.toLowerCase())); + if (hit) return hit.browser_download_url; + } + return null; +} + +function fallback(): Release { + return { + version: "", + urls: Object.fromEntries(platforms.map((p) => [p.id, site.releasesUrl])), + }; +} + +async function fetchRelease(): Promise { + try { + const res = await fetch(`https://api.github.com/repos/${site.repo}/releases/latest`, { + headers: { Accept: "application/vnd.github+json" }, + signal: AbortSignal.timeout(8000), + }); + if (!res.ok) return fallback(); + const data = await res.json(); + const assets: Asset[] = data.assets || []; + const urls = Object.fromEntries( + platforms.map((p) => [p.id, pickAsset(assets, p.match) ?? site.releasesUrl]), + ); + return { version: data.tag_name ?? "", urls }; + } catch { + return fallback(); + } +} + +let cached: Promise | null = null; + +export function getRelease(): Promise { + cached ??= fetchRelease(); + return cached; +} diff --git a/website/src/data/site.ts b/website/src/data/site.ts index c33b12c..c73776a 100644 --- a/website/src/data/site.ts +++ b/website/src/data/site.ts @@ -39,8 +39,8 @@ export type Platform = { export const platforms: Platform[] = [ { id: "mac", label: "macOS", logo: "macos.svg", match: [".dmg"] }, - { id: "windows", label: "Windows", logo: "windows.svg", match: [".msi", ".exe"] }, - { id: "linux", label: "Linux", logo: "linux.svg", match: [".AppImage", ".deb", ".rpm"] }, + { id: "windows", label: "Windows", logo: "windows.svg", match: [".exe", ".msi"] }, + { id: "linux", label: "Linux", logo: "linux.svg", match: [".deb", ".AppImage", ".rpm"] }, ]; // Full-color store logos, served from /public/logos. Shown on white tiles so