refactor: init switching to nextjs router

This commit is contained in:
Fred
2024-05-10 14:57:55 +08:00
parent 00b1a9781d
commit 0c53579996
25 changed files with 473 additions and 123 deletions

102
app/(app)/chat/layout.tsx Normal file
View File

@@ -0,0 +1,102 @@
"use client";
import {
DEFAULT_SIDEBAR_WIDTH,
MAX_SIDEBAR_WIDTH,
MIN_SIDEBAR_WIDTH,
Path,
} from "@/app/constant";
import useDrag from "@/app/hooks/useDrag";
import useMobileScreen from "@/app/hooks/useMobileScreen";
import { updateGlobalCSSVars } from "@/app/utils/client";
import { useRef, useState } from "react";
import { useAppConfig } from "@/app/store/config";
import React from "react";
import { AuthPage } from "@/app/components/auth";
import { SideBar } from "@/app/containers/Sidebar";
import Screen from "@/app/components/Screen";
import { useSwitchTheme } from "@/app/hooks/useSwitchTheme";
import Chat from "@/app/containers/Chat/ChatPanel";
export default function Layout({ children }: { children: React.ReactNode }) {
const [showPanel, setShowPanel] = useState(false);
const [externalProps, setExternalProps] = useState({});
const config = useAppConfig();
useSwitchTheme();
const isMobileScreen = useMobileScreen();
const startDragWidth = useRef(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
// drag side bar
const { onDragStart } = useDrag({
customToggle: () => {
config.update((config) => {
config.sidebarWidth = DEFAULT_SIDEBAR_WIDTH;
});
},
customDragMove: (nextWidth: number) => {
const { menuWidth } = updateGlobalCSSVars(nextWidth);
document.documentElement.style.setProperty(
"--menu-width",
`${menuWidth}px`,
);
config.update((config) => {
config.sidebarWidth = nextWidth;
});
},
customLimit: (x: number) =>
Math.max(
MIN_SIDEBAR_WIDTH,
Math.min(MAX_SIDEBAR_WIDTH, startDragWidth.current + x),
),
});
return (
<div
className={`
w-[100%] relative bg-center
max-md:h-[100%]
md:flex md:my-2.5
`}
>
<div
className={`
flex flex-col px-6
h-[100%]
max-md:w-[100%] max-md:px-4 max-md:pb-4 max-md:flex-1
md:relative md:basis-sidebar md:pb-6 md:rounded-md md:bg-menu
`}
>
{children}
</div>
{!isMobileScreen && (
<div
className={`group/menu-dragger cursor-col-resize w-[0.25rem] flex items-center justify-center`}
onPointerDown={(e) => {
startDragWidth.current = config.sidebarWidth;
onDragStart(e as any);
}}
>
<div className="w-[2px] opacity-0 group-hover/menu-dragger:opacity-100 bg-menu-dragger h-[100%] rounded-[2px]">
&nbsp;
</div>
</div>
)}
<div
className={`
md:flex-1 md:h-[100%] md:w-page
max-md:transition-all max-md:duration-300 max-md:absolute max-md:top-0 max-md:max-h-[100vh] max-md:w-[100%] ${
showPanel ? "max-md:left-0" : "max-md:left-[101%]"
} max-md:z-10
`}
>
{/* <PanelComponent
{...props}
{...externalProps}
setShowPanel={setShowPanel}
setExternalProps={setExternalProps}
showPanel={showPanel}
/> */}
{/* {children} */}
<Chat></Chat>
</div>
</div>
);
}

137
app/(app)/chat/page.tsx Normal file
View File

@@ -0,0 +1,137 @@
"use client";
import {
DragDropContext,
Droppable,
OnDragEndResponder,
} from "@hello-pangea/dnd";
import { useAppConfig, useChatStore } from "@/app/store";
import Locale from "@/app/locales";
// import { useLocation, useNavigate } from "react-router-dom";
import { useRouter, usePathname } from "next/navigation";
import AddIcon from "@/app/icons/addIcon.svg";
import NextChatTitle from "@/app/icons/nextchatTitle.svg";
import Modal from "@/app/components/Modal";
import SessionItem from "@/app/containers/Chat/components/SessionItem";
export default function Page() {
const [sessions, selectedIndex, selectSession, moveSession] = useChatStore(
(state) => [
state.sessions,
state.currentSessionIndex,
state.selectSession,
state.moveSession,
],
);
const config = useAppConfig();
const { isMobileScreen } = config;
const chatStore = useChatStore();
const pathname = usePathname();
const onDragEnd: OnDragEndResponder = (result) => {
const { destination, source } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
moveSession(source.index, destination.index);
};
return (
<div
className={`
h-[100%] flex flex-col
md:px-0
`}
>
<div data-tauri-drag-region>
<div
className={`
flex items-center justify-between
py-6 max-md:box-content max-md:h-0
md:py-7
`}
data-tauri-drag-region
>
<div className="">
<NextChatTitle />
</div>
<div
className="cursor-pointer "
onClick={() => {
// if (config.dontShowMaskSplashScreen) {
// chatStore.newSession();
// navigate(Path.Chat);
// } else {
// navigate(Path.NewChat);
// }
}}
>
<AddIcon />
</div>
</div>
<div
className={`pb-3 text-sm sm:text-sm-mobile text-text-chat-header-subtitle`}
>
Build your own AI assistant.
</div>
</div>
<div className={`flex-1 overflow-y-auto max-md:pb-chat-panel-mobile `}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="chat-list">
{(provided) => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
className={`w-[100%]`}
>
{sessions.map((item, i) => (
<SessionItem
title={item.topic}
time={new Date(item.lastUpdate).toLocaleString()}
count={item.messages.length}
key={item.id}
id={item.id}
index={i}
selected={i === selectedIndex}
onClick={() => {
// navigate(Path.Chat);
// selectSession(i);
}}
onDelete={async () => {
if (
await Modal.warn({
okText: Locale.ChatItem.DeleteOkBtn,
cancelText: Locale.ChatItem.DeleteCancelBtn,
title: Locale.ChatItem.DeleteTitle,
content: Locale.ChatItem.DeleteContent,
})
) {
chatStore.deleteSession(i);
}
}}
mask={item.mask}
isMobileScreen={isMobileScreen}
/>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
</div>
);
}

21
app/(app)/layout.tsx Normal file
View File

@@ -0,0 +1,21 @@
"use client";
import React from "react";
import { AuthPage } from "@/app/components/auth";
import { SideBar } from "@/app/containers/Sidebar";
import Screen from "@/app/components/Screen";
export interface MenuWrapperInspectProps {
setExternalProps?: (v: Record<string, any>) => void;
setShowPanel?: (v: boolean) => void;
showPanel?: boolean;
[k: string]: any;
}
export default function AppLayout({ children }: { children: React.ReactNode }) {
return (
<Screen noAuth={<AuthPage />} sidebar={<SideBar />}>
{children}
</Screen>
);
}

View File

@@ -0,0 +1,4 @@
import React from "react";
export default function Layout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}

View File

@@ -0,0 +1,3 @@
export default function Page() {
return <></>;
}