From 56bcc3f952471aeec266fa7210b9e2ac56808434 Mon Sep 17 00:00:00 2001 From: ErrorCraft <51973682+ErrorCraft@users.noreply.github.com> Date: Sun, 26 Oct 2025 15:24:38 +0100 Subject: [PATCH 1/4] Group each version per release in the version bar --- src/app/java/changelog/layout.tsx | 97 +++++++++++-------- .../java/release-version-link-set.tsx | 55 +++++++++++ src/components/java/version-link.tsx | 28 +++--- src/styles/arrow_down.svg | 3 + src/styles/arrow_up.svg | 3 + src/styles/game-versions.css | 47 +++++++++ 6 files changed, 178 insertions(+), 55 deletions(-) create mode 100644 src/components/java/release-version-link-set.tsx create mode 100644 src/styles/arrow_down.svg create mode 100644 src/styles/arrow_up.svg create mode 100644 src/styles/game-versions.css diff --git a/src/app/java/changelog/layout.tsx b/src/app/java/changelog/layout.tsx index 430bbb5..835ec6b 100644 --- a/src/app/java/changelog/layout.tsx +++ b/src/app/java/changelog/layout.tsx @@ -3,7 +3,6 @@ import { getVersionManifest, type VersionManifest, } from "~/server/java/versions"; -import VersionLink from "~/components/java/version-link"; import { Alert, AlertDescription, AlertTitle } from "~/components/ui/alert"; import { ActivityLogIcon, @@ -19,9 +18,11 @@ import { SheetTrigger, } from "~/components/ui/sheet"; import { Button } from "~/components/ui/button"; +import ReleaseVersionLinkSet from "~/components/java/release-version-link-set"; +import "~/styles/game-versions.css"; export default async function ChangelogLayout({ - children, + children }: { children: React.ReactNode; }) { @@ -64,12 +65,9 @@ export default async function ChangelogLayout({ - +
+ +
@@ -79,12 +77,10 @@ export default async function ChangelogLayout({ className="h-page rounded-md border" viewportClassName="overscroll-contain" > - +

Versions

+
+ +
{children}
@@ -93,34 +89,59 @@ export default async function ChangelogLayout({ ); } +export interface VersionEntry { + name: string; + url: string; + title: string; + description: string; + image: { title: string; url: string; }; +} + +export interface ReleaseVersionEntry extends VersionEntry { + nonReleaseVersions: VersionEntry[]; + isLatest: boolean; +} + function VersionLinks({ versions, - className = "", + type, + className = "" }: { versions: VersionManifest["entries"]; + type: string; className?: string; }) { - return ( - <> -
  • - -
  • - {versions.map((v) => { - return ( -
  • - -
  • - ); - })} - - ); + let orderedVersions: ReleaseVersionEntry[] = [ + { + name: "Latest", + url: "", + title: versions[0].title, + description: versions[0].shortText, + image: versions[0].image, + nonReleaseVersions: [], + isLatest: true + } + ]; + for (let version of versions) { + if (version.type === "release") { + orderedVersions.push({ + name: version.version, + url: version.version, + title: version.title, + description: version.shortText, + image: version.image, + nonReleaseVersions: [], + isLatest: false + }); + continue; + } + orderedVersions.at(-1)!.nonReleaseVersions.push({ + name: version.version, + url: version.version, + title: version.title, + description: version.shortText, + image: version.image + }); + } + return orderedVersions.map(version => ); } diff --git a/src/components/java/release-version-link-set.tsx b/src/components/java/release-version-link-set.tsx new file mode 100644 index 0000000..d4779e1 --- /dev/null +++ b/src/components/java/release-version-link-set.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { ReleaseVersionEntry } from "~/app/java/changelog/layout"; +import VersionLink from "./version-link"; +import { usePathname } from "next/navigation"; + +export default function ReleaseVersionLinkSet({release, type, className}: { + release: ReleaseVersionEntry; + type: string; + className: string; +}) { + let selectedVersion: string = getVersion(); + return ( +
    + + { + release.nonReleaseVersions.length > 0 && <> + + +
    + {release.nonReleaseVersions.map(nonReleaseVersion => )} +
    + + } +
    + ); +} + +function getVersion(): string { + const prefix: string = "java/changelog/"; + const pathname = usePathname(); + if (pathname === prefix) { + return ""; + } + let probableVersion: string = pathname.substring(prefix.length); + if (probableVersion.startsWith("/")) { + return probableVersion.substring(1); + } + return probableVersion; +} + +function containsVersion(release: ReleaseVersionEntry, version: string): boolean { + if (release.isLatest && version === "") { + return true; + } + if (release.name === version) { + return true; + } + for (let nonRelease of release.nonReleaseVersions) { + if (nonRelease.name === version) { + return true; + } + } + return false; +} diff --git a/src/components/java/version-link.tsx b/src/components/java/version-link.tsx index eb38c55..745e2ce 100644 --- a/src/components/java/version-link.tsx +++ b/src/components/java/version-link.tsx @@ -8,41 +8,35 @@ import { } from "~/components/ui/hover-card"; import Link from "next/link"; import { cn } from "~/lib/utils"; -import { usePathname } from "next/navigation"; import { BASE_ASSET_URL, - type VersionManifestEntry, } from "~/server/java/versions"; import type { ClassValue } from "clsx"; +import { VersionEntry } from "~/app/java/changelog/layout"; export default function VersionLink({ - versionName, - versionLink = versionName, - data: { shortText, title, image }, + version, className = "px-3 py-1", + selected }: { - versionName: string; - versionLink?: string; - data: VersionManifestEntry; + version: VersionEntry; className?: ClassValue; + selected: boolean; }) { - const url = `/java/changelog/${versionLink}`; - const pathname = usePathname(); - const selected = url === pathname || url === pathname + "/"; - + const url = `/java/changelog/${version.url}`; return ( - {versionName} + {version.name} @@ -53,11 +47,11 @@ export default function VersionLink({
    -

    {title}

    -

    {shortText}…

    +

    {version.title}

    +

    {version.description}…

    diff --git a/src/styles/arrow_down.svg b/src/styles/arrow_down.svg new file mode 100644 index 0000000..6d168c4 --- /dev/null +++ b/src/styles/arrow_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/arrow_up.svg b/src/styles/arrow_up.svg new file mode 100644 index 0000000..7b626fb --- /dev/null +++ b/src/styles/arrow_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/game-versions.css b/src/styles/game-versions.css new file mode 100644 index 0000000..5654561 --- /dev/null +++ b/src/styles/game-versions.css @@ -0,0 +1,47 @@ +.versions { + display: flex; + flex-direction: column; + margin-left: 0.5em; + user-select: none; +} + +.versions input { + display: none; +} + +.major-version { + display: grid; + gap: 0 0.5em; + grid-template-rows: auto 1fr; + grid-template-columns: 1em 1fr; + grid-template-areas: + "button title" + ". body"; +} + +.major-version > .version-label { + grid-area: title; + font-weight: bold; +} + +.major-version-button { + aspect-ratio: 1 / 1; + align-self: center; + grid-area: button; + background-image: url("arrow_down.svg"); + background-size: cover; +} + +input:checked + .major-version-button { + background-image: url("arrow_up.svg"); +} + +.major-version-body { + grid-area: body; + display: none; +} + +input:checked ~ .major-version-body { + display: flex; + flex-direction: column; +} From c1dc122e826fc59b977852d9400e828a5fa0d1ae Mon Sep 17 00:00:00 2001 From: ErrorCraft <51973682+ErrorCraft@users.noreply.github.com> Date: Tue, 28 Oct 2025 01:27:10 +0100 Subject: [PATCH 2/4] Apply suggestions --- src/app/java/changelog/layout.tsx | 20 ++++--------------- .../java/release-version-link-set.tsx | 18 ++++++----------- src/components/java/version-link.tsx | 14 ++++++++++++- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/app/java/changelog/layout.tsx b/src/app/java/changelog/layout.tsx index 835ec6b..230db52 100644 --- a/src/app/java/changelog/layout.tsx +++ b/src/app/java/changelog/layout.tsx @@ -20,9 +20,10 @@ import { import { Button } from "~/components/ui/button"; import ReleaseVersionLinkSet from "~/components/java/release-version-link-set"; import "~/styles/game-versions.css"; +import { type ReleaseVersionEntry } from "~/components/java/version-link"; export default async function ChangelogLayout({ - children + children, }: { children: React.ReactNode; }) { @@ -89,19 +90,6 @@ export default async function ChangelogLayout({ ); } -export interface VersionEntry { - name: string; - url: string; - title: string; - description: string; - image: { title: string; url: string; }; -} - -export interface ReleaseVersionEntry extends VersionEntry { - nonReleaseVersions: VersionEntry[]; - isLatest: boolean; -} - function VersionLinks({ versions, type, @@ -111,7 +99,7 @@ function VersionLinks({ type: string; className?: string; }) { - let orderedVersions: ReleaseVersionEntry[] = [ + const orderedVersions: ReleaseVersionEntry[] = [ { name: "Latest", url: "", @@ -122,7 +110,7 @@ function VersionLinks({ isLatest: true } ]; - for (let version of versions) { + for (const version of versions) { if (version.type === "release") { orderedVersions.push({ name: version.version, diff --git a/src/components/java/release-version-link-set.tsx b/src/components/java/release-version-link-set.tsx index d4779e1..9a195df 100644 --- a/src/components/java/release-version-link-set.tsx +++ b/src/components/java/release-version-link-set.tsx @@ -1,15 +1,14 @@ "use client"; -import { ReleaseVersionEntry } from "~/app/java/changelog/layout"; -import VersionLink from "./version-link"; import { usePathname } from "next/navigation"; +import VersionLink, { type ReleaseVersionEntry } from "./version-link"; export default function ReleaseVersionLinkSet({release, type, className}: { release: ReleaseVersionEntry; type: string; className: string; }) { - let selectedVersion: string = getVersion(); + const selectedVersion = useVersion(); return (
    @@ -26,13 +25,13 @@ export default function ReleaseVersionLinkSet({release, type, className}: { ); } -function getVersion(): string { - const prefix: string = "java/changelog/"; +function useVersion(): string { + const prefix = "java/changelog/"; const pathname = usePathname(); if (pathname === prefix) { return ""; } - let probableVersion: string = pathname.substring(prefix.length); + const probableVersion = pathname.substring(prefix.length); if (probableVersion.startsWith("/")) { return probableVersion.substring(1); } @@ -46,10 +45,5 @@ function containsVersion(release: ReleaseVersionEntry, version: string): boolean if (release.name === version) { return true; } - for (let nonRelease of release.nonReleaseVersions) { - if (nonRelease.name === version) { - return true; - } - } - return false; + return release.nonReleaseVersions.some(nonRelease => nonRelease.name === version); } diff --git a/src/components/java/version-link.tsx b/src/components/java/version-link.tsx index 745e2ce..8b2407a 100644 --- a/src/components/java/version-link.tsx +++ b/src/components/java/version-link.tsx @@ -12,7 +12,6 @@ import { BASE_ASSET_URL, } from "~/server/java/versions"; import type { ClassValue } from "clsx"; -import { VersionEntry } from "~/app/java/changelog/layout"; export default function VersionLink({ version, @@ -57,3 +56,16 @@ export default function VersionLink({ ); } + +export interface VersionEntry { + name: string; + url: string; + title: string; + description: string; + image: { title: string; url: string; }; +} + +export interface ReleaseVersionEntry extends VersionEntry { + nonReleaseVersions: VersionEntry[]; + isLatest: boolean; +} From 4ee2bd38936fbf9c667bfeb30ae3acc66aa962db Mon Sep 17 00:00:00 2001 From: ErrorCraft <51973682+ErrorCraft@users.noreply.github.com> Date: Thu, 6 Nov 2025 02:09:17 +0100 Subject: [PATCH 3/4] Place the other props on multiple lines --- src/components/java/release-version-link-set.tsx | 6 +++++- src/components/java/version-link.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/java/release-version-link-set.tsx b/src/components/java/release-version-link-set.tsx index 9a195df..5c25106 100644 --- a/src/components/java/release-version-link-set.tsx +++ b/src/components/java/release-version-link-set.tsx @@ -3,7 +3,11 @@ import { usePathname } from "next/navigation"; import VersionLink, { type ReleaseVersionEntry } from "./version-link"; -export default function ReleaseVersionLinkSet({release, type, className}: { +export default function ReleaseVersionLinkSet({ + release, + type, + className, +}: { release: ReleaseVersionEntry; type: string; className: string; diff --git a/src/components/java/version-link.tsx b/src/components/java/version-link.tsx index 8b2407a..24f0e95 100644 --- a/src/components/java/version-link.tsx +++ b/src/components/java/version-link.tsx @@ -16,7 +16,7 @@ import type { ClassValue } from "clsx"; export default function VersionLink({ version, className = "px-3 py-1", - selected + selected, }: { version: VersionEntry; className?: ClassValue; From ae7f420150fe1865abf17e79128d5da65e40031b Mon Sep 17 00:00:00 2001 From: ErrorCraft <51973682+ErrorCraft@users.noreply.github.com> Date: Mon, 17 Nov 2025 00:51:45 +0100 Subject: [PATCH 4/4] Fix the arrows to work on all themes --- src/styles/arrow_down.svg | 2 +- src/styles/arrow_up.svg | 2 +- src/styles/game-versions.css | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/styles/arrow_down.svg b/src/styles/arrow_down.svg index 6d168c4..349e67e 100644 --- a/src/styles/arrow_down.svg +++ b/src/styles/arrow_down.svg @@ -1,3 +1,3 @@ - + diff --git a/src/styles/arrow_up.svg b/src/styles/arrow_up.svg index 7b626fb..f58a950 100644 --- a/src/styles/arrow_up.svg +++ b/src/styles/arrow_up.svg @@ -1,3 +1,3 @@ - + diff --git a/src/styles/game-versions.css b/src/styles/game-versions.css index 5654561..c1d72ef 100644 --- a/src/styles/game-versions.css +++ b/src/styles/game-versions.css @@ -28,12 +28,12 @@ aspect-ratio: 1 / 1; align-self: center; grid-area: button; - background-image: url("arrow_down.svg"); - background-size: cover; + mask-image: url("arrow_down.svg"); + background-color: rgb(var(--ctp-subtext1)); } input:checked + .major-version-button { - background-image: url("arrow_up.svg"); + mask-image: url("arrow_up.svg"); } .major-version-body {