reza added desktop chat

master
ravino 3 years ago
parent 5915c72411
commit b3d9357551
  1. 13
      src/views/Auth/Login/index.js
  2. 36
      src/views/ChatList/Chat/index.js
  3. 1
      src/views/ChatList/Chat/index.scss
  4. 21
      src/views/ChatList/Search/index.js
  5. 26
      src/views/ChatList/Search/index.scss
  6. 52
      src/views/ChatList/index.js
  7. 37
      src/views/ChatList/index.scss
  8. 11
      src/views/ChatRoom/Body/index.js
  9. 25
      src/views/ChatRoom/Body/index.scss
  10. 90
      src/views/ChatRoom/Drawer/index.js
  11. 4
      src/views/ChatRoom/Drawer/index.scss
  12. 8
      src/views/ChatRoom/Header/index.js
  13. 6
      src/views/ChatRoom/Header/index.scss
  14. 21
      src/views/ChatRoom/index.js
  15. 2
      src/views/ChatRoom/index.scss

@ -2,8 +2,11 @@ import React, { Component } from "react";
import Cellphone from "./Cellphone/index"; import Cellphone from "./Cellphone/index";
import Code from "./Code/index"; import Code from "./Code/index";
import { otp } from '../../../Redux/actions/public';
import { login } from '../../../Redux/actions/user';
import { connect } from 'react-redux';
export default class Login extends Component { class Login extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
@ -12,9 +15,9 @@ export default class Login extends Component {
} }
async componentDidUpdate() { async componentDidUpdate() {
const { cellphone, otp, section } = this.state; const { cellphone, otp, page } = this.state;
// if (cellphone && !otp) this.props.otp({ cellphone }); if (cellphone && !otp) this.props.otp({ cellphone });
// if (section && cellphone && otp) this.props.login({ cellphone, otp }); if (page && cellphone && otp) this.props.login({ cellphone, otp });
} }
resend = () => { resend = () => {
@ -26,3 +29,5 @@ export default class Login extends Component {
return <>{this.state.page === 0 ? <Cellphone parent={this} /> : <Code parent={this} />}</>; return <>{this.state.page === 0 ? <Cellphone parent={this} /> : <Code parent={this} />}</>;
} }
} }
export default connect((state) => ({ isLogin: state.user.isLogin }), { otp, login })(Login);

@ -8,15 +8,33 @@ export default class Chat extends Component {
render() { render() {
const { data } = this.props; const { data } = this.props;
return ( return (
<Link to={`/chatroom/${data.id}`} className="chat d-flex"> <>
<Avatar src={data.imageUrl} alt={data.name} className={'avatar fontLight'} /> {
<div className="chat__data d-flex flex-column"> window.innerWidth < 1000 ?
<h1 className="chat__data--name">{data.name}</h1> <Link to={`/chatroom/${data.id}`} className="chat d-flex">
<p className="chat__data--lastMessage">{data.lastMessage.slice(0, 40) + '...'}</p> <Avatar src={data.imageUrl} alt={data.name} className={'avatar fontLight'} />
<span>{data.badge}</span> <div className="chat__data d-flex flex-column">
<div>{moment(data.date || new Date()).format('jD/jM hh:mm')}</div> <h1 className="chat__data--name">{data.name}</h1>
</div> <p className="chat__data--lastMessage">{data.lastMessage.slice(0, 40) + '...'}</p>
</Link> <span>{data.badge}</span>
<div>{moment(data.date || new Date()).format('jD/jM hh:mm')}</div>
</div>
</Link> : null
}
{
window.innerWidth > 1000 ?
<div className="chat d-flex" onClick={() => this.props.parent.setState({ selectedUser : data.id })}>
<Avatar src={data.imageUrl} alt={data.name} className={'avatar fontLight'} />
<div className="chat__data d-flex flex-column">
<h1 className="chat__data--name">{data.name}</h1>
<p className="chat__data--lastMessage">{data.lastMessage.slice(0, 40) + '...'}</p>
<span>{data.badge}</span>
<div>{moment(data.date || new Date()).format('jD/jM hh:mm')}</div>
</div>
</div> : null
}
</>
); );
} }
} }

