Add recording file sharing switch
This commit is contained in:
parent
2180d33e3d
commit
b7198ba4b3
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -515,6 +515,7 @@
|
||||||
"expandedOn": "The meeting is currently being recorded.",
|
"expandedOn": "The meeting is currently being recorded.",
|
||||||
"expandedPending": "Recording is being started...",
|
"expandedPending": "Recording is being started...",
|
||||||
"failedToStart": "Recording failed to start",
|
"failedToStart": "Recording failed to start",
|
||||||
|
"fileSharingdescription": "Share recording with meeting participants",
|
||||||
"live": "LIVE",
|
"live": "LIVE",
|
||||||
"loggedIn": "Logged in as __userName__",
|
"loggedIn": "Logged in as __userName__",
|
||||||
"off": "Recording stopped",
|
"off": "Recording stopped",
|
||||||
|
|
|
@ -243,5 +243,10 @@ ColorSchemeRegistry.register('Dialog', {
|
||||||
|
|
||||||
text: {
|
text: {
|
||||||
...brandedDialogText
|
...brandedDialogText
|
||||||
|
},
|
||||||
|
|
||||||
|
topBorderContainer: {
|
||||||
|
borderTopColor: schemeColor('border'),
|
||||||
|
borderTopWidth: 1
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,6 +31,12 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
_fileRecordingsServiceEnabled: boolean,
|
_fileRecordingsServiceEnabled: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to show the possibility to share file recording with other people (e.g. meeting participants), based on
|
||||||
|
* the actual implementation on the backend.
|
||||||
|
*/
|
||||||
|
_fileRecordingsServiceSharingEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true the dropbox integration is enabled, otherwise - disabled.
|
* If true the dropbox integration is enabled, otherwise - disabled.
|
||||||
*/
|
*/
|
||||||
|
@ -69,6 +75,11 @@ type State = {
|
||||||
*/
|
*/
|
||||||
selectedRecordingService: ?string,
|
selectedRecordingService: ?string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the user requested the service to share the recording with others.
|
||||||
|
*/
|
||||||
|
sharingEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of MiB of available space in user's Dropbox account.
|
* Number of MiB of available space in user's Dropbox account.
|
||||||
*/
|
*/
|
||||||
|
@ -96,6 +107,7 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
this._onSubmit = this._onSubmit.bind(this);
|
this._onSubmit = this._onSubmit.bind(this);
|
||||||
this._onSelectedRecordingServiceChanged
|
this._onSelectedRecordingServiceChanged
|
||||||
= this._onSelectedRecordingServiceChanged.bind(this);
|
= this._onSelectedRecordingServiceChanged.bind(this);
|
||||||
|
this._onSharingSettingChanged = this._onSharingSettingChanged.bind(this);
|
||||||
|
|
||||||
let selectedRecordingService;
|
let selectedRecordingService;
|
||||||
|
|
||||||
|
@ -112,6 +124,7 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
isTokenValid: false,
|
isTokenValid: false,
|
||||||
isValidating: false,
|
isValidating: false,
|
||||||
userName: undefined,
|
userName: undefined,
|
||||||
|
sharingEnabled: true,
|
||||||
spaceLeft: undefined,
|
spaceLeft: undefined,
|
||||||
selectedRecordingService
|
selectedRecordingService
|
||||||
};
|
};
|
||||||
|
@ -154,6 +167,19 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
return this.props._isDropboxEnabled;
|
return this.props._isDropboxEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSharingSettingChanged: () => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to handle sharing setting change from the dialog.
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
_onSharingSettingChanged() {
|
||||||
|
this.setState({
|
||||||
|
sharingEnabled: !this.state.sharingEnabled
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_onSelectedRecordingServiceChanged: (string) => void;
|
_onSelectedRecordingServiceChanged: (string) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,6 +259,11 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
});
|
});
|
||||||
attributes.type = RECORDING_TYPES.DROPBOX;
|
attributes.type = RECORDING_TYPES.DROPBOX;
|
||||||
} else {
|
} else {
|
||||||
|
appData = JSON.stringify({
|
||||||
|
'file_recording_metadata': {
|
||||||
|
'share': this.state.sharingEnabled
|
||||||
|
}
|
||||||
|
});
|
||||||
attributes.type = RECORDING_TYPES.JITSI_REC_SERVICE;
|
attributes.type = RECORDING_TYPES.JITSI_REC_SERVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,12 +297,16 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
* @returns {{
|
* @returns {{
|
||||||
* _appKey: string,
|
* _appKey: string,
|
||||||
* _conference: JitsiConference,
|
* _conference: JitsiConference,
|
||||||
|
* _fileRecordingsServiceEnabled: boolean,
|
||||||
|
* _fileRecordingsServiceSharingEnabled: boolean,
|
||||||
|
* _isDropboxEnabled: boolean,
|
||||||
* _token: string
|
* _token: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function mapStateToProps(state: Object) {
|
export function mapStateToProps(state: Object) {
|
||||||
const {
|
const {
|
||||||
fileRecordingsServiceEnabled = false,
|
fileRecordingsServiceEnabled = false,
|
||||||
|
fileRecordingsServiceSharingEnabled = false,
|
||||||
dropbox = {}
|
dropbox = {}
|
||||||
} = state['features/base/config'];
|
} = state['features/base/config'];
|
||||||
|
|
||||||
|
@ -279,6 +314,7 @@ export function mapStateToProps(state: Object) {
|
||||||
_appKey: dropbox.appKey,
|
_appKey: dropbox.appKey,
|
||||||
_conference: state['features/base/conference'].conference,
|
_conference: state['features/base/conference'].conference,
|
||||||
_fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
|
_fileRecordingsServiceEnabled: fileRecordingsServiceEnabled,
|
||||||
|
_fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled,
|
||||||
_isDropboxEnabled: isDropboxEnabled(state),
|
_isDropboxEnabled: isDropboxEnabled(state),
|
||||||
_token: state['features/dropbox'].token
|
_token: state['features/dropbox'].token
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { authorizeDropbox, updateDropboxToken } from '../../../dropbox';
|
||||||
import {
|
import {
|
||||||
default as styles,
|
default as styles,
|
||||||
DROPBOX_LOGO,
|
DROPBOX_LOGO,
|
||||||
|
ICON_SHARE,
|
||||||
JITSI_LOGO
|
JITSI_LOGO
|
||||||
} from './styles';
|
} from './styles';
|
||||||
|
|
||||||
|
@ -49,6 +50,12 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
fileRecordingsServiceEnabled: boolean,
|
fileRecordingsServiceEnabled: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to show the possibility to share file recording with other people (e.g. meeting participants), based on
|
||||||
|
* the actual implementation on the backend.
|
||||||
|
*/
|
||||||
|
fileRecordingsServiceSharingEnabled: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true the content related to the integrations will be shown.
|
* If true the content related to the integrations will be shown.
|
||||||
*/
|
*/
|
||||||
|
@ -70,11 +77,21 @@ type Props = {
|
||||||
*/
|
*/
|
||||||
onChange: Function,
|
onChange: Function,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to be invoked on sharing setting change.
|
||||||
|
*/
|
||||||
|
onSharingSettingChanged: Function,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The currently selected recording service of type: RECORDING_TYPES.
|
* The currently selected recording service of type: RECORDING_TYPES.
|
||||||
*/
|
*/
|
||||||
selectedRecordingService: ?string,
|
selectedRecordingService: ?string,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean to set file recording sharing on or off.
|
||||||
|
*/
|
||||||
|
sharingSetting: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of MiB of available space in user's Dropbox account.
|
* Number of MiB of available space in user's Dropbox account.
|
||||||
*/
|
*/
|
||||||
|
@ -131,6 +148,60 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the file recording service sharing options, if enabled.
|
||||||
|
*
|
||||||
|
* @returns {React$Component}
|
||||||
|
*/
|
||||||
|
_renderFileSharingContent() {
|
||||||
|
if (!this.props.fileRecordingsServiceSharingEnabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
_dialogStyles,
|
||||||
|
isValidating,
|
||||||
|
onSharingSettingChanged,
|
||||||
|
selectedRecordingService,
|
||||||
|
sharingSetting, t } = this.props;
|
||||||
|
|
||||||
|
const controlDisabled = selectedRecordingService !== RECORDING_TYPES.JITSI_REC_SERVICE;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container
|
||||||
|
className = 'recording-header'
|
||||||
|
key = 'fileSharingSetting'
|
||||||
|
style = { [
|
||||||
|
styles.header,
|
||||||
|
_dialogStyles.topBorderContainer,
|
||||||
|
controlDisabled ? styles.controlDisabled : null
|
||||||
|
] }>
|
||||||
|
<Container className = 'recording-icon-container'>
|
||||||
|
<Image
|
||||||
|
className = 'recording-icon'
|
||||||
|
src = { ICON_SHARE }
|
||||||
|
style = { styles.recordingIcon } />
|
||||||
|
</Container>
|
||||||
|
<Text
|
||||||
|
className = 'recording-title'
|
||||||
|
style = {{
|
||||||
|
..._dialogStyles.text,
|
||||||
|
...styles.title
|
||||||
|
}}>
|
||||||
|
{ t('recording.fileSharingdescription') }
|
||||||
|
</Text>
|
||||||
|
<Switch
|
||||||
|
className = 'recording-switch'
|
||||||
|
disabled = { controlDisabled || isValidating }
|
||||||
|
onValueChange
|
||||||
|
= { onSharingSettingChanged }
|
||||||
|
style = { styles.switch }
|
||||||
|
trackColor = {{ false: ColorPalette.lightGrey }}
|
||||||
|
value = { !controlDisabled && sharingSetting } />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the content in case no integrations were enabled.
|
* Renders the content in case no integrations were enabled.
|
||||||
*
|
*
|
||||||
|
@ -162,9 +233,10 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
=== RECORDING_TYPES.JITSI_REC_SERVICE } />
|
=== RECORDING_TYPES.JITSI_REC_SERVICE } />
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
return (
|
return [
|
||||||
<Container
|
<Container
|
||||||
className = 'recording-header'
|
className = 'recording-header'
|
||||||
|
key = 'noIntegrationSetting'
|
||||||
style = { styles.header }>
|
style = { styles.header }>
|
||||||
<Container className = 'recording-icon-container'>
|
<Container className = 'recording-icon-container'>
|
||||||
<Image
|
<Image
|
||||||
|
@ -181,8 +253,9 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
{ t('recording.serviceDescription') }
|
{ t('recording.serviceDescription') }
|
||||||
</Text>
|
</Text>
|
||||||
{ switchContent }
|
{ switchContent }
|
||||||
</Container>
|
</Container>,
|
||||||
);
|
this._renderFileSharingContent()
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,6 +340,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
className = 'authorization-panel'>
|
className = 'authorization-panel'>
|
||||||
{ content }
|
{ content }
|
||||||
</Container>
|
</Container>
|
||||||
|
{ this._renderFileSharingContent() }
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
isTokenValid,
|
isTokenValid,
|
||||||
isValidating,
|
isValidating,
|
||||||
selectedRecordingService,
|
selectedRecordingService,
|
||||||
|
sharingEnabled,
|
||||||
spaceLeft,
|
spaceLeft,
|
||||||
userName
|
userName
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { _fileRecordingsServiceEnabled, _isDropboxEnabled } = this.props;
|
const {
|
||||||
|
_fileRecordingsServiceEnabled,
|
||||||
|
_fileRecordingsServiceSharingEnabled,
|
||||||
|
_isDropboxEnabled
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
// disable ok button id recording service is shown only, when
|
// disable ok button id recording service is shown only, when
|
||||||
// validating dropbox token, if that is not enabled we either always
|
// validating dropbox token, if that is not enabled we either always
|
||||||
|
@ -46,13 +51,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
okDisabled = { isOkDisabled }
|
okDisabled = { isOkDisabled }
|
||||||
onSubmit = { this._onSubmit } >
|
onSubmit = { this._onSubmit } >
|
||||||
<StartRecordingDialogContent
|
<StartRecordingDialogContent
|
||||||
fileRecordingsServiceEnabled
|
fileRecordingsServiceEnabled = { _fileRecordingsServiceEnabled }
|
||||||
= { _fileRecordingsServiceEnabled }
|
fileRecordingsServiceSharingEnabled = { _fileRecordingsServiceSharingEnabled }
|
||||||
integrationsEnabled = { this._areIntegrationsEnabled() }
|
integrationsEnabled = { this._areIntegrationsEnabled() }
|
||||||
isTokenValid = { isTokenValid }
|
isTokenValid = { isTokenValid }
|
||||||
isValidating = { isValidating }
|
isValidating = { isValidating }
|
||||||
onChange = { this._onSelectedRecordingServiceChanged }
|
onChange = { this._onSelectedRecordingServiceChanged }
|
||||||
|
onSharingSettingChanged = { this._onSharingSettingChanged }
|
||||||
selectedRecordingService = { selectedRecordingService }
|
selectedRecordingService = { selectedRecordingService }
|
||||||
|
sharingSetting = { sharingEnabled }
|
||||||
spaceLeft = { spaceLeft }
|
spaceLeft = { spaceLeft }
|
||||||
userName = { userName } />
|
userName = { userName } />
|
||||||
</CustomSubmitDialog>
|
</CustomSubmitDialog>
|
||||||
|
@ -62,6 +69,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
_areIntegrationsEnabled: () => boolean;
|
_areIntegrationsEnabled: () => boolean;
|
||||||
_onSubmit: () => boolean
|
_onSubmit: () => boolean
|
||||||
_onSelectedRecordingServiceChanged: (string) => void;
|
_onSelectedRecordingServiceChanged: (string) => void;
|
||||||
|
_onSharingSettingChanged: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
||||||
|
|
|
@ -1,26 +1,30 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { BoxModel, createStyleSheet, ColorPalette } from '../../../base/styles';
|
import { BoxModel, ColorPalette } from '../../../base/styles';
|
||||||
|
|
||||||
// XXX The "standard" {@code BoxModel.padding} has been deemed insufficient in
|
// XXX The "standard" {@code BoxModel.padding} has been deemed insufficient in
|
||||||
// the special case(s) of the recording feature bellow.
|
// the special case(s) of the recording feature bellow.
|
||||||
const _PADDING = BoxModel.padding * 1.5;
|
const _PADDING = BoxModel.padding * 1.5;
|
||||||
|
|
||||||
export const DROPBOX_LOGO
|
export const DROPBOX_LOGO = require('../../../../../images/dropboxLogo_square.png');
|
||||||
= require('../../../../../images/dropboxLogo_square.png');
|
|
||||||
|
|
||||||
export const JITSI_LOGO
|
export const ICON_SHARE = require('../../../../../images/icon-users.png');
|
||||||
= require('../../../../../images/jitsiLogo_square.png');
|
|
||||||
|
export const JITSI_LOGO = require('../../../../../images/jitsiLogo_square.png');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The styles of the React {@code Components} of the feature recording.
|
* The styles of the React {@code Components} of the feature recording.
|
||||||
*/
|
*/
|
||||||
export default createStyleSheet({
|
export default {
|
||||||
container: {
|
container: {
|
||||||
flex: 0,
|
flex: 0,
|
||||||
flexDirection: 'column'
|
flexDirection: 'column'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
controlDisabled: {
|
||||||
|
opacity: 0.5
|
||||||
|
},
|
||||||
|
|
||||||
header: {
|
header: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flex: 0,
|
flex: 0,
|
||||||
|
@ -62,4 +66,4 @@ export default createStyleSheet({
|
||||||
text: {
|
text: {
|
||||||
color: ColorPalette.white
|
color: ColorPalette.white
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
|
@ -4,4 +4,6 @@ export default {};
|
||||||
|
|
||||||
export const DROPBOX_LOGO = 'images/dropboxLogo_square.png';
|
export const DROPBOX_LOGO = 'images/dropboxLogo_square.png';
|
||||||
|
|
||||||
|
export const ICON_SHARE = 'images/icon-users.png';
|
||||||
|
|
||||||
export const JITSI_LOGO = 'images/jitsiLogo_square.png';
|
export const JITSI_LOGO = 'images/jitsiLogo_square.png';
|
||||||
|
|
|
@ -28,10 +28,11 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
isTokenValid,
|
isTokenValid,
|
||||||
isValidating,
|
isValidating,
|
||||||
selectedRecordingService,
|
selectedRecordingService,
|
||||||
|
sharingEnabled,
|
||||||
spaceLeft,
|
spaceLeft,
|
||||||
userName
|
userName
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { _fileRecordingsServiceEnabled, _isDropboxEnabled } = this.props;
|
const { _fileRecordingsServiceEnabled, _fileRecordingsServiceSharingEnabled, _isDropboxEnabled } = this.props;
|
||||||
|
|
||||||
// disable ok button id recording service is shown only, when
|
// disable ok button id recording service is shown only, when
|
||||||
// validating dropbox token, if that is not enabled we either always
|
// validating dropbox token, if that is not enabled we either always
|
||||||
|
@ -49,13 +50,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
titleKey = 'dialog.startRecording'
|
titleKey = 'dialog.startRecording'
|
||||||
width = 'small'>
|
width = 'small'>
|
||||||
<StartRecordingDialogContent
|
<StartRecordingDialogContent
|
||||||
fileRecordingsServiceEnabled
|
fileRecordingsServiceEnabled = { _fileRecordingsServiceEnabled }
|
||||||
= { _fileRecordingsServiceEnabled }
|
fileRecordingsServiceSharingEnabled = { _fileRecordingsServiceSharingEnabled }
|
||||||
integrationsEnabled = { this._areIntegrationsEnabled() }
|
integrationsEnabled = { this._areIntegrationsEnabled() }
|
||||||
isTokenValid = { isTokenValid }
|
isTokenValid = { isTokenValid }
|
||||||
isValidating = { isValidating }
|
isValidating = { isValidating }
|
||||||
onChange = { this._onSelectedRecordingServiceChanged }
|
onChange = { this._onSelectedRecordingServiceChanged }
|
||||||
|
onSharingSettingChanged = { this._onSharingSettingChanged }
|
||||||
selectedRecordingService = { selectedRecordingService }
|
selectedRecordingService = { selectedRecordingService }
|
||||||
|
sharingSetting = { sharingEnabled }
|
||||||
spaceLeft = { spaceLeft }
|
spaceLeft = { spaceLeft }
|
||||||
userName = { userName } />
|
userName = { userName } />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
@ -65,6 +68,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
_areIntegrationsEnabled: () => boolean;
|
_areIntegrationsEnabled: () => boolean;
|
||||||
_onSubmit: () => boolean;
|
_onSubmit: () => boolean;
|
||||||
_onSelectedRecordingServiceChanged: (string) => void;
|
_onSelectedRecordingServiceChanged: (string) => void;
|
||||||
|
_onSharingSettingChanged: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
||||||
|
|
Loading…
Reference in New Issue