Skip to content

Commit

Permalink
use lazy loading and admin pages (in dev)
Browse files Browse the repository at this point in the history
zmh-program committed Nov 6, 2023
1 parent d5f9171 commit 5c08d04
Showing 14 changed files with 180 additions and 19 deletions.
10 changes: 10 additions & 0 deletions app/src/assets/admin/all.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import "menu";

.admin-page {
position: relative;
display: flex;
flex-direction: row;
width: 100%;
min-height: calc(100vh - 56px);
height: max-content;
}
59 changes: 59 additions & 0 deletions app/src/assets/admin/menu.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.admin-menu {
display: flex;
flex-shrink: 0;
flex-direction: column;
width: 0;
height: 100%;
padding: 0;
margin: 0;
background: var(--background-sidebar);
transition: 0.225s ease-in-out;
min-height: calc(100vh - 56px);
transition-property: width, background, box-shadow, opacity;
border-right: 0;
opacity: 0;

&.close {
display: none;
}

&.open {
width: 260px;
border-right: 1px solid hsl(var(--border));
opacity: 1;
}

.menu-item {
display: flex;
flex-direction: row;
width: calc(100% - 1.5rem);
height: max-content;
padding: 0.75rem 1rem;
align-items: center;
background: var(--conversation-card);
margin: 0.75rem 0.75rem -0.25rem;
user-select: none;
cursor: pointer;
transition: 0.2s ease-in-out;
border-radius: var(--radius);
font-size: 16px;

&:hover {
background: var(--conversation-card-hover);
}

&.active {
background: var(--conversation-card-hover);
}

& > * {
flex-shrink: 0;
}

& svg {
width: 1.5rem;
height: 1.5rem;
margin-right: 0.5rem;
}
}
}
2 changes: 1 addition & 1 deletion app/src/components/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ function Markdown({ children, className }: MarkdownProps) {
code({ inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || "");
const language = match ? match[1] : "";
if (language) return parseFile(children.toString());
if (language === "file") return parseFile(children.toString());
return !inline && match ? (
<div className={`markdown-syntax`}>
<div className={`markdown-syntax-header`}>
50 changes: 50 additions & 0 deletions app/src/components/admin/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {useSelector} from "react-redux";
import {selectMenu} from "@/store/menu.ts";
import React, {useEffect, useMemo, useState} from "react";
import {LayoutDashboard, Settings} from "lucide-react";
import router from "@/router.tsx";
import {useLocation} from "react-router-dom";

type MenuItemProps = {
title: string;
icon: React.ReactNode;
path: string;
}

function MenuItem({ title, icon, path }: MenuItemProps) {
const location = useLocation();
const active = useMemo(() => (
location.pathname === `/admin${path}` || (location.pathname + "/") === `/admin${path}`
), [location.pathname, path]);

return (
<div className={`menu-item ${active ? "active" : ""}`}
onClick={() => router.navigate(`/admin${path}`)}
>
<div className={`menu-item-icon`}>
{icon}
</div>
<div className={`menu-item-title`}>
{title}
</div>
</div>
)
}

function MenuBar() {
const open = useSelector(selectMenu);
const [close, setClose] = useState(false);
useEffect(() => {
if (open) setClose(false);
else setTimeout(() => setClose(true), 200);
}, [open]);

return (
<div className={`admin-menu ${open ? "open" : ""} ${close ? "close" : ""}`}>
<MenuItem title={"Dashboard"} icon={<LayoutDashboard />} path={"/"} />
<MenuItem title={"Dashboard"} icon={<Settings />} path={"/config"} />
</div>
)
}

export default MenuBar;
10 changes: 5 additions & 5 deletions app/src/components/home/ChatWrapper.tsx
Original file line number Diff line number Diff line change
@@ -15,12 +15,12 @@ import { useToast } from "@/components/ui/use-toast.ts";
import { ToastAction } from "@/components/ui/toast.tsx";
import { alignSelector, contextSelector } from "@/store/settings.ts";
import { FileArray } from "@/conversation/file.ts";
import WebToggle from "@/components/home/components/WebToggle.tsx";
import WebToggle from "@/components/home/assemblies/WebToggle.tsx";
import ChatSpace from "@/components/home/ChatSpace.tsx";
import ChatFooter from "@/components/home/ChatFooter.tsx";
import SendButton from "@/components/home/components/SendButton.tsx";
import ChatInput from "@/components/home/components/ChatInput.tsx";
import ScrollAction from "@/components/home/components/ScrollAction.tsx";
import SendButton from "@/components/home/assemblies/SendButton.tsx";
import ChatInput from "@/components/home/assemblies/ChatInput.tsx";
import ScrollAction from "@/components/home/assemblies/ScrollAction.tsx";

function ChatWrapper() {
const { t } = useTranslation();
@@ -127,7 +127,7 @@ function ChatWrapper() {
<FileProvider value={files} onChange={setFiles} />
<ChatInput
className={align ? "align" : ""}
ref={target}
target={target}
value={input}
onValueChange={setInput}
onEnterPressed={async () => await handleSend(auth, model, web)}
5 changes: 2 additions & 3 deletions app/src/components/home/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "@/store";
import { selectAuthenticated, selectUsername } from "@/store/auth.ts";
import { selectCurrent, selectHistory } from "@/store/chat.ts";
import { useRef, useState } from "react";
@@ -17,7 +16,7 @@ import {
updateConversationList,
} from "@/conversation/history.ts";
import { Button } from "@/components/ui/button.tsx";
import { setMenu } from "@/store/menu.ts";
import {selectMenu, setMenu} from "@/store/menu.ts";
import {
Copy,
Eraser,
@@ -340,7 +339,7 @@ function SidebarMenu() {
function SideBar() {
const { t } = useTranslation();
const dispatch = useDispatch();
const open = useSelector((state: RootState) => state.menu.open);
const open = useSelector(selectMenu);
const auth = useSelector(selectAuthenticated);
const [operateConversation, setOperateConversation] = useState<Operation>({
target: null,
Original file line number Diff line number Diff line change
@@ -5,15 +5,15 @@ import { useTranslation } from "react-i18next";

type ChatInputProps = {
className?: string;
ref?: React.RefObject<HTMLInputElement>;
target?: React.RefObject<HTMLInputElement>;
value: string;
onValueChange: (value: string) => void;
onEnterPressed: () => void;
};

function ChatInput({
className,
ref,
target,
value,
onValueChange,
onEnterPressed,
@@ -24,7 +24,7 @@ function ChatInput({
<Input
id={`input`}
className={`input-box ${className || ""}`}
ref={ref}
ref={target}
value={value}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
onValueChange(e.target.value);
2 changes: 1 addition & 1 deletion app/src/conf.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import {
} from "@/utils/env.ts";
import { getMemory } from "@/utils/memory.ts";

export const version = "3.6.13rc";
export const version = "3.6.13rc1";
export const dev: boolean = getDev();
export const deploy: boolean = true;
export let rest_api: string = getRestApi(deploy);
41 changes: 35 additions & 6 deletions app/src/router.tsx
Original file line number Diff line number Diff line change
@@ -2,9 +2,12 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Home from "./routes/Home.tsx";
import NotFound from "./routes/NotFound.tsx";
import Auth from "./routes/Auth.tsx";
import Generation from "./routes/Generation.tsx";
import Sharing from "./routes/Sharing.tsx";
import Article from "@/routes/Article.tsx";
import { lazy, Suspense } from "react";

const Generation = lazy(() => import("@/routes/Generation.tsx"));
const Sharing = lazy(() => import("@/routes/Sharing.tsx"));
const Article = lazy(() => import("@/routes/Article.tsx"));
const Admin = lazy(() => import("@/routes/Admin.tsx"));

const router = createBrowserRouter([
{
@@ -22,17 +25,43 @@ const router = createBrowserRouter([
{
id: "generation",
path: "/generate",
Component: Generation,
element: (
<Suspense>
<Generation />
</Suspense>
),
ErrorBoundary: NotFound,
},
{
id: "share",
path: "/share/:hash",
Component: Sharing,
element: (
<Suspense>
<Sharing />
</Suspense>
),
ErrorBoundary: NotFound,
},
{
id: "article",
path: "/article",
Component: Article,
element: (
<Suspense>
<Article />
</Suspense>
),
ErrorBoundary: NotFound,
},
{
id: "admin",
path: "/admin",
element: (
<Suspense>
<Admin />
</Suspense>
),
children: [],
ErrorBoundary: NotFound,
},
]);

12 changes: 12 additions & 0 deletions app/src/routes/Admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import "@/assets/admin/all.less";
import MenuBar from "@/components/admin/MenuBar.tsx";

function Admin() {
return (
<div className={`admin-page`}>
<MenuBar />
</div>
)
}

export default Admin;
2 changes: 2 additions & 0 deletions app/src/store/menu.ts
Original file line number Diff line number Diff line change
@@ -24,3 +24,5 @@ export const menuSlice = createSlice({

export const { toggleMenu, closeMenu, openMenu, setMenu } = menuSlice.actions;
export default menuSlice.reducer;

export const selectMenu = (state: any) => state.menu.open;

0 comments on commit 5c08d04

Please sign in to comment.