Add dial-in link to no audio notification (#5026)

* Add dial-in link to no audio notification

* refactor react link component

* fix tests
This commit is contained in:
Andrei Gavrilescu 2020-02-05 20:10:57 +02:00 committed by GitHub
parent b64260e554
commit ed5351d250
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 130 additions and 25 deletions

View File

@ -635,8 +635,10 @@
"moreActions": "More actions",
"mute": "Mute / Unmute",
"noAudioSignalTitle": "There is no input coming from your mic!",
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider changing the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider using the following device:",
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
"noAudioSignalDialInDesc": "You can also dial-in using:",
"noAudioSignalDialInLinkDesc" : "Dial-in numbers",
"noisyAudioInputTitle": "Your microphone appears to be noisy!",
"noisyAudioInputDesc": "Jitsi has detected noise coming from your microphone, please consider muting or changing the device.",
"openChat": "Open chat",

View File

@ -17,7 +17,8 @@ import {
import {
_decodeRoomURI,
_getDefaultPhoneNumber,
getDialInfoPageURL
getDialInfoPageURL,
shouldDisplayDialIn
} from '../../../functions';
import logger from '../../../logger';
import DialInNumber from './DialInNumber';
@ -316,7 +317,6 @@ class InfoDialog extends Component<Props, State> {
*/
_getTextToCopy() {
const { _localParticipant, liveStreamViewURL, t } = this.props;
const shouldDisplayDialIn = this._shouldDisplayDialIn();
const _inviteURL = _decodeRoomURI(this.props._inviteURL);
let invite = _localParticipant && _localParticipant.name
@ -335,7 +335,7 @@ class InfoDialog extends Component<Props, State> {
invite = `${invite}\n${liveStream}`;
}
if (shouldDisplayDialIn) {
if (shouldDisplayDialIn(this.props.dialIn)) {
const dial = t('info.invitePhone', {
number: this.state.phoneNumber,
conferenceID: this.props.dialIn.conferenceID
@ -480,7 +480,7 @@ class InfoDialog extends Component<Props, State> {
* @returns {null|ReactElement}
*/
_renderDialInDisplay() {
if (!this._shouldDisplayDialIn()) {
if (!shouldDisplayDialIn(this.props.dialIn)) {
return null;
}
@ -571,23 +571,6 @@ class InfoDialog extends Component<Props, State> {
);
}
/**
* Returns whether or not dial-in related UI should be displayed.
*
* @private
* @returns {boolean}
*/
_shouldDisplayDialIn() {
const { conferenceID, numbers, numbersEnabled } = this.props.dialIn;
const { phoneNumber } = this.state;
return Boolean(
conferenceID
&& numbers
&& numbersEnabled
&& phoneNumber);
}
_setCopyElement: () => void;
/**

View File

@ -524,6 +524,23 @@ export function getDialInfoPageURLForURIString(
return `${protocol}//${host}${contextRoot}static/dialInInfo.html?room=${room}`;
}
/**
* Returns whether or not dial-in related UI should be displayed.
*
* @param {Object} dialIn - Dial in information.
* @returns {boolean}
*/
export function shouldDisplayDialIn(dialIn: Object) {
const { conferenceID, numbers, numbersEnabled } = dialIn;
const phoneNumber = _getDefaultPhoneNumber(numbers);
return Boolean(
conferenceID
&& numbers
&& numbersEnabled
&& phoneNumber);
}
/**
* Sets the internal state of which dial-in number to display.
*
@ -533,7 +550,11 @@ export function getDialInfoPageURLForURIString(
* @returns {string|null}
*/
export function _getDefaultPhoneNumber(
dialInNumbers: Object): ?string {
dialInNumbers: ?Object): ?string {
if (!dialInNumbers) {
return null;
}
if (Array.isArray(dialInNumbers)) {
// new syntax follows

View File

@ -0,0 +1,95 @@
// @flow
import React, { Component } from 'react';
import { connect } from '../../base/redux';
import { translate } from '../../base/i18n';
import { getDialInfoPageURL, shouldDisplayDialIn } from '../../invite';
/**
* The type of the React {@code Component} props of {@link DialInLink}.
*/
type Props = {
/**
* The name of the current conference.
*/
_room: string,
/**
* The current location url of the conference.
*/
_locationURL: string,
/**
* The redux state representing the dial-in numbers feature.
*/
_dialIn: Object,
/**
* Invoked to obtain translated strings.
*/
t: Function
};
/**
* React {@code Component} responsible for displaying a telephone number and
* conference ID for dialing into a conference.
*
* @extends Component
*/
class DialInLink extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { _room, _locationURL, _dialIn, t } = this.props;
if (!shouldDisplayDialIn(_dialIn)) {
return null;
}
return (
<div>{t('toolbar.noAudioSignalDialInDesc')}&nbsp;
<a
href = {
getDialInfoPageURL(
_room,
_locationURL
)
}
rel = 'noopener noreferrer'
target = '_blank'>
{t('toolbar.noAudioSignalDialInLinkDesc')}
</a>
</div>
);
}
}
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code DialInLink} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* _room: string,
* _locationURL: string,
* _dialIn: Object,
* }}
*/
function _mapStateToProps(state) {
return {
_room: state['features/base/conference'].room,
_locationURL: state['features/base/connection'].locationURL,
_dialIn: state['features/invite']
};
}
export default translate(connect(_mapStateToProps)(DialInLink));

View File

@ -1,5 +1,7 @@
// @flow
import React from 'react';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
import { CONFERENCE_JOINED } from '../base/conference';
import {
@ -13,6 +15,7 @@ import { playSound, registerSound, unregisterSound } from '../base/sounds';
import { hideNotification, showNotification } from '../notifications';
import { setNoAudioSignalNotificationUid } from './actions';
import DialInLink from './components/DialInLink';
import { NO_AUDIO_SIGNAL_SOUND_ID } from './constants';
import { NO_AUDIO_SIGNAL_SOUND_FILE } from './sounds';
@ -91,7 +94,7 @@ async function _handleNoAudioSignalNotification({ dispatch, getState }, action)
// at the point of the implementation the showNotification function only supports doing that for
// the description.
// TODO Add support for arguments to showNotification title and customAction strings.
customActionNameKey = `Use ${formatDeviceLabel(activeDevice.deviceLabel)}`;
customActionNameKey = `Switch to ${formatDeviceLabel(activeDevice.deviceLabel)}`;
customActionHandler = () => {
// Select device callback
dispatch(
@ -107,6 +110,7 @@ async function _handleNoAudioSignalNotification({ dispatch, getState }, action)
const notification = showNotification({
titleKey: 'toolbar.noAudioSignalTitle',
description: <DialInLink />,
descriptionKey,
customActionNameKey,
customActionHandler