[RN] Group the secondary toobar buttons

Rearrange the ToolbarButtons in the secondary Toolbar in order to mostly
group the media-related ones such as the AudioRouteButton, the
switchCamera button, and the audio-only mode button.
This commit is contained in:
Lyubo Marinov 2017-11-14 14:18:16 -06:00
parent f973a695d8
commit e7aff1d8e1
7 changed files with 92 additions and 94 deletions

View File

@ -9,7 +9,7 @@ import { LoadingIndicator } from '../../react';
import { set } from '../../redux';
import AbstractDialog from './AbstractDialog';
import styles from './styles';
import { dialog as styles } from './styles';
/**
* The value of the style property {@link _TAG_KEY} which identifies the

View File

@ -12,7 +12,7 @@ import { connect } from 'react-redux';
import { Icon } from '../../font-icons';
import { bottomSheet as styles } from './styles';
import { simpleBottomSheet as styles } from './styles';
/**
* Underlay color for the buttons on the sheet.

View File

@ -1,9 +1,9 @@
import { ColorPalette, createStyleSheet } from '../../styles';
/**
* The React {@code Component} styles of the feature base/dialog.
* The React {@code Component} styles of {@code Dialog}.
*/
export default createStyleSheet({
export const dialog = createStyleSheet({
/**
* The style of the {@code Text} in a {@code Dialog} button.
*/
@ -21,11 +21,11 @@ export default createStyleSheet({
});
/**
* The React {@code Component} styles for {@code SimpleBottomSheet}.
* These styles have been implemented as per the Material Design guidelines:
* https://material.io/guidelines/components/bottom-sheets.html
* The React {@code Component} styles of {@code SimpleBottomSheet}. These have
* been implemented as per the Material Design guidelines:
* {@link https://material.io/guidelines/components/bottom-sheets.html}.
*/
export const bottomSheet = createStyleSheet({
export const simpleBottomSheet = createStyleSheet({
/**
* Style for the container of the sheet.
*/

View File

@ -7,11 +7,30 @@ import { connect } from 'react-redux';
import { hideDialog, SimpleBottomSheet } from '../../../base/dialog';
const AudioMode = NativeModules.AudioMode;
/**
* {@code PasswordRequiredPrompt}'s React {@code Component} prop types.
*/
type Props = {
/**
* Used for hiding the dialog when the selection was completed.
*/
dispatch: Function
};
type State = {
/**
* Array of available devices.
*/
devices: Array<string>
};
const { AudioMode } = NativeModules;
/**
* Maps each device type to a display name and icon.
* TODO: internationalization.
* TODO i18n
*/
const deviceInfoMap = {
BLUETOOTH: {
@ -37,30 +56,11 @@ const deviceInfoMap = {
};
/**
* Variable to hold the reference to the exported component. This dialog is only
* exported if the {@code AudioMode} module has the capability to get / set
* The exported React {@code Component}. {@code AudioRoutePickerDialog} is
* exported only if the {@code AudioMode} module has the capability to get / set
* audio devices.
*/
let DialogType;
/**
* {@code PasswordRequiredPrompt}'s React {@code Component} prop types.
*/
type Props = {
/**
* Used for hiding the dialog when the selection was completed.
*/
dispatch: Function
};
type State = {
/**
* Array of available devices.
*/
devices: Array<string>
};
let AudioRoutePickerDialog_;
/**
* Implements a React {@code Component} which prompts the user when a password
@ -68,7 +68,10 @@ type State = {
*/
class AudioRoutePickerDialog extends Component<Props, State> {
state = {
// Available audio devices, it will be set in componentWillMount.
/**
* Available audio devices, it will be set in
* {@link #componentWillMount()}.
*/
devices: []
};
@ -87,7 +90,7 @@ class AudioRoutePickerDialog extends Component<Props, State> {
}
/**
* Initializes the device list by querying the {@code AudioMode} module.
* Initializes the device list by querying {@code AudioMode}.
*
* @inheritdoc
*/
@ -107,8 +110,10 @@ class AudioRoutePickerDialog extends Component<Props, State> {
}
if (audioDevices) {
// Make sure devices is alphabetically sorted
this.setState({ devices: _.sortBy(audioDevices, 'text') });
// Make sure devices is alphabetically sorted.
this.setState({
devices: _.sortBy(audioDevices, 'text')
});
}
});
}
@ -119,7 +124,7 @@ class AudioRoutePickerDialog extends Component<Props, State> {
* @returns {void}
*/
_hide() {
this.props.dispatch(hideDialog(DialogType));
this.props.dispatch(hideDialog(AudioRoutePickerDialog_));
}
_onCancel: () => void;
@ -156,7 +161,9 @@ class AudioRoutePickerDialog extends Component<Props, State> {
* @returns {ReactElement}
*/
render() {
if (!this.state.devices.length) {
const { devices } = this.state;
if (!devices.length) {
return null;
}
@ -164,7 +171,7 @@ class AudioRoutePickerDialog extends Component<Props, State> {
<SimpleBottomSheet
onCancel = { this._onCancel }
onSubmit = { this._onSubmit }
options = { this.state.devices } />
options = { devices } />
);
}
}
@ -172,7 +179,7 @@ class AudioRoutePickerDialog extends Component<Props, State> {
// Only export the dialog if we have support for getting / setting audio devices
// in AudioMode.
if (AudioMode.getAudioDevices && AudioMode.setAudioDevice) {
DialogType = connect()(AudioRoutePickerDialog);
AudioRoutePickerDialog_ = connect()(AudioRoutePickerDialog);
}
export default DialogType;
export default AudioRoutePickerDialog_;

View File

@ -3,8 +3,8 @@
import React, { Component } from 'react';
import {
findNodeHandle,
requireNativeComponent,
NativeModules,
requireNativeComponent,
View
} from 'react-native';
import { connect } from 'react-redux';
@ -15,17 +15,15 @@ import { AudioRoutePickerDialog } from '../../mobile/audio-mode';
import ToolbarButton from './ToolbarButton';
/**
* Define the {@code MPVolumeView} React component. It will only be available
* The {@code MPVolumeView} React {@code Component}. It will only be available
* on iOS.
*/
let MPVolumeView;
if (NativeModules.MPVolumeViewManager) {
MPVolumeView = requireNativeComponent('MPVolumeView', null);
}
const MPVolumeView
= NativeModules.MPVolumeViewManager
&& requireNativeComponent('MPVolumeView', null);
/**
* Style required to hide the {@code MPVolumeView} view, since it's displayed
* The style required to hide the {@code MPVolumeView}, since it's displayed
* programmatically.
*/
const HIDE_VIEW_STYLE = { display: 'none' };
@ -33,7 +31,8 @@ const HIDE_VIEW_STYLE = { display: 'none' };
type Props = {
/**
* Used to show the {@code AudioRoutePickerDialog}.
* The redux {@code dispatch} function used to open/show the
* {@code AudioRoutePickerDialog}.
*/
dispatch: Function,
@ -48,12 +47,12 @@ type Props = {
iconStyle: Object,
/**
* {@code AudioRouteButton} styles.
* The style(s) of {@code AudioRouteButton}.
*/
style: Array<*> | Object,
/**
* The color underlying the button.
* The color underlaying the button.
*/
underlayColor: string
};
@ -64,16 +63,6 @@ type Props = {
class AudioRouteButton extends Component<Props> {
_volumeComponent: ?Object;
/**
* Indicates if there is support for audio device selection via this button.
*
* @returns {boolean} - True if audio device selection is supported, false
* otherwise.
*/
static supported() {
return Boolean(MPVolumeView || AudioRoutePickerDialog);
}
/**
* Initializes a new {@code AudioRouteButton} instance.
*
@ -108,27 +97,13 @@ class AudioRouteButton extends Component<Props> {
*/
_onClick() {
if (MPVolumeView) {
const handle = findNodeHandle(this._volumeComponent);
NativeModules.MPVolumeViewManager.show(handle);
NativeModules.MPVolumeViewManager.show(
findNodeHandle(this._volumeComponent));
} else if (AudioRoutePickerDialog) {
this.props.dispatch(openDialog(AudioRoutePickerDialog));
}
}
_setVolumeComponent: (?Object) => void;
/**
* Sets the internal reference to the React Component wrapping the
* {@code MPVolumeView} component.
*
* @param {ReactComponent} component - React Component.
* @returns {void}
*/
_setVolumeComponent(component) {
this._volumeComponent = component;
}
/**
* Implements React's {@link Component#render()}.
*
@ -155,6 +130,21 @@ class AudioRouteButton extends Component<Props> {
</View>
);
}
_setVolumeComponent: (?Object) => void;
/**
* Sets the internal reference to the React Component wrapping the
* {@code MPVolumeView} component.
*
* @param {ReactComponent} component - React Component.
* @private
* @returns {void}
*/
_setVolumeComponent(component) {
this._volumeComponent = component;
}
}
export default connect()(AudioRouteButton);
export default (MPVolumeView || AudioRoutePickerDialog)
&& connect()(AudioRouteButton);

View File

@ -47,8 +47,9 @@ class ToolbarButton extends AbstractToolbarButton {
return React.createElement(TouchableHighlight, props, children);
}
// eslint-disable-next-line valid-jsdoc
/**
* Renders the icon of this {@code ToolbarButton}.
*
* @inheritdoc
*/
_renderIcon() {

View File

@ -282,6 +282,14 @@ class Toolbox extends Component {
<View
key = 'secondaryToolbar'
style = { styles.secondaryToolbar }>
{
AudioRouteButton
&& <AudioRouteButton
iconName = { 'volume' }
iconStyle = { iconStyle }
style = { style }
underlayColor = { underlayColor } />
}
<ToolbarButton
disabled = { audioOnly || videoMuted }
iconName = 'switch-camera'
@ -289,6 +297,12 @@ class Toolbox extends Component {
onClick = { this.props._onToggleCameraFacingMode }
style = { style }
underlayColor = { underlayColor } />
<ToolbarButton
iconName = { audioOnly ? 'visibility-off' : 'visibility' }
iconStyle = { iconStyle }
onClick = { this.props._onToggleAudioOnly }
style = { style }
underlayColor = { underlayColor } />
<ToolbarButton
iconName = {
this.props._locked ? 'security-locked' : 'security'
@ -297,12 +311,6 @@ class Toolbox extends Component {
onClick = { this.props._onRoomLock }
style = { style }
underlayColor = { underlayColor } />
<ToolbarButton
iconName = { audioOnly ? 'visibility-off' : 'visibility' }
iconStyle = { iconStyle }
onClick = { this.props._onToggleAudioOnly }
style = { style }
underlayColor = { underlayColor } />
{
_SHARE_ROOM_TOOLBAR_BUTTON
&& <ToolbarButton
@ -312,14 +320,6 @@ class Toolbox extends Component {
style = { style }
underlayColor = { underlayColor } />
}
{
AudioRouteButton.supported()
&& <AudioRouteButton
iconName = { 'volume' }
iconStyle = { iconStyle }
style = { style }
underlayColor = { underlayColor } />
}
</View>
);