feat: #2 trying to add stop response button

This commit is contained in:
Yifei Zhang 2023-03-23 17:42:38 +00:00
parent 99b88f36fd
commit 806e7b09c1
4 changed files with 75 additions and 4 deletions

View File

@ -237,6 +237,14 @@
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
animation: slide-in ease 0.3s; animation: slide-in ease 0.3s;
&:hover {
.chat-message-top-actions {
opacity: 1;
right: 10px;
pointer-events: all;
}
}
} }
.chat-message-user > .chat-message-container { .chat-message-user > .chat-message-container {
@ -276,6 +284,34 @@
user-select: text; user-select: text;
word-break: break-word; word-break: break-word;
border: var(--border-in-light); border: var(--border-in-light);
position: relative;
}
.chat-message-top-actions {
font-size: 12px;
position: absolute;
right: 20px;
top: -26px;
transition: all ease 0.3s;
opacity: 0;
pointer-events: none;
display: flex;
flex-direction: row-reverse;
.chat-message-top-action {
opacity: 0.5;
color: var(--black);
cursor: pointer;
&:hover {
opacity: 1;
}
&:not(:first-child) {
margin-right: 10px;
}
}
} }
.chat-message-user > .chat-message-container > .chat-message-item { .chat-message-user > .chat-message-container > .chat-message-item {
@ -288,10 +324,10 @@
width: 100%; width: 100%;
padding-top: 5px; padding-top: 5px;
box-sizing: border-box; box-sizing: border-box;
font-size: 12px;
} }
.chat-message-action-date { .chat-message-action-date {
font-size: 12px;
color: #aaa; color: #aaa;
} }

View File

@ -21,7 +21,7 @@ import CopyIcon from "../icons/copy.svg";
import DownloadIcon from "../icons/download.svg"; import DownloadIcon from "../icons/download.svg";
import { Message, SubmitKey, useChatStore, ChatSession } from "../store"; import { Message, SubmitKey, useChatStore, ChatSession } from "../store";
import { showModal } from "./ui-lib"; import { showModal, showToast } from "./ui-lib";
import { copyToClipboard, downloadAs, isIOS, selectOrCopy } from "../utils"; import { copyToClipboard, downloadAs, isIOS, selectOrCopy } from "../utils";
import Locale from "../locales"; import Locale from "../locales";
@ -166,6 +166,8 @@ export function Chat(props: { showSideBar?: () => void }) {
}; };
const latestMessageRef = useRef<HTMLDivElement>(null); const latestMessageRef = useRef<HTMLDivElement>(null);
const [hoveringMessage, setHoveringMessage] = useState(false);
const messages = (session.messages as RenderMessage[]) const messages = (session.messages as RenderMessage[])
.concat( .concat(
isLoading isLoading
@ -195,7 +197,7 @@ export function Chat(props: { showSideBar?: () => void }) {
useLayoutEffect(() => { useLayoutEffect(() => {
setTimeout(() => { setTimeout(() => {
const dom = latestMessageRef.current; const dom = latestMessageRef.current;
if (dom && !isIOS()) { if (dom && !isIOS() && !hoveringMessage) {
dom.scrollIntoView({ dom.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "end", block: "end",
@ -250,7 +252,15 @@ export function Chat(props: { showSideBar?: () => void }) {
</div> </div>
</div> </div>
<div className={styles["chat-body"]}> <div
className={styles["chat-body"]}
onMouseOver={() => {
setHoveringMessage(true);
}}
onMouseOut={() => {
setHoveringMessage(false);
}}
>
{messages.map((message, i) => { {messages.map((message, i) => {
const isUser = message.role === "user"; const isUser = message.role === "user";
@ -271,6 +281,25 @@ export function Chat(props: { showSideBar?: () => void }) {
</div> </div>
)} )}
<div className={styles["chat-message-item"]}> <div className={styles["chat-message-item"]}>
{!isUser && (
<div className={styles["chat-message-top-actions"]}>
{message.streaming && (
<div
className={styles["chat-message-top-action"]}
onClick={() => showToast(Locale.WIP)}
>
{Locale.Chat.Actions.Stop}
</div>
)}
<div
className={styles["chat-message-top-action"]}
onClick={() => copyToClipboard(message.content)}
>
{Locale.Chat.Actions.Copy}
</div>
</div>
)}
{(message.preview || message.content.length === 0) && {(message.preview || message.content.length === 0) &&
!isUser ? ( !isUser ? (
<LoadingIcon /> <LoadingIcon />

View File

@ -1,4 +1,5 @@
const cn = { const cn = {
WIP: "该功能仍在开发中……",
ChatItem: { ChatItem: {
ChatItemCount: (count: number) => `${count} 条对话`, ChatItemCount: (count: number) => `${count} 条对话`,
}, },
@ -8,6 +9,8 @@ const cn = {
ChatList: "查看消息列表", ChatList: "查看消息列表",
CompressedHistory: "查看压缩后的历史 Prompt", CompressedHistory: "查看压缩后的历史 Prompt",
Export: "导出聊天记录", Export: "导出聊天记录",
Copy: "复制",
Stop: "停止",
}, },
Typing: "正在输入…", Typing: "正在输入…",
Input: (submitKey: string) => `输入消息,${submitKey} 发送`, Input: (submitKey: string) => `输入消息,${submitKey} 发送`,

View File

@ -1,6 +1,7 @@
import type { LocaleType } from "./index"; import type { LocaleType } from "./index";
const en: LocaleType = { const en: LocaleType = {
WIP: "WIP...",
ChatItem: { ChatItem: {
ChatItemCount: (count: number) => `${count} messages`, ChatItemCount: (count: number) => `${count} messages`,
}, },
@ -10,6 +11,8 @@ const en: LocaleType = {
ChatList: "Go To Chat List", ChatList: "Go To Chat List",
CompressedHistory: "Compressed History Memory Prompt", CompressedHistory: "Compressed History Memory Prompt",
Export: "Export All Messages as Markdown", Export: "Export All Messages as Markdown",
Copy: "Copy",
Stop: "Stop",
}, },
Typing: "Typing…", Typing: "Typing…",
Input: (submitKey: string) => Input: (submitKey: string) =>