ChatGPT-Next-Web/app/components/home.tsx

140 lines
3.4 KiB
TypeScript
Raw Normal View History

2023-03-09 17:01:40 +00:00
"use client";
require("../polyfill");
2023-04-20 17:12:39 +00:00
import { useState, useEffect } from "react";
2023-03-11 17:14:07 +00:00
2023-03-12 19:06:21 +00:00
import styles from "./home.module.scss";
2023-03-09 17:01:40 +00:00
import BotIcon from "../icons/bot.svg";
2023-03-10 18:25:33 +00:00
import LoadingIcon from "../icons/three-dots.svg";
import { useChatStore } from "../store";
2023-04-20 15:20:25 +00:00
import { getCSSVar, useMobileScreen } from "../utils";
2023-04-02 15:05:54 +00:00
import { Chat } from "./chat";
2023-03-13 16:25:07 +00:00
import dynamic from "next/dynamic";
2023-04-20 17:12:39 +00:00
import { Path } from "../constant";
import { ErrorBoundary } from "./error";
2023-04-20 17:12:39 +00:00
import {
HashRouter as Router,
Routes,
Route,
useLocation,
} from "react-router-dom";
2023-03-21 14:56:27 +00:00
export function Loading(props: { noLogo?: boolean }) {
return (
2023-04-20 17:12:39 +00:00
<div className={styles["loading-content"] + " no-dark"}>
2023-03-21 14:56:27 +00:00
{!props.noLogo && <BotIcon />}
<LoadingIcon />
</div>
);
}
2023-03-21 14:56:27 +00:00
const Settings = dynamic(async () => (await import("./settings")).Settings, {
loading: () => <Loading noLogo />,
});
2023-04-20 17:12:39 +00:00
const SideBar = dynamic(async () => (await import("./sidebar")).SideBar, {
loading: () => <Loading noLogo />,
2023-03-21 14:56:27 +00:00
});
2023-03-11 12:54:24 +00:00
2023-04-20 18:52:53 +00:00
export function useSwitchTheme() {
2023-03-12 19:06:21 +00:00
const config = useChatStore((state) => state.config);
useEffect(() => {
document.body.classList.remove("light");
document.body.classList.remove("dark");
2023-03-12 19:06:21 +00:00
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]',
);
const metaDescriptionLight = document.querySelector(
'meta[name="theme-color"]:not([media])',
);
2023-03-15 17:24:03 +00:00
if (config.theme === "auto") {
metaDescriptionDark?.setAttribute("content", "#151515");
metaDescriptionLight?.setAttribute("content", "#fafafa");
} else {
const themeColor = getCSSVar("--themeColor");
metaDescriptionDark?.setAttribute("content", themeColor);
metaDescriptionLight?.setAttribute("content", themeColor);
}
}, [config.theme]);
2023-03-19 15:13:10 +00:00
}
2023-03-27 08:58:53 +00:00
const useHasHydrated = () => {
const [hasHydrated, setHasHydrated] = useState<boolean>(false);
useEffect(() => {
setHasHydrated(true);
}, []);
return hasHydrated;
};
2023-04-20 17:12:39 +00:00
function WideScreen() {
2023-03-12 19:21:48 +00:00
const config = useChatStore((state) => state.config);
2023-03-11 17:14:07 +00:00
2023-03-09 17:01:40 +00:00
return (
2023-04-10 18:56:48 +00:00
<div
className={`${
2023-04-20 17:12:39 +00:00
config.tightBorder ? styles["tight-container"] : styles.container
2023-04-10 18:56:48 +00:00
}`}
>
2023-04-20 18:52:53 +00:00
<SideBar />
2023-04-10 18:54:31 +00:00
2023-04-20 17:12:39 +00:00
<div className={styles["window-content"]}>
<Routes>
<Route path={Path.Home} element={<Chat />} />
<Route path={Path.Chat} element={<Chat />} />
<Route path={Path.Settings} element={<Settings />} />
</Routes>
</div>
</div>
);
}
2023-04-10 18:56:48 +00:00
2023-04-20 17:12:39 +00:00
function MobileScreen() {
const location = useLocation();
const isHome = location.pathname === Path.Home;
2023-04-10 18:56:48 +00:00
2023-04-20 17:12:39 +00:00
return (
<div className={styles.container}>
2023-04-20 18:52:53 +00:00
<SideBar className={isHome ? styles["sidebar-show"] : ""} />
2023-04-10 18:56:48 +00:00
<div className={styles["window-content"]}>
2023-04-20 17:12:39 +00:00
<Routes>
<Route path={Path.Home} element={null} />
<Route path={Path.Chat} element={<Chat />} />
<Route path={Path.Settings} element={<Settings />} />
</Routes>
2023-03-11 17:14:07 +00:00
</div>
2023-04-10 18:56:48 +00:00
</div>
2023-03-09 17:01:40 +00:00
);
}
export function Home() {
2023-04-20 17:12:39 +00:00
const isMobileScreen = useMobileScreen();
2023-04-20 18:52:53 +00:00
useSwitchTheme();
2023-04-20 17:12:39 +00:00
if (!useHasHydrated()) {
return <Loading />;
}
return (
<ErrorBoundary>
2023-04-20 17:12:39 +00:00
<Router>{isMobileScreen ? <MobileScreen /> : <WideScreen />}</Router>
</ErrorBoundary>
);
}