diff --git a/images/icon-users.png b/images/icon-users.png new file mode 100644 index 000000000..094495343 Binary files /dev/null and b/images/icon-users.png differ diff --git a/lang/main.json b/lang/main.json index 799920102..34732f634 100644 --- a/lang/main.json +++ b/lang/main.json @@ -515,6 +515,7 @@ "expandedOn": "The meeting is currently being recorded.", "expandedPending": "Recording is being started...", "failedToStart": "Recording failed to start", + "fileSharingdescription": "Share recording with meeting participants", "live": "LIVE", "loggedIn": "Logged in as __userName__", "off": "Recording stopped", diff --git a/react/features/base/dialog/components/native/styles.js b/react/features/base/dialog/components/native/styles.js index 60c11294d..daad37f3d 100644 --- a/react/features/base/dialog/components/native/styles.js +++ b/react/features/base/dialog/components/native/styles.js @@ -243,5 +243,10 @@ ColorSchemeRegistry.register('Dialog', { text: { ...brandedDialogText + }, + + topBorderContainer: { + borderTopColor: schemeColor('border'), + borderTopWidth: 1 } }); diff --git a/react/features/recording/components/Recording/AbstractStartRecordingDialog.js b/react/features/recording/components/Recording/AbstractStartRecordingDialog.js index 8bd752377..b7ffe21c1 100644 --- a/react/features/recording/components/Recording/AbstractStartRecordingDialog.js +++ b/react/features/recording/components/Recording/AbstractStartRecordingDialog.js @@ -31,6 +31,12 @@ type Props = { */ _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. */ @@ -69,6 +75,11 @@ type State = { */ 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. */ @@ -96,6 +107,7 @@ class AbstractStartRecordingDialog extends Component { this._onSubmit = this._onSubmit.bind(this); this._onSelectedRecordingServiceChanged = this._onSelectedRecordingServiceChanged.bind(this); + this._onSharingSettingChanged = this._onSharingSettingChanged.bind(this); let selectedRecordingService; @@ -112,6 +124,7 @@ class AbstractStartRecordingDialog extends Component { isTokenValid: false, isValidating: false, userName: undefined, + sharingEnabled: true, spaceLeft: undefined, selectedRecordingService }; @@ -154,6 +167,19 @@ class AbstractStartRecordingDialog extends Component { 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; /** @@ -233,6 +259,11 @@ class AbstractStartRecordingDialog extends Component { }); attributes.type = RECORDING_TYPES.DROPBOX; } else { + appData = JSON.stringify({ + 'file_recording_metadata': { + 'share': this.state.sharingEnabled + } + }); attributes.type = RECORDING_TYPES.JITSI_REC_SERVICE; } @@ -266,12 +297,16 @@ class AbstractStartRecordingDialog extends Component { * @returns {{ * _appKey: string, * _conference: JitsiConference, + * _fileRecordingsServiceEnabled: boolean, + * _fileRecordingsServiceSharingEnabled: boolean, + * _isDropboxEnabled: boolean, * _token: string * }} */ export function mapStateToProps(state: Object) { const { fileRecordingsServiceEnabled = false, + fileRecordingsServiceSharingEnabled = false, dropbox = {} } = state['features/base/config']; @@ -279,6 +314,7 @@ export function mapStateToProps(state: Object) { _appKey: dropbox.appKey, _conference: state['features/base/conference'].conference, _fileRecordingsServiceEnabled: fileRecordingsServiceEnabled, + _fileRecordingsServiceSharingEnabled: fileRecordingsServiceSharingEnabled, _isDropboxEnabled: isDropboxEnabled(state), _token: state['features/dropbox'].token }; diff --git a/react/features/recording/components/Recording/StartRecordingDialogContent.js b/react/features/recording/components/Recording/StartRecordingDialogContent.js index 5c1e42091..ac555a5a4 100644 --- a/react/features/recording/components/Recording/StartRecordingDialogContent.js +++ b/react/features/recording/components/Recording/StartRecordingDialogContent.js @@ -25,6 +25,7 @@ import { authorizeDropbox, updateDropboxToken } from '../../../dropbox'; import { default as styles, DROPBOX_LOGO, + ICON_SHARE, JITSI_LOGO } from './styles'; @@ -49,6 +50,12 @@ type Props = { */ 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. */ @@ -70,11 +77,21 @@ type Props = { */ onChange: Function, + /** + * Callback to be invoked on sharing setting change. + */ + onSharingSettingChanged: Function, + /** * The currently selected recording service of type: RECORDING_TYPES. */ selectedRecordingService: ?string, + /** + * Boolean to set file recording sharing on or off. + */ + sharingSetting: boolean, + /** * Number of MiB of available space in user's Dropbox account. */ @@ -131,6 +148,60 @@ class StartRecordingDialogContent extends Component { ); } + /** + * 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 ( + + + + + + { t('recording.fileSharingdescription') } + + + + ); + } + /** * Renders the content in case no integrations were enabled. * @@ -162,9 +233,10 @@ class StartRecordingDialogContent extends Component { === RECORDING_TYPES.JITSI_REC_SERVICE } /> ) : null; - return ( + return [ { { t('recording.serviceDescription') } { switchContent } - - ); + , + this._renderFileSharingContent() + ]; } /** @@ -267,6 +340,7 @@ class StartRecordingDialogContent extends Component { className = 'authorization-panel'> { content } + { this._renderFileSharingContent() } ); } diff --git a/react/features/recording/components/Recording/native/StartRecordingDialog.js b/react/features/recording/components/Recording/native/StartRecordingDialog.js index 54593d142..fb79e3efd 100644 --- a/react/features/recording/components/Recording/native/StartRecordingDialog.js +++ b/react/features/recording/components/Recording/native/StartRecordingDialog.js @@ -28,10 +28,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { isTokenValid, isValidating, selectedRecordingService, + sharingEnabled, spaceLeft, userName } = this.state; - const { _fileRecordingsServiceEnabled, _isDropboxEnabled } = this.props; + const { + _fileRecordingsServiceEnabled, + _fileRecordingsServiceSharingEnabled, + _isDropboxEnabled + } = this.props; // disable ok button id recording service is shown only, when // validating dropbox token, if that is not enabled we either always @@ -46,13 +51,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { okDisabled = { isOkDisabled } onSubmit = { this._onSubmit } > @@ -62,6 +69,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { _areIntegrationsEnabled: () => boolean; _onSubmit: () => boolean _onSelectedRecordingServiceChanged: (string) => void; + _onSharingSettingChanged: () => void; } export default translate(connect(mapStateToProps)(StartRecordingDialog)); diff --git a/react/features/recording/components/Recording/styles.native.js b/react/features/recording/components/Recording/styles.native.js index 9c0d0bc30..c4fe92a1c 100644 --- a/react/features/recording/components/Recording/styles.native.js +++ b/react/features/recording/components/Recording/styles.native.js @@ -1,26 +1,30 @@ // @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 // the special case(s) of the recording feature bellow. const _PADDING = BoxModel.padding * 1.5; -export const DROPBOX_LOGO - = require('../../../../../images/dropboxLogo_square.png'); +export const DROPBOX_LOGO = require('../../../../../images/dropboxLogo_square.png'); -export const JITSI_LOGO - = require('../../../../../images/jitsiLogo_square.png'); +export const ICON_SHARE = require('../../../../../images/icon-users.png'); + +export const JITSI_LOGO = require('../../../../../images/jitsiLogo_square.png'); /** * The styles of the React {@code Components} of the feature recording. */ -export default createStyleSheet({ +export default { container: { flex: 0, flexDirection: 'column' }, + controlDisabled: { + opacity: 0.5 + }, + header: { alignItems: 'center', flex: 0, @@ -62,4 +66,4 @@ export default createStyleSheet({ text: { color: ColorPalette.white } -}); +}; diff --git a/react/features/recording/components/Recording/styles.web.js b/react/features/recording/components/Recording/styles.web.js index 26854766b..1b8318589 100644 --- a/react/features/recording/components/Recording/styles.web.js +++ b/react/features/recording/components/Recording/styles.web.js @@ -4,4 +4,6 @@ export default {}; export const DROPBOX_LOGO = 'images/dropboxLogo_square.png'; +export const ICON_SHARE = 'images/icon-users.png'; + export const JITSI_LOGO = 'images/jitsiLogo_square.png'; diff --git a/react/features/recording/components/Recording/web/StartRecordingDialog.js b/react/features/recording/components/Recording/web/StartRecordingDialog.js index 8f63fa8e9..b8453572b 100644 --- a/react/features/recording/components/Recording/web/StartRecordingDialog.js +++ b/react/features/recording/components/Recording/web/StartRecordingDialog.js @@ -28,10 +28,11 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { isTokenValid, isValidating, selectedRecordingService, + sharingEnabled, spaceLeft, userName } = this.state; - const { _fileRecordingsServiceEnabled, _isDropboxEnabled } = this.props; + const { _fileRecordingsServiceEnabled, _fileRecordingsServiceSharingEnabled, _isDropboxEnabled } = this.props; // disable ok button id recording service is shown only, when // validating dropbox token, if that is not enabled we either always @@ -49,13 +50,15 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { titleKey = 'dialog.startRecording' width = 'small'> @@ -65,6 +68,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog { _areIntegrationsEnabled: () => boolean; _onSubmit: () => boolean; _onSelectedRecordingServiceChanged: (string) => void; + _onSharingSettingChanged: () => void; } export default translate(connect(mapStateToProps)(StartRecordingDialog));