+
{ this._renderAudioInputPreview() }
+
+
+ { this._renderSelectors() }
+
+ { this._renderAudioOutputPreview() }
+
);
@@ -543,6 +543,7 @@ class DeviceSelectionDialog extends Component {
{
devices: availableDevices.videoInput,
hasPermission: this.props.hasVideoPermission,
+ icon: 'icon-camera',
isDisabled: this.props.disableDeviceChange,
key: 'videoInput',
label: 'settings.selectCamera',
@@ -552,6 +553,7 @@ class DeviceSelectionDialog extends Component {
{
devices: availableDevices.audioInput,
hasPermission: this.props.hasAudioPermission,
+ icon: 'icon-microphone',
isDisabled: this.props.disableAudioInputChange
|| this.props.disableDeviceChange,
key: 'audioInput',
@@ -566,6 +568,7 @@ class DeviceSelectionDialog extends Component {
devices: availableDevices.audioOutput,
hasPermission: this.props.hasAudioPermission
|| this.props.hasVideoPermission,
+ icon: 'icon-volume',
isDisabled: this.props.disableDeviceChange,
key: 'audioOutput',
label: 'settings.selectAudioOutput',
diff --git a/react/features/device-selection/components/DeviceSelector.js b/react/features/device-selection/components/DeviceSelector.js
index 552306e51..827ae61c7 100644
--- a/react/features/device-selection/components/DeviceSelector.js
+++ b/react/features/device-selection/components/DeviceSelector.js
@@ -1,11 +1,15 @@
-import Select from '@atlaskit/single-select';
+import AKButton from '@atlaskit/button';
+import AKDropdownMenu from '@atlaskit/dropdown-menu';
+import ExpandIcon from '@atlaskit/icon/glyph/expand';
import React, { Component } from 'react';
import { translate } from '../../base/i18n';
+const EXPAND_ICON =
;
+
/**
- * React component for selecting a device from a select element. Wraps Select
- * with device selection specific logic.
+ * React component for selecting a device from a select element. Wraps
+ * AKDropdownMenu with device selection specific logic.
*
* @extends Component
*/
@@ -26,6 +30,11 @@ class DeviceSelector extends Component {
*/
hasPermission: React.PropTypes.bool,
+ /**
+ * CSS class for the icon to the left of the dropdown trigger.
+ */
+ icon: React.PropTypes.string,
+
/**
* If true, will render the selector disabled with a default selection.
*/
@@ -79,12 +88,12 @@ class DeviceSelector extends Component {
return this._renderNoDevices();
}
- const items = this.props.devices.map(this._createSelectItem);
+ const items = this.props.devices.map(this._createDropdownItem);
const defaultSelected = items.find(item =>
item.value === this.props.selectedDeviceId
);
- return this._createSelector({
+ return this._createDropdown({
defaultSelected,
isDisabled: this.props.isDisabled,
items,
@@ -93,14 +102,44 @@ class DeviceSelector extends Component {
}
/**
- * Creates an object in the format expected by Select for an option element.
+ * Creates an AtlasKit Button.
+ *
+ * @param {string} buttonText - The text to display within the button.
+ * @private
+ * @returns {ReactElement}
+ */
+ _createDropdownTrigger(buttonText) {
+ return (
+
+ { buttonText }
+
+ );
+ }
+
+ /**
+ * Creates a ReactComponent for displaying an icon.
+ *
+ * @private
+ * @returns {ReactElement}
+ */
+ _createDropdownIcon() {
+ return (
+
+ );
+ }
+
+ /**
+ * Creates an object in the format expected by AKDropdownMenu for an option.
*
* @param {MediaDeviceInfo} device - An object with a label and a deviceId.
* @private
* @returns {Object} The passed in media device description converted to a
- * format recognized as a valid Select item.
+ * format recognized as a valid AKDropdownMenu item.
*/
- _createSelectItem(device) {
+ _createDropdownItem(device) {
return {
content: device.label,
value: device.deviceId
@@ -108,44 +147,49 @@ class DeviceSelector extends Component {
}
/**
- * Creates a Select Component using passed in props and options.
+ * Creates a AKDropdownMenu Component using passed in props and options.
*
- * @param {Object} options - Additional configuration for display Select.
+ * @param {Object} options - Additional configuration for display.
* @param {Object} options.defaultSelected - The option that should be set
* as currently chosen.
- * @param {boolean} options.isDisabled - If true Select will not open on
- * click.
+ * @param {boolean} options.isDisabled - If true, AKDropdownMenu will not
+ * open on click.
* @param {Array} options.items - All the selectable options to display.
* @param {string} options.placeholder - The translation key to display when
* no selection has been made.
* @private
* @returns {ReactElement}
*/
- _createSelector(options) {
+ _createDropdown(options) {
+ const triggerText
+ = (options.defaultSelected && options.defaultSelected.content)
+ || options.placeholder;
+
return (
-
+ onItemActivated = { this._onSelect }>
+ { this._createDropdownTrigger(triggerText) }
+
);
}
/**
* Invokes the passed in callback to notify of selection changes.
*
- * @param {Object} selection - Event returned from Select.
+ * @param {Object} selection - Event from choosing a AKDropdownMenu option.
* @private
* @returns {void}
*/
_onSelect(selection) {
- this.props.onSelect(selection.item.value);
+ const newDeviceId = selection.item.value;
+
+ if (this.props.selectedDeviceId !== newDeviceId) {
+ this.props.onSelect(selection.item.value);
+ }
}
/**
@@ -156,23 +200,23 @@ class DeviceSelector extends Component {
* @returns {ReactElement}
*/
_renderNoDevices() {
- return this._createSelector({
+ return this._createDropdown({
isDisabled: true,
- placeholder: 'settings.noDevice'
+ placeholder: this.props.t('settings.noDevice')
});
}
/**
- * Creates a Select Component that is disabled and has a placeholder stating
- * there is no permission to display the devices.
+ * Creates a AKDropdownMenu Component that is disabled and has a placeholder
+ * stating there is no permission to display the devices.
*
* @private
* @returns {ReactElement}
*/
_renderNoPermission() {
- return this._createSelector({
+ return this._createDropdown({
isDisabled: true,
- placeholder: 'settings.noPermission'
+ placeholder: this.props.t('settings.noPermission')
});
}
}