test: 单个会话订阅. 发送和接收
parent
7bdd2a6eac
commit
e13bc7b096
@ -0,0 +1,177 @@
|
|||||||
|
import {
|
||||||
|
webSocket,
|
||||||
|
} from "rxjs/webSocket";
|
||||||
|
import { filter, buffer, flatMap, merge, map, tap } from "rxjs/operators";
|
||||||
|
// import { v4 as uuid } from "uuid";
|
||||||
|
import { SHA256 } from "crypto-js";
|
||||||
|
|
||||||
|
export class RealTimeAPI {
|
||||||
|
constructor(param) {
|
||||||
|
this.webSocket = webSocket(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
getObservable() {
|
||||||
|
return this.webSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
return this.webSocket.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage(messageHandler) {
|
||||||
|
this.subscribe(messageHandler, undefined, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
onError(errorHandler) {
|
||||||
|
this.subscribe(undefined, errorHandler, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCompletion(completionHandler) {
|
||||||
|
this.subscribe(undefined, undefined, completionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(messageHandler, errorHandler, completionHandler) {
|
||||||
|
// this.getObservable().subscribe(
|
||||||
|
// messageHandler,
|
||||||
|
// errorHandler,
|
||||||
|
// completionHandler
|
||||||
|
// );
|
||||||
|
this.getObservable().subscribe({
|
||||||
|
next: messageHandler,
|
||||||
|
error: errorHandler,
|
||||||
|
complete: completionHandler
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(messageObject) {
|
||||||
|
this.webSocket.next(messageObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
getObservableFilteredByMessageType(messageType) {
|
||||||
|
return this.getObservable().pipe(
|
||||||
|
filter((message) => message.msg === messageType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getObservableFilteredByID(id) {
|
||||||
|
return this.getObservable().pipe(
|
||||||
|
filter((message) => message.id === id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectToServer() {
|
||||||
|
this.sendMessage({
|
||||||
|
msg: "connect",
|
||||||
|
version: "1",
|
||||||
|
support: ["1", "pre2", "pre1"]
|
||||||
|
});
|
||||||
|
return this.getObservableFilteredByMessageType("connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
keepAlive() {
|
||||||
|
return this.getObservableFilteredByMessageType("ping").pipe(
|
||||||
|
tap(() => this.sendMessage({ msg: "pong" }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
login(username, password) {
|
||||||
|
let id = 'uuid()';
|
||||||
|
let usernameType = username.indexOf("@") !== -1 ? "email" : "username";
|
||||||
|
this.sendMessage({
|
||||||
|
msg: "method",
|
||||||
|
method: "login",
|
||||||
|
id: id,
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
user: { [usernameType]: username },
|
||||||
|
password: {
|
||||||
|
digest: SHA256(password).toString(),
|
||||||
|
algorithm: "sha-256"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return this.getLoginObservable(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
loginWithAuthToken(authToken) {
|
||||||
|
let id = 'uuid()';
|
||||||
|
this.sendMessage({
|
||||||
|
msg: "method",
|
||||||
|
method: "login",
|
||||||
|
id: id,
|
||||||
|
params: [{ resume: authToken }]
|
||||||
|
});
|
||||||
|
return this.getLoginObservable(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
loginWithOAuth(credToken, credSecret) {
|
||||||
|
let id = 'uuid()';
|
||||||
|
this.sendMessage({
|
||||||
|
msg: "method",
|
||||||
|
method: "login",
|
||||||
|
id: id,
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
oauth: {
|
||||||
|
credentialToken: credToken,
|
||||||
|
credentialSecret: credSecret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return this.getLoginObservable(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoginObservable(id) {
|
||||||
|
let resultObservable = this.getObservableFilteredByID(id);
|
||||||
|
let resultId;
|
||||||
|
|
||||||
|
let addedObservable = this.getObservable().pipe(
|
||||||
|
buffer(
|
||||||
|
resultObservable.pipe(
|
||||||
|
map(({ msg, error, result }) => {
|
||||||
|
if (msg === "result" && !error) return (resultId = result.id);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
),
|
||||||
|
flatMap(x => x),
|
||||||
|
filter(({ id: msgId }) => resultId !== undefined && msgId === resultId),
|
||||||
|
merge(resultObservable)
|
||||||
|
);
|
||||||
|
|
||||||
|
return addedObservable;
|
||||||
|
}
|
||||||
|
|
||||||
|
callMethod(method, ...params) {
|
||||||
|
let id = 'uuid()';
|
||||||
|
this.sendMessage({
|
||||||
|
msg: "method",
|
||||||
|
method,
|
||||||
|
id,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
return this.getObservableFilteredByID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubscription(streamName, streamParam, addEvent) {
|
||||||
|
let id = 'uuid()';
|
||||||
|
let subscription = this.webSocket.multiplex(
|
||||||
|
() => ({
|
||||||
|
msg: "sub",
|
||||||
|
id: id,
|
||||||
|
name: streamName,
|
||||||
|
params: [streamParam, addEvent]
|
||||||
|
}),
|
||||||
|
() => ({
|
||||||
|
msg: "unsub",
|
||||||
|
id: id
|
||||||
|
}),
|
||||||
|
(message) =>
|
||||||
|
typeof message.collection === "string" &&
|
||||||
|
message.collection === streamName &&
|
||||||
|
message.fields.eventName === streamParam
|
||||||
|
);
|
||||||
|
return subscription;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
import { makeAutoObservable, runInAction, toJS } from 'mobx';
|
||||||
|
import { RealTimeAPI } from '@/lib/realTimeAPI';
|
||||||
|
|
||||||
|
const URL = 'ws://202.103.68.144:8888/whatever/';
|
||||||
|
let realtimeAPI = new RealTimeAPI({ url: URL, protocol: 'aaa' });
|
||||||
|
|
||||||
|
class Conversations {
|
||||||
|
constructor() {
|
||||||
|
makeAutoObservable(this, { rootStore: false });
|
||||||
|
// this.sendMessage = this.sendMessage.bind(this);
|
||||||
|
|
||||||
|
realtimeAPI.onError(this.addError.bind(this, 'Error'));
|
||||||
|
realtimeAPI.onMessage(this.handleMessage.bind(this));
|
||||||
|
realtimeAPI.onCompletion(this.addError.bind(this, 'Not Connected to Server'));
|
||||||
|
realtimeAPI.keepAlive(); // Ping Server
|
||||||
|
// realtimeAPI.onMessage().subscribe(message => {
|
||||||
|
// this.addMessage(message);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
addError = (reason) => {
|
||||||
|
// this.errors.push({ reason });
|
||||||
|
this.errors = [...this.errors, { reason }];
|
||||||
|
}
|
||||||
|
|
||||||
|
addMessage = (message) => {
|
||||||
|
// this.messages.push(msg.message); // Mobx will not work
|
||||||
|
this.messages = [...this.messages, message];
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMessage = (data) => {
|
||||||
|
const msg = data.result;
|
||||||
|
if (!msg) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (typeof msg.type === 'string' && msg.type === 'error') {
|
||||||
|
this.addError('Error Connecting to Server');
|
||||||
|
}
|
||||||
|
// todo: handle message
|
||||||
|
runInAction(() => {
|
||||||
|
this.addMessage({ ...msg.message, sender: 'other', id: Date.now().toString(16), });
|
||||||
|
console.log(toJS(this.messages), 'messages');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage = (msg) => {
|
||||||
|
const msgObj = {
|
||||||
|
type: 'message',
|
||||||
|
message: {
|
||||||
|
sender: 'me',
|
||||||
|
content: msg,
|
||||||
|
readState: false,
|
||||||
|
id: Date.now().toString(16),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
realtimeAPI.sendMessage(msgObj);
|
||||||
|
this.addMessage(msgObj.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
errors = [];
|
||||||
|
messages = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Conversations;
|
@ -0,0 +1,41 @@
|
|||||||
|
// App.js
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Layout, Menu } from 'antd';
|
||||||
|
// import './App.css';
|
||||||
|
|
||||||
|
const { Header, Sider, Content } = Layout;
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const channels = ['General', 'Random'];
|
||||||
|
const messages = [
|
||||||
|
{ user: 'User1', text: 'Hello!' },
|
||||||
|
{ user: 'User2', text: 'Hi!' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout style={{ minHeight: '100vh' }}>
|
||||||
|
<Sider width={200}>
|
||||||
|
<Menu mode="inline" style={{ height: '100%', borderRight: 0 }}>
|
||||||
|
{channels.map(channel => (
|
||||||
|
<Menu.Item key={channel}>{channel}</Menu.Item>
|
||||||
|
))}
|
||||||
|
</Menu>
|
||||||
|
</Sider>
|
||||||
|
<Layout>
|
||||||
|
<Header style={{ background: '#fff', padding: 0 }} />
|
||||||
|
<Content style={{ margin: '24px 16px 0', overflow: 'initial' }}>
|
||||||
|
<div style={{ padding: 24, background: '#fff', textAlign: 'center' }}>
|
||||||
|
{messages.map((message, index) => (
|
||||||
|
<p key={index}>
|
||||||
|
<strong>{message.user}</strong>: {message.text}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
@ -0,0 +1,44 @@
|
|||||||
|
import { Layout, Menu, List, Timeline, Input } from 'antd';
|
||||||
|
|
||||||
|
const { Sider, Content } = Layout;
|
||||||
|
function ChatApp() {
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<Sider theme="light" width={300}>
|
||||||
|
<Menu>
|
||||||
|
<Menu.Item>Unread</Menu.Item>
|
||||||
|
<Menu.Item>Mentions</Menu.Item>
|
||||||
|
<Menu.Item>Favorites</Menu.Item>
|
||||||
|
<Menu.Item>Channel List</Menu.Item>
|
||||||
|
<Menu.Item>Direct Messages</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
|
||||||
|
<List>
|
||||||
|
{/* Show channels and DMs */}
|
||||||
|
</List>
|
||||||
|
</Sider>
|
||||||
|
|
||||||
|
<Content>
|
||||||
|
<Layout>
|
||||||
|
<Sider theme="light">
|
||||||
|
<List>
|
||||||
|
{/* Show user profile cards */}
|
||||||
|
</List>
|
||||||
|
</Sider>
|
||||||
|
|
||||||
|
<Content>
|
||||||
|
<Timeline>
|
||||||
|
{/* Show messages */}
|
||||||
|
</Timeline>
|
||||||
|
|
||||||
|
<Input.Search
|
||||||
|
enterButton="Send"
|
||||||
|
/>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
</Content>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChatApp;
|
@ -0,0 +1,59 @@
|
|||||||
|
import { useEffect, useContext } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { Layout } from 'antd';
|
||||||
|
import Messages from './Components/Messages';
|
||||||
|
import InputBox from './Components/InputBox';
|
||||||
|
import Conversations from './Components/Conversations';
|
||||||
|
import CustomerProfile from './Components/CustomerProfile';
|
||||||
|
|
||||||
|
import WebSocketLib from '@/lib/websocketLib';
|
||||||
|
import { useStore } from '@/stores/StoreContext.js';
|
||||||
|
|
||||||
|
const customer = { url: 'ws://202.103.68.144:8888/whatever/', authToken: 'customer1Token' };
|
||||||
|
// Create a WebSocketLib instance for each customer
|
||||||
|
// const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'WhatApp');
|
||||||
|
// const wsConnect = new WebSocketLib(customer.url, customer.authToken, 'aaa');
|
||||||
|
|
||||||
|
const { Sider, Content } = Layout;
|
||||||
|
|
||||||
|
const CList = [
|
||||||
|
{ name: 'Customer_1', label: 'Customer_1', key: 'Customer_1', value: 'Customer_1' },
|
||||||
|
{ name: 'Customer_2', label: 'Customer_2', key: 'Customer_2', value: 'Customer_2' },
|
||||||
|
{ name: 'Customer_3', label: 'Customer_3', key: 'Customer_3', value: 'Customer_3' },
|
||||||
|
{ name: 'Customer_4', label: 'Customer_4', key: 'Customer_4', value: 'Customer_4' },
|
||||||
|
];
|
||||||
|
const messages = [
|
||||||
|
{ sender: 'Customer_1', text: 'Hello, how can I help you today?' },
|
||||||
|
{ sender: 'Customer_2', text: 'Hello, how can I help you today?' },
|
||||||
|
{ sender: 'Customer_3', text: 'Hello, how can I help you today?' },
|
||||||
|
{ sender: 'Customer_4', text: 'Hello, how can I help you today?' },
|
||||||
|
];
|
||||||
|
const ChatWindow = observer(() => {
|
||||||
|
const { conversationsStore } = useStore();
|
||||||
|
const { sendMessage, messages } = conversationsStore;
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout style={{maxHeight: 'calc(100% - 150px)', height: 'calc(100% - 150px)'}}>
|
||||||
|
<Sider width={300} theme={'light'} style={{ height: '70vh' }}>
|
||||||
|
<Conversations conversations={CList} />
|
||||||
|
</Sider>
|
||||||
|
|
||||||
|
<Content className='h70' style={{maxHeight: '70vh', height: '70vh'}}>
|
||||||
|
<Layout style={{ height: '100%' }}>
|
||||||
|
<Messages />
|
||||||
|
<InputBox onSend={(v) => sendMessage(v)} />
|
||||||
|
</Layout>
|
||||||
|
</Content>
|
||||||
|
|
||||||
|
<Sider width={300} theme={'light'}>
|
||||||
|
<CustomerProfile customer={{}} />
|
||||||
|
</Sider>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ChatWindow;
|
@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
import { Layout } from 'antd';
|
|
||||||
import Messages from './Messages';
|
|
||||||
import InputBox from './InputBox';
|
|
||||||
import Conversations from './Conversations';
|
|
||||||
import CustomerProfile from './CustomerProfile';
|
|
||||||
|
|
||||||
const {Sider, Content } = Layout;
|
|
||||||
|
|
||||||
const CList = [
|
|
||||||
{ name: 'Customer_1', label: 'Customer_1', key: 'Customer_1', value: 'Customer_1' },
|
|
||||||
{ name: 'Customer_2', label: 'Customer_2', key: 'Customer_2', value: 'Customer_2' },
|
|
||||||
{ name: 'Customer_3', label: 'Customer_3', key: 'Customer_3', value: 'Customer_3' },
|
|
||||||
{ name: 'Customer_4', label: 'Customer_4', key: 'Customer_4', value: 'Customer_4' },
|
|
||||||
];
|
|
||||||
function ChatWindow() {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Layout>
|
|
||||||
<Sider width={300} theme={'light'}>
|
|
||||||
<Conversations conversations={CList} />
|
|
||||||
</Sider>
|
|
||||||
|
|
||||||
<Content>
|
|
||||||
<Layout>
|
|
||||||
<Messages />
|
|
||||||
<InputBox />
|
|
||||||
</Layout>
|
|
||||||
</Content>
|
|
||||||
|
|
||||||
<Sider width={300} theme={'light'}>
|
|
||||||
<CustomerProfile customer={{}}/>
|
|
||||||
</Sider>
|
|
||||||
</Layout>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ChatWindow;
|
|
@ -1,31 +1,55 @@
|
|||||||
|
import { observer } from 'mobx-react';
|
||||||
import { List, Avatar } from 'antd';
|
import { List, Avatar } from 'antd';
|
||||||
import PropTypes from 'prop-types';
|
import crypto from 'crypto-js';
|
||||||
|
|
||||||
const ColorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
|
const ColorList = []; // ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
|
||||||
function Conversations({ conversations }) {
|
// const colors = [];
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
const red = Math.floor(Math.random() * 256).toString(16);
|
||||||
|
const green = Math.floor(Math.random() * 256).toString(16);
|
||||||
|
const blue = Math.floor(Math.random() * 256).toString(16);
|
||||||
|
// ColorList.push(`rgb(${red}, ${green}, ${blue})`);
|
||||||
|
ColorList.push(`#${red}${green}${blue}`);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* []
|
||||||
|
*/
|
||||||
|
const Conversations = observer(({ conversations }) => {
|
||||||
return (
|
return (
|
||||||
<List
|
<List
|
||||||
dataSource={conversations}
|
dataSource={conversations}
|
||||||
renderItem={(item, ii) => (
|
renderItem={(item, ii) => (
|
||||||
<List.Item>
|
<List.Item actions={[<a key='list-loadmore-edit'>mark</a>]}>
|
||||||
<List.Item.Meta
|
<List.Item.Meta
|
||||||
avatar={
|
avatar={
|
||||||
<Avatar
|
<Avatar
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: ColorList[ii],
|
backgroundColor: stringToColour(item.name), // ColorList[ii],
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
}}>
|
}}>
|
||||||
{item.name}
|
{item.name}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
}
|
}
|
||||||
title={item.name}
|
title={item.name}
|
||||||
|
description='{最近的消息}'
|
||||||
/>
|
/>
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
Conversations.propTypes = {
|
|
||||||
conversations: PropTypes.string.isRequired,
|
|
||||||
};
|
|
||||||
export default Conversations;
|
export default Conversations;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
import { observer } from 'mobx-react';
|
||||||
import { Card } from 'antd';
|
import { Card } from 'antd';
|
||||||
|
|
||||||
function CustomerProfile({ customer }) {
|
const CustomerProfile = observer(({ customer }) => {
|
||||||
return <Card title={customer.name}>{/* other profile details */}</Card>;
|
return <Card title={customer.name}>{/* other profile details */}</Card>;
|
||||||
}
|
});
|
||||||
CustomerProfile.propTypes = {
|
|
||||||
};
|
|
||||||
export default CustomerProfile;
|
export default CustomerProfile;
|
||||||
|
@ -1,22 +1,34 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
import { Input, Button } from 'antd';
|
import { Input, Button } from 'antd';
|
||||||
|
|
||||||
function InputBox({ onSend }) {
|
const InputBox = observer(({ onSend }) => {
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
function handleSend() {
|
const handleSend = (v) => {
|
||||||
// Logic to get message and call onSend
|
// console.log(v);
|
||||||
|
if (typeof onSend === 'function' && v.trim() !== '') {
|
||||||
|
onSend(v);
|
||||||
|
setMessage('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const sendMessage = async () => {
|
||||||
|
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('');
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Input.Search
|
{/* <Input.TextArea rows={4} />
|
||||||
placeholder="Type message here"
|
<Button type="primary" className="chat-button">
|
||||||
enterButton="Send"
|
Send
|
||||||
size="large"
|
</Button> */}
|
||||||
onSearch={handleSend}
|
<Input.Search placeholder='Type message here' enterButton='Send' size='large' onSearch={handleSend} defaultValue={message} />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export default InputBox;
|
export default InputBox;
|
||||||
|
@ -1,21 +1,36 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { List, Avatar, Timeline } from 'antd';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { useStore } from '@/stores/StoreContext.js';
|
||||||
|
|
||||||
import { List, Avatar } from 'antd';
|
const Messages = observer(() => {
|
||||||
|
const { conversationsStore } = useStore();
|
||||||
|
const { messages: newMessages } = conversationsStore;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Load your data here
|
||||||
|
// For example:
|
||||||
|
// conversationsStore.loadMessages();
|
||||||
|
}, [newMessages]);
|
||||||
|
|
||||||
function Messages({ messages }) {
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<List
|
<List
|
||||||
dataSource={messages}
|
dataSource={conversationsStore.messages}
|
||||||
renderItem={message => (
|
style={{ flex: '1 1' }}
|
||||||
|
renderItem={(message) => (
|
||||||
<List.Item>
|
<List.Item>
|
||||||
<List.Item.Meta
|
<List.Item.Meta
|
||||||
avatar={<Avatar>{message.sender[0]}</Avatar>}
|
// avatar={<Avatar>{message.sender[0]}</Avatar>}
|
||||||
title={message.sender}
|
title={message.sender !== 'me' ? message.sender : ''}
|
||||||
|
description={message.sender !== 'me' ? `(${message.id}) ${message.content}` : ''}
|
||||||
/>
|
/>
|
||||||
<div>{message.text}</div>
|
{message.sender === 'me' && <div>{message.content} ({message.id})</div>}
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export default Messages;
|
export default Messages;
|
||||||
|
Loading…
Reference in New Issue