diff options
-rw-r--r-- | .eslintrc | 3 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/client/react/App.js | 9 | ||||
-rw-r--r-- | src/client/react/components/container/Menu.js | 14 | ||||
-rw-r--r-- | src/client/react/components/presentational/Menu.js | 14 | ||||
-rw-r--r-- | src/client/react/index.js | 11 | ||||
-rw-r--r-- | src/client/react/lib/getHistory.js | 22 | ||||
-rw-r--r-- | src/client/react/lib/url.js | 10 | ||||
-rw-r--r-- | src/client/react/store/actions.js | 14 | ||||
-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
@@ -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 |