Add recording file sharing switch

This commit is contained in:
Bettenbuk Zoltan 2019-04-23 14:30:46 +02:00 committed by Дамян Минков
parent 2180d33e3d
commit b7198ba4b3
9 changed files with 150 additions and 16 deletions

BIN
images/icon-users.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -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",

View File

@ -243,5 +243,10 @@ ColorSchemeRegistry.register('Dialog', {
text: {
...brandedDialogText
},
topBorderContainer: {
borderTopColor: schemeColor('border'),
borderTopWidth: 1
}
});

View File

@ -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<Props, State> {
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<Props, State> {
isTokenValid: false,
isValidating: false,
userName: undefined,
sharingEnabled: true,
spaceLeft: undefined,
selectedRecordingService
};
@ -154,6 +167,19 @@ class AbstractStartRecordingDialog extends Component<Props, State> {
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<Props, State> {
});
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<Props, State> {
* @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
};

View File

@ -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<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.
*
@ -162,9 +233,10 @@ class StartRecordingDialogContent extends Component<Props> {
=== RECORDING_TYPES.JITSI_REC_SERVICE } />
) : null;
return (
return [
<Container
className = 'recording-header'
key = 'noIntegrationSetting'
style = { styles.header }>
<Container className = 'recording-icon-container'>
<Image
@ -181,8 +253,9 @@ class StartRecordingDialogContent extends Component<Props> {
{ t('recording.serviceDescription') }
</Text>
{ switchContent }
</Container>
);
</Container>,
this._renderFileSharingContent()
];
}
/**
@ -267,6 +340,7 @@ class StartRecordingDialogContent extends Component<Props> {
className = 'authorization-panel'>
{ content }
</Container>
{ this._renderFileSharingContent() }
</Container>
);
}

View File

@ -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 } >
<StartRecordingDialogContent
fileRecordingsServiceEnabled
= { _fileRecordingsServiceEnabled }
fileRecordingsServiceEnabled = { _fileRecordingsServiceEnabled }
fileRecordingsServiceSharingEnabled = { _fileRecordingsServiceSharingEnabled }
integrationsEnabled = { this._areIntegrationsEnabled() }
isTokenValid = { isTokenValid }
isValidating = { isValidating }
onChange = { this._onSelectedRecordingServiceChanged }
onSharingSettingChanged = { this._onSharingSettingChanged }
selectedRecordingService = { selectedRecordingService }
sharingSetting = { sharingEnabled }
spaceLeft = { spaceLeft }
userName = { userName } />
</CustomSubmitDialog>
@ -62,6 +69,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
_areIntegrationsEnabled: () => boolean;
_onSubmit: () => boolean
_onSelectedRecordingServiceChanged: (string) => void;
_onSharingSettingChanged: () => void;
}
export default translate(connect(mapStateToProps)(StartRecordingDialog));

View File

@ -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
}
});
};

View File

@ -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';

View File

@ -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'>
<StartRecordingDialogContent
fileRecordingsServiceEnabled
= { _fileRecordingsServiceEnabled }
fileRecordingsServiceEnabled = { _fileRecordingsServiceEnabled }
fileRecordingsServiceSharingEnabled = { _fileRecordingsServiceSharingEnabled }
integrationsEnabled = { this._areIntegrationsEnabled() }
isTokenValid = { isTokenValid }
isValidating = { isValidating }
onChange = { this._onSelectedRecordingServiceChanged }
onSharingSettingChanged = { this._onSharingSettingChanged }
selectedRecordingService = { selectedRecordingService }
sharingSetting = { sharingEnabled }
spaceLeft = { spaceLeft }
userName = { userName } />
</Dialog>
@ -65,6 +68,7 @@ class StartRecordingDialog extends AbstractStartRecordingDialog {
_areIntegrationsEnabled: () => boolean;
_onSubmit: () => boolean;
_onSelectedRecordingServiceChanged: (string) => void;
_onSharingSettingChanged: () => void;
}
export default translate(connect(mapStateToProps)(StartRecordingDialog));