diff --git a/app/components/button.tsx b/app/components/button.tsx
index f40a4e8f..2e5707ae 100644
--- a/app/components/button.tsx
+++ b/app/components/button.tsx
@@ -8,6 +8,7 @@ export function IconButton(props: {
text?: string;
bordered?: boolean;
shadow?: boolean;
+ noDark?: boolean;
className?: string;
title?: string;
}) {
@@ -23,7 +24,11 @@ export function IconButton(props: {
title={props.title}
role="button"
>
-
{props.icon}
+
+ {props.icon}
+
{props.text && (
{props.text}
)}
diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss
index b52baa12..5216fb25 100644
--- a/app/components/chat.module.scss
+++ b/app/components/chat.module.scss
@@ -1,3 +1,5 @@
+@import "../styles/animation.scss";
+
.prompt-toast {
position: absolute;
bottom: -50px;
@@ -19,6 +21,8 @@
padding: 10px 20px;
border-radius: 100px;
+ animation: slide-in-from-top ease 0.3s;
+
.prompt-toast-content {
margin-left: 10px;
}
diff --git a/app/components/chat.tsx b/app/components/chat.tsx
index 4a80fe14..b35cd3eb 100644
--- a/app/components/chat.tsx
+++ b/app/components/chat.tsx
@@ -51,7 +51,7 @@ const Emoji = dynamic(async () => (await import("emoji-picker-react")).Emoji, {
export function Avatar(props: { role: Message["role"] }) {
const config = useChatStore((state) => state.config);
- if (props.role === "assistant") {
+ if (props.role !== "user") {
return ;
}
@@ -99,7 +99,8 @@ function exportMessages(messages: Message[], topic: string) {
}
function PromptToast(props: {
- showModal: boolean;
+ showToast?: boolean;
+ showModal?: boolean;
setShowModal: (_: boolean) => void;
}) {
const chatStore = useChatStore();
@@ -126,16 +127,18 @@ function PromptToast(props: {
return (
-
props.setShowModal(true)}
- >
-
-
- {Locale.Context.Toast(context.length)}
-
-
+ {props.showToast && (
+
props.setShowModal(true)}
+ >
+
+
+ {Locale.Context.Toast(context.length)}
+
+
+ )}
{props.showModal && (
}
className={chatStyle["context-delete-button"]}
onClick={() => removeContextPrompt(i)}
+ bordered
/>
))}
@@ -281,7 +285,7 @@ function useScrollToBottom() {
useLayoutEffect(() => {
const dom = scrollRef.current;
if (dom && autoScroll) {
- setTimeout(() => (dom.scrollTop = dom.scrollHeight), 500);
+ setTimeout(() => (dom.scrollTop = dom.scrollHeight), 1);
}
});
@@ -310,6 +314,12 @@ export function Chat(props: {
const [isLoading, setIsLoading] = useState(false);
const { submitKey, shouldSubmit } = useSubmitHandler();
const { scrollRef, setAutoScroll } = useScrollToBottom();
+ const [hitBottom, setHitBottom] = useState(false);
+
+ const onChatBodyScroll = (e: HTMLElement) => {
+ const isTouchBottom = e.scrollTop + e.clientHeight >= e.scrollHeight - 20;
+ setHitBottom(isTouchBottom);
+ };
// prompt hints
const promptStore = usePromptStore();
@@ -505,12 +515,17 @@ export function Chat(props: {
-
+
onChatBodyScroll(e.currentTarget)}
+ >
{messages.map((message, i) => {
const isUser = message.role === "user";
@@ -612,7 +627,8 @@ export function Chat(props: {
}
text={Locale.Chat.Send}
- className={styles["chat-input-send"] + " no-dark"}
+ className={styles["chat-input-send"]}
+ noDark
onClick={onUserSubmit}
/>
diff --git a/app/components/home.module.scss b/app/components/home.module.scss
index 24b1f1bf..95964ae1 100644
--- a/app/components/home.module.scss
+++ b/app/components/home.module.scss
@@ -1,4 +1,5 @@
@import "./window.scss";
+@import "../styles/animation.scss";
@mixin container {
background-color: var(--white);
@@ -73,7 +74,7 @@
.sidebar {
position: absolute;
left: -100%;
- z-index: 999;
+ z-index: 1000;
height: var(--full-height);
transition: all ease 0.3s;
box-shadow: none;
@@ -132,18 +133,6 @@
overflow: hidden;
}
-@keyframes slide-in {
- from {
- opacity: 0;
- transform: translateY(20px);
- }
-
- to {
- opacity: 1;
- transform: translateY(0px);
- }
-}
-
.chat-item:hover {
background-color: var(--hover-color);
}
diff --git a/app/components/ui-lib.module.scss b/app/components/ui-lib.module.scss
index 5c7925b0..4aa83662 100644
--- a/app/components/ui-lib.module.scss
+++ b/app/components/ui-lib.module.scss
@@ -1,3 +1,5 @@
+@import "../styles/animation.scss";
+
.card {
background-color: var(--white);
border-radius: 10px;
@@ -24,18 +26,6 @@
height: 100vh;
}
-@keyframes slide-in {
- from {
- transform: translateY(10px);
- opacity: 0;
- }
-
- to {
- transform: translateY(0);
- opacity: 1;
- }
-}
-
.list-item {
display: flex;
justify-content: space-between;
diff --git a/app/locales/cn.ts b/app/locales/cn.ts
index 2feed51a..a0e1da7a 100644
--- a/app/locales/cn.ts
+++ b/app/locales/cn.ts
@@ -35,7 +35,7 @@ const cn = {
Download: "下载文件",
},
Memory: {
- Title: "上下文记忆 Prompt",
+ Title: "历史记忆",
EmptyContent: "尚未记忆",
Copy: "全部复制",
},
diff --git a/app/styles/animation.scss b/app/styles/animation.scss
new file mode 100644
index 00000000..b423b08a
--- /dev/null
+++ b/app/styles/animation.scss
@@ -0,0 +1,23 @@
+@keyframes slide-in {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0px);
+ }
+}
+
+@keyframes slide-in-from-top {
+ from {
+ opacity: 0;
+ transform: translateY(-20px);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0px);
+ }
+}