diff --git a/packages/react/src/components/ChatInput/ChatInput.js b/packages/react/src/components/ChatInput/ChatInput.js index 18416d792..b64699512 100644 --- a/packages/react/src/components/ChatInput/ChatInput.js +++ b/packages/react/src/components/ChatInput/ChatInput.js @@ -28,6 +28,7 @@ import { useToastBarDispatch } from '../../hooks/useToastBarDispatch'; import { Modal } from '../Modal'; import useSettingsStore from '../../store/settingsStore'; import ChatInfo from '../ChatInfo/ChatInfo'; +import QuoteMessage from '../QuoteMessage/QuoteMessage'; const editingMessageCss = css` background-color: #fff8e0; @@ -103,6 +104,8 @@ const ChatInput = ({ scrollToBottom }) => { const { editMessage, setEditMessage, + quoteMessage, + setQuoteMessage, isRecordingMessage, upsertMessage, replaceMessage, @@ -110,6 +113,8 @@ const ChatInput = ({ scrollToBottom }) => { } = useMessageStore((state) => ({ editMessage: state.editMessage, setEditMessage: state.setEditMessage, + quoteMessage: state.quoteMessage, + setQuoteMessage: state.setQuoteMessage, isRecordingMessage: state.isRecordingMessage, upsertMessage: state.upsertMessage, replaceMessage: state.replaceMessage, @@ -157,6 +162,12 @@ const ChatInput = ({ scrollToBottom }) => { } }; + const getMessageLink = async (id) => { + const host = await RCInstance.getHost(); + const res = await RCInstance.channelInfo(); + return `${host}/channel/${res.room.name}/?msg=${id}`; + }; + const sendMessage = async (isAttachmentMode = false) => { messageRef.current.focus(); messageRef.current.style.height = '44px'; @@ -183,7 +194,7 @@ const ChatInput = ({ scrollToBottom }) => { if (!message.length || !isUserAuthenticated) { messageRef.current.value = ''; - if (editMessage.msg) { + if (editMessage.msg || editMessage.attachments) { setEditMessage({}); } return; @@ -202,9 +213,19 @@ const ChatInput = ({ scrollToBottom }) => { return; } } - messageRef.current.value = ''; - const pendingMessage = createPendingMessage(message, user); + let pendingMessage = ''; + if (quoteMessage.msg || quoteMessage.attachments) { + const msgLink = await getMessageLink(quoteMessage?._id); + pendingMessage = createPendingMessage( + `[ ](${msgLink})\n ${message}`, + user + ); + setQuoteMessage({}); + } else { + pendingMessage = createPendingMessage(message, user); + } + if (ECOptions.enableThreads && threadId) { pendingMessage.tmid = threadId; } @@ -439,7 +460,10 @@ const ChatInput = ({ scrollToBottom }) => { } else { e.target.style.height = '150px'; } - } else if (editMessage.msg && e.keyCode === 27) { + } else if ( + (editMessage.msg || editMessage.attachments) && + e.keyCode === 27 + ) { messageRef.current.value = ''; setDisableButton(true); setEditMessage({}); @@ -490,6 +514,9 @@ const ChatInput = ({ scrollToBottom }) => { return ( + {(quoteMessage.msg || quoteMessage.attachments) && ( + + )} ( + + + +); + +export default Quote; diff --git a/packages/react/src/components/Icon/icons/index.js b/packages/react/src/components/Icon/icons/index.js index 4205df6f2..afd5b2f33 100644 --- a/packages/react/src/components/Icon/icons/index.js +++ b/packages/react/src/components/Icon/icons/index.js @@ -52,6 +52,7 @@ import Online from './Online'; import Offline from './Offline'; import Away from './Away'; import Busy from './Busy'; +import Quote from './Quote'; const icons = { file: File, @@ -108,6 +109,7 @@ const icons = { offline: Offline, away: Away, busy: Busy, + quote: Quote, }; export default icons; diff --git a/packages/react/src/components/Message/Message.js b/packages/react/src/components/Message/Message.js index 5cc9ebe3f..01578549d 100644 --- a/packages/react/src/components/Message/Message.js +++ b/packages/react/src/components/Message/Message.js @@ -72,6 +72,9 @@ const Message = ({ editMessage: state.editMessage, setEditMessage: state.setEditMessage, })); + + const setQuoteMessage = useMessageStore((state) => state.setQuoteMessage); + const openThread = useMessageStore((state) => state.openThread); const handleStarMessage = async (msg) => { @@ -248,6 +251,7 @@ const Message = ({ setEditMessage(message); } }} + handleQuoteMessage={() => setQuoteMessage(message)} handleEmojiClick={handleEmojiClick} handlerReportMessage={() => { setMessageToReport(message._id); diff --git a/packages/react/src/components/Message/MessageToolbox.js b/packages/react/src/components/Message/MessageToolbox.js index 0e45bb379..3292e963e 100644 --- a/packages/react/src/components/Message/MessageToolbox.js +++ b/packages/react/src/components/Message/MessageToolbox.js @@ -58,6 +58,7 @@ export const MessageToolbox = ({ handleDeleteMessage, handlerReportMessage, handleEditMessage, + handleQuoteMessage, isEditing = false, ...props }) => { @@ -98,6 +99,16 @@ export const MessageToolbox = ({ /> ) : null} + + + handleQuoteMessage(message)} + /> + + { + const { RCInstance } = useContext(RCContext); + const getUserAvatarUrl = (username) => { + const host = RCInstance.getHost(); + const URL = `${host}/avatar/${username}`; + return URL; + }; + const setQuoteMessage = useMessageStore((state) => state.setQuoteMessage); + + const { classNames, styleOverrides } = useComponentOverrides('QuoteMessage'); + return ( + + + setQuoteMessage({})} size="small"> + + + + + + {message?.u.username} + {format(new Date(message.ts), 'h:mm a')} + + + {message.msg + ? message.msg + : `${message.file?.name} (${ + message.file?.size ? (message.file.size / 1024).toFixed(2) : 0 + } kB)`} + + + ); +}; + +export default QuoteMessage; diff --git a/packages/react/src/store/messageStore.js b/packages/react/src/store/messageStore.js index 092c2c692..d607e0825 100644 --- a/packages/react/src/store/messageStore.js +++ b/packages/react/src/store/messageStore.js @@ -7,6 +7,7 @@ const useMessageStore = create((set, get) => ({ threadMessages: [], filtered: false, editMessage: {}, + quoteMessage: {}, messageToReport: NaN, showReportMessage: false, isRecordingMessage: false, @@ -65,6 +66,7 @@ const useMessageStore = create((set, get) => ({ } }, setEditMessage: (editMessage) => set(() => ({ editMessage })), + setQuoteMessage: (quoteMessage) => set(() => ({ quoteMessage })), setMessageToReport: (messageId) => set(() => ({ messageToReport: messageId })), toggleShowReportMessage: () => { diff --git a/packages/react/tools/icons-generator.js b/packages/react/tools/icons-generator.js index b0ee9b6b7..c6c415703 100644 --- a/packages/react/tools/icons-generator.js +++ b/packages/react/tools/icons-generator.js @@ -43,6 +43,7 @@ const iconsList = [ 'chevron-left', 'key', 'attachment', + 'quote', ]; const svgDirPath = path.join( __dirname,