Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

reducer.ts 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import { PARTICIPANT_ID_CHANGED } from '../participants/actionTypes';
  2. import ReducerRegistry from '../redux/ReducerRegistry';
  3. import { set } from '../redux/functions';
  4. import {
  5. SET_NO_SRC_DATA_NOTIFICATION_UID,
  6. TRACK_ADDED,
  7. TRACK_CREATE_CANCELED,
  8. TRACK_CREATE_ERROR,
  9. TRACK_NO_DATA_FROM_SOURCE,
  10. TRACK_REMOVED,
  11. TRACK_UPDATE_LAST_VIDEO_MEDIA_EVENT,
  12. TRACK_UPDATED,
  13. TRACK_WILL_CREATE
  14. } from './actionTypes';
  15. interface ITrack {
  16. isReceivingData: boolean;
  17. jitsiTrack: Object;
  18. lastMediaEvent?: string;
  19. local: boolean;
  20. mediaType: string;
  21. mirror: boolean;
  22. muted: boolean;
  23. participantId: string;
  24. streamingStatus?: string;
  25. videoStarted: boolean;
  26. videoType?: string|null;
  27. }
  28. /**
  29. * Track type.
  30. *
  31. * @typedef {object} Track
  32. * @property {JitsiLocalTrack|JitsiRemoteTrack} jitsiTrack - The associated
  33. * {@code JitsiTrack} instance. Optional for local tracks if those are still
  34. * being created (ie {@code getUserMedia} is still in progress).
  35. * @property {Promise} [gumProcess] - If a local track is still being created,
  36. * it will have no {@code JitsiTrack}, but a {@code gumProcess} set to a
  37. * {@code Promise} with and extra {@code cancel()}.
  38. * @property {boolean} local=false - If the track is local.
  39. * @property {MEDIA_TYPE} mediaType=false - The media type of the track.
  40. * @property {boolean} mirror=false - The indicator which determines whether the
  41. * display/rendering of the track should be mirrored. It only makes sense in the
  42. * context of video (at least at the time of this writing).
  43. * @property {boolean} muted=false - If the track is muted.
  44. * @property {(string|undefined)} participantId - The ID of the participant whom
  45. * the track belongs to.
  46. * @property {boolean} videoStarted=false - If the video track has already
  47. * started to play.
  48. * @property {(VIDEO_TYPE|undefined)} videoType - The type of video track if
  49. * any.
  50. */
  51. /**
  52. * Reducer function for a single track.
  53. *
  54. * @param {Track|undefined} state - Track to be modified.
  55. * @param {Object} action - Action object.
  56. * @param {string} action.type - Type of action.
  57. * @param {string} action.name - Name of last media event.
  58. * @param {string} action.newValue - New participant ID value (in this
  59. * particular case).
  60. * @param {string} action.oldValue - Old participant ID value (in this
  61. * particular case).
  62. * @param {Track} action.track - Information about track to be changed.
  63. * @param {Participant} action.participant - Information about participant.
  64. * @returns {Track|undefined}
  65. */
  66. function track(state: ITrack, action: any) {
  67. switch (action.type) {
  68. case PARTICIPANT_ID_CHANGED:
  69. if (state.participantId === action.oldValue) {
  70. return {
  71. ...state,
  72. participantId: action.newValue
  73. };
  74. }
  75. break;
  76. case TRACK_UPDATED: {
  77. const t = action.track;
  78. if (state.jitsiTrack === t.jitsiTrack) {
  79. // Make sure that there's an actual update in order to reduce the
  80. // risk of unnecessary React Component renders.
  81. for (const p in t) {
  82. // @ts-ignore
  83. if (state[p] !== t[p]) {
  84. // There's an actual update.
  85. return {
  86. ...state,
  87. ...t
  88. };
  89. }
  90. }
  91. }
  92. break;
  93. }
  94. case TRACK_UPDATE_LAST_VIDEO_MEDIA_EVENT: {
  95. const t = action.track;
  96. if (state.jitsiTrack === t) {
  97. if (state.lastMediaEvent !== action.name) {
  98. return {
  99. ...state,
  100. lastMediaEvent: action.name
  101. };
  102. }
  103. }
  104. break;
  105. }
  106. case TRACK_NO_DATA_FROM_SOURCE: {
  107. const t = action.track;
  108. if (state.jitsiTrack === t.jitsiTrack) {
  109. const isReceivingData = t.jitsiTrack.isReceivingData();
  110. if (state.isReceivingData !== isReceivingData) {
  111. return {
  112. ...state,
  113. isReceivingData
  114. };
  115. }
  116. }
  117. break;
  118. }
  119. }
  120. return state;
  121. }
  122. export type ITracksState = ITrack[];
  123. /**
  124. * Listen for actions that mutate (e.g. Add, remove) local and remote tracks.
  125. */
  126. ReducerRegistry.register('features/base/tracks', (state: ITracksState = [], action) => {
  127. switch (action.type) {
  128. case PARTICIPANT_ID_CHANGED:
  129. case TRACK_NO_DATA_FROM_SOURCE:
  130. case TRACK_UPDATE_LAST_VIDEO_MEDIA_EVENT:
  131. case TRACK_UPDATED:
  132. return state.map((t: ITrack) => track(t, action));
  133. case TRACK_ADDED: {
  134. let withoutTrackStub = state;
  135. if (action.track.local) {
  136. withoutTrackStub
  137. = state.filter(
  138. (t: ITrack) => !t.local || t.mediaType !== action.track.mediaType);
  139. }
  140. return [ ...withoutTrackStub, action.track ];
  141. }
  142. case TRACK_CREATE_CANCELED:
  143. case TRACK_CREATE_ERROR: {
  144. return state.filter((t: ITrack) => !t.local || t.mediaType !== action.trackType);
  145. }
  146. case TRACK_REMOVED:
  147. return state.filter((t: ITrack) => t.jitsiTrack !== action.track.jitsiTrack);
  148. case TRACK_WILL_CREATE:
  149. return [ ...state, action.track ];
  150. default:
  151. return state;
  152. }
  153. });
  154. export interface INoSrcDataState {
  155. noSrcDataNotificationUid?: string|number;
  156. }
  157. /**
  158. * Listen for actions that mutate the no-src-data state, like the current notification id.
  159. */
  160. ReducerRegistry.register('features/base/no-src-data', (state: INoSrcDataState = {}, action) => {
  161. switch (action.type) {
  162. case SET_NO_SRC_DATA_NOTIFICATION_UID:
  163. return set(state, 'noSrcDataNotificationUid', action.uid);
  164. default:
  165. return state;
  166. }
  167. });