Created
May 22, 2019 02:57
-
-
Save kvnam/3896ca1dd4e5b4cd7e4ef6a71555612c to your computer and use it in GitHub Desktop.
ReactChat-ChatComponent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useEffect } from "react"; | |
import Grid from "@material-ui/core/Grid"; | |
import { | |
createStyles, | |
Theme, | |
WithStyles, | |
withStyles, | |
Typography, | |
Button | |
} from "@material-ui/core"; | |
import List from "@material-ui/core/List"; | |
import ListItem from "@material-ui/core/ListItem"; | |
import ListItemText from "@material-ui/core/ListItemText"; | |
import TextField from '@material-ui/core/TextField'; | |
import Message from "../components/Room/Chat/Message"; | |
import { getUserService } from "../services/Users"; | |
import { getWSService } from "../services/WebSocket"; | |
import "./chatroom.scss"; | |
interface User { | |
username: string; | |
room: string; | |
joined? : Date | |
last_active? : Date | |
} | |
interface Message { | |
type: string; | |
msg: any; | |
sent: Date | string; | |
user: User; | |
} | |
const styles = (theme: Theme) => | |
createStyles({ | |
... | |
}); | |
export interface Props extends WithStyles<typeof styles> { | |
user: User; | |
} | |
function ChatRoom(props: Props) { | |
const { classes } = props; | |
//Handle users | |
const [users, setUsers] = useState<User[]>( | |
getUserService().getUserList(props.user.room) | |
); | |
//Handle the messages in the chat window | |
const [messageList, updateMessageList] = useState<Message[]>([]); | |
const [fields, setFields] = useState({ | |
userService: getUserService(), | |
userAdded: false | |
}); | |
//Handle message being sent by the user | |
const [currentMessage, setCurrentMessage] = useState<Message>({ | |
type: "", | |
msg: "", | |
user: { | |
username: "", | |
room: "" | |
}, | |
sent: "" | |
}); | |
//Add message to the list | |
const addMessageToList = (message: Message) => { | |
let updatedList = [...messageList]; | |
updatedList.push(message); | |
updateMessageList(updatedList); | |
} | |
//Handler to receive chat messages from the WebSocket service | |
const chatMessageHandler = (message: Message) => { | |
if (message.type === "all") { | |
addMessageToList(message); | |
} | |
}; | |
//Handler to receive user list messages from the WebSocket service | |
const userListMessageHandler = (message: Message) => { | |
if(message.type === "userlist"){ | |
const userList = message.msg; | |
const updatedUserList = userList.map((msgObj: User) => { | |
const { joined, username, room, last_active, } = msgObj; | |
return { | |
joined, | |
username, | |
room, | |
last_active, | |
}; | |
}); | |
setUsers(updatedUserList); | |
} | |
} | |
//Handle input change | |
const onInputChange = (event: React.FormEvent<EventTarget>) => { | |
let eventTarget = event.target as HTMLInputElement; | |
let updatedMsg = { ...currentMessage }; | |
updatedMsg.msg = eventTarget.value; | |
setCurrentMessage(updatedMsg); | |
} | |
// Handle sending of a message to chat | |
const onSendMessage = () => { | |
let updatedMsg = { ...currentMessage }; | |
updatedMsg.type = "all"; | |
updatedMsg.sent = new Date(); | |
updatedMsg.user = { | |
username: props.user.username, | |
room: props.user.room | |
}; | |
setCurrentMessage(updatedMsg); | |
getWSService().sendMessage("test", updatedMsg); | |
//Add this message to chat | |
addMessageToList(updatedMsg); | |
//Reset chat box | |
updatedMsg = { | |
type: "", | |
msg: "", | |
user: { | |
username: "", | |
room: "" | |
}, | |
sent: "" | |
}; | |
setCurrentMessage(updatedMsg); | |
} | |
//Handle the change in user service status | |
useEffect(() => { | |
if(!fields.userAdded && !users.find(usrVal => usrVal.username === props.user.username)){ | |
const userAdd = fields.userService.addUser({ | |
username: props.user.username, | |
room: props.user.room | |
}); | |
setFields({...fields, userAdded: userAdd}); | |
} | |
}, [fields.userService]); | |
//Handle change in user added status | |
useEffect(() => { | |
if ( | |
fields.userAdded && | |
users && | |
!users.find(usrVal => usrVal.username === props.user.username) | |
) { | |
const userList = [...users]; | |
userList.push(props.user); | |
setUsers(userList); | |
//Add message listener for this chat room | |
getWSService().addMessageListener( | |
props.user.room, | |
"all", | |
chatMessageHandler | |
); | |
//Add user list listener | |
getWSService().addMessageListener( | |
props.user.room, | |
"userlist", | |
userListMessageHandler | |
); | |
} | |
}, [fields.userAdded]); | |
if(fields.userAdded){ | |
return ( | |
<Grid | |
container | |
alignItems="flex-start" | |
justify="flex-start" | |
className={classes.roomContainer} | |
> | |
<Grid item xs={12} md={8}> | |
<Grid | |
container | |
alignItems="flex-start" | |
justify="flex-start" | |
direction="column" | |
> | |
<Grid item xs={12} md={12} className={classes.root}> | |
<div className={classes.chatWindow}> | |
<Typography className={classes.greeting} variant="h5"> | |
Welcome to room {props.user.room}! | |
</Typography> | |
{messageList.map((message, index) => ( | |
<Message key={index} message={message} /> | |
))} | |
</div> | |
</Grid> | |
<Grid item xs={12} md={12} className={classes.root}> | |
<Grid container direction="row" alignItems="flex-start"> | |
<Grid item xs={9} md={11}> | |
<div className={classes.sendChatBox}> | |
<TextField id="standard-multiline-flexible" label="Enter your message here" | |
multiline rowsMax="4" fullWidth value={currentMessage.msg} | |
onChange={(event) => onInputChange(event)} | |
className="msg-box" margin="normal" | |
/> | |
</div> | |
</Grid> | |
<Grid item xs={3} md={1}> | |
<div> | |
<Button onClick={onSendMessage} className={classes.sendBtn} variant="contained" | |
type="button" color="secondary">Send</Button> | |
</div> | |
</Grid> | |
</Grid> | |
</Grid> | |
</Grid> | |
</Grid> | |
<Grid item xs={12} md={4}> | |
<div className={classes.members}> | |
<Typography className={classes.greeting} variant="h5"> | |
Members | |
</Typography> | |
<List> | |
{users.map((user, index) => { | |
return ( | |
<ListItem key={user.username + index} className="user-name"> | |
<ListItemText primary={user.username} /> | |
</ListItem> | |
); | |
})} | |
</List> | |
</div> | |
</Grid> | |
</Grid> | |
); | |
} | |
return <div className="loading">Adding you to the room, please wait..</div>; | |
} | |
export default withStyles(styles)(ChatRoom); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment