To match good practice I will start with frontend and to make things simple I will use Material-UI. Simple slack clone need a left panel with channels and main panel with chat. I will reuse part of the layout from my previous post about material ui and I will add simple input and messages.
I will also try to make all my components functional instead of creating classes. For managing state in my functional components I will use use-global-hook package.
There is a great reading about react functional components by example if you want to learn how to create react functional components. Also there is great reading about why functional components.
I started with drawer containing two rooms named general
and test
. I also added direct message to user named testUser.
From functionalities there is button to add room
On chat room panel there is TextField to type message and send it to room. Each message is typography component.
To simplify I made one global model and decided to use custom MVC pattern. My prototype now look like this.
After I divided my components for ChatBar, ChatDrawer and ChatContent and placed message input to the bottom I added some states to be able to add messages when typing enter.
I added feature that if you hold shift and press enter it will result in new line.
My handlers in my ChatContent component are now a bit messy and look like this.
const classes = themeStyles();
const [message, setMessage] = React.useState('');
const [messageRows, setMessageRows] = React.useState(1);
const [messageList, setMessageList] = React.useState([]);
const handleKeyPress = (e) => {
if (e.charCode === 13) {
if(e.shiftKey) {
setMessageRows(messageRows+1);
} else {
messageList.push(message);
setMessageList(messageList);
setMessage('');
setMessageRows(1);
}
}
}
const handleChange = (e) => {
setMessage(e.target.value);
}
I struggled with css to position everything so I called it a day.
Next day I looked at design and something was wrong with this layout so I decided to create one more main component on bottom and place my chat message text input there so I can have cleaner layout and don't mess with css so much. I named it MessageBar. I also moved list of messages to model and I got almost all frontend ready for accepting input from backend.
Last thing I've done was placing chat content data scroll on bottom of the div so I could view last message after I press enter. As always stackoverflow answer was a relief.
So now my chat frontend look like this.
Remaining functionalities for frontend are create / join room and start screeen with nick input. I will make those and update this post.
Next post will be about backend tornado and rethinkdb.
You can see the demo frontend application here