diff --git a/packages/client/src/Call.ts b/packages/client/src/Call.ts index 8d22dcdb9..18595a5ac 100644 --- a/packages/client/src/Call.ts +++ b/packages/client/src/Call.ts @@ -26,6 +26,7 @@ import type { AcceptCallResponse, BlockUserRequest, BlockUserResponse, + CallRingEvent, CollectUserFeedbackRequest, CollectUserFeedbackResponse, Credentials, @@ -595,6 +596,30 @@ export class Call { return this.state.createdBy?.id === this.currentUserId; } + /** + * Update from the call response from the "call.ring" event + * @internal + */ + updateFromRingingEvent = async (event: CallRingEvent) => { + await this.setup(); + // call.ring event excludes the call creator in the members list + // as the creator does not get the ring event + // so update the member list accordingly + const creator = this.state.members.find( + (m) => m.user.id === event.call.created_by.id, + ); + if (!creator) { + this.state.setMembers(event.members); + } else { + this.state.setMembers([creator, ...event.members]); + } + // update the call state with the latest event data + this.state.updateFromCallResponse(event.call); + this.ringingSubject.next(true); + this.watching = true; + await this.applyDeviceConfig(false); + }; + /** * Loads the information about the call. * diff --git a/packages/client/src/StreamVideoClient.ts b/packages/client/src/StreamVideoClient.ts index 354fc1e85..6eb29840f 100644 --- a/packages/client/src/StreamVideoClient.ts +++ b/packages/client/src/StreamVideoClient.ts @@ -263,7 +263,6 @@ export class StreamVideoClient { ); return; } - this.logger('info', `New call created and registered: ${call.cid}`); const newCall = new Call({ streamClient: this.streamClient, @@ -287,25 +286,24 @@ export class StreamVideoClient { ); return; } - - // The call might already be tracked by the client, // if `call.created` was received before `call.ring`. - // In that case, we cleanup the already tracked call. - const prevCall = this.writeableStateStore.findCall(call.type, call.id); - await prevCall?.leave({ reason: 'cleaning-up in call.ring' }); - // we create a new call - const theCall = new Call({ - streamClient: this.streamClient, - type: call.type, - id: call.id, - members, - clientStore: this.writeableStateStore, - ringing: true, - }); - theCall.state.updateFromCallResponse(call); - // we fetch the latest metadata for the call from the server - await theCall.get(); - this.writeableStateStore.registerCall(theCall); + // the client already has the call instance and we just need to update the state + const theCall = this.writeableStateStore.findCall(call.type, call.id); + if (theCall) { + await theCall.updateFromRingingEvent(event); + } else { + // if client doesn't have the call instance, create the instance and fetch the latest state + // Note: related - we also have onRingingCall method to handle this case from push notifications + const newCallInstance = new Call({ + streamClient: this.streamClient, + type: call.type, + id: call.id, + members, + clientStore: this.writeableStateStore, + ringing: true, + }); + await newCallInstance.get(); + } }), );