@ -7,6 +7,7 @@
position: relative; position: relative;
padding: 0px 0px 0px; padding: 0px 0px 0px;
text-decoration: none; text-decoration: none;
cursor: pointer;
.avatar { .avatar {
background-color: #b4b4b4; background-color: #b4b4b4;
width: 55px; width: 55px;

@ -0,0 +1,21 @@
import React, { Component } from 'react';
import navbarSearch from "../../../assets/icons/navbarSearch.png";
import './index.scss';
const maxDesktopSize = 1250;
const fontSize = {
desktop: {
input: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 70,
},
};
export default function Search(props){
return(
<div className="desktop-chat-search d-flex">
<input type="search" style={{ fontSize: fontSize.desktop.input }} placeholder="جستجو" />
<img src={navbarSearch} alt="جستجو" />
</div>
);
}

@ -0,0 +1,26 @@
.desktop-chat-search{
width: 100%;
position: relative;
margin: 10px 0px;
img{
position: absolute;
left: 7px;
top: 6px;
width: 20px;
}
input{
width: 100%;
padding: 5px 10px 5px 35px;
font-family: numeralMedium;
border-radius: 5px;
background-color: #ebebeb;
color: #6f7074;
border: 0px;
&:focus{
outline: 0px
}
&::placeholder{
color: #bfbfbf;
}
}
}

@ -5,25 +5,57 @@ import { connect } from 'react-redux';
import ChatIcon from '@material-ui/icons/Chat'; import ChatIcon from '@material-ui/icons/Chat';
import Chat from './Chat/index'; import Chat from './Chat/index';
import Navbar from '../Home/Navbar/index'; import Navbar from '../Home/Navbar/index';
import Search from './Search/index';
import Chatroom from '../ChatRoom/index';
import './index.scss'; import './index.scss';
import { DesktopWindowsRounded } from '@material-ui/icons';
class ChatList extends Component { class ChatList extends Component {
state = {
selectedUser: null,
}
componentDidMount() { componentDidMount() {
this.props.list(); this.props.list();
} }
render() { render() {
return ( return (
<div className="chat-list d-flex flex-column"> <>
<Navbar /> {
{this.props.chat_list.map((item, i) => ( window.innerWidth < 1000 ?
<Chat key={i} data={item} /> <div className="chat-list d-flex flex-column">
))} <Navbar />
<Link to="/characters" className="chat-list__float d-flex"> {this.props.chat_list.map((item, i) => (
<ChatIcon fontSize="small" /> <Chat key={i} data={item} />
</Link> ))}
</div> <Link to="/characters" className="chat-list__float d-flex">
<ChatIcon fontSize="small" />
</Link>
</div> : null
}
{
window.innerWidth > 1000 ?
<div className="desktop-chat d-flex">
<div className="desktop-chat__list d-flex flex-column">
<Search />
{this.props.chat_list.map((item, i) => (
<Chat key={i} data={item} parent={this} />
))}
<Link to="/characters" className="desktop-chat__list--float d-flex">
<ChatIcon fontSize="small" />
</Link>
</div>
{
this.state.selectedUser ?
<Chatroom id={this.state.selectedUser} /> : null
}
</div> : null
}
</>
); );
} }
} }

@ -24,3 +24,40 @@
} }
} }
} }
.desktop-chat{
width: 100vw;
height: 100vh;
max-width: 1250px;
margin: 0px auto;
&__list{
width: cacl(100% / 3);
min-width: 350px;
height: 100%;
overflow-y: scroll;
scrollbar-width: 0px;
box-shadow: 0px 0px 5px rgb(230, 230, 230);
position: relative;
padding: 10px;
&::-webkit-scrollbar{
display: none;
}
&--float {
position: absolute;
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;
}
}
}
}

@ -18,7 +18,7 @@ class List extends Component {
this.state = { this.state = {
emoji: false, emoji: false,
counter: 1, counter: 1,
id: window.location.href.split('/').pop() * 1, id: window.innerWidth < 1000 ? window.location.href.split('/').pop() * 1 : this.props.id,
data: {}, data: {},
message: '', message: '',
voice: null, voice: null,
@ -352,10 +352,17 @@ class List extends Component {
// this.componentDidUpdate(); // this.componentDidUpdate();
} }
componentDidUpdate() { 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){
this.props.info({ id: window.innerWidth < 1000 ? window.location.href.split('/').pop() * 1 : this.props.id });
this.props.list({ chatId: window.innerWidth < 1000 ? window.location.href.split('/').pop() * 1 : this.props.id });
}
} }
randomColor() { 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);

