initial pass on audio-only calls

This commit is contained in:
or-else
2023-01-04 12:47:02 -08:00
parent 1bc6f87844
commit 80d48077c9
23 changed files with 180 additions and 40 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "Call",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+4
View File
@@ -500,6 +500,10 @@
"defaultMessage": "Archive",
"description": "Move topic from the list of active chats to archive"
},
"menu_item_audio_call": {
"defaultMessage": "Call",
"description": "Start audio call"
},
"menu_item_block": {
"defaultMessage": "Block",
"description": "Block topic or user"
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+7
View File
@@ -1542,5 +1542,12 @@
"description": "Label for call in progress",
"missing": false,
"obsolete": false
},
"menu_item_audio_call": {
"translation": "",
"defaultMessage": "Call",
"description": "Start audio call",
"missing": true,
"obsolete": false
}
}
+1
View File
@@ -1348,6 +1348,7 @@ class MessagesView extends React.Component {
topic={this.state.topic}
seq={this.props.callSeq}
callState={this.props.callState}
callAudioOnly={this.props.callAudioOnly}
tinode={this.props.tinode}
title={this.state.title}
avatar={this.state.avatar || true}
+31 -6
View File
@@ -69,6 +69,11 @@ const messages = defineMessages({
defaultMessage: 'Info',
description: 'Show extended topic information'
},
menu_item_audio_call: {
id: 'menu_item_audio_call',
defaultMessage: 'Call',
description: 'Start audio call'
},
menu_item_video_call: {
id: 'menu_item_video_call',
defaultMessage: 'Video call',
@@ -158,6 +163,7 @@ class TinodeWeb extends React.Component {
this.handleHideForwardDialog = this.handleHideForwardDialog.bind(this);
this.handleStartVideoCall = this.handleStartVideoCall.bind(this);
this.handleStartAudioCall = this.handleStartAudioCall.bind(this);
this.handleInfoMessage = this.handleInfoMessage.bind(this);
this.handleDataMessage = this.handleDataMessage.bind(this);
this.handleCallClose = this.handleCallClose.bind(this);
@@ -233,6 +239,7 @@ class TinodeWeb extends React.Component {
// Video calls.
callTopic: undefined,
callState: CALL_STATE_NONE,
callAudioOnly: undefined,
// If true, call state should be transitioned to CALL_STATE_IN_PROGRESS upon
// switching to the call topic.
callShouldStart: false,
@@ -1584,6 +1591,10 @@ class TinodeWeb extends React.Component {
title: this.props.intl.formatMessage(messages.menu_item_info),
handler: this.handleShowInfoView
} : null,
subscribed && Tinode.isP2PTopicName(topicName) && webrtc ? {
title: this.props.intl.formatMessage(messages.menu_item_audio_call),
handler: this.handleStartAudioCall
} : null,
subscribed && Tinode.isP2PTopicName(topicName) && webrtc ? {
title: this.props.intl.formatMessage(messages.menu_item_video_call),
handler: this.handleStartVideoCall
@@ -1709,14 +1720,23 @@ class TinodeWeb extends React.Component {
handleStartVideoCall() {
this.setState({
callTopic: this.state.topicSelected,
callState: CALL_STATE_OUTGOING_INITATED
callState: CALL_STATE_OUTGOING_INITATED,
callAudioOnly: false
});
}
handleCallInvite(callTopic, callSeq, callState) {
handleStartAudioCall() {
this.setState({
callTopic: this.state.topicSelected,
callState: CALL_STATE_OUTGOING_INITATED,
callAudioOnly: true
});
}
handleCallInvite(callTopic, callSeq, callState, audioOnly) {
switch (callState) {
case CALL_STATE_OUTGOING_INITATED:
let head = { webrtc: CALL_HEAD_STARTED };
const head = { webrtc: CALL_HEAD_STARTED, aonly: !!audioOnly };
this.handleSendMessage(Drafty.videoCall(), undefined, undefined, head)
.then(ctrl => {
if (ctrl.code < 200 || ctrl.code >= 300 || !ctrl.params || !ctrl.params.seq) {
@@ -1787,7 +1807,8 @@ class TinodeWeb extends React.Component {
}
this.setState({
callTopic: undefined,
callState: CALL_STATE_NONE
callState: CALL_STATE_NONE,
callAudioOnly: undefined
});
}
@@ -1820,7 +1841,8 @@ class TinodeWeb extends React.Component {
this.setState({
callTopic: null,
callState: CALL_STATE_NONE,
callSeq: null
callSeq: null,
callAudioOnly: undefined
});
return;
}
@@ -1853,7 +1875,8 @@ class TinodeWeb extends React.Component {
this.setState({
callTopic: data.topic,
callState: CALL_STATE_INCOMING_RECEIVED,
callSeq: data.seq
callSeq: data.seq,
callAudioOnly: !!msg.head.aonly
});
} else {
// Another call is either in progress or being established.
@@ -1913,6 +1936,7 @@ class TinodeWeb extends React.Component {
topic={this.state.callTopic}
seq={this.state.callSeq}
callState={this.state.callState}
audioOnly={this.state.callAudioOnly}
onRinging={this.handleCallRinging}
onAcceptCall={this.handleCallAccept}
onReject={this.handleCallHangup}
@@ -2024,6 +2048,7 @@ class TinodeWeb extends React.Component {
callTopic={this.state.callTopic}
callSeq={this.state.callSeq}
callState={this.state.callState}
callAudioOnly={this.state.callAudioOnly}
onCallHangup={this.handleCallHangup}
onCallInvite={this.handleCallInvite}
+15 -10
View File
@@ -37,9 +37,11 @@ class CallPanel extends React.PureComponent {
callInitialSetupComplete: false
};
console.log("CallPanel", props.callAudioOnly);
this.localStreamConstraints = {
audio: true,
video: true
video: !props.callAudioOnly
};
this.isOutgoingCall = props.callState == CALL_STATE_OUTGOING_INITATED;
@@ -146,7 +148,7 @@ class CallPanel extends React.PureComponent {
if (this.props.callState == CALL_STATE_IN_PROGRESS) {
// We apparently just accepted the call.
this.props.onInvite(this.props.topic, this.props.seq, this.props.callState);
this.props.onInvite(this.props.topic, this.props.seq, this.props.callState, this.props.callAudioOnly);
return;
}
@@ -160,7 +162,7 @@ class CallPanel extends React.PureComponent {
DIALING_SOUND.play();
// Send call invitation.
this.props.onInvite(this.props.topic, this.props.seq, this.props.callState);
this.props.onInvite(this.props.topic, this.props.seq, this.props.callState, this.props.callAudioOnly);
})
.catch(this.handleGetUserMediaError);
}
@@ -410,9 +412,12 @@ class CallPanel extends React.PureComponent {
render() {
const remoteActive = this.remoteRef.current && this.remoteRef.current.srcObject;
const disabled = !(this.state.localStream && this.state.localStream.getTracks());
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';
const noVideo = this.props.callAudioOnly;
const audioTracks = this.state.localStream && this.state.localStream.getAudioTracks();
const videoTracks = !noVideo && this.state.localStream && this.state.localStream.getVideoTracks();
const enabled = !!(audioTracks && audioTracks[0]);
const audioIcon = audioTracks && audioTracks[0] && audioTracks[0].enabled ? 'mic' : 'mic_off';
const videoIcon = videoTracks && videoTracks[0] && videoTracks[0].enabled ? 'videocam' : 'videocam_off';
const peerTitle = clipStr(this.props.title, MAX_PEER_TITLE_LENGTH);
const pulseAnimation = this.state.waitingForPeer ? ' pulse' : '';
@@ -420,14 +425,14 @@ class CallPanel extends React.PureComponent {
<>
<div id="video-container">
<div id="video-container-panel">
<div className="call-party self">
<div className="call-party self" disabled={noVideo}>
<video ref={this.localRef} autoPlay muted playsInline />
<div className="caller-name inactive">
<FormattedMessage id="calls_you_label"
defaultMessage="You" description="Shown over the local video screen" />
</div>
</div>
<div className="call-party peer">
<div className="call-party peer" disabled={noVideo}>
<video ref={this.remoteRef} autoPlay playsInline />
{remoteActive ?
<div className="caller-name inactive">{peerTitle}</div> :
@@ -448,10 +453,10 @@ class CallPanel extends React.PureComponent {
<button className="danger" onClick={this.handleCloseClick}>
<i className="material-icons">call_end</i>
</button>
<button className="secondary" onClick={this.handleToggleCameraClick} disabled={disabled}>
<button className="secondary" onClick={this.handleToggleCameraClick} disabled={!enabled}>
<i className="material-icons">{videoIcon}</i>
</button>
<button className="secondary" onClick={this.handleToggleMicClick} disabled={disabled}>
<button className="secondary" onClick={this.handleToggleMicClick} disabled={!enabled}>
<i className="material-icons">{audioIcon}</i>
</button>
</div>