From 6ae61c5357644675e162b4a2c2d90b53c58b91a8 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Mon, 10 Apr 2023 00:54:17 +0800 Subject: [PATCH] fix: #522 resizable side bar --- app/components/button.module.scss | 3 ++ app/components/home.module.scss | 28 +++++++++++++-- app/components/home.tsx | 60 ++++++++++++++++++++++++++++++- app/store/app.ts | 2 ++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/app/components/button.module.scss b/app/components/button.module.scss index e7d5d894..3a3393e7 100644 --- a/app/components/button.module.scss +++ b/app/components/button.module.scss @@ -49,4 +49,7 @@ .icon-button-text { margin-left: 5px; font-size: 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } diff --git a/app/components/home.module.scss b/app/components/home.module.scss index 6be5c67f..c0c9ef14 100644 --- a/app/components/home.module.scss +++ b/app/components/home.module.scss @@ -48,6 +48,27 @@ display: flex; flex-direction: column; box-shadow: inset -2px 0px 2px 0px rgb(0, 0, 0, 0.05); + position: relative; + transition: width ease 0.1s; +} + +.sidebar-drag { + $width: 10px; + + position: absolute; + top: 0; + right: 0; + height: 100%; + width: $width; + background-color: var(--black); + cursor: ew-resize; + opacity: 0; + transition: all ease 0.3s; + + &:hover, + &:active { + opacity: 0.2; + } } .window-content { @@ -177,10 +198,11 @@ margin-top: 8px; } -.chat-item-count { -} - +.chat-item-count, .chat-item-date { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .sidebar-tail { diff --git a/app/components/home.tsx b/app/components/home.tsx index b6a2161d..6e2eeae3 100644 --- a/app/components/home.tsx +++ b/app/components/home.tsx @@ -2,7 +2,13 @@ require("../polyfill"); -import { useState, useEffect } from "react"; +import { + useState, + useEffect, + useRef, + useCallback, + MouseEventHandler, +} from "react"; import { IconButton } from "./button"; import styles from "./home.module.scss"; @@ -24,6 +30,7 @@ import { Chat } from "./chat"; import dynamic from "next/dynamic"; import { REPO_URL } from "../constant"; import { ErrorBoundary } from "./error"; +import { useDebounce } from "use-debounce"; export function Loading(props: { noLogo?: boolean }) { return ( @@ -75,6 +82,49 @@ function useSwitchTheme() { }, [config.theme]); } +function useDragSideBar() { + const limit = (x: number) => Math.min(500, Math.max(220, x)); + + const chatStore = useChatStore(); + const startX = useRef(0); + const startDragWidth = useRef(chatStore.config.sidebarWidth ?? 300); + const lastUpdateTime = useRef(Date.now()); + + const handleMouseMove = useRef((e: MouseEvent) => { + if (Date.now() < lastUpdateTime.current + 100) { + return; + } + lastUpdateTime.current = Date.now(); + const d = e.clientX - startX.current; + const nextWidth = limit(startDragWidth.current + d); + chatStore.updateConfig((config) => (config.sidebarWidth = nextWidth)); + }); + + const handleMouseUp = useRef(() => { + startDragWidth.current = chatStore.config.sidebarWidth ?? 300; + window.removeEventListener("mousemove", handleMouseMove.current); + window.removeEventListener("mouseup", handleMouseUp.current); + }); + + const onDragMouseDown = (e: MouseEvent) => { + startX.current = e.clientX; + + window.addEventListener("mousemove", handleMouseMove.current); + window.addEventListener("mouseup", handleMouseUp.current); + }; + + useEffect(() => { + document.documentElement.style.setProperty( + "--sidebar-width", + `${limit(chatStore.config.sidebarWidth ?? 300)}px`, + ); + }, [chatStore.config.sidebarWidth]); + + return { + onDragMouseDown, + }; +} + const useHasHydrated = () => { const [hasHydrated, setHasHydrated] = useState(false); @@ -101,6 +151,9 @@ function _Home() { const [openSettings, setOpenSettings] = useState(false); const config = useChatStore((state) => state.config); + // drag side bar + const { onDragMouseDown } = useDragSideBar(); + useSwitchTheme(); if (loading) { @@ -174,6 +227,11 @@ function _Home() { /> + +
onDragMouseDown(e as any)} + >
diff --git a/app/store/app.ts b/app/store/app.ts index f35ca82a..81366890 100644 --- a/app/store/app.ts +++ b/app/store/app.ts @@ -53,6 +53,7 @@ export interface ChatConfig { theme: Theme; tightBorder: boolean; sendPreviewBubble: boolean; + sidebarWidth: number; disablePromptHint: boolean; @@ -141,6 +142,7 @@ const DEFAULT_CONFIG: ChatConfig = { theme: Theme.Auto as Theme, tightBorder: false, sendPreviewBubble: true, + sidebarWidth: 300, disablePromptHint: false,