packages/calling-stateful-client/src/CallClientState.ts (403 lines of code) (raw):
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
AudioDeviceInfo,
BreakoutRoom,
BreakoutRoomsSettings,
CallDirection,
CallEndReason,
CallerInfo,
CallState as CallStatus,
DeviceAccess,
DominantSpeakersInfo,
IncomingCallKind,
LatestMediaDiagnostics,
LatestNetworkDiagnostics,
MediaStreamType,
ParticipantRole,
RemoteParticipantState as RemoteParticipantStatus,
ScalingMode,
VideoDeviceInfo,
CommunicationServicesError
} from '@azure/communication-calling';
/* @conditional-compile-remove(remote-ufd) */
import type {
ServerDiagnosticType,
MediaDiagnosticType,
NetworkDiagnosticType,
DiagnosticValueType,
DiagnosticQuality,
DiagnosticFlag
} from '@azure/communication-calling';
import { ParticipantInfo, RealTimeTextResultType } from '@azure/communication-calling';
import { TeamsCallInfo } from '@azure/communication-calling';
import { CallInfo } from '@azure/communication-calling';
import { CapabilitiesChangeInfo, ParticipantCapabilities } from '@azure/communication-calling';
import { CaptionsResultType } from '@azure/communication-calling';
import { CaptionsKind } from '@azure/communication-calling';
import { VideoEffectName } from '@azure/communication-calling';
import { CallKind } from '@azure/communication-calling';
import { EnvironmentInfo } from '@azure/communication-calling';
import { CommunicationIdentifierKind } from '@azure/communication-common';
import { ReactionMessage } from '@azure/communication-calling';
import { SpotlightedParticipant } from '@azure/communication-calling';
/* @conditional-compile-remove(local-recording-notification) */
import { LocalRecordingInfo, RecordingInfo } from '@azure/communication-calling';
/**
* State only version of {@link @azure/communication-calling#CallAgent} except calls is moved to be a child directly of
* {@link CallClientState} and not included here. The reason to have CallAgent's state proxied is to provide access to
* displayName. We don't flatten CallAgent.displayName and put it in CallClientState because it would be ambiguious that
* displayName is actually reliant on the creation/existence of CallAgent to be available.
*
* @public
*/
export interface CallAgentState {
/**
* Proxy of {@link @azure/communication-calling#CallAgent.displayName}.
*/
displayName?: string;
}
/**
* @public
*/
export interface CaptionsInfo {
/**
* The state in which this caption data can be classified.
*/
resultType: CaptionsResultType;
/**
* The information of the call participant who spoke the captioned text.
*/
speaker: CallerInfo;
/**
* The language that the spoken words were interpretted as. Corresponds to the language specified in startCaptions / setSpokenLanguage.
*/
spokenLanguage: string;
/**
* The caption text.
*/
captionText: string;
/**
* Timestamp of when the captioned words were initially spoken.
*/
timestamp: Date;
/**
* Timestamp of when the captions were last updated.
*/
lastUpdatedTimestamp?: Date;
/**
* The language that the captions are presented in. Corresponds to the captionLanguage specified in startCaptions / setCaptionLanguage.
*/
captionLanguage?: string;
/**
* The original spoken caption text prior to translating to subtitle language
*/
spokenText?: string;
}
/**
* @public
*/
export interface RealTimeTextInfo {
/**
* The sequence id of the real time text.
*/
sequenceId: number;
/**
* The sender of the real time text.
*/
sender: ParticipantInfo;
/**
* The real time text message.
*/
message: string;
/**
* The result type of the real time text message.
*/
resultType: RealTimeTextResultType;
/**
* The timestamp when the real time text message was created.
*/
receivedTimestamp?: Date;
/**
* The timestamp when the real time text message was last updated.
*/
updatedTimestamp?: Date;
/**
* If message originated from the local participant
* default is false
*/
isMe?: boolean;
}
/**
* @public
*/
export interface CaptionsCallFeatureState {
/**
* supported spoken languages
*/
supportedSpokenLanguages: string[];
/**
* array of received captions
*/
captions: CaptionsInfo[];
/**
* whether captions is on/off
*/
isCaptionsFeatureActive: boolean;
/**
* whether start captions button is clicked or now
*/
startCaptionsInProgress: boolean;
/**
* supported caption languages
*/
supportedCaptionLanguages: string[];
/**
* current spoken language
*/
currentSpokenLanguage: string;
/**
* current caption language
*/
currentCaptionLanguage: string;
/**
* current caption kind: teams or acs captions
*/
captionsKind: CaptionsKind;
}
/**
* @public
*/
export interface RealTimeTextCallFeatureState {
/**
* array of received captions
*/
realTimeTexts: {
completedMessages?: RealTimeTextInfo[];
currentInProgress?: RealTimeTextInfo[];
myInProgress?: RealTimeTextInfo;
};
/**
* whether real time text is on/off
*/
isRealTimeTextFeatureActive?: boolean;
}
/**
* State only version of {@link @azure/communication-calling#TranscriptionCallFeature}. {@link StatefulCallClient} will
* automatically listen for transcription state of the call and update the state exposed by {@link StatefulCallClient}
* accordingly.
*
* @public
*/
export interface TranscriptionCallFeatureState {
/**
* Proxy of {@link @azure/communication-calling#TranscriptionCallFeature.isTranscriptionActive}.
*/
isTranscriptionActive: boolean;
}
/**
* State only version of {@link @azure/communication-calling#CapabilitiesFeature}
*
* @public
*/
export interface CapabilitiesFeatureState {
/**
* Proxy of {@link @azure/communication-calling#CapabilitiesFeature.capabilities}.
*/
capabilities: ParticipantCapabilities;
/**
* Proxy of the latest {@link @azure/communication-calling#CapabilitiesChangeInfo}
*/
latestCapabilitiesChangeInfo: CapabilitiesChangeInfo;
}
/**
* State only version of {@link @azure/communication-calling#SpotlightCallFeature}
*
* @public
*/
export interface SpotlightCallFeatureState {
/**
* Ordered array of spotlighted participants in call
*/
spotlightedParticipants: SpotlightedParticipant[];
/**
* Local participant spotlight
*/
localParticipantSpotlight?: SpotlightState;
/**
* Proxy of {@link @azure/communication-calling#SpotlightCallFeature.maxParticipantsToSpotlight}.
*/
maxParticipantsToSpotlight: number;
}
/**
* Spotlight state with order
*
* @public
*/
export interface SpotlightState {
/**
* Order position of spotlight in call
*/
spotlightedOrderPosition?: number;
}
/**
* Breakout rooms state
*
* @public
*/
export interface BreakoutRoomsState {
/** Breakout room assigned to local user in call */
assignedBreakoutRoom?: BreakoutRoom;
/** Breakout room settings of call. This is defined when call is a breakout room. */
breakoutRoomSettings?: BreakoutRoomsSettings;
/** Display name of breakout room. This is defined when call is a breakout room. */
breakoutRoomDisplayName?: string;
}
/**
* State only version of {@link @azure/communication-calling#RecordingCallFeature}. {@link StatefulCallClient} will
* automatically listen for recording state of the call and update the state exposed by {@link StatefulCallClient} accordingly.
*
* @public
*/
export interface RecordingCallFeatureState {
/**
* Proxy of {@link @azure/communication-calling#RecordingCallFeature.isRecordingActive}.
*/
isRecordingActive: boolean;
/* @conditional-compile-remove(local-recording-notification) */
/**
* Contains list of information of started recordings
* Proxy of {@link @azure/communication-calling#RecordingCallFeature.recordings}.
*/
activeRecordings?: RecordingInfo[];
/* @conditional-compile-remove(local-recording-notification) */
/**
* Contains list of information of stopped recordings
*/
lastStoppedRecording?: RecordingInfo[];
}
/* @conditional-compile-remove(local-recording-notification) */
/**
* State only version of {@link @azure/communication-calling#LocalRecordingCallFeature}. {@link StatefulCallClient} will
* automatically listen for local recording state of the call and update the state exposed by {@link StatefulCallClient} accordingly.
*
* @beta
*/
export interface LocalRecordingCallFeatureState {
/**
* Proxy of {@link @azure/communication-calling#LocalRecordingCallFeature.isRecordingActive}.
*/
isLocalRecordingActive: boolean;
/**
* Contains list of information of started recordings
* Proxy of {@link @azure/communication-calling#LocalRecordingCallFeature.recordings}.
*/
activeLocalRecordings?: LocalRecordingInfo[];
/**
* Contains list of information of stopped recordings
*/
lastStoppedLocalRecording?: LocalRecordingInfo[];
}
/**
* State only version of {@link @azure/communication-calling#RaiseHandCallFeature}. {@link StatefulCallClient} will
* automatically listen for raised hands on the call and update the state exposed by {@link StatefulCallClient} accordingly.
*
* @public
*/
export interface RaiseHandCallFeatureState {
/**
* Proxy of {@link @azure/communication-calling#RaiseHandCallFeature.raisedHands}.
*/
raisedHands: RaisedHandState[];
/**
* Contains information for local participant from list {@link @azure/communication-calling#RaiseHandCallFeature.raisedHands}.
*/
localParticipantRaisedHand?: RaisedHandState;
}
/* @conditional-compile-remove(together-mode) */
/**
* Represents the name of the call feature stream
* @public
*/
export type CallFeatureStreamName = 'togetherMode';
/* @conditional-compile-remove(together-mode) */
/**
* State only version of {@link @azure/communication-calling#CallFeatureStream}.
* Represents call feature stream state.
* @public
*/
export interface CallFeatureStreamState extends RemoteVideoStreamState {
/**
* The name of the call feature stream.
*/
feature?: CallFeatureStreamName;
}
/* @conditional-compile-remove(together-mode) */
/**
* State only version of {@link @azure/communication-calling#TogetherModeSeatingMap}.
* @public
*
* Represents the seating position of a participant in Together Mode.
*/
export interface TogetherModeSeatingPositionState {
/**
* The top left offset from the top of the together mode view.
*/
top: number;
/**
* The left offset position from the left of the together mode view.
*/
left: number;
/**
* The width of the seating area
*/
width: number;
/**
* The height of the seating area.
*/
height: number;
}
/* @conditional-compile-remove(together-mode) */
/**
* Represents the seating positions of participants in Together Mode.
*
* @public
*/
export type TogetherModeParticipantSeatingState = Record<string, TogetherModeSeatingPositionState>;
/* @conditional-compile-remove(together-mode) */
/**
* Represents the streams in Together Mode.
*
* @public
*/
export interface TogetherModeStreamsState {
/**
* The main video stream in Together Mode.
*/
mainVideoStream?: CallFeatureStreamState;
}
/* @conditional-compile-remove(together-mode) */
/**
* State only version of {@link @azure/communication-calling#TogetherModeCallFeature}. {@link StatefulCallClient}.
* Represents the state of the Together Mode feature.
* @public
*/
export interface TogetherModeCallFeatureState {
/**
* Flag indicating if Together Mode is active in the call
*/
isActive: boolean;
/**
* Proxy of {@link @azure/communication-calling#TogetherModeCallFeature.togetherModeStream}.
*/
streams: TogetherModeStreamsState;
/**
* Proxy of {@link @azure/communication-calling#TogetherModeCallFeature.TogetherModeSeatingMap}.
*/
seatingPositions: TogetherModeParticipantSeatingState;
}
/**
* State only version of {@link @azure/communication-calling#PPTLiveCallFeature}. {@link StatefulCallClient} will
* automatically listen for pptLive on the call and update the state exposed by {@link StatefulCallClient} accordingly.
*
* @public
*/
export interface PPTLiveCallFeatureState {
/**
* Proxy of {@link @azure/communication-calling#PPTLiveCallFeature.isActive}.
*/
isActive: boolean;
}
/**
* Raised hand state with order
*
* @public
*/
export type RaisedHandState = {
raisedHandOrderPosition: number;
};
/**
* State only version of {@link @azure/communication-calling#Call.ReactionMessage} with UI helper props receivedOn.
* Reaction state with a timestamp which helps UI to decide to render the reaction accordingly.
*
* @public
*/
export type ReactionState = {
/**
* Reaction message from the meeting {@link @azure/communication-calling#Call.ReactionMessage}
*/
reactionMessage: ReactionMessage;
/**
* Received timestamp of the reaction message in a meeting.
*/
receivedOn: Date;
};
/**
* State only version of {@link @azure/communication-calling#LocalVideoStream}.
*
* @public
*/
export interface LocalVideoStreamState {
/**
* Proxy of {@link @azure/communication-calling#LocalVideoStream.source}.
*/
source: VideoDeviceInfo;
/**
* Proxy of {@link @azure/communication-calling#LocalVideoStream.mediaStreamType}.
*/
mediaStreamType: MediaStreamType;
/**
* {@link VideoStreamRendererView} that is managed by createView/disposeView in {@link StatefulCallClient}
* API. This can be undefined if the stream has not yet been rendered and defined after createView creates the view.
*/
view?: VideoStreamRendererViewState;
/**
* Stores the state of the video effects.
* @public
*/
videoEffects?: LocalVideoStreamVideoEffectsState;
}
/**
* State only version of a LocalVideoStream's {@link @azure/communication-calling#VideoEffectsFeature}.
*
* @public
*/
export interface LocalVideoStreamVideoEffectsState {
/**
* List of effects if any are active.
*/
activeEffects?: VideoEffectName[];
}
/**
* State only version of Optimal Video Count Feature {@link @azure/communication-calling#OptimalVideoCountCallFeature}.
*
* @public
*/
export interface OptimalVideoCountFeatureState {
/**
* State of the current optimal video count.
*/
maxRemoteVideoStreams: number;
}
/**
* State only version of {@link @azure/communication-calling#RemoteVideoStream}.
*
* @public
*/
export interface RemoteVideoStreamState {
/**
* Proxy of {@link @azure/communication-calling#RemoteVideoStream.id}.
*/
id: number;
/**
* Proxy of {@link @azure/communication-calling#RemoteVideoStream.mediaStreamType}.
*/
mediaStreamType: MediaStreamType;
/**
* Proxy of {@link @azure/communication-calling#RemoteVideoStream.isAvailable}.
*/
isAvailable: boolean;
/**
* Proxy of {@link @azure/communication-calling#RemoteVideoStream.isReceiving}.
* @public
*/
isReceiving: boolean;
/**
* {@link VideoStreamRendererView} that is managed by createView/disposeView in {@link StatefulCallClient}
* API. This can be undefined if the stream has not yet been rendered and defined after createView creates the view.
*/
view?: VideoStreamRendererViewState;
/**
* Proxy of {@link @azure/communication-calling#RemoteVideoStream.size}.
*/
streamSize?: { width: number; height: number };
}
/**
* State only version of {@link @azure/communication-calling#VideoStreamRendererView}. This property is added to the state exposed
* by {@link StatefulCallClient} by {@link StatefulCallClient.createView} and removed by {@link StatefulCallClient.disposeView}.
*
* @public
*/
export interface VideoStreamRendererViewState {
/**
* Proxy of {@link @azure/communication-calling#VideoStreamRendererView.scalingMode}.
*/
scalingMode: ScalingMode;
/**
* Proxy of {@link @azure/communication-calling#VideoStreamRendererView.isMirrored}.
*/
isMirrored: boolean;
/**
* Proxy of {@link @azure/communication-calling#VideoStreamRendererView.target}.
*/
target: HTMLElement;
}
/**
* Media access state
* @public
*/
export interface MediaAccessState {
/**
* Whether the audio is forcibly muted
*/
isAudioPermitted: boolean;
/**
* Whether the video is forcibly muted
*/
isVideoPermitted: boolean;
}
/**
* State only version of {@link @azure/communication-calling#RemoteParticipant}. {@link StatefulCallClient} will
* automatically retrieve RemoteParticipants and add their state to the state exposed by {@link StatefulCallClient}.
*
* @public
*/
export interface RemoteParticipantState {
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.identifier}.
*/
identifier: CommunicationIdentifierKind;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.displayName}.
*/
displayName?: string;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.state}.
*/
state: RemoteParticipantStatus;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.callEndReason}.
*/
callEndReason?: CallEndReason;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.videoStreams} as an object with
* {@link RemoteVideoStream} fields keyed by {@link @azure/communication-calling#RemoteVideoStream.id}.
*/
videoStreams: { [key: number]: RemoteVideoStreamState };
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.isMuted}.
*/
isMuted: boolean;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.isSpeaking}.
*/
isSpeaking: boolean;
/**
* Proxy of {@link @azure/communication-calling#RemoteParticipant.role}.
*/
role?: ParticipantRole;
/**
* Proxy of {@link @azure/communication-calling#Call.RaisedHand.raisedHands}.
*/
raisedHand?: RaisedHandState;
/**
* Proxy of {@link @azure/communication-calling#Call.PPTLive.target}.
*
* @public
*/
contentSharingStream?: HTMLElement;
/**
* Proxy of {@link @azure/communication-calling#Call.ReactionMessage} with
* UI helper props receivedOn which indicates the timestamp when the message was received.
*
* @public
*/
reactionState?: ReactionState;
/**
* Proxy of {@link @azure/communication-calling#SpotlightCallFeature.spotlightedParticipants}.
*/
spotlight?: SpotlightState;
/**
* Proxy of {@link @azure/communication-calling#Call.MediaAccessCallFeature.MediaAccess}.
*/
mediaAccess?: MediaAccessState;
/* @conditional-compile-remove(remote-ufd) */
/**
* The diagnostic status of RemoteParticipant{@link @azure/communication-calling#RemoteDiagnostics}.
*/
diagnostics?: Partial<Record<RemoteDiagnosticType, RemoteDiagnosticState>>;
}
/**
* State only version of {@link @azure/communication-calling#Call}. {@link StatefulCallClient} will automatically
* retrieve Call's state and add it to the state exposed by {@link StatefulCallClient}.
*
* @public
*/
export interface CallState {
/**
* Proxy of {@link @azure/communication-calling#Call.id}.
*/
id: string;
/**
* Type of the call.
*/
kind: CallKind;
/**
* Proxy of {@link @azure/communication-calling#Call.callerInfo}.
*/
callerInfo: CallerInfo;
/**
* Proxy of {@link @azure/communication-calling#Call.state}.
*/
state: CallStatus;
/**
* Proxy of {@link @azure/communication-calling#Call.callEndReason}.
*/
callEndReason?: CallEndReason;
/**
* Proxy of {@link @azure/communication-calling#Call.direction}.
*/
direction: CallDirection;
/**
* Proxy of {@link @azure/communication-calling#Call.isMuted}.
*/
isMuted: boolean;
/**
* Proxy of {@link @azure/communication-calling#Call.isScreenSharingOn}.
*/
isScreenSharingOn: boolean;
/**
* Proxy of {@link @azure/communication-calling#DominantSpeakersInfo }.
*/
dominantSpeakers?: DominantSpeakersInfo;
/**
* Proxy of {@link @azure/communication-calling#Call.localVideoStreams}.
*/
localVideoStreams: LocalVideoStreamState[];
/**
* Proxy of {@link @azure/communication-calling#Call.remoteParticipants}.
* Object with {@link RemoteParticipant} fields keyed by flattened {@link RemoteParticipantState.identifier}.
* To obtain a flattened {@link RemoteParticipantState.identifier}, use
* {@link @azure/communication-react#toFlatCommunicationIdentifier}.
*/
remoteParticipants: { [keys: string]: RemoteParticipantState };
/**
* Stores remote participants that have left the call so that the callEndReason could be retrieved.
* Object with {@link RemoteParticipant} fields keyed by flattened {@link RemoteParticipantState.identifier}.
* To obtain a flattened {@link RemoteParticipantState.identifier}, use
* {@link @azure/communication-react#toFlatCommunicationIdentifier}.
*/
remoteParticipantsEnded: { [keys: string]: RemoteParticipantState };
/**
* Proxy of {@link @azure/communication-calling#TranscriptionCallFeature}.
*/
transcription: TranscriptionCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#CaptionsCallFeature}.
*/
captionsFeature: CaptionsCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#RealTimeTextCallFeature}.
*/
realTimeTextFeature: RealTimeTextCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#OptimalVideoCountCallFeature}.
*/
optimalVideoCount: OptimalVideoCountFeatureState;
/**
* Proxy of {@link @azure/communication-calling#RecordingCallFeature}.
*/
recording: RecordingCallFeatureState;
/* @conditional-compile-remove(local-recording-notification) */
/**
* Proxy of {@link @azure/communication-calling#LocalRecordingCallFeature}.
*/
localRecording: LocalRecordingCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#PPTLiveCallFeature}.
*
*@public
*/
pptLive: PPTLiveCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#RaiseHandCallFeature}.
*/
raiseHand: RaiseHandCallFeatureState;
/* @conditional-compile-remove(together-mode) */
/**
* Proxy of {@link @azure/communication-calling#TogetherModeCallFeature}.
*/
togetherMode: TogetherModeCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#Call.ReactionMessage} with
* UI helper props receivedOn which indicates the timestamp when the message was received.
*
* @public
*/
localParticipantReaction?: ReactionState;
/**
* Stores the currently active screenshare participant's key. If there is no screenshare active, then this will be
* undefined. You can use this key to access the remoteParticipant data in {@link CallState.remoteParticipants} object.
*
* Note this only applies to ScreenShare in RemoteParticipant. A local ScreenShare being active will not affect this
* property.
*
* This property is added by the stateful layer and is not a proxy of SDK state
*/
screenShareRemoteParticipant?: string;
/**
* Stores the currently active pptlive participant's key. Will be reused by White board etc. If there is no screenshare active, then this will be
* undefined. You can use this key to access the remoteParticipant data in {@link CallState.remoteParticipants} object.
*
* Note this only applies to PPTLive in RemoteParticipant.
*
* This property is added by the stateful layer and is not a proxy of SDK state
*
* @public
*/
contentSharingRemoteParticipant?: string;
/**
* Stores the local date when the call started on the client. This property is added by the stateful layer and is not
* a proxy of SDK state.
*/
startTime: Date;
/**
* Stores the local date when the call ended on the client. This property is added by the stateful layer and is not
* a proxy of SDK state.
*/
endTime: Date | undefined;
/**
* Stores the latest call diagnostics.
*/
diagnostics: DiagnosticsCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#Call.role}.
*/
role?: ParticipantRole;
/* @conditional-compile-remove(total-participant-count) */
/**
* Proxy of {@link @azure/communication-calling#Call.totalParticipantCount}.
*/
totalParticipantCount?: number;
/**
* Transfer state of call
*/
transfer: TransferFeatureState;
/**
* Proxy of {@link @azure/communication-calling#CapabilitiesFeature}.
*/
capabilitiesFeature?: CapabilitiesFeatureState;
/**
* Hide attendee names in teams meeting
*/
hideAttendeeNames?: boolean;
/**
* Proxy of {@link @azure/communication-calling#SpotlightCallFeature}.
*/
spotlight?: SpotlightCallFeatureState;
/**
* Proxy of {@link @azure/communication-calling#Call.info}.
*/
info?: TeamsCallInfo | /* @conditional-compile-remove(calling-beta-sdk) */ CallInfo;
/**
* Proxy of {@link @azure/communication-calling#TeamsMeetingAudioConferencingCallFeature}.
*/
meetingConference?: { conferencePhones: ConferencePhoneInfo[] };
/**
* Proxy of {@link @azure/communication-calling#BreakoutRoomsFeature}.
*/
breakoutRooms?: BreakoutRoomsState;
/**
* Proxy of {@link @azure/communication-calling#MediaAccessFeature}.
*/
meetingMediaAccess?: MediaAccessState;
}
/**
* Transfer feature state
*
* @public
*/
export interface TransferFeatureState {
/**
* Accepted transfer requests
*/
acceptedTransfers: { [key: string]: AcceptedTransfer };
}
/**
* Transfer feature state
*
* @public
*/
export interface AcceptedTransfer {
/**
* Stores call id of accepted transfer
*/
callId: string;
/**
* Stores timestamp when transfer was accepted
*/
timestamp: Date;
}
/**
* State to track the types {@link CallInfo} and {@link TeamsCallInfo}
* @public
*/
export interface CallInfoState {
/**
* GroupId of the call that you joined
*/
groupId?: string;
/**
* The teams meeting thread id
*/
threadId?: string;
/**
* participant id of the local user
*/
participantId: string;
/**
* Differentiator between the Call and TeamsCall types
*/
kind: IncomingCallKind;
}
/**
* State only version of {@link @azure/communication-calling#IncomingCall}. {@link StatefulCallClient} will
* automatically detect incoming calls and add their state to the state exposed by {@link StatefulCallClient}.
*
* @public
*/
export interface IncomingCallState {
/**
* Proxy of {@link @azure/communication-calling#IncomingCall.id}.
*/
id: string;
/**
* Proxy of {@link @azure/communication-calling#IncomingCall.callInfo}.
*/
info: CallInfoState;
/**
* Proxy of {@link @azure/communication-calling#IncomingCall.callerInfo}.
*/
callerInfo: CallerInfo;
/**
* Set to the state returned by 'callEnded' event on {@link @azure/communication-calling#IncomingCall} when received.
* This property is added by the stateful layer and is not a proxy of SDK state.
*/
callEndReason?: CallEndReason;
/**
* Stores the local date when the call started on the client. This property is added by the stateful layer and is not
* a proxy of SDK state.
*/
startTime: Date;
/**
* Stores the local date when the call ended on the client. This property is added by the stateful layer and is not a
* proxy of SDK state. It is undefined if the call is not ended yet.
*/
endTime?: Date;
}
/**
* State only version of {@link @azure/communication-calling#TeamsIncomingCall}
* @public
*/
export interface TeamsIncomingCallState {
/**
* Proxy of {@link @azure/communication-calling#TeamsIncomingCall.id}.
*/
id: string;
/**
* Proxy of {@link @azure/communication-calling#TeamsIncomingCall.teamsCallInfo}.
*/
info: CallInfoState;
/**
* Proxy of {@link @azure/communication-calling#TeamsIncomingCall.callerInfo}.
*/
callerInfo: CallerInfo;
/**
* Set to the state returned by 'callEnded' event on {@link @azure/communication-calling#IncomingCall} when received.
* This property is added by the stateful layer and is not a proxy of SDK state.
*/
callEndReason?: CallEndReason;
/**
* Stores the local date when the call started on the client. This property is added by the stateful layer and is not
* a proxy of SDK state.
*/
startTime: Date;
/**
* Stores the local date when the call ended on the client. This property is added by the stateful layer and is not a
* proxy of SDK state. It is undefined if the call is not ended yet.
*/
endTime?: Date;
}
/**
* This type is meant to encapsulate all the state inside {@link @azure/communication-calling#DeviceManager}. For
* optional parameters they may not be available until permission is granted by the user. The cameras, microphones,
* speakers, and deviceAccess states will be empty until the corresponding
* {@link @azure/communication-calling#DeviceManager}'s getCameras, getMicrophones, getSpeakers, and askDevicePermission
* APIs are called and completed.
*
* @public
*/
export type DeviceManagerState = {
/**
* Proxy of {@link @azure/communication-calling#DeviceManager.isSpeakerSelectionAvailable}.
*/
isSpeakerSelectionAvailable: boolean;
/**
* Proxy of {@link @azure/communication-calling#DeviceManager.selectedMicrophone}.
*/
selectedMicrophone?: AudioDeviceInfo;
/**
* Proxy of {@link @azure/communication-calling#DeviceManager.selectedSpeaker}.
*/
selectedSpeaker?: AudioDeviceInfo;
/**
* Stores the selected camera device info. This is added by the stateful layer and does not exist in the Calling SDK.
* It is meant as a convenience to the developer. It must be explicitly set before it has any value and does not
* persist across instances of the {@link StatefulCallClient}. The developer controls entirely what this value holds
* at any time.
*/
selectedCamera?: VideoDeviceInfo;
/**
* Stores any cameras data returned from {@link @azure/communication-calling#DeviceManager.getCameras}.
*/
cameras: VideoDeviceInfo[];
/**
* Stores any microphones data returned from {@link @azure/communication-calling#DeviceManager.getMicrophones}.
*/
microphones: AudioDeviceInfo[];
/**
* Stores any speakers data returned from {@link @azure/communication-calling#DeviceManager.getSpeakers}.
*/
speakers: AudioDeviceInfo[];
/**
* Stores deviceAccess data returned from {@link @azure/communication-calling#DeviceManager.askDevicePermission}.
*/
deviceAccess?: DeviceAccess;
/**
* Stores created views that are not associated with any CallState (when {@link StatefulCallClient.createView} is
* called with undefined callId, undefined participantId, and defined LocalVideoStream).
*
* The values in this array are generated internally when {@link StatefulCallClient.createView} is called and are
* considered immutable.
*/
unparentedViews: LocalVideoStreamState[];
};
/**
* Container for all of the state data proxied by {@link StatefulCallClient}. The calls, callsEnded, incomingCalls, and
* incomingCallsEnded states will be automatically provided if a callAgent has been created. The deviceManager will be
* empty initially until populated see {@link DeviceManagerState}. The userId state is provided as a convenience for the
* developer and is completely controled and set by the developer.
*
* @public
*/
export interface CallClientState {
/**
* Proxy of {@link @azure/communication-calling#CallAgent.calls} as an object with CallState {@link CallState} fields.
* It is keyed by {@link @azure/communication-calling#Call.id}. Please note that
* {@link @azure/communication-calling#Call.id} could change. You should not cache the id itself but the entire
* {@link @azure/communication-calling#Call} and then use the id contained to look up data in this map.
*/
calls: { [key: string]: CallState };
/**
* Calls that have ended are stored here so the callEndReason could be checked.
* It is an object with {@link @azure/communication-calling#Call.id} keys and {@link CallState} values.
*
* Only {@link MAX_CALL_HISTORY_LENGTH} Calls are kept in the history. Oldest calls are evicted if required.
*/
callsEnded: { [key: string]: CallState };
/**
* Proxy of {@link @azure/communication-calling#IncomingCall} as an object with {@link IncomingCall} fields.
* It is keyed by {@link @azure/communication-calling#IncomingCall.id}.
*/
incomingCalls: {
[key: string]: IncomingCallState | TeamsIncomingCallState;
};
/**
* Incoming Calls that have ended are stored here so the callEndReason could be checked.
* It is an as an object with {@link @azure/communication-calling#Call.id} keys and {@link IncomingCall} values.
*
* Only {@link MAX_CALL_HISTORY_LENGTH} Calls are kept in the history. Oldest calls are evicted if required.
*/
incomingCallsEnded: {
[key: string]: IncomingCallState | TeamsIncomingCallState;
};
/**
* Proxy of {@link @azure/communication-calling#DeviceManager}. Please review {@link DeviceManagerState}.
*/
deviceManager: DeviceManagerState;
/**
* Proxy of {@link @azure/communication-calling#CallAgent}. Please review {@link CallAgentState}.
*/
callAgent?: CallAgentState;
/**
* Stores a userId. This is not used by the {@link StatefulCallClient} and is provided here as a convenience for the
* developer for easier access to userId. Must be passed in at initialization of the {@link StatefulCallClient}.
* Completely controlled by the developer.
*/
userId: CommunicationIdentifierKind;
/**
* Stores the latest error for each API method.
*
* See documentation of {@Link CallErrors} for details.
*/
latestErrors: CallErrors;
/**
* Stores the latest notifications.
*
* See documentation of {@Link CallNotifications} for details.
*/
latestNotifications: CallNotifications;
/**
* A phone number in E.164 format that will be used to represent callers identity.
* For example, using the alternateCallerId to add a participant using PSTN, this number will
* be used as the caller id in the PSTN call.
*/
alternateCallerId?: string;
/**
* state to track the environment that the stateful client was made in is supported
*/
environmentInfo?: EnvironmentInfo;
}
/**
* Errors teed from API calls to the Calling SDK.
*
* Each property in the object stores the latest error for a particular SDK API method.
*
* Errors from this object can be cleared using the {@link newClearCallErrorsModifier}.
* Additionally, errors are automatically cleared when:
* - The state is cleared.
* - Subsequent calls to related API methods succeed.
* See documentation of individual stateful client methods for details on when errors may be automatically cleared.
*
* @public
*/
export type CallErrors = {
[target in CallErrorTarget]: CallError;
};
/**
* Error thrown from failed stateful API methods.
*
* @public
*/
export class CallError extends Error {
/**
* The API method target that failed.
*/
public target: CallErrorTarget;
/**
* Error thrown by the failed SDK method.
*/
public innerError: Error;
/**
* Timestamp added to the error by the stateful layer.
*/
public timestamp: Date;
/**
* Primary code for the calling error
*/
public code?: number;
/**
* Sub code for the calling error
*/
public subCode?: number;
/** needs to be a (innerError as CommunicationServicesError) */
constructor(target: CallErrorTarget, innerError: Error, timestamp?: Date) {
super();
this.target = target;
this.innerError = innerError;
if ('code' in (innerError as CommunicationServicesError)) {
this.code = (innerError as CommunicationServicesError).code;
}
if ('subCode' in (innerError as CommunicationServicesError)) {
this.subCode = (innerError as CommunicationServicesError).subCode;
}
// Testing note: It is easier to mock Date::now() than the Date() constructor.
this.timestamp = timestamp ?? new Date(Date.now());
this.name = 'CallError';
this.message = `${this.target}: ${this.innerError.message} code=${this.code} subCode=${this.subCode}`;
}
}
/**
* String literal type for all permissible keys in {@Link CallErrors}.
*
* @public
*/
export type CallErrorTarget =
| 'Call.addParticipant'
| 'Call.dispose'
| 'Call.feature'
| 'Call.hangUp'
| 'Call.hold'
| 'Call.mute'
| 'Call.muteIncomingAudio'
| 'Call.off'
| 'Call.on'
| 'Call.removeParticipant'
| 'Call.resume'
| 'Call.sendDtmf'
| 'Call.startAudio'
| 'Call.startScreenSharing'
| 'Call.startVideo'
| 'Call.stopScreenSharing'
| 'Call.stopAudio'
| 'Call.stopVideo'
| 'Call.unmute'
| 'Call.unmuteIncomingAudio'
| 'CallAgent.dispose'
| 'CallAgent.feature'
| 'CallAgent.join'
| 'CallAgent.off'
| 'CallAgent.on'
| 'CallAgent.startCall'
| 'CallClient.createCallAgent'
| 'CallClient.createTeamsCallAgent'
| 'CallClient.feature'
| 'CallClient.getDeviceManager'
| 'CallClient.getEnvironmentInfo'
| 'DeviceManager.askDevicePermission'
| 'DeviceManager.getCameras'
| 'DeviceManager.getMicrophones'
| 'DeviceManager.getSpeakers'
| 'DeviceManager.off'
| 'DeviceManager.on'
| 'DeviceManager.selectMicrophone'
| 'DeviceManager.selectSpeaker'
| 'IncomingCall.accept'
| 'IncomingCall.reject'
| 'TeamsCall.addParticipant'
| 'VideoEffectsFeature.startEffects'
| /* @conditional-compile-remove(calling-beta-sdk) */ 'CallAgent.handlePushNotification'
| /* @conditional-compile-remove(calling-beta-sdk) */ 'Call.admit'
| /* @conditional-compile-remove(calling-beta-sdk) */ 'Call.rejectParticipant'
| /* @conditional-compile-remove(calling-beta-sdk) */ 'Call.admitAll'
| 'Call.mutedByOthers'
| 'Call.muteAllRemoteParticipants'
| 'Call.setConstraints';
/**
* @public
*/
export type CallNotifications = {
[target in NotificationTarget]: CallNotification;
};
/**
* @public
*/
export interface CallNotification {
target: NotificationTarget;
timestamp: Date;
}
/** @public */
export type NotificationTarget =
| 'assignedBreakoutRoomOpened'
| 'assignedBreakoutRoomOpenedPromptJoin'
| 'assignedBreakoutRoomChanged'
| 'assignedBreakoutRoomClosed'
| 'breakoutRoomJoined'
| 'breakoutRoomClosingSoon'
| 'capabilityTurnVideoOnPresent'
| 'capabilityTurnVideoOnAbsent'
| 'capabilityUnmuteMicPresent'
| 'capabilityUnmuteMicAbsent'
| /* @conditional-compile-remove(together-mode) */ 'togetherModeStarted'
| /* @conditional-compile-remove(together-mode) */ 'togetherModeEnded';
/**
* State only proxy for {@link @azure/communication-calling#DiagnosticsCallFeature}.
*
* @public
*/
export interface DiagnosticsCallFeatureState {
/**
* Stores diagnostics related to network conditions.
*/
network: NetworkDiagnosticsState;
/**
* Stores diagnostics related to media quality.
*/
media: MediaDiagnosticsState;
}
/* @conditional-compile-remove(remote-ufd) */
/**
* All type names for {@link @azure/communication-calling#RemoteDiagnosticState}.
*
* @beta
*/
export type RemoteDiagnosticType = NetworkDiagnosticType | MediaDiagnosticType | ServerDiagnosticType;
/* @conditional-compile-remove(remote-ufd) */
/**
* State only proxy for {@link @azure/communication-calling#DiagnosticsCallFeature}.
*
* @beta
*/
export declare type RemoteDiagnosticState = {
readonly diagnostic: RemoteDiagnosticType;
readonly value: DiagnosticQuality | DiagnosticFlag;
readonly valueType: DiagnosticValueType;
};
/**
* State only proxy for {@link @azure/communication-calling#NetworkDiagnostics}.
*
* @public
*/
export interface NetworkDiagnosticsState {
latest: LatestNetworkDiagnostics;
}
/**
* State only proxy for {@link @azure/communication-calling#MediaDiagnostics}.
*
* @public
*/
export interface MediaDiagnosticsState {
latest: LatestMediaDiagnostics;
}
/**
* @public
* Information for conference phone info
*/
export interface ConferencePhoneInfo {
/**
* Phone number for the conference
*/
phoneNumber: string;
/**
* Conference id for the conference
*/
conferenceId: string;
/**
* Is toll free phone number
*/
isTollFree: boolean;
/**
* phone number country
*/
country?: string;
/**
* phone number city
*/
city?: string;
}