diff --git a/.eslintrc b/.eslintrc
index 4241933e..ea5baeef 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -27,7 +27,7 @@
"max-len": [1, 120, 4],
},
"plugins": [
- "react", "import"
+ "react", "jsx-a11y", "import"
],
"settings": {
"import/parser": "babel-eslint",
diff --git a/README.md b/README.md
index 971d5de1..80276d5c 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,8 @@ The p5.js Web Editor is built on a MERN stack - MongoDB, Express, React/Redux, a
This project does not use CSS Modules, but uses Sass. I like to follow [BEM rules](http://getbem.com/) for CSS naming conventions, write OOSCSS with placeholders and mixins, and follow the [7-1 Pattern](https://sass-guidelin.es/#the-7-1-pattern) for Sass.
+I'm using [ES6](http://es6-features.org/) and transpiling to ES5 using [Babel](https://babeljs.io/). For reference to the JavaScript style guide, see the [Airbnb Style Guide](https://github.com/airbnb/javascript), [React ESLint Plugin](https://github.com/yannickcr/eslint-plugin-react).
+
I'm new to using ESLint, but I decided on a configuration based on some popular React/Redux boilerplates. Open to suggestions on this. If in development, you're getting annoyed with ESLint, you can remove it from `webpack.config.dev.js` in the JavaScript loader, or disable any line from eslint by commenting at the end of the line `// eslint-disable-line`.
##Dump of links I'm saving for reference
diff --git a/client/components/Nav.js b/client/components/Nav.js
index 3fa29e7f..1485e041 100644
--- a/client/components/Nav.js
+++ b/client/components/Nav.js
@@ -59,24 +59,25 @@ function Nav(props) {
return (
-
+
Open
);
}
- if (!props.user.authenticated) {
- return (
-
-
-
- Open
-
-
-
- );
- }
+ return (
+
+
+
+ Open
+
+
+
+ );
})()}
@@ -87,10 +88,34 @@ function Nav(props) {
);
@@ -107,7 +132,9 @@ Nav.propTypes = {
}).isRequired,
project: PropTypes.shape({
id: PropTypes.string
- })
+ }),
+ logoutUser: PropTypes.func.isRequired,
+ stopSketch: PropTypes.func.isRequired
};
export default Nav;
diff --git a/client/images/file.svg b/client/images/file.svg
new file mode 100644
index 00000000..aa19bd0c
--- /dev/null
+++ b/client/images/file.svg
@@ -0,0 +1,14 @@
+
+
+
+ "K" file icon Copy
+ Created with Sketch.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/modules/IDE/components/EditorAccessibility.js b/client/modules/IDE/components/EditorAccessibility.js
index e98b4605..dbab82ad 100644
--- a/client/modules/IDE/components/EditorAccessibility.js
+++ b/client/modules/IDE/components/EditorAccessibility.js
@@ -7,18 +7,18 @@ class EditorAccessibility extends React.Component {
render() {
let messages = [];
if (this.props.lintMessages.length > 0) {
- for (let i = 0; i < this.props.lintMessages.length; i++) {
+ this.props.lintMessages.forEach((lintMessage, i) => {
messages.push(
-
- {this.props.lintMessages[i].severity} in line
- {this.props.lintMessages[i].line} :
- {this.props.lintMessages[i].message}
+
+ {lintMessage.severity} in line
+ {lintMessage.line} :
+ {lintMessage.message}
);
- }
+ });
} else {
messages.push(
- There are no lint messages
+ There are no lint messages
);
}
return (
diff --git a/client/modules/IDE/pages/IDEView.js b/client/modules/IDE/pages/IDEView.js
index d02a0cd5..b90224bb 100644
--- a/client/modules/IDE/pages/IDEView.js
+++ b/client/modules/IDE/pages/IDEView.js
@@ -15,6 +15,7 @@ import * as IDEActions from '../actions/ide';
import * as ProjectActions from '../actions/project';
import * as EditorAccessibilityActions from '../actions/editorAccessibility';
import * as PreferencesActions from '../actions/preferences';
+import * as UserActions from '../../User/actions';
import { getFile, getHTMLFile, getJSFiles, getCSSFiles, setSelectedFile } from '../reducers/files';
import SplitPane from 'react-split-pane';
import Overlay from '../../App/components/Overlay';
@@ -30,6 +31,7 @@ class IDEView extends React.Component {
}
componentDidMount() {
+ this.props.stopSketch();
if (this.props.params.project_id) {
const id = this.props.params.project_id;
this.props.getProject(id);
@@ -117,6 +119,8 @@ class IDEView extends React.Component {
exportProjectAsZip={this.props.exportProjectAsZip}
cloneProject={this.props.cloneProject}
project={this.props.project}
+ logoutUser={this.props.logoutUser}
+ stopSketch={this.props.stopSketch}
/>
{
+ axios.get(`${ROOT_URL}/logout`, { withCredentials: true })
+ .then(() => {
+ dispatch({
+ type: ActionTypes.UNAUTH_USER
+ });
+ })
+ .catch(response => dispatch(authError(response.data.error)));
+ };
+}
+
diff --git a/client/modules/User/reducers.js b/client/modules/User/reducers.js
index db3dac3e..c2f3f8ab 100644
--- a/client/modules/User/reducers.js
+++ b/client/modules/User/reducers.js
@@ -5,6 +5,10 @@ const user = (state = { authenticated: false }, action) => {
case ActionTypes.AUTH_USER:
return { ...action.user,
authenticated: true };
+ case ActionTypes.UNAUTH_USER:
+ return {
+ authenticated: false
+ };
case ActionTypes.AUTH_ERROR:
return {
authenticated: false
diff --git a/client/styles/base/_base.scss b/client/styles/base/_base.scss
index 29568ba3..dbf361c6 100644
--- a/client/styles/base/_base.scss
+++ b/client/styles/base/_base.scss
@@ -11,6 +11,10 @@ body, input, button {
color: $light-primary-text-color;
}
+body {
+ background-color: $light-background-color;
+}
+
.root-app, .app {
min-height: 100%;
height: 100%;
diff --git a/client/styles/components/_console.scss b/client/styles/components/_console.scss
index e1fd9658..d96dfd4c 100644
--- a/client/styles/components/_console.scss
+++ b/client/styles/components/_console.scss
@@ -4,6 +4,8 @@
background: $console-light-background-color;
z-index: 1000;
overflow: hidden;
+ display: flex;
+ flex-direction: column;
& > {
position:relative;
@@ -13,14 +15,17 @@
// assign styles to different types of console messages
.preview-console__log {
color: $dark-secondary-text-color;
+ flex: 1 0 auto;
}
.preview-console__error {
color: $console-error-color;
+ flex: 1 0 auto;
}
.preview-console__warn {
color: $console-warn-color;
+ flex: 1 0 auto;
}
}
@@ -41,7 +46,7 @@
display: flex;
flex-direction: column;
overflow-y: auto;
- height: #{121 / $base-font-size}rem;
+ flex: 1 0 0%;
}
diff --git a/client/styles/components/_nav.scss b/client/styles/components/_nav.scss
index 64867783..940f6af0 100644
--- a/client/styles/components/_nav.scss
+++ b/client/styles/components/_nav.scss
@@ -1,6 +1,6 @@
.nav {
width: 100%;
- padding: #{10 / $base-font-size}rem #{40 / $base-font-size}rem;
+ padding: #{10 / $base-font-size}rem #{70 / $base-font-size}rem;
padding-left: #{170 / $base-font-size}rem;
display: flex;
flex-direction: row;
@@ -24,4 +24,22 @@
& + & {
margin-left: #{20 / $base-font-size}rem;
}
+ position: relative;
+ &:hover .nav__dropdown {
+ display: flex;
+ }
+}
+
+.nav__dropdown {
+ display: none;
+ position: absolute;
+ flex-direction: column;
+ background-color: $light-background-color;
+ padding: #{10 / $base-font-size}rem;
+ left: #{-10 / $base-font-size}rem;
+ border: 1px solid $ide-border-color;
+ & li + li {
+ margin-top: #{10 / $base-font-size}rem;
+ }
+ width: #{140 / $base-font-size}rem;
}
\ No newline at end of file
diff --git a/server/controllers/session.controller.js b/server/controllers/session.controller.js
index cbee93f4..77a9e20c 100644
--- a/server/controllers/session.controller.js
+++ b/server/controllers/session.controller.js
@@ -30,3 +30,9 @@ export function getSession(req, res) {
}
return res.status(404).send({ message: 'Session does not exist' });
}
+
+export function destroySession(req, res) {
+ req.logout();
+ res.json({success: true});
+}
+
diff --git a/server/routes/session.routes.js b/server/routes/session.routes.js
index b0305d70..8b68cefd 100644
--- a/server/routes/session.routes.js
+++ b/server/routes/session.routes.js
@@ -7,6 +7,8 @@ router.route('/login').post(SessionController.createSession);
router.route('/session').get(SessionController.getSession);
+router.route('/logout').get(SessionController.destroySession);
+
export default router;
// TODO add github authentication stuff