diff --git a/package.json b/package.json
index cd65a38e..0b9b0613 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"babel-preset-react-hmre": "^1.0.1",
"babel-preset-stage-0": "^6.5.0",
"body-parser": "^1.15.0",
+ "classnames": "^2.2.3",
"codemirror": "^5.11.0",
"cross-env": "^1.0.7",
"css-loader": "^0.23.1",
@@ -56,8 +57,11 @@
"react-redux": "^4.4.0",
"react-router": "^2.0.0",
"redux": "^3.3.1",
+ "redux-storage": "^3.0.0",
+ "redux-storage-engine-localstorage": "^1.0.0",
"sass-loader": "^3.1.2",
"style-loader": "^0.13.0",
+ "sw-toolbox": "^3.1.1",
"to-markdown": "^2.0.1",
"webpack": "^1.12.12",
"webpack-dev-middleware": "^1.5.1",
diff --git a/src/Actions/index.js b/src/Actions/index.js
index 8b063477..5239e403 100644
--- a/src/Actions/index.js
+++ b/src/Actions/index.js
@@ -6,6 +6,7 @@ import keyMirror from 'fbjs/lib/keyMirror';
export const UPDATE_TEXT = 'UPDATE_TEXT';
export const TOGGLE_EDITORS = 'TOGGLE_EDITORS';
+export const TOGGLE_HISTORY_SIDEBAR = 'TOGGLE_HISTORY_SIDEBAR';
/*
* Other Constants
@@ -27,3 +28,7 @@ export function updateText(text, editor) {
export function toggleEditors(toggledEditor) {
return { type: TOGGLE_EDITORS, toggledEditor };
}
+
+export function toggleHistorySidebar() {
+ return { type: TOGGLE_HISTORY_SIDEBAR };
+}
diff --git a/src/Components/Header/Header.js b/src/Components/Header/Header.js
index 040aba12..c39821bf 100644
--- a/src/Components/Header/Header.js
+++ b/src/Components/Header/Header.js
@@ -1,12 +1,14 @@
import React from 'react';
import styles from './Header.scss';
+import classNames from 'classnames/bind';
+const cx = classNames.bind(styles);
-const Header = ({ activeEditors, toggleEditors }) => {
+const Header = ({ activeEditors, toggleEditors, showHistorySidebar, toggleHistorySidebar }) => {
return (
Beautiful Atlas
-
+
{
className={ activeEditors.includes('TEXT') ? styles.active : '' }
>Text
-
Versions
+
+ History
+
);
};
+Header.propTypes = {
+ showHistorySidebar: React.PropTypes.bool.isRequired,
+ toggleHistorySidebar: React.PropTypes.func.isRequired,
+}
+
export default Header;
diff --git a/src/Components/Header/Header.scss b/src/Components/Header/Header.scss
index 157d54a3..9b9616ea 100644
--- a/src/Components/Header/Header.scss
+++ b/src/Components/Header/Header.scss
@@ -40,6 +40,13 @@
}
}
+ .sidebar {
+ span {
+ margin-right: 12px;
+ cursor: pointer;
+ }
+ }
+
.active {
text-decoration: underline;
text-decoration-color: #fff;
diff --git a/src/Components/HistorySidebar/HistorySidebar.js b/src/Components/HistorySidebar/HistorySidebar.js
new file mode 100644
index 00000000..315fcdda
--- /dev/null
+++ b/src/Components/HistorySidebar/HistorySidebar.js
@@ -0,0 +1,17 @@
+import React from 'react';
+
+import styles from './HistorySidebar.scss';
+
+class HistorySidebar extends React.Component {
+ render() {
+ return (
+
+ );
+ }
+};
+
+export default HistorySidebar;
diff --git a/src/Components/HistorySidebar/HistorySidebar.scss b/src/Components/HistorySidebar/HistorySidebar.scss
new file mode 100644
index 00000000..fcdce15c
--- /dev/null
+++ b/src/Components/HistorySidebar/HistorySidebar.scss
@@ -0,0 +1,12 @@
+.container {
+ width: 200px;
+
+ background-color: #FBFBFB;
+ border-left: 1px solid #f0f0f0;
+
+ font-size: 12px;
+}
+
+.header {
+ padding: 20px 10px;
+}
\ No newline at end of file
diff --git a/src/Components/HistorySidebar/index.js b/src/Components/HistorySidebar/index.js
new file mode 100644
index 00000000..c4a6466c
--- /dev/null
+++ b/src/Components/HistorySidebar/index.js
@@ -0,0 +1,2 @@
+import HistorySidebar from './HistorySidebar';
+export default HistorySidebar;
diff --git a/src/Reducers/index.js b/src/Reducers/index.js
index 77be62db..9b74a476 100644
--- a/src/Reducers/index.js
+++ b/src/Reducers/index.js
@@ -4,10 +4,11 @@ import { combineReducers } from 'redux';
import {
UPDATE_TEXT,
TOGGLE_EDITORS,
+ TOGGLE_HISTORY_SIDEBAR,
ActiveEditors,
} from '../Actions';
-function activeEditors(state = [ActiveEditors.MARKDOWN, ActiveEditors.TEXT], action) {
+const activeEditors = (state = [ActiveEditors.MARKDOWN, ActiveEditors.TEXT], action) => {
switch (action.type) {
case TOGGLE_EDITORS: {
const newState = _.xor(state, [action.toggledEditor]);
@@ -22,7 +23,20 @@ function activeEditors(state = [ActiveEditors.MARKDOWN, ActiveEditors.TEXT], act
}
}
-function text(state = '', action) {
+const historySidebar = (state = { visible: false }, action) => {
+ switch (action.type) {
+ case TOGGLE_HISTORY_SIDEBAR: {
+ return {
+ ...state,
+ visible: !state.visible,
+ };
+ }
+ default:
+ return state;
+ }
+}
+
+const text = (state = '', action) => {
switch (action.type) {
case UPDATE_TEXT:
return action.text;
@@ -31,9 +45,8 @@ function text(state = '', action) {
}
}
-const application = combineReducers({
+export default combineReducers({
activeEditors,
+ historySidebar,
text,
});
-
-export default application;
diff --git a/src/Views/App/App.js b/src/Views/App/App.js
index 76a67630..c87b275d 100644
--- a/src/Views/App/App.js
+++ b/src/Views/App/App.js
@@ -4,7 +4,10 @@ import { connect } from 'react-redux';
import 'normalize.css/normalize.css';
import styles from './App.scss';
-import { toggleEditors } from '../../Actions';
+import {
+ toggleEditors,
+ toggleHistorySidebar,
+ } from '../../Actions';
import Header from '../../Components/Header';
@@ -13,17 +16,18 @@ import Auth from '../../Utils/Auth';
class App extends Component {
static propTypes = {
children: React.PropTypes.element,
- activeEditors: React.PropTypes.isRequired,
+ activeEditors: React.PropTypes.array.isRequired,
toggleEditors: React.PropTypes.func.isRequired,
+ showHistorySidebar: React.PropTypes.bool.isRequired,
+ toggleHistorySidebar: React.PropTypes.func.isRequired,
}
- static defaultProps = {}
-
state = {
loggedIn: Auth.loggedIn(),
}
componentWillMount = () => {
+ console.log(this.props);
Auth.onChange = this.updateAuth;
}
@@ -44,6 +48,8 @@ class App extends Component {
{ this.props.children }
@@ -56,6 +62,7 @@ class App extends Component {
const mapStateToProps = (state) => {
return {
activeEditors: state.activeEditors,
+ showHistorySidebar: state.historySidebar.visible,
};
};
@@ -64,6 +71,9 @@ const mapDispatchToProps = (dispatch) => {
toggleEditors: (toggledEditor) => {
dispatch(toggleEditors(toggledEditor));
},
+ toggleHistorySidebar: () => {
+ dispatch(toggleHistorySidebar());
+ }
};
};
diff --git a/src/Views/Dashboard/Dashboard.js b/src/Views/Dashboard/Dashboard.js
index 0f92efc8..8ba970a1 100644
--- a/src/Views/Dashboard/Dashboard.js
+++ b/src/Views/Dashboard/Dashboard.js
@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import MarkdownEditor from '../../Components/MarkdownEditor';
import TextEditor from '../../Components/TextEditor';
+import HistorySidebar from '../../Components/HistorySidebar';
import { toMarkdown } from '../../Utils/Markdown';
import { updateText } from '../../Actions';
@@ -14,7 +15,8 @@ class Dashboard extends Component {
editMarkdown: React.PropTypes.func.isRequired,
editText: React.PropTypes.func.isRequired,
text: React.PropTypes.string,
- activeEditors: React.PropTypes.array,
+ activeEditors: React.PropTypes.arrayOf(React.PropTypes.string),
+ showHistorySidebar: React.PropTypes.bool.isRequired,
}
// componentDidMount = () => {
@@ -25,6 +27,7 @@ class Dashboard extends Component {
// }
render() {
+ console.log(this.props.showHistorySidebar);
const activeEditors = this.props.activeEditors;
return (
@@ -47,6 +50,13 @@ class Dashboard extends Component {
) : null
}
+ {
+ this.props.showHistorySidebar ?
+
+
+
+ : null
+ }
);
}
@@ -57,6 +67,7 @@ const mapStateToProps = (state) => {
text: state.text,
editor: state.editor,
activeEditors: state.activeEditors,
+ showHistorySidebar: state.historySidebar.visible,
};
};
diff --git a/src/index.js b/src/index.js
index 1d248aad..c324c4d1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,7 +2,9 @@ import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route } from 'react-router';
-import { createStore, compose } from 'redux';
+import { createStore, applyMiddleware, compose } from 'redux';
+import * as storage from 'redux-storage';
+import createEngine from 'redux-storage-engine-localstorage';
import History from './Utils/History';
import Auth from './Utils/Auth';
@@ -13,12 +15,17 @@ import App from './Views/App';
import Login from './Views/Login';
import Dashboard from './Views/Dashboard';
-const store = createStore(
- reducers,
- compose(
- window.devToolsExtension ? window.devToolsExtension() : f => f
- )
-);
+const reducer = storage.reducer(reducers);
+const engine = createEngine('atlas-store');
+const storageMiddleware = storage.createMiddleware(engine);
+
+const createStoreWithMiddleware = applyMiddleware(storageMiddleware)(createStore);
+const store = createStoreWithMiddleware(reducer);
+
+const load = storage.createLoader(engine);
+load(store)
+ .then((newState) => console.log('Loaded state:', newState))
+ .catch(() => console.log('Failed to load previous state'));
function requireAuth(nextState, replace) {
if (!Auth.loggedIn()) {