您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

reducer.ts 4.6KB

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