Open Nlaniyadav opened 4 weeks ago
Channel list.js
import React from 'react'; import { Channel } from './Channel';
export class ChannelList extends React.Component {
handleClick = id => {
this.props.onSelectChannel(id);
}
render() {
let list = <div className="no-content-message">There is no channels to show</div>;
if (this.props.channels && this.props.channels.map) {
list = this.props.channels.map(c => <Channel key={c.id} id={c.id} name={c.name} participants={c.participants} onClick={this.handleClick} />);
}
return (
<div className='channel-list'>
{list}
</div>);
}
}
Chart.js
import React from 'react'; import { ChannelList } from './ChannelList'; import './chat.scss'; import { MessagesPanel } from './MessagesPanel'; import socketClient from "socket.io-client"; const SERVER = "http://127.0.0.1:8080"; export class Chat extends React.Component {
state = {
channels: null,
socket: null,
channel: null
}
socket;
componentDidMount() {
this.loadChannels();
this.configureSocket();
}
configureSocket = () => {
var socket = socketClient(SERVER);
socket.on('connection', () => {
if (this.state.channel) {
this.handleChannelSelect(this.state.channel.id);
}
});
socket.on('channel', channel => {
let channels = this.state.channels;
channels.forEach(c => {
if (c.id === channel.id) {
c.participants = channel.participants;
}
});
this.setState({ channels });
});
socket.on('message', message => {
let channels = this.state.channels
channels.forEach(c => {
if (c.id === message.channel_id) {
if (!c.messages) {
c.messages = [message];
} else {
c.messages.push(message);
}
}
});
this.setState({ channels });
});
this.socket = socket;
}
loadChannels = async () => {
fetch('http://localhost:8080/getChannels').then(async response => {
let data = await response.json();
this.setState({ channels: data.channels });
})
}
handleChannelSelect = id => {
let channel = this.state.channels.find(c => {
return c.id === id;
});
this.setState({ channel });
this.socket.emit('channel-join', id, ack => {
});
}
handleSendMessage = (channel_id, text) => {
this.socket.emit('send-message', { channel_id, text, senderName: this.socket.id, id: Date.now() });
}
render() {
return (
<div className='chat-app'>
<ChannelList channels={this.state.channels} onSelectChannel={this.handleChannelSelect} />
<MessagesPanel onSendMessage={this.handleSendMessage} channel={this.state.channel} />
</div>
);
}
}
Message.js
import React from 'react';
export class Message extends React.Component {
render() {
return (
<div className='message-item'>
<div><b>{this.props.senderName}</b></div>
<span>{this.props.text}</span>
</div>
)
}
}
Message pannel.js
import React from 'react'; import { Message } from './Message';
export class MessagesPanel extends React.Component { state = { input_value: '' } send = () => { if (this.state.input_value && this.state.input_value != '') { this.props.onSendMessage(this.props.channel.id, this.state.input_value); this.setState({ input_value: '' }); } }
handleInput = e => {
this.setState({ input_value: e.target.value });
}
render() {
let list = <div className="no-content-message">There is no messages to show</div>;
if (this.props.channel && this.props.channel.messages) {
list = this.props.channel.messages.map(m => <Message key={m.id} id={m.id} senderName={m.senderName} text={m.text} />);
}
return (
<div className='messages-panel'>
<div className="meesages-list">{list}</div>
{this.props.channel &&
<div className="messages-input">
<input type="text" onChange={this.handleInput} value={this.state.input_value} />
<button onClick={this.send}>Send</button>
</div>
}
</div>);
}
}
Chart.scss
.chat-app { width: 100%; height: 100%; display: flex;
.no-content-message {
color: #cccccc;
font-style: italic;
font-size: 20px;
text-align: center;
margin: 20px;
}
.channel-list {
width: calc(20% - 12px);
border: 1px solid rgb(224, 224, 224);
margin: 10px;
margin-right: 0;
border-right: none;
height: calc(100% - 22px);
}
.channel-item {
border-bottom: 1px solid rgb(224, 224, 224);
padding: 10px;
div {
font-weight: bold;
}
span {
font-size: 10px;
}
&:hover {
background-color: rgb(224, 224, 224);
cursor: pointer;
}
}
.messages-panel {
width: calc(80% - 12px);
border: 1px solid rgb(224, 224, 224);
margin: 10px;
margin-left: 0;
height: calc(100% - 22px);
display: flex;
flex-direction: column;
align-items: flex-start;
.meesages-list {
align-self: stretch;
height: 100%;
}
.messages-input {
width: 100%;
height: 40px;
border-top: 1px solid rgb(224, 224, 224);
background-color: #f0f0f0;
display: flex;
input {
margin: auto;
height: 20px;
width: 100%;
margin-left: 15px;
border-radius: 15px;
border: 1px solid rgb(224, 224, 224);
&:focus {
border-radius: 15px;
border: 2px solid #66a6ff;
outline: none;
}
}
button {
width: 60px;
margin: auto 10px;
background-color: #0e62da;
color: white;
border: 1px solid;
border-radius: 10px;
padding: 5px 13px;
&:hover {
cursor: pointer;
background-color: #66a6ff;
}
}
}
}
}
Channel.js
import React from 'react';
export class Channel extends React.Component {
}