mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-13 07:43:43 +08:00
94 lines
2.6 KiB
TypeScript
94 lines
2.6 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { Geist, Geist_Mono } from "next/font/google";
|
|
import "./globals.css";
|
|
import { ThemeProvider } from "@/components/ThemeProvider";
|
|
import { Analytics } from "@vercel/analytics/react";
|
|
import { ServiceWorkerRegister } from "@/components/ServiceWorkerRegister";
|
|
import { PasswordGate } from "@/components/PasswordGate";
|
|
import { siteConfig } from "@/lib/config/site-config";
|
|
|
|
|
|
const geistSans = Geist({
|
|
variable: "--font-geist-sans",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
const geistMono = Geist_Mono({
|
|
variable: "--font-geist-mono",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
export const metadata: Metadata = {
|
|
title: siteConfig.title,
|
|
description: siteConfig.description,
|
|
icons: {
|
|
icon: '/icon.png',
|
|
},
|
|
};
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode;
|
|
}>) {
|
|
return (
|
|
<html lang="zh-CN" suppressHydrationWarning>
|
|
<body
|
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
suppressHydrationWarning
|
|
>
|
|
<ThemeProvider>
|
|
<PasswordGate hasEnvPassword={!!process.env.ACCESS_PASSWORD}>
|
|
{children}
|
|
</PasswordGate>
|
|
<Analytics />
|
|
<ServiceWorkerRegister />
|
|
</ThemeProvider>
|
|
|
|
{/* ARIA Live Region for Screen Reader Announcements */}
|
|
<div
|
|
id="aria-live-announcer"
|
|
role="status"
|
|
aria-live="polite"
|
|
aria-atomic="true"
|
|
className="sr-only"
|
|
/>
|
|
|
|
{/* Google Cast SDK */}
|
|
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1" async />
|
|
|
|
{/* Scroll Performance Optimization Script */}
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
(function() {
|
|
let scrollTimer;
|
|
const body = document.body;
|
|
|
|
function handleScroll() {
|
|
body.classList.add('scrolling');
|
|
clearTimeout(scrollTimer);
|
|
scrollTimer = setTimeout(function() {
|
|
body.classList.remove('scrolling');
|
|
}, 150);
|
|
}
|
|
|
|
let ticking = false;
|
|
window.addEventListener('scroll', function() {
|
|
if (!ticking) {
|
|
window.requestAnimationFrame(function() {
|
|
handleScroll();
|
|
ticking = false;
|
|
});
|
|
ticking = true;
|
|
}
|
|
}, { passive: true });
|
|
})();
|
|
`,
|
|
}}
|
|
/>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|