forked from XiaoMo/ChatGPT-Next-Web
feat: #2 trying to add stop response button
This commit is contained in:
parent
99b88f36fd
commit
806e7b09c1
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 />
|
||||||
|
@ -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} 发送`,
|
||||||
|
@ -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) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user