master
Reza_ashrafi 3 years ago
parent b3d9357551
commit 422e4ae6fb
  1. 3
      src/views/ChatList/index.js
  2. 16
      src/views/ChatList/index.scss
  3. 533
      src/views/ChatRoom/Body/index.js
  4. 134
      src/views/ChatRoom/Body/index.scss
  5. 83
      src/views/ChatRoom/Drawer/index.js
  6. 34
      src/views/ChatRoom/Drawer/index.scss
  7. 21
      src/views/ChatRoom/Header/index.js
  8. 212
      src/views/ChatRoom/Info/index.js
  9. 79
      src/views/ChatRoom/Info/index.scss
  10. 62
      src/views/ChatRoom/index.js
  11. 33
      src/views/ChatRoom/index.scss

@ -38,6 +38,9 @@ class ChatList extends Component {
{ {
window.innerWidth > 1000 ? window.innerWidth > 1000 ?
<div className="desktop-chat d-flex"> <div className="desktop-chat d-flex">
<div className="desktop-chat__banner">
</div>
<div className="desktop-chat__list d-flex flex-column"> <div className="desktop-chat__list d-flex flex-column">
<Search /> <Search />
{this.props.chat_list.map((item, i) => ( {this.props.chat_list.map((item, i) => (

@ -27,9 +27,19 @@
.desktop-chat{ .desktop-chat{
width: 100vw; width: 100vw;
height: 100vh; height: 90vh;
max-width: 1250px; max-width: 1250px;
margin: 0px auto; margin:5vh auto;
box-shadow: 0px 0px 10px rgb(209, 209, 209);
overflow: hidden;
&__banner{
position: fixed;
left: 0px;
top: 0px;
width: 100vw;
height: 150px;
background-color: #7dc241;
}
&__list{ &__list{
width: cacl(100% / 3); width: cacl(100% / 3);
min-width: 350px; min-width: 350px;
@ -39,6 +49,8 @@
box-shadow: 0px 0px 5px rgb(230, 230, 230); box-shadow: 0px 0px 5px rgb(230, 230, 230);
position: relative; position: relative;
padding: 10px; padding: 10px;
z-index: 10;
background-color:white;
&::-webkit-scrollbar{ &::-webkit-scrollbar{
display: none; display: none;
} }

@ -1,26 +1,29 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import Message from './Message'; import Message from "./Message";
import ChatInputs from './Input'; import ChatInputs from "./Input";
import Keyboard from './Keyboard'; import Keyboard from "./Keyboard";
import { RecordState } from 'audio-react-recorder'; import { RecordState } from "audio-react-recorder";
import ReactPlayer from 'react-player'; import ReactPlayer from "react-player";
import ReactAudioPlayer from 'react-audio-player'; import ReactAudioPlayer from "react-audio-player";
import { ToastContainer } from 'react-toastify'; import { ToastContainer } from "react-toastify";
import { list, send, sendKeys } from '../../../Redux/actions/message'; import { list, send, sendKeys } from "../../../Redux/actions/message";
import { info, bio } from '../../../Redux/actions/chat'; import { info, bio } from "../../../Redux/actions/chat";
import { connect } from 'react-redux'; import { connect } from "react-redux";
import Emoji from './Emoji/index'; import Emoji from "./Emoji/index";
import './index.scss'; import "./index.scss";
class List extends Component { class List extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
emoji: false, emoji: false,
counter: 1, counter: 1,
id: window.innerWidth < 1000 ? window.location.href.split('/').pop() * 1 : this.props.id, id:
window.innerWidth < 1000
? window.location.href.split("/").pop() * 1
: this.props.id,
data: {}, data: {},
message: '', message: "",
voice: null, voice: null,
file: null, file: null,
image: null, image: null,
@ -30,15 +33,15 @@ class List extends Component {
}; };
} }
addcounter(type) { addcounter(type) {
if (type === 'parent') { if (type === "parent") {
if (localStorage.getItem('tapType') === 'nothing') { if (localStorage.getItem("tapType") === "nothing") {
localStorage.removeItem('tapType'); localStorage.removeItem("tapType");
return; return;
} else { } else {
this.setState({ counter: this.state.counter + 1 }); this.setState({ counter: this.state.counter + 1 });
} }
} else { } else {
localStorage.setItem('tapType', 'nothing'); localStorage.setItem("tapType", "nothing");
return; return;
} }
} }
@ -69,67 +72,64 @@ class List extends Component {
}); });
}; };
typeText = (type,val) => { typeText = (type, val) => {
if(type === 'text'){ if (type === "text") {
this.setState({ this.setState({
message: val, message: val,
}); });
} } else {
else{ this.setState((prevState) => ({
this.setState(prevState => ({ message: prevState.message + val,
message: prevState.message + val ,
})); }));
} }
}; };
addFile = async (e) => { addFile = async (e) => {
if ( if (
e.target.files[0].type === 'image/apng' || e.target.files[0].type === "image/apng" ||
e.target.files[0].type === 'image/avif' || e.target.files[0].type === "image/avif" ||
e.target.files[0].type === 'image/gif' || e.target.files[0].type === "image/gif" ||
e.target.files[0].type === 'image/jpeg' || e.target.files[0].type === "image/jpeg" ||
e.target.files[0].type === 'image/png' || e.target.files[0].type === "image/png" ||
e.target.files[0].type === 'image/svg+xml' || e.target.files[0].type === "image/svg+xml" ||
e.target.files[0].type === 'image/webp' e.target.files[0].type === "image/webp"
) { ) {
this.setState({ this.setState({
image: URL.createObjectURL(e.target.files[0]), image: URL.createObjectURL(e.target.files[0]),
file: 'fill', file: "fill",
video: null, video: null,
document: null, document: null,
music: null, music: null,
}); });
} else if ( } else if (
e.target.files[0].type === 'video/3gpp' || e.target.files[0].type === "video/3gpp" ||
e.target.files[0].type === 'video/mpeg' || e.target.files[0].type === "video/mpeg" ||
e.target.files[0].type === 'video/mp4' || e.target.files[0].type === "video/mp4" ||
e.target.files[0].type === 'video/ogg' || e.target.files[0].type === "video/ogg" ||
e.target.files[0].type === 'video/quicktime' || e.target.files[0].type === "video/quicktime" ||
e.target.files[0].type === 'video/webm' e.target.files[0].type === "video/webm"
) { ) {
this.setState({ this.setState({
image: null, image: null,
file: 'fill', file: "fill",
video: URL.createObjectURL(e.target.files[0]), video: URL.createObjectURL(e.target.files[0]),
document: null, document: null,
music: null, music: null,
}); });
} else if ( } else if (
e.target.files[0].type === 'audio/3gpp' || e.target.files[0].type === "audio/3gpp" ||
e.target.files[0].type === 'audio/aac' || e.target.files[0].type === "audio/aac" ||
e.target.files[0].type === 'audio/flac' || e.target.files[0].type === "audio/flac" ||
e.target.files[0].type === 'audio/mpeg' || e.target.files[0].type === "audio/mpeg" ||
e.target.files[0].type === 'audio/mp3' || e.target.files[0].type === "audio/mp3" ||
e.target.files[0].type === 'audio/mp4' || e.target.files[0].type === "audio/mp4" ||
e.target.files[0].type === 'audio/ogg' || e.target.files[0].type === "audio/ogg" ||
e.target.files[0].type === 'audio/wav' || e.target.files[0].type === "audio/wav" ||
e.target.files[0].type === 'audio/webm' e.target.files[0].type === "audio/webm"
) { ) {
this.setState({ this.setState({
image: null, image: null,
file: 'fill', file: "fill",
video: null, video: null,
document: null, document: null,
music: URL.createObjectURL(e.target.files[0]), music: URL.createObjectURL(e.target.files[0]),
@ -137,10 +137,13 @@ class List extends Component {
} else { } else {
this.setState({ this.setState({
image: null, image: null,
file: 'fill', file: "fill",
video: null, video: null,
music: null, music: null,
document: { data: URL.createObjectURL(e.target.files[0]), name: e.target.files[0].name }, document: {
data: URL.createObjectURL(e.target.files[0]),
name: e.target.files[0].name,
},
}); });
} }
}; };
@ -157,8 +160,8 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm12', id: "m12",
type: 'normal', type: "normal",
text: prevState.message, text: prevState.message,
voice: null, voice: null,
image: null, image: null,
@ -168,15 +171,15 @@ class List extends Component {
document: null, document: null,
createdAt: now.toString(), createdAt: now.toString(),
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
}, },
})); }));
this.setState({ this.setState({
message: '', message: "",
}); });
} }
}; };
@ -189,9 +192,9 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm9', id: "m9",
text: null, text: null,
type: 'normal', type: "normal",
voice: audioData, voice: audioData,
createdAt: now.toString(), createdAt: now.toString(),
image: null, image: null,
@ -199,8 +202,8 @@ class List extends Component {
document: null, document: null,
music: null, music: null,
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
@ -221,8 +224,8 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm8', id: "m8",
type: 'normal', type: "normal",
text: prevState.message, text: prevState.message,
voice: null, voice: null,
createdAt: now.toString(), createdAt: now.toString(),
@ -231,8 +234,8 @@ class List extends Component {
document: null, document: null,
music: null, music: null,
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
@ -241,7 +244,7 @@ class List extends Component {
this.setState({ this.setState({
file: null, file: null,
image: null, image: null,
message: '', message: "",
}); });
} else if (video !== null) { } else if (video !== null) {
this.setState((prevState) => ({ this.setState((prevState) => ({
@ -250,8 +253,8 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm8', id: "m8",
type: 'normal', type: "normal",
text: prevState.message, text: prevState.message,
voice: null, voice: null,
createdAt: now.toString(), createdAt: now.toString(),
@ -260,8 +263,8 @@ class List extends Component {
document: null, document: null,
music: null, music: null,
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
@ -270,7 +273,7 @@ class List extends Component {
this.setState({ this.setState({
file: null, file: null,
video: null, video: null,
message: '', message: "",
}); });
} else if (music !== null) { } else if (music !== null) {
this.setState((prevState) => ({ this.setState((prevState) => ({
@ -279,9 +282,9 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm8', id: "m8",
text: prevState.message, text: prevState.message,
type: 'normal', type: "normal",
voice: null, voice: null,
createdAt: now.toString(), createdAt: now.toString(),
image: null, image: null,
@ -289,8 +292,8 @@ class List extends Component {
document: null, document: null,
music: music, music: music,
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
@ -299,7 +302,7 @@ class List extends Component {
this.setState({ this.setState({
file: null, file: null,
music: null, music: null,
message: '', message: "",
}); });
} else if (document !== null) { } else if (document !== null) {
this.setState((prevState) => ({ this.setState((prevState) => ({
@ -308,9 +311,9 @@ class List extends Component {
messages: [ messages: [
...prevState.data.messages, ...prevState.data.messages,
{ {
id: 'm8', id: "m8",
text: prevState.message, text: prevState.message,
type: 'normal', type: "normal",
voice: null, voice: null,
createdAt: now.toString(), createdAt: now.toString(),
@ -319,8 +322,8 @@ class List extends Component {
document: document, document: document,
music: null, music: null,
user: { user: {
id: 'u1', id: "u1",
name: 'علی', name: "علی",
}, },
}, },
], ],
@ -329,7 +332,7 @@ class List extends Component {
this.setState({ this.setState({
file: null, file: null,
document: null, document: null,
message: '', message: "",
}); });
} }
}; };
@ -338,7 +341,7 @@ class List extends Component {
this.setState({ this.setState({
file: null, file: null,
document: null, document: null,
message: '', message: "",
image: null, image: null,
video: null, video: null,
voice: null, voice: null,
@ -353,19 +356,29 @@ class List extends Component {
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
let chatroom = document.getElementById('chatroom'); let chatroom = document.getElementById("chatroom");
chatroom.scrollTop = chatroom.scrollHeight + 40; chatroom.scrollTop = chatroom.scrollHeight + 40;
if(prevProps.id !== this.props.id){ if (prevProps.id !== this.props.id) {
this.props.info({ id: window.innerWidth < 1000 ? window.location.href.split('/').pop() * 1 : 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 }); this.props.list({
chatId:
window.innerWidth < 1000
? window.location.href.split("/").pop() * 1
: this.props.id,
});
} }
} }
randomColor() { randomColor() {
let hex = Math.floor(Math.random() * 0x999999); let hex = Math.floor(Math.random() * 0x999999);
let color = '#' + hex.toString(16); let color = "#" + hex.toString(16);
return color; return color;
} }
@ -375,115 +388,261 @@ class List extends Component {
const last = messageList.slice(-1)[0] || {}; const last = messageList.slice(-1)[0] || {};
const userIdx = this.userIdx || {}; const userIdx = this.userIdx || {};
if (Object.keys(userIdx).length == 0) { if (Object.keys(userIdx).length == 0) {
chatInfo.users.map((e) => (userIdx[e.id] = { ...e, color: this.randomColor() })); chatInfo.users.map(
(e) => (userIdx[e.id] = { ...e, color: this.randomColor() })
);
this.userIdx = userIdx; this.userIdx = userIdx;
} }
return ( return (
<div <>
className="chat-body d-flex flex-column nobar " {window.innerWidth < 1000 ? (
onClick={() => this.addcounter('parent')} <div
> className="chat-body d-flex flex-column nobar "
<div onClick={() => this.addcounter("parent")}
className="chat-body__content d-flex flex-column nobar" >
id="chatroom" <div
style={{ className="chat-body__content d-flex flex-column nobar"
paddingTop: 10, id="chatroom"
overflowX: 'hidden', style={{
overflowY: this.state.file !== null ? 'hidden' : 'scroll', paddingTop: 10,
paddingBottom: last.action === 'keyboard' ? 150 : 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 && {chatInfo.users &&
this.state.music === null && messageList.map((message, i) =>
this.state.video === null ? ( this.state.image === null &&
<Message 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()} addcounter={() => this.addcounter()}
isActive={message.id == last.id} onStop={this.onStop}
prevUserId={i > 0 ? messageList[i - 1].userId : 0} stop={this.stop}
isSelf={new Set([101, 103, 106, 108, 110]).has(message.userId * 1)} start={this.start}
key={message.id} cancel={this.cancel}
file={this.state.image} message={this.state.message}
document={this.state.document} recordState={this.state.voice}
message={message} typeText={this.typeText}
user={userIdx[message.userId] || { id: 0, fileId: 0, name: 'null' }} sendMessage={this.sendMessage}
addFile={this.addFile}
file={this.state.file}
parent={this}
/> />
) : null ) : null}
)} {last.action === "keyboard" ? (
{this.state.image !== null ? ( <Keyboard
<div className="chat-body__content--preview d-flex"> options={last.options}
<img src={this.state.image} alt="" /> addcounter={() => this.addcounter()}
</div> />
) : null} ) : null}
{this.state.video !== null ? ( {this.state.emoji ? (
<div className="chat-body__content--preview d-flex"> <div className="chat-body__footer--emoji d-flex flex-column">
<ReactPlayer url={this.state.video} controls /> <Emoji typeText={this.typeText} />
</div>
) : null}
</div> </div>
) : null} <ToastContainer
{this.state.music !== null ? ( position="top-center"
<div className="chat-body__content--preview d-flex"> autoClose={1500}
<ReactAudioPlayer src={this.state.music} controls /> hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</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>
) : null} <div
{this.state.document !== null ? ( className="desktop-chat-body__footer d-flex nobar d-flex flex-column"
<div className="chat-body__content--confirm d-flex"> onClick={() => this.addcounter("nothing")}
<div className="chat-body__content--confirm___box d-flex flex-column"> >
<p>{`ارسال (${this.state.document.name}) به ${this.props.info.title}؟`}</p> {last.action == "text" ? (
<div className="chat-body__content--confirm___box---options d-flex"> <ChatInputs
<button style={{ color: '#00ff00' }} onClick={() => this.sendFile()}> addcounter={() => this.addcounter()}
ارسال onStop={this.onStop}
</button> stop={this.stop}
<button style={{ color: '#ffffff' }} onClick={() => this.cancelSendFile()}> start={this.start}
کنسل cancel={this.cancel}
</button> 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> </div>
</div> ) : null}
</div> </div>
) : null} <ToastContainer
</div> position="top-center"
<div autoClose={1500}
className="chat-body__footer d-flex nobar d-flex flex-column" hideProgressBar={true}
onClick={() => this.addcounter('nothing')} newestOnTop={true}
> closeOnClick
{last.action == 'text' ? ( rtl={true}
<ChatInputs pauseOnFocusLoss
addcounter={() => this.addcounter()} draggable
onStop={this.onStop} pauseOnHover
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} </div>
{last.action === 'keyboard' ? ( ) : null}
<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>
<ToastContainer
position="top-center"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</div>
); );
} }
} }

@ -23,7 +23,7 @@
background: url(../../../assets/images/whatsapp.png); background: url(../../../assets/images/whatsapp.png);
background-size: cover; background-size: cover;
padding: 0px 10px 0px; padding: 0px 10px 0px;
height: calc(100vh); height: 100vh;
position: relative; position: relative;
&--preview { &--preview {
position: absolute; position: absolute;
@ -144,3 +144,135 @@
} }
} }
} }
.desktop-chat-body {
background-color: rgb(210, 196, 214);
// justify-content: flex-start;
width: 100%;
height: 100%;
overflow-x: hidden;
font-family: numeralLight;
&__content {
background: url(../../../assets/images/whatsapp.png);
background-size: cover;
padding: 0px 10px 0px;
height: 90vh;
position: relative;
&--preview {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
background-color: rgb(210, 196, 214);
z-index: 1000;
& img {
width: 100%;
max-height: 400px;
object-fit: scale-down;
}
}
&--confirm {
width: 100vw;
height: 100vh;
position: fixed;
top: 0px;
left: 0px;
justify-content: center;
align-items: center;
z-index: 300;
&___box {
position: relative;
bottom: 50px;
width: 100%;
max-width: 250px;
padding: 10px;
// background: rgb(139, 73, 186);
// background: linear-gradient(180deg, rgb(144, 73, 186) 0%, #64cd82 95%);
text-align: right;
direction: rtl;
color: white;
border-radius: 5px;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 1);
font-size: 16px;
&---options {
justify-self: flex-end;
align-self: flex-start;
width: 110px;
height: 40px;
justify-content: space-between;
& button {
background-color: inherit;
border: none;
font-size: 14px;
&:focus {
outline: none;
}
}
}
}
}
&::-webkit-scrollbar{
width: 0px;
display: none;
}
}
&__footer {
width: 100%;
z-index: 1000;
background-color: rgb(210, 196, 214);
background: url(../../../assets/images/whatsapp.png);
// box-shadow: 0px 0px 5px 2px #9d9595ad;
background-size: cover;
overflow-y: hidden;
overflow-x: hidden;
padding-bottom: 15px;
&::-webkit-scrollbar{
width: 0px;
display: none;
}
&--emoji{
margin-top: 5px;
width: 100%;
background-color: red;
height: 250px;
&::-webkit-scrollbar{
width: 0px;
display: none;
}
// justify-self: flex-end;
// position: absolute;
// bottom: 0px;
// left: 0px;
.MuiBox-root{
max-height : 202px;
min-height: 160px;
overflow-y: scroll;
padding: 10px 10px 0px !important;
}
.MuiTab-root{
padding: 2px !important;
min-height: 22px !important;
min-width: 34px !important;
font-size: 24px !important;
margin-right: 10px !important;
}
.MuiTabs-root{
min-height: 28px !important;
}
.PrivateTabIndicator-colorPrimary-7{
width : 34px !important;
background-color: green !important;
}
.MuiPaper-elevation4{
box-shadow: none !important;
}
}
}
}

@ -1,90 +1,13 @@
import React from 'react'; import React from 'react';
import clsx from 'clsx';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import Info from '../Info/index'; import Info from '../Info/index';
import './index.scss'; import './index.scss';
const drawerWidth = 350;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: theme.spacing(2),
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
drawerHeader: {
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: -drawerWidth,
},
contentShift: {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
},
}));
export default function PersistentDrawerLeft(props) { export default function PersistentDrawerLeft(props) {
const classes = useStyles(); console.log(props.open);
const theme = useTheme();
return ( return (
<div> <div className={`custom-drawer d-flex ${props.open ? 'custom-drawer-active' : ''}`}>
<React.Fragment key={'left'}> <Info parent={props.parent} />
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
open={props.open}
classes={{
paper: classes.drawerPaper,
}}
>
<Info />
</Drawer>
</React.Fragment>
</div> </div>
); );
} }

@ -1,4 +1,32 @@
.MuiDrawer-paper{ .custom-drawer{
position: absolute !important; // width: 350px;
height: 100%;
width: 0px;
position: relative;
display: none;
}
@keyframes drawerActive {
0% {
width: 0px;
}
100% {
width: 350px;
}
}
// @keyframes drawerDeactivate {
// 0% {
// width: 350px;
// }
// 100% {
// width: 0px;
// }
// }
.custom-drawer-active{
width: 350px;
animation-name: drawerActive;
animation-duration: 0.3s;
} }

@ -33,19 +33,26 @@ class Header extends Component {
window.history.back(); window.history.back();
}; };
render() { render() {
const { page, setPage, chatInfo,parent } = this.props; const { page, setPage, chatInfo, parent } = this.props;
const { anchorEl } = this.state; const { anchorEl } = this.state;
return ( return (
<div className="chat-header d-flex align-items-center"> <div className="chat-header d-flex align-items-center">
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<ArrowForwardIcon {window.innerWidth < 1000 ? (
<ArrowForwardIcon
onClick={() =>
page === "chatroom" ? this.back() : setPage("chatroom")
}
style={{ color: "grey", width: 29, height: 29, marginTop: 4 }}
/>
) : null}
<div
onClick={() => onClick={() =>
page === "chatroom" ? this.back() : setPage("chatroom") window.innerWidth < 1000
? setPage("info")
: parent.handleDrawerOpen()
} }
style={{ color: "grey", width: 29, height: 29, marginTop: 4 }}
/>
<div
onClick={() => window.innerWidth < 1000 ? setPage("info") : parent.handleDrawerOpen()}
className="chat-header__info d-flex mr-1" className="chat-header__info d-flex mr-1"
> >
<StatusAvatar /> <StatusAvatar />

@ -1,14 +1,60 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import ChatIcon from '@material-ui/icons/Chat'; import ChatIcon from "@material-ui/icons/Chat";
import FileTabs from './FileTabs'; import FileTabs from "./FileTabs";
import Gallery from './Gallery'; import Gallery from "./Gallery";
import user2 from '../../../assets/images/user2.png'; import VideocamOutlinedIcon from "@material-ui/icons/VideocamOutlined";
import CallOutlinedIcon from "@material-ui/icons/CallOutlined";
import MoreHorizOutlinedIcon from "@material-ui/icons/MoreHorizOutlined";
import Switch from "@material-ui/core/Switch";
import { withStyles } from "@material-ui/core/styles";
import BlockIcon from '@material-ui/icons/Block';
import './index.scss'; import user2 from "../../../assets/images/user2.png";
import "./index.scss";
const maxDesktopSize = 1250;
const fontSize = {
desktop: {
h1: window.innerWidth > maxDesktopSize ? 20 : window.innerWidth / 70,
h2: window.innerWidth > maxDesktopSize ? 18 : window.innerWidth / 80,
p: window.innerWidth > maxDesktopSize ? 16 : window.innerWidth / 85,
h3: window.innerWidth > maxDesktopSize ? 17 : window.innerWidth / 85,
span: window.innerWidth > maxDesktopSize ? 17 : window.innerWidth / 85,
},
};
export default class ChatInfo extends Component { export default class ChatInfo extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
alarms: false,
buttons: [
{
icon: (
<CallOutlinedIcon
style={{ color: "white", width: 40, height: 40 }}
/>
),
backgroundColor: "#00CC69",
},
{
icon: (
<VideocamOutlinedIcon
style={{ color: "white", width: 40, height: 40 }}
/>
),
backgroundColor: "blue",
},
{
icon: (
<MoreHorizOutlinedIcon
style={{ color: "black", width: 40, height: 40 }}
/>
),
backgroundColor: "grey",
},
],
gallery: null, gallery: null,
user: { user: {
profileImages: [ profileImages: [
@ -17,9 +63,14 @@ export default class ChatInfo extends Component {
{ id: 2, src: user2 }, { id: 2, src: user2 },
{ id: 3, src: user2 }, { id: 3, src: user2 },
], ],
name: 'محسن محمدی', username: "MohammadReza",
lastAct: '2 دقیقه پیش آنلاین بوده', educationalInfo: [
bio: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد ', "استاد علوم طبیعی پایه دوازدهم",
"کارشناس ارشد علوم و فنون از دانشگاه تهران",
],
name: "محسن محمدی",
lastAct: "2 دقیقه پیش آنلاین بوده",
bio: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنام",
}, },
}; };
} }
@ -30,31 +81,132 @@ export default class ChatInfo extends Component {
}); });
}; };
handleChange = () => {
this.setState((prevState) => ({
alarms: !prevState.alarms,
}));
};
render() { render() {
const { user, gallery } = this.state; const { user, gallery, buttons, alarms } = this.state;
return ( return (
<div className="chat-info d-flex flex-column"> <>
<div className="chat-info__image d-flex"> {window.innerWidth > 1000 ? (
<img src={user.profileImages[0].src} onClick={() => this.setGallery('profile')} alt="" /> <section className="desktop-contact-info d-flex flex-column">
<div className="chat-info__image--float d-flex"> <header className="desktop-contact-info__header d-flex align-items-center justify-content-center"></header>
<ChatIcon style={{ color: 'white', width: 46, height: 46 }} /> <div className="desktop-contact-info__body d-flex flex-column align-items-center">
</div> <img
</div> className="desktop-contact-info__body--profileImage"
<div className="chat-info__box d-flex flex-column"> src={user.profileImages[0].src}
<div className="chat-info__box--status d-flex flex-column"> alt="عکس کاربر"
<h1>{user.name}</h1> />
<p>{user.lastAct}</p> <h1 style={{ fontSize: fontSize.desktop.h1 }}>{user.name}</h1>
</div> <div className="desktop-contact-info__body--bio d-flex flex-column">
<div className="chat-info__box--description d-flex"> <h2 style={{ fontSize: fontSize.desktop.h2 }}>اطلاعات</h2>
<p>{user.bio}</p> <p style={{ fontSize: fontSize.desktop.p }}>{user.bio}</p>
<h2 style={{ fontSize: fontSize.desktop.h2 }}>مشخصات تحصیلی</h2>
<ul>
{user.educationalInfo.map((item, i) => (
<li key={i}>{item}</li>
))}
</ul>
</div>
<div className="desktop-contact-info__body--buttons d-flex justify-content-around mt-3">
{buttons.map((item, i) => (
<li style={{ backgroundColor: item.backgroundColor }} key={i}>
{item.icon}
</li>
))}
</div>
<div className="desktop-contact-info__body--options d-flex justify-content-between">
<h3 style={{ fontSize: fontSize.desktop.h3 }}>نام کاربری</h3>
<span style={{ fontSize: fontSize.desktop.span }}>
{user.username}@
</span>
</div>
<div className="desktop-contact-info__body--options d-flex justify-content-between align-items-center">
<div>
<h3 style={{ fontSize: fontSize.desktop.h3 }}>اعلانات</h3>
<span style={{color: alarms ? '#00CC69' : 'red'}}>{alarms ? 'روشن ': 'خاموش'}</span>
</div>
<AntSwitch
checked={alarms}
onChange={() => this.handleChange()}
/>
</div>
<div className="desktop-contact-info__body--options d-flex justify-content-between">
<span style={{ color : 'red',fontSize: fontSize.desktop.h3 }}>مسدود سازی مخاطب</span>
<BlockIcon style={{width : 35, height : 35, color : 'red'}} />
</div>
</div>
</section>
) : null}
{window.innerWidth < 1000 ? (
<div className="contact-info d-flex flex-column">
<div className="chat-info__image d-flex">
<img
src={user.profileImages[0].src}
onClick={() => this.setGallery("profile")}
alt=""
/>
<div
className="chat-info__image--float d-flex"
onClick={() => this.props.parent.handleDrawerClose()}
>
<ChatIcon style={{ color: "white", width: 46, height: 46 }} />
</div>
</div>
<div className="chat-info__box d-flex flex-column">
<div className="chat-info__box--status d-flex flex-column">
<h1>{user.name}</h1>
<p>{user.lastAct}</p>
</div>
<div className="chat-info__box--description d-flex">
<p>{user.bio}</p>
</div>
<FileTabs onClick={this.setGallery} />
</div>
{gallery === "profile" ? (
<Gallery data={user.profileImages} onClick={this.setGallery} />
) : null}
{gallery === "media" ? <Gallery data={null} /> : null}
</div> </div>
<FileTabs onClick={this.setGallery} />
</div>
{gallery === 'profile' ? (
<Gallery data={user.profileImages} onClick={this.setGallery} />
) : null} ) : null}
{gallery === 'media' ? <Gallery data={null} /> : null} </>
</div>
); );
} }
} }
const AntSwitch = withStyles((theme) => ({
root: {
width: 28,
height: 16,
padding: 0,
display: "flex",
},
switchBase: {
padding: 2,
color: "",
"&$checked": {
transform: "translateX(12px)",
color: theme.palette.common.white,
"& + $track": {
opacity: 1,
backgroundColor: "#00CC69",
borderColor: "#00CC69",
},
},
},
thumb: {
width: 12,
height: 12,
boxShadow: "none",
},
track: {
border: `1px solid ${theme.palette.grey[500]}`,
borderRadius: 16 / 2,
opacity: 1,
backgroundColor: theme.palette.common.white,
},
checked: {},
}))(Switch);

@ -80,3 +80,82 @@
} }
} }
} }
.desktop-contact-info{
width: 100%;
height: 100%;
overflow-y: scroll;
box-shadow: 0px 0px 7px rgb(214, 214, 214);
background-color:white;
&::-webkit-scrollbar{
display: none;
width: 0px;
}
&__header{
height: 55px;
width : 100%;
border-bottom: 1px solid rgb(224, 224, 224);
}
&__body{
width: 100%;
height: calc(100% - 55px);
padding-top: 20px;
&--profileImage{
width: 100px;
height: 100px;
border-radius: 50%;
}
h1{
color: #6F7074;
margin-top: 10px;
font-family: numeralBold;
}
&--bio{
width: 100%;
padding: 0px 10px;
h2{
font-family: numeralMedium;
color: #00CC69;
}
p{
font-family: numeralLight;
color: #6F7074;
text-align: justify;
letter-spacing: -1px;
}
ul{
padding: 0px;
list-style: none;
li{
font-family: numeralLight;
color: #6F7074;
text-align: justify;
letter-spacing: -1px;
}
}
}
&--buttons{
width: 80%;
margin-bottom: 15px;
li{
list-style: none;
padding: 10px;
border-radius: 50%;
}
}
&--options{
width: calc(100% - 20px);
padding: 15px 0px;
border-bottom: 1px solid rgb(224, 224, 224);
h3{
font-family: numeralMedium;
color: #6F7074;
}
span{
font-family: numeralLight;
color: #6F7074;
}
}
}
}

@ -1,16 +1,16 @@
import React, { Component } from 'react'; import React, { Component } from "react";
import Header from './Header'; import Header from "./Header";
import Body from './Body'; import Body from "./Body";
import Info from './Info'; import Info from "./Info";
import Drawer from './Drawer/index'; import Drawer from "./Drawer/index";
import './index.scss'; import "./index.scss";
export default class ChatRoom extends Component { export default class ChatRoom extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
window.nav = this.nav.bind(this); window.nav = this.nav.bind(this);
this.state = { this.state = {
page: 'chatroom', page: "chatroom",
open: false, open: false,
}; };
} }
@ -19,15 +19,15 @@ export default class ChatRoom extends Component {
}; };
handleDrawerOpen = () => { handleDrawerOpen = () => {
this.setState({ this.setState({
open: true, open: true,
}) });
}; };
handleDrawerClose = () => { handleDrawerClose = () => {
this.setState({ this.setState({
open: false, open: false,
}) });
}; };
setPage = (val) => { setPage = (val) => {
@ -37,19 +37,39 @@ export default class ChatRoom extends Component {
}; };
render() { render() {
return ( return (
<div className="chat-room d-flex flex-column"> <>
<Header page={this.state.page} setPage={this.setPage} parent={this} /> {window.innerWidth > 1000 ? (
{this.state.page === 'chatroom' ? (
<> <>
<Body id={this.props.id} setPage={this.setPage} /> <div className="desktop-chat-room d-flex flex-column">
<Header
page={this.state.page}
setPage={this.setPage}
parent={this}
/>
<Body id={this.props.id} setPage={this.setPage} />
</div>
<Drawer open={this.state.open} parent={this} /> <Drawer open={this.state.open} parent={this} />
</> </>
) : ( ) : null}
<> {window.innerWidth < 1000 ? (
<Info /> <div className="chat-room d-flex flex-column">
</> <Header
)} page={this.state.page}
</div> setPage={this.setPage}
parent={this}
/>
{this.state.page === "chatroom" ? (
<>
<Body id={this.props.id} setPage={this.setPage} />
</>
) : (
<>
<Info />
</>
)}
</div>
) : null}
</>
); );
} }
} }

@ -1,8 +1,6 @@
@media screen and (max-width: 4500px) { @media screen and (max-width: 4500px) {
.chat-room { .chat-room {
flex: 1; flex: 1;
background: rgb(139, 73, 186);
background: linear-gradient(180deg, rgb(144, 73, 186) 0%, #64cd82 22%);
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
width: 100vw; width: 100vw;
@ -31,3 +29,34 @@
} }
} }
} }
.desktop-chat-room {
flex: 1;
height: 100%;
overflow: hidden;
width: 100vw;
position: relative;
overflow-x: hidden;
&__status {
border-top-left-radius: 40px;
border-top-right-radius: 40px;
height: 150px;
background: rgb(106, 103, 250);
position: relative;
align-items: center;
justify-content: flex-start;
h1 {
font-size: 18px;
margin: 0;
letter-spacing: -1px;
font-family: IRANSansNumeralLight;
color: white;
font-weight: 100;
}
p {
font-size: 12px;
color: white;
margin: 0px;
}
}
}
Loading…
Cancel
Save