From b02d66491c210d8be36ed670fc83c1f2032b7297 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 4 Jun 2016 00:37:10 -0700 Subject: web: implement update and remove for list and view --- web/src/js/ducks/eventLog.js | 8 ++++-- web/src/js/ducks/utils/list.js | 62 ++++++++++++++++++++++++++++++++++++------ web/src/js/ducks/utils/view.js | 45 ++++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 20 deletions(-) (limited to 'web/src/js') diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 00b25bcf..e3661fe7 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -7,9 +7,9 @@ export const UPDATE_LOG = "UPDATE_EVENTLOG" const { reduceList, - addToList, updateList, fetchList, + addItem, } = makeList(UPDATE_LOG, "/events") @@ -51,7 +51,9 @@ export default function reducer(state = defaultState, action) { events, filteredEvents: updateViewList( state.filteredEvents, - events, action, + state.events, + events, + action, x => state.filter[x.level] ) } @@ -69,7 +71,7 @@ export function toggleEventLogVisibility() { } let id = 0 export function addLogEntry(message, level = "web") { - return addToList({ + return addItem({ message, level, id: `log-${id++}` diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js index b750982e..e5ce75ef 100644 --- a/web/src/js/ducks/utils/list.js +++ b/web/src/js/ducks/utils/list.js @@ -1,6 +1,8 @@ -import {fetchApi} from "../../utils"; +import {fetchApi} from "../../utils" export const ADD = "ADD" +export const UPDATE = "UPDATE" +export const REMOVE = "REMOVE" export const REQUEST_LIST = "REQUEST_LIST" export const RECEIVE_LIST = "RECEIVE_LIST" @@ -11,7 +13,7 @@ const defaultState = { actionsDuringFetch: [], byId: {}, indexOf: {}, -}; +} export default function makeList(actionType, fetchURL) { function reduceList(state = defaultState, action = {}) { @@ -45,6 +47,7 @@ export default function makeList(actionType, fetchURL) { } } + let list, itemIndex switch (action.cmd) { case ADD: return { @@ -53,6 +56,27 @@ export default function makeList(actionType, fetchURL) { indexOf: {...state.indexOf, [action.item.id]: state.list.length}, } + case UPDATE: + + list = [...state.list] + itemIndex = state.indexOf[action.item.id] + list[itemIndex] = action.item + return { + ...defaultState, + list + } + + case REMOVE: + list = [...state.list] + itemIndex = state.indexOf[action.item.id] + list.splice(itemIndex, 1) + return { + ...defaultState, + list, + byId: {...state.byId, [action.item.id]: undefined}, + indexOf: {...state.indexOf, [action.item.id]: undefined}, + } + case REQUEST_LIST: return { ...defaultState, @@ -60,12 +84,12 @@ export default function makeList(actionType, fetchURL) { } default: - console.debug("unknown action", action.type) + console.debug("unknown action", action) return state } } - function addToList(item) { + function addItem(item) { return { type: actionType, cmd: ADD, @@ -73,17 +97,37 @@ export default function makeList(actionType, fetchURL) { } } + function updateItem(item) { + return { + type: actionType, + cmd: UPDATE, + item + } + } + + function removeItem(item) { + return { + type: actionType, + cmd: REMOVE, + item + } + } + - function updateList(action) { + function updateList(event) { /* This action creater takes all WebSocket events */ return dispatch => { - switch (action.cmd) { + switch (event.cmd) { case "add": - return dispatch(addToList(action.data)) + return dispatch(addItem(event.data)) + case "update": + return dispatch(updateItem(event.data)) + case "remove": + return dispatch(removeItem(event.data)) case "reset": return dispatch(fetchList()) default: - console.error("unknown list update", action) + console.error("unknown list update", event) } } } @@ -117,5 +161,5 @@ export default function makeList(actionType, fetchURL) { } - return {reduceList, addToList, updateList, fetchList} + return {reduceList, updateList, fetchList, addItem, updateItem, removeItem,} } \ No newline at end of file diff --git a/web/src/js/ducks/utils/view.js b/web/src/js/ducks/utils/view.js index 4b265f89..55fdf6c7 100644 --- a/web/src/js/ducks/utils/view.js +++ b/web/src/js/ducks/utils/view.js @@ -1,4 +1,4 @@ -import {ADD, REQUEST_LIST, RECEIVE_LIST} from "./list" +import {ADD, UPDATE, REMOVE, REQUEST_LIST, RECEIVE_LIST} from "./list" const defaultFilterFn = x => true const defaultSortFn = false @@ -6,13 +6,13 @@ const defaultSortFn = false const makeCompareFn = sortFn => { let compareFn = (a, b) => { let akey = sortFn(a), - bkey = sortFn(b); + bkey = sortFn(b) if (akey < bkey) { - return -1; + return -1 } else if (akey > bkey) { - return 1; + return 1 } else { - return 0; + return 0 } } if (sortFn.reverse) @@ -33,19 +33,48 @@ const sortedInsert = (list, sortFn, item) => { return l } +const sortedRemove = (list, sortFn, item) => { + let itemId = item.id + return list.filter(x => x.id !== itemId) +} + // for when the list changes -export function updateViewList(state, nextList, action, filterFn = defaultFilterFn, sortFn = defaultSortFn) { +export function updateViewList(state, currentList, nextList, action, filterFn = defaultFilterFn, sortFn = defaultSortFn) { switch (action.cmd) { case REQUEST_LIST: return state case RECEIVE_LIST: return updateViewFilter(nextList.list, filterFn, sortFn) case ADD: - if (filterFn(action.item)) + if (filterFn(action.item)) { + return sortedInsert(state, sortFn, action.item) + } + return state + case UPDATE: + // let's determine if it's in the view currently and if it should be in the view. + let currentItemState = currentList.byId[action.item.id], + nextItemState = action.item, + isInView = filterFn(currentItemState), + shouldBeInView = filterFn(nextItemState) + + if (!isInView && shouldBeInView) return sortedInsert(state, sortFn, action.item) + if (isInView && !shouldBeInView) + return sortedRemove(state, sortFn, action.item) + if (isInView && shouldBeInView && sortFn(currentItemState) !== sortFn(nextItemState)) { + let s = [...state] + s.sort(sortFn) + return s + } + return state + case REMOVE: + let isInView_ = filterFn(currentList.byId[action.item.id]) + if (isInView_) { + return sortedRemove(state, sortFn, action.item) + } return state default: - console.error("Unknown list action: ", action); + console.error("Unknown list action: ", action) return state } } -- cgit v1.2.3