Redux state: Allow multiple calls to be stored
This commit is contained in:
parent
753e0279c6
commit
3468de255d
21 changed files with 1191 additions and 515 deletions
|
@ -21,10 +21,7 @@ import {
|
|||
UserId,
|
||||
} from 'ringrtc';
|
||||
|
||||
import {
|
||||
ActionsType as UxActionsType,
|
||||
CallDetailsType,
|
||||
} from '../state/ducks/calling';
|
||||
import { ActionsType as UxActionsType } from '../state/ducks/calling';
|
||||
import { EnvelopeClass } from '../textsecure.d';
|
||||
import { AudioDevice, MediaDeviceSettings } from '../types/Calling';
|
||||
import { ConversationModel } from '../models/conversations';
|
||||
|
@ -48,9 +45,13 @@ export class CallingClass {
|
|||
|
||||
private deviceReselectionTimer?: NodeJS.Timeout;
|
||||
|
||||
private callsByConversation: { [conversationId: string]: Call };
|
||||
|
||||
constructor() {
|
||||
this.videoCapturer = new GumVideoCapturer(640, 480, 30);
|
||||
this.videoRenderer = new CanvasVideoRenderer();
|
||||
|
||||
this.callsByConversation = {};
|
||||
}
|
||||
|
||||
initialize(uxActions: UxActionsType): void {
|
||||
|
@ -101,12 +102,8 @@ export class CallingClass {
|
|||
|
||||
window.log.info('CallingClass.startCallingLobby(): Starting lobby');
|
||||
this.uxActions.showCallLobby({
|
||||
callDetails: {
|
||||
...conversationProps,
|
||||
callId: undefined,
|
||||
isIncoming: false,
|
||||
isVideoCall,
|
||||
},
|
||||
conversationId: conversationProps.id,
|
||||
isVideoCall,
|
||||
});
|
||||
|
||||
await this.startDeviceReselectionTimer();
|
||||
|
@ -124,7 +121,8 @@ export class CallingClass {
|
|||
|
||||
async startOutgoingCall(
|
||||
conversationId: string,
|
||||
isVideoCall: boolean
|
||||
hasLocalAudio: boolean,
|
||||
hasLocalVideo: boolean
|
||||
): Promise<void> {
|
||||
window.log.info('CallingClass.startCallingLobby()');
|
||||
|
||||
|
@ -147,7 +145,7 @@ export class CallingClass {
|
|||
return;
|
||||
}
|
||||
|
||||
const haveMediaPermissions = await this.requestPermissions(isVideoCall);
|
||||
const haveMediaPermissions = await this.requestPermissions(hasLocalVideo);
|
||||
if (!haveMediaPermissions) {
|
||||
window.log.info('Permissions were denied, new call not allowed.');
|
||||
this.stopCallingLobby();
|
||||
|
@ -171,24 +169,38 @@ export class CallingClass {
|
|||
// from the RingRTC before we lookup the ICE servers.
|
||||
const call = RingRTC.startOutgoingCall(
|
||||
remoteUserId,
|
||||
isVideoCall,
|
||||
hasLocalVideo,
|
||||
this.localDeviceId,
|
||||
callSettings
|
||||
);
|
||||
|
||||
await this.startDeviceReselectionTimer();
|
||||
RingRTC.setOutgoingAudio(call.callId, hasLocalAudio);
|
||||
RingRTC.setVideoCapturer(call.callId, this.videoCapturer);
|
||||
RingRTC.setVideoRenderer(call.callId, this.videoRenderer);
|
||||
this.attachToCall(conversation, call);
|
||||
|
||||
this.uxActions.outgoingCall({
|
||||
callDetails: this.getAcceptedCallDetails(conversation, call),
|
||||
conversationId: conversation.id,
|
||||
hasLocalAudio,
|
||||
hasLocalVideo,
|
||||
});
|
||||
|
||||
await this.startDeviceReselectionTimer();
|
||||
}
|
||||
|
||||
async accept(callId: CallId, asVideoCall: boolean): Promise<void> {
|
||||
private getCallIdForConversation(conversationId: string): undefined | CallId {
|
||||
return this.callsByConversation[conversationId]?.callId;
|
||||
}
|
||||
|
||||
async accept(conversationId: string, asVideoCall: boolean): Promise<void> {
|
||||
window.log.info('CallingClass.accept()');
|
||||
|
||||
const callId = this.getCallIdForConversation(conversationId);
|
||||
if (!callId) {
|
||||
window.log.warn('Trying to accept a non-existent call');
|
||||
return;
|
||||
}
|
||||
|
||||
const haveMediaPermissions = await this.requestPermissions(asVideoCall);
|
||||
if (haveMediaPermissions) {
|
||||
await this.startDeviceReselectionTimer();
|
||||
|
@ -201,23 +213,47 @@ export class CallingClass {
|
|||
}
|
||||
}
|
||||
|
||||
decline(callId: CallId): void {
|
||||
decline(conversationId: string): void {
|
||||
window.log.info('CallingClass.decline()');
|
||||
|
||||
const callId = this.getCallIdForConversation(conversationId);
|
||||
if (!callId) {
|
||||
window.log.warn('Trying to decline a non-existent call');
|
||||
return;
|
||||
}
|
||||
|
||||
RingRTC.decline(callId);
|
||||
}
|
||||
|
||||
hangup(callId: CallId): void {
|
||||
hangup(conversationId: string): void {
|
||||
window.log.info('CallingClass.hangup()');
|
||||
|
||||
const callId = this.getCallIdForConversation(conversationId);
|
||||
if (!callId) {
|
||||
window.log.warn('Trying to hang up a non-existent call');
|
||||
return;
|
||||
}
|
||||
|
||||
RingRTC.hangup(callId);
|
||||
}
|
||||
|
||||
setOutgoingAudio(callId: CallId, enabled: boolean): void {
|
||||
setOutgoingAudio(conversationId: string, enabled: boolean): void {
|
||||
const callId = this.getCallIdForConversation(conversationId);
|
||||
if (!callId) {
|
||||
window.log.warn('Trying to set outgoing audio for a non-existent call');
|
||||
return;
|
||||
}
|
||||
|
||||
RingRTC.setOutgoingAudio(callId, enabled);
|
||||
}
|
||||
|
||||
setOutgoingVideo(callId: CallId, enabled: boolean): void {
|
||||
setOutgoingVideo(conversationId: string, enabled: boolean): void {
|
||||
const callId = this.getCallIdForConversation(conversationId);
|
||||
if (!callId) {
|
||||
window.log.warn('Trying to set outgoing video for a non-existent call');
|
||||
return;
|
||||
}
|
||||
|
||||
RingRTC.setOutgoingVideo(callId, enabled);
|
||||
}
|
||||
|
||||
|
@ -673,8 +709,9 @@ export class CallingClass {
|
|||
|
||||
this.attachToCall(conversation, call);
|
||||
|
||||
this.uxActions.incomingCall({
|
||||
callDetails: this.getAcceptedCallDetails(conversation, call),
|
||||
this.uxActions.receiveIncomingCall({
|
||||
conversationId: conversation.id,
|
||||
isVideoCall: call.isVideoCall,
|
||||
});
|
||||
|
||||
window.log.info('CallingClass.handleIncomingCall(): Proceeding');
|
||||
|
@ -699,6 +736,8 @@ export class CallingClass {
|
|||
}
|
||||
|
||||
private attachToCall(conversation: ConversationModel, call: Call): void {
|
||||
this.callsByConversation[conversation.id] = call;
|
||||
|
||||
const { uxActions } = this;
|
||||
if (!uxActions) {
|
||||
return;
|
||||
|
@ -709,23 +748,29 @@ export class CallingClass {
|
|||
// eslint-disable-next-line no-param-reassign
|
||||
call.handleStateChanged = () => {
|
||||
if (call.state === CallState.Accepted) {
|
||||
acceptedTime = Date.now();
|
||||
acceptedTime = acceptedTime || Date.now();
|
||||
} else if (call.state === CallState.Ended) {
|
||||
this.addCallHistoryForEndedCall(conversation, call, acceptedTime);
|
||||
this.stopDeviceReselectionTimer();
|
||||
this.lastMediaDeviceSettings = undefined;
|
||||
delete this.callsByConversation[conversation.id];
|
||||
}
|
||||
uxActions.callStateChange({
|
||||
conversationId: conversation.id,
|
||||
acceptedTime,
|
||||
callState: call.state,
|
||||
callDetails: this.getAcceptedCallDetails(conversation, call),
|
||||
callEndedReason: call.endedReason,
|
||||
isIncoming: call.isIncoming,
|
||||
isVideoCall: call.isVideoCall,
|
||||
title: conversation.getTitle(),
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
call.handleRemoteVideoEnabled = () => {
|
||||
uxActions.remoteVideoChange({
|
||||
remoteVideoEnabled: call.remoteVideoEnabled,
|
||||
conversationId: conversation.id,
|
||||
hasVideo: call.remoteVideoEnabled,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -797,21 +842,6 @@ export class CallingClass {
|
|||
};
|
||||
}
|
||||
|
||||
private getAcceptedCallDetails(
|
||||
conversation: ConversationModel,
|
||||
call: Call
|
||||
): CallDetailsType {
|
||||
const conversationProps = conversation.format();
|
||||
|
||||
return {
|
||||
...conversationProps,
|
||||
acceptedTime: Date.now(),
|
||||
callId: call.callId,
|
||||
isIncoming: call.isIncoming,
|
||||
isVideoCall: call.isVideoCall,
|
||||
};
|
||||
}
|
||||
|
||||
private addCallHistoryForEndedCall(
|
||||
conversation: ConversationModel,
|
||||
call: Call,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue