diff options
Diffstat (limited to 'app/javascript/flavours/glitch/reducers/contexts.js')
-rw-r--r-- | app/javascript/flavours/glitch/reducers/contexts.js | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/reducers/contexts.js b/app/javascript/flavours/glitch/reducers/contexts.js new file mode 100644 index 000000000..effd70756 --- /dev/null +++ b/app/javascript/flavours/glitch/reducers/contexts.js @@ -0,0 +1,80 @@ +import { + ACCOUNT_BLOCK_SUCCESS, + ACCOUNT_MUTE_SUCCESS, +} from 'flavours/glitch/actions/accounts'; +import { CONTEXT_FETCH_SUCCESS } from 'flavours/glitch/actions/statuses'; +import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from 'flavours/glitch/actions/timelines'; +import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; + +const initialState = ImmutableMap({ + ancestors: ImmutableMap(), + descendants: ImmutableMap(), +}); + +const normalizeContext = (state, id, ancestors, descendants) => { + const ancestorsIds = ImmutableList(ancestors.map(ancestor => ancestor.id)); + const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id)); + + return state.withMutations(map => { + map.setIn(['ancestors', id], ancestorsIds); + map.setIn(['descendants', id], descendantsIds); + }); +}; + +const deleteFromContexts = (immutableState, ids) => immutableState.withMutations(state => { + state.update('ancestors', immutableAncestors => immutableAncestors.withMutations(ancestors => { + state.update('descendants', immutableDescendants => immutableDescendants.withMutations(descendants => { + ids.forEach(id => { + descendants.get(id, ImmutableList()).forEach(descendantId => { + ancestors.update(descendantId, ImmutableList(), list => list.filterNot(itemId => itemId === id)); + }); + + ancestors.get(id, ImmutableList()).forEach(ancestorId => { + descendants.update(ancestorId, ImmutableList(), list => list.filterNot(itemId => itemId === id)); + }); + + descendants.delete(id); + ancestors.delete(id); + }); + })); + })); +}); + +const filterContexts = (state, relationship, statuses) => { + const ownedStatusIds = statuses.filter(status => status.get('account') === relationship.id) + .map(status => status.get('id')); + + return deleteFromContexts(state, ownedStatusIds); +}; + +const updateContext = (state, status, references) => { + return state.update('descendants', map => { + references.forEach(parentId => { + map = map.update(parentId, ImmutableList(), list => { + if (list.includes(status.id)) { + return list; + } + + return list.push(status.id); + }); + }); + + return map; + }); +}; + +export default function contexts(state = initialState, action) { + switch(action.type) { + case ACCOUNT_BLOCK_SUCCESS: + case ACCOUNT_MUTE_SUCCESS: + return filterContexts(state, action.relationship, action.statuses); + case CONTEXT_FETCH_SUCCESS: + return normalizeContext(state, action.id, action.ancestors, action.descendants); + case TIMELINE_DELETE: + return deleteFromContexts(state, [action.id]); + case TIMELINE_CONTEXT_UPDATE: + return updateContext(state, action.status, action.references); + default: + return state; + } +}; |