You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

460 lines
12 KiB

import React, { Component } from 'react';
import Message from './Message/Message';
import ChatInputs from './ChatInputs/ChatInput';
import ChatSuggest from './ChatSuggest/ChatSuggest';
import { RecordState } from 'audio-react-recorder';
import ReactPlayer from 'react-player';
import ReactAudioPlayer from 'react-audio-player';
import { ToastContainer } from 'react-toastify';
import './Body.scss';
import { list, send, sendKeys } from '../../../Redux/actions/message';
import { info, bio } from '../../../Redux/actions/chat';
import { connect } from 'react-redux';
class Body extends Component {
constructor(props) {
super(props);
this.state = {
id: window.location.href.split('/').pop() * 1,
data: {},
message: '',
voice: null,
file: null,
image: null,
video: null,
music: null,
document: null,
footer: 'suggest',
suggest: [
[
{ id: 0, text: 'سلام' },
{ id: 0, text: 'سلام' },
],
[{ id: 1, text: 'وقت بخیر' }],
[{ id: 2, text: 'لطفا بامن تماس بگیر' }],
[{ id: 3, text: 'متشکرم' }],
],
};
}
start = () => {
this.setState({
voice: RecordState.START,
});
};
stop = () => {
this.setState({
voice: RecordState.STOP,
});
};
//audioData contains blob and blobUrl
onStop = (audioData) => {
this.setState({
voice: audioData,
});
this.sendVoice(audioData);
};
cancel = () => {
this.setState({
voice: null,
});
};
typeText = (e) => {
this.setState({
message: e.target.value,
});
};
addFile = async (e) => {
if (
e.target.files[0].type === 'image/apng' ||
e.target.files[0].type === 'image/avif' ||
e.target.files[0].type === 'image/gif' ||
e.target.files[0].type === 'image/jpeg' ||
e.target.files[0].type === 'image/png' ||
e.target.files[0].type === 'image/svg+xml' ||
e.target.files[0].type === 'image/webp'
) {
this.setState({
image: URL.createObjectURL(e.target.files[0]),
file: 'fill',
video: null,
document: null,
music: null,
});
} else if (
e.target.files[0].type === 'video/3gpp' ||
e.target.files[0].type === 'video/mpeg' ||
e.target.files[0].type === 'video/mp4' ||
e.target.files[0].type === 'video/ogg' ||
e.target.files[0].type === 'video/quicktime' ||
e.target.files[0].type === 'video/webm'
) {
this.setState({
image: null,
file: 'fill',
video: URL.createObjectURL(e.target.files[0]),
document: null,
music: null,
});
} else if (
e.target.files[0].type === 'audio/3gpp' ||
e.target.files[0].type === 'audio/aac' ||
e.target.files[0].type === 'audio/flac' ||
e.target.files[0].type === 'audio/mpeg' ||
e.target.files[0].type === 'audio/mp3' ||
e.target.files[0].type === 'audio/mp4' ||
e.target.files[0].type === 'audio/ogg' ||
e.target.files[0].type === 'audio/wav' ||
e.target.files[0].type === 'audio/webm'
) {
this.setState({
image: null,
file: 'fill',
video: null,
document: null,
music: URL.createObjectURL(e.target.files[0]),
});
} else {
this.setState({
image: null,
file: 'fill',
video: null,
music: null,
document: { data: URL.createObjectURL(e.target.files[0]), name: e.target.files[0].name },
});
}
};
sendMessage = () => {
console.log(1);
if (this.state.file !== null) {
this.sendFile();
return;
} else {
console.log(2);
let now = new Date();
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm12',
type: 'normal',
text: prevState.message,
voice: null,
image: null,
file: null,
video: null,
music: null,
document: null,
createdAt: now.toString(),
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
message: '',
});
}
};
sendVoice = (audioData) => {
let now = new Date();
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm9',
text: null,
type: 'normal',
voice: audioData,
createdAt: now.toString(),
image: null,
video: null,
document: null,
music: null,
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
voice: null,
});
};
sendFile = () => {
const { image, video, music, document } = this.state;
let now = new Date();
if (image !== null) {
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm8',
type: 'normal',
text: prevState.message,
voice: null,
createdAt: now.toString(),
image: image,
video: null,
document: null,
music: null,
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
file: null,
image: null,
message: '',
});
} else if (video !== null) {
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm8',
type: 'normal',
text: prevState.message,
voice: null,
createdAt: now.toString(),
image: null,
video: video,
document: null,
music: null,
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
file: null,
video: null,
message: '',
});
} else if (music !== null) {
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm8',
text: prevState.message,
type: 'normal',
voice: null,
createdAt: now.toString(),
image: null,
video: null,
document: null,
music: music,
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
file: null,
music: null,
message: '',
});
} else if (document !== null) {
this.setState((prevState) => ({
data: {
...prevState.data,
messages: [
...prevState.data.messages,
{
id: 'm8',
text: prevState.message,
type: 'normal',
voice: null,
createdAt: now.toString(),
image: null,
video: null,
document: document,
music: null,
user: {
id: 'u1',
name: 'علی',
},
},
],
},
}));
this.setState({
file: null,
document: null,
message: '',
});
}
};
cancelSendFile = () => {
this.setState({
file: null,
document: null,
message: '',
image: null,
video: null,
voice: null,
music: null,
});
};
componentDidMount() {
this.props.list({ chatId: this.state.id });
this.props.info({ id: this.state.id });
// this.componentDidUpdate();
}
componentDidUpdate() {
let chatroom = document.getElementById('chatroom');
chatroom.scrollTop = chatroom.scrollHeight + 40;
}
randomColor() {
let hex = Math.floor(Math.random() * 0x999999);
let color = '#' + hex.toString(16);
return color;
}
render() {
const { setPage, chatInfo, messageList, userId } = this.props;
const userIdx = {};
chatInfo.users.map((e) => (userIdx[e.id] = { ...e, color: this.randomColor() }));
console.log({ userId });
return (
<div className="chat-body d-flex flex-column">
<div className="chat-room__status d-flex flex-column" onClick={() => setPage('info')}>
<h1>{chatInfo.title}</h1>
<p>{chatInfo.subtitle}</p>
</div>
<div
className="chat-body__content d-flex flex-column"
id="chatroom"
style={{
overflowX: 'hidden',
overflowY: this.state.file !== null ? 'hidden' : 'scroll',
paddingBottom: this.state.footer === 'suggest' ? 110 : 70,
}}
>
{chatInfo.users &&
messageList.map((item, i) =>
this.state.image === null &&
this.state.music === null &&
this.state.video === null ? (
<Message
isSelf={userId == item.userId}
key={i}
file={this.state.image}
document={this.state.document}
message={item}
user={userIdx[item.userId] || { id: 0, fileId: 0, name: 'null' }}
/>
) : null
)}
{this.state.image !== null ? (
<div className="chat-body__content--preview d-flex">
<img src={this.state.image} alt="" />
</div>
) : null}
{this.state.video !== null ? (
<div className="chat-body__content--preview d-flex">
<ReactPlayer url={this.state.video} controls />
</div>
) : null}
{this.state.music !== null ? (
<div className="chat-body__content--preview d-flex">
<ReactAudioPlayer src={this.state.music} controls />
</div>
) : null}
{this.state.document !== null ? (
<div className="chat-body__content--confirm d-flex">
<div className="chat-body__content--confirm___box d-flex flex-column">
<p>{`ارسال (${this.state.document.name}) به ${this.props.info.title}؟`}</p>
<div className="chat-body__content--confirm___box---options d-flex">
<button style={{ color: '#00ff00' }} onClick={() => this.sendFile()}>
ارسال
</button>
<button style={{ color: '#ffffff' }} onClick={() => this.cancelSendFile()}>
کنسل
</button>
</div>
</div>
</div>
) : null}
</div>
<div className="chat-body__footer d-flex">
{this.state.footer === 'normal' ? (
<ChatInputs
onStop={this.onStop}
stop={this.stop}
start={this.start}
cancel={this.cancel}
message={this.state.message}
recordState={this.state.voice}
typeText={this.typeText}
sendMessage={this.sendMessage}
addFile={this.addFile}
file={this.state.file}
/>
) : null}
{this.state.footer === 'suggest' ? <ChatSuggest suggest={this.state.suggest} /> : null}
</div>
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</div>
);
}
}
export default connect(
(state) => {
console.log(state);
return {
chatInfo: state.chat.info,
userId: state.user.isLogin.id,
messageList: state.message.list || [],
};
},
{ list, send, sendKeys, info, bio }
)(Body);