Video calls: some more cleaup.

This commit is contained in:
aforge
2022-04-22 20:43:10 -07:00
parent 0daef53c87
commit c4d4aa77db
7 changed files with 78 additions and 68 deletions
+20 -1
View File
@@ -2633,7 +2633,12 @@ video {
padding: 20px;
}
#video-call-hangup {
.video-call-accept {
border-radius: 10px;
background-color: green;
}
.video-call-hangup {
border-radius: 10px;
background-color: red;
}
@@ -2642,3 +2647,17 @@ video {
border-radius: 10px;
background-color: gray;
}
.incoming-call-title {
text-align: center;
padding: 10px;
}
.incoming-call-badges {
text-align: center;
}
.incoming-call-actions {
text-align: center;
padding: 20px;
}
+5
View File
@@ -209,3 +209,8 @@ export function cancelablePromise(promise) {
export function isVideoCall(mime) {
return mime == 'application/tinode-video-call';
}
// Clips string to the specified length.
export function clipStr(str, length) {
return str && str.substring(0, length);
}
@@ -1,6 +1,6 @@
// InfoView: panel with topic/user info.
// IncomingCallView: displays Accept & Reject buttons for incoming calls.
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { FormattedMessage, injectIntl } from 'react-intl';
import Tinode from 'tinode-sdk';
@@ -8,18 +8,14 @@ import AvatarUpload from '../widgets/avatar-upload.jsx';
import BadgeList from '../widgets/badge-list.jsx';
import MenuCancel from '../widgets/menu-cancel.jsx';
import { MAX_TITLE_LENGTH, MAX_TOPIC_DESCRIPTION_LENGTH, NO_ACCESS_MODE } from '../config.js';
import { CALL_STATE_INCOMING_RECEIVED, MAX_TITLE_LENGTH } from '../config.js';
import { makeImageUrl } from '../lib/blob-helpers.js';
import { arrayEqual, theCard } from '../lib/utils.js';
function _clip(str, length) {
return str && str.substring(0, length);
}
import { clipStr } from '../lib/utils.js'
const RING_SOUND = new Audio("audio/phone_ring.mp3");
class CallView extends React.Component {
class IncomingCallView extends React.Component {
constructor(props) {
super(props);
@@ -29,7 +25,6 @@ class CallView extends React.Component {
avatar: null,
trustedBadges: [],
previousMetaDesc: undefined,
offerSent: false,
};
this.resetDesc = this.resetDesc.bind(this);
@@ -45,7 +40,7 @@ class CallView extends React.Component {
return;
}
this.resetDesc(topic, this.props);
if (this.props.callState == 2) {
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);
@@ -96,7 +91,7 @@ class CallView extends React.Component {
}
this.setState({
fullName: _clip(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
fullName: clipStr(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
trustedBadges: badges,
});
@@ -126,16 +121,9 @@ class CallView extends React.Component {
render() {
const {formatMessage} = this.props.intl;
let panelTitle = 'Unknown';
switch (this.props.callState) {
case 1:
panelTitle = 'Calling';
break;
case 2:
panelTitle = 'Incoming Call From';
break;
case 3:
panelTitle = 'Call Established';
break;
if (this.props.callState == CALL_STATE_INCOMING_RECEIVED) {
panelTitle = <FormattedMessage id="calls_incoming_title"
defaultMessage="Incoming Call" description="Incoming call title (Incoming call view)" />;
}
return (
@@ -146,43 +134,41 @@ class CallView extends React.Component {
<MenuCancel onCancel={this.handleRejectCall} />
</div>
</div>
<div id="info-view-content" className="scrollable-panel">
<div className="panel-form-column">
<center>
<AvatarUpload
tinode={this.props.tinode}
avatar={this.state.avatar}
readOnly={true}
uid={this.props.topic}
title={this.state.fullName} />
</center>
<div className="group" style={{padding: "10px", textAlign: "center"}}>
<div className="large ellipsized">{this.state.fullName}</div>
</div>
<div className="group" style={{textAlign: "center"}}>
<BadgeList trustedBadges={this.state.trustedBadges} />
</div>
<div id="actions" className="group" style={{padding: "20px", textAlign: "center"}}>
{this.props.callState >= 1 && this.props.callState < 3 ?
<button onClick={this.handleRejectCall} style={{borderRadius: "10px", backgroundColor: "red"}}>
<div id="info-view-content" className="scrollable-panel">
<div className="panel-form-column">
<center>
<AvatarUpload
tinode={this.props.tinode}
avatar={this.state.avatar}
readOnly={true}
uid={this.props.topic}
title={this.state.fullName} />
</center>
<div className="group incoming-call-title">
<div className="large ellipsized">{clipStr(this.state.fullName)}</div>
</div>
<div className="group incoming-call-badges">
<BadgeList trustedBadges={this.state.trustedBadges} />
</div>
<div id="actions" className="group incoming-call-actions">
{this.props.callState == CALL_STATE_INCOMING_RECEIVED ?
<>
<button className="video-call-hangup" onClick={this.handleRejectCall}>
<i className="material-icons">call_end</i>
</button>
:
null
}
{this.props.callState >= 2 && this.props.callState < 3 ?
<button onClick={this.handleAcceptCall} style={{borderRadius: "10px", backgroundColor: "green"}}>
<button className="video-call-accept" onClick={this.handleAcceptCall}>
<i className="material-icons">call</i>
</button>
:
null
}
</div>
</>
:
null
}
</div>
</div>
</div>
</div>
);
}
};
export default injectIntl(CallView);
export default injectIntl(IncomingCallView);
+4 -8
View File
@@ -18,7 +18,7 @@ import TopicSecurity from '../widgets/topic-security.jsx';
import { MAX_TITLE_LENGTH, MAX_TOPIC_DESCRIPTION_LENGTH, NO_ACCESS_MODE } from '../config.js';
import { makeImageUrl } from '../lib/blob-helpers.js';
import { theCard } from '../lib/utils.js';
import { theCard, clipStr } from '../lib/utils.js';
const messages = defineMessages({
info: {
@@ -78,10 +78,6 @@ const messages = defineMessages({
},
});
function _clip(str, length) {
return str && str.substring(0, length);
}
class InfoView extends React.Component {
constructor(props) {
super(props);
@@ -206,11 +202,11 @@ class InfoView extends React.Component {
deleter: acs && acs.isDeleter(),
muted: acs && acs.isMuted(),
fullName: _clip(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
description: _clip(topic.public ? topic.public.note : undefined, MAX_TOPIC_DESCRIPTION_LENGTH),
fullName: clipStr(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
description: clipStr(topic.public ? topic.public.note : undefined, MAX_TOPIC_DESCRIPTION_LENGTH),
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
trustedBadges: badges,
private: _clip(topic.private ? topic.private.comment : null, MAX_TITLE_LENGTH),
private: clipStr(topic.private ? topic.private.comment : null, MAX_TITLE_LENGTH),
archived: topic.isArchived(),
address: topic.name,
groupTopic: topic.isGroupType(),
+2 -2
View File
@@ -14,7 +14,7 @@ import Invitation from '../widgets/invitation.jsx';
import LetterTile from '../widgets/letter-tile.jsx';
import LoadSpinner from '../widgets/load-spinner.jsx';
import LogoView from './logo-view.jsx';
import RtcPanel from '../widgets/rtc-panel.jsx';
import CallPanel from '../widgets/call-panel.jsx';
import SendMessage from '../widgets/send-message.jsx';
import { DEFAULT_P2P_ACCESS_MODE, IMAGE_PREVIEW_DIM, KEYPRESS_DELAY,
@@ -984,7 +984,7 @@ class MessagesView extends React.Component {
} else if (this.state.rtcPanel) {
const topic = this.props.tinode.getTopic(this.state.topic);
component2 = (
<RtcPanel
<CallPanel
topic={topic}
seq={this.props.callSeq}
callState={this.props.callState}
+2 -2
View File
@@ -12,7 +12,7 @@ import ContextMenu from '../widgets/context-menu.jsx';
import ForwardDialog from '../widgets/forward-dialog.jsx';
import InfoView from './info-view.jsx';
import CallView from './call-view.jsx';
import IncomingCallView from './incoming-call-view.jsx';
import MessagesView from './messages-view.jsx';
import SidepanelView from './sidepanel-view.jsx';
@@ -2024,7 +2024,7 @@ class TinodeWeb extends React.Component {
}
{this.state.callTopic && this.state.callState == CALL_STATE_INCOMING_RECEIVED ?
<CallView
<IncomingCallView
tinode={this.tinode}
onClose={this.handleCallClose}
topic={this.state.callTopic}
@@ -1,11 +1,15 @@
// CallPanel: displays local and remote viewports and controls.
import React from 'react';
import { FormattedMessage } from 'react-intl';
import LetterTile from '../widgets/letter-tile.jsx';
import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS, CALL_WEBRTC_CONFIG } from '../config.js';
import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS, CALL_WEBRTC_CONFIG,
MAX_TITLE_LENGTH } from '../config.js';
export default class RtcPanel extends React.PureComponent {
import { clipStr } from '../lib/utils.js'
export default class CallPanel extends React.PureComponent {
constructor(props) {
super(props);
@@ -372,13 +376,13 @@ export default class RtcPanel extends React.PureComponent {
<div className="video-elem">
<video id="remoteVideo" ref={this.remoteRef} autoPlay playsInline></video>
{remoteActive ?
<div className="video-title">{this.props.title}</div>
<div className="video-title">{clipStr(this.props.title, MAX_TITLE_LENGTH)}</div>
:
null}
</div>
</div>
<div id="video-container-controls">
<button id="video-call-hangup" onClick={this.handleCloseClick}>
<button className="video-call-hangup" onClick={this.handleCloseClick}>
<i className="material-icons">call_end</i>
</button>
<button className="video-call-toggle-media" onClick={this.handleToggleCameraClick}><i className="material-icons">{videoIcon}</i></button>