diff --git a/app/components/button.module.scss b/app/components/button.module.scss
index e7d5d89..3a3393e 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/chat-list.tsx b/app/components/chat-list.tsx
index ab5d849..cab8812 100644
--- a/app/components/chat-list.tsx
+++ b/app/components/chat-list.tsx
@@ -96,7 +96,7 @@ export function ChatList() {
index={i}
selected={i === selectedIndex}
onClick={() => selectSession(i)}
- onDelete={chatStore.deleteSession}
+ onDelete={() => chatStore.deleteSession(i)}
/>
))}
{provided.placeholder}
diff --git a/app/components/chat.tsx b/app/components/chat.tsx
index c5c257e..d25deec 100644
--- a/app/components/chat.tsx
+++ b/app/components/chat.tsx
@@ -3,7 +3,7 @@ import { memo, useState, useRef, useEffect, useLayoutEffect } from "react";
import SendWhiteIcon from "../icons/send-white.svg";
import BrainIcon from "../icons/brain.svg";
-import ExportIcon from "../icons/export.svg";
+import ExportIcon from "../icons/share.svg";
import ReturnIcon from "../icons/return.svg";
import CopyIcon from "../icons/copy.svg";
import DownloadIcon from "../icons/download.svg";
@@ -11,6 +11,8 @@ import LoadingIcon from "../icons/three-dots.svg";
import BotIcon from "../icons/bot.svg";
import AddIcon from "../icons/add.svg";
import DeleteIcon from "../icons/delete.svg";
+import MaxIcon from "../icons/max.svg";
+import MinIcon from "../icons/min.svg";
import {
Message,
@@ -19,6 +21,7 @@ import {
BOT_HELLO,
ROLES,
createMessage,
+ useAccessStore,
} from "../store";
import {
@@ -485,11 +488,17 @@ export function Chat(props: {
const context: RenderMessage[] = session.context.slice();
+ const accessStore = useAccessStore();
+
if (
context.length === 0 &&
session.messages.at(0)?.content !== BOT_HELLO.content
) {
- context.push(BOT_HELLO);
+ const copiedHello = Object.assign({}, BOT_HELLO);
+ if (!accessStore.isAuthorized()) {
+ copiedHello.content = Locale.Error.Unauthorized;
+ }
+ context.push(copiedHello);
}
// preview messages
@@ -584,6 +593,17 @@ export function Chat(props: {
}}
/>
+
+ : }
+ bordered
+ onClick={() => {
+ chatStore.updateConfig(
+ (config) => (config.tightBorder = !config.tightBorder),
+ );
+ }}
+ />
+
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/components/settings.module.scss b/app/components/settings.module.scss
index 7d40d83..830e1ba 100644
--- a/app/components/settings.module.scss
+++ b/app/components/settings.module.scss
@@ -19,11 +19,16 @@
cursor: pointer;
}
-.password-input {
+.password-input-container {
+ max-width: 50%;
display: flex;
justify-content: flex-end;
.password-eye {
margin-right: 4px;
}
+
+ .password-input {
+ min-width: 80%;
+ }
}
diff --git a/app/components/settings.tsx b/app/components/settings.tsx
index 0d1c1d0..bbb28b4 100644
--- a/app/components/settings.tsx
+++ b/app/components/settings.tsx
@@ -60,13 +60,17 @@ function PasswordInput(props: HTMLProps
) {
}
return (
-
+
: }
onClick={changeVisibility}
className={styles["password-eye"]}
/>
-
+
);
}
@@ -120,8 +124,7 @@ export function Settings(props: { closeSettings: () => void }) {
const builtinCount = SearchService.count.builtin;
const customCount = promptStore.prompts.size ?? 0;
- const showUsage = !!accessStore.token || !!accessStore.accessCode;
-
+ const showUsage = accessStore.isAuthorized();
useEffect(() => {
checkUpdate();
showUsage && checkUsage();
@@ -342,37 +345,7 @@ export function Settings(props: { closeSettings: () => void }) {
>
-
-
-
- updateConfig(
- (config) =>
- (config.disablePromptHint = e.currentTarget.checked),
- )
- }
- >
-
-
- }
- text={Locale.Settings.Prompt.Edit}
- onClick={() => showToast(Locale.WIP)}
- />
-
-
{enabledAccessControl ? (
void }) {
+
+
+
+ updateConfig(
+ (config) =>
+ (config.disablePromptHint = e.currentTarget.checked),
+ )
+ }
+ >
+
+
+
+ }
+ text={Locale.Settings.Prompt.Edit}
+ onClick={() => showToast(Locale.WIP)}
+ />
+
+
+