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.

reducer.ts 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import ReducerRegistry from '../base/redux/ReducerRegistry';
  2. import {
  3. CHANGE_VOTE,
  4. CLEAR_POLLS,
  5. RECEIVE_ANSWER,
  6. RECEIVE_POLL,
  7. REGISTER_VOTE,
  8. RESET_NB_UNREAD_POLLS,
  9. RETRACT_VOTE
  10. } from './actionTypes';
  11. import { IAnswer, IPoll } from './types';
  12. const INITIAL_STATE = {
  13. polls: {},
  14. // Number of not read message
  15. nbUnreadPolls: 0
  16. };
  17. export interface IPollsState {
  18. nbUnreadPolls: number;
  19. polls: {
  20. [pollId: string]: IPoll;
  21. };
  22. }
  23. ReducerRegistry.register<IPollsState>('features/polls', (state = INITIAL_STATE, action): IPollsState => {
  24. switch (action.type) {
  25. case CHANGE_VOTE: {
  26. const { pollId, value } = action;
  27. return {
  28. ...state,
  29. polls: {
  30. ...state.polls,
  31. [pollId]: {
  32. ...state.polls[pollId],
  33. changingVote: value,
  34. showResults: !value
  35. }
  36. }
  37. };
  38. }
  39. case CLEAR_POLLS: {
  40. return {
  41. ...state,
  42. ...INITIAL_STATE
  43. };
  44. }
  45. // Reducer triggered when a poll is received
  46. case RECEIVE_POLL: {
  47. const newState = {
  48. ...state,
  49. polls: {
  50. ...state.polls,
  51. // The poll is added to the dictionary of received polls
  52. [action.pollId]: action.poll
  53. },
  54. nbUnreadPolls: state.nbUnreadPolls + 1
  55. };
  56. return newState;
  57. }
  58. // Reducer triggered when an answer is received
  59. // The answer is added to an existing poll
  60. case RECEIVE_ANSWER: {
  61. const { pollId, answer }: { answer: IAnswer; pollId: string; } = action;
  62. // if the poll doesn't exist
  63. if (!(pollId in state.polls)) {
  64. console.warn('requested poll does not exist: pollId ', pollId);
  65. return state;
  66. }
  67. // if the poll exists, we update it with the incoming answer
  68. const newAnswers = state.polls[pollId].answers
  69. .map(_answer => {
  70. // checking if the voters is an array for supporting old structure model
  71. const answerVoters = _answer.voters
  72. ? _answer.voters.length
  73. ? [ ..._answer.voters ] : Object.keys(_answer.voters) : [];
  74. return {
  75. name: _answer.name,
  76. voters: answerVoters
  77. };
  78. });
  79. for (let i = 0; i < newAnswers.length; i++) {
  80. // if the answer was chosen, we add the senderId to the array of voters of this answer
  81. const voters = newAnswers[i].voters as any;
  82. const index = voters.indexOf(answer.voterId);
  83. if (answer.answers[i]) {
  84. if (index === -1) {
  85. voters.push(answer.voterId);
  86. }
  87. } else if (index > -1) {
  88. voters.splice(index, 1);
  89. }
  90. }
  91. // finally we update the state by returning the updated poll
  92. return {
  93. ...state,
  94. polls: {
  95. ...state.polls,
  96. [pollId]: {
  97. ...state.polls[pollId],
  98. answers: newAnswers
  99. }
  100. }
  101. };
  102. }
  103. case REGISTER_VOTE: {
  104. const { answers, pollId }: { answers: Array<boolean> | null; pollId: string; } = action;
  105. return {
  106. ...state,
  107. polls: {
  108. ...state.polls,
  109. [pollId]: {
  110. ...state.polls[pollId],
  111. changingVote: false,
  112. lastVote: answers,
  113. showResults: true
  114. }
  115. }
  116. };
  117. }
  118. case RETRACT_VOTE: {
  119. const { pollId }: { pollId: string; } = action;
  120. return {
  121. ...state,
  122. polls: {
  123. ...state.polls,
  124. [pollId]: {
  125. ...state.polls[pollId],
  126. showResults: false
  127. }
  128. }
  129. };
  130. }
  131. case RESET_NB_UNREAD_POLLS: {
  132. return {
  133. ...state,
  134. nbUnreadPolls: 0
  135. };
  136. }
  137. default:
  138. return state;
  139. }
  140. });