Add Void difficulty and publish changelogs
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 3m40s
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 3m40s
This commit is contained in:
@@ -33,7 +33,7 @@ export default async function About() {
|
||||
<h2>{t("Five chances to find your way")}</h2>
|
||||
<p>
|
||||
{t(
|
||||
"Easy gives you 180 seconds, Normal 90, and Hard 30. Hard disables zoom. A timed-out round scores zero; you can still finish the expedition.",
|
||||
"Easy gives you 180 seconds, Normal 90, and Hard 30. Void is the hardest: just 10 seconds, a fixed panorama and map, no zoom, no compass or coordinates, and strict scoring. A timed-out round scores zero; you can still finish the expedition.",
|
||||
)}
|
||||
</p>
|
||||
<h2>{t("Closer means better")}</h2>
|
||||
|
||||
@@ -384,7 +384,10 @@ html[data-theme="light"] .site-cursor-dot span {
|
||||
background: #273b21;
|
||||
box-shadow: 0 0 1px #fff;
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.header-inner {
|
||||
max-width: 1600px;
|
||||
}
|
||||
@media (max-width: 1500px) {
|
||||
.site-header {
|
||||
height: auto;
|
||||
}
|
||||
@@ -458,3 +461,31 @@ html[data-theme="light"] .site-cursor-dot span {
|
||||
grid-row: 3;
|
||||
}
|
||||
}
|
||||
.difficulty-options button.difficulty-void {
|
||||
border-color: #a855f7;
|
||||
background: linear-gradient(145deg, #21122f, #100c18);
|
||||
color: #e9d5ff;
|
||||
box-shadow: 0 0 16px #a855f738, inset 0 0 20px #a855f710;
|
||||
}
|
||||
.difficulty-options button.difficulty-void strong {
|
||||
color: #e9d5ff;
|
||||
text-shadow: 0 0 10px #c084fc99, 0 0 22px #a855f780;
|
||||
}
|
||||
.difficulty-options button.difficulty-void.selected,
|
||||
html[data-theme="light"] .difficulty-options button.difficulty-void.selected {
|
||||
color: #f3e8ff;
|
||||
background: linear-gradient(145deg, #482363, #21122f);
|
||||
border-color: #d8b4fe;
|
||||
box-shadow: 0 0 24px #a855f760, inset 0 0 20px #c084fc18;
|
||||
}
|
||||
html[data-theme="light"] .difficulty-options button.difficulty-void {
|
||||
background: #f3e8ff;
|
||||
border-color: #a855f7;
|
||||
color: #581c87;
|
||||
}
|
||||
html[data-theme="light"] .difficulty-options button.difficulty-void strong {
|
||||
color: #7e22ce;
|
||||
}
|
||||
html[data-theme="light"] .difficulty-options button.difficulty-void.selected strong {
|
||||
color: #f3e8ff;
|
||||
}
|
||||
|
||||
77
app/changelogs/page.tsx
Normal file
77
app/changelogs/page.tsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import Link from "next/link";
|
||||
import type { Metadata } from "next";
|
||||
import { Header, Footer } from "@/components/Shell";
|
||||
import { ReleaseNotes } from "@/components/ReleaseNotes";
|
||||
import { ChangelogRefresh } from "@/components/ChangelogRefresh";
|
||||
import { getChangelog } from "@/lib/changelog";
|
||||
import { getI18n } from "@/lib/i18n";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Changelogs",
|
||||
description: "The latest MineGeo releases, improvements, and bug fixes.",
|
||||
};
|
||||
|
||||
export default async function ChangelogsPage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<{ before?: string }>;
|
||||
}) {
|
||||
const params = await searchParams;
|
||||
const before =
|
||||
typeof params.before === "string" && /^\d{17,20}$/.test(params.before)
|
||||
? params.before
|
||||
: undefined;
|
||||
const [{ t, formatDate }, feed] = await Promise.all([
|
||||
getI18n(),
|
||||
getChangelog(before),
|
||||
]);
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content changelog-page">
|
||||
{!before && <ChangelogRefresh />}
|
||||
<span className="eyebrow">{t("WHAT'S NEW")}</span>
|
||||
<h1>{t("Changelogs")}</h1>
|
||||
<p className="lead">
|
||||
{t("New releases, improvements, and fixes from MineGeo.")}
|
||||
</p>
|
||||
{before && <Link href="/changelogs">{t("Latest releases")}</Link>}
|
||||
{feed.unavailable ? (
|
||||
<div className="empty-state">
|
||||
<h2>{t("Release notes are temporarily unavailable")}</h2>
|
||||
<p>{t("Please check back soon.")}</p>
|
||||
</div>
|
||||
) : feed.entries.length === 0 ? (
|
||||
<p className="muted">{t("No releases on this page yet.")}</p>
|
||||
) : (
|
||||
<div className="changelog-list">
|
||||
{feed.entries.map((entry) => (
|
||||
<article
|
||||
className="changelog-entry"
|
||||
key={entry.id}
|
||||
id={`release-${entry.id}`}
|
||||
>
|
||||
<div className="changelog-meta">
|
||||
<span className="tag">{t(entry.kind)}</span>
|
||||
<time dateTime={entry.publishedAt}>
|
||||
{formatDate(entry.publishedAt)}
|
||||
</time>
|
||||
</div>
|
||||
<h2>{entry.title}</h2>
|
||||
<div className="release-notes">
|
||||
<ReleaseNotes body={entry.body} />
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{!feed.unavailable && "before" in feed && feed.before && (
|
||||
<Link className="button" href={`/changelogs?before=${feed.before}`}>
|
||||
{t("Older posts")}
|
||||
</Link>
|
||||
)}
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export default async function DashboardPage() {
|
||||
typeof s.difficulty_settings === "object" &&
|
||||
!Array.isArray(s.difficulty_settings) &&
|
||||
typeof s.difficulty_settings.name === "string"
|
||||
? ["easy", "normal", "hard"].includes(s.difficulty)
|
||||
? ["easy", "normal", "hard", "void"].includes(s.difficulty)
|
||||
? t(s.difficulty_settings.name)
|
||||
: s.difficulty_settings.name
|
||||
: t(
|
||||
|
||||
@@ -1745,3 +1745,13 @@ pre {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.changelog-page { max-width: 960px; }
|
||||
.changelog-list { margin: 36px 0; }
|
||||
.changelog-entry { padding: 32px 0; border-top: 1px solid var(--line); scroll-margin-top: 100px; }
|
||||
.changelog-entry h2 { margin: 14px 0 20px; font-size: clamp(1.4rem, 3vw, 2rem); }
|
||||
.changelog-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 16px; color: var(--muted); font-size: .85rem; }
|
||||
.release-notes { line-height: 1.8; overflow-wrap: anywhere; }
|
||||
.release-notes ul { padding-left: 24px; }
|
||||
.release-notes li + li { margin-top: 12px; }
|
||||
.release-notes p { white-space: normal; }
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||
return {
|
||||
title: t("Leaderboard"),
|
||||
description: t(
|
||||
"Meet MineGeo’s top explorers. Compare the best five-round scores across easy, normal, and hard Minecraft expeditions.",
|
||||
"Meet MineGeo’s top explorers. Compare the best five-round scores across Easy, Normal, Hard, and Void Minecraft expeditions.",
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user