Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 46 additions & 37 deletions src/app/java/changelog/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,6 +18,9 @@ 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";
import { type ReleaseVersionEntry } from "~/components/java/version-link";

export default async function ChangelogLayout({
children,
Expand Down Expand Up @@ -64,12 +66,9 @@ export default async function ChangelogLayout({
</SheetDescription>
</SheetHeader>
<ScrollArea className="h-full">
<ul>
<VersionLinks
versions={versions}
className="rounded-lg px-3 py-2"
/>
</ul>
<div className="versions">
<VersionLinks versions={versions} type="vertical" className="rounded-lg px-3 py-2" />
</div>
</ScrollArea>
</SheetContent>
</Sheet>
Expand All @@ -79,12 +78,10 @@ export default async function ChangelogLayout({
className="h-page rounded-md border"
viewportClassName="overscroll-contain"
>
<ul>
<li key="header" className="p-2">
<h2 className="font-semibold">Versions:</h2>
</li>
<VersionLinks versions={versions} className="py-1 pl-3 pr-4" />
</ul>
<h2 key="header" className="p-2 font-semibold justify-self-center">Versions</h2>
<div className="versions">
<VersionLinks versions={versions} type="horizontal" className="py-1 pl-3 pr-4" />
</div>
</ScrollArea>
</div>
<div>{children}</div>
Expand All @@ -95,32 +92,44 @@ export default async function ChangelogLayout({

function VersionLinks({
versions,
className = "",
type,
className = ""
}: {
versions: VersionManifest["entries"];
type: string;
className?: string;
}) {
return (
<>
<li key="latest">
<VersionLink
versionName="Latest"
versionLink=""
data={versions[0]}
className={className}
/>
</li>
{versions.map((v) => {
return (
<li key={v.version}>
<VersionLink
versionName={v.version}
data={v}
className={className}
/>
</li>
);
})}
</>
);
const orderedVersions: ReleaseVersionEntry[] = [
{
name: "Latest",
url: "",
title: versions[0].title,
description: versions[0].shortText,
image: versions[0].image,
nonReleaseVersions: [],
isLatest: true
}
];
for (const 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 => <ReleaseVersionLinkSet key={version.name} type={type} release={version} className={className} />);
}
53 changes: 53 additions & 0 deletions src/components/java/release-version-link-set.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use client";

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;
}) {
const selectedVersion = useVersion();
return (
<div className="major-version">
<VersionLink version={release} selected={release.name === selectedVersion} className={className} />
{
release.nonReleaseVersions.length > 0 && <>
<input type="checkbox" id={`major-version-${release.name}-${type}`} defaultChecked={containsVersion(release, selectedVersion)}></input>
<label className="major-version-button" htmlFor={`major-version-${release.name}-${type}`}></label>
<div className="major-version-body">
{release.nonReleaseVersions.map(nonReleaseVersion => <VersionLink key={nonReleaseVersion.name} version={nonReleaseVersion} selected={nonReleaseVersion.name === selectedVersion} className={className} />)}
</div>
</>
}
</div>
);
}

function useVersion(): string {
const prefix = "java/changelog/";
const pathname = usePathname();
if (pathname === prefix) {
return "";
}
const probableVersion = 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;
}
return release.nonReleaseVersions.some(nonRelease => nonRelease.name === version);
}
40 changes: 23 additions & 17 deletions src/components/java/version-link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,34 @@ 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";

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 (
<HoverCard closeDelay={0} openDelay={0}>
<HoverCardTrigger asChild>
<Link
href={url}
className={cn(
"inline-block w-full text-subtext1 hover:bg-surface1",
"inline-block w-full text-subtext1 hover:bg-surface1 version-label",
{ "bg-surface0 underline": selected },
className,
)}
prefetch={false}
>
{versionName}
{version.name}
</Link>
</HoverCardTrigger>
<HoverCardPortal>
Expand All @@ -53,13 +46,26 @@ export default function VersionLink({
<div
className="absolute inset-0 -z-10 rounded-md bg-cover bg-center opacity-20"
style={{
backgroundImage: `url(${BASE_ASSET_URL + image.url})`,
backgroundImage: `url(${BASE_ASSET_URL + version.image.url})`,
}}
/>
<h2>{title}</h2>
<p>{shortText}…</p>
<h2>{version.title}</h2>
<p>{version.description}…</p>
</HoverCardContent>
</HoverCardPortal>
</HoverCard>
);
}

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;
}
3 changes: 3 additions & 0 deletions src/styles/arrow_down.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/styles/arrow_up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions src/styles/game-versions.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading