diff --git a/package.json b/package.json
index d53a7ad..597dfdb 100644
--- a/package.json
+++ b/package.json
@@ -8,18 +8,25 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
+ "array-move": "^3.0.1",
+ "audio-react-recorder": "^1.0.4",
"axios": "^0.21.1",
"bootstrap": "^5.0.1",
"jalali-moment": "^3.3.10",
"prettier": "^2.3.1",
"prop-types": "^15.7.2",
"react": "^17.0.2",
+ "react-audio-player": "^0.17.0",
"react-dom": "^17.0.2",
"react-elastic-carousel": "^0.11.5",
+ "react-leaflet": "^3.2.0",
+ "react-player": "^2.9.0",
"react-qr-scanner": "^1.0.0-alpha.7",
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
+ "react-sortable-hoc": "^2.0.0",
+ "react-swipeable-views": "^0.14.0",
"react-toastify": "^7.0.4",
"redux": "^4.1.0",
"redux-devtools-extension": "^2.13.9",
diff --git a/src/AppRouter.js b/src/AppRouter.js
index cee95d1..d0cea3e 100644
--- a/src/AppRouter.js
+++ b/src/AppRouter.js
@@ -12,6 +12,8 @@ import QR from './views/QR/index';
import Auth from './views/Auth/index';
import QRScan from './views/QRScan/index';
import Activation from './views/Activation/index';
+import ChatList from './views/ChatList/index';
+import Chatroom from './views/ChatRoom/index';
class AppRouter extends Component {
constructor(props) {
@@ -64,6 +66,15 @@ class AppRouter extends Component {
+
+
+
+ {
+ window.innerWidth < 1000 ?
+
+
+ : null
+ }
);
diff --git a/src/Redux/actions/message.js b/src/Redux/actions/message.js
index 14d7279..064898f 100644
--- a/src/Redux/actions/message.js
+++ b/src/Redux/actions/message.js
@@ -1,13 +1,13 @@
-// import proxy from '../proxy';
-// export const list =
-// (data = {}) =>
-// async (dispatch) =>
-// (await proxy.get('message/list', data)).dispatch(dispatch);
-// export const send =
-// (data = {}) =>
-// async (dispatch) =>
-// (await proxy.post('message/send', data)).dispatch(dispatch);
-// export const sendKeys =
-// (data = {}) =>
-// async (dispatch) =>
-// (await proxy.post('message/sendKeys', data)).dispatch(dispatch);
+import proxy from '../proxy';
+export const list =
+ (data = {}) =>
+ async (dispatch) =>
+ (await proxy.get('message/list', data)).dispatch(dispatch);
+export const send =
+ (data = {}) =>
+ async (dispatch) =>
+ (await proxy.post('message/send', data)).dispatch(dispatch);
+export const sendKeys =
+ (data = {}) =>
+ async (dispatch) =>
+ (await proxy.post('message/sendKeys', data)).dispatch(dispatch);
diff --git a/src/Redux/proxy.js b/src/Redux/proxy.js
index 7b3ea3c..c3ab403 100644
--- a/src/Redux/proxy.js
+++ b/src/Redux/proxy.js
@@ -1,6 +1,6 @@
import axios from 'axios';
import { toast } from 'react-toastify';
-const baseURL = 'https://chatstory.ir/api/v1'; //"https://chatstory.ir/api/v1";
+const baseURL = 'https://chatstory.ir/api/v1'; //'https://chatstory.ir/api/v1';
const token = '';
const loginURL = 'user/otp/login';
const logoutURL = 'user/logout';
@@ -48,7 +48,7 @@ class Proxy {
localStorage.setItem('refresh', login.refreshToken);
delete login.refreshToken;
localStorage.setItem('userData', JSON.stringify(login));
- if (data !== {}) window.router.setState({ islogin: true });
+ if (data != {}) window.router.setState({ islogin: true });
return this.result('login', login);
};
logout = async () => {
@@ -62,7 +62,7 @@ class Proxy {
let refresh = localStorage.getItem('refresh');
let userData = localStorage.getItem('userData');
if (!refresh) return false;
- if (refresh === 'undefined') {
+ if (refresh == 'undefined') {
localStorage.removeItem('refresh');
localStorage.removeItem('userData');
return false;
diff --git a/src/Redux/reducers/message.js b/src/Redux/reducers/message.js
index 4f00511..2cda7d0 100644
--- a/src/Redux/reducers/message.js
+++ b/src/Redux/reducers/message.js
@@ -1,16 +1,16 @@
-// const initialState = {
-// list: [],
-// };
-// export default function chat(state = initialState, action) {
-// let { type, data } = action;
-// switch (type) {
-// case 'message/list':
-// return { ...state, list: data };
-// case 'message/send':
-// return { ...state, list: [...list, ...data] };
-// case 'message/sendKeys':
-// return { ...state, list: [...list, ...data] };
-// default:
-// return state;
-// }
-// }
+const initialState = {
+ list: [],
+};
+export default function chat(state = initialState, action) {
+ let { type, data } = action;
+ switch (type) {
+ case 'message/list':
+ return { ...state, list: data };
+ case 'message/send':
+ return { ...state, list: [...state.list, ...data] };
+ case 'message/sendKeys':
+ return { ...state, list: [...state.list, ...data] };
+ default:
+ return state;
+ }
+}
diff --git a/src/assets/images/whatsapp.png b/src/assets/images/whatsapp.png
new file mode 100644
index 0000000..301d951
Binary files /dev/null and b/src/assets/images/whatsapp.png differ
diff --git a/src/views/ChatList/Chat/index.js b/src/views/ChatList/Chat/index.js
new file mode 100644
index 0000000..8697ef4
--- /dev/null
+++ b/src/views/ChatList/Chat/index.js
@@ -0,0 +1,22 @@
+import React, { Component } from 'react';
+import { Link } from 'react-router-dom';
+import moment from 'jalali-moment';
+import Avatar from '@material-ui/core/Avatar';
+
+import './index.scss';
+export default class Chat extends Component {
+ render() {
+ const { data } = this.props;
+ return (
+
+
+
+
{data.name}
+
{data.lastMessage.slice(0, 40) + '...'}
+
{data.badge}
+
{moment(data.date || new Date()).format('jD/jM hh:mm')}
+
+
+ );
+ }
+}
diff --git a/src/views/ChatList/Chat/index.scss b/src/views/ChatList/Chat/index.scss
new file mode 100644
index 0000000..9e79cd4
--- /dev/null
+++ b/src/views/ChatList/Chat/index.scss
@@ -0,0 +1,72 @@
+@media screen and (max-width: 4500px) {
+ .chat {
+ width: 100%;
+ direction: rtl;
+ align-items: center;
+ margin-bottom: 10px;
+ position: relative;
+ padding: 0px 0px 0px;
+ text-decoration: none;
+ .avatar {
+ background-color: #b4b4b4;
+ width: 55px;
+ height: 55px;
+ // padding: 5px;
+ border-radius: 35px;
+ object-fit: cover;
+ }
+ &__data {
+ text-align: right;
+ flex: 1;
+ justify-content: space-around;
+ height: 100%;
+ padding: 10px 10px 20px;
+ border-bottom: rgba(209, 208, 208, 0.7) solid 1px;
+
+ &--name {
+ font-size: 18px;
+ }
+ h1 {
+ font-family: numeralMedium;
+ font-size: 15px;
+ margin: 0;
+ font-weight: 600;
+ color: #6f7074;
+ }
+ p {
+ font-size: 12px;
+ margin: 0;
+ max-width: calc(100vw - 100px);
+ font-family: numeralLight;
+ color: #6f7074;
+ }
+ span {
+ background-color: #25d366;
+ min-width: 20px;
+ font-size: 11px;
+ height: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 13px;
+ position: absolute;
+ padding-top: 1px;
+ padding: 0 5px;
+ left: 20px;
+ bottom: 10px;
+ color: white;
+ }
+ div {
+ color: rgb(99, 99, 99);
+ position: absolute;
+ left: 20px;
+ font-size: 12px;
+ top: 5px;
+ }
+ }
+ }
+}
+
+a{
+ text-decoration: none;
+}
diff --git a/src/views/ChatList/index.js b/src/views/ChatList/index.js
new file mode 100644
index 0000000..a331790
--- /dev/null
+++ b/src/views/ChatList/index.js
@@ -0,0 +1,37 @@
+import React, { Component } from 'react';
+import {Link} from 'react-router-dom';
+import { list } from '../../Redux/actions/chat';
+import { connect } from 'react-redux';
+import ChatIcon from '@material-ui/icons/Chat';
+import Chat from './Chat/index';
+import Navbar from '../Home/Navbar/index';
+
+
+import './index.scss';
+
+class ChatList extends Component {
+ componentDidMount() {
+ this.props.list();
+ }
+ render() {
+ return (
+
+
+ {this.props.chat_list.map((item, i) => (
+
+ ))}
+
+
+
+
+ );
+ }
+}
+
+export default connect(
+ (state) => ({
+ chat_list: state.chat.list || [],
+ }),
+ { list }
+)(ChatList);
+
diff --git a/src/views/ChatList/index.scss b/src/views/ChatList/index.scss
new file mode 100644
index 0000000..eb2b27d
--- /dev/null
+++ b/src/views/ChatList/index.scss
@@ -0,0 +1,26 @@
+@media screen and (max-width: 4500px) {
+ .chat-list {
+ flex: 1;
+ padding: 70px 14px 10px;
+ position: relative;
+ background: white;
+ &__float {
+ position: fixed;
+ height: 50px;
+ width: 50px;
+ bottom: 20px;
+ left: 20px;
+ justify-content: center;
+ align-items: center;
+ background-color: #01db38;
+ border-radius: 100px;
+
+ box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.4);
+ & svg {
+ color: white;
+ width: 25px;
+ height: 25px;
+ }
+ }
+ }
+}
diff --git a/src/views/ChatRoom/Body/Emoji/index.js b/src/views/ChatRoom/Body/Emoji/index.js
new file mode 100644
index 0000000..0b5f1e3
--- /dev/null
+++ b/src/views/ChatRoom/Body/Emoji/index.js
@@ -0,0 +1,224 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { makeStyles } from '@material-ui/core/styles';
+import AppBar from '@material-ui/core/AppBar';
+import Tabs from '@material-ui/core/Tabs';
+import Tab from '@material-ui/core/Tab';
+import Typography from '@material-ui/core/Typography';
+import Box from '@material-ui/core/Box';
+
+import './index.scss';
+
+const Smileys = [
+ '😃',
+ '😃',
+ '😄',
+ '😁',
+ '😆',
+ '😅',
+ '😂',
+ '🤣',
+ '🥲',
+ '☺️',
+ '😊',
+ '😇',
+ '🙂',
+ '🙃',
+ '😉',
+ '😌',
+ '😍',
+ '🥰',
+ '😘',
+ '😗',
+ '😙',
+ '😚',
+ '😋',
+ '😛',
+ '😝',
+ '😜',
+ '🤪',
+ '🤨',
+ '🧐',
+ '🤓',
+ '😎',
+ '🥸',
+ '🤩',
+ '🥳',
+ '😏',
+ '😒',
+ '😞',
+ '😔',
+ '😟',
+ '😕',
+ '🙁',
+ '☹️',
+ '😣',
+ '😖',
+ '😫',
+ '😩',
+ '🥺',
+ '😢',
+ '😭',
+ '😤',
+ '😠',
+ '😡',
+ '🤬',
+ '🤯',
+ '😳',
+ '🥵',
+ '🥶',
+ '😱',
+ '😨',
+ '😰',
+ '😥',
+ '😓',
+ '🤗',
+ '🤔',
+ '🤭',
+ '🤫',
+ '🤥',
+ '😶',
+ '😐',
+ '😑',
+ '😬',
+ '🙄',
+ '😯',
+ '😦',
+ '😧',
+ '😮',
+ '😲',
+ '🥱',
+ '😴',
+ '🤤',
+ '😪',
+ '😵',
+ '🤐',
+ '🥴',
+ '🤢',
+ '🤮',
+ '🤧',
+ '😷',
+ '🤒',
+ '🤕',
+ '🤑',
+ '🤠',
+ '😈',
+ '👿',
+ '👹',
+ '👺',
+ '🤡',
+ '💩',
+ '👻',
+ '💀',
+ '☠️',
+ '👽',
+ '👾',
+ '🤖',
+ '🎃',
+ '😺',
+ '😸',
+ '😹',
+ '😻',
+ '😼',
+ '😽',
+ '🙀',
+ '😿',
+ '😾',
+];
+
+const animals = [
+ '🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐻❄️', '🐨', '🐯', '🦁', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇', '🐺', '🐗', '🐴', '🦄', '🐝', '🪱', '🐛', '🦋', '🐌', '🐞', '🐜', '🪰', '🪲', '🪳', '🦟', '🦗', '🕷', '🕸', '🦂', '🐢', '🐍', '🦎', '🦖', '🦕', '🐙', '🦑', '🦐', '🦞', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳', '🐋', '🦈', '🐊', '🐅', '🐆', '🦓', '🦍', '🦧', '🦣', '🐘', '🦛', '🦏', '🐪', '🐫', '🦒', '🦘', '🦬', '🐃', '🐂', '🐄', '🐎', '🐖', '🐏', '🐑', '🦙', '🐐', '🦌', '🐕', '🐩', '🦮', '🐕🦺', '🐈', '🐈⬛', '🪶', '🐓', '🦃', '🦤', '🦚', '🦜', '🦢', '🦩', '🕊', '🐇', '🦝', '🦨', '🦡', '🦫', '🦦', '🦥', '🐁', '🐀', '🐿', '🦔', '🐾', '🐉', '🐲', '🌵', '🎄', '🌲', '🌳', '🌴', '🪵', '🌱', '🌿', '☘️', '🍀', '🎍', '🪴', '🎋', '🍃', '🍂', '🍁', '🍄', '🐚', '🪨', '🌾', '💐', '🌷', '🌹', '🥀', '🌺', '🌸', '🌼', '🌻', '🌞', '🌝', '🌛', '🌜', '🌚', '🌕', '🌖', '🌗', '🌘', '🌑', '🌒', '🌓', '🌔', '🌙', '🌎', '🌍', '🌏', '🪐 ', '💫', '⭐️', '🌟', '✨', '⚡️', '☄️', '💥', '🔥', '🌪', '🌈', '☀️', '🌤', '⛅️', '🌥', '☁️', '🌦', '🌧', '⛈', '🌩', '🌨', '❄️', '☃️', '⛄️', '🌬', '💨', '💧', '💦', '☔️', '☂️', '🌊', '🌫'
+];
+
+function TabPanel(props) {
+ const { children, value, index, ...other } = props;
+
+ return (
+
+ {value === index && (
+
+ {children}
+
+ )}
+
+ );
+}
+
+TabPanel.propTypes = {
+ children: PropTypes.node,
+ index: PropTypes.any.isRequired,
+ value: PropTypes.any.isRequired,
+};
+
+function a11yProps(index) {
+ return {
+ id: `scrollable-force-tab-${index}`,
+ 'aria-controls': `scrollable-force-tabpanel-${index}`,
+ };
+}
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ flexGrow: 1,
+ width: '100%',
+ backgroundColor: theme.palette.background.paper,
+ flexDirection: 'row-reverse'
+ },
+ list: {
+ flex: 1,
+ width: '100%',
+ flexDirection: 'row-reverse'
+ },
+}));
+
+export default function ScrollableTabsButtonForce(props) {
+ const classes = useStyles();
+ const [value, setValue] = React.useState(0);
+
+ const handleChange = (event, newValue) => {
+ setValue(newValue);
+ };
+ console.log(props.emojies[0]);
+ return (
+
+
+
+ {props.emojies.map((item) => (
+
+ ))}
+
+
+ {props.emojies.map((item) => (
+
+
+ {item.list.map((jojo,i) => (
+ props.typeText('emoji',jojo)} style={{fontSize: 24, width: 30, height:30 }} className="m-1">{jojo}
+ ))}
+
+
+ ))}
+
+ );
+}
+
+ScrollableTabsButtonForce.defaultProps = {
+ emojies: [
+ { type: 'Smileys', list: Smileys, id: 0 },
+ { type: 'Animals', list: animals, id: 1 },
+ ],
+};
+
diff --git a/src/views/ChatRoom/Body/Emoji/index.scss b/src/views/ChatRoom/Body/Emoji/index.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/views/ChatRoom/Body/Input/index.js b/src/views/ChatRoom/Body/Input/index.js
new file mode 100644
index 0000000..4e7f62d
--- /dev/null
+++ b/src/views/ChatRoom/Body/Input/index.js
@@ -0,0 +1,171 @@
+import React, { Component } from 'react';
+import AudioReactRecorder from 'audio-react-recorder';
+import MicIcon from '@material-ui/icons/Mic';
+import CheckIcon from '@material-ui/icons/Check';
+import CloseIcon from '@material-ui/icons/Close';
+import AttachmentIcon from '@material-ui/icons/Attachment';
+import TextField from '@material-ui/core/TextField';
+import SendIcon from '@material-ui/icons/Send';
+import EmojiEmotions from '@material-ui/icons/EmojiEmotions';
+import KeyboardIcon from '@material-ui/icons/Keyboard';
+import PhotoCamera from '@material-ui/icons/PhotoCamera';
+
+import './index.scss';
+export default class ChatInputs extends Component {
+ state = {
+ emoji: false,
+ };
+ render() {
+ const {
+ onStop,
+ stop,
+ start,
+ recordState,
+ cancel,
+ typeText,
+ message,
+ sendMessage,
+ addFile,
+ file,
+ addcounter,
+ } = this.props;
+ return (
+
+
+ {/*
+
+ {
+ recordState ?
+
: null
+ } */}
+
+
+
+ {(recordState === null && message === '' && file === null) ||
+ (recordState && recordState.url && message === '' && file === null) ? (
+
+
+
+ ) : null}
+ {message !== '' || file !== null ? (
+
addcounter()}>
+
+
+ ) : null}
+ {recordState === 'start' ? (
+ <>
+
+
+
+
+
+
+ >
+ ) : null}
+
+
+ {recordState !== 'start' ? (
+
+ {message === '' ? (
+
+ ) : null}
+
+
+
typeText('text',e.target.value)}
+ multiline
+ style={{
+ marginRight: 5,
+ }}
+ />
+ {this.props.parent.state.emoji ? (
+ this.props.parent.setState({ emoji: false })}
+ />
+ ) : (
+ this.props.parent.setState({ emoji: true })}
+ />
+ )}
+
+ ) : null}
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Input/index.scss b/src/views/ChatRoom/Body/Input/index.scss
new file mode 100644
index 0000000..309440b
--- /dev/null
+++ b/src/views/ChatRoom/Body/Input/index.scss
@@ -0,0 +1,97 @@
+@media screen and (max-width: 4500px) {
+ .chat-inputs {
+ border-bottom-right-radius: 40px;
+ border-bottom-left-radius: 40px;
+ width: 100%;
+ padding: 2px 5px 0px;
+ align-items: flex-end;
+ justify-content: flex-end;
+ &__box {
+ width: 100%;
+ border-radius: 30px;
+ background-color: #fff;
+ box-shadow: 0 0.4px 1px 0px #aaa;
+ // background: rgb(18, 15, 153);
+ // background: linear-gradient(90deg, rgba(18, 15, 153, 1) 0%, rgba(105, 9, 121, 1) 60%);
+ min-height: 45px;
+ margin-left: 10px;
+ align-items: center;
+ padding: 8px 15px;
+ &--file {
+ width: 30px;
+ height: 30px;
+ position: relative;
+ align-self: flex-end;
+ input[type='file'] {
+ opacity: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 100;
+ position: relative;
+ }
+ }
+ // input[type=text]{
+ // flex : 1;
+ // background-color: inherit;
+ // border : 0px;
+ // text-align: right;
+ // direction: rtl;
+ // color : white;
+ // font-size: 14px;
+ // &:focus{
+ // outline:none;
+ // }
+ // &::placeholder{
+ // color : white;
+ // }
+ // }
+ .MuiTextField-root {
+ flex: 1;
+ border: 0px !important;
+ outline: none !important;
+ text-align: right;
+ textarea {
+ text-align: right;
+ direction: rtl;
+ color: black;
+ font-size: 14px;
+ font-family: IRANSansNumeralLight;
+ }
+ }
+ }
+ &__voice {
+ &--icon {
+ width: 50px;
+ height: 50px;
+ border-radius: 30px;
+ justify-content: center;
+ align-items: center;
+ background-color: white;
+ }
+ }
+ }
+}
+
+.audio-react-recorder {
+ display: none;
+}
+
+.MuiInput-underline:hover:not(.Mui-disabled):before {
+ border-bottom: 0px !important;
+}
+
+.MuiInput-underline:hover:not(.Mui-disabled):before {
+ border-bottom: 0px !important;
+}
+
+.MuiInput-underline:hover:not(.Mui-disabled):before {
+ border-bottom: 0px !important;
+}
+
+.MuiInput-underline:after {
+ border-bottom: 0px !important;
+}
+
+.MuiInput-underline:before {
+ border-bottom: 0px !important;
+}
diff --git a/src/views/ChatRoom/Body/Keyboard/index.js b/src/views/ChatRoom/Body/Keyboard/index.js
new file mode 100644
index 0000000..b458f1e
--- /dev/null
+++ b/src/views/ChatRoom/Body/Keyboard/index.js
@@ -0,0 +1,32 @@
+import React, { Component } from 'react';
+import Carousel from 'react-elastic-carousel';
+import './index.scss';
+export default function Keyboard({ options, action }) {
+ return (
+
+
+ {options.map((row, i) => (
+
+ ))}
+
+
+ );
+}
+
+const Row = ({ row, action }) => {
+ return (
+
+ {row.map((item, i) => (
+
+ ))}
+
+ );
+};
+
+const KeyboardItem = ({ item, action }) => {
+ return (
+ action(item)}>
+ {item.text}
+
+ );
+};
diff --git a/src/views/ChatRoom/Body/Keyboard/index.scss b/src/views/ChatRoom/Body/Keyboard/index.scss
new file mode 100644
index 0000000..fa9c43f
--- /dev/null
+++ b/src/views/ChatRoom/Body/Keyboard/index.scss
@@ -0,0 +1,74 @@
+@media screen and (max-width: 4500px) {
+ .chat-suggest {
+ & .rec-slider-container {
+ margin: 0 !important;
+ }
+ // border-bottom-right-radius: 40px;
+ // border-bottom-left-radius: 40px;
+ width: 100%;
+ // height : 40px;
+ padding: 2px 0px 0px;
+ align-items: flex-start;
+ margin-top: 5px;
+ &__row {
+ width: 100%;
+ &--item {
+ padding: 8px 6px;
+ background-color: white;
+ border-radius: 5px;
+ margin: 0 2px;
+ width: 100% !important;
+ justify-content: right;
+ color: black;
+ height: 90px;
+ text-align: right;
+ }
+ }
+ }
+}
+
+.portrait-slider {
+ width: 100% !important;
+ height: 100% !important;
+ position: relative;
+ padding: 0px 6px 0px;
+ margin-bottom: 2px;
+ justify-content: center !important;
+}
+
+.rec-dot_active {
+ background-color: white !important;
+ color: white !important;
+ // box-shadow: 0 0 1px rgba(255, 255, 255, 1) !important;
+}
+
+.Carousel-button-10 {
+ background-color: white !important;
+}
+.rec-pagination {
+ z-index: 600;
+ margin-top: 2px !important;
+ // position: absolute;
+ // top: -12px;
+ // left: calc(50% - 20px) !important;
+ & button {
+ background-color: grey;
+ margin: 2px !important;
+ box-shadow: 0px 0px 0px rgba(255, 255, 255, 1);
+ }
+}
+
+// .guuruq{
+// box-shadow: 0 1px 2px rgba(0, 0, 0, 0%);
+// }
+
+// .cJeRRR{
+// background-color: white !important;
+
+// }
+
+// .cJeRRR:hover, .cJeRRR:focus{
+// cursor: pointer;
+// box-shadow: 0px 0px 0px rgba(255,255,255,1) !important;
+// background-color: white !important;
+// }
diff --git a/src/views/ChatRoom/Body/Message/Comment/index.js b/src/views/ChatRoom/Body/Message/Comment/index.js
new file mode 100644
index 0000000..e40d64a
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Comment/index.js
@@ -0,0 +1,83 @@
+import React, { Component } from 'react';
+import DoneIcon from '@material-ui/icons/Done';
+import DoneAllIcon from '@material-ui/icons/DoneAll';
+import EditIcon from '@material-ui/icons/Edit';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+import './index.scss';
+import Menu from '@material-ui/core/Menu';
+import MenuItem from '@material-ui/core/MenuItem';
+import ReplyIcon from '@material-ui/icons/Reply';
+import ForwardIcon from '@material-ui/icons/Forward';
+import DeleteIcon from '@material-ui/icons/Delete';
+import ScheduleIcon from '@material-ui/icons/Schedule';
+const menu = [
+ { text: 'پسند', icon: FavoriteIcon, onClick: () => {} },
+ { text: 'تبادل نظر', icon: TextsmsIcon, onClick: () => {} },
+ { text: 'پاسخ', icon: ReplyIcon, onClick: () => {} },
+ { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} },
+];
+const selfMenu = [
+ { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} },
+ { text: 'ویرایش', icon: EditIcon, onClick: () => {} },
+ { text: 'حذف', icon: DeleteIcon, onClick: () => {} },
+];
+export default class Comment extends Component {
+ state = { messageMenu: null };
+ handleClose = () => {
+ this.setState({
+ messageMenu: null,
+ });
+ };
+ handleClick = (event) => {
+ this.setState({
+ messageMenu: event.currentTarget,
+ });
+ };
+ render() {
+ const { message, user, document, children, addcounter } = this.props;
+ const { messageMenu } = this.state;
+ const hasavatar = prevUserId != message.userId;
+
+ return (
+
+
+
+
addcounter('nothing')}>
+
+
+
+
+
+
{message.text}
+
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/Comment/index.scss b/src/views/ChatRoom/Body/Message/Comment/index.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/views/ChatRoom/Body/Message/Inline/index.js b/src/views/ChatRoom/Body/Message/Inline/index.js
new file mode 100644
index 0000000..bccb404
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Inline/index.js
@@ -0,0 +1,46 @@
+import React, { Component } from 'react';
+import Avatar from '@material-ui/core/Avatar';
+
+import './index.scss';
+import { toast } from 'react-toastify';
+
+export default class Message2D extends Component {
+ state = { value: this.props.message.value };
+ click(id) {
+ if (this.props.isActive) {
+ this.setState({ value: id });
+ toast.success('ثبت شد');
+ this.props.action();
+ }
+ }
+ render() {
+ const { message, user, isSelf, isActive, action } = this.props;
+ return (
+
+
+ {message.options.map((option, i) => (
+
+ {option.map((item, i) => (
+
this.click(item.id)}
+ >
+ {item.name}
+
+ ))}
+
+ ))}
+
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/Inline/index.scss b/src/views/ChatRoom/Body/Message/Inline/index.scss
new file mode 100644
index 0000000..3b1c3ba
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Inline/index.scss
@@ -0,0 +1,101 @@
+@media screen and (max-width: 4500px) {
+ .message-2d {
+ display: flex;
+ justify-content: flex-end;
+ // width: 100%;
+ position: relative;
+ img {
+ width: 65px;
+ height: 65px;
+ object-fit: cover;
+ border-radius: 30px;
+ border: 3px solid rgba(201, 201, 201, 0.857);
+ position: relative;
+ top: 20px;
+ z-index: 50;
+ }
+ &__text {
+ justify-content: flex-end;
+ width: 100%;
+ padding: 15px 15px 5px;
+ background-color: white;
+ border-radius: 5px;
+ position: relative;
+ margin-bottom: 5px;
+ text-align: right;
+ direction: rtl;
+ p {
+ width: 100%;
+ text-align: right;
+ font-size: 16px;
+ // font-family: IRANSansNumeralBold;
+ }
+ }
+ &__options {
+ width: 100%;
+ z-index: 200;
+ &--row {
+ width: 100%;
+ justify-content: space-around;
+ div {
+ background-color: rgb(255 255 255 / 40%);
+ border-radius: 10px;
+ justify-content: center;
+ align-items: center;
+ margin: 2px 3px;
+ padding: 6px;
+ flex: 1;
+ text-align: center;
+ span {
+ font-size: 16px;
+ color: black;
+ font-weight: 400;
+ }
+ }
+ }
+ &--radio {
+ width: calc(50% - 6px);
+ margin: 3px;
+ padding: 10px;
+ text-align: center;
+ font-size: 16px;
+ color: black;
+ font-weight: 600;
+ border-radius: 5px;
+ }
+ &--draggable {
+ background-color: rgb(255 255 255 / 40%);
+ border-radius: 10px;
+ justify-content: center;
+ align-items: center;
+ margin: 2px 3px;
+ padding: 6px;
+ font-size: 16px;
+ color: black;
+ font-weight: 600;
+ position: relative;
+ }
+ }
+ & button {
+ background: #64cd82;
+ // background: linear-gradient(180deg, rgb(163, 73, 186) 0%, rgb(108, 72, 191) 52%);
+ width: 100%;
+ margin: 3px auto 0px;
+ border: none;
+ padding: 5px 0px;
+ font-size: 18px;
+ border-radius: 10px;
+ color: white;
+ }
+ }
+}
+
+.MuiGrid-container {
+ display: flex !important;
+ width: 100% !important;
+ margin: 0px !important;
+ background-color: rgb(255 255 255 / 40%);
+ justify-content: center !important;
+ align-items: center !important;
+ border-radius: 10px;
+}
diff --git a/src/views/ChatRoom/Body/Message/MultiSelect/index.js b/src/views/ChatRoom/Body/Message/MultiSelect/index.js
new file mode 100644
index 0000000..aacd485
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/MultiSelect/index.js
@@ -0,0 +1,63 @@
+import React, { Component } from 'react';
+import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
+import Avatar from '@material-ui/core/Avatar';
+import { toast } from 'react-toastify';
+
+export default class RadioMessage extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ value: this.props.message.value,
+ };
+ }
+
+ handleRadioChange = (newValue) => {
+ if (this.props.isActive)
+ this.setState({
+ value: newValue,
+ });
+ };
+
+ render() {
+ const { message, user, isSelf, isActive } = this.props;
+ return (
+
+
+ {message.options.map((row) => (
+
+ ))}
+
+ {isActive && (
+
+ )}
+
+ );
+ }
+}
+
+const Row = (props) => {
+ return (
+
+ {props.list.map((item) => (
+
+ ))}
+
+ );
+};
+
+const Item = (props) => {
+ return (
+ props.handleRadioChange(props.item.name)}
+ style={{
+ backgroundColor: props.item.name === props.value ? '#6f42c1' : 'rgb(181 224 252 / 47%)',
+ color: props.item.name === props.value ? 'white' : 'black',
+ }}
+ >
+ {props.item.name}
+
+ );
+};
diff --git a/src/views/ChatRoom/Body/Message/Normal/index.js b/src/views/ChatRoom/Body/Message/Normal/index.js
new file mode 100644
index 0000000..e9be640
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Normal/index.js
@@ -0,0 +1,245 @@
+import React, { Component } from 'react';
+import ReactAudioPlayer from 'react-audio-player';
+import ReactPlayer from 'react-player';
+import CloudDownloadIcon from '@material-ui/icons/CloudDownload';
+import Avatar from '@material-ui/core/Avatar';
+import moment from 'jalali-moment';
+import DoneIcon from '@material-ui/icons/Done';
+import DoneAllIcon from '@material-ui/icons/DoneAll';
+import EditIcon from '@material-ui/icons/Edit';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+import './index.scss';
+import Menu from '@material-ui/core/Menu';
+import MenuItem from '@material-ui/core/MenuItem';
+import ReplyIcon from '@material-ui/icons/Reply';
+import ForwardIcon from '@material-ui/icons/Forward';
+import DeleteIcon from '@material-ui/icons/Delete';
+import FavoriteIcon from '@material-ui/icons/Favorite';
+import TextsmsIcon from '@material-ui/icons/Textsms';
+import ScheduleIcon from '@material-ui/icons/Schedule';
+const file = (fileId) => `${window.baseURL}/file/download/${fileId}`;
+const menu = [
+ { text: 'پسند', icon: FavoriteIcon, onClick: () => {} },
+ { text: 'تبادل نظر', icon: TextsmsIcon, onClick: () => {} },
+ { text: 'پاسخ', icon: ReplyIcon, onClick: () => {} },
+ { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} },
+];
+const selfMenu = [
+ { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} },
+ { text: 'ویرایش', icon: EditIcon, onClick: () => {} },
+ { text: 'حذف', icon: DeleteIcon, onClick: () => {} },
+];
+export default class NormalMessage extends Component {
+ state = { messageMenu: null };
+ handleClose = () => {
+ this.setState({
+ messageMenu: null,
+ });
+ };
+ handleClick = (event) => {
+ this.setState({
+ messageMenu: event.currentTarget,
+ });
+ };
+ render() {
+ const { message, user, document, isSelf, prevUserId, children,addcounter } = this.props;
+ const { messageMenu } = this.state;
+ const hasavatar = prevUserId != message.userId;
+
+ return (
+
+ {hasavatar && false && (
+
+ {user.name
+ .split(' ')
+ .map((e) => e.slice(0, 1))
+ .join(' ')}
+
+ )}
+
+
+
+
+
addcounter('nothing')}>
+
+
+
+ {hasavatar &&
{user.name}
}
+
+
+ {message.type == 'text' ? (
+
{message.text}
+ ) : null}
+ {message.type == 'voice' ? (
+
+ ) : null}
+ {message.type == 'image' ? (
+
+
+
+
+
{message.text}
+
+ ) : null}
+ {message.type == 'video' ? (
+
+ ) : null}
+ {message.type == 'audio' ? (
+
+ ) : null}
+ {message.type == 'document' ? (
+
+
+ {message.text}
+
+ ) : null}
+
+
+
+ {message.updatedAt != message.createdAt ? (
+ <>
+ ویرایش در
+
+ {moment(message.updatedAt).format(' hh:mm jMM/jDD')}
+ >
+ ) : (
+ moment(message.createdAt).format('hh:mm')
+ )}
+
+
+ {isSelf && message.status == 0 && }
+ {isSelf && message.status == 2 && }
+ {isSelf && message.status == 1 && (
+
+ )}
+
+
+
+
+
addcounter('nothing')}>
+ {!isSelf ? (
+ <>
+ {' '}
+
+ {10}
+
+
+
+
+ {10}
+
+
+ >
+ ) : (
+ <>
+
+
+ +5
+
+ خلاقیت
+
+
+ >
+ )}
+
+
+
+ {children}
+
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/Normal/index.scss b/src/views/ChatRoom/Body/Message/Normal/index.scss
new file mode 100644
index 0000000..86fe695
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Normal/index.scss
@@ -0,0 +1,155 @@
+@media screen and (max-width: 4500px) {
+ .normal-message__box--date.self {
+ padding-right: 20px 0 0 !important ;
+ }
+ .keys {
+ max-width: 465px;
+ min-width: 250px;
+ padding: 2px 0;
+ }
+ .icons {
+ //position: absolute;
+ width: 90px;
+ padding: 0 5px;
+ display: inline-block !important;
+ // top: 55px;
+ // right: -35px;
+ direction:rtl;
+ text-align: left;
+ & .MuiSvgIcon-root {
+ font-size: 18px !important;
+ opacity: 0.8;
+ }
+ & span {
+ font-size: 11px !important;
+ opacity: 0.8;
+ }
+ }
+ .icons.self {
+ direction: ltr;
+ text-align: right;
+ font-size: small;
+ // left: -35px;
+ // right: none;
+ }
+ .MuiMenuItem-root {
+ min-height: 10px !important;
+ font-size: 12px !important;
+ color: grey;
+ padding: 5px 10px !important;
+ & .MuiSvgIcon-root {
+ font-size: 16px !important;
+ padding: 2px;
+ color: grey;
+ }
+ }
+
+ .normal-message {
+ // width: 100%;
+ position: relative;
+ margin-bottom: 2px;
+ img {
+ width: 65px;
+ height: 65px;
+ object-fit: cover;
+ border-radius: 15px;
+ border: 3px solid rgba(201, 201, 201, 0.857);
+ position: relative;
+ top: 20px;
+ z-index: 50;
+ }
+ &__box {
+ line-height: 1.3em;
+ max-width: 500px;
+ min-width: 250px;
+ display: flex;
+ justify-content: flex-end;
+ // width: 100%;
+ padding: 20px 10px 15px;
+ background-color: white;
+ border-radius: 5px;
+ position: relative;
+ p {
+ width: 100%;
+ text-align: right;
+ direction: rtl;
+ font-size: 15px;
+ margin: 0 0 5px !important;
+ // font-family: IRANSansNumeral;
+ font-weight: 200;
+ color: #afafaf;
+ }
+ &--detail {
+ position: absolute;
+ width: 100%;
+ top: 10px;
+ justify-content: space-between;
+ font-size: 12px;
+ span {
+ font-family: IRANSansNumeralLight;
+ }
+ }
+
+ &--date {
+ position: absolute;
+ width: 100%;
+ padding: 0px 0px 0;
+ bottom: 0px;
+ justify-content: flex-end;
+ font-size: 11px;
+ span {
+ font-family: IRANSansNumeralLight;
+ }
+ }
+ &--date.self {
+ justify-content: flex-end;
+ padding: 0;
+ }
+ &--caption {
+ width: 100%;
+ margin-bottom: 20px;
+ text-align: right;
+ & img {
+ height: 100%;
+ max-height: 250px;
+ width: 100%;
+ max-width: 250px;
+ border-radius: 0px;
+ border: 0px;
+ position: static;
+ }
+ & video {
+ height: 180px !important;
+ width: 100%;
+ }
+ & p {
+ margin-top: 20px;
+ }
+ // & audio{
+ // min-width: 100% !important;
+ // }
+ }
+ &--file {
+ background-color: rgb(143, 228, 143) !important;
+ }
+ &--document {
+ width: 100%;
+ max-width: 300px;
+ align-items: center;
+ justify-content: space-between;
+ height: 50px;
+ padding: 10px;
+ border-radius: 10px;
+ div {
+ font-size: 14px;
+ }
+ }
+ }
+ }
+}
+
+.react-audio-player {
+ width: 100% !important;
+ color: red;
+ fill: red;
+}
diff --git a/src/views/ChatRoom/Body/Message/Select/index.js b/src/views/ChatRoom/Body/Message/Select/index.js
new file mode 100644
index 0000000..067731b
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Select/index.js
@@ -0,0 +1,56 @@
+import React, { Component } from 'react';
+import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
+
+export default class RadioMessage extends Component {
+ state = {
+ value: this.props.message.value,
+ };
+ handleRadioChange = (value) => {
+ if (this.props.isActive) this.setState({ value });
+ };
+
+ render() {
+ const { message, user, isSelf, isActive, action } = this.props;
+ const { value } = this.state;
+ return (
+
+
+ {message.options.map((row) => (
+
+ ))}
+
+ {isActive && (
+
+ )}
+
+ );
+ }
+}
+
+const Row = (props) => {
+ return (
+
+ {props.list.map((item) => (
+
+ ))}
+
+ );
+};
+
+const Item = (props) => {
+ return (
+ props.handleRadioChange(props.item.name)}
+ style={{
+ backgroundColor:
+ props.item.name === props.value ? 'rgb(100, 205, 130)' : 'rgba(255, 255, 255, 0.4)',
+ color: props.item.name === props.value ? 'white' : 'black',
+ }}
+ >
+ {props.item.name}
+
+ );
+};
diff --git a/src/views/ChatRoom/Body/Message/Select/index.scss b/src/views/ChatRoom/Body/Message/Select/index.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/views/ChatRoom/Body/Message/Slider/index.js b/src/views/ChatRoom/Body/Message/Slider/index.js
new file mode 100644
index 0000000..5458515
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Slider/index.js
@@ -0,0 +1,62 @@
+import React, { Component } from 'react';
+import Grid from '@material-ui/core/Grid';
+import Slider from '@material-ui/core/Slider';
+import Input from '@material-ui/core/Input';
+import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
+import Avatar from '@material-ui/core/Avatar';
+import { toast } from 'react-toastify';
+export default class SliderMessage extends Component {
+ state = {
+ value: this.props.message.value || 0,
+ };
+ onChange = (value) => {
+ if (!this.props.isActive || !value) return;
+ const [min, max, step] = this.props.message.options[0] || [0, 100, 1];
+ this.setState({ value: Math.min(max, Math.max(min, parseFloat(value))) });
+ };
+
+ render() {
+ const { message, isActive, action } = this.props;
+ const [min, max, step] = message.options[0] || [0, 100, 1];
+ const { value } = this.state;
+ return (
+
+
+
+ this.onChange(value)}
+ aria-labelledby="input-slider"
+ min={min}
+ max={max}
+ step={step}
+ />
+
+
+ this.onChange(e.target.value)}
+ onBlur={() => this.onChange(value)}
+ inputProps={{
+ step: step,
+ min: min,
+ max: max,
+ type: 'number',
+ 'aria-labelledby': 'input-slider',
+ }}
+ />
+
+
+ {isActive && (
+
+ )}
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/Slider/index.scss b/src/views/ChatRoom/Body/Message/Slider/index.scss
new file mode 100644
index 0000000..a5ed48b
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Slider/index.scss
@@ -0,0 +1,13 @@
+.sliderBox {
+ margin-top: 2px;
+ .slider {
+ margin-top: 10px;
+ }
+ input {
+ width: 42px;
+ border-bottom: 2px solid #000099;
+ padding-left: 10px;
+ margin-bottom: 18px;
+ color: #000099;
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/Sort/index.js b/src/views/ChatRoom/Body/Message/Sort/index.js
new file mode 100644
index 0000000..99df8c5
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Sort/index.js
@@ -0,0 +1,53 @@
+import React, { Component, useEffect } from 'react';
+import { SortableContainer, SortableElement } from 'react-sortable-hoc';
+import arrayMove from 'array-move';
+import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
+import Avatar from '@material-ui/core/Avatar';
+import { toast } from 'react-toastify';
+
+export default class DraggableMessage extends Component {
+ constructor(props) {
+ super(props);
+ this.state = this.props.message;
+ }
+ onSortEnd = ({ oldIndex, newIndex }) => {
+ if (this.props.isActive)
+ this.setState(({ options }) => ({
+ options: arrayMove(options, oldIndex, newIndex),
+ }));
+ };
+
+ render() {
+ const { message, user, isSelf, isActive, action } = this.props;
+
+ return (
+
+
+ {isActive && (
+
+ )}
+
+ );
+ }
+}
+
+const SortableList = SortableContainer(({ items, disabled }) => {
+ return (
+
+ {items.map((row, index) => (
+
+ ))}
+
+ );
+});
+
+const SortableItem = SortableElement(({ value }) => (
+
+ {value.map((item) => (
+
{item.name}
+ ))}
+
+));
diff --git a/src/views/ChatRoom/Body/Message/Sort/index.scss b/src/views/ChatRoom/Body/Message/Sort/index.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/views/ChatRoom/Body/Message/Tap/index.js b/src/views/ChatRoom/Body/Message/Tap/index.js
new file mode 100644
index 0000000..6d039a7
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Tap/index.js
@@ -0,0 +1,27 @@
+import React, { Component } from 'react';
+import arrayMove from 'array-move';
+import './index.scss';
+
+export default class DraggableMessage extends Component {
+ constructor(props) {
+ super(props);
+ this.state = this.props.message;
+ }
+ onSortEnd = ({ oldIndex, newIndex }) => {
+ if (this.props.isActive)
+ this.setState(({ options }) => ({
+ options: arrayMove(options, oldIndex, newIndex),
+ }));
+ };
+
+ render() {
+ const { message, user, isSelf, isActive } = this.props;
+ if (!isActive) return null;
+ return ;
+ }
+ a = (
+
+ );
+}
diff --git a/src/views/ChatRoom/Body/Message/Tap/index.scss b/src/views/ChatRoom/Body/Message/Tap/index.scss
new file mode 100644
index 0000000..5769f8e
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/Tap/index.scss
@@ -0,0 +1,15 @@
+.tapbox {
+ z-index: 500;
+ position: absolute;
+ left: -10px;
+ background-color: #fff;
+ width: 100vw;
+ height: calc(100% - 90px);
+ opacity: 0.1;
+ cursor: pointer;
+}
+.ptapbox {
+ top: 0;
+ left: 0;
+ position: absolute;
+}
diff --git a/src/views/ChatRoom/Body/Message/index.js b/src/views/ChatRoom/Body/Message/index.js
new file mode 100644
index 0000000..4b13c79
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/index.js
@@ -0,0 +1,48 @@
+import React, { Component } from 'react';
+import Normal from './Normal';
+import Inline from './Inline';
+import Sort from './Sort';
+import Slider from './Slider';
+import Select from './Select';
+import MultiSelect from './MultiSelect';
+import Tap from './Tap';
+import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt';
+
+import './index.scss';
+const types = {
+ sort: Sort,
+ inline: Inline,
+ slider: Slider,
+ select: Select,
+ multiselect: MultiSelect,
+ tap: Tap,
+};
+export default class Message extends Component {
+ render() {
+ const { message, user, isSelf, file, document, prevUserId, isActive, addcounter } = this.props;
+ const Action = types[message.action];
+ return (
+
+
+ {Action ? (
+
+ ) : null}
+ {/* {isActive && (
+
+ )} */}
+
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Body/Message/index.scss b/src/views/ChatRoom/Body/Message/index.scss
new file mode 100644
index 0000000..4fc619f
--- /dev/null
+++ b/src/views/ChatRoom/Body/Message/index.scss
@@ -0,0 +1,5 @@
+@media screen and (max-width: 4500px) {
+ .Message {
+ margin-top: 2px;
+ }
+}
diff --git a/src/views/ChatRoom/Body/index.js b/src/views/ChatRoom/Body/index.js
new file mode 100644
index 0000000..2e38970
--- /dev/null
+++ b/src/views/ChatRoom/Body/index.js
@@ -0,0 +1,493 @@
+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 { ToastContainer } from 'react-toastify';
+import { list, send, sendKeys } from '../../../Redux/actions/message';
+import { info, bio } from '../../../Redux/actions/chat';
+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.location.href.split('/').pop() * 1,
+ 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() {
+ 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: 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 (
+ this.addcounter('parent')}
+ >
+
+ {chatInfo.users &&
+ messageList.map((message, i) =>
+ this.state.image === null &&
+ this.state.music === null &&
+ this.state.video === null ? (
+
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 ? (
+
+
+
+ ) : null}
+ {this.state.video !== null ? (
+
+
+
+ ) : null}
+ {this.state.music !== null ? (
+
+
+
+ ) : null}
+ {this.state.document !== null ? (
+
+
+
{`ارسال (${this.state.document.name}) به ${this.props.info.title}؟`}
+
+
+
+
+
+
+ ) : null}
+
+
this.addcounter('nothing')}
+ >
+ {last.action == 'text' ? (
+
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' ? (
+ this.addcounter()} />
+ ) : null}
+ {this.state.emoji ? (
+
+
+
+ ) : 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] || {},
+ };
+ },
+ { list, send, sendKeys, info, bio }
+)(List);
diff --git a/src/views/ChatRoom/Body/index.scss b/src/views/ChatRoom/Body/index.scss
new file mode 100644
index 0000000..88161cc
--- /dev/null
+++ b/src/views/ChatRoom/Body/index.scss
@@ -0,0 +1,139 @@
+@media screen and (max-width: 4500px) {
+ .chat-body .MuiAvatar-circle {
+ box-shadow: 0px 0px 0px 2px #fff;
+ border: 3px solid #ffffff66;
+ width: 60px;
+ height: 60px;
+ // top: 20px;
+ z-index: 30;
+ // font-family: 'IRANSansNumeralBold';
+ // & div {
+ // font-family: 'IRANSansNumeralBold';
+ // }
+ }
+
+ .chat-body {
+ background-color: rgb(210, 196, 214);
+ // justify-content: flex-start;
+ flex: 1;
+ height: 100%;
+ overflow-x: hidden;
+ font-family: numeralLight;
+ &__content {
+ background: url(../../../assets/images/whatsapp.png);
+ background-size: cover;
+ padding: 0px 10px 0px;
+ margin-bottom: 55px;
+ height: 100%;
+ min-height: 200px;
+ 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;
+ }
+ }
+ }
+ }
+ }
+ }
+ &__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: scroll;
+ overflow-x: hidden;
+ position: fixed;
+ bottom: 0px;
+ left: 0;
+ padding-bottom: 5px;
+ &--emoji{
+ margin-top: 5px;
+ width: 100%;
+ background-color: red;
+ height: 250px;
+ // 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;
+ }
+ }
+ }
+ }
+}
diff --git a/src/views/ChatRoom/Header/Avatar/index.js b/src/views/ChatRoom/Header/Avatar/index.js
new file mode 100644
index 0000000..1a9537b
--- /dev/null
+++ b/src/views/ChatRoom/Header/Avatar/index.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import Badge from '@material-ui/core/Badge';
+import Avatar from '@material-ui/core/Avatar';
+import { makeStyles, withStyles } from '@material-ui/core/styles';
+
+const StyledBadge = withStyles((theme) => ({
+ badge: {
+ backgroundColor: '#44b700',
+ color: '#44b700',
+ boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
+ '&::after': {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '100%',
+ height: '100%',
+ borderRadius: '50%',
+ animation: '$ripple 1.2s infinite ease-in-out',
+ border: '1px solid currentColor',
+ content: '""',
+ },
+ },
+ '@keyframes ripple': {
+ '0%': {
+ transform: 'scale(.8)',
+ opacity: 1,
+ },
+ '100%': {
+ transform: 'scale(2.4)',
+ opacity: 0,
+ },
+ },
+}))(Badge);
+
+const useStyles = makeStyles((theme) => ({
+ root: {
+ display: 'flex',
+ '& > *': {
+ margin: 0,
+ },
+ },
+}));
+
+export default function StatusAvatar(props) {
+ const classes = useStyles();
+
+ return (
+
+ );
+}
diff --git a/src/views/ChatRoom/Header/index.js b/src/views/ChatRoom/Header/index.js
new file mode 100644
index 0000000..ccae44c
--- /dev/null
+++ b/src/views/ChatRoom/Header/index.js
@@ -0,0 +1,102 @@
+import React, { Component } from "react";
+import MoreVertIcon from "@material-ui/icons/MoreVert";
+import ArrowForwardIcon from "@material-ui/icons/ArrowForward";
+import Menu from "@material-ui/core/Menu";
+import MenuItem from "@material-ui/core/MenuItem";
+import VideocamIcon from "@material-ui/icons/Videocam";
+import StatusAvatar from "./Avatar/index.js";
+import CallIcon from "@material-ui/icons/Call";
+import { connect } from "react-redux";
+
+import "./index.scss";
+class Header extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ anchorEl: null,
+ };
+ }
+
+ handleClick = (event) => {
+ this.setState({
+ anchorEl: event.currentTarget,
+ });
+ };
+
+ handleClose = () => {
+ this.setState({
+ anchorEl: null,
+ });
+ };
+
+ back = () => {
+ window.history.back();
+ };
+ render() {
+ const { page, setPage, chatInfo } = this.props;
+ const { anchorEl } = this.state;
+ return (
+
+
+
+ page === "chatroom" ? this.back() : setPage("chatroom")
+ }
+ style={{ color: "white", width: 29, height: 29, marginTop: 4 }}
+ />
+ setPage("info")}
+ className="chat-header__info d-flex mr-1"
+ >
+
+
+
{chatInfo ? chatInfo.title : null}
+ {chatInfo ? chatInfo.subTitle : null}
+
+
+
+
+
+ );
+ }
+}
+
+export default connect((state) => ({ chatInfo: state.chat.info }), {})(Header);
diff --git a/src/views/ChatRoom/Header/index.scss b/src/views/ChatRoom/Header/index.scss
new file mode 100644
index 0000000..a300095
--- /dev/null
+++ b/src/views/ChatRoom/Header/index.scss
@@ -0,0 +1,31 @@
+@media screen and (max-width: 4500px) {
+ .chat-header {
+ height: 60px;
+ width: 100%;
+ justify-content: space-between;
+ align-items: flex-end;
+ padding: 5px 5px 5px;
+ position: relative;
+ background-color: #128c7e;
+ &__info {
+ text-align: right;
+
+ & h1 {
+ font-size: 16px;
+ color: white;
+ margin: 0px;
+ margin-bottom: 5px;
+ font-weight: 600;
+ }
+ & span {
+ color: white;
+ font-size: 11px;
+ }
+ }
+ }
+}
+
+.MuiMenu-paper {
+ background: #00cba2; //rgb(63, 71, 67) !important;
+ color: black !important;
+}
diff --git a/src/views/ChatRoom/Info/FileTabs/index.js b/src/views/ChatRoom/Info/FileTabs/index.js
new file mode 100644
index 0000000..16d75aa
--- /dev/null
+++ b/src/views/ChatRoom/Info/FileTabs/index.js
@@ -0,0 +1,90 @@
+import React, { Component } from 'react';
+
+import './index.scss';
+export default class FileTabs extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ type: 'media',
+ };
+ }
+
+ setType = (val) => {
+ this.setState({
+ type: val,
+ });
+ };
+ render() {
+ return (
+
+
+
this.setType('media')}
+ >
+ Media
+
+ this.setType('file')}
+ >
+ Files
+
+ this.setType('link')}
+ >
+ Links
+
+ this.setType('music')}
+ >
+ Music
+
+ this.setType('voice')}
+ >
+ Voice
+
+
+ {this.state.type === 'media' ? (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : null}
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Info/FileTabs/index.scss b/src/views/ChatRoom/Info/FileTabs/index.scss
new file mode 100644
index 0000000..73224c7
--- /dev/null
+++ b/src/views/ChatRoom/Info/FileTabs/index.scss
@@ -0,0 +1,36 @@
+@media screen and (max-width: 4500px) {
+ .file-tabs {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ direction: rtl;
+ position: sticky;
+ top: 0-5px;
+ &__types {
+ width: 100%;
+ justify-content: space-between;
+ align-items: center;
+ padding: 3px calc((100vw - 310px) / 2) 3px calc((100vw - 310px) / 2);
+ direction: ltr;
+ border-top: 8px solid rgb(13, 84, 150);
+ margin-top: 20px;
+ background-color: #128c7e;
+ & li {
+ font-size: 16px;
+ list-style: none;
+ font-weight: 600;
+ }
+ }
+ &__media {
+ width: 100%;
+ overflow-y: scroll;
+ padding-bottom: 52px;
+ &--item {
+ width: calc(100% / 3);
+ height: calc(100vw / 3);
+ border: 2px solid rgb(200, 183, 232);
+ background-color: red;
+ }
+ }
+ }
+}
diff --git a/src/views/ChatRoom/Info/Gallery/index.js b/src/views/ChatRoom/Info/Gallery/index.js
new file mode 100644
index 0000000..d233951
--- /dev/null
+++ b/src/views/ChatRoom/Info/Gallery/index.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import Carousel from 'react-elastic-carousel';
+import CloseIcon from '@material-ui/icons/Close';
+
+import './index.scss';
+
+export default function Gallery(props) {
+ // const [state,setState] = useState({
+
+ // });
+ return (
+
+
props.onClick(null)}>
+
+
+
+ {props.data.map((item, i) => (
+
+ ))}
+
+
+ );
+}
+
+const Image = (props) => {
+ return ;
+};
diff --git a/src/views/ChatRoom/Info/Gallery/index.scss b/src/views/ChatRoom/Info/Gallery/index.scss
new file mode 100644
index 0000000..a1149d6
--- /dev/null
+++ b/src/views/ChatRoom/Info/Gallery/index.scss
@@ -0,0 +1,64 @@
+@media screen and (max-width: 4500px) {
+ .gallery-modal {
+ width: 100%;
+ height: 100%;
+ background-color: #383737f1;
+ position: absolute;
+ left: 0;
+ top: 0;
+ z-index: 700;
+ .rec-carousel-wrapper {
+ position: relative;
+ bottom: 70px;
+ }
+ .rec-arrow {
+ position: absolute;
+ background: none;
+ box-shadow: none;
+ &:hover:enabled {
+ background: none;
+ box-shadow: none;
+ color: black;
+ }
+ }
+ .rec-arrow-right {
+ top: calc(50% - 20px);
+ left: 0px;
+ z-index: 800;
+ }
+ .rec-arrow-left {
+ top: calc(50% - 20px);
+ right: 0px;
+ z-index: 800;
+ }
+ .rec-pagination {
+ // display:none;
+ z-index: 600;
+ position: absolute;
+ top: auto;
+ bottom: -30px !important;
+ // left: calc(50% - 20px) !important;
+ & button {
+ background-color: grey;
+ margin: 2px !important;
+ box-shadow: 0px 0px 0px rgba(255, 255, 255, 1);
+ }
+ }
+ }
+ .rec-dot_active {
+ background-color: white !important;
+ color: white !important;
+ // box-shadow: 0 0 1px rgba(255, 255, 255, 1) !important;
+ }
+
+ .Carousel-button-10 {
+ background-color: white !important;
+ }
+ .rec-pagination {
+ img {
+ // width: 100vw;
+ // max-height: 200px;
+ // height: 100vh;
+ }
+ }
+}
diff --git a/src/views/ChatRoom/Info/index.js b/src/views/ChatRoom/Info/index.js
new file mode 100644
index 0000000..ac07b94
--- /dev/null
+++ b/src/views/ChatRoom/Info/index.js
@@ -0,0 +1,60 @@
+import React, { Component } from 'react';
+import ChatIcon from '@material-ui/icons/Chat';
+import FileTabs from './FileTabs';
+import Gallery from './Gallery';
+import user2 from '../../../assets/images/user2.png';
+
+import './index.scss';
+export default class ChatInfo extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ gallery: null,
+ user: {
+ profileImages: [
+ { id: 0, src: user2 },
+ { id: 1, src: user2 },
+ { id: 2, src: user2 },
+ { id: 3, src: user2 },
+ ],
+ name: 'محسن محمدی',
+ lastAct: '2 دقیقه پیش آنلاین بوده',
+ bio: 'لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد ',
+ },
+ };
+ }
+
+ setGallery = (val) => {
+ this.setState({
+ gallery: val,
+ });
+ };
+
+ render() {
+ const { user, gallery } = this.state;
+ return (
+
+
+
this.setGallery('profile')} alt="" />
+
+
+
+
+
+
+
{user.name}
+
{user.lastAct}
+
+
+
+
+ {gallery === 'profile' ? (
+
+ ) : null}
+ {gallery === 'media' ?
: null}
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/Info/index.scss b/src/views/ChatRoom/Info/index.scss
new file mode 100644
index 0000000..0bb73d2
--- /dev/null
+++ b/src/views/ChatRoom/Info/index.scss
@@ -0,0 +1,82 @@
+@media screen and (max-width: 4500px) {
+ .chat-info {
+ width: 100%;
+ min-height: 100vh;
+ position: relative;
+ direction: rtl;
+ &__image {
+ width: 100%;
+ background-color: rgb(82, 82, 82);
+ justify-content: center;
+ align-items: center;
+ height: 290px;
+ position: relative;
+ & img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ &--float {
+ position: absolute;
+ width: 65px;
+ height: 65px;
+ bottom: -30px;
+ right: 40px;
+ background : #128c7e;
+ padding: 5px;
+ border-radius: 100px;
+ z-index: 400;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 0px 0px 50px rgba(36, 0, 72, 0.8);
+ }
+ }
+ &__box {
+ width: 100%;
+ z-index: 100;
+ height: calc(100% - 250px);
+ background-color: #0ab8a3;
+ direction: rtl;
+ padding: 20px 0px 0px 0px;
+ position: sticky;
+ // transform: translateY(-40px);
+ //top: -150px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ z-index: 200;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ &--status {
+ width: 100%;
+ align-items: flex-end;
+ padding: 0px 30px;
+ h1 {
+ font-size: 19px;
+ margin: 0;
+ letter-spacing: -1px;
+ font-family: IRANSansNumeralLight;
+ color: black;
+ font-weight: 100;
+ }
+ p {
+ font-size: 14px;
+ color: rgb(61, 61, 61);
+ margin: 0px;
+ }
+ }
+ &--description {
+ width: 100%;
+ justify-content: center;
+ align-items: center;
+ margin-top: 20px;
+ & p {
+ width: 100%;
+ max-width: 310px;
+ text-align: justify;
+ font-size: 12px;
+ }
+ }
+ }
+ }
+}
diff --git a/src/views/ChatRoom/index.js b/src/views/ChatRoom/index.js
new file mode 100644
index 0000000..d702040
--- /dev/null
+++ b/src/views/ChatRoom/index.js
@@ -0,0 +1,38 @@
+import React, { Component } from 'react';
+import Header from './Header';
+import Body from './Body';
+import Info from './Info';
+import './index.scss';
+export default class ChatRoom extends Component {
+ constructor(props) {
+ super(props);
+ window.nav = this.nav.bind(this);
+ this.state = {
+ page: 'chatroom',
+ };
+ }
+ nav = (url) => {
+ this.props.history.push(url);
+ };
+ setPage = (val) => {
+ this.setState({
+ page: val,
+ });
+ };
+ render() {
+ return (
+
+
+ {this.state.page === 'chatroom' ? (
+ <>
+
+ >
+ ) : (
+ <>
+
+ >
+ )}
+
+ );
+ }
+}
diff --git a/src/views/ChatRoom/index.scss b/src/views/ChatRoom/index.scss
new file mode 100644
index 0000000..e4bf0ac
--- /dev/null
+++ b/src/views/ChatRoom/index.scss
@@ -0,0 +1,33 @@
+@media screen and (max-width: 4500px) {
+ .chat-room {
+ flex: 1;
+ background: rgb(139, 73, 186);
+ background: linear-gradient(180deg, rgb(144, 73, 186) 0%, #64cd82 22%);
+ height: 100vh;
+ overflow: hidden;
+ width: 100vw;
+ box-shadow: 0px 0px 40px rgba(145, 145, 145, 0.8);
+ &__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;
+ }
+ }
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index dd51740..767e126 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1150,6 +1150,13 @@
core-js-pure "^3.14.0"
regenerator-runtime "^0.13.4"
+"@babel/runtime@7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c"
+ integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==
+ dependencies:
+ regenerator-runtime "^0.12.0"
+
"@babel/runtime@7.12.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
@@ -1164,6 +1171,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.2.0":
+ version "7.14.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d"
+ integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.4", "@babel/template@^7.14.5", "@babel/template@^7.3.3":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
@@ -1592,6 +1606,11 @@
schema-utils "^2.6.5"
source-map "^0.7.3"
+"@react-leaflet/core@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@react-leaflet/core/-/core-1.1.0.tgz#389b2b373f1da4caeb3c4cf6f33d84561c58d504"
+ integrity sha512-zFxMHgfjCi7khRVB7o7H8NoJl36NaezvfcaeEurVXx22lAGHFlTHiSuLOGA4tOiHj+Ep+Lo3uwUGJ3YM9BGkHg==
+
"@rollup/plugin-node-resolve@^7.1.1":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca"
@@ -2563,6 +2582,11 @@ array-includes@^3.1.1, array-includes@^3.1.2, array-includes@^3.1.3:
get-intrinsic "^1.1.1"
is-string "^1.0.5"
+array-move@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/array-move/-/array-move-3.0.1.tgz#179645cc0987b65953a4fc06b6df9045e4ba9618"
+ integrity sha512-H3Of6NIn2nNU1gsVDqDnYKY/LCdWvCMMOWifNGhKcVQgiZ6nOek39aESOvro6zmueP07exSl93YLvkN4fZOkSg==
+
array-union@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
@@ -2679,6 +2703,13 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
+audio-react-recorder@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/audio-react-recorder/-/audio-react-recorder-1.0.4.tgz#db81f10286c2252af8d42162e1f49dbd1de0dffd"
+ integrity sha512-an7eX0yOGDbZOSu2LvnfWIsI41pkx9nXgtBVbI+9ByS91WKqoVGVb5pbmqHax5sZty2DjOIG/neuxcghIU/ucg==
+ dependencies:
+ prop-types "^15.7.2"
+
autoprefixer@^9.6.1:
version "9.8.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f"
@@ -4217,7 +4248,7 @@ deep-is@^0.1.3, deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-deepmerge@^4.2.2:
+deepmerge@^4.0.0, deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
@@ -6078,6 +6109,13 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"
+invariant@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
+ integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
+ dependencies:
+ loose-envify "^1.0.0"
+
ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
@@ -7141,6 +7179,11 @@ jss@10.6.0, jss@^10.5.1:
array-includes "^3.1.2"
object.assign "^4.1.2"
+keycode@^2.1.7:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
+ integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=
+
killable@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@@ -7236,6 +7279,11 @@ load-json-file@^4.0.0:
pify "^3.0.0"
strip-bom "^3.0.0"
+load-script@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4"
+ integrity sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=
+
loader-runner@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@@ -7351,7 +7399,7 @@ loglevel@^1.6.8:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
-loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -7449,6 +7497,11 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
+memoize-one@^5.1.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
+ integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
+
memory-fs@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
@@ -9220,7 +9273,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.6.2, prop-types@^15.7.2:
+prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -9391,6 +9444,13 @@ react-app-polyfill@^2.0.0:
regenerator-runtime "^0.13.7"
whatwg-fetch "^3.4.1"
+react-audio-player@^0.17.0:
+ version "0.17.0"
+ resolved "https://registry.yarnpkg.com/react-audio-player/-/react-audio-player-0.17.0.tgz#4be7b1952512801f36ba0865a9c98f7b108f991e"
+ integrity sha512-aCZgusPxA9HK7rLZcTdhTbBH9l6do9vn3NorgoDZRxRxJlOy9uZWzPaKjd7QdcuP2vXpxGA/61JMnnOEY7NXeA==
+ dependencies:
+ prop-types "^15.7.2"
+
react-dev-utils@^11.0.3:
version "11.0.4"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a"
@@ -9445,6 +9505,20 @@ react-error-overlay@^6.0.9:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a"
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==
+react-event-listener@^0.6.0:
+ version "0.6.6"
+ resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a"
+ integrity sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==
+ dependencies:
+ "@babel/runtime" "^7.2.0"
+ prop-types "^15.6.0"
+ warning "^4.0.1"
+
+react-fast-compare@^3.0.1:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
+ integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
+
react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -9455,11 +9529,29 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+react-leaflet@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/react-leaflet/-/react-leaflet-3.2.0.tgz#8d5d05beab3f9e52665738ad737bb7b1da99f30b"
+ integrity sha512-eHVqoRGjW8T9GxLt7jyTKP3BDQ7XQ5AD+tc/zkbaABn1dbmREDy8GojNcYjZQa3QFLQoOLQMcUC1PTtzytZpUA==
+ dependencies:
+ "@react-leaflet/core" "^1.1.0"
+
react-only-when@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/react-only-when/-/react-only-when-1.0.2.tgz#a8a79b48dd6cfbd91ddc710674a94153e88039d3"
integrity sha512-agE6l3L6bqaVuwNtjihTQ36M+VBfPS63KOzcNL4ZTmlwSxQPvhzIqmBWfiol0/wLYmKxCcBqgXkEJpvj5Kob8Q==
+react-player@^2.9.0:
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/react-player/-/react-player-2.9.0.tgz#ef7fe7073434087565f00ff219824e1e02c4b046"
+ integrity sha512-jNUkTfMmUhwPPAktAdIqiBcVUKsFKrVGH6Ocutj6535CNfM91yrvWxHg6fvIX8Y/fjYUPoejddwh7qboNV9vGA==
+ dependencies:
+ deepmerge "^4.0.0"
+ load-script "^1.0.0"
+ memoize-one "^5.1.1"
+ prop-types "^15.7.2"
+ react-fast-compare "^3.0.1"
+
react-qr-scanner@^1.0.0-alpha.7:
version "1.0.0-alpha.7"
resolved "https://registry.yarnpkg.com/react-qr-scanner/-/react-qr-scanner-1.0.0-alpha.7.tgz#f63993cffe238f8cbca4984d03973accc842500b"
@@ -9580,6 +9672,46 @@ react-scripts@4.0.3:
optionalDependencies:
fsevents "^2.1.3"
+react-sortable-hoc@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz#f6780d8aa4b922a21f3e754af542f032677078b7"
+ integrity sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==
+ dependencies:
+ "@babel/runtime" "^7.2.0"
+ invariant "^2.2.4"
+ prop-types "^15.5.7"
+
+react-swipeable-views-core@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.14.0.tgz#6ac443a7cc7bc5ea022fbd549292bb5fff361cce"
+ integrity sha512-0W/e9uPweNEOSPjmYtuKSC/SvKKg1sfo+WtPdnxeLF3t2L82h7jjszuOHz9C23fzkvLfdgkaOmcbAxE9w2GEjA==
+ dependencies:
+ "@babel/runtime" "7.0.0"
+ warning "^4.0.1"
+
+react-swipeable-views-utils@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.14.0.tgz#6b76e251906747482730c22002fe47ab1014ba32"
+ integrity sha512-W+fXBOsDqgFK1/g7MzRMVcDurp3LqO3ksC8UgInh2P/tKgb5DusuuB1geKHFc6o1wKl+4oyER4Zh3Lxmr8xbXA==
+ dependencies:
+ "@babel/runtime" "7.0.0"
+ keycode "^2.1.7"
+ prop-types "^15.6.0"
+ react-event-listener "^0.6.0"
+ react-swipeable-views-core "^0.14.0"
+ shallow-equal "^1.2.1"
+
+react-swipeable-views@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.14.0.tgz#149c0df3d92220cc89e3f6d5c04a78dfe46f9b54"
+ integrity sha512-wrTT6bi2nC3JbmyNAsPXffUXLn0DVT9SbbcFr36gKpbaCgEp7rX/OFxsu5hPc/NBsUhHyoSRGvwqJNNrWTwCww==
+ dependencies:
+ "@babel/runtime" "7.0.0"
+ prop-types "^15.5.4"
+ react-swipeable-views-core "^0.14.0"
+ react-swipeable-views-utils "^0.14.0"
+ warning "^4.0.1"
+
react-swipeable@^5.5.1:
version "5.5.1"
resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-5.5.1.tgz#48ae6182deaf62f21d4b87469b60281dbd7c4a76"
@@ -9735,6 +9867,11 @@ regenerator-runtime@^0.11.0:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+regenerator-runtime@^0.12.0:
+ version "0.12.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
+ integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
+
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
version "0.13.7"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
@@ -10306,6 +10443,11 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1"
safe-buffer "^5.0.1"
+shallow-equal@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
+ integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
+
shallowequal@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
@@ -11511,6 +11653,13 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
+warning@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
+ integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
+ dependencies:
+ loose-envify "^1.0.0"
+
watchpack-chokidar2@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"