diff --git a/README.md b/README.md index cba9d35f..1ca37656 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,10 @@ bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/s ![More](./docs/images/more.png) +## Translation + +If you want to add a new translation, read this [document](./docs/translation.md). + ## Donation [Buy Me a Coffee](https://www.buymeacoffee.com/yidadaa) diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss index fa3a1cf2..99b2d022 100644 --- a/app/components/chat.module.scss +++ b/app/components/chat.module.scss @@ -240,24 +240,39 @@ &:last-child { animation: slide-in ease 0.3s; } - - &:hover { - .chat-message-actions { - opacity: 1; - transform: translateY(0px); - max-width: 100%; - height: 40px; - } - - .chat-message-action-date { - opacity: 0.2; - } - } } .chat-message-user { display: flex; flex-direction: row-reverse; + + .chat-message-header { + flex-direction: row-reverse; + } +} + +.chat-message-header { + margin-top: 20px; + display: flex; + align-items: center; + + .chat-message-actions { + display: flex; + box-sizing: border-box; + font-size: 12px; + align-items: flex-end; + justify-content: space-between; + transition: all ease 0.3s; + transform: scale(0.9) translateY(5px); + margin: 0 10px; + opacity: 0; + pointer-events: none; + + .chat-input-actions { + display: flex; + flex-wrap: nowrap; + } + } } .chat-message-container { @@ -270,6 +285,12 @@ .chat-message-edit { opacity: 0.9; } + + .chat-message-actions { + opacity: 1; + pointer-events: all; + transform: scale(1) translateY(0); + } } } @@ -278,7 +299,6 @@ } .chat-message-avatar { - margin-top: 20px; position: relative; .chat-message-edit { @@ -318,27 +338,6 @@ border: var(--border-in-light); position: relative; transition: all ease 0.3s; - - .chat-message-actions { - display: flex; - box-sizing: border-box; - font-size: 12px; - align-items: flex-end; - justify-content: space-between; - transition: all ease 0.3s 0.15s; - transform: translateX(-5px) scale(0.9) translateY(30px); - opacity: 0; - height: 0; - max-width: 0; - position: absolute; - left: 0; - z-index: 2; - - .chat-input-actions { - display: flex; - flex-wrap: nowrap; - } - } } .chat-message-action-date { diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 13105e84..02c0dd92 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -708,49 +708,46 @@ export function Chat() { let lastUserMessageIndex: number | null = null; for (let i = 0; i < session.messages.length; i += 1) { const message = session.messages[i]; - if (message.id === messageId) { - break; - } if (message.role === "user") { lastUserMessageIndex = i; } + if (message.id === messageId) { + break; + } } return lastUserMessageIndex; }; - const deleteMessage = (userIndex: number) => { - chatStore.updateCurrentSession((session) => - session.messages.splice(userIndex, 2), + const deleteMessage = (msgId?: number) => { + chatStore.updateCurrentSession( + (session) => + (session.messages = session.messages.filter((m) => m.id !== msgId)), ); }; - const onDelete = (botMessageId: number) => { - const userIndex = findLastUserIndex(botMessageId); - if (userIndex === null) return; - deleteMessage(userIndex); + const onDelete = (msgId: number) => { + deleteMessage(msgId); }; - const onResend = (botMessageId: number) => { - // find last user input message and resend - const userIndex = findLastUserIndex(botMessageId); - if (userIndex === null) return; + const onResend = (message: ChatMessage) => { + let content = message.content; + + if (message.role === "assistant" && message.id) { + const userIndex = findLastUserIndex(message.id); + if (userIndex) { + content = session.messages.at(userIndex)?.content ?? content; + } + } setIsLoading(true); - const content = session.messages[userIndex].content; - deleteMessage(userIndex); chatStore.onUserInput(content).then(() => setIsLoading(false)); inputRef.current?.focus(); }; - const onPinMessage = (botMessage: ChatMessage) => { - if (!botMessage.id) return; - const userMessageIndex = findLastUserIndex(botMessage.id); - if (userMessageIndex === null) return; - - const userMessage = session.messages[userMessageIndex]; + const onPinMessage = (message: ChatMessage) => { chatStore.updateCurrentSession((session) => - session.mask.context.push(userMessage, botMessage), + session.mask.context.push(message), ); showToast(Locale.Chat.Actions.PinToastContent, { @@ -923,11 +920,11 @@ export function Chat() { > {messages.map((message, i) => { const isUser = message.role === "user"; + const isContext = i < context.length; const showActions = - !isUser && i > 0 && !(message.preview || message.content.length === 0) && - i >= context.length; // do not show actions for context prompts + !isContext; const showTyping = message.preview || message.streaming; const shouldShowClearContextDivider = i === clearContextIndex - 1; @@ -941,64 +938,38 @@ export function Chat() { } >