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.

80 lines
2.7 KiB

  1. import {
  2. ACCOUNT_BLOCK_SUCCESS,
  3. ACCOUNT_MUTE_SUCCESS,
  4. } from 'flavours/glitch/actions/accounts';
  5. import { CONTEXT_FETCH_SUCCESS } from 'flavours/glitch/actions/statuses';
  6. import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from 'flavours/glitch/actions/timelines';
  7. import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
  8. const initialState = ImmutableMap({
  9. ancestors: ImmutableMap(),
  10. descendants: ImmutableMap(),
  11. });
  12. const normalizeContext = (state, id, ancestors, descendants) => {
  13. const ancestorsIds = ImmutableList(ancestors.map(ancestor => ancestor.id));
  14. const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id));
  15. return state.withMutations(map => {
  16. map.setIn(['ancestors', id], ancestorsIds);
  17. map.setIn(['descendants', id], descendantsIds);
  18. });
  19. };
  20. const deleteFromContexts = (immutableState, ids) => immutableState.withMutations(state => {
  21. state.update('ancestors', immutableAncestors => immutableAncestors.withMutations(ancestors => {
  22. state.update('descendants', immutableDescendants => immutableDescendants.withMutations(descendants => {
  23. ids.forEach(id => {
  24. descendants.get(id, ImmutableList()).forEach(descendantId => {
  25. ancestors.update(descendantId, ImmutableList(), list => list.filterNot(itemId => itemId === id));
  26. });
  27. ancestors.get(id, ImmutableList()).forEach(ancestorId => {
  28. descendants.update(ancestorId, ImmutableList(), list => list.filterNot(itemId => itemId === id));
  29. });
  30. descendants.delete(id);
  31. ancestors.delete(id);
  32. });
  33. }));
  34. }));
  35. });
  36. const filterContexts = (state, relationship, statuses) => {
  37. const ownedStatusIds = statuses.filter(status => status.get('account') === relationship.id)
  38. .map(status => status.get('id'));
  39. return deleteFromContexts(state, ownedStatusIds);
  40. };
  41. const updateContext = (state, status, references) => {
  42. return state.update('descendants', map => {
  43. references.forEach(parentId => {
  44. map = map.update(parentId, ImmutableList(), list => {
  45. if (list.includes(status.id)) {
  46. return list;
  47. }
  48. return list.push(status.id);
  49. });
  50. });
  51. return map;
  52. });
  53. };
  54. export default function contexts(state = initialState, action) {
  55. switch(action.type) {
  56. case ACCOUNT_BLOCK_SUCCESS:
  57. case ACCOUNT_MUTE_SUCCESS:
  58. return filterContexts(state, action.relationship, action.statuses);
  59. case CONTEXT_FETCH_SUCCESS:
  60. return normalizeContext(state, action.id, action.ancestors, action.descendants);
  61. case TIMELINE_DELETE:
  62. return deleteFromContexts(state, [action.id]);
  63. case TIMELINE_CONTEXT_UPDATE:
  64. return updateContext(state, action.status, action.references);
  65. default:
  66. return state;
  67. }
  68. };