function disposeViewVideo()

in packages/calling-stateful-client/src/StreamUtils.ts [334:448]


function disposeViewVideo(
  context: CallContext,
  internalContext: InternalCallContext,
  callId: string,
  stream: RemoteVideoStreamState | LocalVideoStreamState,
  participantId?: CommunicationIdentifierKind | string
): void {
  // we can only have 3 types of createView
  let streamEventType: 'disposeViewLocal' | 'disposeViewRemote' | 'disposeViewUnparented';

  // we will reuse these for local as well but we need to make sure the remote stream is passed in like before.

  if (participantId) {
    streamEventType = 'disposeViewRemote';
  } else if (callId) {
    streamEventType = 'disposeViewLocal';
  } else {
    // TODO update for when unparented view.
    streamEventType = 'disposeViewUnparented';
  }

  const streamType = stream.mediaStreamType;
  const localStreamKey = (stream as LocalVideoStream).mediaStreamType;
  const remoteStreamId = (stream as RemoteVideoStream).id;

  // we want to check to see if there is a participantId this will tell us whether its a local stream or a remote one.
  const participantKey =
    streamEventType === 'disposeViewRemote' && participantId
      ? typeof participantId === 'string'
        ? participantId
        : toFlatCommunicationIdentifier(participantId)
      : undefined;
  const streamLogInfo = { callId, participantKey, streamId: remoteStreamId ?? localStreamKey, streamType };

  _logStreamEvent(EventNames.START_DISPOSE_STREAM, streamLogInfo);

  if (streamEventType === 'disposeViewRemote' && participantKey) {
    context.setRemoteVideoStreamRendererView(callId, participantKey, remoteStreamId, undefined);
  }

  const renderInfo =
    streamEventType === 'disposeViewRemote' && participantKey
      ? internalContext.getRemoteRenderInfoForParticipant(callId, participantKey, remoteStreamId)
      : internalContext.getLocalRenderInfo(callId, localStreamKey);

  if (!renderInfo) {
    _logStreamEvent(EventNames.DISPOSE_INFO_NOT_FOUND, streamLogInfo);
    return;
  }

  // Nothing to dispose of or clean up -- we can safely exit early here.
  if (renderInfo.status === 'NotRendered') {
    _logStreamEvent(EventNames.STREAM_ALREADY_DISPOSED, streamLogInfo);
    return;
  }

  // Status is already marked as "stopping" so we can exit early here. This is because stopping only occurs
  // when the stream is being created in createView but hasn't been completed being created yet. The createView
  // method will see the "stopping" status and perform the cleanup
  if (renderInfo.status === 'Stopping') {
    _logStreamEvent(EventNames.STREAM_STOPPING, streamLogInfo);
    return;
  }

  // If the stream is in the middle of being rendered (i.e. has state "Rendering"), we need the status as
  // "stopping" without performing any cleanup. This will tell the `createView` method that it should stop
  // rendering and clean up the state once the view has finished being created.
  if (renderInfo.status === 'Rendering') {
    _logStreamEvent(EventNames.STREAM_STOPPING, streamLogInfo);
    streamEventType === 'disposeViewRemote' && participantKey
      ? internalContext.setRemoteRenderInfo(
          callId,
          participantKey,
          remoteStreamId,
          renderInfo.stream as RemoteVideoStream,
          'Stopping',
          undefined
        )
      : internalContext.setLocalRenderInfo(
          callId,
          localStreamKey,
          renderInfo.stream as LocalVideoStream,
          'Stopping',
          renderInfo.renderer
        );
    return;
  }

  if (renderInfo.renderer) {
    _logStreamEvent(EventNames.DISPOSING_RENDERER, streamLogInfo);
    renderInfo.renderer.dispose();
    // Else the state must be in the "Rendered" state, so we can dispose the renderer and clean up the state.
    if (streamEventType === 'disposeViewRemote' && participantKey) {
      internalContext.setRemoteRenderInfo(
        callId,
        participantKey,
        remoteStreamId,
        renderInfo.stream as RemoteVideoStream,
        'NotRendered',
        undefined
      );
    } else if (streamEventType === 'disposeViewLocal') {
      internalContext.setLocalRenderInfo(
        callId,
        localStreamKey,
        renderInfo.stream as LocalVideoStream,
        'NotRendered',
        undefined
      );
      context.setLocalVideoStreamRendererView(callId, localStreamKey, undefined);
    }
  } else {
    _logStreamEvent(EventNames.RENDERER_NOT_FOUND, streamLogInfo);
  }
}