Fix sequencing of call state updates

This commit is contained in:
Fedor Indutny
2025-03-17 13:06:51 -07:00
committed by GitHub
parent 3758e8138a
commit 9a8b42d835

View File

@@ -1457,7 +1457,9 @@ export class CallingClass {
this.#callsLookup[conversationId] = groupCall; this.#callsLookup[conversationId] = groupCall;
// NOTE: This assumes only one active call at a time. See comment above. // NOTE: This assumes only one active call at a time. See comment above.
if (localDeviceState.videoMuted) { if (localDeviceState.sharingScreen) {
// Controlled by `#startPresenting`/`#stopPresenting`
} else if (localDeviceState.videoMuted) {
this.disableLocalVideo(); this.disableLocalVideo();
} else { } else {
drop(this.enableCaptureAndSend(groupCall, null, logId)); drop(this.enableCaptureAndSend(groupCall, null, logId));
@@ -2196,10 +2198,13 @@ export class CallingClass {
return; return;
} }
if (enabled) {
// Make sure we have access to camera
await window.reduxActions.globalModals.ensureSystemMediaPermissions( await window.reduxActions.globalModals.ensureSystemMediaPermissions(
'camera', 'camera',
'call' 'call'
); );
}
if (call instanceof Call) { if (call instanceof Call) {
RingRTC.setOutgoingVideo(call.callId, enabled); RingRTC.setOutgoingVideo(call.callId, enabled);
@@ -2210,16 +2215,56 @@ export class CallingClass {
} }
} }
#setOutgoingVideoIsScreenShare( async #startPresenting(
call: Call | GroupCall, call: Call | GroupCall,
enabled: boolean mediaStream: MediaStream
): void { ): Promise<void> {
if (call instanceof Call) { if (call instanceof Call) {
RingRTC.setOutgoingVideoIsScreenShare(call.callId, enabled); RingRTC.setOutgoingVideoIsScreenShare(call.callId, true);
// Note: there is no "presenting" API for direct calls.
} else if (call instanceof GroupCall) { } else if (call instanceof GroupCall) {
call.setOutgoingVideoIsScreenShare(enabled); call.setOutgoingVideoIsScreenShare(true);
call.setPresenting(enabled); call.setPresenting(true);
} else {
throw missingCaseError(call);
}
// Start screen sharing stream
await this.enableCaptureAndSend(call, {
maxFramerate: REQUESTED_SCREEN_SHARE_FRAMERATE,
maxHeight: REQUESTED_SCREEN_SHARE_HEIGHT,
maxWidth: REQUESTED_SCREEN_SHARE_WIDTH,
mediaStream,
onEnded: () => {
this.#reduxInterface?.cancelPresenting();
},
});
// Enable the video transmission once the stream is running
if (call instanceof Call) {
RingRTC.setOutgoingVideo(call.callId, true);
} else if (call instanceof GroupCall) {
call.setOutgoingVideoMuted(false);
} else {
throw missingCaseError(call);
}
}
async #stopPresenting(
call: Call | GroupCall,
hasLocalVideo: boolean
): Promise<void> {
if (call instanceof Call) {
// Disable video transmission first
RingRTC.setOutgoingVideo(call.callId, hasLocalVideo);
// Stop screenshare
RingRTC.setOutgoingVideoIsScreenShare(call.callId, false);
} else if (call instanceof GroupCall) {
// Ditto
call.setOutgoingVideoMuted(!hasLocalVideo);
call.setOutgoingVideoIsScreenShare(false);
call.setPresenting(false);
} else { } else {
throw missingCaseError(call); throw missingCaseError(call);
} }
@@ -2242,30 +2287,14 @@ export class CallingClass {
const isPresenting = mediaStream != null; const isPresenting = mediaStream != null;
if (isPresenting) { if (isPresenting) {
this.#hadLocalVideoBeforePresenting = hasLocalVideo; this.#hadLocalVideoBeforePresenting = hasLocalVideo;
drop( await this.#startPresenting(call, mediaStream);
this.enableCaptureAndSend(call, {
maxFramerate: REQUESTED_SCREEN_SHARE_FRAMERATE,
maxHeight: REQUESTED_SCREEN_SHARE_HEIGHT,
maxWidth: REQUESTED_SCREEN_SHARE_WIDTH,
mediaStream,
onEnded: () => {
this.#reduxInterface?.cancelPresenting();
},
})
);
drop(this.setOutgoingVideo(conversationId, true));
} else { } else {
drop( const prevHasLocalVideo =
this.setOutgoingVideo( this.#hadLocalVideoBeforePresenting ?? hasLocalVideo;
conversationId,
this.#hadLocalVideoBeforePresenting ?? hasLocalVideo
)
);
this.#hadLocalVideoBeforePresenting = undefined; this.#hadLocalVideoBeforePresenting = undefined;
await this.#stopPresenting(call, prevHasLocalVideo);
} }
this.#setOutgoingVideoIsScreenShare(call, isPresenting);
if (isPresenting) { if (isPresenting) {
ipcRenderer.send('show-screen-share', source?.name); ipcRenderer.send('show-screen-share', source?.name);