Comply w/ coding style

This commit is contained in:
Lyubo Marinov 2017-04-06 11:45:36 -05:00
parent 3af6cc53d1
commit fd10362bef
7 changed files with 196 additions and 174 deletions

View File

@ -453,9 +453,9 @@ export function setPassword(conference, method, password) {
* @param {(string|undefined)} room - The name of the room of the conference to * @param {(string|undefined)} room - The name of the room of the conference to
* be joined. * be joined.
* @returns {{ * @returns {{
* type: SET_ROOM, * type: SET_ROOM,
* room: string * room: string
* }} * }}
*/ */
export function setRoom(room) { export function setRoom(room) {
return { return {

View File

@ -1,35 +1,21 @@
import { getLogger } from 'jitsi-meet-logger';
import { openDialog } from '../base/dialog'; import { openDialog } from '../base/dialog';
import { import {
RESET_DESKTOP_SOURCES, RESET_DESKTOP_SOURCES,
UPDATE_DESKTOP_SOURCES UPDATE_DESKTOP_SOURCES
} from './actionTypes'; } from './actionTypes';
import { DesktopPicker } from './components'; import { DesktopPicker } from './components';
const logger = getLogger(__filename); const logger = require('jitsi-meet-logger').getLogger(__filename);
/**
* Signals to remove all stored DesktopCapturerSources.
*
* @returns {{
* type: RESET_DESKTOP_SOURCES
* }}
*/
export function resetDesktopSources() {
return {
type: RESET_DESKTOP_SOURCES
};
}
/** /**
* Begins a request to get available DesktopCapturerSources. * Begins a request to get available DesktopCapturerSources.
* *
* @param {Array} types - An array with DesktopCapturerSource type strings. * @param {Array} types - An array with DesktopCapturerSource type strings.
* @param {Object} options - Additional configuration for getting a list * @param {Object} options - Additional configuration for getting a list of
* of sources. * sources.
* @param {Object} options.thumbnailSize - The desired height and width * @param {Object} options.thumbnailSize - The desired height and width of the
* of the return native image object used for the preview image of the source. * return native image object used for the preview image of the source.
* @returns {Function} * @returns {Function}
*/ */
export function obtainDesktopSources(types, options = {}) { export function obtainDesktopSources(types, options = {}) {
@ -42,21 +28,37 @@ export function obtainDesktopSources(types, options = {}) {
} }
return dispatch => { return dispatch => {
if (window.JitsiMeetElectron const { JitsiMeetElectron } = window;
&& window.JitsiMeetElectron.obtainDesktopStreams) {
window.JitsiMeetElectron.obtainDesktopStreams( if (JitsiMeetElectron && JitsiMeetElectron.obtainDesktopStreams) {
JitsiMeetElectron.obtainDesktopStreams(
sources => dispatch(updateDesktopSources(sources)), sources => dispatch(updateDesktopSources(sources)),
error => logger.error( error =>
`Error while obtaining desktop sources: ${error}`), logger.error(
`Error while obtaining desktop sources: ${error}`),
capturerOptions capturerOptions
); );
} else { } else {
logger.error('Called JitsiMeetElectron.obtainDesktopStreams ' logger.error(
+ 'but it is not defined'); 'Called JitsiMeetElectron.obtainDesktopStreams'
+ ' but it is not defined');
} }
}; };
} }
/**
* Signals to remove all stored DesktopCapturerSources.
*
* @returns {{
* type: RESET_DESKTOP_SOURCES
* }}
*/
export function resetDesktopSources() {
return {
type: RESET_DESKTOP_SOURCES
};
}
/** /**
* Signals to open a dialog with the DesktopPicker component. * Signals to open a dialog with the DesktopPicker component.
* *

View File

@ -6,37 +6,39 @@ import { connect } from 'react-redux';
import { Dialog, hideDialog } from '../../base/dialog'; import { Dialog, hideDialog } from '../../base/dialog';
import { translate } from '../../base/i18n'; import { translate } from '../../base/i18n';
import {
resetDesktopSources, import { obtainDesktopSources, resetDesktopSources } from '../actions';
obtainDesktopSources
} from '../actions';
import DesktopPickerPane from './DesktopPickerPane'; import DesktopPickerPane from './DesktopPickerPane';
const updateInterval = 1000; const THUMBNAIL_SIZE = {
const thumbnailSize = {
height: 300, height: 300,
width: 300 width: 300
}; };
const tabConfigurations = [ const UPDATE_INTERVAL = 1000;
const TAB_CONFIGURATIONS = [
{ {
/**
* The indicator which determines whether this tab configuration is
* selected by default.
*
* @type {boolean}
*/
defaultSelected: true,
label: 'dialog.yourEntireScreen', label: 'dialog.yourEntireScreen',
type: 'screen', type: 'screen'
isDefault: true
}, },
{ {
label: 'dialog.applicationWindow', label: 'dialog.applicationWindow',
type: 'window' type: 'window'
} }
]; ];
const CONFIGURED_TYPES = config.desktopSharingChromeSources || [];
const validTypes = tabConfigurations.map(configuration => configuration.type); const VALID_TYPES = TAB_CONFIGURATIONS.map(c => c.type);
const configuredTypes = config.desktopSharingChromeSources || []; const TABS_TO_POPULATE
= TAB_CONFIGURATIONS.filter(
const tabsToPopulate = tabConfigurations.filter(configuration => c => CONFIGURED_TYPES.includes(c.type) && VALID_TYPES.includes(c.type));
configuredTypes.includes(configuration.type) const TYPES_TO_FETCH = TABS_TO_POPULATE.map(c => c.type);
&& validTypes.includes(configuration.type)
);
const typesToFetch = tabsToPopulate.map(configuration => configuration.type);
/** /**
* React component for DesktopPicker. * React component for DesktopPicker.
@ -56,14 +58,14 @@ class DesktopPicker extends Component {
dispatch: React.PropTypes.func, dispatch: React.PropTypes.func,
/** /**
* The callback to be invoked when the component is closed or * The callback to be invoked when the component is closed or when
* when a DesktopCapturerSource has been chosen. * a DesktopCapturerSource has been chosen.
*/ */
onSourceChoose: React.PropTypes.func, onSourceChoose: React.PropTypes.func,
/** /**
* An object with arrays of DesktopCapturerSources. The key * An object with arrays of DesktopCapturerSources. The key should be
* should be the source type. * the source type.
*/ */
sources: React.PropTypes.object, sources: React.PropTypes.object,
@ -94,8 +96,8 @@ class DesktopPicker extends Component {
} }
/** /**
* Perform an immediate update request for DesktopCapturerSources and * Perform an immediate update request for DesktopCapturerSources and begin
* begin requesting updates at an interval. * requesting updates at an interval.
* *
* @inheritdoc * @inheritdoc
*/ */
@ -104,16 +106,6 @@ class DesktopPicker extends Component {
this._startPolling(); this._startPolling();
} }
/**
* Clean up component and DesktopCapturerSource store state.
*
* @inheritdoc
*/
componentWillUnmount() {
this._stopPolling();
this.props.dispatch(resetDesktopSources());
}
/** /**
* Notifies this mounted React Component that it will receive new props. * Notifies this mounted React Component that it will receive new props.
* Sets a default selected source if one is not already set. * Sets a default selected source if one is not already set.
@ -125,11 +117,23 @@ class DesktopPicker extends Component {
*/ */
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
if (!this.state.selectedSourceId if (!this.state.selectedSourceId
&& nextProps.sources.screen.length) { && nextProps.sources.screen.length) {
this.setState({ selectedSourceId: nextProps.sources.screen[0].id }); this.setState({
selectedSourceId: nextProps.sources.screen[0].id
});
} }
} }
/**
* Clean up component and DesktopCapturerSource store state.
*
* @inheritdoc
*/
componentWillUnmount() {
this._stopPolling();
this.props.dispatch(resetDesktopSources());
}
/** /**
* Implements React's {@link Component#render()}. * Implements React's {@link Component#render()}.
* *
@ -145,22 +149,68 @@ class DesktopPicker extends Component {
titleKey = 'dialog.shareYourScreen' titleKey = 'dialog.shareYourScreen'
width = 'medium' > width = 'medium' >
{ this._renderTabs() } { this._renderTabs() }
</Dialog>); </Dialog>
);
} }
/** /**
* Dispatches an action to get currently available DesktopCapturerSources. * Dispatches an action to hide the DesktopPicker and invokes the passed in
* callback with a selectedSourceId, if any.
* *
* @private * @param {string} id - The id of the DesktopCapturerSource to pass into the
* onSourceChoose callback.
* @returns {void} * @returns {void}
*/ */
_updateSources() { _onCloseModal(id = '') {
this.props.dispatch(obtainDesktopSources( this.props.onSourceChoose(id);
typesToFetch, this.props.dispatch(hideDialog());
{ }
thumbnailSize
} /**
)); * Sets the currently selected DesktopCapturerSource.
*
* @param {string} id - The id of DesktopCapturerSource.
* @returns {void}
*/
_onPreviewClick(id) {
this.setState({ selectedSourceId: id });
}
/**
* Request to close the modal and execute callbacks with the selected source
* id.
*
* @returns {void}
*/
_onSubmit() {
this._onCloseModal(this.state.selectedSourceId);
}
/**
* Configures and renders the tabs for display.
*
* @private
* @returns {ReactElement}
*/
_renderTabs() {
const { selectedSourceId } = this.state;
const { sources, t } = this.props;
const tabs
= TABS_TO_POPULATE.map(({ defaultSelected, label, type }) => {
return {
content: <DesktopPickerPane
key = { type }
onClick = { this._onPreviewClick }
onDoubleClick = { this._onCloseModal }
selectedSourceId = { selectedSourceId }
sources = { sources[type] || [] }
type = { type } />,
defaultSelected,
label: t(label)
};
});
return <Tabs tabs = { tabs } />;
} }
/** /**
@ -171,8 +221,7 @@ class DesktopPicker extends Component {
*/ */
_startPolling() { _startPolling() {
this._stopPolling(); this._stopPolling();
this._poller = window.setInterval(this._updateSources, this._poller = window.setInterval(this._updateSources, UPDATE_INTERVAL);
updateInterval);
} }
/** /**
@ -187,62 +236,18 @@ class DesktopPicker extends Component {
} }
/** /**
* Sets the currently selected DesktopCapturerSource. * Dispatches an action to get currently available DesktopCapturerSources.
* *
* @param {string} id - The id of DesktopCapturerSource.
* @returns {void}
*/
_onPreviewClick(id) {
this.setState({ selectedSourceId: id });
}
/**
* Request to close the modal and execute callbacks
* with the selected source id.
*
* @returns {void}
*/
_onSubmit() {
this._onCloseModal(this.state.selectedSourceId);
}
/**
* Dispatches an action to hide the DesktopPicker and invokes
* the passed in callback with a selectedSourceId, if any.
*
* @param {string} id - The id of the DesktopCapturerSource to pass into
* the onSourceChoose callback.
* @returns {void}
*/
_onCloseModal(id = '') {
this.props.onSourceChoose(id);
this.props.dispatch(hideDialog());
}
/**
* Configures and renders the tabs for display.
*
* @returns {ReactElement}
* @private * @private
* @returns {void}
*/ */
_renderTabs() { _updateSources() {
const tabs = tabsToPopulate.map(tabConfig => { this.props.dispatch(obtainDesktopSources(
const type = tabConfig.type; TYPES_TO_FETCH,
{
return { THUMBNAIL_SIZE
label: this.props.t(tabConfig.label), }
defaultSelected: tabConfig.isDefault, ));
content: <DesktopPickerPane
key = { type }
onClick = { this._onPreviewClick }
onDoubleClick = { this._onCloseModal }
selectedSourceId = { this.state.selectedSourceId }
sources = { this.props.sources[type] || [] }
type = { type } />
};
});
return <Tabs tabs = { tabs } />;
} }
} }
@ -250,15 +255,15 @@ class DesktopPicker extends Component {
* Maps (parts of) the Redux state to the associated DesktopPicker's props. * Maps (parts of) the Redux state to the associated DesktopPicker's props.
* *
* @param {Object} state - Redux state. * @param {Object} state - Redux state.
* @protected * @private
* @returns {{ * @returns {{
* sources: Object * sources: Object
* }} * }}
*/ */
function mapStateToProps(state) { function _mapStateToProps(state) {
return { return {
sources: state['features/desktop-picker/sources'] sources: state['features/desktop-picker']
}; };
} }
export default translate(connect(mapStateToProps)(DesktopPicker)); export default translate(connect(_mapStateToProps)(DesktopPicker));

View File

@ -1,4 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import DesktopSourcePreview from './DesktopSourcePreview'; import DesktopSourcePreview from './DesktopSourcePreview';
/** /**
@ -19,8 +20,8 @@ class DesktopPickerPane extends Component {
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
/** /**
* The handler to be invoked when a DesktopSourcePreview is * The handler to be invoked when a DesktopSourcePreview is double
* double clicked. * clicked.
*/ */
onDoubleClick: React.PropTypes.func, onDoubleClick: React.PropTypes.func,
@ -47,19 +48,28 @@ class DesktopPickerPane extends Component {
* @returns {ReactElement} * @returns {ReactElement}
*/ */
render() { render() {
const previews = this.props.sources.map(source => const {
<DesktopSourcePreview onClick,
isSelected = { source.id === this.props.selectedSourceId } onDoubleClick,
key = { source.id } selectedSourceId,
onClick = { this.props.onClick } sources,
onDoubleClick = { this.props.onDoubleClick } type
source = { source } /> } = this.props;
);
const classnames = 'desktop-picker-pane default-scrollbar ' const classNames
+ `source-type-${this.props.type}`; = `desktop-picker-pane default-scrollbar source-type-${type}`;
const previews
= sources.map(
source =>
<DesktopSourcePreview
key = { source.id }
onClick = { onClick }
onDoubleClick = { onDoubleClick }
selected = { source.id === selectedSourceId }
source = { source } />);
return ( return (
<div className = { classnames }> <div className = { classNames }>
{ previews } { previews }
</div> </div>
); );

View File

@ -13,22 +13,24 @@ class DesktopSourcePreview extends Component {
*/ */
static propTypes = { static propTypes = {
/** /**
* If true the 'is-selected' class will be added to the component. * The callback to invoke when the component is clicked. The id of
*/ * the DesktopCapturerSource will be passed in.
isSelected: React.PropTypes.bool,
/**
* The callback to invoke when the component is clicked.
* The id of the DesktopCapturerSource will be passed in.
*/ */
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
/** /**
* The callback to invoke when the component is double clicked. * The callback to invoke when the component is double clicked. The id
* The id of the DesktopCapturerSource will be passed in. * of the DesktopCapturerSource will be passed in.
*/ */
onDoubleClick: React.PropTypes.func, onDoubleClick: React.PropTypes.func,
/**
* The indicator which determines whether this DesktopSourcePreview is
* selected. If true, the 'is-selected' CSS class will be added to the
* Component.
*/
selected: React.PropTypes.bool,
/** /**
* The DesktopCapturerSource to display. * The DesktopCapturerSource to display.
*/ */
@ -55,8 +57,8 @@ class DesktopSourcePreview extends Component {
* @returns {ReactElement} * @returns {ReactElement}
*/ */
render() { render() {
const isSelectedClass = this.props.isSelected ? 'is-selected' : ''; const selectedClass = this.props.selected ? 'is-selected' : '';
const displayClasses = `desktop-picker-source ${isSelectedClass}`; const displayClasses = `desktop-picker-source ${selectedClass}`;
return ( return (
<div <div

View File

@ -1,5 +1,5 @@
export * from './actionTypes';
export * from './actions'; export * from './actions';
export * from './actionTypes';
export * from './components'; export * from './components';
import './reducer'; import './reducer';

View File

@ -1,10 +1,11 @@
import { ReducerRegistry } from '../base/redux'; import { ReducerRegistry } from '../base/redux';
import { import {
RESET_DESKTOP_SOURCES, RESET_DESKTOP_SOURCES,
UPDATE_DESKTOP_SOURCES UPDATE_DESKTOP_SOURCES
} from './actionTypes'; } from './actionTypes';
const defaultState = { const DEFAULT_STATE = {
screen: [], screen: [],
window: [] window: []
}; };
@ -19,39 +20,41 @@ const defaultState = {
* @returns {Object} * @returns {Object}
*/ */
ReducerRegistry.register( ReducerRegistry.register(
'features/desktop-picker/sources', 'features/desktop-picker',
(state = defaultState, action) => { (state = DEFAULT_STATE, action) => {
switch (action.type) { switch (action.type) {
case RESET_DESKTOP_SOURCES: case RESET_DESKTOP_SOURCES:
return { ...defaultState }; return { ...DEFAULT_STATE };
case UPDATE_DESKTOP_SOURCES: case UPDATE_DESKTOP_SOURCES:
return seperateSourcesByType(action.sources); return _seperateSourcesByType(action.sources);
default: default:
return state; return state;
} }
}); });
/** /**
* Converts an array of DesktopCapturerSources to an object with types * Converts an array of DesktopCapturerSources to an object with types for keys
* for keys and values being an array with sources of the key's type. * and values being an array with sources of the key's type.
* *
* @param {Array} sources - DesktopCapturerSources. * @param {Array} sources - DesktopCapturerSources.
* @returns {Object} An object with the sources split into seperate arrays
* based on source type.
* @private * @private
* @returns {Object} An object with the sources split into seperate arrays based
* on source type.
*/ */
function seperateSourcesByType(sources = []) { function _seperateSourcesByType(sources = []) {
const sourcesByType = { const sourcesByType = {
screen: [], screen: [],
window: [] window: []
}; };
sources.forEach(source => { sources.forEach(source => {
const sourceIdParts = source.id.split(':'); const idParts = source.id.split(':');
const sourceType = sourceIdParts[0]; const type = idParts[0];
if (sourcesByType[sourceType]) { if (sourcesByType[type]) {
sourcesByType[sourceType].push(source); sourcesByType[type].push(source);
} }
}); });