fix: #522 resizable side bar
This commit is contained in:
parent
eae5a8a2e6
commit
6ae61c5357
@ -49,4 +49,7 @@
|
|||||||
.icon-button-text {
|
.icon-button-text {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,27 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-shadow: inset -2px 0px 2px 0px rgb(0, 0, 0, 0.05);
|
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 {
|
.window-content {
|
||||||
@ -177,10 +198,11 @@
|
|||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-item-count {
|
.chat-item-count,
|
||||||
}
|
|
||||||
|
|
||||||
.chat-item-date {
|
.chat-item-date {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-tail {
|
.sidebar-tail {
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
require("../polyfill");
|
require("../polyfill");
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import {
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useCallback,
|
||||||
|
MouseEventHandler,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
import styles from "./home.module.scss";
|
import styles from "./home.module.scss";
|
||||||
@ -24,6 +30,7 @@ import { Chat } from "./chat";
|
|||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { REPO_URL } from "../constant";
|
import { REPO_URL } from "../constant";
|
||||||
import { ErrorBoundary } from "./error";
|
import { ErrorBoundary } from "./error";
|
||||||
|
import { useDebounce } from "use-debounce";
|
||||||
|
|
||||||
export function Loading(props: { noLogo?: boolean }) {
|
export function Loading(props: { noLogo?: boolean }) {
|
||||||
return (
|
return (
|
||||||
@ -75,6 +82,49 @@ function useSwitchTheme() {
|
|||||||
}, [config.theme]);
|
}, [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 useHasHydrated = () => {
|
||||||
const [hasHydrated, setHasHydrated] = useState<boolean>(false);
|
const [hasHydrated, setHasHydrated] = useState<boolean>(false);
|
||||||
|
|
||||||
@ -101,6 +151,9 @@ function _Home() {
|
|||||||
const [openSettings, setOpenSettings] = useState(false);
|
const [openSettings, setOpenSettings] = useState(false);
|
||||||
const config = useChatStore((state) => state.config);
|
const config = useChatStore((state) => state.config);
|
||||||
|
|
||||||
|
// drag side bar
|
||||||
|
const { onDragMouseDown } = useDragSideBar();
|
||||||
|
|
||||||
useSwitchTheme();
|
useSwitchTheme();
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@ -174,6 +227,11 @@ function _Home() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={styles["sidebar-drag"]}
|
||||||
|
onMouseDown={(e) => onDragMouseDown(e as any)}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles["window-content"]}>
|
<div className={styles["window-content"]}>
|
||||||
|
@ -53,6 +53,7 @@ export interface ChatConfig {
|
|||||||
theme: Theme;
|
theme: Theme;
|
||||||
tightBorder: boolean;
|
tightBorder: boolean;
|
||||||
sendPreviewBubble: boolean;
|
sendPreviewBubble: boolean;
|
||||||
|
sidebarWidth: number;
|
||||||
|
|
||||||
disablePromptHint: boolean;
|
disablePromptHint: boolean;
|
||||||
|
|
||||||
@ -141,6 +142,7 @@ const DEFAULT_CONFIG: ChatConfig = {
|
|||||||
theme: Theme.Auto as Theme,
|
theme: Theme.Auto as Theme,
|
||||||
tightBorder: false,
|
tightBorder: false,
|
||||||
sendPreviewBubble: true,
|
sendPreviewBubble: true,
|
||||||
|
sidebarWidth: 300,
|
||||||
|
|
||||||
disablePromptHint: false,
|
disablePromptHint: false,
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user