Files
watchparty/app/src/Create.js
T
2020-07-15 01:09:59 -04:00

248 lines
7.3 KiB
JavaScript

import React, { Component } from 'react';
import { Button, TextField, Typography, Paper, ButtonGroup } from '@material-ui/core';
import {
JoinRoomApi,
CreateRoomApi,
PLAYER_STATUS,
getPlayerSource,
LocalData,
updateLocalData,
} from './Api';
import { goTo } from 'route-lite';
import Chat from './Chat';
import {
ChevronRight,
InfoRounded,
ContactSupportRounded,
MonetizationOnRounded,
} from '@material-ui/icons';
const CONSTANTS = {
USER_NAME_LENGTH: 12,
NAME_LENGTH: 24,
PIN_LENGTH: 9,
};
export default class Create extends Component {
constructor(props) {
super(props);
const defaultMode = LocalData().partyName ? 'join' : 'create';
this.state = {
userName: LocalData().userName || '',
name: LocalData().partyName || '',
pin: LocalData().partyPin || '',
mode: defaultMode,
};
this.createCall = this.createCall.bind(this);
this.joinCall = this.joinCall.bind(this);
this.success = this.success.bind(this);
}
partyNameChange(value) {
if (value.length <= CONSTANTS.NAME_LENGTH) this.setState({ name: value });
}
partyPinChange(value) {
if (value.length <= CONSTANTS.PIN_LENGTH) this.setState({ pin: value });
}
userNameChange(value) {
if (value.length <= CONSTANTS.USER_NAME_LENGTH) this.setState({ userName: value });
}
createOrJoin() {
this.props.updateLoading(true);
const { userName, name, pin, mode } = this.state;
if (!userName.replace(/\s+/g, '')) {
this.props.notify('Missing user name');
this.props.updateLoading(false);
return;
}
if (!name.replace(/\s+/g, '')) {
this.props.notify('Missing party name');
this.props.updateLoading(false);
return;
}
if (!pin.replace(/\s+/g, '')) {
this.props.notify('Missing party pin');
this.props.updateLoading(false);
return;
}
if (userName && name && pin) {
switch (mode) {
case 'create':
this.createCall(userName, name, pin);
break;
case 'join':
this.joinCall(userName, name, pin);
break;
default:
this.props.updateLoading(false);
break;
}
} else {
this.props.notify('Double check your inputs');
}
}
createCall(userName, partyName, partyPin) {
this.props.updateLoading(true);
const apidata = {
userName,
partyName,
partyPin,
player: {
source: getPlayerSource(),
status: PLAYER_STATUS.PAUSED,
time: 0,
url: window.location.href,
},
};
CreateRoomApi(apidata)
.then((res) => res.json())
.then((createResult) => {
if (createResult.status <= 299) {
this.success(userName, partyName, partyPin);
} else {
this.props.updateLoading(false);
this.props.notify(createResult.message || createResult.statusText);
}
})
.catch((err) => {
console.error('Create Party API Error', err);
this.props.notify(err.message || 'Something went wrong');
this.props.updateLoading(false);
});
}
joinCall(userName, partyName, partyPin) {
const apidata = {
userName,
partyName,
partyPin,
source: getPlayerSource(),
};
JoinRoomApi(apidata)
.then((res) => res.json())
.then((joinResult) => {
if (joinResult.status <= 299) {
this.success(userName, partyName, partyPin);
} else {
this.props.updateLoading(false);
this.props.notify(joinResult.message || joinResult.statusText);
}
})
.catch((err) => {
console.error('Join Party API Error', err);
this.props.notify(err.message || 'Something went wrong');
this.props.updateLoading(false);
});
}
success(userName, partyName, partyPin) {
updateLocalData({ userName, partyName, partyPin });
this.props.updateLoading(false);
goTo(Chat, this.props);
}
render() {
const { mode, name, pin, userName } = this.state;
return (
<div className="party-create-container">
<Typography
color="secondary"
className="brand-title"
variant="h6"
display="block"
gutterBottom
>
WATCH PARTY
</Typography>
<Paper className="create-input-card" elevation={3}>
<ButtonGroup className="create-mode-select" size="small" fullWidth>
<Button
id="mode-select-left"
variant={mode === 'create' ? 'contained' : null}
color={mode === 'create' ? 'secondary' : null}
disableElevation={mode === 'create'}
onClick={() => this.setState({ mode: 'create' })}
>
Create
</Button>
<Button
id="mode-select-right"
variant={mode === 'join' ? 'contained' : null}
color={mode === 'join' ? 'secondary' : null}
disableElevation={mode === 'join'}
onClick={() => this.setState({ mode: 'join' })}
>
Join
</Button>
</ButtonGroup>
<TextField
color="secondary"
size="small"
className="create-name"
label="Name"
variant="outlined"
value={userName}
onChange={(e) => this.userNameChange(e.target.value)}
helperText={
userName ? `${userName.length}/${CONSTANTS.USER_NAME_LENGTH} Characters` : null
}
/>
<TextField
color="secondary"
size="small"
className="create-name"
label="Party Name"
variant="outlined"
value={name}
onChange={(e) => this.partyNameChange(e.target.value)}
helperText={name ? `${name.length}/${CONSTANTS.NAME_LENGTH} Characters` : null}
/>
<TextField
color="secondary"
size="small"
className="create-pin"
label="Party Pin"
variant="outlined"
type="number"
value={pin}
onChange={(e) => this.partyPinChange(e.target.value)}
helperText={pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null}
/>
<Button
size="small"
variant="contained"
color="secondary"
onClick={() => this.createOrJoin()}
>
<span>{mode === 'create' ? 'Start Party' : 'Join Party'}</span> <ChevronRight />
</Button>
</Paper>
<div className="create-bottom-card">
<Button
color="secondary"
target="_blank"
startIcon={<InfoRounded />}
size="small"
href="https://www.chromewatchparty.com/welcome/#tips"
>
FAQ
</Button>
<Button
color="secondary"
target="_blank"
startIcon={<ContactSupportRounded />}
size="small"
href="mailto:admin@chromewatchparty.com?subject=User Feedback"
>
Feedback
</Button>
<Button
color="secondary"
target="_blank"
startIcon={<MonetizationOnRounded />}
size="small"
href="https://paypal.me/Ayushya"
>
Donate
</Button>
</div>
</div>
);
}
}