diff --git a/app/components/home.tsx b/app/components/home.tsx index 576112715..19ecb730f 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -59,7 +59,7 @@ const Sd = dynamic(async () => (await import("./sd")).Sd, { loading: () => , }); -const SdPanel = dynamic(async () => (await import("./sd")).SdPanel, { +const SdNew = dynamic(async () => (await import("./sd")).SdNew, { loading: () => , }); @@ -144,7 +144,7 @@ function Screen() { const isHome = location.pathname === Path.Home; const isAuth = location.pathname === Path.Auth; const isSd = location.pathname === Path.Sd; - const isSdPanel = location.pathname === Path.SdPanel; + const isSdNew = location.pathname === Path.SdNew; const isMobileScreen = useMobileScreen(); const shouldTightBorder = @@ -157,7 +157,7 @@ function Screen() { const renderContent = () => { if (isAuth) return ; if (isSd) return ; - if (isSdPanel) return ; + if (isSdNew) return ; return ( <> @@ -167,8 +167,6 @@ function Screen() { } /> } /> } /> - } /> - } /> } /> diff --git a/app/components/sd/index.tsx b/app/components/sd/index.tsx index d442c22bc..f2808bd3e 100644 --- a/app/components/sd/index.tsx +++ b/app/components/sd/index.tsx @@ -1,2 +1,3 @@ export * from "./sd"; export * from "./sd-panel"; +export * from "./sd-new"; diff --git a/app/components/sd/sd-new.tsx b/app/components/sd/sd-new.tsx new file mode 100644 index 000000000..77e70d64f --- /dev/null +++ b/app/components/sd/sd-new.tsx @@ -0,0 +1,85 @@ +import homeStyles from "@/app/components/home.module.scss"; + +import { IconButton } from "@/app/components/button"; +import GithubIcon from "@/app/icons/github.svg"; +import ReturnIcon from "@/app/icons/return.svg"; +import Locale from "@/app/locales"; +import HistoryIcon from "@/app/icons/history.svg"; + +import { Path, REPO_URL } from "@/app/constant"; + +import { useNavigate } from "react-router-dom"; +import dynamic from "next/dynamic"; +import { + SideBarContainer, + SideBarBody, + SideBarTail, + useDragSideBar, + useHotKey, +} from "@/app/components/sidebar"; + +const SdPanel = dynamic( + async () => (await import("@/app/components/sd")).SdPanel, + { + loading: () => null, + }, +); + +export function SdNew() { + useHotKey(); + const { onDragStart, shouldNarrow } = useDragSideBar(); + const navigate = useNavigate(); + return ( + +
+ { +
+
+ } + bordered + title={Locale.Sd.Actions.ReturnHome} + onClick={() => navigate(Path.Home)} + /> +
+
+ } + +
+
Stability
+
+
+
+ } + bordered + title={Locale.Sd.Actions.History} + onClick={() => navigate(Path.Sd)} + /> +
+
+
+ + + + + } shadow /> + + } + /> +
+ ); +} diff --git a/app/components/sd/sd-sidebar.tsx b/app/components/sd/sd-sidebar.tsx index 9d85846d7..93909218f 100644 --- a/app/components/sd/sd-sidebar.tsx +++ b/app/components/sd/sd-sidebar.tsx @@ -1,5 +1,3 @@ -import styles from "@/app/components/home.module.scss"; - import { IconButton } from "@/app/components/button"; import GithubIcon from "@/app/icons/github.svg"; import SDIcon from "@/app/icons/sd.svg"; @@ -13,12 +11,14 @@ import dynamic from "next/dynamic"; import { SideBarContainer, SideBarBody, + SideBarHeader, + SideBarTail, useDragSideBar, useHotKey, } from "@/app/components/sidebar"; const SdPanel = dynamic( - async () => (await import("@/app/components/sd/sd-panel")).SdPanel, + async () => (await import("@/app/components/sd")).SdPanel, { loading: () => null, }, @@ -35,31 +35,27 @@ export function SideBar(props: { className?: string }) { shouldNarrow={shouldNarrow} {...props} > -
-
+ } bordered - title={Locale.Chat.Actions.ChatList} - onClick={() => navigate(Path.Chat)} + title={Locale.Sd.Actions.ReturnHome} + onClick={() => navigate(Path.Home)} /> -
-
- -
-
+ } + logo={} + > -
- -
+ + } shadow /> + + } + /> ); } diff --git a/app/components/sd/sd.tsx b/app/components/sd/sd.tsx index 547a877ee..83326e5eb 100644 --- a/app/components/sd/sd.tsx +++ b/app/components/sd/sd.tsx @@ -111,7 +111,7 @@ export function Sd() { icon={} bordered title={Locale.Chat.Actions.ChatList} - onClick={() => navigate(Path.SdPanel)} + onClick={() => navigate(Path.SdNew)} /> diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index 79af7e121..5db77170e 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useMemo, useState } from "react"; +import React, { useEffect, useRef, useMemo, useState, Fragment } from "react"; import styles from "./home.module.scss"; @@ -161,70 +161,24 @@ export function SideBarContainer(props: { ); } -export function SideBarHeader(props: { shouldNarrow: boolean }) { - const navigate = useNavigate(); - const config = useAppConfig(); - const { shouldNarrow } = props; - const [showPluginSelector, setShowPluginSelector] = useState(false); - +export function SideBarHeader(props: { + title?: string | React.ReactNode; + subTitle?: string | React.ReactNode; + logo?: React.ReactNode; + children?: React.ReactNode; +}) { + const { title, subTitle, logo, children } = props; return ( - <> +
- NextChat -
-
- Build your own AI assistant. -
-
- + {title}
+
{subTitle}
+
{logo}
- -
- } - text={shouldNarrow ? undefined : Locale.Mask.Name} - className={styles["sidebar-bar-button"]} - onClick={() => { - if (config.dontShowMaskSplashScreen !== true) { - navigate(Path.NewChat, { state: { fromHome: true } }); - } else { - navigate(Path.Masks, { state: { fromHome: true } }); - } - }} - shadow - /> - } - text={shouldNarrow ? undefined : Locale.Plugin.Name} - className={styles["sidebar-bar-button"]} - onClick={() => setShowPluginSelector(true)} - shadow - /> -
- {showPluginSelector && ( - { - return { - title: item.name, - value: item.path, - }; - }), - ]} - onClose={() => setShowPluginSelector(false)} - onSelection={(s) => { - navigate(s[0], { state: { fromHome: true } }); - }} - /> - )} - + {children} +
); } @@ -240,50 +194,16 @@ export function SideBarBody(props: { ); } -export function SideBarTail(props: { shouldNarrow: boolean }) { - const { shouldNarrow } = props; - const chatStore = useChatStore(); - const navigate = useNavigate(); - const config = useAppConfig(); +export function SideBarTail(props: { + primaryAction?: React.ReactNode; + secondaryAction?: React.ReactNode; +}) { + const { primaryAction, secondaryAction } = props; + return (
-
-
- } - onClick={async () => { - if (await showConfirm(Locale.Home.DeleteChat)) { - chatStore.deleteSession(chatStore.currentSessionIndex); - } - }} - /> -
-
- - } shadow /> - -
- -
-
- } - text={shouldNarrow ? undefined : Locale.Home.NewChat} - onClick={() => { - if (config.dontShowMaskSplashScreen) { - chatStore.newSession(); - navigate(Path.Chat); - } else { - navigate(Path.NewChat); - } - }} - shadow - /> -
+
{primaryAction}
+
{secondaryAction}
); } @@ -291,7 +211,10 @@ export function SideBarTail(props: { shouldNarrow: boolean }) { export function SideBar(props: { className?: string }) { useHotKey(); const { onDragStart, shouldNarrow } = useDragSideBar(); + const [showPluginSelector, setShowPluginSelector] = useState(false); const navigate = useNavigate(); + const config = useAppConfig(); + const chatStore = useChatStore(); return ( - + } + > +
+ } + text={shouldNarrow ? undefined : Locale.Mask.Name} + className={styles["sidebar-bar-button"]} + onClick={() => { + if (config.dontShowMaskSplashScreen !== true) { + navigate(Path.NewChat, { state: { fromHome: true } }); + } else { + navigate(Path.Masks, { state: { fromHome: true } }); + } + }} + shadow + /> + } + text={shouldNarrow ? undefined : Locale.Plugin.Name} + className={styles["sidebar-bar-button"]} + onClick={() => setShowPluginSelector(true)} + shadow + /> +
+ {showPluginSelector && ( + { + return { + title: item.name, + value: item.path, + }; + }), + ]} + onClose={() => setShowPluginSelector(false)} + onSelection={(s) => { + navigate(s[0], { state: { fromHome: true } }); + }} + /> + )} +
{ if (e.target === e.currentTarget) { @@ -309,7 +280,47 @@ export function SideBar(props: { className?: string }) { > - + +
+ } + onClick={async () => { + if (await showConfirm(Locale.Home.DeleteChat)) { + chatStore.deleteSession(chatStore.currentSessionIndex); + } + }} + /> +
+
+ + } shadow /> + +
+ + + } + secondaryAction={ + } + text={shouldNarrow ? undefined : Locale.Home.NewChat} + onClick={() => { + if (config.dontShowMaskSplashScreen) { + chatStore.newSession(); + navigate(Path.Chat); + } else { + navigate(Path.NewChat); + } + }} + shadow + /> + } + />
); } diff --git a/app/constant.ts b/app/constant.ts index 8f13d6103..1065aa14a 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -34,7 +34,7 @@ export enum Path { Masks = "/masks", Auth = "/auth", Sd = "/sd", - SdPanel = "/sd-panel", + SdNew = "/sd-new", } export enum ApiPath { diff --git a/app/icons/history.svg b/app/icons/history.svg new file mode 100644 index 000000000..e7b47c022 --- /dev/null +++ b/app/icons/history.svg @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/locales/cn.ts b/app/locales/cn.ts index a6391913d..6370cf76f 100644 --- a/app/locales/cn.ts +++ b/app/locales/cn.ts @@ -564,6 +564,8 @@ const cn = { Copy: "ๅคๅˆถๆ็คบ่ฏ", Delete: "ๅˆ ้™ค", Retry: "้‡่ฏ•", + ReturnHome: "่ฟ”ๅ›ž้ฆ–้กต", + History: "ๆŸฅ็œ‹ๅކๅฒ", }, EmptyRecord: "ๆš‚ๆ— ็ป˜็”ป่ฎฐๅฝ•", Status: { diff --git a/app/locales/en.ts b/app/locales/en.ts index 0bbea0c16..24784946c 100644 --- a/app/locales/en.ts +++ b/app/locales/en.ts @@ -570,6 +570,8 @@ const en: LocaleType = { Copy: "Copy Prompt", Delete: "Delete", Retry: "Retry", + ReturnHome: "Return Home", + History: "History", }, EmptyRecord: "No images yet", Status: {