All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 12m17s
146 lines
4.5 KiB
TypeScript
146 lines
4.5 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { Analytics } from "@vercel/analytics/next";
|
|
import "./globals.css";
|
|
import "./block-theme.css";
|
|
import "./account.css";
|
|
import "./map-theme.css";
|
|
import "./workshop.css";
|
|
import "./leaderboard.css";
|
|
import "./home-map.css";
|
|
import "./rounded-theme.css";
|
|
import "./cursor.css";
|
|
import { SiteCursor } from "@/components/SiteCursor";
|
|
import { I18nProvider } from "@/components/I18nProvider";
|
|
import { getI18n } from "@/lib/i18n";
|
|
import "./polish.css";
|
|
import "./mobile-game.css";
|
|
import "./multiplayer.css";
|
|
import "./support.css";
|
|
import "./appearance.css";
|
|
import "./community.css";
|
|
import "./community-social.css";
|
|
import "./cinematic-intro.css";
|
|
import "./tournaments.css";
|
|
import "./site-glass.css";
|
|
import { themeInitScript } from "@/shared/theme";
|
|
import { SiteSettingsProvider } from "@/components/SiteSettingsProvider";
|
|
import { initialSiteSettings } from "@/lib/site-settings";
|
|
import { rawUser, accountState } from "@/lib/supabase";
|
|
import { LegacyPasswordNotice } from "@/components/LegacyPasswordNotice";
|
|
import { BackNavigationTransition } from "@/components/BackNavigationTransition";
|
|
import { Suspense } from "react";
|
|
export async function generateMetadata(): Promise<Metadata> {
|
|
const { t } = await getI18n();
|
|
return {
|
|
title: {
|
|
default: t("MineGeo — Get lost in a familiar world"),
|
|
template: "%s · MineGeo",
|
|
},
|
|
description: t(
|
|
"Guess where you are in Minecraft. Explore community servers through 360° panoramas and place your pin on the map.",
|
|
),
|
|
};
|
|
}
|
|
export default async function RootLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode;
|
|
}) {
|
|
const [{ locale, preference, detectedLocale, t }, settings] =
|
|
await Promise.all([getI18n(), initialSiteSettings()]);
|
|
return (
|
|
<html lang={locale} data-theme="dark" suppressHydrationWarning>
|
|
<head>
|
|
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
|
|
</head>
|
|
<body>
|
|
<svg
|
|
aria-hidden="true"
|
|
className="site-filter-definitions"
|
|
focusable="false"
|
|
>
|
|
<defs>
|
|
<filter
|
|
id="liquid-glass-distortion"
|
|
x="-10%"
|
|
y="-20%"
|
|
width="120%"
|
|
height="140%"
|
|
colorInterpolationFilters="sRGB"
|
|
>
|
|
<feTurbulence
|
|
type="fractalNoise"
|
|
baseFrequency="0.012 0.055"
|
|
numOctaves={2}
|
|
seed={7}
|
|
result="glass-noise"
|
|
/>
|
|
<feGaussianBlur
|
|
in="glass-noise"
|
|
stdDeviation="2.5"
|
|
result="soft-glass-noise"
|
|
/>
|
|
<feDisplacementMap
|
|
in="SourceGraphic"
|
|
in2="soft-glass-noise"
|
|
scale={18}
|
|
xChannelSelector="R"
|
|
yChannelSelector="G"
|
|
result="refracted-backdrop"
|
|
/>
|
|
<feSpecularLighting
|
|
in="soft-glass-noise"
|
|
surfaceScale={3}
|
|
specularConstant={0.55}
|
|
specularExponent={32}
|
|
lightingColor="#fff"
|
|
result="glass-highlight"
|
|
>
|
|
<feDistantLight azimuth={315} elevation={55} />
|
|
</feSpecularLighting>
|
|
<feComposite
|
|
in="glass-highlight"
|
|
in2="SourceAlpha"
|
|
operator="in"
|
|
result="bounded-highlight"
|
|
/>
|
|
<feBlend
|
|
in="refracted-backdrop"
|
|
in2="bounded-highlight"
|
|
mode="screen"
|
|
/>
|
|
</filter>
|
|
</defs>
|
|
</svg>
|
|
<a className="skip-link" href="#main-content">
|
|
{t("Skip to content")}
|
|
</a>
|
|
<I18nProvider
|
|
locale={locale}
|
|
preference={preference}
|
|
detectedLocale={detectedLocale}
|
|
>
|
|
<SiteSettingsProvider initialSettings={settings}>
|
|
<Suspense fallback={null}>
|
|
<BackNavigationTransition />
|
|
</Suspense>
|
|
{children}
|
|
<SiteCursor />
|
|
<Suspense fallback={null}>
|
|
<AccountPasswordNotice />
|
|
</Suspense>
|
|
</SiteSettingsProvider>
|
|
</I18nProvider>
|
|
<Analytics />
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|
|
async function AccountPasswordNotice() {
|
|
const account = await rawUser();
|
|
const active = account
|
|
? (await accountState(account.id)) === "active"
|
|
: false;
|
|
return <LegacyPasswordNotice enabled={active && !!account?.email} />;
|
|
}
|