diff options
Diffstat (limited to 'web/src/js/ducks/utils/list.js')
-rw-r--r-- | web/src/js/ducks/utils/list.js | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js new file mode 100644 index 00000000..37b2ae3a --- /dev/null +++ b/web/src/js/ducks/utils/list.js @@ -0,0 +1,121 @@ +import {fetchApi} from "../../utils"; + +const ADD = "ADD" +const REQUEST_LIST = "REQUEST_LIST" +const RECEIVE_LIST = "RECEIVE_LIST" + + +const defaultState = { + list: [], + isFetching: false, + actionsDuringFetch: [], + byId: {}, + indexOf: {}, +}; + +export default function makeList(actionType, fetchURL) { + function reduceList(state = defaultState, action = {}) { + + if (action.type !== actionType) { + return state + } + + // Handle cases where we finished fetching or are still fetching. + if (action.cmd === RECEIVE_LIST) { + let s = { + isFetching: false, + actionsDuringFetch: [], + list: action.list, + byId: {}, + indexOf: {} + } + for (let i = 0; i < action.list.length; i++) { + let item = action.list[i] + s.byId[item.id] = item + s.indexOf[item.id] = i + } + for (action of state.actionsDuringFetch) { + s = reduceList(s, action) + } + return s + } else if (state.isFetching) { + return { + ...state, + actionsDuringFetch: [...state.actionsDuringFetch, action] + } + } + + switch (action.cmd) { + case ADD: + return { + list: [...state.list, action.item], + byId: {...state.byId, [action.item.id]: action.item}, + indexOf: {...state.indexOf, [action.item.id]: state.list.length}, + } + + case REQUEST_LIST: + return { + ...defaultState, + isFetching: true + } + + default: + console.debug("unknown action", action.type) + return state + } + } + + function addToList(item) { + return { + type: actionType, + cmd: ADD, + item + } + } + + + function updateList(action) { + /* This action creater takes all WebSocket events */ + return dispatch => { + switch (action.cmd) { + case "add": + return dispatch(addToList(action.data)) + case "reset": + return dispatch(fetchList()) + default: + console.error("unknown list update", action) + } + } + } + + function requestList() { + return { + type: actionType, + cmd: REQUEST_LIST, + } + } + + function receiveList(list) { + return { + type: actionType, + cmd: RECEIVE_LIST, + list + } + } + + function fetchList() { + return dispatch => { + + dispatch(requestList()) + + fetchApi(fetchURL).then(response => { + return response.json().then(json => { + dispatch(receiveList(json.data)) + }) + }) + } + } + + + return {reduceList, addToList, updateList, fetchList} +}
\ No newline at end of file |