From eccf674a4868c2aeebb25a8a8abe4c65cdbe5521 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Thu, 9 Nov 2023 22:36:43 +0700 Subject: [PATCH] Prepare streaming text by status message --- web/containers/Providers/EventHandler.tsx | 18 +++++++++-- web/helpers/atoms/ChatMessage.atom.ts | 12 ++++++- web/models/ChatMessage.ts | 2 +- web/screens/Chat/SimpleTextMessage/index.tsx | 13 +++----- web/styles/components/message.scss | 34 -------------------- 5 files changed, 33 insertions(+), 46 deletions(-) diff --git a/web/containers/Providers/EventHandler.tsx b/web/containers/Providers/EventHandler.tsx index 7b4f5b607..f3a603cbf 100644 --- a/web/containers/Providers/EventHandler.tsx +++ b/web/containers/Providers/EventHandler.tsx @@ -22,7 +22,7 @@ import { } from '@/helpers/atoms/Conversation.atom' import { downloadingModelsAtom } from '@/helpers/atoms/Model.atom' -import { toChatMessage } from '@/models/ChatMessage' +import { MessageStatus, toChatMessage } from '@/models/ChatMessage' import { pluginManager } from '@/plugin' let currentConversation: Conversation | undefined = undefined @@ -68,7 +68,8 @@ export default function EventHandler({ children }: { children: ReactNode }) { updateMessage( messageResponse._id, messageResponse.conversationId, - messageResponse.message + messageResponse.message, + MessageStatus.Pending ) } @@ -100,6 +101,19 @@ export default function EventHandler({ children }: { children: ReactNode }) { if (!messageResponse.conversationId || !convoRef.current) return updateConvWaiting(messageResponse.conversationId, false) + if ( + messageResponse.conversationId && + messageResponse._id && + messageResponse.message + ) { + updateMessage( + messageResponse._id, + messageResponse.conversationId, + messageResponse.message, + MessageStatus.Ready + ) + } + const convo = convoRef.current.find( (e) => e._id == messageResponse.conversationId ) diff --git a/web/helpers/atoms/ChatMessage.atom.ts b/web/helpers/atoms/ChatMessage.atom.ts index e463bc96a..079568a9a 100644 --- a/web/helpers/atoms/ChatMessage.atom.ts +++ b/web/helpers/atoms/ChatMessage.atom.ts @@ -2,6 +2,8 @@ import { atom } from 'jotai' import { getActiveConvoIdAtom } from './Conversation.atom' +import { MessageStatus } from '@/models/ChatMessage' + /** * Stores all chat messages for all conversations */ @@ -89,11 +91,19 @@ export const deleteConversationMessage = atom(null, (get, set, id: string) => { export const updateMessageAtom = atom( null, - (get, set, id: string, conversationId: string, text: string) => { + ( + get, + set, + id: string, + conversationId: string, + text: string, + status: MessageStatus + ) => { const messages = get(chatMessages)[conversationId] ?? [] const message = messages.find((e) => e.id === id) if (message) { message.text = text + message.status = status const updatedMessages = [...messages] const newData: Record = { diff --git a/web/models/ChatMessage.ts b/web/models/ChatMessage.ts index ade7a46e5..b7f18d932 100644 --- a/web/models/ChatMessage.ts +++ b/web/models/ChatMessage.ts @@ -79,6 +79,6 @@ export const toChatMessage = ( text: content, imageUrls: imageUrls, createdAt: createdAt, - status: m.message === '' ? MessageStatus.Pending : MessageStatus.Ready, + status: MessageStatus.Ready, } } diff --git a/web/screens/Chat/SimpleTextMessage/index.tsx b/web/screens/Chat/SimpleTextMessage/index.tsx index 7e3066a09..6b70c0bb9 100644 --- a/web/screens/Chat/SimpleTextMessage/index.tsx +++ b/web/screens/Chat/SimpleTextMessage/index.tsx @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import React, { Fragment } from 'react' +import React, { useState } from 'react' import hljs from 'highlight.js' @@ -10,7 +10,7 @@ import { markedHighlight } from 'marked-highlight' import { twMerge } from 'tailwind-merge' -// import Typewriter from 'typewriter-effect' +import Typewriter from 'typewriter-effect' import LogoMark from '@/containers/Brand/Logo/Mark' @@ -20,10 +20,6 @@ import { displayDate } from '@/utils/datetime' import { MessageSenderType, MessageStatus } from '@/models/ChatMessage' -// export const currentStreamingMessageAtom = atom( -// undefined -// ) - type Props = { avatarUrl: string senderName: string @@ -62,7 +58,8 @@ const SimpleTextMessage: React.FC = ({ senderName, senderType, createdAt, - status, + // will use status as streaming text + // status, text = '', }) => { const parsedText = marked.parse(text) @@ -87,7 +84,7 @@ const SimpleTextMessage: React.FC = ({ ) : ( <> diff --git a/web/styles/components/message.scss b/web/styles/components/message.scss index e6410db1a..2f7ab6aba 100644 --- a/web/styles/components/message.scss +++ b/web/styles/components/message.scss @@ -6,37 +6,3 @@ } @apply text-muted-foreground; } - -// .typewriter * { -// color: #fff; -// font-family: monospace; -// overflow: hidden; /* Ensures the content is not revealed until the animation */ -// border-right: 0.15em solid orange; /* The typwriter cursor */ -// white-space: nowrap; /* Keeps the content on a single line */ -// margin: 0 auto; /* Gives that scrolling effect as the typing happens */ -// letter-spacing: 0.15em; /* Adjust as needed */ -// animation: -// typing 3.5s steps(30, end), -// blink-caret 0.5s step-end infinite; -// } - -// /* The typing effect */ -// @keyframes typing { -// from { -// width: 0; -// } -// to { -// width: 100%; -// } -// } - -// /* The typewriter cursor effect */ -// @keyframes blink-caret { -// from, -// to { -// border-color: transparent; -// } -// 50% { -// border-color: orange; -// } -// }