[RN] Make feature dialogs branded: recording
This commit is contained in:
parent
4bc09dd8b9
commit
62e7fd7e8e
|
@ -3,6 +3,7 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import { Container, Text } from '../../react';
|
import { Container, Text } from '../../react';
|
||||||
|
import { type StyleType } from '../../styles';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
@ -11,7 +12,9 @@ type Props = {
|
||||||
/**
|
/**
|
||||||
* Children of the component.
|
* Children of the component.
|
||||||
*/
|
*/
|
||||||
children: string | React$Node
|
children: string | React$Node,
|
||||||
|
|
||||||
|
style: ?StyleType
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,10 +28,10 @@ export default class DialogContent extends Component<Props> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const { children, style } = this.props;
|
||||||
|
|
||||||
const childrenComponent = typeof children === 'string'
|
const childrenComponent = typeof children === 'string'
|
||||||
? <Text>{ children }</Text>
|
? <Text style = { style }>{ children }</Text>
|
||||||
: children;
|
: children;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -38,6 +38,7 @@ export default createStyleSheet({
|
||||||
borderColor: ColorPalette.lightGrey,
|
borderColor: ColorPalette.lightGrey,
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
|
color: ColorPalette.white,
|
||||||
height: BUTTON_HEIGHT,
|
height: BUTTON_HEIGHT,
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import { Component } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createRecordingDialogEvent,
|
createRecordingDialogEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
} from '../../../analytics';
|
} from '../../../analytics';
|
||||||
import { Dialog } from '../../../base/dialog';
|
|
||||||
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,27 +139,6 @@ export default class AbstractStartLiveStreamDialog<P: Props>
|
||||||
this._isMounted = false;
|
this._isMounted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements {@code Component}'s render.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
cancelTitleKey = 'dialog.Cancel'
|
|
||||||
okTitleKey = 'dialog.startLiveStreaming'
|
|
||||||
onCancel = { this._onCancel }
|
|
||||||
onSubmit = { this._onSubmit }
|
|
||||||
titleKey = 'liveStreaming.start'
|
|
||||||
width = { 'small' }>
|
|
||||||
{
|
|
||||||
this._renderDialogContent()
|
|
||||||
}
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onCancel: () => boolean;
|
_onCancel: () => boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,13 +235,6 @@ export default class AbstractStartLiveStreamDialog<P: Props>
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the platform specific dialog content.
|
|
||||||
*
|
|
||||||
* @returns {React$Component}
|
|
||||||
*/
|
|
||||||
_renderDialogContent: () => React$Component<*>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import { Component } from 'react';
|
||||||
|
|
||||||
import { Dialog } from '../../../base/dialog';
|
|
||||||
import {
|
import {
|
||||||
createRecordingDialogEvent,
|
createRecordingDialogEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
|
@ -53,24 +52,6 @@ export default class AbstractStopLiveStreamDialog extends Component<Props> {
|
||||||
this._onSubmit = this._onSubmit.bind(this);
|
this._onSubmit = this._onSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
okTitleKey = 'dialog.stopLiveStreaming'
|
|
||||||
onSubmit = { this._onSubmit }
|
|
||||||
titleKey = 'dialog.liveStreaming'
|
|
||||||
width = 'small'>
|
|
||||||
{ this._renderDialogContent() }
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSubmit: () => boolean;
|
_onSubmit: () => boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,14 +71,6 @@ export default class AbstractStopLiveStreamDialog extends Component<Props> {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to be implemented by the platform specific implementations.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {React$Component<*>}
|
|
||||||
*/
|
|
||||||
_renderDialogContent: () => React$Component<*>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -126,14 +126,16 @@ class GoogleSigninForm extends Component<Props> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userInfo = signedInUser
|
||||||
|
? `${t('liveStreaming.signedInAs')} ${signedInUser}`
|
||||||
|
: t('liveStreaming.signInCTA');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style = { styles.formWrapper }>
|
<View style = { styles.formWrapper }>
|
||||||
<View style = { styles.helpText }>
|
<View style = { styles.helpText }>
|
||||||
{ signedInUser ? <Text>
|
<Text style = { styles.text }>
|
||||||
{ `${t('liveStreaming.signedInAs')} ${signedInUser}` }
|
{ userInfo }
|
||||||
</Text> : <Text>
|
</Text>
|
||||||
{ t('liveStreaming.signInCTA') }
|
|
||||||
</Text> }
|
|
||||||
</View>
|
</View>
|
||||||
<GoogleSignInButton
|
<GoogleSignInButton
|
||||||
onClick = { this._onGoogleButtonPress }
|
onClick = { this._onGoogleButtonPress }
|
||||||
|
|
|
@ -4,6 +4,7 @@ import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { CustomSubmitDialog } from '../../../../base/dialog';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
import { googleApi } from '../../../../google-api';
|
import { googleApi } from '../../../../google-api';
|
||||||
|
|
||||||
|
@ -36,9 +37,39 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
|
||||||
= this._onStreamKeyChangeNative.bind(this);
|
= this._onStreamKeyChangeNative.bind(this);
|
||||||
this._onStreamKeyPick = this._onStreamKeyPick.bind(this);
|
this._onStreamKeyPick = this._onStreamKeyPick.bind(this);
|
||||||
this._onUserChanged = this._onUserChanged.bind(this);
|
this._onUserChanged = this._onUserChanged.bind(this);
|
||||||
this._renderDialogContent = this._renderDialogContent.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@code Component}'s render.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<CustomSubmitDialog
|
||||||
|
okTitleKey = 'dialog.startLiveStreaming'
|
||||||
|
onCancel = { this._onCancel }
|
||||||
|
onSubmit = { this._onSubmit } >
|
||||||
|
<View style = { styles.startDialogWrapper }>
|
||||||
|
<GoogleSigninForm
|
||||||
|
onUserChanged = { this._onUserChanged } />
|
||||||
|
<StreamKeyPicker
|
||||||
|
broadcasts = { this.state.broadcasts }
|
||||||
|
onChange = { this._onStreamKeyPick } />
|
||||||
|
<StreamKeyForm
|
||||||
|
onChange = { this._onStreamKeyChangeNative }
|
||||||
|
value = {
|
||||||
|
this.state.streamKey || this.props._streamKey
|
||||||
|
} />
|
||||||
|
</View>
|
||||||
|
</CustomSubmitDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onCancel: () => boolean;
|
||||||
|
|
||||||
|
_onSubmit: () => boolean;
|
||||||
|
|
||||||
_onStreamKeyChange: string => void
|
_onStreamKeyChange: string => void
|
||||||
|
|
||||||
_onStreamKeyChangeNative: string => void;
|
_onStreamKeyChangeNative: string => void;
|
||||||
|
@ -102,29 +133,6 @@ class StartLiveStreamDialog extends AbstractStartLiveStreamDialog<Props> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderDialogContent: () => React$Component<*>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the platform specific dialog content.
|
|
||||||
*
|
|
||||||
* @returns {React$Component}
|
|
||||||
*/
|
|
||||||
_renderDialogContent() {
|
|
||||||
return (
|
|
||||||
<View style = { styles.startDialogWrapper }>
|
|
||||||
<GoogleSigninForm
|
|
||||||
onUserChanged = { this._onUserChanged } />
|
|
||||||
<StreamKeyPicker
|
|
||||||
broadcasts = { this.state.broadcasts }
|
|
||||||
onChange = { this._onStreamKeyPick } />
|
|
||||||
<StreamKeyForm
|
|
||||||
onChange = { this._onStreamKeyChangeNative }
|
|
||||||
value = { this.state.streamKey || this.props._streamKey } />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(StartLiveStreamDialog));
|
export default translate(connect(_mapStateToProps)(StartLiveStreamDialog));
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { DialogContent } from '../../../../base/dialog';
|
import { ConfirmDialog } from '../../../../base/dialog';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
import AbstractStopLiveStreamDialog, {
|
import AbstractStopLiveStreamDialog, {
|
||||||
|
@ -19,19 +19,20 @@ import AbstractStopLiveStreamDialog, {
|
||||||
class StopLiveStreamDialog extends AbstractStopLiveStreamDialog {
|
class StopLiveStreamDialog extends AbstractStopLiveStreamDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the platform specific {@code Dialog} content.
|
* Implements React's {@link Component#render()}.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
_renderDialogContent() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<DialogContent>
|
<ConfirmDialog
|
||||||
{
|
contentKey = 'dialog.stopStreamingWarning'
|
||||||
this.props.t('dialog.stopStreamingWarning')
|
onSubmit = { this._onSubmit } />
|
||||||
}
|
|
||||||
</DialogContent>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(StopLiveStreamDialog));
|
export default translate(connect(_mapStateToProps)(StopLiveStreamDialog));
|
||||||
|
|
|
@ -9,7 +9,7 @@ import AbstractStreamKeyForm, {
|
||||||
type Props
|
type Props
|
||||||
} from '../AbstractStreamKeyForm';
|
} from '../AbstractStreamKeyForm';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles, { PLACEHOLDER_COLOR } from './styles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A React Component for entering a key for starting a YouTube live stream.
|
* A React Component for entering a key for starting a YouTube live stream.
|
||||||
|
@ -49,12 +49,13 @@ class StreamKeyForm extends AbstractStreamKeyForm {
|
||||||
<TextInput
|
<TextInput
|
||||||
onChangeText = { this._onInputChange }
|
onChangeText = { this._onInputChange }
|
||||||
placeholder = { t('liveStreaming.enterStreamKey') }
|
placeholder = { t('liveStreaming.enterStreamKey') }
|
||||||
|
placeholderTextColor = { PLACEHOLDER_COLOR }
|
||||||
style = { styles.streamKeyInput }
|
style = { styles.streamKeyInput }
|
||||||
value = { this.props.value } />
|
value = { this.props.value } />
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress = { this._onOpenHelp }
|
onPress = { this._onOpenHelp }
|
||||||
style = { styles.streamKeyHelp } >
|
style = { styles.streamKeyHelp } >
|
||||||
<Text>
|
<Text style = { styles.text }>
|
||||||
{
|
{
|
||||||
t('liveStreaming.streamIdHelp')
|
t('liveStreaming.streamIdHelp')
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ class StreamKeyPicker extends Component<Props, State> {
|
||||||
return (
|
return (
|
||||||
<View style = { styles.formWrapper }>
|
<View style = { styles.formWrapper }>
|
||||||
<View style = { styles.streamKeyPickerCta }>
|
<View style = { styles.streamKeyPickerCta }>
|
||||||
<Text>
|
<Text style = { styles.text }>
|
||||||
{ this.props.t('liveStreaming.choose') }
|
{ this.props.t('liveStreaming.choose') }
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
@ -90,7 +90,7 @@ class StreamKeyPicker extends Component<Props, State> {
|
||||||
? styles.streamKeyPickerItemHighlight : null
|
? styles.streamKeyPickerItemHighlight : null
|
||||||
] }
|
] }
|
||||||
underlayColor = { TOUCHABLE_UNDERLAY }>
|
underlayColor = { TOUCHABLE_UNDERLAY }>
|
||||||
<Text style = { styles.streamKeyPickerItemText }>
|
<Text style = { styles.text }>
|
||||||
{ broadcast.title }
|
{ broadcast.title }
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableHighlight>))
|
</TouchableHighlight>))
|
||||||
|
|
|
@ -11,6 +11,11 @@ import {
|
||||||
*/
|
*/
|
||||||
export const ACTIVE_OPACITY = 0.3;
|
export const ACTIVE_OPACITY = 0.3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color for the key input field placeholder.
|
||||||
|
*/
|
||||||
|
export const PLACEHOLDER_COLOR = ColorPalette.lightGrey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Underlay of the TouchableHighlight.
|
* Underlay of the TouchableHighlight.
|
||||||
*/
|
*/
|
||||||
|
@ -69,14 +74,19 @@ export default createStyleSheet({
|
||||||
*/
|
*/
|
||||||
streamKeyInput: {
|
streamKeyInput: {
|
||||||
alignSelf: 'stretch',
|
alignSelf: 'stretch',
|
||||||
height: 50
|
borderColor: ColorPalette.lightGrey,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
color: ColorPalette.white,
|
||||||
|
height: 40,
|
||||||
|
marginBottom: 5
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Label for the previous field.
|
* Label for the previous field.
|
||||||
*/
|
*/
|
||||||
streamKeyInputLabel: {
|
streamKeyInputLabel: {
|
||||||
alignSelf: 'flex-start'
|
alignSelf: 'flex-start',
|
||||||
|
color: ColorPalette.white
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,7 +118,7 @@ export default createStyleSheet({
|
||||||
* Additional style for the selected item.
|
* Additional style for the selected item.
|
||||||
*/
|
*/
|
||||||
streamKeyPickerItemHighlight: {
|
streamKeyPickerItemHighlight: {
|
||||||
backgroundColor: ColorPalette.lighterGrey
|
backgroundColor: ColorPalette.darkGrey
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,6 +129,10 @@ export default createStyleSheet({
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
flexDirection: 'column'
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
|
||||||
|
text: {
|
||||||
|
color: ColorPalette.white
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Spinner from '@atlaskit/spinner';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { Dialog } from '../../../../base/dialog';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -59,8 +60,6 @@ class StartLiveStreamDialog
|
||||||
this._onRequestGoogleSignIn = this._onRequestGoogleSignIn.bind(this);
|
this._onRequestGoogleSignIn = this._onRequestGoogleSignIn.bind(this);
|
||||||
this._onYouTubeBroadcastIDSelected
|
this._onYouTubeBroadcastIDSelected
|
||||||
= this._onYouTubeBroadcastIDSelected.bind(this);
|
= this._onYouTubeBroadcastIDSelected.bind(this);
|
||||||
|
|
||||||
this._renderDialogContent = this._renderDialogContent.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,6 +77,39 @@ class StartLiveStreamDialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@code Component}'s render.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { _googleApiApplicationClientID } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
cancelTitleKey = 'dialog.Cancel'
|
||||||
|
okTitleKey = 'dialog.startLiveStreaming'
|
||||||
|
onCancel = { this._onCancel }
|
||||||
|
onSubmit = { this._onSubmit }
|
||||||
|
titleKey = 'liveStreaming.start'
|
||||||
|
width = { 'small' }>
|
||||||
|
<div className = 'live-stream-dialog'>
|
||||||
|
{ _googleApiApplicationClientID
|
||||||
|
? this._renderYouTubePanel() : null }
|
||||||
|
<StreamKeyForm
|
||||||
|
onChange = { this._onStreamKeyChange }
|
||||||
|
value = {
|
||||||
|
this.state.streamKey || this.props._streamKey
|
||||||
|
} />
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onCancel: () => boolean;
|
||||||
|
|
||||||
|
_onSubmit: () => boolean;
|
||||||
|
|
||||||
_onInitializeGoogleApi: () => Promise<*>;
|
_onInitializeGoogleApi: () => Promise<*>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -221,27 +253,6 @@ class StartLiveStreamDialog
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderDialogContent: () => React$Component<*>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the platform specific dialog content.
|
|
||||||
*
|
|
||||||
* @returns {React$Component}
|
|
||||||
*/
|
|
||||||
_renderDialogContent() {
|
|
||||||
const { _googleApiApplicationClientID } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className = 'live-stream-dialog'>
|
|
||||||
{ _googleApiApplicationClientID
|
|
||||||
? this._renderYouTubePanel() : null }
|
|
||||||
<StreamKeyForm
|
|
||||||
onChange = { this._onStreamKeyChange }
|
|
||||||
value = { this.state.streamKey || this.props._streamKey } />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a React Element for authenticating with the Google web client.
|
* Renders a React Element for authenticating with the Google web client.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { Dialog } from '../../../../base/dialog';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
import AbstractStopLiveStreamDialog, {
|
import AbstractStopLiveStreamDialog, {
|
||||||
|
@ -17,13 +19,24 @@ import AbstractStopLiveStreamDialog, {
|
||||||
class StopLiveStreamDialog extends AbstractStopLiveStreamDialog {
|
class StopLiveStreamDialog extends AbstractStopLiveStreamDialog {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the platform specific {@code Dialog} content.
|
* Implements React's {@link Component#render()}.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
_renderDialogContent() {
|
render() {
|
||||||
return this.props.t('dialog.stopStreamingWarning');
|
return (
|
||||||
|
<Dialog
|
||||||
|
okTitleKey = 'dialog.stopLiveStreaming'
|
||||||
|
onSubmit = { this._onSubmit }
|
||||||
|
titleKey = 'dialog.liveStreaming'
|
||||||
|
width = 'small'>
|
||||||
|
{ this.props.t('dialog.stopStreamingWarning') }
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(StopLiveStreamDialog));
|
export default translate(connect(_mapStateToProps)(StopLiveStreamDialog));
|
||||||
|
|
|
@ -18,8 +18,7 @@ import {
|
||||||
|
|
||||||
import { getActiveSession } from '../../functions';
|
import { getActiveSession } from '../../functions';
|
||||||
|
|
||||||
import StartRecordingDialog from './StartRecordingDialog';
|
import { StartRecordingDialog, StopRecordingDialog } from './_';
|
||||||
import { StopRecordingDialog } from './_';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} props of
|
* The type of the React {@code Component} props of
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createRecordingDialogEvent,
|
createRecordingDialogEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
} from '../../../analytics';
|
} from '../../../analytics';
|
||||||
import { Dialog } from '../../../base/dialog';
|
|
||||||
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
||||||
import {
|
import {
|
||||||
getDropboxData,
|
getDropboxData,
|
||||||
isEnabled as isDropboxEnabled
|
isEnabled as isDropboxEnabled
|
||||||
} from '../../../dropbox';
|
} from '../../../dropbox';
|
||||||
|
|
||||||
import StartRecordingDialogContent from './StartRecordingDialogContent';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +71,7 @@ type State = {
|
||||||
/**
|
/**
|
||||||
* Component for the recording start dialog.
|
* Component for the recording start dialog.
|
||||||
*/
|
*/
|
||||||
class StartRecordingDialog extends Component<Props, State> {
|
class AbstractStartRecordingDialog extends Component<Props, State> {
|
||||||
/**
|
/**
|
||||||
* Initializes a new {@code StartRecordingDialog} instance.
|
* Initializes a new {@code StartRecordingDialog} instance.
|
||||||
*
|
*
|
||||||
|
@ -93,6 +89,8 @@ class StartRecordingDialog extends Component<Props, State> {
|
||||||
userName: undefined,
|
userName: undefined,
|
||||||
spaceLeft: undefined
|
spaceLeft: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._onSubmit = this._onSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,7 +111,7 @@ class StartRecordingDialog extends Component<Props, State> {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
if (this.props._token !== prevProps._token) {
|
if (this.props._token !== prevProps._token) {
|
||||||
this._onTokenUpdated();
|
this._onTokenUpdated();
|
||||||
}
|
}
|
||||||
|
@ -158,33 +156,6 @@ class StartRecordingDialog extends Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
const { isTokenValid, isValidating, spaceLeft, userName } = this.state;
|
|
||||||
const { _isDropboxEnabled } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
okDisabled = { !isTokenValid && _isDropboxEnabled }
|
|
||||||
okTitleKey = 'dialog.confirm'
|
|
||||||
onSubmit = { this._onSubmit }
|
|
||||||
titleKey = 'dialog.recording'
|
|
||||||
width = 'small'>
|
|
||||||
<StartRecordingDialogContent
|
|
||||||
integrationsEnabled = { _isDropboxEnabled }
|
|
||||||
isTokenValid = { isTokenValid }
|
|
||||||
isValidating = { isValidating }
|
|
||||||
spaceLeft = { spaceLeft }
|
|
||||||
userName = { userName } />
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSubmit: () => boolean;
|
_onSubmit: () => boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,7 +211,7 @@ class StartRecordingDialog extends Component<Props, State> {
|
||||||
* _token: string
|
* _token: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
function mapStateToProps(state: Object) {
|
export function mapStateToProps(state: Object) {
|
||||||
const { dropbox = {} } = state['features/base/config'];
|
const { dropbox = {} } = state['features/base/config'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -251,4 +222,4 @@ function mapStateToProps(state: Object) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(StartRecordingDialog);
|
export default AbstractStartRecordingDialog;
|
|
@ -1,12 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import { Component } from 'react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createRecordingDialogEvent,
|
createRecordingDialogEvent,
|
||||||
sendAnalytics
|
sendAnalytics
|
||||||
} from '../../../analytics';
|
} from '../../../analytics';
|
||||||
import { Dialog } from '../../../base/dialog';
|
|
||||||
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
|
||||||
|
|
||||||
import { getActiveSession } from '../../functions';
|
import { getActiveSession } from '../../functions';
|
||||||
|
@ -53,24 +52,6 @@ export default class AbstractStopRecordingDialog<P: Props>
|
||||||
this._onSubmit = this._onSubmit.bind(this);
|
this._onSubmit = this._onSubmit.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements React's {@link Component#render()}.
|
|
||||||
*
|
|
||||||
* @inheritdoc
|
|
||||||
* @returns {ReactElement}
|
|
||||||
*/
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
okTitleKey = 'dialog.confirm'
|
|
||||||
onSubmit = { this._onSubmit }
|
|
||||||
titleKey = 'dialog.recording'
|
|
||||||
width = 'small'>
|
|
||||||
{ this._renderDialogContent() }
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSubmit: () => boolean;
|
_onSubmit: () => boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,14 +71,6 @@ export default class AbstractStopRecordingDialog<P: Props>
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the platform specific dialog content.
|
|
||||||
*
|
|
||||||
* @protected
|
|
||||||
* @returns {React$Component}
|
|
||||||
*/
|
|
||||||
_renderDialogContent: () => React$Component<*>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -85,7 +85,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
* @returns {React$Component}
|
* @returns {React$Component}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
if (this.props.integrationsEnabled) {
|
if (this.props.integrationsEnabled === true) { // explicit true needed
|
||||||
return this._renderIntegrationsContent();
|
return this._renderIntegrationsContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
*/
|
*/
|
||||||
_renderNoIntegrationsContent() {
|
_renderNoIntegrationsContent() {
|
||||||
return (
|
return (
|
||||||
<DialogContent>
|
<DialogContent style = { styles.noIntegrationContent }>
|
||||||
{ this.props.t('recording.startRecordingBody') }
|
{ this.props.t('recording.startRecordingBody') }
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
);
|
);
|
||||||
|
@ -195,12 +195,12 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
className = 'logged-in-panel'
|
className = 'logged-in-panel'
|
||||||
style = { styles.loggedIn }>
|
style = { styles.loggedIn }>
|
||||||
<Container>
|
<Container>
|
||||||
<Text>
|
<Text style = { styles.text }>
|
||||||
{ t('recording.loggedIn', { userName }) }
|
{ t('recording.loggedIn', { userName }) }
|
||||||
</Text>
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
<Container>
|
<Container>
|
||||||
<Text>
|
<Text style = { styles.text }>
|
||||||
{
|
{
|
||||||
t('recording.availableSpace', {
|
t('recording.availableSpace', {
|
||||||
spaceLeft,
|
spaceLeft,
|
||||||
|
@ -211,7 +211,9 @@ class StartRecordingDialogContent extends Component<Props> {
|
||||||
</Container>
|
</Container>
|
||||||
</Container>
|
</Container>
|
||||||
<Container style = { styles.startRecordingText }>
|
<Container style = { styles.startRecordingText }>
|
||||||
<Text>{ t('recording.startRecordingBody') }</Text>
|
<Text style = { styles.text }>
|
||||||
|
{ t('recording.startRecordingBody') }
|
||||||
|
</Text>
|
||||||
</Container>
|
</Container>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import { ConfirmDialog, CustomSubmitDialog } from '../../../../base/dialog';
|
||||||
|
|
||||||
|
import AbstractStartRecordingDialog, {
|
||||||
|
mapStateToProps
|
||||||
|
} from '../AbstractStartRecordingDialog';
|
||||||
|
import StartRecordingDialogContent from '../StartRecordingDialogContent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Component for getting confirmation to start a file recording session in
|
||||||
|
* progress.
|
||||||
|
*
|
||||||
|
* @extends Component
|
||||||
|
*/
|
||||||
|
class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { isTokenValid, isValidating, spaceLeft, userName } = this.state;
|
||||||
|
const { _isDropboxEnabled } = this.props;
|
||||||
|
|
||||||
|
if (!_isDropboxEnabled) {
|
||||||
|
return (
|
||||||
|
<ConfirmDialog
|
||||||
|
contentKey = 'recording.startRecordingBody'
|
||||||
|
onSubmit = { this._onSubmit } />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CustomSubmitDialog
|
||||||
|
okDisabled = { !isTokenValid }
|
||||||
|
onSubmit = { this._onSubmit } >
|
||||||
|
<StartRecordingDialogContent
|
||||||
|
isTokenValid = { isTokenValid }
|
||||||
|
isValidating = { isValidating }
|
||||||
|
spaceLeft = { spaceLeft }
|
||||||
|
userName = { userName } />
|
||||||
|
</CustomSubmitDialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
|
@ -3,7 +3,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { DialogContent } from '../../../../base/dialog';
|
import { ConfirmDialog } from '../../../../base/dialog';
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
|
||||||
import AbstractStopRecordingDialog, {
|
import AbstractStopRecordingDialog, {
|
||||||
|
@ -20,19 +20,19 @@ import AbstractStopRecordingDialog, {
|
||||||
class StopRecordingDialog extends AbstractStopRecordingDialog<Props> {
|
class StopRecordingDialog extends AbstractStopRecordingDialog<Props> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the platform specific dialog content.
|
* Implements {@code Component#render}.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
_renderDialogContent() {
|
render() {
|
||||||
const { t } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogContent>
|
<ConfirmDialog
|
||||||
{ t('dialog.stopRecordingWarning') }
|
contentKey = 'dialog.stopRecordingWarning'
|
||||||
</DialogContent>
|
onSubmit = { this._onSubmit } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(StopRecordingDialog));
|
export default translate(connect(_mapStateToProps)(StopRecordingDialog));
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
export { default as RecordButton } from './RecordButton';
|
export { default as RecordButton } from './RecordButton';
|
||||||
|
export { default as StartRecordingDialog } from './StartRecordingDialog';
|
||||||
export { default as StopRecordingDialog } from './StopRecordingDialog';
|
export { default as StopRecordingDialog } from './StopRecordingDialog';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import { BoxModel, createStyleSheet } from '../../../base/styles';
|
import { BoxModel, createStyleSheet, 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.
|
||||||
|
@ -28,16 +28,26 @@ export default createStyleSheet({
|
||||||
paddingBottom: _PADDING
|
paddingBottom: _PADDING
|
||||||
},
|
},
|
||||||
|
|
||||||
|
noIntegrationContent: {
|
||||||
|
color: ColorPalette.white
|
||||||
|
},
|
||||||
|
|
||||||
startRecordingText: {
|
startRecordingText: {
|
||||||
paddingBottom: _PADDING
|
paddingBottom: _PADDING
|
||||||
},
|
},
|
||||||
|
|
||||||
switch: {
|
switch: {
|
||||||
|
color: ColorPalette.white,
|
||||||
paddingRight: BoxModel.padding
|
paddingRight: BoxModel.padding
|
||||||
},
|
},
|
||||||
|
|
||||||
title: {
|
title: {
|
||||||
|
color: ColorPalette.white,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'bold'
|
fontWeight: 'bold'
|
||||||
|
},
|
||||||
|
|
||||||
|
text: {
|
||||||
|
color: ColorPalette.white
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import { Dialog } from '../../../../base/dialog';
|
||||||
|
|
||||||
|
import AbstractStartRecordingDialog, {
|
||||||
|
mapStateToProps
|
||||||
|
} from '../AbstractStartRecordingDialog';
|
||||||
|
import StartRecordingDialogContent from '../StartRecordingDialogContent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Component for getting confirmation to start a file recording session in
|
||||||
|
* progress.
|
||||||
|
*
|
||||||
|
* @extends Component
|
||||||
|
*/
|
||||||
|
class StartRecordingDialog extends AbstractStartRecordingDialog {
|
||||||
|
/**
|
||||||
|
* Implements React's {@link Component#render()}.
|
||||||
|
*
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
render() {
|
||||||
|
const { isTokenValid, isValidating, spaceLeft, userName } = this.state;
|
||||||
|
const { _isDropboxEnabled } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
okDisabled = { !isTokenValid && _isDropboxEnabled }
|
||||||
|
okTitleKey = 'dialog.confirm'
|
||||||
|
onSubmit = { this._onSubmit }
|
||||||
|
titleKey = 'dialog.recording'
|
||||||
|
width = 'small'>
|
||||||
|
<StartRecordingDialogContent
|
||||||
|
integrationsEnabled = { _isDropboxEnabled }
|
||||||
|
isTokenValid = { isTokenValid }
|
||||||
|
isValidating = { isValidating }
|
||||||
|
spaceLeft = { spaceLeft }
|
||||||
|
userName = { userName } />
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default translate(connect(mapStateToProps)(StartRecordingDialog));
|
|
@ -1,8 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { translate } from '../../../../base/i18n';
|
import { translate } from '../../../../base/i18n';
|
||||||
|
import { Dialog } from '../../../../base/dialog';
|
||||||
|
|
||||||
import AbstractStopRecordingDialog, {
|
import AbstractStopRecordingDialog, {
|
||||||
type Props,
|
type Props,
|
||||||
|
@ -16,20 +18,27 @@ import AbstractStopRecordingDialog, {
|
||||||
* @extends Component
|
* @extends Component
|
||||||
*/
|
*/
|
||||||
class StopRecordingDialog extends AbstractStopRecordingDialog<Props> {
|
class StopRecordingDialog extends AbstractStopRecordingDialog<Props> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the platform specific dialog content.
|
* Implements React's {@link Component#render()}.
|
||||||
*
|
*
|
||||||
* @protected
|
* @inheritdoc
|
||||||
* @returns {React$Component}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
_renderDialogContent() {
|
render() {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
t('dialog.stopRecordingWarning')
|
<Dialog
|
||||||
|
okTitleKey = 'dialog.confirm'
|
||||||
|
onSubmit = { this._onSubmit }
|
||||||
|
titleKey = 'dialog.recording'
|
||||||
|
width = 'small'>
|
||||||
|
{ t('dialog.stopRecordingWarning') }
|
||||||
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSubmit: () => boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect(_mapStateToProps)(StopRecordingDialog));
|
export default translate(connect(_mapStateToProps)(StopRecordingDialog));
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
export { default as RecordButton } from './RecordButton';
|
export { default as RecordButton } from './RecordButton';
|
||||||
|
export { default as StartRecordingDialog } from './StartRecordingDialog';
|
||||||
export { default as StopRecordingDialog } from './StopRecordingDialog';
|
export { default as StopRecordingDialog } from './StopRecordingDialog';
|
||||||
|
|
Loading…
Reference in New Issue