diff options
Diffstat (limited to 'src/client/react/store')
-rw-r--r-- | src/client/react/store/actions.js | 54 | ||||
-rw-r--r-- | src/client/react/store/reducers.js | 1 | ||||
-rw-r--r-- | src/client/react/store/selectors.js | 30 |
3 files changed, 69 insertions, 16 deletions
diff --git a/src/client/react/store/actions.js b/src/client/react/store/actions.js index 2d2cd30..e7ef91d 100644 --- a/src/client/react/store/actions.js +++ b/src/client/react/store/actions.js @@ -1,19 +1,40 @@ +import { push } from 'connected-react-router'; +import queryString from 'query-string'; import users from '../users'; +import { selectUser, selectWeek, selectCurrentWeek } from './selectors'; import purifyWeek from '../lib/purifyWeek'; import withinRange from '../lib/withinRange'; -export function setUser(newUser) { - return (dispatch, getState, { getHistory }) => { - const { updatePathname } = getHistory(); +function updatePathname(pathname = '') { + return (dispatch, getState) => { + const query = getState().router.location.search; + dispatch(push(`/${pathname}${query}`)); + }; +} +function updateQuery(newQuery) { + return (dispatch, getState) => { + const { location } = getState().router; + const query = queryString.stringify({ + ...queryString.parse(location.search), + ...newQuery, + }); + + dispatch(push(`${location.pathname}?${query}`)); + }; +} + +export function setUser(newUser) { + return (dispatch) => { dispatch({ type: 'SEARCH/RESET' }); - updatePathname(newUser); + dispatch(updatePathname(newUser)); }; } export function shiftRoom(shift) { - return (dispatch, getState, { getHistory }) => { - const { user } = getHistory(); + return (dispatch, getState) => { + const state = getState(); + const user = selectUser(state); const { allRoomIds } = users; if (users.byId[user].type !== 'r') throw new Error('User must be a room'); @@ -31,27 +52,28 @@ export function shiftRoom(shift) { } export function setWeek(newWeek) { - return (dispatch, getState, { getHistory, moment }) => { - const { updateQuery } = getHistory(); + return (dispatch, getState) => { + const state = getState(); + const isCurrentWeek = selectCurrentWeek(state) === newWeek; - const isCurrentWeek = moment().week() === newWeek; - - updateQuery({ + dispatch(updateQuery({ week: isCurrentWeek ? undefined : newWeek, - }); + })); }; } export function shiftWeek(shift) { - return (dispatch, getState, { getHistory }) => { - const { week } = getHistory(); + return (dispatch, getState) => { + const state = getState(); + const week = selectWeek(state); dispatch(setWeek(purifyWeek(week + shift))); }; } export function showRoomFinder() { - return (dispatch, getState, { getHistory }) => { - const { user } = getHistory(); + return (dispatch, getState) => { + const state = getState(); + const user = selectUser(state); if (user == null || users.byId[user].type !== 'r') { // We are not currently viewing a room, correct the situation. diff --git a/src/client/react/store/reducers.js b/src/client/react/store/reducers.js index 4a3576d..cd68d96 100644 --- a/src/client/react/store/reducers.js +++ b/src/client/react/store/reducers.js @@ -22,6 +22,7 @@ import getSearchResults from '../lib/getSearchResults'; import withinRange from '../lib/withinRange'; const DEFAULT_STATE = { + timestamp: Date.now(), search: null, isRoomFinderVisible: false, schedules: {}, diff --git a/src/client/react/store/selectors.js b/src/client/react/store/selectors.js new file mode 100644 index 0000000..8264cdb --- /dev/null +++ b/src/client/react/store/selectors.js @@ -0,0 +1,30 @@ +import moment from 'moment'; +import queryString from 'query-string'; +import purifyWeek from '../lib/purifyWeek'; +import users from '../users'; + +export function selectUser(store) { + const { location } = store.router; + 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 selectCurrentWeek(store) { + return moment(store.now).week(); +} + +export function selectWeek(store) { + const { location } = store.router; + const weekStr = queryString.parse(location.search).week; + + if (!weekStr) { + return selectCurrentWeek(store); + } + + return purifyWeek(parseInt(weekStr, 10)); +} |