You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
2.0 KiB

  1. import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses';
  2. import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from '../actions/timelines';
  3. import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
  4. const initialState = ImmutableMap({
  5. ancestors: ImmutableMap(),
  6. descendants: ImmutableMap(),
  7. });
  8. const normalizeContext = (state, id, ancestors, descendants) => {
  9. const ancestorsIds = ImmutableList(ancestors.map(ancestor => ancestor.id));
  10. const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id));
  11. return state.withMutations(map => {
  12. map.setIn(['ancestors', id], ancestorsIds);
  13. map.setIn(['descendants', id], descendantsIds);
  14. });
  15. };
  16. const deleteFromContexts = (state, id) => {
  17. state.getIn(['descendants', id], ImmutableList()).forEach(descendantId => {
  18. state = state.updateIn(['ancestors', descendantId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
  19. });
  20. state.getIn(['ancestors', id], ImmutableList()).forEach(ancestorId => {
  21. state = state.updateIn(['descendants', ancestorId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
  22. });
  23. state = state.deleteIn(['descendants', id]).deleteIn(['ancestors', id]);
  24. return state;
  25. };
  26. const updateContext = (state, status, references) => {
  27. return state.update('descendants', map => {
  28. references.forEach(parentId => {
  29. map = map.update(parentId, ImmutableList(), list => {
  30. if (list.includes(status.id)) {
  31. return list;
  32. }
  33. return list.push(status.id);
  34. });
  35. });
  36. return map;
  37. });
  38. };
  39. export default function contexts(state = initialState, action) {
  40. switch(action.type) {
  41. case CONTEXT_FETCH_SUCCESS:
  42. return normalizeContext(state, action.id, action.ancestors, action.descendants);
  43. case TIMELINE_DELETE:
  44. return deleteFromContexts(state, action.id);
  45. case TIMELINE_CONTEXT_UPDATE:
  46. return updateContext(state, action.status, action.references);
  47. default:
  48. return state;
  49. }
  50. };