a bit more work on sizing video
This commit is contained in:
+21
-8
@@ -1604,29 +1604,42 @@ img.channel {
|
||||
|
||||
#video-container-panel {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.video-elem {
|
||||
width: 50%;
|
||||
position: relative;
|
||||
background-color: #eee;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid #ccc;
|
||||
margin: 0.25rem;
|
||||
box-sizing: content-box;
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
|
||||
.video-elem:hover {
|
||||
border: 2px solid #2196f3;
|
||||
}
|
||||
|
||||
.video-elem.peer {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.video-elem.self {
|
||||
position: absolute;
|
||||
right: 0.5rem;
|
||||
bottom: 0.5rem;
|
||||
width: 10rem;
|
||||
height: 10rem;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* "You" badge. */
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "You already in an ongoing call!",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": false,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
"defaultMessage": "Report Conversation",
|
||||
"description": "Flat button [Report Group]"
|
||||
},
|
||||
"already_in_call": {
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one"
|
||||
},
|
||||
"archived_contacts": {
|
||||
"defaultMessage": "Archived contacts ({count})",
|
||||
"description": "Label for archived chats"
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,5 +1409,12 @@
|
||||
"description": "Start video call",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
},
|
||||
"already_in_call": {
|
||||
"translation": "",
|
||||
"defaultMessage": "You already in an ongoing call!",
|
||||
"description": "Error message when the user tried to accept a new call without finishing pervious one",
|
||||
"missing": true,
|
||||
"obsolete": false
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -1062,8 +1062,7 @@ class MessagesView extends React.Component {
|
||||
onInvite={this.props.onCallInvite}
|
||||
onSendOffer={this.props.onCallSendOffer}
|
||||
onIceCandidate={this.props.onCallIceCandidate}
|
||||
onSendAnswer={this.props.onCallSendAnswer}
|
||||
/>
|
||||
onSendAnswer={this.props.onCallSendAnswer} />
|
||||
);
|
||||
} else {
|
||||
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||
|
||||
+77
-63
@@ -1,6 +1,6 @@
|
||||
// CallPanel: displays local and remote viewports and controls.
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import LetterTile from '../widgets/letter-tile.jsx';
|
||||
|
||||
@@ -9,7 +9,15 @@ import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS } from '../constan
|
||||
|
||||
import { clipStr } from '../lib/utils.js'
|
||||
|
||||
export default class CallPanel extends React.PureComponent {
|
||||
const messages = defineMessages({
|
||||
already_in_call: {
|
||||
id: 'already_in_call',
|
||||
defaultMessage: 'You already in an ongoing call!',
|
||||
description: 'Error message when the user tried to accept a new call without finishing pervious one',
|
||||
}
|
||||
});
|
||||
|
||||
class CallPanel extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
@@ -108,24 +116,64 @@ export default class CallPanel extends React.PureComponent {
|
||||
|
||||
start() {
|
||||
if (this.state.localStream) {
|
||||
console.log("You can't start a call because you already have one open!");
|
||||
} else {
|
||||
if (this.props.callState == CALL_STATE_IN_PROGRESS) {
|
||||
// We apparently just accepted the call.
|
||||
this.props.onInvite(this.props.topic.name, this.props.seq, this.props.callState);
|
||||
return;
|
||||
}
|
||||
// This is an outgoing call waiting for the other side to pick up.
|
||||
// Start local video.
|
||||
navigator.mediaDevices.getUserMedia(this.localStreamConstraints)
|
||||
.then(stream => {
|
||||
this.setState({localStream: stream});
|
||||
this.localRef.current.srcObject = stream;
|
||||
// Send call invitation.
|
||||
this.props.onInvite(this.props.topic.name, this.props.seq, this.props.callState);
|
||||
})
|
||||
.catch(this.handleGetUserMediaError);
|
||||
this.props.onError(this.props.intl.formatMessage(messages.already_in_call));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.props.callState == CALL_STATE_IN_PROGRESS) {
|
||||
// We apparently just accepted the call.
|
||||
this.props.onInvite(this.props.topic.name, this.props.seq, this.props.callState);
|
||||
return;
|
||||
}
|
||||
|
||||
// This is an outgoing call waiting for the other side to pick up.
|
||||
// Start local video.
|
||||
navigator.mediaDevices.getUserMedia(this.localStreamConstraints)
|
||||
.then(stream => {
|
||||
this.setState({localStream: stream});
|
||||
this.localRef.current.srcObject = stream;
|
||||
// Send call invitation.
|
||||
this.props.onInvite(this.props.topic.name, this.props.seq, this.props.callState);
|
||||
})
|
||||
.catch(this.handleGetUserMediaError);
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.stopTracks(this.localRef.current);
|
||||
this.stopTracks(this.remoteRef.current);
|
||||
if (this.state.pc) {
|
||||
this.state.pc.ontrack = null;
|
||||
this.state.pc.onremovetrack = null;
|
||||
this.state.pc.onremovestream = null;
|
||||
this.state.pc.onicecandidate = null;
|
||||
this.state.pc.oniceconnectionstatechange = null;
|
||||
this.state.pc.onsignalingstatechange = null;
|
||||
this.state.pc.onicegatheringstatechange = null;
|
||||
this.state.pc.onnegotiationneeded = null;
|
||||
|
||||
this.state.pc.close();
|
||||
}
|
||||
this.setState({pc: null});
|
||||
}
|
||||
|
||||
stopTracks(el) {
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
let stream = el.srcObject;
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tracks = stream.getTracks();
|
||||
if (tracks) {
|
||||
tracks.forEach(track => {
|
||||
track.stop();
|
||||
track.enabled = false;
|
||||
});
|
||||
}
|
||||
el.srcObject = null;
|
||||
el.src = '';
|
||||
}
|
||||
|
||||
createPeerConnection() {
|
||||
@@ -257,40 +305,6 @@ export default class CallPanel extends React.PureComponent {
|
||||
this.handleCloseClick();
|
||||
}
|
||||
|
||||
stopTracks(el) {
|
||||
if (el == null) { return; }
|
||||
let stream = el.srcObject;
|
||||
if (stream == null) { return; }
|
||||
let tracks = stream.getTracks();
|
||||
|
||||
if (tracks != null) {
|
||||
tracks.forEach((track) => {
|
||||
track.stop();
|
||||
track.enabled = false;
|
||||
});
|
||||
}
|
||||
el.srcObject = null;
|
||||
el.src = '';
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.stopTracks(this.localRef.current);
|
||||
this.stopTracks(this.remoteRef.current);
|
||||
if (this.state.pc != null) {
|
||||
this.state.pc.ontrack = null;
|
||||
this.state.pc.onremovetrack = null;
|
||||
this.state.pc.onremovestream = null;
|
||||
this.state.pc.onicecandidate = null;
|
||||
this.state.pc.oniceconnectionstatechange = null;
|
||||
this.state.pc.onsignalingstatechange = null;
|
||||
this.state.pc.onicegatheringstatechange = null;
|
||||
this.state.pc.onnegotiationneeded = null;
|
||||
|
||||
this.state.pc.close();
|
||||
}
|
||||
this.setState({pc: null});
|
||||
}
|
||||
|
||||
handleCloseClick() {
|
||||
this.stop();
|
||||
this.props.onHangup(this.props.topic.name, this.props.seq);
|
||||
@@ -322,23 +336,23 @@ export default class CallPanel extends React.PureComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
const remoteActive = this.remoteRef.current != null && this.remoteRef.current.srcObject != null;
|
||||
const audioIcon = this.state.localStream != null && this.state.localStream.getAudioTracks()[0].enabled ? 'mic' : 'mic_off';
|
||||
const videoIcon = this.state.localStream != null && this.state.localStream.getVideoTracks()[0].enabled ? 'videocam' : 'videocam_off';
|
||||
const remoteActive = this.remoteRef.current && this.remoteRef.current.srcObject;
|
||||
const audioIcon = this.state.localStream && this.state.localStream.getAudioTracks()[0].enabled ? 'mic' : 'mic_off';
|
||||
const videoIcon = this.state.localStream && this.state.localStream.getVideoTracks()[0].enabled ? 'videocam' : 'videocam_off';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id="video-container">
|
||||
<div id="video-container-panel">
|
||||
<div className="video-elem">
|
||||
<video id="localVideo" ref={this.localRef} autoPlay muted playsInline></video>
|
||||
<div className="video-elem self">
|
||||
<video ref={this.localRef} autoPlay muted playsInline></video>
|
||||
<div className="video-title">
|
||||
<FormattedMessage id="calls_you_label"
|
||||
defaultMessage="You" description="Shown over the local video screen" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="video-elem">
|
||||
<video id="remoteVideo" ref={this.remoteRef} autoPlay playsInline></video>
|
||||
<div className="video-elem peer">
|
||||
<video ref={this.remoteRef} autoPlay playsInline></video>
|
||||
{remoteActive ?
|
||||
<div className="video-title">{clipStr(this.props.title, MAX_TITLE_LENGTH)}</div>
|
||||
:
|
||||
@@ -346,9 +360,7 @@ export default class CallPanel extends React.PureComponent {
|
||||
</div>
|
||||
</div>
|
||||
<div id="video-container-controls">
|
||||
<button className="danger" onClick={this.handleCloseClick}>
|
||||
<i className="material-icons">call_end</i>
|
||||
</button>
|
||||
<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>
|
||||
</div>
|
||||
@@ -357,3 +369,5 @@ export default class CallPanel extends React.PureComponent {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default injectIntl(CallPanel);
|
||||
|
||||
+79
-68
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user