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
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);
|
|
|