import clsx from 'clsx';
import dynamic from 'next/dynamic';
import { useEffect, useState } from 'react';
import {
Route,
HashRouter as Router,
Routes,
useLocation,
} from 'react-router-dom';
import { type ClientApi, getClientApi } from '../client/api';
import { getClientConfig } from '../config/client';
import { Path, SlotID } from '../constant';
import BotIcon from '../icons/bot.svg';
import LoadingIcon from '../icons/three-dots.svg';
import { getISOLang, getLang } from '../locales';
import { useAccessStore } from '../store';
import { useAppConfig } from '../store/config';
import { getCSSVar, useMobileScreen } from '../utils';
import { AuthPage } from './auth';
import { ErrorBoundary } from './error';
import styles from './home.module.scss';
import { SideBar } from './sidebar';
'use client';
require('../polyfill');
export function Loading(props: { noLogo?: boolean }) {
return (
{!props.noLogo && }
);
}
const Artifacts = dynamic(async () => (await import('./artifacts')).Artifacts, {
loading: () => ,
});
const Settings = dynamic(async () => (await import('./settings')).Settings, {
loading: () => ,
});
const Chat = dynamic(async () => (await import('./chat')).Chat, {
loading: () => ,
});
const NewChat = dynamic(async () => (await import('./new-chat')).NewChat, {
loading: () => ,
});
const MaskPage = dynamic(async () => (await import('./mask')).MaskPage, {
loading: () => ,
});
const PluginPage = dynamic(async () => (await import('./plugin')).PluginPage, {
loading: () => ,
});
const SearchChat = dynamic(
async () => (await import('./search-chat')).SearchChatPage,
{
loading: () => ,
},
);
const Sd = dynamic(async () => (await import('./sd')).Sd, {
loading: () => ,
});
export function useSwitchTheme() {
const config = useAppConfig();
useEffect(() => {
document.body.classList.remove('light');
document.body.classList.remove('dark');
if (config.theme === 'dark') {
document.body.classList.add('dark');
} else if (config.theme === 'light') {
document.body.classList.add('light');
}
const metaDescriptionDark = document.querySelector(
'meta[name="theme-color"][media*="dark"]',
);
const metaDescriptionLight = document.querySelector(
'meta[name="theme-color"][media*="light"]',
);
if (config.theme === 'auto') {
metaDescriptionDark?.setAttribute('content', '#151515');
metaDescriptionLight?.setAttribute('content', '#fafafa');
} else {
const themeColor = getCSSVar('--theme-color');
metaDescriptionDark?.setAttribute('content', themeColor);
metaDescriptionLight?.setAttribute('content', themeColor);
}
}, [config.theme]);
}
function useHtmlLang() {
useEffect(() => {
const lang = getISOLang();
const htmlLang = document.documentElement.lang;
if (lang !== htmlLang) {
document.documentElement.lang = lang;
}
}, []);
}
function useHasHydrated() {
const [hasHydrated, setHasHydrated] = useState(false);
useEffect(() => {
setHasHydrated(true);
}, []);
return hasHydrated;
}
function loadAsyncGoogleFont() {
const linkEl = document.createElement('link');
const proxyFontUrl = '/google-fonts';
const remoteFontUrl = 'https://fonts.googleapis.com';
const googleFontUrl
= getClientConfig()?.buildMode === 'export' ? remoteFontUrl : proxyFontUrl;
linkEl.rel = 'stylesheet';
linkEl.href
= `${googleFontUrl
}/css2?family=${
encodeURIComponent('Noto Sans:wght@300;400;700;900')
}&display=swap`;
document.head.appendChild(linkEl);
}
export function WindowContent(props: { children: React.ReactNode }) {
return (
{props?.children}
);
}
function Screen() {
const config = useAppConfig();
const location = useLocation();
const isArtifact = location.pathname.includes(Path.Artifacts);
const isHome = location.pathname === Path.Home;
const isAuth = location.pathname === Path.Auth;
const isSd = location.pathname === Path.Sd;
const isSdNew = location.pathname === Path.SdNew;
const isMobileScreen = useMobileScreen();
const shouldTightBorder
= getClientConfig()?.isApp || (config.tightBorder && !isMobileScreen);
useEffect(() => {
loadAsyncGoogleFont();
}, []);
if (isArtifact) {
return (
} />
);
}
const renderContent = () => {
if (isAuth)
{ return ; }
if (isSd)
{ return ; }
if (isSdNew)
{ return ; }
return (
<>
} />
} />
} />
} />
} />
} />
} />
>
);
};
return (
{renderContent()}
);
}
export function useLoadData() {
const config = useAppConfig();
const api: ClientApi = getClientApi(config.modelConfig.providerName);
useEffect(() => {
(async () => {
const models = await api.llm.models();
config.mergeModels(models);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}
export function Home() {
useSwitchTheme();
useLoadData();
useHtmlLang();
useEffect(() => {
console.log('[Config] got config from build time', getClientConfig());
useAccessStore.getState().fetch();
}, []);
if (!useHasHydrated()) {
return ;
}
return (
);
}