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.
 
 
 

636 lines
19 KiB

import React, { Component } from "react";
import Message from "./Message";
import ChatInputs from "./Input";
import Keyboard from "./Keyboard";
import { RecordState } from "audio-react-recorder";
import ReactPlayer from "react-player";
import ReactAudioPlayer from "react-audio-player";
// import { list, send, sendKeys } from "../../../Redux/actions/message";
import { chat } from "../../../Redux/actions";
import { connect } from "react-redux";
import Emoji from "./Emoji/index";
import "./index.scss";
class List extends Component {
constructor(props) {
super(props);
this.state = {
emoji: false,
counter: 1,
id:
window.innerWidth < 1000
? window.location.href.split("/").pop() * 1
: this.props.id,
data: {},
message: "",
voice: null,
file: null,
image: null,
video: null,
music: null,
document: null,
};
}
addcounter(type) {
if (type === "parent") {
if (localStorage.getItem("tapType") === "nothing") {
localStorage.removeItem("tapType");
return;
} else {
this.setState({ counter: this.state.counter + 1 });
}
} else {
localStorage.setItem("tapType", "nothing");
return;
}
}
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 = (type, val) => {
if (type === "text") {
this.setState({
message: val,
});
} else {
this.setState((prevState) => ({
message: prevState.message + val,
}));
}
};
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 = () => {
if (this.state.file !== null) {
this.sendFile();
return;
} else {
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(prevProps) {
let chatroom = document.getElementById("chatroom");
chatroom.scrollTop = chatroom.scrollHeight + 40;
if (prevProps.id !== this.props.id) {
this.props.info({
id:
window.innerWidth < 1000
? window.location.href.split("/").pop() * 1
: this.props.id,
});
this.props.list({
chatId:
window.innerWidth < 1000
? window.location.href.split("/").pop() * 1
: this.props.id,
});
}
}
randomColor() {
let hex = Math.floor(Math.random() * 0x999999);
let color = "#" + hex.toString(16);
return color;
}
render() {
const { setPage, chatInfo, messageList: msaster, userId } = this.props; //last
const messageList = msaster.slice(0, this.state.counter);
const last = messageList.slice(-1)[0] || {};
const userIdx = this.userIdx || {};
if (Object.keys(userIdx).length == 0) {
chatInfo.users.map(
(e) => (userIdx[e.id] = { ...e, color: this.randomColor() })
);
this.userIdx = userIdx;
}
return (
<>
{window.innerWidth < 1000 ? (
<div
className="chat-body d-flex flex-column nobar "
onClick={() => this.addcounter("parent")}
>
<div
className="chat-body__content d-flex flex-column nobar"
id="chatroom"
style={{
paddingTop: 10,
overflowX: "hidden",
overflowY: this.state.file !== null ? "hidden" : "scroll",
paddingBottom: last.action === "keyboard" ? 150 : 10,
}}
>
{chatInfo.users &&
messageList.map((message, i) =>
this.state.image === null &&
this.state.music === null &&
this.state.video === null ? (
<Message
addcounter={() => this.addcounter()}
isActive={message.id == last.id}
prevUserId={i > 0 ? messageList[i - 1].userId : 0}
isSelf={new Set([101, 103, 106, 108, 110]).has(
message.userId * 1
)}
key={message.id}
file={this.state.image}
document={this.state.document}
message={message}
user={
userIdx[message.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 nobar d-flex flex-column"
onClick={() => this.addcounter("nothing")}
>
{last.action == "text" ? (
<ChatInputs
addcounter={() => this.addcounter()}
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}
parent={this}
/>
) : null}
{last.action === "keyboard" ? (
<Keyboard
options={last.options}
addcounter={() => this.addcounter()}
/>
) : null}
{this.state.emoji ? (
<div className="chat-body__footer--emoji d-flex flex-column">
<Emoji typeText={this.typeText} />
</div>
) : null}
</div>
</div>
) : null}
{window.innerWidth > 1000 ? (
<div
className="desktop-chat-body d-flex flex-column nobar "
onClick={() => this.addcounter("parent")}
>
<div
className="desktop-chat-body__content d-flex flex-column nobar"
id="chatroom"
style={{
paddingTop: 10,
overflowX: "hidden",
overflowY: this.state.file !== null ? "hidden" : "scroll",
paddingBottom: last.action === "keyboard" ? 150 : 10,
}}
>
{chatInfo.users &&
messageList.map((message, i) =>
this.state.image === null &&
this.state.music === null &&
this.state.video === null ? (
<Message
addcounter={() => this.addcounter()}
isActive={message.id == last.id}
prevUserId={i > 0 ? messageList[i - 1].userId : 0}
isSelf={new Set([101, 103, 106, 108, 110]).has(
message.userId * 1
)}
key={message.id}
file={this.state.image}
document={this.state.document}
message={message}
user={
userIdx[message.userId] || {
id: 0,
fileId: 0,
name: "null",
}
}
/>
) : null
)}
{this.state.image !== null ? (
<div className="desktop-chat-body__content--preview d-flex">
<img src={this.state.image} alt="" />
</div>
) : null}
{this.state.video !== null ? (
<div className="desktop-chat-body__content--preview d-flex">
<ReactPlayer url={this.state.video} controls />
</div>
) : null}
{this.state.music !== null ? (
<div className="desktop-chat-body__content--preview d-flex">
<ReactAudioPlayer src={this.state.music} controls />
</div>
) : null}
{this.state.document !== null ? (
<div className="desktop-chat-body__content--confirm d-flex">
<div className="desktop-chat-body__content--confirm___box d-flex flex-column">
<p>{`ارسال (${this.state.document.name}) به ${this.props.info.title}؟`}</p>
<div className="desktop-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="desktop-chat-body__footer d-flex nobar d-flex flex-column"
onClick={() => this.addcounter("nothing")}
>
{last.action == "text" ? (
<ChatInputs
addcounter={() => this.addcounter()}
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}
parent={this}
/>
) : null}
{last.action === "keyboard" ? (
<Keyboard
options={last.options}
addcounter={() => this.addcounter()}
/>
) : null}
{this.state.emoji ? (
<div className="desktop-chat-body__footer--emoji d-flex flex-column">
<Emoji typeText={this.typeText} />
</div>
) : null}
</div>
</div>
) : null}
</>
);
}
}
export default connect(
(state) => {
return {
chatInfo: state.chat.info,
userId: state.user.isLogin.id,
messageList: state.message.list || [],
last: state.message.list.slice(-1)[0] || {},
};
},
{ info: chat.info, bio: chat.bio }
)(List);