The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

73 lines
2.6 KiB

  1. import {
  2. ANNOUNCEMENTS_FETCH_REQUEST,
  3. ANNOUNCEMENTS_FETCH_SUCCESS,
  4. ANNOUNCEMENTS_FETCH_FAIL,
  5. ANNOUNCEMENTS_UPDATE,
  6. ANNOUNCEMENTS_DISMISS,
  7. ANNOUNCEMENTS_REACTION_UPDATE,
  8. ANNOUNCEMENTS_REACTION_ADD_REQUEST,
  9. ANNOUNCEMENTS_REACTION_ADD_FAIL,
  10. ANNOUNCEMENTS_REACTION_REMOVE_REQUEST,
  11. ANNOUNCEMENTS_REACTION_REMOVE_FAIL,
  12. } from '../actions/announcements';
  13. import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
  14. const initialState = ImmutableMap({
  15. items: ImmutableList(),
  16. isLoading: false,
  17. });
  18. const updateReaction = (state, id, name, updater) => state.update('items', list => list.map(announcement => {
  19. if (announcement.get('id') === id) {
  20. return announcement.update('reactions', reactions => {
  21. if (reactions.find(reaction => reaction.get('name') === name)) {
  22. return reactions.map(reaction => {
  23. if (reaction.get('name') === name) {
  24. return updater(reaction);
  25. }
  26. return reaction;
  27. });
  28. }
  29. return reactions.push(updater(fromJS({ name, count: 0 })));
  30. });
  31. }
  32. return announcement;
  33. }));
  34. const updateReactionCount = (state, reaction) => updateReaction(state, reaction.announcement_id, reaction.name, x => x.set('count', reaction.count));
  35. const addReaction = (state, id, name) => updateReaction(state, id, name, x => x.set('me', true).update('count', y => y + 1));
  36. const removeReaction = (state, id, name) => updateReaction(state, id, name, x => x.set('me', false).update('count', y => y - 1));
  37. export default function announcementsReducer(state = initialState, action) {
  38. switch(action.type) {
  39. case ANNOUNCEMENTS_FETCH_REQUEST:
  40. return state.set('isLoading', true);
  41. case ANNOUNCEMENTS_FETCH_SUCCESS:
  42. return state.withMutations(map => {
  43. map.set('items', fromJS(action.announcements));
  44. map.set('isLoading', false);
  45. });
  46. case ANNOUNCEMENTS_FETCH_FAIL:
  47. return state.set('isLoading', false);
  48. case ANNOUNCEMENTS_UPDATE:
  49. return state.update('items', list => list.unshift(fromJS(action.announcement)).sortBy(announcement => announcement.get('starts_at')));
  50. case ANNOUNCEMENTS_DISMISS:
  51. return state.update('items', list => list.filterNot(announcement => announcement.get('id') === action.id));
  52. case ANNOUNCEMENTS_REACTION_UPDATE:
  53. return updateReactionCount(state, action.reaction);
  54. case ANNOUNCEMENTS_REACTION_ADD_REQUEST:
  55. case ANNOUNCEMENTS_REACTION_REMOVE_FAIL:
  56. return addReaction(state, action.id, action.name);
  57. case ANNOUNCEMENTS_REACTION_REMOVE_REQUEST:
  58. case ANNOUNCEMENTS_REACTION_ADD_FAIL:
  59. return removeReaction(state, action.id, action.name);
  60. default:
  61. return state;
  62. }
  63. };