ChatWindow

dev/chat
Lei OT 2 years ago
parent 4ee4eb85bf
commit 2017b373e9

@ -16,6 +16,7 @@
"mobx": "^6.12.0", "mobx": "^6.12.0",
"mobx-react": "^9.1.0", "mobx-react": "^9.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-chat-elements": "^12.0.11",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router-dom": "^6.21.1", "react-router-dom": "^6.21.1",
"rxjs": "^7.8.1" "rxjs": "^7.8.1"

@ -39,19 +39,14 @@ class Conversations {
// todo: handle message // todo: handle message
runInAction(() => { runInAction(() => {
this.addMessage({ ...msg.message, sender: 'other', id: Date.now().toString(16), }); this.addMessage({ ...msg.message, sender: 'other', id: Date.now().toString(16), });
console.log(toJS(this.messages), 'messages'); // console.log(toJS(this.messages), 'messages');
}); });
} }
sendMessage = (msg) => { sendMessage = (msg) => {
const msgObj = { const msgObj = {
type: 'message', type: 'message',
message: { message: msg,
sender: 'me',
content: msg,
readState: false,
id: Date.now().toString(16),
},
}; };
realtimeAPI.sendMessage(msgObj); realtimeAPI.sendMessage(msgObj);
this.addMessage(msgObj.message); this.addMessage(msgObj.message);

@ -1,3 +1,4 @@
import crypto from 'crypto-js';
/** /**
* ! 不支持计算 Set Map * ! 不支持计算 Set Map
* @param {*} val * @param {*} val
@ -298,3 +299,13 @@ export const cartesianProductArray = (arr, sep = '_', index = 0, prefix = '') =>
}); });
return result; return result;
}; };
export const stringToColour = (str) => {
// Hash the username using SHA256
const hash = crypto.SHA256(str);
// Convert the hash to a hexadecimal string
const hexString = hash.toString(crypto.enc.Hex);
// Use the first 6 characters of the hex string as a color
const color = '#' + hexString.substring(0, 6);
return color;
};

@ -7,6 +7,7 @@ import zhLocale from 'antd/locale/zh_CN';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn'; import 'dayjs/locale/zh-cn';
import 'react-chat-elements/dist/main.css'
import '@/assets/App.css' import '@/assets/App.css'
import AppLogo from '@/assets/logo-gh.png' import AppLogo from '@/assets/logo-gh.png'
import { useStore } from '@/stores/StoreContext.js' import { useStore } from '@/stores/StoreContext.js'

@ -1,20 +1,23 @@
import { useEffect, useContext } from 'react'; import { useEffect, useContext } from 'react';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Layout } from 'antd'; import { Layout, List, Avatar } from 'antd';
import Messages from './Components/Messages'; import Messages from './Components/Messages';
import InputBox from './Components/InputBox'; import InputBox from './Components/InputBox';
import Conversations from './Components/Conversations'; import Conversations from './Components/ConversationsList';
import CustomerProfile from './Components/CustomerProfile'; import CustomerProfile from './Components/CustomerProfile';
import WebSocketLib from '@/lib/websocketLib'; import WebSocketLib from '@/lib/websocketLib';
import { useStore } from '@/stores/StoreContext.js'; import { useStore } from '@/stores/StoreContext.js';
import { stringToColour } from '@/utils/utils';
import './Conversations.css';
const customer = { url: 'ws://202.103.68.144:8888/whatever/', authToken: 'customer1Token' }; const customer = { url: 'ws://202.103.68.144:8888/whatever/', authToken: 'customer1Token' };
// Create a WebSocketLib instance for each customer // Create a WebSocketLib instance for each customer
// const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'WhatApp'); // const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'WhatApp');
// const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'aaa'); // const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'aaa');
const { Sider, Content } = Layout; const { Sider, Content, Header, Footer } = Layout;
const CList = [ const CList = [
{ name: 'Customer_1', label: 'Customer_1', key: 'Customer_1', value: 'Customer_1' }, { name: 'Customer_1', label: 'Customer_1', key: 'Customer_1', value: 'Customer_1' },
@ -32,24 +35,52 @@ const ChatWindow = observer(() => {
const { conversationsStore } = useStore(); const { conversationsStore } = useStore();
const { sendMessage, messages } = conversationsStore; const { sendMessage, messages } = conversationsStore;
useEffect(() => { useEffect(() => {
return () => {}; return () => {};
}, []); }, []);
return ( return (
<Layout style={{maxHeight: 'calc(100% - 150px)', height: 'calc(100% - 150px)'}}> <Layout className='full-height' style={{ maxHeight: 'calc(100% - 150px)', height: 'calc(100% - 150px)' }}>
<Sider width={300} theme={'light'} style={{ height: '70vh' }}> <Sider width={220} theme={'light'} className='scrollable-column' style={{ height: '70vh' }}>
<Conversations conversations={CList} /> <Conversations conversations={CList} />
</Sider> </Sider>
<Content className='h70' style={{maxHeight: '70vh', height: '70vh'}}> <Content className='h70' style={{ maxHeight: '70vh', height: '70vh' }}>
<Layout style={{ height: '100%' }}> <Layout style={{ height: '100%' }}>
<Header className='ant-layout-sider-light ant-card' style={{paddingLeft: '10px'}}>
<List
dataSource={[{ name: 'Customer_1', label: 'Customer_1', key: 'Customer_1', value: 'Customer_1' }]}
renderItem={(item, ii) => (
<List.Item actions={[<a key='list-loadmore-edit'>mark</a>]}>
<List.Item.Meta
avatar={
<Avatar
style={{
backgroundColor: stringToColour(item.name),
verticalAlign: 'middle',
}}>
{item.name}
</Avatar>
}
title={item.name}
description='{最近的消息}'
/>
</List.Item>
)}
/>
</Header>
<Content style={{ maxHeight: '70vh', height: '70vh' }}>
<div className='scrollable-column' >
<Messages /> <Messages />
</div>
</Content>
<Footer className='ant-layout-sider-light' style={{padding: '10px'}}>
<InputBox onSend={(v) => sendMessage(v)} /> <InputBox onSend={(v) => sendMessage(v)} />
</Footer>
</Layout> </Layout>
{/* <InputBox onSend={(v) => sendMessage(v)} /> */}
</Content> </Content>
<Sider width={300} theme={'light'}> <Sider width={300} theme={'light'} className='scrollable-column' style={{ maxHeight: '70vh', height: '70vh' }}>
<CustomerProfile customer={{}} /> <CustomerProfile customer={{}} />
</Sider> </Sider>
</Layout> </Layout>

@ -0,0 +1,13 @@
import { useContext } from 'react';
import { observer } from "mobx-react";
import { stores_Context } from '../config';
import { Table } from 'antd';
const ContactInfo = observer((props) => {
// const { } = useContext(stores_Context);
return (
<>
</>
);
});
export default ContactInfo;

@ -0,0 +1,13 @@
import { useContext } from 'react';
import { observer } from "mobx-react";
import { stores_Context } from '../config';
import { Table } from 'antd';
const ContactPanel = observer((props) => {
// const { } = useContext(stores_Context);
return (
<>
</>
);
});
export default ContactPanel;

@ -1,6 +1,7 @@
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { List, Avatar } from 'antd'; import { List, Avatar } from 'antd';
import crypto from 'crypto-js'; import crypto from 'crypto-js';
import { stringToColour } from '@/utils/utils';
const ColorList = []; // ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae']; const ColorList = []; // ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
// const colors = []; // const colors = [];
@ -11,19 +12,7 @@ for (let i = 0; i < 10; i++) {
// ColorList.push(`rgb(${red}, ${green}, ${blue})`); // ColorList.push(`rgb(${red}, ${green}, ${blue})`);
ColorList.push(`#${red}${green}${blue}`); ColorList.push(`#${red}${green}${blue}`);
} }
console.log(ColorList); // console.log(ColorList);
const stringToColour = (str) => {
// Hash the username using SHA256
const hash = crypto.SHA256(str);
// Convert the hash to a hexadecimal string
const hexString = hash.toString(crypto.enc.Hex);
// Use the first 6 characters of the hex string as a color
const color = '#' + hexString.substring(0, 6);
return color;
};
/** /**
* [] * []

@ -1,32 +1,45 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Input, Button } from 'antd'; import { Input, Button } from 'antd';
// import { Input } from 'react-chat-elements';
const InputBox = observer(({ onSend }) => { const InputBox = observer(({ onSend }) => {
const [message, setMessage] = useState(''); const [message, setMessage] = useState('');
const handleSend = (v) => {
// console.log(v); const sendMessage = () => {
if (typeof onSend === 'function' && v.trim() !== '') { // console.log(message);
onSend(v); if (typeof onSend === 'function' && message.trim() !== '') {
setMessage(''); const msgObj = {
} type: 'text',
text: {
body: message,
},
// contentType: 'text/markdown',
sender: 'me',
id: Date.now().toString(16),
readState: false,
}; };
const sendMessage = async () => { onSend(msgObj);
if (message.trim() !== '') {
// const api = new RealTimeAPI('wss://your_rocket_chat_server_url/websocket');
// await api.login('your_username', 'your_password'); // replace with your actual username and password
// await api.sendMessage({ roomId: 'ROOM_ID', msg: message }); // replace 'ROOM_ID' with your actual room id
setMessage(''); setMessage('');
} }
}; };
return ( return (
<div> <div>
{/* <Input.TextArea rows={4} /> <Input.Search placeholder='Type message here' enterButton='Send' size='large' onSearch={sendMessage} value={message} onChange={(e) => setMessage(e.target.value)} />
<Button type="primary" className="chat-button">
Send {/* <Input
</Button> */} placeholder='Type a message'
<Input.Search placeholder='Type message here' enterButton='Send' size='large' onSearch={handleSend} value={message} onChange={(e) => setMessage(e.target.value)} /> multiline={true}
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={(e) => {
if (e.shiftKey && e.charCode === 13) {
sendMessage();
}
}}
rightButtons={<button onClick={sendMessage}>Send</button>}
/> */}
</div> </div>
); );
}); });

