aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Loomans <noahloomans@gmail.com>2018-06-28 13:45:27 +0200
committerNoah Loomans <noahloomans@gmail.com>2018-06-28 13:45:27 +0200
commit9efc432e160b429a0643c38e28140bcf42af30a7 (patch)
tree2ff1722ed690dc673c8a83cbbf03b40b6526d9f3
parent9e55c4b1a151b434cba4b4425514c3aeac6f22d8 (diff)
Add history to redux thunk
-rw-r--r--.eslintrc3
-rw-r--r--package.json1
-rw-r--r--src/client/react/App.js9
-rw-r--r--src/client/react/components/container/Menu.js14
-rw-r--r--src/client/react/components/presentational/Menu.js14
-rw-r--r--src/client/react/index.js11
-rw-r--r--src/client/react/lib/getHistory.js22
-rw-r--r--src/client/react/lib/url.js10
-rw-r--r--src/client/react/store/actions.js14
-rw-r--r--src/client/react/store/reducers.js (renamed from src/client/react/reducers.js)4
-rw-r--r--src/client/react/store/reducers.test.js (renamed from src/client/react/reducers.test.js)0
11 files changed, 69 insertions, 33 deletions
diff --git a/.eslintrc b/.eslintrc
index 06eeac5..dab636c 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -11,6 +11,7 @@
"no-underscore-dangle": ["error", { "allow": ["_test", "__REDUX_DEVTOOLS_EXTENSION_COMPOSE__"] }],
"no-prototype-builtins": "off",
"react/forbid-prop-types": "off",
- "react/prefer-stateless-function": "off"
+ "react/prefer-stateless-function": "off",
+ "import/prefer-default-export": "off"
}
}
diff --git a/package.json b/package.json
index 81a86da..403d038 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
"express": "^4.16.3",
"express-handlebars": "^3.0.0",
"fuzzy-search": "^2.0.1",
+ "history": "^4.7.2",
"iconv-lite": "^0.4.17",
"jsdom": "^11.6.2",
"left-pad": "^1.1.1",
diff --git a/src/client/react/App.js b/src/client/react/App.js
index e9ff565..a5a5cbd 100644
--- a/src/client/react/App.js
+++ b/src/client/react/App.js
@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import {
- BrowserRouter,
+ Router,
Route,
Switch,
Redirect,
@@ -16,20 +16,21 @@ import User from './components/page/User';
export default class App extends React.Component {
static propTypes = {
store: PropTypes.object.isRequired,
+ history: PropTypes.object.isRequired,
}
render() {
- const { store } = this.props;
+ const { store, history } = this.props;
return (
<Provider store={store}>
- <BrowserRouter>
+ <Router history={history}>
<Switch>
<Route exact path="/" component={Index} />
<Route path="/:type/:value" component={User} />
<Redirect to="/" />
</Switch>
- </BrowserRouter>
+ </Router>
</Provider>
);
}
diff --git a/src/client/react/components/container/Menu.js b/src/client/react/components/container/Menu.js
index 0e81fde..c9e6ba3 100644
--- a/src/client/react/components/container/Menu.js
+++ b/src/client/react/components/container/Menu.js
@@ -19,18 +19,12 @@
*/
import { connect } from 'react-redux';
-import { withRouter } from 'react-router-dom';
-import { makeSetUser, userFromMatch } from '../../lib/url';
+import { showRoomFinder } from '../../store/actions';
import Menu from '../presentational/Menu';
-const mapStateToProps = (state, { match }) => ({
- user: userFromMatch(match),
+const mapDispatchToProps = dispatch => ({
+ showRoomFinder: () => dispatch(showRoomFinder()),
});
-const mapDispatchToProps = (dispatch, { history }) => ({
- setUser: makeSetUser(history),
- showRoomFinder: () => dispatch({ type: 'ROOM_FINDER/SHOW' }),
-});
-
-export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Menu));
+export default connect(null, mapDispatchToProps)(Menu);
diff --git a/src/client/react/components/presentational/Menu.js b/src/client/react/components/presentational/Menu.js
index d43c1d3..077a2e4 100644
--- a/src/client/react/components/presentational/Menu.js
+++ b/src/client/react/components/presentational/Menu.js
@@ -23,30 +23,18 @@ import { PropTypes } from 'prop-types';
import { Button, ButtonIcon } from 'rmwc/Button';
import { SimpleMenu, MenuItem } from 'rmwc/Menu';
import { Icon } from 'rmwc/Icon';
-import users from '../../users';
import './Menu.scss';
class Menu extends React.Component {
static propTypes = {
- user: PropTypes.string,
- setUser: PropTypes.func.isRequired,
showRoomFinder: PropTypes.func.isRequired,
}
- static defaultProps = {
- user: null,
- }
-
onItemSelected(index) {
switch (index) {
case 'room_finder': {
- const { setUser, user, showRoomFinder } = this.props;
-
- if (user == null || users.byId[user].type !== 'r') {
- // We are not currently viewing a room, correct the situation.
- setUser(users.allRoomIds[0]);
- }
+ const { showRoomFinder } = this.props;
showRoomFinder();
break;
diff --git a/src/client/react/index.js b/src/client/react/index.js
index 650e6de..2e35594 100644
--- a/src/client/react/index.js
+++ b/src/client/react/index.js
@@ -27,7 +27,10 @@ import { createStore, applyMiddleware, compose as reduxCompose } from 'redux';
import thunk from 'redux-thunk';
import moment from 'moment';
-import reducer from './reducers';
+import createHistory from 'history/createBrowserHistory';
+
+import makeGetHistory from './lib/getHistory';
+import reducer from './store/reducers';
import App from './App';
import './index.scss';
@@ -35,6 +38,8 @@ import './index.scss';
// number logic is used.
moment.locale('nl');
+const history = createHistory();
+
const compose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || reduxCompose;
const store = createStore(
@@ -42,12 +47,12 @@ const store = createStore(
// Redux devtools extension
// https://github.com/zalmoxisus/redux-devtools-extension
compose(
- applyMiddleware(thunk),
+ applyMiddleware(thunk.withExtraArgument(makeGetHistory(history))),
),
);
ReactDOM.render(
- <App store={store} />,
+ <App store={store} history={history} />,
document.querySelector('#root'),
);
diff --git a/src/client/react/lib/getHistory.js b/src/client/react/lib/getHistory.js
new file mode 100644
index 0000000..642a9a8
--- /dev/null
+++ b/src/client/react/lib/getHistory.js
@@ -0,0 +1,22 @@
+import {
+ makeSetUser,
+ makeSetWeek,
+ weekFromLocation,
+ userFromLocation,
+} from './url';
+
+export default function makeGetHistory(history) {
+ return function getHistory() {
+ const user = userFromLocation(history.location);
+ const week = weekFromLocation(history.location);
+ const setUser = makeSetUser(history);
+ const setWeek = makeSetWeek(history);
+
+ return {
+ user,
+ week,
+ setUser,
+ setWeek,
+ };
+ };
+}
diff --git a/src/client/react/lib/url.js b/src/client/react/lib/url.js
index 644fd74..fcd3e6a 100644
--- a/src/client/react/lib/url.js
+++ b/src/client/react/lib/url.js
@@ -33,6 +33,16 @@ export function userFromMatch(match) {
return user;
}
+export function userFromLocation(location) {
+ const match = location.pathname.match(/^\/([stcr])\/([-0-9a-zA-Z]+)/);
+ if (!match) return null;
+
+ const user = `${match[1]}/${match[2]}`;
+ if (!users.allIds.includes(user)) return null;
+
+ return user;
+}
+
export function weekFromLocation(location) {
const weekStr = queryString.parse(location.search).week;
diff --git a/src/client/react/store/actions.js b/src/client/react/store/actions.js
new file mode 100644
index 0000000..c4cc9ba
--- /dev/null
+++ b/src/client/react/store/actions.js
@@ -0,0 +1,14 @@
+import users from '../users';
+
+export function showRoomFinder() {
+ return (dispatch, getState, getHistory) => {
+ const { user, setUser } = getHistory();
+
+ if (user == null || users.byId[user].type !== 'r') {
+ // We are not currently viewing a room, correct the situation.
+ setUser(users.allRoomIds[0]);
+ }
+
+ dispatch({ type: 'ROOM_FINDER/SHOW' });
+ };
+}
diff --git a/src/client/react/reducers.js b/src/client/react/store/reducers.js
index 37d26f2..c2ee7e9 100644
--- a/src/client/react/reducers.js
+++ b/src/client/react/store/reducers.js
@@ -18,8 +18,8 @@
*
*/
-import getSearchResults from './lib/getSearchResults';
-import users from './users';
+import getSearchResults from '../lib/getSearchResults';
+import users from '../users';
const DEFAULT_STATE = {
// results: [
diff --git a/src/client/react/reducers.test.js b/src/client/react/store/reducers.test.js
index cd195b0..cd195b0 100644
--- a/src/client/react/reducers.test.js
+++ b/src/client/react/store/reducers.test.js