Skip to content

Commit a9c1690

Browse files
committed
clean up download page
1 parent 611a3a4 commit a9c1690

File tree

4 files changed

+49
-58
lines changed

4 files changed

+49
-58
lines changed
File renamed without changes.

src/app/download/page.tsx

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,69 @@
11
import type { Metadata } from "next";
2+
import { XMLParser } from "fast-xml-parser";
23
import Image from "next/image";
34
import SectionWrapper from "@/components/section-wrapper";
45
import { H1, P } from "@/components/text";
5-
import { fetchLatestGhosttyVersion } from "@/lib/fetch-latest-ghostty-version";
66
import SVGIMG from "../../../public/ghostty-logo.svg";
7-
import ReleaseDownloadPage from "./release-download-page";
8-
import TipDownloadPage from "./tip-download-page";
7+
import ReleaseDownloadPage from "./ReleaseDownloadPage";
8+
import TipDownloadPage from "./TipDownloadPage";
99
import s from "./DownloadPage.module.css";
1010

11-
export const dynamic = "force-static";
11+
type AppcastItem = {
12+
"sparkle:version": string;
13+
"sparkle:shortVersionString": string;
14+
};
1215

16+
type Appcast = {
17+
rss?: {
18+
channel?: {
19+
item?: AppcastItem | AppcastItem[];
20+
};
21+
};
22+
};
23+
24+
/** Metadata for the download page. */
1325
export const metadata: Metadata = {
1426
title: "Download Ghostty",
1527
description:
1628
"Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.",
1729
};
1830

19-
async function loadPageData(): Promise<{
20-
latestVersion: string;
21-
}> {
22-
return {
23-
latestVersion: await fetchLatestGhosttyVersion(),
24-
};
31+
/** Fetches and parses the appcast to determine the latest released Ghostty version. */
32+
async function fetchLatestGhosttyVersion(): Promise<string> {
33+
const response = await fetch(
34+
"https://release.files.ghostty.org/appcast.xml",
35+
{
36+
cache: "force-cache",
37+
},
38+
);
39+
if (!response.ok) {
40+
throw new Error(`Failed to fetch XML: ${response.statusText}`);
41+
}
42+
43+
const xmlContent = await response.text();
44+
const parser = new XMLParser({
45+
ignoreAttributes: false,
46+
});
47+
const parsedXml = parser.parse(xmlContent) as Appcast;
48+
49+
const items = parsedXml.rss?.channel?.item;
50+
if (!items) {
51+
throw new Error("Failed to parse appcast XML: no items found");
52+
}
53+
54+
const itemsArray = Array.isArray(items) ? items : [items];
55+
const latestItem = itemsArray.reduce((maxItem, currentItem) => {
56+
const currentVersion = Number.parseInt(currentItem["sparkle:version"], 10);
57+
const maxVersion = Number.parseInt(maxItem["sparkle:version"], 10);
58+
return currentVersion > maxVersion ? currentItem : maxItem;
59+
});
60+
61+
return latestItem["sparkle:shortVersionString"];
2562
}
2663

64+
/** Renders the download page for either stable releases or the tip build. */
2765
export default async function DownloadPage() {
28-
const { latestVersion } = await loadPageData();
66+
const latestVersion = await fetchLatestGhosttyVersion();
2967
const isTip = process.env.GIT_COMMIT_REF === "tip";
3068

3169
return (

src/lib/fetch-latest-ghostty-version.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)