Skip to content

Commit

Permalink
add change name commnad for chat
Browse files Browse the repository at this point in the history
  • Loading branch information
qnkhuat committed Jul 14, 2021
1 parent eccc230 commit fb96ade
Showing 1 changed file with 119 additions and 88 deletions.
207 changes: 119 additions & 88 deletions client/src/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import PubSub from "../lib/pubsub";
import TextField from '@material-ui/core/TextField';
import KeyboardArrowRightRoundedIcon from '@material-ui/icons/KeyboardArrowRightRounded';

// key in local storage
const USER_CONFIG_KEY = "tstreamUser";

interface TstreamUser {
name: string,
color: string,
Expand All @@ -24,8 +27,7 @@ export interface ChatMsg {
interface State {
msgList: ChatMsg[];
inputContent: string;
name: string;
color: string;
userConfig: TstreamUser | null;
isWaitingUsername: boolean,
tempMsg: string,
}
Expand All @@ -38,12 +40,7 @@ const ChatSection: React.FC<ChatMsg> = ({ Name, Content, Color, Time}) => {
{
Name === '' ?
<div className="font-bold">
{
Content === "Invalid Username" ?
<img src="./warning.png" alt="warning" height="30" width="30" className="inline-block m-2"/> :
<img src="./hand-wave.png" alt="hand-wave" />
}
{Content}
<p>{Content}</p>
</div> :
<>
<span style={{color: Color}} className="font-black">{Name}</span>
Expand All @@ -61,11 +58,12 @@ class Chat extends React.Component<Props, State> {

constructor(props: Props) {
super(props);

let userConfig = this.getUserConfig()
this.state = {
msgList: [],
inputContent: '',
name: '',
color: '',
userConfig: userConfig,
isWaitingUsername: false,
tempMsg: '',
}
Expand Down Expand Up @@ -94,112 +92,147 @@ class Chat extends React.Component<Props, State> {
});
});

const payload = localStorage.getItem('tstreamUser');
if (payload !== null) {
const tstreamUser : TstreamUser = JSON.parse(payload);
this.setState({
name: tstreamUser.name,
color: tstreamUser.color,
});
}

// disable enter default behavior of textarea
document.getElementById("chat-input")!.addEventListener('keydown', (e) => {
var code = e.keyCode || e.which;
if (code === 13) {
if (e.key === 'Enter') {
e.preventDefault();
this.onSendMsg(this.state.inputContent);

let content = this.state.inputContent;
if (content.length > 0 && content[0] == "/") {
this.handleCommand(content.slice(1));
} else {
this.handleSendMsg(content);
}
this.setState({
inputContent: "",
});
}
});

this.props.msgManager.pub("request", constants.MSG_TREQUEST_CACHE_CHAT);
}

onSendMsg(content: string) {
// command doesn't include the first '/'
handleCommand(command: string) {
let args = command.split(' ');
switch (args[0]) {
case "name":
if (args.length == 2) {
let userConfig = this.getUserConfig()
if (userConfig == null) {
let color = constants.COLOR_LIST[Math.floor(Math.random() * (constants.COLOR_LIST.length))];
userConfig = {
name: args[1],
color: color,
}
} else {
userConfig.name = args[1]
}

this.setUserConfig(userConfig);
this.setState({userConfig: userConfig});
this.addNotiMessage(`Set name successfully to ${userConfig.name}`);

} else {
this.addNotiMessage("Invalid command");
}
break;
default:
this.addNotiMessage("Invalid command. Type /help to see available commands");
}

}

// display a notify for viewer only
addNotiMessage(messsage: string) {
let data = {
Name: '',
Content: messsage,
Color: '',
Time: new Date().toISOString(),
};

this.addNewMsg(data);

}



getUserConfig(): TstreamUser | null {
const payload = localStorage.getItem(USER_CONFIG_KEY);
if (payload !== null) {
const tstreamUser : TstreamUser = JSON.parse(payload);
return tstreamUser
} else {
return null
}
}

setUserConfig(config: TstreamUser) {
localStorage.setItem(USER_CONFIG_KEY, JSON.stringify(config));
}

handleSendMsg(content: string) {
let tempMsg : string = content.trim();
let name : string = '';
let color : string = '';

// Don't find the user data in the browser
if (this.state.name === '' || this.state.color === '') {
let notification: string = '';
if (! this.state.userConfig) {

// ask for first time
if (!this.state.isWaitingUsername) {
notification = "Please enter your username (I.e: elonmusk)";
this.setState({
tempMsg: tempMsg,
isWaitingUsername: true,
});
}
else {
this.addNotiMessage("Please enter your username (I.e: elonmusk)");
return ;

} else {
// invalid username
if (tempMsg === '' || tempMsg.length > 10) {
notification = 'Invalid Username';
}
// valid username
else {
name = tempMsg;
color = constants.COLOR_LIST[Math.floor(Math.random() * (constants.COLOR_LIST.length))];
this.setState({
name: name,
color: color,
isWaitingUsername: false,
});
if (tempMsg.includes(" ") || tempMsg === '') {
this.addNotiMessage('Username must contain only lower case letters and number');
return ;

let tstreamUser : TstreamUser = {
} else {
// user just set username

this.addNotiMessage("You can change name again with command /name (newname)");
// valid username
let userConfig : TstreamUser = {
name: tempMsg,
color: color,
color:constants.COLOR_LIST[Math.floor(Math.random() * (constants.COLOR_LIST.length))],
}

localStorage.setItem('tstreamUser', JSON.stringify(tstreamUser));

tempMsg = this.state.tempMsg;
this.setState({
userConfig: userConfig,
isWaitingUsername: false,
});

// if the first message is empty, just ignore it
if (tempMsg === "") {
this.setState({
inputContent: "",
});
return ;
}
}
}
this.setUserConfig(userConfig);

// send notification
if (notification !== '') {
let data = {
Name: '',
Content: notification,
Color: '',
Time: new Date().toISOString(),
};
let data = {
Name: userConfig.name,
Content: this.state.tempMsg,
Color: userConfig.color,
Time: new Date().toISOString(),
};

this.addNewMsg(data);
return ;
this.addNewMsg(data);
this.props.msgManager?.pub(constants.MSG_TCHAT_OUT, data);
}
}
}

if (tempMsg === '') {
return;
}
} else {
let data = {
Name: this.state.userConfig.name,
Content: tempMsg,
Color: this.state.userConfig.color,
Time: new Date().toISOString(),
};

if (name === '') {
name = this.state.name;
this.addNewMsg(data);
this.props.msgManager?.pub(constants.MSG_TCHAT_OUT, data);
}
if (color === '') {
color = this.state.color;
}

let data = {
Name: name,
Content: tempMsg,
Color: color,
Time: new Date().toISOString(),
};

this.addNewMsg(data);
this.props.msgManager?.pub(constants.MSG_TCHAT_OUT, data);
}

render() {
Expand All @@ -217,9 +250,7 @@ class Chat extends React.Component<Props, State> {
}
</div>
<div className="bottom-0 transform w-full" id="chat-input">
<div
className="border-b border-gray-500 flex-shrink-0 flex items-center justify-between"
>
<div className="border-b border-gray-500 flex-shrink-0 flex items-center justify-between">
<TextField
InputProps={{
style: {
Expand Down

0 comments on commit fb96ade

Please # to comment.