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.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import { ILocalParticipant, IParticipant } from '../base/participants/types';
  2. import ReducerRegistry from '../base/redux/ReducerRegistry';
  3. import {
  4. ADD_MESSAGE,
  5. CLEAR_MESSAGES,
  6. CLOSE_CHAT,
  7. EDIT_MESSAGE,
  8. OPEN_CHAT,
  9. REMOVE_LOBBY_CHAT_PARTICIPANT,
  10. SET_IS_POLL_TAB_FOCUSED,
  11. SET_LOBBY_CHAT_ACTIVE_STATE,
  12. SET_LOBBY_CHAT_RECIPIENT,
  13. SET_PRIVATE_MESSAGE_RECIPIENT
  14. } from './actionTypes';
  15. import { IMessage } from './types';
  16. const DEFAULT_STATE = {
  17. isOpen: false,
  18. isPollsTabFocused: false,
  19. lastReadMessage: undefined,
  20. messages: [],
  21. nbUnreadMessages: 0,
  22. privateMessageRecipient: undefined,
  23. lobbyMessageRecipient: undefined,
  24. isLobbyChatActive: false
  25. };
  26. export interface IChatState {
  27. isLobbyChatActive: boolean;
  28. isOpen: boolean;
  29. isPollsTabFocused: boolean;
  30. lastReadMessage?: IMessage;
  31. lobbyMessageRecipient?: {
  32. id: string;
  33. name: string;
  34. } | ILocalParticipant;
  35. messages: IMessage[];
  36. nbUnreadMessages: number;
  37. privateMessageRecipient?: IParticipant;
  38. }
  39. ReducerRegistry.register<IChatState>('features/chat', (state = DEFAULT_STATE, action): IChatState => {
  40. switch (action.type) {
  41. case ADD_MESSAGE: {
  42. const newMessage: IMessage = {
  43. displayName: action.displayName,
  44. error: action.error,
  45. participantId: action.participantId,
  46. isReaction: action.isReaction,
  47. messageId: action.messageId,
  48. messageType: action.messageType,
  49. message: action.message,
  50. privateMessage: action.privateMessage,
  51. lobbyChat: action.lobbyChat,
  52. recipient: action.recipient,
  53. timestamp: action.timestamp
  54. };
  55. // React native, unlike web, needs a reverse sorted message list.
  56. const messages = navigator.product === 'ReactNative'
  57. ? [
  58. newMessage,
  59. ...state.messages
  60. ]
  61. : [
  62. ...state.messages,
  63. newMessage
  64. ];
  65. return {
  66. ...state,
  67. lastReadMessage:
  68. action.hasRead ? newMessage : state.lastReadMessage,
  69. nbUnreadMessages: state.isPollsTabFocused ? state.nbUnreadMessages + 1 : state.nbUnreadMessages,
  70. messages
  71. };
  72. }
  73. case CLEAR_MESSAGES:
  74. return {
  75. ...state,
  76. lastReadMessage: undefined,
  77. messages: []
  78. };
  79. case EDIT_MESSAGE: {
  80. let found = false;
  81. const newMessage = action.message;
  82. const messages = state.messages.map(m => {
  83. if (m.messageId === newMessage.messageId) {
  84. found = true;
  85. return newMessage;
  86. }
  87. return m;
  88. });
  89. // no change
  90. if (!found) {
  91. return state;
  92. }
  93. return {
  94. ...state,
  95. messages
  96. };
  97. }
  98. case SET_PRIVATE_MESSAGE_RECIPIENT:
  99. return {
  100. ...state,
  101. privateMessageRecipient: action.participant
  102. };
  103. case OPEN_CHAT:
  104. return {
  105. ...state,
  106. isOpen: true,
  107. privateMessageRecipient: action.participant
  108. };
  109. case CLOSE_CHAT:
  110. return {
  111. ...state,
  112. isOpen: false,
  113. lastReadMessage: state.messages[
  114. navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
  115. privateMessageRecipient: action.participant,
  116. isLobbyChatActive: false
  117. };
  118. case SET_IS_POLL_TAB_FOCUSED: {
  119. return {
  120. ...state,
  121. isPollsTabFocused: action.isPollsTabFocused,
  122. nbUnreadMessages: 0
  123. }; }
  124. case SET_LOBBY_CHAT_RECIPIENT:
  125. return {
  126. ...state,
  127. isLobbyChatActive: true,
  128. lobbyMessageRecipient: action.participant,
  129. privateMessageRecipient: undefined,
  130. isOpen: action.open
  131. };
  132. case SET_LOBBY_CHAT_ACTIVE_STATE:
  133. return {
  134. ...state,
  135. isLobbyChatActive: action.payload,
  136. isOpen: action.payload || state.isOpen,
  137. privateMessageRecipient: undefined
  138. };
  139. case REMOVE_LOBBY_CHAT_PARTICIPANT:
  140. return {
  141. ...state,
  142. messages: state.messages.filter(m => {
  143. if (action.removeLobbyChatMessages) {
  144. return !m.lobbyChat;
  145. }
  146. return true;
  147. }),
  148. isOpen: state.isOpen && state.isLobbyChatActive ? false : state.isOpen,
  149. isLobbyChatActive: false,
  150. lobbyMessageRecipient: undefined
  151. };
  152. }
  153. return state;
  154. });