@ -15,7 +15,7 @@
.chat-body { .chat-body {
background-color: rgb(210, 196, 214); background-color: rgb(210, 196, 214);
// justify-content: flex-start; // justify-content: flex-start;
flex: 1; width: 100%;
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
font-family: numeralLight; font-family: numeralLight;
@ -23,9 +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;
margin-bottom: 55px; height: calc(100vh);
height: 100%;
min-height: 200px;
position: relative; position: relative;
&--preview { &--preview {
position: absolute; position: absolute;
@ -83,6 +81,10 @@
} }
} }
} }
&::-webkit-scrollbar{
width: 0px;
display: none;
}
} }
&__footer { &__footer {
width: 100%; width: 100%;
@ -91,17 +93,22 @@
background: url(../../../assets/images/whatsapp.png); background: url(../../../assets/images/whatsapp.png);
// box-shadow: 0px 0px 5px 2px #9d9595ad; // box-shadow: 0px 0px 5px 2px #9d9595ad;
background-size: cover; background-size: cover;
overflow-y: scroll; overflow-y: hidden;
overflow-x: hidden; overflow-x: hidden;
position: fixed; padding-bottom: 15px;
bottom: 0px; &::-webkit-scrollbar{
left: 0; width: 0px;
padding-bottom: 5px; display: none;
}
&--emoji{ &--emoji{
margin-top: 5px; margin-top: 5px;
width: 100%; width: 100%;
background-color: red; background-color: red;
height: 250px; height: 250px;
&::-webkit-scrollbar{
width: 0px;
display: none;
}
// justify-self: flex-end; // justify-self: flex-end;
// position: absolute; // position: absolute;
// bottom: 0px; // bottom: 0px;

@ -0,0 +1,90 @@
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 './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) {
const classes = useStyles();
const theme = useTheme();
return (
<div>
<React.Fragment key={'left'}>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
open={props.open}
classes={{
paper: classes.drawerPaper,
}}
>
<Info />
</Drawer>
</React.Fragment>
</div>
);
}

@ -0,0 +1,4 @@
.MuiDrawer-paper{
position: absolute !important;
}

@ -33,7 +33,7 @@ class Header extends Component {
window.history.back(); window.history.back();
}; };
render() { render() {
const { page, setPage, chatInfo } = 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">
@ -42,10 +42,10 @@ class Header extends Component {
onClick={() => onClick={() =>
page === "chatroom" ? this.back() : setPage("chatroom") page === "chatroom" ? this.back() : setPage("chatroom")
} }
style={{ color: "white", width: 29, height: 29, marginTop: 4 }} style={{ color: "grey", width: 29, height: 29, marginTop: 4 }}
/> />
<div <div
onClick={() => setPage("info")} 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 />
@ -61,7 +61,7 @@ class Header extends Component {
aria-controls="simple-menu" aria-controls="simple-menu"
aria-haspopup="true" aria-haspopup="true"
onClick={this.handleClick} onClick={this.handleClick}
style={{ color: "white", width: 32, height: 32 }} style={{ color: "grey", width: 32, height: 32 }}
/> />
{/* <VideocamIcon style={{ color: 'white', width: 30, height: 30, marginLeft: 8 }} /> {/* <VideocamIcon style={{ color: 'white', width: 30, height: 30, marginLeft: 8 }} />
<CallIcon style={{ color: 'white', width: 27, height: 27, marginLeft: 17 }} /> */} <CallIcon style={{ color: 'white', width: 27, height: 27, marginLeft: 17 }} /> */}

@ -6,19 +6,19 @@
align-items: flex-end; align-items: flex-end;
padding: 5px 5px 5px; padding: 5px 5px 5px;
position: relative; position: relative;
background-color: #128c7e; background-color: #d4d4d4;
&__info { &__info {
text-align: right; text-align: right;
& h1 { & h1 {
font-size: 16px; font-size: 16px;
color: white; color: black;
margin: 0px; margin: 0px;
margin-bottom: 5px; margin-bottom: 5px;
font-weight: 600; font-weight: 600;
} }
& span { & span {
color: white; color: #464646;
font-size: 11px; font-size: 11px;
} }
} }

@ -2,6 +2,8 @@ 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 './index.scss'; import './index.scss';
export default class ChatRoom extends Component { export default class ChatRoom extends Component {
constructor(props) { constructor(props) {
@ -9,11 +11,25 @@ export default class ChatRoom extends Component {
window.nav = this.nav.bind(this); window.nav = this.nav.bind(this);
this.state = { this.state = {
page: 'chatroom', page: 'chatroom',
open: false,
}; };
} }
nav = (url) => { nav = (url) => {
this.props.history.push(url); this.props.history.push(url);
}; };
handleDrawerOpen = () => {
this.setState({
open: true,
})
};
handleDrawerClose = () => {
this.setState({
open: false,
})
};
setPage = (val) => { setPage = (val) => {
this.setState({ this.setState({
page: val, page: val,
@ -22,10 +38,11 @@ export default class ChatRoom extends Component {
render() { render() {
return ( return (
<div className="chat-room d-flex flex-column"> <div className="chat-room d-flex flex-column">
<Header page={this.state.page} setPage={this.setPage} /> <Header page={this.state.page} setPage={this.setPage} parent={this} />
{this.state.page === 'chatroom' ? ( {this.state.page === 'chatroom' ? (
<> <>
<Body setPage={this.setPage} /> <Body id={this.props.id} setPage={this.setPage} />
<Drawer open={this.state.open} parent={this} />
</> </>
) : ( ) : (
<> <>

@ -6,7 +6,7 @@
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
width: 100vw; width: 100vw;
box-shadow: 0px 0px 40px rgba(145, 145, 145, 0.8); position: relative;
&__status { &__status {
border-top-left-radius: 40px; border-top-left-radius: 40px;
border-top-right-radius: 40px; border-top-right-radius: 40px;

Loading…
Cancel
Save