選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

actions.any.js 9.4KB

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