Дамян Минков 768cff48a4
Notify for new device (#4165)
* Fix detecting preferred audio output.

Fixes detecting when a new output device is found and we have stored user preference of using that device.

* Does not store which is the currently open device on save.

Does not save the currently opened device when saving settings dialog, this will be done once we successfully replace the tracks to use the new devices.

* Saves opened audio device after successfully changing it.

If we do it earlier _updateAudioDeviceId is using localAudio and can store wrong value.

* Adds notification for new non preferred devices.

A notification is shown which gives an option to the user to select and use the newly plugged devices.
Adding custom button and handler for the action to the notifications.

* Changes logic to search and handle all newly added devices from array.

* Moves some utility methods to features/base/devices.
2019-05-03 18:25:33 +01:00

197 lines
5.1 KiB
JavaScript

// @flow
import Flag from '@atlaskit/flag';
import EditorInfoIcon from '@atlaskit/icon/glyph/editor/info';
import ErrorIcon from '@atlaskit/icon/glyph/error';
import WarningIcon from '@atlaskit/icon/glyph/warning';
import { colors } from '@atlaskit/theme';
import React from 'react';
import { translate } from '../../../base/i18n';
import { NOTIFICATION_TYPE } from '../../constants';
import AbstractNotification, {
type Props
} from '../AbstractNotification';
declare var interfaceConfig: Object;
/**
* Secondary colors for notification icons.
*
* @type {{error, info, normal, success, warning}}
*/
const ICON_COLOR = {
error: colors.R400,
info: colors.N500,
normal: colors.N0,
success: colors.G400,
warning: colors.Y200
};
/**
* Implements a React {@link Component} to display a notification.
*
* @extends Component
*/
class Notification extends AbstractNotification<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const {
appearance,
hideErrorSupportLink,
isDismissAllowed,
onDismissed,
t,
title,
titleArguments,
titleKey,
uid
} = this.props;
return (
<Flag
actions = { this._mapAppearanceToButtons(hideErrorSupportLink) }
appearance = { appearance }
description = { this._renderDescription() }
icon = { this._mapAppearanceToIcon() }
id = { uid }
isDismissAllowed = { isDismissAllowed }
onDismissed = { onDismissed }
title = { title || t(titleKey, titleArguments) } />
);
}
_getDescription: () => Array<string>
_onDismissed: () => void;
/**
* Creates a {@code ReactElement} for displaying the contents of the
* notification.
*
* @private
* @returns {ReactElement}
*/
_renderDescription() {
return (
<div>
{
this._getDescription()
}
</div>
);
}
/**
* Opens the support page.
*
* @returns {void}
* @private
*/
_onOpenSupportLink() {
window.open(interfaceConfig.SUPPORT_URL, '_blank', 'noopener');
}
/**
* Creates action button configurations for the notification based on
* notification appearance.
*
* @param {boolean} hideErrorSupportLink - Indicates if the support link
* should be hidden in the error messages.
* @private
* @returns {Object[]}
*/
_mapAppearanceToButtons(hideErrorSupportLink) {
switch (this.props.appearance) {
case NOTIFICATION_TYPE.ERROR: {
const buttons = [
{
content: this.props.t('dialog.dismiss'),
onClick: this._onDismissed
}
];
if (!hideErrorSupportLink) {
buttons.push({
content: this.props.t('dialog.contactSupport'),
onClick: this._onOpenSupportLink
});
}
return buttons;
}
case NOTIFICATION_TYPE.WARNING:
return [
{
content: this.props.t('dialog.Ok'),
onClick: this._onDismissed
}
];
default:
if (this.props.customActionNameKey && this.props.customActionHandler) {
return [
{
content: this.props.t(this.props.customActionNameKey),
onClick: () => {
if (this.props.customActionHandler()) {
this._onDismissed();
}
}
}
];
}
return [];
}
}
/**
* Creates an icon component depending on the configured notification
* appearance.
*
* @private
* @returns {ReactElement}
*/
_mapAppearanceToIcon() {
const appearance = this.props.appearance;
const secIconColor = ICON_COLOR[this.props.appearance];
const iconSize = 'medium';
switch (appearance) {
case NOTIFICATION_TYPE.ERROR:
return (
<ErrorIcon
label = { appearance }
secondaryColor = { secIconColor }
size = { iconSize } />
);
case NOTIFICATION_TYPE.WARNING:
return (
<WarningIcon
label = { appearance }
secondaryColor = { secIconColor }
size = { iconSize } />
);
default:
return (
<EditorInfoIcon
label = { appearance }
secondaryColor = { secIconColor }
size = { iconSize } />
);
}
}
}
export default translate(Notification);