You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
import { SpeedInsights } from '@vercel/speed-insights/next';
|
|
import { ThemeAppearance } from 'antd-style';
|
|
import { ResolvingViewport } from 'next';
|
|
import { ReactNode } from 'react';
|
|
import { isRtlLang } from 'rtl-detect';
|
|
|
|
import Analytics from '@/components/Analytics';
|
|
import { DEFAULT_LANG } from '@/const/locale';
|
|
// import PWAInstall from '@/features/PWAInstall';
|
|
import AuthProvider from '@/layout/AuthProvider';
|
|
import GlobalProvider from '@/layout/GlobalProvider';
|
|
import { Locales } from '@/locales/resources';
|
|
import { DynamicLayoutProps } from '@/types/next';
|
|
import { RouteVariants } from '@/utils/server/routeVariants';
|
|
|
|
const inVercel = process.env.VERCEL === '1';
|
|
|
|
interface RootLayoutProps extends DynamicLayoutProps {
|
|
children: ReactNode;
|
|
modal: ReactNode;
|
|
}
|
|
|
|
const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
|
|
const { variants } = await params;
|
|
|
|
const { locale, isMobile, theme, primaryColor, neutralColor } =
|
|
RouteVariants.deserializeVariants(variants);
|
|
|
|
const direction = isRtlLang(locale) ? 'rtl' : 'ltr';
|
|
|
|
return (
|
|
<html dir={direction} lang={locale} suppressHydrationWarning>
|
|
<body>
|
|
<GlobalProvider
|
|
appearance={theme}
|
|
isMobile={isMobile}
|
|
locale={locale}
|
|
neutralColor={neutralColor}
|
|
primaryColor={primaryColor}
|
|
>
|
|
<AuthProvider>
|
|
{children}
|
|
{!isMobile && modal}
|
|
</AuthProvider>
|
|
{/*<PWAInstall />*/}
|
|
</GlobalProvider>
|
|
<Analytics />
|
|
{inVercel && <SpeedInsights />}
|
|
</body>
|
|
</html>
|
|
);
|
|
};
|
|
|
|
export default RootLayout;
|
|
|
|
export { generateMetadata } from './metadata';
|
|
|
|
export const generateViewport = async (props: DynamicLayoutProps): ResolvingViewport => {
|
|
const isMobile = await RouteVariants.getIsMobile(props);
|
|
|
|
const dynamicScale = isMobile ? { maximumScale: 1, userScalable: false } : {};
|
|
|
|
return {
|
|
...dynamicScale,
|
|
initialScale: 1,
|
|
minimumScale: 1,
|
|
themeColor: [
|
|
{ color: '#f8f8f8', media: '(prefers-color-scheme: light)' },
|
|
{ color: '#000', media: '(prefers-color-scheme: dark)' },
|
|
],
|
|
viewportFit: 'cover',
|
|
width: 'device-width',
|
|
};
|
|
};
|
|
|
|
export const generateStaticParams = () => {
|
|
const themes: ThemeAppearance[] = ['dark', 'light'];
|
|
const mobileOptions = [true, false];
|
|
// only static for serveral page, other go to dynamtic
|
|
const staticLocales: Locales[] = [DEFAULT_LANG, 'zh-CN'];
|
|
|
|
const variants: { variants: string }[] = [];
|
|
|
|
for (const locale of staticLocales) {
|
|
for (const theme of themes) {
|
|
for (const isMobile of mobileOptions) {
|
|
variants.push({
|
|
variants: RouteVariants.serializeVariants({ isMobile, locale, theme }),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return variants;
|
|
};
|