多行文本输入, 输入区域样式

dev/chat
Lei OT 2 years ago
parent ff15ef9e2d
commit 21c0341a02

@ -2,7 +2,7 @@ import { useEffect } from 'react';
import { Layout, Spin } from 'antd'; import { Layout, Spin } from 'antd';
import MessagesHeader from './Components/MessagesHeader'; import MessagesHeader from './Components/MessagesHeader';
import Messages from './Components/Messages'; import Messages from './Components/Messages';
import InputBox from './Components/InputComposer'; import InputComposer from './Components/InputComposer';
import ConversationsList from './Components/ConversationsList'; import ConversationsList from './Components/ConversationsList';
import CustomerProfile from './Components/CustomerProfile'; import CustomerProfile from './Components/CustomerProfile';
@ -39,8 +39,8 @@ const ChatWindow = () => {
<Messages /> <Messages />
</div> </div>
</Content> </Content>
<Footer className='ant-layout-sider-light p-1'> <Footer className='ant-layout-sider-light p-1 max-h-32'>
<InputBox /> <InputComposer />
</Footer> </Footer>
</Layout> </Layout>
</Content> </Content>

@ -1,10 +1,10 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Input, Flex } from 'antd'; import { Input, Flex, Button } from 'antd';
// import { Input } from 'react-chat-elements'; // import { Input } from 'react-chat-elements';
import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext'; import { useConversationState, useConversationDispatch } from '@/stores/ConversationContext';
import { useAuthContext } from '@/stores/AuthContext'; import { useAuthContext } from '@/stores/AuthContext';
import { sentNewMessage } from '@/actions/ConversationActions'; import { sentNewMessage } from '@/actions/ConversationActions';
import { SendOutlined } from '@ant-design/icons'; import { SendOutlined, MessageOutlined, SmileOutlined } from '@ant-design/icons';
import { isEmpty } from '@/utils/utils'; import { isEmpty } from '@/utils/utils';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { sentMsgTypeMapped } from '@/lib/msgUtils'; import { sentMsgTypeMapped } from '@/lib/msgUtils';
@ -13,7 +13,7 @@ import InputTemplate from './InputTemplate';
const InputBox = () => { const InputBox = () => {
const { loginUser } = useAuthContext(); const { loginUser } = useAuthContext();
const { userId } = loginUser; const { userId } = loginUser;
const { websocket, currentConversation, } = useConversationState(); const { websocket, currentConversation } = useConversationState();
const dispatch = useConversationDispatch(); const dispatch = useConversationDispatch();
const [textContent, setTextContent] = useState(''); const [textContent, setTextContent] = useState('');
@ -47,20 +47,30 @@ const InputBox = () => {
return ( return (
<div> <div>
<Flex gap={8}> <Input.TextArea
<InputTemplate disabled={!talkabled} invokeSendMessage={invokeSendMessage} /> size='large'
<Input.Search placeholder='Enter for Send, Shift+Enter for new line'
disabled={!talkabled} rows={2}
placeholder='Type message here' disabled={!talkabled}
// enterButton={'Send'} value={textContent}
enterButton={<SendOutlined />} onChange={(e) => setTextContent(e.target.value)}
size='large' className='rounded-b-none'
onSearch={handleSendText} onPressEnter={(e) => {
value={textContent} if (!e.shiftKey) {
onChange={(e) => setTextContent(e.target.value)} e.preventDefault();
/> handleSendText();
}
}}
autoSize={{minRows: 2, maxRows: 6}}
/>
<Flex justify={'space-between'} className=' bg-gray-200 p-1'>
<Flex gap={4} className='divide-y-0 divide-x divide-solid divide-gray-500 '>
<InputTemplate key='templates' disabled={!talkabled} invokeSendMessage={invokeSendMessage} />
</Flex>
<Button key={'send-btn'} type='primary' size='middle' icon={<SendOutlined />} disabled={!talkabled}>
Send
</Button>
</Flex> </Flex>
<div></div>
</div> </div>
); );
}; };

@ -1,4 +1,4 @@
import { useState } from 'react'; import { useState, useRef, useEffect } from 'react';
import { App, Popover, Flex, Button, List, Input } from 'antd'; import { App, Popover, Flex, Button, List, Input } from 'antd';
import { MessageOutlined, SendOutlined } from '@ant-design/icons'; import { MessageOutlined, SendOutlined } from '@ant-design/icons';
import { useAuthContext } from '@/stores/AuthContext'; import { useAuthContext } from '@/stores/AuthContext';
@ -22,18 +22,25 @@ const splitTemplate = (template) => {
return obj; return obj;
}; };
const InputTemplate = ({ disabled = false, invokeSendMessage }) => { const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
const searchInputRef = useRef(null);
const { notification } = App.useApp(); const { notification } = App.useApp();
const { loginUser } = useAuthContext(); const { loginUser } = useAuthContext();
const { currentConversation, templates } = useConversationState(); const { currentConversation, templates } = useConversationState();
// : customer, agent // : customer, agent
const valueMapped = { ...cloneDeep(currentConversation), ...objectMapper(loginUser, { username: [{ key: 'agent_name' }, { key: 'your_name' }] }) }; const valueMapped = { ...cloneDeep(currentConversation), ...objectMapper(loginUser, { username: [{ key: 'agent_name' }, { key: 'your_name' }] }) };
useEffect(() => {
setDataSource(templates);
return () => {};
}, [templates]);
const [openTemplates, setOpenTemplates] = useState(false); const [openTemplates, setOpenTemplates] = useState(false);
const [dataSource, setDataSource] = useState(templates); const [dataSource, setDataSource] = useState(templates);
const [searchContent, setSearchContent] = useState(''); const [searchContent, setSearchContent] = useState('');
const handleSearchTemplates = (val) => { const handleSearchTemplates = (val) => {
if (val.toLowerCase().trim() !== '') { if (val.toLowerCase().trim() !== '') {
const res = templates.filter((item) => item.name.includes(val.toLowerCase().trim()) || item.components_origin.some((itemc) => itemc.text.toLowerCase().includes(val.toLowerCase().trim()))); const res = templates.filter(
(item) => item.name.includes(val.toLowerCase().trim()) || item.components_origin.some((itemc) => itemc.text.toLowerCase().includes(val.toLowerCase().trim()))
);
setDataSource(res); setDataSource(res);
return false; return false;
} }
@ -117,9 +124,11 @@ const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
return ( return (
<> <>
<Popover <Popover
fresh
content={ content={
<> <>
<Input.Search <Input.Search
ref={searchInputRef}
onSearch={handleSearchTemplates} onSearch={handleSearchTemplates}
allowClear allowClear
value={searchContent} value={searchContent}
@ -170,7 +179,7 @@ const InputTemplate = ({ disabled = false, invokeSendMessage }) => {
trigger='click' trigger='click'
open={openTemplates} open={openTemplates}
onOpenChange={setOpenTemplates}> onOpenChange={setOpenTemplates}>
<Button type='primary' shape='circle' icon={<MessageOutlined />} size={'large'} disabled={disabled} /> <Button type='text' className=' rounded-none text-primary' icon={<MessageOutlined />} size={'middle'} disabled={disabled} />
</Popover> </Popover>
</> </>
); );

@ -15,6 +15,7 @@ export default {
bg: '#ece5dd', bg: '#ece5dd',
me: '#ccd5ae', me: '#ccd5ae',
}, },
'primary': '#1ba784',
}, },
extend: { extend: {
// gridTemplateColumns: { // gridTemplateColumns: {

Loading…
Cancel
Save