Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Novo Layout: Morpheus #174

Merged
merged 39 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
6bef460
Initial commit for Morpheus Office
Jun 28, 2019
60f37b5
Add the White Rabbit
Jun 28, 2019
e974ba5
Add .vscode dir to git ignore
Jun 28, 2019
4e0c0cf
Add room page to morpheus
Jun 28, 2019
7884b2c
organize a little more the morpheus store
Jun 30, 2019
642e235
Add office search filter to app bar
Jun 30, 2019
8b3e5bb
add users search filter in drawer
Jun 30, 2019
7629185
improving RoomCard layout
Jun 30, 2019
6963c46
Add snackbar and new socket events
Jun 30, 2019
68ffada
Add room name to users list
Jun 30, 2019
41b09e1
add invitaion feature to morpheus
Jun 30, 2019
6690ec4
Fix user name in app bar
Jun 30, 2019
ca45b33
Merge branch 'master' into feature/morpheus
juliemar Jul 2, 2019
bd10ee7
Change useReducer to Redux
Jul 3, 2019
42b5c22
Extracted the App routes to a specialized component
Jul 3, 2019
8a70d55
organized the snackbar action to a component in component dir
Jul 3, 2019
aa918ba
reorganized the components
Jul 4, 2019
eb8608d
Share button in app bar
Jul 4, 2019
c92c205
fix invitation
Jul 4, 2019
09fbd6c
Emit event when user enter and left meeting
Jul 4, 2019
0a307e1
Add headset in user of RoomCard when connected
Jul 5, 2019
a548c7d
Fix AppBarRouter component's name
Jul 5, 2019
9aa4090
Add headset to users avatar when they're in meeting and only show inv…
Jul 5, 2019
2d28fc4
Add error 500 and 404 page
Jul 6, 2019
2f916d0
Add some tests to Morpheus
Jul 7, 2019
bc5249f
Add roomId to office route
Jul 7, 2019
e0e3bc6
Add more components tests
megatroom Jul 7, 2019
c217562
Add test to MenuUsers
Jul 7, 2019
6087d3d
Implemented Google autologin in Morpheus
Jul 9, 2019
5386c31
Only show notification if a user enter in current room
Jul 9, 2019
9be8657
Close socket client connection before opening again
Jul 9, 2019
1e31953
Add option in app bar to disable notification temporarily
Jul 9, 2019
1e4b208
Add permission validation for browser notification
Jul 10, 2019
b25c4ee
Removed the Jest and passed the Morpheus tests for Mocha
Jul 12, 2019
48bb2eb
Enable "react/forbid-prop-types" ESLint rule and add shape to all obj…
Jul 12, 2019
97251ab
Divide MenuUsers to MenuUsers and MenuUsersItem
Jul 12, 2019
10599f7
Transform logic to use early return in frontend/morpheus.js
Jul 12, 2019
a4ffc18
Create hooks dir to separate the useEvents and useSocket that were in…
Jul 12, 2019
6bc70c8
small fix on the function call
Jul 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ dist

# Generated random room config
file/matrix.room.web.json

# VSCode user settings
.vscode/
3 changes: 3 additions & 0 deletions .mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
require: ["@babel/register", "jsdom-global/register", "./test/setup.js"]
};
12 changes: 11 additions & 1 deletion backend/app.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ router.get("/new", (req, res) => {
temporary: true,
};

const found = req.app.locals.roomsDetail.find(element => element.id == req.query.roomId);
const found = req.app.locals.roomsDetail.find(
element => element.id == req.query.roomId,
);

if (!found) {
req.app.locals.roomsDetail.splice(1, 0, newRoom);
Expand All @@ -35,4 +37,12 @@ router.get("/office", (req, res) => {
res.render("office");
});

router.get("/rooms", (req, res) => {
res.json(req.app.locals.roomsDetail);
});

router.get("/morpheus*", (req, res) => {
res.render("morpheus");
});

module.exports = router;
5 changes: 3 additions & 2 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ module.exports = {
},
rules: {
quotes: ["error", "double"],
"react/jsx-filename-extension": [1, { "extensions": [".js"] }],
"react/jsx-filename-extension": [1, { extensions: [".js"] }],
"import/prefer-default-export": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
"react-hooks/exhaustive-deps": "warn",
"no-new": "off"
}
};
85 changes: 85 additions & 0 deletions frontend/components/AppBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from "react";
import PropTypes from "prop-types";
import clsx from "clsx";
import { makeStyles } from "@material-ui/core/styles";
import UIAppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";

import { drawerWidth } from "./Drawer";

const useStyles = makeStyles(theme => ({
root: {
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
colorDefault: {
backgroundColor: "#fff"
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginRight: theme.spacing(2)
},
title: {
flexGrow: 1
},
hide: {
display: "none"
}
}));

const AppBar = ({ isDrawerOpen, openDrawer, children }) => {
const classes = useStyles();

return (
<div className={classes.root}>
<UIAppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: isDrawerOpen
})}
classes={{
colorDefault: classes.colorDefault
}}
color="default"
>
<Toolbar>
<IconButton
edge="start"
className={clsx(classes.menuButton, isDrawerOpen && classes.hide)}
color="inherit"
aria-label="Menu"
onClick={openDrawer}
>
<MenuIcon />
</IconButton>
{children}
</Toolbar>
</UIAppBar>
</div>
);
};

