jiti-meet/react/features/recording/actions.any.ts

370 lines
12 KiB
TypeScript
Raw Normal View History

import { IStore } from '../app/types';
import { getMeetingRegion, getRecordingSharingUrl } from '../base/config/functions';
2018-09-10 15:39:33 +00:00
import JitsiMeetJS, { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
import { getLocalParticipant, getParticipantDisplayName } from '../base/participants/functions';
2022-09-27 14:37:38 +00:00
import { copyText } from '../base/util/copyText';
import { getVpaasTenant, isVpaasMeeting } from '../jaas/functions';
2018-06-14 09:15:36 +00:00
import {
hideNotification,
showErrorNotification,
showNotification,
showWarningNotification
} from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
import { INotificationProps } from '../notifications/types';
2018-06-14 09:15:36 +00:00
import {
CLEAR_RECORDING_SESSIONS,
RECORDING_SESSION_UPDATED,
SET_MEETING_HIGHLIGHT_BUTTON_STATE,
2018-07-05 11:17:45 +00:00
SET_PENDING_RECORDING_NOTIFICATION_UID,
SET_SELECTED_RECORDING_SERVICE,
SET_STREAM_KEY,
START_LOCAL_RECORDING,
STOP_LOCAL_RECORDING
2018-06-14 09:15:36 +00:00
} from './actionTypes';
import {
getRecordingLink,
getResourceId,
isSavingRecordingOnDropbox,
sendMeetingHighlight
} from './functions';
import logger from './logger';
2018-06-14 09:15:36 +00:00
/**
* Clears the data of every recording sessions.
*
* @returns {{
* type: CLEAR_RECORDING_SESSIONS
* }}
*/
export function clearRecordingSessions() {
return {
type: CLEAR_RECORDING_SESSIONS
};
}
/**
* Sets the meeting highlight button disable state.
*
* @param {boolean} disabled - The disabled state value.
* @returns {{
* type: CLEAR_RECORDING_SESSIONS
* }}
*/
export function setHighlightMomentButtonState(disabled: boolean) {
return {
type: SET_MEETING_HIGHLIGHT_BUTTON_STATE,
disabled
};
}
2018-06-14 09:15:36 +00:00
/**
* Signals that the pending recording notification should be removed from the
* screen.
*
* @param {string} streamType - The type of the stream ({@code 'file'} or
* {@code 'stream'}).
2018-06-14 09:15:36 +00:00
* @returns {Function}
*/
2018-07-05 11:17:45 +00:00
export function hidePendingRecordingNotification(streamType: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
2018-07-05 11:17:45 +00:00
const { pendingNotificationUids } = getState()['features/recording'];
const pendingNotificationUid = pendingNotificationUids[streamType];
2018-06-14 09:15:36 +00:00
if (pendingNotificationUid) {
dispatch(hideNotification(pendingNotificationUid));
2018-07-05 11:17:45 +00:00
dispatch(
_setPendingRecordingNotificationUid(
undefined, streamType));
2018-06-14 09:15:36 +00:00
}
};
}
/**
2018-07-05 11:17:45 +00:00
* Sets the stream key last used by the user for later reuse.
2018-06-14 09:15:36 +00:00
*
2018-07-05 11:17:45 +00:00
* @param {string} streamKey - The stream key to set.
2018-06-14 09:15:36 +00:00
* @returns {{
2018-07-05 11:17:45 +00:00
* type: SET_STREAM_KEY,
* streamKey: string
2018-06-14 09:15:36 +00:00
* }}
*/
2018-07-05 11:17:45 +00:00
export function setLiveStreamKey(streamKey: string) {
2018-06-14 09:15:36 +00:00
return {
2018-07-05 11:17:45 +00:00
type: SET_STREAM_KEY,
streamKey
2018-06-14 09:15:36 +00:00
};
}
/**
* Signals that the pending recording notification should be shown on the
* screen.
*
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
2018-06-14 09:15:36 +00:00
* @returns {Function}
*/
2018-07-05 11:17:45 +00:00
export function showPendingRecordingNotification(streamType: string) {
return async (dispatch: IStore['dispatch']) => {
2018-07-05 11:17:45 +00:00
const isLiveStreaming
= streamType === JitsiMeetJS.constants.recording.mode.STREAM;
const dialogProps = isLiveStreaming ? {
descriptionKey: 'liveStreaming.pending',
titleKey: 'dialog.liveStreaming'
} : {
2018-06-14 09:15:36 +00:00
descriptionKey: 'recording.pending',
titleKey: 'dialog.recording'
2018-07-05 11:17:45 +00:00
};
const notification = await dispatch(showNotification({
2018-07-05 11:17:45 +00:00
...dialogProps
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
2018-06-14 09:15:36 +00:00
if (notification) {
dispatch(_setPendingRecordingNotificationUid(notification.uid, streamType));
}
2018-06-14 09:15:36 +00:00
};
}
/**
* Highlights a meeting moment.
*
* {@code stream}).
*
* @returns {Function}
*/
export function highlightMeetingMoment() {
return async (dispatch: Function, getState: Function) => {
dispatch(setHighlightMomentButtonState(true));
const success = await sendMeetingHighlight(getState());
if (success) {
dispatch(showNotification({
descriptionKey: 'recording.highlightMomentSucessDescription',
titleKey: 'recording.highlightMomentSuccess'
}, NOTIFICATION_TIMEOUT_TYPE.SHORT));
}
dispatch(setHighlightMomentButtonState(false));
};
}
2018-06-14 09:15:36 +00:00
/**
* Signals that the recording error notification should be shown.
*
* @param {Object} props - The Props needed to render the notification.
* @returns {showErrorNotification}
*/
export function showRecordingError(props: Object) {
return showErrorNotification(props, NOTIFICATION_TIMEOUT_TYPE.LONG);
2018-06-14 09:15:36 +00:00
}
/**
* Signals that the recording warning notification should be shown.
*
* @param {Object} props - The Props needed to render the notification.
* @returns {showWarningNotification}
*/
export function showRecordingWarning(props: Object) {
return showWarningNotification(props);
}
2018-06-14 09:15:36 +00:00
/**
* Signals that the stopped recording notification should be shown on the
* screen for a given period.
*
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
* @param {string?} participantName - The participant name stopping the recording.
2018-06-14 09:15:36 +00:00
* @returns {showNotification}
*/
export function showStoppedRecordingNotification(streamType: string, participantName?: string) {
2018-07-05 11:17:45 +00:00
const isLiveStreaming
= streamType === JitsiMeetJS.constants.recording.mode.STREAM;
const descriptionArguments = { name: participantName };
2018-07-05 11:17:45 +00:00
const dialogProps = isLiveStreaming ? {
descriptionKey: participantName ? 'liveStreaming.offBy' : 'liveStreaming.off',
descriptionArguments,
2018-07-05 11:17:45 +00:00
titleKey: 'dialog.liveStreaming'
} : {
descriptionKey: participantName ? 'recording.offBy' : 'recording.off',
descriptionArguments,
titleKey: 'dialog.recording'
};
return showNotification(dialogProps, NOTIFICATION_TIMEOUT_TYPE.SHORT);
}
/**
* Signals that a started recording notification should be shown on the
* screen for a given period.
*
* @param {string} mode - The type of the recording: Stream of File.
* @param {string | Object } initiator - The participant who started recording.
* @param {string} sessionId - The recording session id.
* @returns {Function}
*/
export function showStartedRecordingNotification(
mode: string,
initiator: { getId: Function; } | string,
sessionId: string) {
return async (dispatch: Function, getState: Function) => {
const state = getState();
const initiatorId = getResourceId(initiator);
const participantName = getParticipantDisplayName(state, initiatorId);
const notifyProps: {
dialogProps: INotificationProps;
type: string;
} = {
dialogProps: {
descriptionKey: participantName ? 'liveStreaming.onBy' : 'liveStreaming.on',
descriptionArguments: { name: participantName },
titleKey: 'dialog.liveStreaming'
},
type: NOTIFICATION_TIMEOUT_TYPE.SHORT
};
2018-07-05 11:17:45 +00:00
if (mode !== JitsiMeetJS.constants.recording.mode.STREAM) {
const recordingSharingUrl = getRecordingSharingUrl(state);
const iAmRecordingInitiator = getLocalParticipant(state)?.id === initiatorId;
notifyProps.dialogProps = {
customActionHandler: undefined,
customActionNameKey: undefined,
descriptionKey: participantName ? 'recording.onBy' : 'recording.on',
descriptionArguments: { name: participantName },
titleKey: 'dialog.recording'
};
// fetch the recording link from the server for recording initiators in jaas meetings
if (recordingSharingUrl
&& isVpaasMeeting(state)
&& iAmRecordingInitiator
&& !isSavingRecordingOnDropbox(state)) {
const region = getMeetingRegion(state);
const tenant = getVpaasTenant(state);
try {
const response = await getRecordingLink(recordingSharingUrl, sessionId, region, tenant);
const { url: link, urlExpirationTimeMillis: ttl } = response;
if (typeof APP === 'object') {
APP.API.notifyRecordingLinkAvailable(link, ttl);
}
// add the option to copy recording link
notifyProps.dialogProps = {
...notifyProps.dialogProps,
customActionNameKey: [ 'recording.copyLink' ],
customActionHandler: [ () => copyText(link) ],
titleKey: 'recording.on',
descriptionKey: 'recording.linkGenerated'
};
notifyProps.type = NOTIFICATION_TIMEOUT_TYPE.STICKY;
} catch (err) {
dispatch(showErrorNotification({
titleKey: 'recording.errorFetchingLink'
}, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
return logger.error('Could not fetch recording link', err);
}
}
}
dispatch(showNotification(notifyProps.dialogProps, notifyProps.type));
};
2018-06-14 09:15:36 +00:00
}
/**
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
* Updates the known state for a given recording session.
*
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
* @param {Object} session - The new state to merge with the existing state in
* redux.
* @returns {{
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
* type: RECORDING_SESSION_UPDATED,
* sessionData: Object
* }}
*/
export function updateRecordingSessionData(session: any) {
2018-09-10 15:39:33 +00:00
const status = session.getStatus();
const timestamp
= status === JitsiRecordingConstants.status.ON
? Date.now() / 1000
: undefined;
return {
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
type: RECORDING_SESSION_UPDATED,
sessionData: {
error: session.getError(),
id: session.getID(),
initiator: session.getInitiator(),
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
liveStreamViewURL: session.getLiveStreamViewURL(),
mode: session.getMode(),
2018-09-10 15:39:33 +00:00
status,
terminator: session.getTerminator(),
2018-09-10 15:39:33 +00:00
timestamp
feat(recording): frontend logic can support live streaming and recording (#2952) * feat(recording): frontend logic can support live streaming and recording Instead of either live streaming or recording, now both can live together. The changes to facilitate such include the following: - Killing the state storing in Recording.js. Instead state is stored in the lib and updated in redux for labels to display the necessary state updates. - Creating a new container, Labels, for recording labels. Previously labels were manually created and positioned. The container can create a reasonable number of labels and only the container itself needs to be positioned with CSS. The VideoQualityLabel has been shoved into the container as well because it moves along with the recording labels. - The action for updating recording state has been modified to enable updating an array of recording sessions to support having multiple sessions. - Confirmation dialogs for stopping and starting a file recording session have been created, as they previously were jquery modals opened by Recording.js. - Toolbox.web displays live streaming and recording buttons based on configuration instead of recording availability. - VideoQualityLabel and RecordingLabel have been simplified to remove any positioning logic, as the Labels container handles such. - Previous recording state update logic has been moved into the RecordingLabel component. Each RecordingLabel is in charge of displaying state for a recording session. The display UX has been left alone. - Sipgw availability is no longer broadcast so remove logic depending on its state. Some moving around of code was necessary to get around linting errors about the existing code being too deeply nested (even though I didn't touch it). * work around lib-jitsi-meet circular dependency issues * refactor labels to use html base * pass in translation keys to video quality label * add video quality classnames for torture tests * break up, rearrange recorder session update listener * add comment about disabling startup resize animation * rename session to sessionData * chore(deps): update to latest lib for recording changes
2018-05-16 14:00:16 +00:00
}
};
}
2018-07-05 11:17:45 +00:00
/**
* Sets the selected recording service.
*
* @param {string} selectedRecordingService - The new selected recording service.
* @returns {Object}
*/
export function setSelectedRecordingService(selectedRecordingService: string) {
return {
type: SET_SELECTED_RECORDING_SERVICE,
selectedRecordingService
};
}
2018-07-05 11:17:45 +00:00
/**
* Sets UID of the the pending streaming notification to use it when hinding
* the notification is necessary, or unsets it when undefined (or no param) is
* passed.
*
* @param {?number} uid - The UID of the notification.
* @param {string} streamType - The type of the stream ({@code file} or
* {@code stream}).
2018-07-05 11:17:45 +00:00
* @returns {{
* type: SET_PENDING_RECORDING_NOTIFICATION_UID,
* streamType: string,
* uid: number
* }}
*/
function _setPendingRecordingNotificationUid(uid: string | undefined, streamType: string) {
2018-07-05 11:17:45 +00:00
return {
type: SET_PENDING_RECORDING_NOTIFICATION_UID,
streamType,
uid
};
}
/**
* Starts local recording.
*
* @param {boolean} onlySelf - Whether to only record the local streams.
* @returns {Object}
*/
export function startLocalVideoRecording(onlySelf: boolean) {
return {
type: START_LOCAL_RECORDING,
onlySelf
};
}
/**
* Stops local recording.
*
* @returns {Object}
*/
export function stopLocalVideoRecording() {
return {
type: STOP_LOCAL_RECORDING
};
}