aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-05-04 12:52:25 +0300
committereug-vs <eugene@eug-vs.xyz>2022-05-04 12:52:25 +0300
commitf35c1cf5480f7506442ac4c9170c5e0a1a4a8b15 (patch)
tree94fa0fa38e8a90df08933c05910bea6bed461291
parent8dc803f882f31430abb600fba250fdcf3334d9bf (diff)
downloadchrono-cube-ui-f35c1cf5480f7506442ac4c9170c5e0a1a4a8b15.tar.gz
feat: remove material UI and useless functionality
-rw-r--r--package.json3
-rw-r--r--src/components/GithubAvatar/GithubAvatar.tsx39
-rw-r--r--src/components/Loading/Loading.tsx33
-rw-r--r--src/components/SolutionCard/SolutionCard.tsx117
-rw-r--r--src/components/Timer.tsx90
-rw-r--r--src/developers.json14
-rw-r--r--src/index.tsx83
-rw-r--r--src/pages/Contribute/Contribute.tsx149
-rw-r--r--src/pages/Profile/Profile.tsx95
-rw-r--r--src/pages/Profile/Registration.tsx85
-rw-r--r--src/pages/Scoreboard/Scoreboard.tsx70
-rw-r--r--src/pages/Timer/Timer.tsx102
-rw-r--r--src/pages/Timer/TimerButton.tsx130
-rw-r--r--src/react-app-env.d.ts1
-rw-r--r--src/requests.ts11
-rw-r--r--src/types.d.ts17
-rw-r--r--src/utils/convertTimeToString.ts18
-rw-r--r--yarn.lock280
18 files changed, 115 insertions, 1222 deletions
diff --git a/package.json b/package.json
index f975405..6f6bd7f 100644
--- a/package.json
+++ b/package.json
@@ -4,11 +4,8 @@
"private": true,
"homepage": "https://eug-vs.github.io/chrono-cube",
"dependencies": {
- "@material-ui/core": "^4.9.7",
- "@material-ui/icons": "^4.9.1",
"axios": "^0.19.2",
"react": "^16.13.1",
- "react-benzin": "^3.0.0",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},
diff --git a/src/components/GithubAvatar/GithubAvatar.tsx b/src/components/GithubAvatar/GithubAvatar.tsx
deleted file mode 100644
index 32ac553..0000000
--- a/src/components/GithubAvatar/GithubAvatar.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import React from 'react';
-
-import {
- Avatar,
- Link,
-} from '@material-ui/core';
-
-interface PropTypes {
- username: string;
-}
-
-const githubUrl = 'https://github.com/';
-const getUserGithubUrl = (username: string): string => githubUrl + username;
-
-const GithubAvatar: React.FC<PropTypes> = ({ username }) => {
- if (username === 'anonymous') return <Avatar/>;
-
- const userGithubUrl = getUserGithubUrl(username);
- const avatarUrl = userGithubUrl + '.png';
- const usernameTokens = username.split(/[ ,.\-_#@;]/g);
- const altText = (
- (usernameTokens.length > 1)?
- (usernameTokens[0][0] + usernameTokens[1][0])
- :
- usernameTokens[0][0]
- ).toUpperCase()
-
- return (
- <Link href={userGithubUrl}>
- <Avatar>
- <img src={avatarUrl} alt={altText} />
- </Avatar>
- </Link>
- )
-};
-
-export { getUserGithubUrl };
-export default GithubAvatar;
-
diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx
deleted file mode 100644
index a784be1..0000000
--- a/src/components/Loading/Loading.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-
-import {
- Card,
- CardHeader,
-} from '@material-ui/core';
-
-import { makeStyles } from '@material-ui/core/styles';
-import CircularProgress from '@material-ui/core/CircularProgress';
-
-
-const useStyles = makeStyles(theme => ({
- root: {
- padding: theme.spacing(1),
- background: theme.palette.background.elevation2,
- },
-}));
-
-const Loading: React.FC = () => {
- const classes = useStyles();
-
- return (
- <Card className={classes.root}>
- <CardHeader
- avatar={(<CircularProgress color="secondary" />)}
- title="Loading"
- subheader="Please, wait."
- />
- </Card>
- )
-};
-
-export default Loading;
diff --git a/src/components/SolutionCard/SolutionCard.tsx b/src/components/SolutionCard/SolutionCard.tsx
deleted file mode 100644
index 7ec8888..0000000
--- a/src/components/SolutionCard/SolutionCard.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, { useState } from 'react';
-
-import {
- Typography,
- Card,
- CardHeader,
- CardContent,
- IconButton,
- Grid,
- Menu,
- MenuItem,
-} from '@material-ui/core';
-import { Solution } from '../../types';
-
-import { makeStyles } from '@material-ui/core/styles';
-import TimerIcon from '@material-ui/icons/Timer';
-import MoreVertIcon from '@material-ui/icons/MoreVert';
-import DeleteIcon from '@material-ui/icons/Delete';
-
-import GithubAvatar from '../GithubAvatar/GithubAvatar';
-import { del } from '../../requests';
-
-
-const DATE_FORMAT = {
- month: 'long',
- day: 'numeric',
- year: 'numeric',
- hour: '2-digit',
- minute: '2-digit',
-};
-
-const useStyles = makeStyles(theme => ({
- root: {
- padding: theme.spacing(1),
- background: theme.palette.background.elevation2,
-
- '& .MuiTypography-h3': {
- margin: theme.spacing(2),
- },
- },
- menu: {
- '& ul': {
- background: theme.palette.background.elevation3,
- }
- },
-}));
-
-
-interface PropTypes {
- data: Solution;
- removeThisCard: (id: number) => void;
-}
-
-
-const SolutionCard: React.FC<PropTypes> = ({ data, removeThisCard }) => {
- const classes = useStyles();
- const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
-
- const author = data.author? data.author.username : 'anonymous';
- const date = new Date(data.date);
-
- const handleOpenMenu = (event: React.MouseEvent<HTMLButtonElement>): void => {
- setAnchorEl(event.currentTarget);
- };
-
- const handleClose = (): void => {
- setAnchorEl(null);
- };
-
- const handleDelete = (): void => {
- del(`solutions/${data.id}/`).then(() => {
- removeThisCard(data.id);
- });
- handleClose();
- };
-
- return (
- <Card className={classes.root}>
- <CardHeader
- avatar={<GithubAvatar username={author} />}
- title={author}
- subheader={date.toLocaleString('default', DATE_FORMAT)}
- action={
- <IconButton onClick={handleOpenMenu}>
- <MoreVertIcon />
- </IconButton>
- }
- />
- <Menu
- anchorEl={anchorEl}
- open={Boolean(anchorEl)}
- keepMounted
- onClose={handleClose}
- className={classes.menu}
- >
- <MenuItem onClick={handleDelete}>
- <DeleteIcon />
- Delete
- </MenuItem>
- </Menu>
- <CardContent>
- <Grid container direction="row" justify="center" alignItems="center">
- <Grid item>
- <TimerIcon/>
- </Grid>
- <Grid item>
- <Typography variant="h3" color="primary">
- { data.result }
- </Typography>
- </Grid>
- </Grid>
- </CardContent>
- </Card>
- )
-};
-
-export default SolutionCard;
diff --git a/src/components/Timer.tsx b/src/components/Timer.tsx
new file mode 100644
index 0000000..c9d7adf
--- /dev/null
+++ b/src/components/Timer.tsx
@@ -0,0 +1,90 @@
+import React, { useState, useEffect } from 'react';
+import convertTimeToString from '../utils/convertTimeToString';
+
+enum Mode {
+ 'idle',
+ 'countdown',
+ 'running' ,
+ 'over',
+};
+
+const helperText = {
+ [Mode.idle]: 'Hold SPACE to start countdown',
+ [Mode.countdown]: 'Release SPACE to begin',
+ [Mode.running]: 'Go fast!',
+ [Mode.over]: 'You are too late!',
+};
+
+// TODO: add to props
+const registerResult = (result: string): void => {
+ console.log(result)
+};
+
+const Timer: React.FC = () => {
+ const KEY_CODE = 32; // Space key
+ const maxCountdown = 15000;
+
+ const [mode, setMode] = useState<Mode>(Mode.idle);
+ const [displayTime, setDisplayTime] = useState<string>('00:00:00');
+
+ useEffect(() => {
+ const timestamp = Date.now();
+
+ if (mode === Mode.countdown) {
+ const repeater = setInterval(() => {
+ const timeDelta = maxCountdown - (Date.now() - timestamp);
+ if (timeDelta <= 0) setMode(Mode.over);
+ setDisplayTime(convertTimeToString(timeDelta));
+ }, 10);
+ return (): void => clearInterval(repeater);
+ }
+
+ if (mode === Mode.running) {
+ const repeater = setInterval(() => {
+ setDisplayTime(convertTimeToString(Date.now() - timestamp));
+ }, 10);
+ return (): void => clearInterval(repeater);
+ }
+
+ if (mode === Mode.over) {
+ setDisplayTime('00:00:00');
+ }
+ }, [mode]);
+
+ const handleKeyPress = (event: KeyboardEvent): void => {
+ event.preventDefault();
+ if (event.keyCode === KEY_CODE && mode === Mode.idle) setMode(Mode.countdown);
+ };
+
+ const handleKeyUp = (event: KeyboardEvent): void => {
+ if (event.keyCode === KEY_CODE) {
+ if (mode === Mode.running) {
+ registerResult(displayTime);
+ setMode(Mode.idle);
+ } else if (mode === Mode.over) {
+ setMode(Mode.idle);
+ } else {
+ setMode(Mode.running);
+ }
+ }
+ };
+
+ useEffect(() => {
+ window.addEventListener('keyup', handleKeyUp);
+ window.addEventListener('keypress', handleKeyPress);
+
+ return () => {
+ window.removeEventListener('keyup', handleKeyUp);
+ window.removeEventListener('keypress', handleKeyPress);
+ };
+ });
+
+ return (
+ <>
+ <span>{ displayTime }</span>
+ <p>{ helperText[mode] }</p>
+ </>
+ );
+};
+
+export default Timer;
diff --git a/src/developers.json b/src/developers.json
deleted file mode 100644
index 00ed2e3..0000000
--- a/src/developers.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "username": "eug-vs",
- "role": "Back-end, front-end, management"
- },
- {
- "username": "asketonim",
- "role": "Front-end, management"
- },
- {
- "username": "soleni",
- "role": "Testing"
- }
-]
diff --git a/src/index.tsx b/src/index.tsx
index 360ca89..2b8d92d 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,87 +1,10 @@
-import React, { useState, useEffect } from 'react';
+import React from 'react';
import ReactDOM from 'react-dom';
-import {
- BenzinThemeProvider,
- Header,
-} from 'react-benzin';
-import { User, Solution } from './types';
-
-import 'typeface-roboto';
-
-import Timer from './pages/Timer/Timer';
-import Scoreboard from './pages/Scoreboard/Scoreboard';
-import Contribute from './pages/Contribute/Contribute';
-import Profile from './pages/Profile/Profile';
-
-import TimerIcon from '@material-ui/icons/Timer';
-import AccountCircleIcon from '@material-ui/icons/AccountCircle';
-import AssignmentIcon from '@material-ui/icons/Assignment';
-import GitHubIcon from '@material-ui/icons/GitHub';
-
-import { get } from './requests';
-
+import Timer from './components/Timer';
const App: React.FC = () => {
- const [page, setPage] = useState<string>('app');
- const [user, setUser] = useState<User>({ username: 'anonymous', id: null });
- const [recentSolutions, setRecentSolutions] = useState<Solution[]>([]);
-
- const headerContents = {
- app: (<TimerIcon />),
- profile: (<AccountCircleIcon />),
- scoreboard: (<AssignmentIcon />),
- contribute: (<GitHubIcon />),
- };
-
- useEffect(() => {
- const userId = localStorage.getItem('userId');
- if (userId) {
- get('users/').then(response => {
- setUser(response.data.filter((user: User) => user.id === +userId)[0]);
- });
- }
- }, []);
-
- const Page: React.FC<{ page: string }> = ({ page }) => {
- switch (page) {
- case 'app':
- return (
- <Timer
- user={user}
- recentSolutions={recentSolutions}
- setRecentSolutions={setRecentSolutions}
- setPage={setPage}
- />
- );
-
- case 'profile':
- return <Profile user={user} setUser={setUser} />;
-
- case 'scoreboard':
- return <Scoreboard />;
-
- case 'contribute':
- return <Contribute />;
-
- default:
- return <Contribute />;
- }
- };
-
- return (
- <BenzinThemeProvider>
- <Header
- logo={{
- title: 'ChronoCube',
- icon: null
- }}
- contents={headerContents}
- page={page}
- setPage={setPage}/>
- <Page page={page} />
- </BenzinThemeProvider>
- );
+ return (<Timer />);
};
document.body.style.overflow = 'hidden';
diff --git a/src/pages/Contribute/Contribute.tsx b/src/pages/Contribute/Contribute.tsx
deleted file mode 100644
index 67f2b8a..0000000
--- a/src/pages/Contribute/Contribute.tsx
+++ /dev/null
@@ -1,149 +0,0 @@
-import React from 'react';
-
-import {
- Typography,
- Button,
- List,
- ListItem,
- Link,
- Divider,
- makeStyles,
-} from '@material-ui/core';
-
-import TrendingUpIcon from '@material-ui/icons/TrendingUp';
-import BugReportIcon from '@material-ui/icons/BugReport';
-import NewReleasesIcon from '@material-ui/icons/NewReleases';
-
-import { Window, ContentSection } from 'react-benzin';
-import GithubAvatar, { getUserGithubUrl } from '../../components/GithubAvatar/GithubAvatar';
-
-import developers from '../../developers.json';
-
-const useStyles = makeStyles(theme => ({
- mono: {
- padding: theme.spacing(4),
-
- '& .MuiAvatar-root': {
- marginRight: theme.spacing(2),
- width: theme.spacing(6),
- height: theme.spacing(6),
- }
- },
-}));
-
-
-
-
-const Contribute: React.FC = () => {
- const classes = useStyles();
-
- return (
- <Window type="mono">
- <div className={classes.mono}>
- <ContentSection sectionName="Thank You for using ChronoCube!">
- <p>
- ChronoCube is an Open-Source application, and we welcome anyone who desires to help our project!
- </p>
- <Button
- variant="contained"
- color="primary"
- startIcon={<TrendingUpIcon />}
- href="https://github.com/users/Eug-VS/projects/3"
- >
- Track our progress
- </Button>
- </ContentSection>
- <ContentSection sectionName="Technology stack">
- <p> We only use modern and most relevant technologies to achieve the best results! </p>
- <ul>
- <li><Link href="https://www.django-rest-framework.org/">
- Django REST Framework
- </Link></li>
- <li><Link href="https://reactjs.org/">
- React.js
- </Link></li>
- <li><Link href="https://material-ui.com/">
- Material UI components
- </Link></li>
- </ul>
- <p> Special thanks to other Open-Source projects which made ChronoCube possible: </p>
- <ul>
- <li><Link href="https://github.com/bvaughn/react-window">
- react-window
- </Link></li>
- </ul>
- </ContentSection>
- <ContentSection sectionName="How can I contribute to the project?">
- <p> Thank You for considering helping our project! </p>
- <p>
- All the development process is being tracked on
- the <Link href="https://github.com/users/Eug-VS/projects/3">KanBan board</Link>.
- You can always check it to see what is the current state of the project.
- To contribute your code, fork our repository and then open
- a <Link href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests">
- Pull Request</Link>. We will carefully review and, hopefully, accept it!
- If you are unfamiliar with this kind of workflow, we recommend
- reading <Link href="https://github.com/features/project-management/">GitHub guidelines</Link>.
- </p>
- <p>
- We always welcome newcomers! If you are unfamiliar with certain technologies or even with the
- development in general, it is great time to start learning something new!
- Our community will kindly assist every your step, and with us you can easily become
- highly-evaluated developer!
- </p>
- <Button
- variant="contained"
- color="primary"
- startIcon={<NewReleasesIcon />}
- href="https://github.com/Eug-VS/chrono-cube/issues/new"
- >
- Suggest feature
- </Button>
- <Button
- variant="contained"
- color="primary"
- startIcon={<BugReportIcon />}
- href="https://github.com/Eug-VS/chrono-cube/issues/new"
- >
- Report a bug
- </Button>
- </ContentSection>
- <ContentSection sectionName="Developers">
- <List>
- {
- developers.map(developer => (
- <div key={developer.username}>
- <ListItem>
- <GithubAvatar username={developer.username} />
- <div>
- <Link href={getUserGithubUrl(developer.username)}>{developer.username}</Link>
- <Typography component="div" color="textSecondary">
- {developer.role}
- </Typography>
- </div>
- </ListItem>
- <Divider variant="middle" />
- </div>
- ))
- }
- <ListItem>
- <GithubAvatar username="anonymous" />
- You can be here!
- </ListItem>
- </List>
- <Button
- variant="contained"
- color="primary"
- size="large"
- href="https://github.com/users/Eug-VS/projects/3"
- >
- Join us!
- </Button>
- </ContentSection>
- </div>
- </Window>
- );
-};
-
-
-export default Contribute;
diff --git a/src/pages/Profile/Profile.tsx b/src/pages/Profile/Profile.tsx
deleted file mode 100644
index 83acb30..0000000
--- a/src/pages/Profile/Profile.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import React, { useState, useEffect } from 'react';
-
-import {
- Button,
- makeStyles,
-} from '@material-ui/core';
-
-import Registration from './Registration';
-import {
- Window,
- ContentSection,
- SmartList,
-} from 'react-benzin';
-import { User, Solution, RenderPropTypes } from '../../types';
-
-import SolutionCard from '../../components/SolutionCard/SolutionCard';
-
-import { get } from '../../requests';
-
-
-const useStyles = makeStyles(theme => ({
- primary: {
- padding: theme.spacing(4),
- },
- cell: {
- padding: theme.spacing(5),
- },
-}));
-
-
-interface PropTypes {
- user: User;
- setUser: (user: User) => void;
-}
-
-
-const Profile: React.FC<PropTypes> = ({ user, setUser }) => {
- const classes = useStyles();
-
- const [profileSolutions, setProfileSolutions] = useState<Solution[]>([]);
-
- const handleLogout = (): void => {
- setUser({ username: 'anonymous', id: null });
- localStorage.clear();
- };
-
- useEffect(() => {
- get(`solutions/?author=${user.id}`).then(response => {
- setProfileSolutions(response.data.reverse());
- });
- }, [user]);
-
- const removeSolution = (id: number): void => {
- setProfileSolutions(profileSolutions.filter((solution => solution.id !== id)));
- };
-
- const renderItem: React.FC<RenderPropTypes> = ({ index, style }) => {
- return (
- <div style={style} className={classes.cell}>
- <SolutionCard data={profileSolutions[index]} removeThisCard={removeSolution} />
- </div>
- );
- };
-
- return (
- <>
- <Window type="primary">
- <div className={classes.primary}>
- { user.id? (
- <ContentSection sectionName={`Welcome back, ${user.username}!`}>
- <p> Total amount of solutions: {profileSolutions.length} </p>
- <p> You can always log out from your account! </p>
- <Button variant="contained" color="secondary" onClick={handleLogout}>
- Logout
- </Button>
- </ContentSection>
- ): (
- <Registration setUser={setUser} />
- )
- }
- </div>
- </Window>
- <Window type="secondary" name="History">
- <SmartList
- itemSize={270}
- itemCount={profileSolutions.length}
- renderItem={renderItem}
- />
- </Window>
- </>
- )
-};
-
-
-export default Profile;
diff --git a/src/pages/Profile/Registration.tsx b/src/pages/Profile/Registration.tsx
deleted file mode 100644
index a5e0f3e..0000000
--- a/src/pages/Profile/Registration.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-import React, {useState} from 'react';
-
-import {
- TextField,
- Button,
- Checkbox,
- FormControlLabel,
- Grid,
-} from '@material-ui/core';
-import { User } from '../../types';
-
-import { ContentSection } from 'react-benzin';
-import { get, post } from '../../requests';
-
-
-interface PropTypes {
- setUser: (user: User) => void;
-}
-
-const Registration: React.FC<PropTypes> = ({ setUser }) => {
-
- const [username, setUsername] = useState<string>('');
- const [isRememberMe, setIsRememberMe] = useState<boolean>(false);
-
- const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
- setUsername(event.target.value);
- };
-
- const handleCheck = (event: React.ChangeEvent<HTMLInputElement>): void => {
- setIsRememberMe(event.target.checked);
- };
-
- const handleSubmit = (): void => {
- if (username !== '') {
- post('users/', { username })
- .then(response => {
- const user = response.data;
- setUser(user);
- if (isRememberMe) {
- localStorage.setItem('userId', user.id);
- }
- })
- .catch(err => {
- get('users/').then(response => {
- const user = response.data.filter((user: User) => user.username === username)[0];
- setUser(user);
- if (isRememberMe) {
- localStorage.setItem('userId', user.id);
- }
- });
- });
- }
- };
-
- return (
- <ContentSection sectionName="Tell us who you are">
- <p> Choose yourself a username to track your progress and compete with others: </p>
- <Grid container direction="column">
- <Grid item>
- <TextField
- variant="outlined"
- color="secondary"
- label="Username"
- value={username}
- onChange={handleChange}
- />
- </Grid>
- <Grid item>
- <FormControlLabel
- control={<Checkbox color="secondary" onChange={handleCheck} />}
- label="Remember me"
- />
- </Grid>
- <Grid item>
- <Button variant="contained" color="secondary" onClick={handleSubmit}>
- Submit!
- </Button>
- </Grid>
- </Grid>
- </ContentSection>
- );
-};
-
-
-export default Registration;
diff --git a/src/pages/Scoreboard/Scoreboard.tsx b/src/pages/Scoreboard/Scoreboard.tsx
deleted file mode 100644
index e4185bd..0000000
--- a/src/pages/Scoreboard/Scoreboard.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import React, { useEffect, useState } from 'react';
-
-import { makeStyles } from '@material-ui/core/styles';
-
-import { Window, SmartList } from 'react-benzin';
-import { Solution, RenderPropTypes } from '../../types';
-
-import SolutionCard from '../../components/SolutionCard/SolutionCard';
-import Loading from '../../components/Loading/Loading';
-
-import { get } from '../../requests';
-
-
-const useStyles = makeStyles(theme => ({
- cell: {
- display: 'flex',
- justifyContent: 'center',
- padding: theme.spacing(4),
-
- '& .MuiCard-root': {
- width: '30%',
- }
- }
-}));
-
-
-const Scoreboard: React.FC = () => {
- const classes = useStyles();
- const [solutions, setSolutions] = useState<Solution[]>([]);
-
- const updateSolutions = (): void => {
- get('scoreboard/').then(response => {
- setSolutions(response.data);
- });
- };
-
- const removeSolution = (id: number): void => {
- updateSolutions();
- };
-
- useEffect(() => {
- setTimeout(updateSolutions, 300);
- }, []);
-
- const renderItem: React.FC<RenderPropTypes> = ({ index, style }) => {
- return (
- <div style={style} className={classes.cell}>
- <SolutionCard data={solutions[index]} removeThisCard={removeSolution}/>
- </div>
- )
- };
-
- return (
- <Window type="mono">
- { solutions.length === 0 &&
- <div className={classes.cell}>
- <Loading/>
- </div>
- }
- <SmartList
- itemSize={300}
- itemCount={solutions.length}
- renderItem={renderItem}
- />
- </Window>
- )
-};
-
-
-export default Scoreboard;
diff --git a/src/pages/Timer/Timer.tsx b/src/pages/Timer/Timer.tsx
deleted file mode 100644
index a890815..0000000
--- a/src/pages/Timer/Timer.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import React from 'react';
-
-import { post } from '../../requests';
-
-import {
- Window,
- ContentSection,
- SmartList,
-} from 'react-benzin';
-import { User, Solution, RenderPropTypes } from '../../types';
-
-import TimerButton from './TimerButton';
-import SolutionCard from '../../components/SolutionCard/SolutionCard';
-
-import { Button, makeStyles } from '@material-ui/core';
-
-
-const useStyles = makeStyles(theme => ({
- primary: {
- padding: theme.spacing(4),
- },
- cell: {
- padding: theme.spacing(5),
- },
-}));
-
-
-interface PropTypes {
- user: User;
- recentSolutions: Solution[];
- setRecentSolutions: (newRecentSolutions: Solution[]) => void;
- setPage: (newPage: string) => void;
-}
-
-
-const Timer: React.FC<PropTypes> = ({ user, recentSolutions, setRecentSolutions, setPage }) => {
- const classes = useStyles();
-
- const registerResult = (result: string): void => {
- const solution = { 'author_id': user.id, result };
- post('solutions/', solution).then(response => {
- setRecentSolutions([response.data].concat(recentSolutions));
- });
- };
-
- const handleLearnMore = (): void => {
- setPage('contribute');
- };
-
- const handleLogin = (): void => {
- setPage('profile');
- };
-
- const removeSolution = (id: number): void => {
- setRecentSolutions(recentSolutions.filter((solution => solution.id !== id)));
- };
-
- const renderItem: React.FC<RenderPropTypes> = ({ index, style }) => {
- const solution = recentSolutions[index];
- return (
- <div style={style} className={classes.cell}>
- <SolutionCard data={solution} removeThisCard={removeSolution} />
- </div>
- );
- };
-
- return (
- <>
- <Window type="primary">
- <div className={classes.primary}>
- <ContentSection sectionName="Welcome to ChronoCube!">
- <p>
- ChronoCube is a professional speedcubing timer.
- Share your results publicly - let everyone see your progress and
- achievements!
- Every speedcuber will benefit
- from using it - both amateur and professional!
- </p>
- <Button variant="contained" color="primary" onClick={handleLearnMore}> Learn more </Button>
- </ContentSection>
- {user.id === null &&
- <ContentSection sectionName="Log into an account">
- <p> Tell us your name so we can track your progress</p>
- <Button variant="contained" color="primary" onClick={handleLogin} size="large"> Login </Button>
- </ContentSection>
- }
- <TimerButton registerResult={registerResult} />
- </div>
- </Window>
- <Window type="secondary" name="Recent solutions">
- <SmartList
- itemSize={270}
- itemCount={recentSolutions.length}
- renderItem={renderItem}
- />
- </Window>
- </>
- );
-};
-
-
-export default Timer;
diff --git a/src/pages/Timer/TimerButton.tsx b/src/pages/Timer/TimerButton.tsx
deleted file mode 100644
index 0a3bf38..0000000
--- a/src/pages/Timer/TimerButton.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import React, { useState, useEffect } from 'react';
-
-import { Paper, Typography } from '@material-ui/core';
-import { makeStyles } from '@material-ui/core/styles';
-
-const useStyles = makeStyles(theme => ({
- root: {
- textAlign: 'center',
- padding: theme.spacing(5),
- background: theme.palette.background.elevation3,
- marginTop: theme.spacing(10),
- },
-}));
-
-
-interface PropTypes {
- registerResult: (result: string) => void;
-}
-
-type Mode = 'idle' | 'countdown' | 'running' | 'over';
-
-
-const TimerButton: React.FC<PropTypes> = ({ registerResult }) => {
- const classes = useStyles();
-
- const SPACE = 32;
- const maxCountdown = 15000;
- const [time, setTime] = useState<string>('00:00:00');
- const [mode, setMode] = useState<Mode>('idle');
-
- useEffect(()=> {
- const timestamp = Date.now();
-
- if (mode === 'countdown') {
- const repeater = setInterval(() => {
- const timeDelta = maxCountdown - (Date.now() - timestamp);
- if (timeDelta <= 0) setMode('over');
- setTime(convertTimeToString(timeDelta));
- }, 10);
- return (): void => clearInterval(repeater);
- }
-
- if (mode === 'running') {
- const repeater = setInterval(() => {
- setTime(convertTimeToString(Date.now() - timestamp));
- }, 10);
- return (): void => clearInterval(repeater);
- }
-
- if (mode === 'over') {
- setTime('00:00:00');
- }
- }, [mode]);
-
- const handleKeyPress = (event: KeyboardEvent): void => {
- event.preventDefault();
- if (event.keyCode === SPACE && mode === 'idle' ) setMode('countdown');
- };
-
- const handleKeyUp = (event: KeyboardEvent): void => {
- if (event.keyCode === SPACE) {
- if (mode === 'running') {
- registerResult(time);
- setMode('idle');
- } else if (mode === 'over') {
- setMode('idle');
- } else {
- setMode('running');
- }
- }
- };
-
- useEffect(() => {
- window.addEventListener('keyup', handleKeyUp);
- window.addEventListener('keypress', handleKeyPress);
-
- return (): void => {
- window.removeEventListener('keyup', handleKeyUp);
- window.removeEventListener('keypress', handleKeyPress);
- };
- });
-
- const composeHelperText = (): string => {
- switch (mode) {
- case 'running': return 'Go fast!';
- case 'countdown': return 'Release SPACE to begin';
- case 'over': return 'You are too late!';
- default: return 'Hold SPACE to start countdown';
- }
- };
-
- const helperColor = (): 'primary' | 'secondary' | 'textSecondary' => {
- switch (mode) {
- case 'running': return 'primary';
- case 'over': return 'secondary';
- default: return 'textSecondary';
- }
- };
-
- return (
- <Paper className={classes.root}>
- <Typography variant="h1"> {time} </Typography>
- <Typography variant="h5" color={helperColor()}>
- {composeHelperText()}
- </Typography>
- </Paper>
- );
-};
-
-const convertTimeToString = (timeDelta: number): string => {
- let resultTime = '';
-
- const minute = Math.floor(timeDelta / 60000);
- if (minute < 10) resultTime += '0';
- resultTime += minute + ':';
-
- let second = Math.floor(timeDelta / 1000);
- if (second > 59) second %= 60;
- if (second < 10) resultTime += '0';
- resultTime += second + ':';
-
- const mill = Math.floor((timeDelta % 1000) / 10);
- if (mill < 10) resultTime += '0';
- resultTime += mill;
-
- return resultTime;
-};
-
-
-export default TimerButton;
diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts
deleted file mode 100644
index 6431bc5..0000000
--- a/src/react-app-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="react-scripts" />
diff --git a/src/requests.ts b/src/requests.ts
deleted file mode 100644
index 0242ed5..0000000
--- a/src/requests.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import axios, { AxiosResponse } from 'axios';
-
-const baseUrl = 'https://eugvs.pythonanywhere.com/';
-const baseApiUrl = baseUrl + 'api/';
-
-export const get = (url: string): Promise<AxiosResponse> => axios.get(baseApiUrl + url);
-
-export const del = (url: string): Promise<AxiosResponse> => axios.delete(baseApiUrl + url);
-
-export const post = (url: string, data: object): Promise<AxiosResponse> => axios.post(baseApiUrl + url, data);
-
diff --git a/src/types.d.ts b/src/types.d.ts
deleted file mode 100644
index 949d410..0000000
--- a/src/types.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export interface User {
- username: string;
- id: number | null;
-}
-
-export interface Solution {
- id: number;
- result: string;
- date: string;
- author: User;
-}
-
-interface RenderPropTypes {
- index: number;
- style: React.CSSProperties;
-}
-
diff --git a/src/utils/convertTimeToString.ts b/src/utils/convertTimeToString.ts
new file mode 100644
index 0000000..098f34a
--- /dev/null
+++ b/src/utils/convertTimeToString.ts
@@ -0,0 +1,18 @@
+export default (timeDelta: number): string => {
+ let resultTime = '';
+
+ const minute = Math.floor(timeDelta / 60000);
+ if (minute < 10) resultTime += '0';
+ resultTime += minute + ':';
+
+ let second = Math.floor(timeDelta / 1000);
+ if (second > 59) second %= 60;
+ if (second < 10) resultTime += '0';
+ resultTime += second + ':';
+
+ const mill = Math.floor((timeDelta % 1000) / 10);
+ if (mill < 10) resultTime += '0';
+ resultTime += mill;
+
+ return resultTime;
+};
diff --git a/yarn.lock b/yarn.lock
index 81d3f12..76efc55 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1147,7 +1147,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
version "7.17.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
@@ -1205,11 +1205,6 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18"
integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==
-"@emotion/hash@^0.8.0":
- version "0.8.0"
- resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
- integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
-
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@@ -1421,77 +1416,6 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
-"@material-ui/core@^4.9.0", "@material-ui/core@^4.9.7":
- version "4.12.4"
- resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.12.4.tgz#4ac17488e8fcaf55eb6a7f5efb2a131e10138a73"
- integrity sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@material-ui/styles" "^4.11.5"
- "@material-ui/system" "^4.12.2"
- "@material-ui/types" "5.1.0"
- "@material-ui/utils" "^4.11.3"
- "@types/react-transition-group" "^4.2.0"
- clsx "^1.0.4"
- hoist-non-react-statics "^3.3.2"
- popper.js "1.16.1-lts"
- prop-types "^15.7.2"
- react-is "^16.8.0 || ^17.0.0"
- react-transition-group "^4.4.0"
-
-"@material-ui/icons@^4.9.1":
- version "4.11.3"
- resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.11.3.tgz#b0693709f9b161ce9ccde276a770d968484ecff1"
- integrity sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==
- dependencies:
- "@babel/runtime" "^7.4.4"
-
-"@material-ui/styles@^4.11.5":
- version "4.11.5"
- resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.5.tgz#19f84457df3aafd956ac863dbe156b1d88e2bbfb"
- integrity sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@emotion/hash" "^0.8.0"
- "@material-ui/types" "5.1.0"
- "@material-ui/utils" "^4.11.3"
- clsx "^1.0.4"
- csstype "^2.5.2"
- hoist-non-react-statics "^3.3.2"
- jss "^10.5.1"
- jss-plugin-camel-case "^10.5.1"
- jss-plugin-default-unit "^10.5.1"
- jss-plugin-global "^10.5.1"
- jss-plugin-nested "^10.5.1"
- jss-plugin-props-sort "^10.5.1"
- jss-plugin-rule-value-function "^10.5.1"
- jss-plugin-vendor-prefixer "^10.5.1"
- prop-types "^15.7.2"
-
-"@material-ui/system@^4.12.2":
- version "4.12.2"
- resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-4.12.2.tgz#f5c389adf3fce4146edd489bf4082d461d86aa8b"
- integrity sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==
- dependencies:
- "@babel/runtime" "^7.4.4"
- "@material-ui/utils" "^4.11.3"
- csstype "^2.5.2"
- prop-types "^15.7.2"
-
-"@material-ui/types@5.1.0":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2"
- integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==
-
-"@material-ui/utils@^4.11.3":
- version "4.11.3"
- resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.11.3.tgz#232bd86c4ea81dab714f21edad70b7fdf0253942"
- integrity sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==
- dependencies:
- "@babel/runtime" "^7.4.4"
- prop-types "^15.7.2"
- react-is "^16.8.0 || ^17.0.0"
-
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -1716,22 +1640,6 @@
dependencies:
"@types/react" "^16"
-"@types/react-transition-group@^4.2.0":
- version "4.4.4"
- resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
- integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
- dependencies:
- "@types/react" "*"
-
-"@types/react@*":
- version "18.0.8"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.8.tgz#a051eb380a9fbcaa404550543c58e1cf5ce4ab87"
- integrity sha512-+j2hk9BzCOrrOSJASi5XiOyBbERk9jG5O73Ya4M0env5Ixi6vUNli4qy994AINcEF+1IEHISYFfIT4zwr++LKw==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
"@types/react@^16":
version "16.14.25"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.25.tgz#d003f712c7563fdef5a87327f1892825af375608"
@@ -3137,11 +3045,6 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
-clsx@^1.0.4:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
- integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
-
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -3583,14 +3486,6 @@ css-tree@^1.1.2:
mdn-data "2.0.14"
source-map "^0.6.1"
-css-vendor@^2.0.8:
- version "2.0.8"
- resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d"
- integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==
- dependencies:
- "@babel/runtime" "^7.8.3"
- is-in-browser "^1.0.2"
-
css-what@^3.2.1:
version "3.4.2"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
@@ -3713,11 +3608,6 @@ cssstyle@^1.0.0, cssstyle@^1.1.1:
dependencies:
cssom "0.3.x"
-csstype@^2.5.2:
- version "2.6.20"
- resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda"
- integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==
-
csstype@^3.0.2:
version "3.0.11"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
@@ -3980,14 +3870,6 @@ dom-converter@^0.2.0:
dependencies:
utila "~0.4"
-dom-helpers@^5.0.1:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
- integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
- dependencies:
- "@babel/runtime" "^7.8.7"
- csstype "^3.0.2"
-
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -4137,11 +4019,6 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-emojilib@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e"
- integrity sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==
-
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
@@ -5436,13 +5313,6 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
-hoist-non-react-statics@^3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
- integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
- dependencies:
- react-is "^16.7.0"
-
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
@@ -5592,11 +5462,6 @@ humanize-url@^1.0.0:
normalize-url "^1.0.0"
strip-url-auth "^1.0.0"
-hyphenate-style-name@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
- integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
-
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -6020,11 +5885,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
-is-in-browser@^1.0.2, is-in-browser@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835"
- integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=
-
is-negative-zero@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
@@ -6800,76 +6660,6 @@ jsprim@^1.2.2:
json-schema "0.4.0"
verror "1.10.0"
-jss-plugin-camel-case@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz#4921b568b38d893f39736ee8c4c5f1c64670aaf7"
- integrity sha512-UH6uPpnDk413/r/2Olmw4+y54yEF2lRIV8XIZyuYpgPYTITLlPOsq6XB9qeqv+75SQSg3KLocq5jUBXW8qWWww==
- dependencies:
- "@babel/runtime" "^7.3.1"
- hyphenate-style-name "^1.0.3"
- jss "10.9.0"
-
-jss-plugin-default-unit@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.0.tgz#bb23a48f075bc0ce852b4b4d3f7582bc002df991"
- integrity sha512-7Ju4Q9wJ/MZPsxfu4T84mzdn7pLHWeqoGd/D8O3eDNNJ93Xc8PxnLmV8s8ZPNRYkLdxZqKtm1nPQ0BM4JRlq2w==
- dependencies:
- "@babel/runtime" "^7.3.1"
- jss "10.9.0"
-
-jss-plugin-global@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.9.0.tgz#fc07a0086ac97aca174e37edb480b69277f3931f"
- integrity sha512-4G8PHNJ0x6nwAFsEzcuVDiBlyMsj2y3VjmFAx/uHk/R/gzJV+yRHICjT4MKGGu1cJq2hfowFWCyrr/Gg37FbgQ==
- dependencies:
- "@babel/runtime" "^7.3.1"
- jss "10.9.0"
-
-jss-plugin-nested@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.9.0.tgz#cc1c7d63ad542c3ccc6e2c66c8328c6b6b00f4b3"
- integrity sha512-2UJnDrfCZpMYcpPYR16oZB7VAC6b/1QLsRiAutOt7wJaaqwCBvNsosLEu/fUyKNQNGdvg2PPJFDO5AX7dwxtoA==
- dependencies:
- "@babel/runtime" "^7.3.1"
- jss "10.9.0"
- tiny-warning "^1.0.2"
-
-jss-plugin-props-sort@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.0.tgz#30e9567ef9479043feb6e5e59db09b4de687c47d"
- integrity sha512-7A76HI8bzwqrsMOJTWKx/uD5v+U8piLnp5bvru7g/3ZEQOu1+PjHvv7bFdNO3DwNPC9oM0a//KwIJsIcDCjDzw==
- dependencies:
- "@babel/runtime" "^7.3.1"
- jss "10.9.0"
-
-jss-plugin-rule-value-function@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.0.tgz#379fd2732c0746fe45168011fe25544c1a295d67"
- integrity sha512-IHJv6YrEf8pRzkY207cPmdbBstBaE+z8pazhPShfz0tZSDtRdQua5jjg6NMz3IbTasVx9FdnmptxPqSWL5tyJg==
- dependencies:
- "@babel/runtime" "^7.3.1"
- jss "10.9.0"
- tiny-warning "^1.0.2"
-
-jss-plugin-vendor-prefixer@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.0.tgz#aa9df98abfb3f75f7ed59a3ec50a5452461a206a"
- integrity sha512-MbvsaXP7iiVdYVSEoi+blrW+AYnTDvHTW6I6zqi7JcwXdc6I9Kbm234nEblayhF38EftoenbM+5218pidmC5gA==
- dependencies:
- "@babel/runtime" "^7.3.1"
- css-vendor "^2.0.8"
- jss "10.9.0"
-
-jss@10.9.0, jss@^10.5.1:
- version "10.9.0"
- resolved "https://registry.yarnpkg.com/jss/-/jss-10.9.0.tgz#7583ee2cdc904a83c872ba695d1baab4b59c141b"
- integrity sha512-YpzpreB6kUunQBbrlArlsMpXYyndt9JATbt95tajx0t4MTJJcCJdd4hdNpHmOIDiUJrF/oX5wtVFrS3uofWfGw==
- dependencies:
- "@babel/runtime" "^7.3.1"
- csstype "^3.0.2"
- is-in-browser "^1.1.3"
- tiny-warning "^1.0.2"
-
jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3:
version "2.4.1"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e"
@@ -7213,11 +7003,6 @@ mem@^4.0.0:
mimic-fn "^2.0.0"
p-is-promise "^2.0.0"
-"memoize-one@>=3.1.1 <6":
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
- integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
-
memory-fs@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
@@ -8236,11 +8021,6 @@ pnp-webpack-plugin@1.6.4:
dependencies:
ts-pnp "^1.1.6"
-popper.js@1.16.1-lts:
- version "1.16.1-lts"
- resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05"
- integrity sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==
-
portfinder@^1.0.25:
version "1.0.28"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
@@ -9148,20 +8928,6 @@ react-app-polyfill@^1.0.6:
regenerator-runtime "^0.13.3"
whatwg-fetch "^3.0.0"
-react-benzin@^3.0.0:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/react-benzin/-/react-benzin-3.1.2.tgz#b78c1f5962aed371f6b12b93333919d339c8cca8"
- integrity sha512-7XMeTnjNF+SbWFvmlnawhcM+1ttKfXRV96omHuyLibu8PUfsBGqdpnS/eF4JsMIHJNEPI2HZhMQCF4yxxWYInw==
- dependencies:
- "@material-ui/core" "^4.9.0"
- axios "^0.19.2"
- emojilib "^2.4.0"
- react "^16.12.0"
- react-dom "^16.12.0"
- react-virtualized-auto-sizer "^1.0.2"
- react-window "^1.8.5"
- typeface-roboto "0.0.75"
-
react-dev-utils@^10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"
@@ -9192,7 +8958,7 @@ react-dev-utils@^10.2.1:
strip-ansi "6.0.0"
text-table "0.2.0"
-react-dom@^16.12.0, react-dom@^16.13.1:
+react-dom@^16.13.1:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==
@@ -9207,16 +8973,11 @@ react-error-overlay@^6.0.7:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb"
integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==
-react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4:
+react-is@^16.13.1, react-is@^16.8.4:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-"react-is@^16.8.0 || ^17.0.0":
- version "17.0.2"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
- integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-
react-scripts@3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a"
@@ -9277,30 +9038,7 @@ react-scripts@3.4.1:
optionalDependencies:
fsevents "2.1.2"
-react-transition-group@^4.4.0:
- version "4.4.2"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
- integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
- dependencies:
- "@babel/runtime" "^7.5.5"
- dom-helpers "^5.0.1"
- loose-envify "^1.4.0"
- prop-types "^15.6.2"
-
-react-virtualized-auto-sizer@^1.0.2:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca"
- integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ==
-
-react-window@^1.8.5:
- version "1.8.7"
- resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.7.tgz#5e9fd0d23f48f432d7022cdb327219353a15f0d4"
- integrity sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==
- dependencies:
- "@babel/runtime" "^7.0.0"
- memoize-one ">=3.1.1 <6"
-
-react@^16.12.0, react@^16.13.1:
+react@^16.13.1:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==
@@ -10661,11 +10399,6 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
-tiny-warning@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
- integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
-
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -10841,11 +10574,6 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typeface-roboto@0.0.75:
- version "0.0.75"
- resolved "https://registry.yarnpkg.com/typeface-roboto/-/typeface-roboto-0.0.75.tgz#98d5ba35ec234bbc7172374c8297277099cc712b"
- integrity sha512-VrR/IiH00Z1tFP4vDGfwZ1esNqTiDMchBEXYY9kilT6wRGgFoCAlgkEUMHb1E3mB0FsfZhv756IF0+R+SFPfdg==
-
typescript@^3.8.3:
version "3.9.10"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"