AppBar.propTypes = {
isDrawerOpen: PropTypes.bool,
openDrawer: PropTypes.func,
children: PropTypes.node
};

AppBar.defaultProps = {
isDrawerOpen: false,
openDrawer: undefined,
children: undefined
};

export default AppBar;
30 changes: 30 additions & 0 deletions frontend/components/AppBarTitle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import PropTypes from "prop-types";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(() => ({
title: {
flexGrow: 1
}
}));

const AppBarTitle = ({ children }) => {
const classes = useStyles();

return (
<Typography variant="h6" className={classes.title} color="secondary">
{children}
</Typography>
);
};

AppBarTitle.propTypes = {
children: PropTypes.node
};

AppBarTitle.defaultProps = {
children: undefined
};

export default AppBarTitle;
63 changes: 63 additions & 0 deletions frontend/components/Drawer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import UIDrawer from "@material-ui/core/Drawer";
import Divider from "@material-ui/core/Divider";
import IconButton from "@material-ui/core/IconButton";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";

export const drawerWidth = 260;

export const drawerHeader = theme => ({
display: "flex",
alignItems: "center",
padding: "0 8px",
...theme.mixins.toolbar,
justifyContent: "flex-end"
});

const useStyles = makeStyles(theme => ({
root: {
width: drawerWidth,
flexShrink: 0
},
drawerPaper: {
width: drawerWidth
},
drawerHeader: drawerHeader(theme)
}));

const Drawer = ({ open, onClose, children }) => {
const classes = useStyles();
return (
<UIDrawer
className={classes.root}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={onClose}>
<ChevronLeftIcon />
</IconButton>
</div>
<Divider />
{children}
</UIDrawer>
);
};

Drawer.propTypes = {
open: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
children: PropTypes.node
};

Drawer.defaultProps = {
children: undefined
};

export default Drawer;
98 changes: 98 additions & 0 deletions frontend/components/EnterMeetingDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import Checkbox from "@material-ui/core/Checkbox";
import Mic from "@material-ui/icons/Mic";
import MicOff from "@material-ui/icons/MicOff";
import Videocam from "@material-ui/icons/Videocam";
import VideocamOff from "@material-ui/icons/VideocamOff";
import Tooltip from "@material-ui/core/Tooltip";

const useStyles = makeStyles(() => ({
toolbar: {
textAlign: "center",
minWidth: 260
},
sideMargin: {
marginRight: 8
}
}));

const EnterMeetingDialog = ({ open, onClose, onConfirm, title }) => {
const [micEnabled, setMicEnabled] = useState(true);
const [videoEnabled, setVideoEnabled] = useState(true);
const classes = useStyles();

return (
<Dialog open={open} onClose={onClose}>
<DialogTitle id="alert-dialog-title">{title}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Enter the Matrix with:
</DialogContentText>
<div className={classes.toolbar}>
<Tooltip title={`${micEnabled ? "Disable" : "Enable"} MIC`}>
<Checkbox
className={classes.sideMargin}
icon={<MicOff fontSize="large" />}
checkedIcon={<Mic fontSize="large" />}
checked={micEnabled}
onChange={event => {
setMicEnabled(event.target.checked);
}}
/>
</Tooltip>
<Tooltip title={`${videoEnabled ? "Disable" : "Enable"} Video`}>
<Checkbox
icon={<VideocamOff fontSize="large" />}
checkedIcon={<Videocam fontSize="large" />}
checked={videoEnabled}
onChange={event => {
setVideoEnabled(event.target.checked);
}}
/>
</Tooltip>
</div>
</DialogContent>
<DialogActions>
<Button onClick={onClose} color="primary">
Cancel
</Button>
<Button
onClick={() => {
onConfirm({
startWithAudioMuted: !micEnabled,
startWithVideoMuted: !videoEnabled
});
}}
color="primary"
autoFocus
>
Enter
</Button>
</DialogActions>
</Dialog>
);
};

EnterMeetingDialog.propTypes = {
title: PropTypes.string,
open: PropTypes.bool,
onClose: PropTypes.func,
onConfirm: PropTypes.func
};

EnterMeetingDialog.defaultProps = {
title: "",
open: false,
onClose: undefined,
onConfirm: undefined
};

export default EnterMeetingDialog;
59 changes: 59 additions & 0 deletions frontend/components/Error500.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import Fab from "@material-ui/core/Fab";

const useStyles = makeStyles(() => ({
root: {
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
background: "url('/images/matrix-code-animated.gif')",
backgroundSize: "cover",
backgroundRepeat: "no-repeat"
},
box: {
textAlign: "center"
},
imgTitle: {
width: 360,
marginBottom: 30
}
}));

const Error500 = ({ onReload }) => {
const classes = useStyles();

return (
<div className={classes.root}>
<div className={classes.box}>
<div>
<img
className={classes.imgTitle}
src="/images/systemfailure.jpeg"
alt="System Failure"
/>
</div>
<Fab
variant="extended"
color="secondary"
aria-label="Reload"
onClick={onReload}
>
Reload the Matrix
</Fab>
</div>
</div>
);
};

Error500.propTypes = {
onReload: PropTypes.func
};

Error500.defaultProps = {
onReload: () => {}
};

export default Error500;
Loading