v1.3.0-beta/UI redone

This commit is contained in:
2020-05-31 00:35:24 -04:00
parent fba32fd7d1
commit aa15c4eb30
21 changed files with 676 additions and 333 deletions
+188 -180
View File
@@ -1,200 +1,208 @@
import React, { useState } from 'react';
import React, { Component } from 'react';
import { Button, TextField, Typography, Paper, ButtonGroup } from '@material-ui/core';
import {
Button,
InputAdornment,
TextField,
Typography,
IconButton,
Paper,
} from '@material-ui/core';
import Save from '@material-ui/icons/Save';
import { JoinRoomApi, CreateRoomApi, PLAYER_STATUS, getPlayerSource } from './Api';
JoinRoomApi,
CreateRoomApi,
PLAYER_STATUS,
getPlayerSource,
LocalData,
updateLocalData,
} from './Api';
import { goTo } from 'route-lite';
import Chat from './Chat';
import { ChevronRight } from '@material-ui/icons';
const saveName = (data) => {
const { name, notify } = data;
window.localStorage.setItem('watchPartyUserName', name);
notify('Saved name');
const CONSTANTS = {
USER_NAME_LENGTH: 12,
NAME_LENGTH: 24,
PIN_LENGTH: 9,
};
const getName = () => window.localStorage.getItem('watchPartyUserName');
const saveRoomId = (data) => {
const { rid, notify } = data;
window.localStorage.setItem('watchPartyRoomId', rid);
notify('Saved room');
};
const getRoomId = () => window.localStorage.getItem('watchPartyRoomId');
const joinRoom = async (data) => {
data.props.updateLoading(true);
data.props.notify('Joining party...');
const apidata = {
roomId: data.joinName.trim(),
userName: data.name.trim(),
source: getPlayerSource(),
};
const confirmedRoomId = await JoinRoomApi(apidata)
.then((res) => res.json())
.then((res) => res.roomId)
.catch((err) => {
data.props.updateLoading(false);
data.props.notify(err.message || err.statusText);
console.error('Join Room API error', err);
});
if (confirmedRoomId && confirmedRoomId === apidata.roomId) {
saveName({
name: apidata.userName,
notify: data.props.notify,
});
saveRoomId({
rid: confirmedRoomId,
notify: data.props.notify,
});
data.props.notify('Joined party');
goTo(Chat, data.props);
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);
}
};
const createRoom = async (data) => {
data.props.updateLoading(true);
data.props.notify('Starting party...');
const apidata = {
roomPin: data.createPin,
roomName: data.createName,
userName: data.name,
player: {
source: getPlayerSource(),
status: PLAYER_STATUS.PAUSED,
time: 0,
url: '',
},
};
CreateRoomApi(apidata)
.then((res) => res.json())
.then((res) => {
if (res.status <= 299) {
saveName({
name: data.name,
notify: data.props.notify,
});
saveRoomId({
rid: res.roomId,
notify: data.props.notify,
});
data.props.notify('Started party');
goTo(Chat, data.props);
} else {
data.props.updateLoading(false);
data.props.notify(res.message || res.statusText);
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() {
const { userName, name, pin, mode } = this.state;
if (!userName.replace(/\s+/g, '')) {
this.props.notify('Missing user name');
return;
}
if (!name.replace(/\s+/g, '')) {
this.props.notify('Missing party name');
return;
}
if (!pin.replace(/\s+/g, '')) {
this.props.notify('Missing party pin');
return;
}
if (userName && name && pin) {
switch (mode) {
case 'create':
this.createCall(userName, name, pin);
break;
case 'join':
this.joinCall(userName, name, pin);
break;
default:
break;
}
})
.catch((err) => {
data.props.updateLoading(false);
data.props.notify(err.message || err.statusText);
console.error('Create Room API error', err);
});
};
const Create = (props) => {
const [name, setName] = useState(getName() || '');
const [createName, setCreateName] = useState('');
const [createPin, setCreatePin] = useState('');
const [joinName, setJoinName] = useState(getRoomId() || '');
const [joinPin, setJoinPin] = useState('');
const { notify } = props;
return (
<div className="party-create-container">
<Typography className="brand-title" variant="h6" display="block" gutterBottom>
WATCH PARTY
</Typography>
<div className="party-create-inputs">
<TextField
fullWidth
value={name}
onChange={(e) => (e.target.value.length <= 24 ? setName(e.target.value) : null)}
className="name-field"
label="Name"
variant="filled"
helperText={name.length > 0 ? `${name.length}/24` : null}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => saveName({ name, notify })}>
<Save />
</IconButton>
</InputAdornment>
),
}}
/>
<Paper className="join-card" elevation={3}>
<Typography variant="button" display="block" gutterBottom>
CREATE PARTY
</Typography>
<TextField
fullWidth
value={createName}
className="card-field addFocus"
onChange={(e) => (e.target.value.length <= 24 ? setCreateName(e.target.value) : null)}
helperText={createName.length > 0 ? `${createName.length}/24` : null}
label="Party Name"
/>
<TextField
fullWidth
type="number"
value={createPin}
className="card-field addFocus"
onChange={(e) => (e.target.value.length <= 10 ? setCreatePin(e.target.value) : null)}
helperText={createPin.length > 0 ? `${createPin.length}/10` : null}
label="Pin Code"
/>
<Button
onClick={() => createRoom({ name, createName, props, createPin })}
disabled={createName === ''}
color="primary"
fullWidth
variant="contained"
>
CREATE
</Button>
</Paper>
<Paper className="join-card" elevation={3}>
<Typography variant="button" display="block" gutterBottom>
JOIN PARTY
</Typography>
} 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"
fullWidth
value={joinName}
className="card-field addFocus"
onChange={(e) => setJoinName(e.target.value)}
label="Party Name"
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
fullWidth
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={joinPin}
className="card-field addFocus"
onChange={(e) => setJoinPin(e.target.value)}
helperText="Ask your party leader for this code"
label="Pin Code"
value={pin}
onChange={(e) => this.partyPinChange(e.target.value)}
helperText={pin ? `${pin.length}/${CONSTANTS.PIN_LENGTH} Digits` : null}
/>
<Button
onClick={() => joinRoom({ joinName, name, props, joinPin })}
disabled={joinName === ''}
size="small"
variant="contained"
color="secondary"
fullWidth
onClick={() => this.createOrJoin()}
>
JOIN
<span>{mode === 'create' ? 'Start Party' : 'Join Party'}</span> <ChevronRight />
</Button>
</Paper>
</div>
</div>
);
};
export default Create;
);
}
}