2018-06-26 22:56:22 +00:00
|
|
|
// @flow
|
|
|
|
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
|
|
|
|
import { MEDIA_TYPE } from '../../../base/media';
|
|
|
|
import {
|
|
|
|
Avatar,
|
|
|
|
getAvatarURL,
|
|
|
|
getParticipants,
|
|
|
|
getParticipantDisplayName,
|
|
|
|
getParticipantPresenceStatus
|
|
|
|
} from '../../../base/participants';
|
|
|
|
import { Container, Text } from '../../../base/react';
|
|
|
|
import { isLocalTrackMuted } from '../../../base/tracks';
|
|
|
|
import { CALLING, PresenceLabel } from '../../../presence-status';
|
|
|
|
|
|
|
|
import styles from './styles';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The type of the React {@code Component} props of {@link CalleeInfo}.
|
|
|
|
*/
|
|
|
|
type Props = {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The callee's information such as avatar and display name.
|
|
|
|
*/
|
|
|
|
_callee: Object,
|
|
|
|
|
|
|
|
_isVideoMuted: boolean
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements a React {@link Component} which depicts the establishment of a
|
|
|
|
* call with a specific remote callee.
|
|
|
|
*
|
|
|
|
* @extends Component
|
|
|
|
*/
|
|
|
|
class CalleeInfo extends Component<Props> {
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
avatar,
|
|
|
|
name,
|
|
|
|
status = CALLING
|
|
|
|
} = this.props._callee;
|
|
|
|
const className = this.props._isVideoMuted ? 'solidBG' : undefined;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Container
|
|
|
|
{ ...this._style('ringing', className) }
|
|
|
|
id = 'ringOverlay'>
|
|
|
|
<Container
|
|
|
|
{ ...this._style('ringing__content') }>
|
|
|
|
<Avatar
|
|
|
|
{ ...this._style('ringing__avatar') }
|
|
|
|
uri = { avatar } />
|
|
|
|
<Container { ...this._style('ringing__status') }>
|
|
|
|
<PresenceLabel
|
|
|
|
defaultPresence = { status }
|
2018-07-09 22:18:09 +00:00
|
|
|
{ ...this._style('ringing__text') } />
|
2018-06-26 22:56:22 +00:00
|
|
|
</Container>
|
|
|
|
<Container { ...this._style('ringing__name') }>
|
|
|
|
<Text
|
|
|
|
{ ...this._style('ringing__text') }>
|
|
|
|
{ name }
|
|
|
|
</Text>
|
|
|
|
</Container>
|
|
|
|
</Container>
|
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempts to convert specified CSS class names into React
|
|
|
|
* {@link Component} props {@code style} or {@code className}.
|
|
|
|
*
|
|
|
|
* @param {Array<string>} classNames - The CSS class names to convert
|
|
|
|
* into React {@code Component} props {@code style} or {@code className}.
|
|
|
|
* @returns {{
|
|
|
|
* className: string,
|
|
|
|
* style: Object
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
_style(...classNames: Array<?string>) {
|
|
|
|
let className = '';
|
|
|
|
let style;
|
|
|
|
|
|
|
|
for (const aClassName of classNames) {
|
|
|
|
if (aClassName) {
|
|
|
|
// Attemp to convert aClassName into style.
|
|
|
|
if (styles && aClassName in styles) {
|
|
|
|
// React Native will accept an Array as the value of the
|
|
|
|
// style prop. However, I do not know about React.
|
|
|
|
style = {
|
|
|
|
...style,
|
|
|
|
...styles[aClassName]
|
|
|
|
};
|
|
|
|
} else {
|
|
|
|
// Otherwise, leave it as className.
|
|
|
|
className += `${aClassName} `;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Choose which of the className and/or style props has a value and,
|
|
|
|
// consequently, must be returned.
|
|
|
|
const props = {};
|
|
|
|
|
|
|
|
if (className) {
|
|
|
|
props.className = className.trim();
|
|
|
|
}
|
|
|
|
if (style) {
|
|
|
|
props.style = style;
|
|
|
|
}
|
|
|
|
|
|
|
|
return props;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Maps (parts of) the redux state to {@code CalleeInfo}'s props.
|
|
|
|
*
|
|
|
|
* @param {Object} state - The redux state.
|
|
|
|
* @private
|
|
|
|
* @returns {{
|
|
|
|
* _callee: Object
|
|
|
|
* }}
|
|
|
|
*/
|
|
|
|
function _mapStateToProps(state) {
|
|
|
|
const _isVideoMuted
|
|
|
|
= isLocalTrackMuted(state['features/base/tracks'], MEDIA_TYPE.VIDEO);
|
|
|
|
const poltergeist
|
|
|
|
= getParticipants(state).find(p => p.botType === 'poltergeist');
|
|
|
|
|
|
|
|
if (poltergeist) {
|
|
|
|
const { id } = poltergeist;
|
|
|
|
|
|
|
|
return {
|
|
|
|
_callee: {
|
|
|
|
avatar: getAvatarURL(poltergeist),
|
|
|
|
name: getParticipantDisplayName(state, id),
|
|
|
|
status: getParticipantPresenceStatus(state, id)
|
|
|
|
},
|
|
|
|
_isVideoMuted
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
_callee: state['features/invite'].initialCalleeInfo,
|
|
|
|
_isVideoMuted
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-03-19 15:42:25 +00:00
|
|
|
// $FlowExpectedError
|
2018-06-26 22:56:22 +00:00
|
|
|
export default connect(_mapStateToProps)(CalleeInfo);
|