fix(local-recording) Add notification config and style fixes (#11728)
Add analytics
This commit is contained in:
parent
31348179d4
commit
7dca91a50a
|
@ -295,8 +295,13 @@ var config = {
|
||||||
// Whether to enable live streaming or not.
|
// Whether to enable live streaming or not.
|
||||||
// liveStreamingEnabled: false,
|
// liveStreamingEnabled: false,
|
||||||
|
|
||||||
// Whether to enable local recording or not.
|
// Local recording configuration.
|
||||||
// enableLocalRecording: false,
|
// localRecording: {
|
||||||
|
// // Whether to enable local recording or not.
|
||||||
|
// enable: false,
|
||||||
|
// // Whether to notify all participants when a participant is recording locally.
|
||||||
|
// notifyAllParticipants: false
|
||||||
|
// },
|
||||||
|
|
||||||
// Transcription (in interface_config,
|
// Transcription (in interface_config,
|
||||||
// subtitles and buttons can be configured)
|
// subtitles and buttons can be configured)
|
||||||
|
|
|
@ -28,8 +28,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.local-recording-warning {
|
.local-recording-warning {
|
||||||
margin-top: 4px;
|
margin-top: 8px;
|
||||||
display: block;
|
display: block;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
|
||||||
|
&.text {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #3D3D3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.notification {
|
||||||
|
color: #040404;
|
||||||
|
background-color: #F8AE1A;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.recording-switch-disabled {
|
.recording-switch-disabled {
|
||||||
|
@ -46,7 +59,7 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 56px;
|
width: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cloud-content-recording-icon-container {
|
.cloud-content-recording-icon-container {
|
||||||
|
@ -58,7 +71,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.jitsi-recording-header {
|
.jitsi-recording-header {
|
||||||
margin-bottom: 32px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jitsi-content-recording-icon-container-with-switch {
|
.jitsi-content-recording-icon-container-with-switch {
|
||||||
|
|
|
@ -894,6 +894,7 @@
|
||||||
"limitNotificationDescriptionWeb": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
"limitNotificationDescriptionWeb": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||||
"linkGenerated": "We have generated a link to your recording.",
|
"linkGenerated": "We have generated a link to your recording.",
|
||||||
"live": "LIVE",
|
"live": "LIVE",
|
||||||
|
"localRecordingNoNotificationWarning": "The recording will not be announced to other participants. You will need to let them know that the meeting is recorded.",
|
||||||
"localRecordingWarning": "Make sure you select the current tab in order to use the right video and audio. The recording is currently limited to 1GB, which is around 100 minutes.",
|
"localRecordingWarning": "Make sure you select the current tab in order to use the right video and audio. The recording is currently limited to 1GB, which is around 100 minutes.",
|
||||||
"loggedIn": "Logged in as {{userName}}",
|
"loggedIn": "Logged in as {{userName}}",
|
||||||
"off": "Recording stopped",
|
"off": "Recording stopped",
|
||||||
|
|
|
@ -143,7 +143,6 @@ export default [
|
||||||
'enableLayerSuspension',
|
'enableLayerSuspension',
|
||||||
'enableLipSync',
|
'enableLipSync',
|
||||||
'enableLobbyChat',
|
'enableLobbyChat',
|
||||||
'enableLocalRecording',
|
|
||||||
'enableOpusRed',
|
'enableOpusRed',
|
||||||
'enableRemb',
|
'enableRemb',
|
||||||
'enableSaveLogs',
|
'enableSaveLogs',
|
||||||
|
@ -185,6 +184,7 @@ export default [
|
||||||
'ignoreStartMuted',
|
'ignoreStartMuted',
|
||||||
'inviteAppName',
|
'inviteAppName',
|
||||||
'liveStreamingEnabled',
|
'liveStreamingEnabled',
|
||||||
|
'localRecording',
|
||||||
'localSubject',
|
'localSubject',
|
||||||
'maxFullResolutionParticipants',
|
'maxFullResolutionParticipants',
|
||||||
'mouseMoveCallbackInterval',
|
'mouseMoveCallbackInterval',
|
||||||
|
|
|
@ -178,9 +178,12 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
}
|
}
|
||||||
|
|
||||||
case SET_LOCAL_PARTICIPANT_RECORDING_STATUS: {
|
case SET_LOCAL_PARTICIPANT_RECORDING_STATUS: {
|
||||||
|
const state = store.getState();
|
||||||
const { recording } = action;
|
const { recording } = action;
|
||||||
const localId = getLocalParticipant(store.getState())?.id;
|
const localId = getLocalParticipant(state)?.id;
|
||||||
|
const { localRecording } = state['features/base/config'];
|
||||||
|
|
||||||
|
if (localRecording.notifyAllParticipants) {
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
// XXX Only the local participant is allowed to update without
|
// XXX Only the local participant is allowed to update without
|
||||||
// stating the JitsiConference instance (i.e. participant property
|
// stating the JitsiConference instance (i.e. participant property
|
||||||
|
@ -192,6 +195,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
local: true,
|
local: true,
|
||||||
localRecording: recording
|
localRecording: recording
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,11 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_localRecordingEnabled: boolean,
|
_localRecordingEnabled: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we won't notify the other participants about the recording.
|
||||||
|
*/
|
||||||
|
_localRecordingNoNotification: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color-schemed stylesheet of this component.
|
* The color-schemed stylesheet of this component.
|
||||||
*/
|
*/
|
||||||
|
@ -442,7 +447,8 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Container
|
<Container
|
||||||
className = 'recording-header'
|
className = { `recording-header ${this._shouldRenderNoIntegrationsContent()
|
||||||
|
? 'recording-header-line' : ''}` }
|
||||||
style = { styles.headerIntegrations }>
|
style = { styles.headerIntegrations }>
|
||||||
<Container
|
<Container
|
||||||
className = 'recording-icon-container'>
|
className = 'recording-icon-container'>
|
||||||
|
@ -609,7 +615,14 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
* @returns {React$Component}
|
* @returns {React$Component}
|
||||||
*/
|
*/
|
||||||
_renderLocalRecordingContent() {
|
_renderLocalRecordingContent() {
|
||||||
const { _styles: styles, isValidating, t, _dialogStyles, selectedRecordingService } = this.props;
|
const {
|
||||||
|
_styles: styles,
|
||||||
|
isValidating,
|
||||||
|
t,
|
||||||
|
_dialogStyles,
|
||||||
|
selectedRecordingService,
|
||||||
|
_localRecordingNoNotification
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!this._localRecordingAvailable) {
|
if (!this._localRecordingAvailable) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -645,9 +658,14 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
=== RECORDING_TYPES.LOCAL } />
|
=== RECORDING_TYPES.LOCAL } />
|
||||||
</Container>
|
</Container>
|
||||||
{selectedRecordingService === RECORDING_TYPES.LOCAL
|
{selectedRecordingService === RECORDING_TYPES.LOCAL
|
||||||
&& <Text className = 'local-recording-warning'>
|
&& <>
|
||||||
|
<Text className = 'local-recording-warning text'>
|
||||||
{t('recording.localRecordingWarning')}
|
{t('recording.localRecordingWarning')}
|
||||||
</Text>
|
</Text>
|
||||||
|
{_localRecordingNoNotification && <Text className = 'local-recording-warning notification'>
|
||||||
|
{t('recording.localRecordingNoNotificationWarning')}
|
||||||
|
</Text>}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
|
@ -689,7 +707,8 @@ function _mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
..._abstractMapStateToProps(state),
|
..._abstractMapStateToProps(state),
|
||||||
isVpaas: isVpaasMeeting(state),
|
isVpaas: isVpaasMeeting(state),
|
||||||
_localRecordingEnabled: state['features/base/config'].enableLocalRecording,
|
_localRecordingEnabled: state['features/base/config'].localRecording.enable,
|
||||||
|
_localRecordingNoNotification: !state['features/base/config'].localRecording.notifyAllParticipants,
|
||||||
_styles: ColorSchemeRegistry.get(state, 'StartRecordingDialogContent')
|
_styles: ColorSchemeRegistry.get(state, 'StartRecordingDialogContent')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,8 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
|
||||||
}
|
}
|
||||||
|
|
||||||
case START_LOCAL_RECORDING: {
|
case START_LOCAL_RECORDING: {
|
||||||
|
const { localRecording } = getState()['features/base/config'];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await LocalRecordingManager.startLocalRecording({ dispatch,
|
await LocalRecordingManager.startLocalRecording({ dispatch,
|
||||||
getState });
|
getState });
|
||||||
|
@ -140,9 +142,12 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
|
||||||
titleKey: 'dialog.recording'
|
titleKey: 'dialog.recording'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (localRecording.notifyAllParticipants) {
|
||||||
dispatch(playSound(RECORDING_ON_SOUND_ID));
|
dispatch(playSound(RECORDING_ON_SOUND_ID));
|
||||||
|
}
|
||||||
dispatch(showNotification(props, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
|
dispatch(showNotification(props, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
|
||||||
dispatch(updateLocalRecordingStatus(true));
|
dispatch(updateLocalRecordingStatus(true));
|
||||||
|
sendAnalytics(createRecordingEvent('started', 'local'));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Capture failed', err);
|
logger.error('Capture failed', err);
|
||||||
|
|
||||||
|
@ -158,10 +163,14 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
|
||||||
}
|
}
|
||||||
|
|
||||||
case STOP_LOCAL_RECORDING: {
|
case STOP_LOCAL_RECORDING: {
|
||||||
|
const { localRecording } = getState()['features/base/config'];
|
||||||
|
|
||||||
if (LocalRecordingManager.isRecordingLocally()) {
|
if (LocalRecordingManager.isRecordingLocally()) {
|
||||||
LocalRecordingManager.stopLocalRecording();
|
LocalRecordingManager.stopLocalRecording();
|
||||||
dispatch(playSound(RECORDING_OFF_SOUND_ID));
|
|
||||||
dispatch(updateLocalRecordingStatus(false));
|
dispatch(updateLocalRecordingStatus(false));
|
||||||
|
if (localRecording.notifyAllParticipants) {
|
||||||
|
dispatch(playSound(RECORDING_OFF_SOUND_ID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue