mirror of
				https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
				synced 2025-11-04 08:13:43 +08:00 
			
		
		
		
	feat: #2 trying to add stop response button
This commit is contained in:
		@@ -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) =>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user