diff --git a/web/components/chat/ChatTextField/ChatTextField.tsx b/web/components/chat/ChatTextField/ChatTextField.tsx index b8fd46b34..aa443cfd9 100644 --- a/web/components/chat/ChatTextField/ChatTextField.tsx +++ b/web/components/chat/ChatTextField/ChatTextField.tsx @@ -1,10 +1,12 @@ import { SmileOutlined } from '@ant-design/icons'; import { Button, Input } from 'antd'; -import { useRef, useState } from 'react'; +import React, { useRef, useState } from 'react'; import { useRecoilValue } from 'recoil'; import ContentEditable from 'react-contenteditable'; import WebsocketService from '../../../services/websocket-service'; import { websocketServiceAtom } from '../../stores/ClientConfigStore'; +import { getCaretPosition, convertToText, convertOnPaste } from '../chat'; +import { MessageType } from '../../../interfaces/socket-events'; import s from './ChatTextField.module.scss'; interface Props { @@ -22,8 +24,27 @@ export default function ChatTextField(props: Props) { // large is 40px const size = 'small'; + const sendMessage = () => { + if (!websocketService) { + console.log('websocketService is not defined'); + return; + } + + const message = convertToText(value); + websocketService.send({ type: MessageType.CHAT, body: message }); + setValue(''); + }; + const handleChange = evt => { text.current = evt.target.value; + setValue(evt.target.value); + }; + + const handleKeyDown = event => { + const key = event && event.key; + + if (key === 'Enter') { + } }; return ( @@ -33,11 +54,14 @@ export default function ChatTextField(props: Props) { style={{ width: '60%', maxHeight: '50px', padding: '5px' }} html={text.current} onChange={handleChange} + onKeyDown={e => { + handleKeyDown(e); + }} /> - diff --git a/webroot/js/utils/chat.js b/web/components/chat/chat.js similarity index 78% rename from webroot/js/utils/chat.js rename to web/components/chat/chat.js index d793803cb..a1fd14e8a 100644 --- a/webroot/js/utils/chat.js +++ b/web/components/chat/chat.js @@ -1,8 +1,8 @@ -import { - CHAT_INITIAL_PLACEHOLDER_TEXT, - CHAT_PLACEHOLDER_TEXT, - CHAT_PLACEHOLDER_OFFLINE, -} from './constants.js'; +// import { +// CHAT_INITIAL_PLACEHOLDER_TEXT, +// CHAT_PLACEHOLDER_TEXT, +// CHAT_PLACEHOLDER_OFFLINE, +// } from './constants.js'; // Taken from https://stackoverflow.com/a/46902361 export function getCaretPosition(node) { @@ -26,8 +26,8 @@ export function getCaretPosition(node) { // Might not need this anymore // Pieced together from parts of https://stackoverflow.com/questions/6249095/how-to-set-caretcursor-position-in-contenteditable-element-div export function setCaretPosition(editableDiv, position) { - var range = document.createRange(); - var sel = window.getSelection(); + const range = document.createRange(); + const sel = window.getSelection(); range.selectNode(editableDiv); range.setStart(editableDiv.childNodes[0], position); range.collapse(true); @@ -36,21 +36,21 @@ export function setCaretPosition(editableDiv, position) { sel.addRange(range); } -export function generatePlaceholderText(isEnabled, hasSentFirstChatMessage) { - if (isEnabled) { - return hasSentFirstChatMessage - ? CHAT_PLACEHOLDER_TEXT - : CHAT_INITIAL_PLACEHOLDER_TEXT; - } - return CHAT_PLACEHOLDER_OFFLINE; -} +// export function generatePlaceholderText(isEnabled, hasSentFirstChatMessage) { +// if (isEnabled) { +// return hasSentFirstChatMessage +// ? CHAT_PLACEHOLDER_TEXT +// : CHAT_INITIAL_PLACEHOLDER_TEXT; +// } +// return CHAT_PLACEHOLDER_OFFLINE; +// } export function extraUserNamesFromMessageHistory(messages) { const list = []; if (messages) { messages - .filter((m) => m.user && m.user.displayName) - .forEach(function (message) { + .filter(m => m.user && m.user.displayName) + .forEach(message => { if (!list.includes(message.user.displayName)) { list.push(message.user.displayName); } @@ -87,9 +87,7 @@ export function convertToText(str = '') { // Trim each line. value = value .split('\n') - .map((line = '') => { - return line.trim(); - }) + .map((line = '') => line.trim()) .join('\n'); // No more than 2x newline, per "paragraph". @@ -145,19 +143,9 @@ export function convertOnPaste(event = { preventDefault() {} }, emojiList) { export function createEmojiMarkup(data, isCustom) { const emojiUrl = isCustom ? data.emoji : data.url; const emojiName = ( - isCustom - ? data.name - : data.url.split('\\').pop().split('/').pop().split('.').shift() + isCustom ? data.name : data.url.split('\\').pop().split('/').pop().split('.').shift() ).toLowerCase(); - return ( - ':‌‌' +
-    emojiName +
-    '‌‌:' - ); + return `:‌‌${emojiName}‌‌:`; } // trim html white space characters from ends of messages for more accurate counting @@ -168,7 +156,7 @@ export function trimNbsp(html) { export function emojify(HTML, emojiList) { const textValue = convertToText(HTML); - for (var lastPos = textValue.length; lastPos >= 0; lastPos--) { + for (let lastPos = textValue.length; lastPos >= 0; lastPos--) { const endPos = textValue.lastIndexOf(':', lastPos); if (endPos <= 0) { break; @@ -178,13 +166,13 @@ export function emojify(HTML, emojiList) { break; } const typedEmoji = textValue.substring(startPos + 1, endPos).trim(); - const emojiIndex = emojiList.findIndex(function (emojiItem) { - return emojiItem.name.toLowerCase() === typedEmoji.toLowerCase(); - }); + const emojiIndex = emojiList.findIndex( + emojiItem => emojiItem.name.toLowerCase() === typedEmoji.toLowerCase(), + ); if (emojiIndex != -1) { const emojiImgElement = createEmojiMarkup(emojiList[emojiIndex], true); - HTML = HTML.replace(':' + typedEmoji + ':', emojiImgElement); + HTML = HTML.replace(`:${typedEmoji}:`, emojiImgElement); } } return HTML; diff --git a/web/components/stores/ClientConfigStore.tsx b/web/components/stores/ClientConfigStore.tsx index 24cac5f2b..ffa5971e7 100644 --- a/web/components/stores/ClientConfigStore.tsx +++ b/web/components/stores/ClientConfigStore.tsx @@ -75,12 +75,11 @@ export function ClientConfigStore() { const [websocketService, setWebsocketService] = useRecoilState(websocketServiceAtom); - // let websocketService: WebsocketService; + let ws: WebsocketService; const updateClientConfig = async () => { try { const config = await ClientConfigService.getConfig(); - // console.log(`ClientConfig: ${JSON.stringify(config)}`); setClientConfig(config); setAppState(AppState.Online); } catch (error) { @@ -133,7 +132,7 @@ export function ClientConfigStore() { const startChat = async () => { setChatState(ChatState.Loading); try { - const ws = new WebsocketService(accessToken, '/ws'); + ws = new WebsocketService(accessToken, '/ws'); ws.handleMessage = handleMessage; setWebsocketService(ws); } catch (error) { diff --git a/web/stories/ChatTextField.stories.tsx b/web/stories/ChatTextField.stories.tsx index 0f117dc9a..9a4880047 100644 --- a/web/stories/ChatTextField.stories.tsx +++ b/web/stories/ChatTextField.stories.tsx @@ -32,7 +32,7 @@ export const Example = Template.bind({}); export const LongerMessage = Template.bind({}); LongerMessage.args = { value: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', }; LongerMessage.parameters = {