Browse Source

feat: close #2848 click drag icon to toggle sidebar width

Yidadaa 1 year ago
parent
commit
d713d01600
3 changed files with 54 additions and 29 deletions
  1. 46 27
      app/components/sidebar.tsx
  2. 1 0
      app/constant.ts
  3. 7 2
      app/store/config.ts

+ 46 - 27
app/components/sidebar.tsx

@@ -17,6 +17,7 @@ import Locale from "../locales";
 import { useAppConfig, useChatStore } from "../store";
 
 import {
+  DEFAULT_SIDEBAR_WIDTH,
   MAX_SIDEBAR_WIDTH,
   MIN_SIDEBAR_WIDTH,
   NARROW_SIDEBAR_WIDTH,
@@ -57,39 +58,57 @@ function useDragSideBar() {
 
   const config = useAppConfig();
   const startX = useRef(0);
-  const startDragWidth = useRef(config.sidebarWidth ?? 300);
+  const startDragWidth = useRef(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
   const lastUpdateTime = useRef(Date.now());
 
-  const handleMouseMove = useRef((e: MouseEvent) => {
-    if (Date.now() < lastUpdateTime.current + 50) {
-      return;
-    }
-    lastUpdateTime.current = Date.now();
-    const d = e.clientX - startX.current;
-    const nextWidth = limit(startDragWidth.current + d);
+  const toggleSideBar = () => {
     config.update((config) => {
-      if (nextWidth < MIN_SIDEBAR_WIDTH) {
-        config.sidebarWidth = NARROW_SIDEBAR_WIDTH;
+      if (config.sidebarWidth < MIN_SIDEBAR_WIDTH) {
+        config.sidebarWidth = DEFAULT_SIDEBAR_WIDTH;
       } else {
-        config.sidebarWidth = nextWidth;
+        config.sidebarWidth = NARROW_SIDEBAR_WIDTH;
       }
     });
-  });
-
-  const handleMouseUp = useRef(() => {
-    // In useRef the data is non-responsive, so `config.sidebarWidth` can't get the dynamic sidebarWidth
-    // startDragWidth.current = config.sidebarWidth ?? 300;
-    window.removeEventListener("mousemove", handleMouseMove.current);
-    window.removeEventListener("mouseup", handleMouseUp.current);
-  });
+  };
 
-  const onDragMouseDown = (e: MouseEvent) => {
-    startX.current = e.clientX;
+  const onDragStart = (e: MouseEvent) => {
     // Remembers the initial width each time the mouse is pressed
+    startX.current = e.clientX;
     startDragWidth.current = config.sidebarWidth;
-    window.addEventListener("mousemove", handleMouseMove.current);
-    window.addEventListener("mouseup", handleMouseUp.current);
+    const dragStartTime = Date.now();
+
+    const handleDragMove = (e: MouseEvent) => {
+      if (Date.now() < lastUpdateTime.current + 20) {
+        return;
+      }
+      lastUpdateTime.current = Date.now();
+      const d = e.clientX - startX.current;
+      const nextWidth = limit(startDragWidth.current + d);
+      config.update((config) => {
+        if (nextWidth < MIN_SIDEBAR_WIDTH) {
+          config.sidebarWidth = NARROW_SIDEBAR_WIDTH;
+        } else {
+          config.sidebarWidth = nextWidth;
+        }
+      });
+    };
+
+    const handleDragEnd = () => {
+      // In useRef the data is non-responsive, so `config.sidebarWidth` can't get the dynamic sidebarWidth
+      window.removeEventListener("pointermove", handleDragMove);
+      window.removeEventListener("pointerup", handleDragEnd);
+
+      // if user click the drag icon, should toggle the sidebar
+      const shouldFireClick = Date.now() - dragStartTime < 300;
+      if (shouldFireClick) {
+        toggleSideBar();
+      }
+    };
+
+    window.addEventListener("pointermove", handleDragMove);
+    window.addEventListener("pointerup", handleDragEnd);
   };
+
   const isMobileScreen = useMobileScreen();
   const shouldNarrow =
     !isMobileScreen && config.sidebarWidth < MIN_SIDEBAR_WIDTH;
@@ -97,13 +116,13 @@ function useDragSideBar() {
   useEffect(() => {
     const barWidth = shouldNarrow
       ? NARROW_SIDEBAR_WIDTH
-      : limit(config.sidebarWidth ?? 300);
+      : limit(config.sidebarWidth ?? DEFAULT_SIDEBAR_WIDTH);
     const sideBarWidth = isMobileScreen ? "100vw" : `${barWidth}px`;
     document.documentElement.style.setProperty("--sidebar-width", sideBarWidth);
   }, [config.sidebarWidth, isMobileScreen, shouldNarrow]);
 
   return {
-    onDragMouseDown,
+    onDragStart,
     shouldNarrow,
   };
 }
@@ -112,7 +131,7 @@ export function SideBar(props: { className?: string }) {
   const chatStore = useChatStore();
 
   // drag side bar
-  const { onDragMouseDown, shouldNarrow } = useDragSideBar();
+  const { onDragStart, shouldNarrow } = useDragSideBar();
   const navigate = useNavigate();
   const config = useAppConfig();
 
@@ -206,7 +225,7 @@ export function SideBar(props: { className?: string }) {
 
       <div
         className={styles["sidebar-drag"]}
-        onMouseDown={(e) => onDragMouseDown(e as any)}
+        onPointerDown={(e) => onDragStart(e as any)}
       >
         <DragIcon />
       </div>

+ 1 - 0
app/constant.ts

@@ -43,6 +43,7 @@ export enum StoreKey {
   Sync = "sync",
 }
 
+export const DEFAULT_SIDEBAR_WIDTH = 300;
 export const MAX_SIDEBAR_WIDTH = 500;
 export const MIN_SIDEBAR_WIDTH = 230;
 export const NARROW_SIDEBAR_WIDTH = 100;

+ 7 - 2
app/store/config.ts

@@ -1,6 +1,11 @@
 import { LLMModel } from "../client/api";
 import { getClientConfig } from "../config/client";
-import { DEFAULT_INPUT_TEMPLATE, DEFAULT_MODELS, StoreKey } from "../constant";
+import {
+  DEFAULT_INPUT_TEMPLATE,
+  DEFAULT_MODELS,
+  DEFAULT_SIDEBAR_WIDTH,
+  StoreKey,
+} from "../constant";
 import { createPersistStore } from "../utils/store";
 
 export type ModelType = (typeof DEFAULT_MODELS)[number]["name"];
@@ -29,7 +34,7 @@ export const DEFAULT_CONFIG = {
   tightBorder: !!getClientConfig()?.isApp,
   sendPreviewBubble: true,
   enableAutoGenerateTitle: true,
-  sidebarWidth: 300,
+  sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
 
   disablePromptHint: false,