Files
KVideo/app/layout.tsx
T
2026-01-12 19:41:18 +08:00

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>
);
}