@ -1,7 +1,8 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { List, Avatar, Timeline } from 'antd';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { useStore } from '@/stores/StoreContext.js'; import { useStore } from '@/stores/StoreContext.js';
import { List, Avatar, Timeline } from 'antd';
import { MessageBox } from 'react-chat-elements';
const Messages = observer(() => { const Messages = observer(() => {
const { conversationsStore } = useStore(); const { conversationsStore } = useStore();
@ -15,20 +16,27 @@ const Messages = observer(() => {
return ( return (
<> <>
<List {conversationsStore.messages.map((message, index) => (
<MessageBox
key={message.id}
position={ message.sender === 'me' ? 'right' : 'left' }
type={'text'}
text={message.text.body}
/>
))}
{/* <List
dataSource={conversationsStore.messages} dataSource={conversationsStore.messages}
style={{ flex: '1 1' }} style={{ flex: '1 1' }}
renderItem={(message) => ( renderItem={(message) => (
<List.Item> <List.Item>
<List.Item.Meta <List.Item.Meta
// avatar={<Avatar>{message.sender[0]}</Avatar>}
title={message.sender !== 'me' ? message.sender : ''} title={message.sender !== 'me' ? message.sender : ''}
description={message.sender !== 'me' ? `(${message.id}) ${message.content}` : ''} description={message.sender !== 'me' ? `(${message.id}) ${message.content}` : ''}
/> />
{message.sender === 'me' && <div>{message.content} ({message.id})</div>} {message.sender === 'me' && <div>{message.content} ({message.id})</div>}
</List.Item> </List.Item>
)} )}
/> /> */}
</> </>
); );
}); });

@ -0,0 +1,12 @@
.full-height {
height: 100vh;
}
.scrollable-column {
height: 100%;
overflow-y: auto;
}
.column {
height: 100%;
}
Loading…
Cancel
Save