made incoming calls panel prettier

This commit is contained in:
or-else
2022-05-27 15:09:53 -07:00
parent ff605369be
commit 50c8c61078
9 changed files with 303 additions and 308 deletions
+155
View File
@@ -0,0 +1,155 @@
// IncomingCallView: displays Accept & Reject buttons for incoming calls.
import React from 'react';
import { FormattedMessage } from 'react-intl';
import BadgeList from './badge-list.jsx';
import LetterTile from './letter-tile.jsx';
import { MAX_TITLE_LENGTH, MAX_PEER_TITLE_LENGTH } from '../config.js';
import { CALL_STATE_INCOMING_RECEIVED } from '../constants.js';
import { makeImageUrl } from '../lib/blob-helpers.js';
import { clipStr } from '../lib/utils.js'
const RING_SOUND = new Audio('audio/call-in.m4a');
export default class IncomingCallView extends React.Component {
constructor(props) {
super(props);
this.state = {
topic: null,
fullName: undefined,
avatar: null,
trustedBadges: [],
previousMetaDesc: undefined,
};
this.resetDesc = this.resetDesc.bind(this);
this.onMetaDesc = this.onMetaDesc.bind(this);
this.handleRejectCall = this.handleRejectCall.bind(this);
this.handleAcceptCall = this.handleAcceptCall.bind(this);
this.ringTimer = null;
}
componentDidMount() {
const topic = this.props.tinode.getTopic(this.props.topic);
if (!topic) {
return;
}
this.resetDesc(topic, this.props);
if (this.props.callState == CALL_STATE_INCOMING_RECEIVED) {
RING_SOUND.play();
this.ringTimer = setInterval(() => RING_SOUND.play(), 2000);
this.props.onRinging(this.props.topic, this.props.seq);
}
}
// No need to separately handle component mount.
componentDidUpdate(props) {
const topic = this.props.tinode.getTopic(props.topic);
if (!topic) {
return;
}
if (this.onMetaDesc != topic.onMetaDesc) {
this.previousMetaDesc = topic.onMetaDesc;
topic.onMetaDesc = this.onMetaDesc;
}
if (this.state.topic != props.topic) {
this.setState({topic: props.topic});
this.resetDesc(topic, props);
}
}
componentWillUnmount() {
if (this.ringTimer != null) {
clearInterval(this.ringTimer);
RING_SOUND.pause();
}
const topic = this.props.tinode.getTopic(this.props.topic);
if (!topic) {
return;
}
this.setState({topic: null});
topic.onMetaDesc = this.previousMetaDesc;
}
resetDesc(topic, props) {
const defacs = topic.getDefaultAccess() || {};
const acs = topic.getAccessMode();
const badges = [];
if (topic.trusted) {
for (const [key, val] of Object.entries(topic.trusted)) {
if (val) {
badges.push(key);
}
}
}
this.setState({
fullName: clipStr(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
trustedBadges: badges,
});
}
onMetaDesc(desc) {
const topic = this.props.tinode.getTopic(this.props.topic);
if (!topic) {
return;
}
this.resetDesc(topic, this.props);
if (this.previousMetaDesc && this.previousMetaDesc != this.onMetaDesc) {
this.previousMetaDesc(desc);
}
}
handleAcceptCall() {
this.props.onAcceptCall(this.props.topic);
}
handleRejectCall() {
this.props.onReject(this.props.topic, this.props.seq);
this.props.onClose();
}
render() {
return (
<div className="alert-container">
<div className="incoming-call">
<div className="caller-card incoming">
<div className="avatar-box">
<LetterTile
tinode={this.props.tinode}
avatar={this.state.avatar || true}
topic={this.props.topic}
title={this.state.fullName} />
</div>
<div className="caller-name">{clipStr(this.state.fullName, MAX_PEER_TITLE_LENGTH)}</div>
</div>
<div className="group incoming-call-badges">
<BadgeList trustedBadges={this.state.trustedBadges} />
</div>
<div className="controls">
{this.props.callState == CALL_STATE_INCOMING_RECEIVED ?
<>
<button className="danger" onClick={this.handleRejectCall}>
<i className="material-icons">call_end</i>
</button>
<button className="positive" onClick={this.handleAcceptCall}>
<i className="material-icons">call</i>
</button>
</>
:
null
}
</div>
</div>
</div>
);
}
};
+7 -7
View File
@@ -1,8 +1,8 @@
// CallPanel: displays local and remote viewports and controls.
// CallPanel displays call in progress: local and remote viewports and controls.
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import LetterTile from '../widgets/letter-tile.jsx';
import LetterTile from './letter-tile.jsx';
import { CALL_WEBRTC_CONFIG, MAX_PEER_TITLE_LENGTH } from '../config.js';
import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS } from '../constants.js';
@@ -353,7 +353,7 @@ class CallPanel extends React.PureComponent {
<div id="video-container-panel">
<div className="call-party self">
<video ref={this.localRef} autoPlay muted playsInline></video>
<div className="title inactive">
<div className="caller-name inactive">
<FormattedMessage id="calls_you_label"
defaultMessage="You" description="Shown over the local video screen" />
</div>
@@ -361,8 +361,8 @@ class CallPanel extends React.PureComponent {
<div className="call-party peer">
<video ref={this.remoteRef} autoPlay playsInline></video>
{remoteActive ?
<div className="title inactive">{peerTitle}</div> :
<div className="peer-card">
<div className="caller-name inactive">{peerTitle}</div> :
<div className="caller-card">
<div className="avatar-box">
<LetterTile
tinode={this.props.tinode}
@@ -370,12 +370,12 @@ class CallPanel extends React.PureComponent {
topic={this.props.topic}
title={this.props.title} />
</div>
<div className="title">{peerTitle}</div>
<div className="caller-name">{peerTitle}</div>
</div>
}
</div>
</div>
<div id="video-container-controls">
<div className="controls">
<button className="danger" onClick={this.handleCloseClick}><i className="material-icons">call_end</i></button>
<button className="secondary" onClick={this.handleToggleCameraClick}><i className="material-icons">{videoIcon}</i></button>
<button className="secondary" onClick={this.handleToggleMicClick}><i className="material-icons">{audioIcon}</i></button>