Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

actions.any.js 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // @flow
  2. import { getMeetingRegion, getRecordingSharingUrl } from '../base/config';
  3. import JitsiMeetJS, { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
  4. import { getLocalParticipant, getParticipantDisplayName } from '../base/participants';
  5. import { copyText } from '../base/util/helpers';
  6. import { getVpaasTenant, isVpaasMeeting } from '../billing-counter/functions';
  7. import {
  8. NOTIFICATION_TIMEOUT,
  9. hideNotification,
  10. showErrorNotification,
  11. showNotification
  12. } from '../notifications';
  13. import {
  14. CLEAR_RECORDING_SESSIONS,
  15. RECORDING_SESSION_UPDATED,
  16. SET_PENDING_RECORDING_NOTIFICATION_UID,
  17. SET_STREAM_KEY
  18. } from './actionTypes';
  19. import { getRecordingLink, getResourceId } from './functions';
  20. import logger from './logger';
  21. /**
  22. * Clears the data of every recording sessions.
  23. *
  24. * @returns {{
  25. * type: CLEAR_RECORDING_SESSIONS
  26. * }}
  27. */
  28. export function clearRecordingSessions() {
  29. return {
  30. type: CLEAR_RECORDING_SESSIONS
  31. };
  32. }
  33. /**
  34. * Signals that the pending recording notification should be removed from the
  35. * screen.
  36. *
  37. * @param {string} streamType - The type of the stream ({@code 'file'} or
  38. * {@code 'stream'}).
  39. * @returns {Function}
  40. */
  41. export function hidePendingRecordingNotification(streamType: string) {
  42. return (dispatch: Function, getState: Function) => {
  43. const { pendingNotificationUids } = getState()['features/recording'];
  44. const pendingNotificationUid = pendingNotificationUids[streamType];
  45. if (pendingNotificationUid) {
  46. dispatch(hideNotification(pendingNotificationUid));
  47. dispatch(
  48. _setPendingRecordingNotificationUid(
  49. undefined, streamType));
  50. }
  51. };
  52. }
  53. /**
  54. * Sets the stream key last used by the user for later reuse.
  55. *
  56. * @param {string} streamKey - The stream key to set.
  57. * @returns {{
  58. * type: SET_STREAM_KEY,
  59. * streamKey: string
  60. * }}
  61. */
  62. export function setLiveStreamKey(streamKey: string) {
  63. return {
  64. type: SET_STREAM_KEY,
  65. streamKey
  66. };
  67. }
  68. /**
  69. * Signals that the pending recording notification should be shown on the
  70. * screen.
  71. *
  72. * @param {string} streamType - The type of the stream ({@code file} or
  73. * {@code stream}).
  74. * @returns {Function}
  75. */
  76. export function showPendingRecordingNotification(streamType: string) {
  77. return async (dispatch: Function) => {
  78. const isLiveStreaming
  79. = streamType === JitsiMeetJS.constants.recording.mode.STREAM;
  80. const dialogProps = isLiveStreaming ? {
  81. descriptionKey: 'liveStreaming.pending',
  82. titleKey: 'dialog.liveStreaming'
  83. } : {
  84. descriptionKey: 'recording.pending',
  85. titleKey: 'dialog.recording'
  86. };
  87. const notification = await dispatch(showNotification({
  88. isDismissAllowed: false,
  89. ...dialogProps
  90. }));
  91. if (notification) {
  92. dispatch(_setPendingRecordingNotificationUid(notification.uid, streamType));
  93. }
  94. };
  95. }
  96. /**
  97. * Signals that the recording error notification should be shown.
  98. *
  99. * @param {Object} props - The Props needed to render the notification.
  100. * @returns {showErrorNotification}
  101. */
  102. export function showRecordingError(props: Object) {
  103. return showErrorNotification(props);
  104. }
  105. /**
  106. * Signals that the stopped recording notification should be shown on the
  107. * screen for a given period.
  108. *
  109. * @param {string} streamType - The type of the stream ({@code file} or
  110. * {@code stream}).
  111. * @param {string?} participantName - The participant name stopping the recording.
  112. * @returns {showNotification}
  113. */
  114. export function showStoppedRecordingNotification(streamType: string, participantName?: string) {
  115. const isLiveStreaming
  116. = streamType === JitsiMeetJS.constants.recording.mode.STREAM;
  117. const descriptionArguments = { name: participantName };
  118. const dialogProps = isLiveStreaming ? {
  119. descriptionKey: participantName ? 'liveStreaming.offBy' : 'liveStreaming.off',
  120. descriptionArguments,
  121. titleKey: 'dialog.liveStreaming'
  122. } : {
  123. descriptionKey: participantName ? 'recording.offBy' : 'recording.off',
  124. descriptionArguments,
  125. titleKey: 'dialog.recording'
  126. };
  127. return showNotification(dialogProps, NOTIFICATION_TIMEOUT);
  128. }
  129. /**
  130. * Signals that a started recording notification should be shown on the
  131. * screen for a given period.
  132. *
  133. * @param {string} mode - The type of the recording: Stream of File.
  134. * @param {string | Object } initiator - The participant who started recording.
  135. * @param {string} sessionId - The recording session id.
  136. * @returns {Function}
  137. */
  138. export function showStartedRecordingNotification(
  139. mode: string,
  140. initiator: Object | string,
  141. sessionId: string) {
  142. return async (dispatch: Function, getState: Function) => {
  143. const state = getState();
  144. const initiatorId = getResourceId(initiator);
  145. const participantName = getParticipantDisplayName(state, initiatorId);
  146. let dialogProps = {
  147. customActionNameKey: undefined,
  148. descriptionKey: participantName ? 'liveStreaming.onBy' : 'liveStreaming.on',
  149. descriptionArguments: { name: participantName },
  150. isDismissAllowed: true,
  151. titleKey: 'dialog.liveStreaming'
  152. };
  153. if (mode !== JitsiMeetJS.constants.recording.mode.STREAM) {
  154. const recordingSharingUrl = getRecordingSharingUrl(state);
  155. const iAmRecordingInitiator = getLocalParticipant(state).id === initiatorId;
  156. dialogProps = {
  157. customActionHandler: undefined,
  158. customActionNameKey: undefined,
  159. descriptionKey: participantName ? 'recording.onBy' : 'recording.on',
  160. descriptionArguments: { name: participantName },
  161. isDismissAllowed: true,
  162. titleKey: 'dialog.recording'
  163. };
  164. // fetch the recording link from the server for recording initiators in jaas meetings
  165. if (recordingSharingUrl
  166. && isVpaasMeeting(state)
  167. && iAmRecordingInitiator) {
  168. const region = getMeetingRegion(state);
  169. const tenant = getVpaasTenant(state);
  170. try {
  171. const link = await getRecordingLink(recordingSharingUrl, sessionId, region, tenant);
  172. // add the option to copy recording link
  173. dialogProps.customActionNameKey = 'recording.copyLink';
  174. dialogProps.customActionHandler = () => copyText(link);
  175. dialogProps.titleKey = 'recording.on';
  176. dialogProps.descriptionKey = 'recording.linkGenerated';
  177. dialogProps.isDismissAllowed = false;
  178. } catch (err) {
  179. dispatch(showErrorNotification({
  180. titleKey: 'recording.errorFetchingLink'
  181. }));
  182. return logger.error('Could not fetch recording link', err);
  183. }
  184. }
  185. }
  186. dispatch(showNotification(dialogProps));
  187. };
  188. }
  189. /**
  190. * Updates the known state for a given recording session.
  191. *
  192. * @param {Object} session - The new state to merge with the existing state in
  193. * redux.
  194. * @returns {{
  195. * type: RECORDING_SESSION_UPDATED,
  196. * sessionData: Object
  197. * }}
  198. */
  199. export function updateRecordingSessionData(session: Object) {
  200. const status = session.getStatus();
  201. const timestamp
  202. = status === JitsiRecordingConstants.status.ON
  203. ? Date.now() / 1000
  204. : undefined;
  205. return {
  206. type: RECORDING_SESSION_UPDATED,
  207. sessionData: {
  208. error: session.getError(),
  209. id: session.getID(),
  210. initiator: session.getInitiator(),
  211. liveStreamViewURL: session.getLiveStreamViewURL(),
  212. mode: session.getMode(),
  213. status,
  214. terminator: session.getTerminator(),
  215. timestamp
  216. }
  217. };
  218. }
  219. /**
  220. * Sets UID of the the pending streaming notification to use it when hinding
  221. * the notification is necessary, or unsets it when undefined (or no param) is
  222. * passed.
  223. *
  224. * @param {?number} uid - The UID of the notification.
  225. * @param {string} streamType - The type of the stream ({@code file} or
  226. * {@code stream}).
  227. * @returns {{
  228. * type: SET_PENDING_RECORDING_NOTIFICATION_UID,
  229. * streamType: string,
  230. * uid: number
  231. * }}
  232. */
  233. function _setPendingRecordingNotificationUid(uid: ?number, streamType: string) {
  234. return {
  235. type: SET_PENDING_RECORDING_NOTIFICATION_UID,
  236. streamType,
  237. uid
  238. };
  239. }