@capgo/capacitor-stream-call 0.0.6 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,48 +23,67 @@ export interface LoginOptions {
23
23
  magicDivId?: string;
24
24
  }
25
25
  /**
26
- * @interface CallOptions
27
- * @description Options for initiating a video call
28
- * @property {string} userId - ID of the user to call
29
- * @property {string} [type=default] - Type of call
30
- * @property {boolean} [ring=true] - Whether to send ring notification
26
+ * @typedef CallState
27
+ * @description Represents all possible call states from API and UI
31
28
  */
32
- export interface CallOptions {
33
- /** User ID of the person to call */
34
- userIds: string[];
35
- /** Type of call, defaults to 'default' */
36
- type?: string;
37
- /** Whether to ring the other user, defaults to true */
38
- ring?: boolean;
39
- }
29
+ export type CallState = 'idle' | 'ringing' | 'joining' | 'reconnecting' | 'joined' | 'leaving' | 'left' | 'created' | 'session_started' | 'rejected' | 'missed' | 'accepted' | 'ended' | 'unknown';
40
30
  /**
41
- * @interface SuccessResponse
42
- * @description Standard response indicating operation success/failure
43
- * @property {boolean} success - Whether the operation succeeded
31
+ * @typedef CallType
32
+ * @description Represents the pre-defined types of a call.
33
+ * - `default`: Simple 1-1 or group video calling with sensible defaults. Video/audio enabled, backstage disabled. Admins/hosts have elevated permissions.
34
+ * - `audio_room`: For audio-only spaces (like Clubhouse). Backstage enabled (requires `goLive`), pre-configured permissions for requesting to speak.
35
+ * - `livestream`: For one-to-many streaming. Backstage enabled (requires `goLive`), access granted to all authenticated users.
36
+ * - `development`: For testing ONLY. All permissions enabled, backstage disabled. **Not recommended for production.**
44
37
  */
45
- export interface SuccessResponse {
46
- /** Whether the operation was successful */
47
- success: boolean;
48
- }
38
+ export type CallType = 'default' | 'audio_room' | 'livestream' | 'development';
49
39
  /**
50
40
  * @interface CallEvent
51
41
  * @description Event emitted when call state changes
52
42
  * @property {string} callId - Unique identifier of the call
53
- * @property {string} state - Current state of the call (joined, left, ringing, etc)
43
+ * @property {CallState} state - Current state of the call
44
+ * @property {string} [userId] - User ID of the participant who triggered the event
45
+ * @property {string} [reason] - Reason for the call state change
54
46
  */
55
47
  export interface CallEvent {
56
48
  /** ID of the call */
57
49
  callId: string;
58
50
  /** Current state of the call */
59
- state: string;
51
+ state: CallState;
60
52
  /** User ID of the participant in the call who triggered the event */
61
53
  userId?: string;
62
- /** Reason for the call state change */
54
+ /** Reason for the call state change, if applicable */
63
55
  reason?: string;
64
56
  }
65
57
  export interface CameraEnabledResponse {
66
58
  enabled: boolean;
67
59
  }
60
+ /**
61
+ * @interface SuccessResponse
62
+ * @description Standard response indicating operation success/failure
63
+ * @property {boolean} success - Whether the operation succeeded
64
+ */
65
+ export interface SuccessResponse {
66
+ /** Whether the operation was successful */
67
+ success: boolean;
68
+ }
69
+ /**
70
+ * @interface CallOptions
71
+ * @description Options for initiating a video call
72
+ * @property {string[]} userIds - IDs of the users to call
73
+ * @property {CallType} [type=default] - Type of call
74
+ * @property {boolean} [ring=true] - Whether to send ring notification
75
+ * @property {string} [team] - Team name to call
76
+ */
77
+ export interface CallOptions {
78
+ /** User ID of the person to call */
79
+ userIds: string[];
80
+ /** Type of call, defaults to 'default' */
81
+ type?: CallType;
82
+ /** Whether to ring the other user, defaults to true */
83
+ ring?: boolean;
84
+ /** Team name to call */
85
+ team?: string;
86
+ }
68
87
  /**
69
88
  * @interface StreamCallPlugin
70
89
  * @description Capacitor plugin for Stream Video calling functionality
@@ -163,5 +182,20 @@ export interface StreamCallPlugin {
163
182
  * await StreamCall.rejectCall();
164
183
  */
165
184
  rejectCall(): Promise<SuccessResponse>;
185
+ /**
186
+ * Check if camera is enabled
187
+ * @returns {Promise<CameraEnabledResponse>} Camera enabled status
188
+ * @example
189
+ * const isCameraEnabled = await StreamCall.isCameraEnabled();
190
+ * console.log(isCameraEnabled);
191
+ */
166
192
  isCameraEnabled(): Promise<CameraEnabledResponse>;
193
+ /**
194
+ * Get the current call status
195
+ * @returns {Promise<CallEvent>} Current call status as a CallEvent
196
+ * @example
197
+ * const callStatus = await StreamCall.getCallStatus();
198
+ * console.log(callStatus);
199
+ */
200
+ getCallStatus(): Promise<CallEvent>;
167
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @interface LoginOptions\n * @description Configuration options for logging into the Stream Video service\n * @property {string} token - Stream Video API token for authentication\n * @property {string} userId - Unique identifier for the current user\n * @property {string} name - Display name for the current user\n * @property {string} [imageURL] - Avatar URL for the current user\n * @property {string} apiKey - Stream Video API key for your application\n * @property {string} [magicDivId] - DOM element ID where video will be rendered\n */\nexport interface LoginOptions {\n /** Stream Video API token */\n token: string;\n /** User ID for the current user */\n userId: string;\n /** Display name for the current user */\n name: string;\n /** Optional avatar URL for the current user */\n imageURL?: string;\n /** Stream Video API key */\n apiKey: string;\n /** ID of the HTML element where the video will be rendered */\n magicDivId?: string;\n}\n\n/**\n * @interface CallOptions\n * @description Options for initiating a video call\n * @property {string} userId - ID of the user to call\n * @property {string} [type=default] - Type of call\n * @property {boolean} [ring=true] - Whether to send ring notification\n */\nexport interface CallOptions {\n /** User ID of the person to call */\n userIds: string[];\n /** Type of call, defaults to 'default' */\n type?: string;\n /** Whether to ring the other user, defaults to true */\n ring?: boolean;\n}\n\n/**\n * @interface SuccessResponse\n * @description Standard response indicating operation success/failure\n * @property {boolean} success - Whether the operation succeeded\n */\nexport interface SuccessResponse {\n /** Whether the operation was successful */\n success: boolean;\n}\n\n/**\n * @interface CallEvent\n * @description Event emitted when call state changes\n * @property {string} callId - Unique identifier of the call\n * @property {string} state - Current state of the call (joined, left, ringing, etc)\n */\nexport interface CallEvent {\n /** ID of the call */\n callId: string;\n /** Current state of the call */\n state: string;\n /** User ID of the participant in the call who triggered the event */\n userId?: string\n /** Reason for the call state change */\n reason?: string;\n}\n\nexport interface CameraEnabledResponse {\n enabled: boolean;\n}\n\n/**\n * @interface StreamCallPlugin\n * @description Capacitor plugin for Stream Video calling functionality\n */\nexport interface StreamCallPlugin {\n /**\n * Login to Stream Video service\n * @param {LoginOptions} options - Login configuration\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.login({\n * token: 'your-token',\n * userId: 'user-123',\n * name: 'John Doe',\n * apiKey: 'your-api-key'\n * });\n */\n login(options: LoginOptions): Promise<SuccessResponse>;\n\n /**\n * Logout from Stream Video service\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.logout();\n */\n logout(): Promise<SuccessResponse>;\n\n /**\n * Initiate a call to another user\n * @param {CallOptions} options - Call configuration\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.call({\n * userId: 'user-456',\n * type: 'video',\n * ring: true\n * });\n */\n call(options: CallOptions): Promise<SuccessResponse>;\n\n /**\n * End the current call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.endCall();\n */\n endCall(): Promise<SuccessResponse>;\n\n /**\n * Enable or disable microphone\n * @param {{ enabled: boolean }} options - Microphone state\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.setMicrophoneEnabled({ enabled: false });\n */\n setMicrophoneEnabled(options: { enabled: boolean }): Promise<SuccessResponse>;\n\n /**\n * Enable or disable camera\n * @param {{ enabled: boolean }} options - Camera state\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.setCameraEnabled({ enabled: false });\n */\n setCameraEnabled(options: { enabled: boolean }): Promise<SuccessResponse>;\n\n /**\n * Add listener for call events\n * @param {'callEvent'} eventName - Name of the event to listen for\n * @param {(event: CallEvent) => void} listenerFunc - Callback function\n * @returns {Promise<{ remove: () => Promise<void> }>} Function to remove listener\n * @example\n * const listener = await StreamCall.addListener('callEvent', (event) => {\n * console.log(`Call ${event.callId} is now ${event.state}`);\n * });\n */\n addListener(\n eventName: 'callEvent',\n listenerFunc: (event: CallEvent) => void,\n ): Promise<{ remove: () => Promise<void> }>;\n\n /**\n * Remove all event listeners\n * @returns {Promise<void>}\n * @example\n * await StreamCall.removeAllListeners();\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Accept an incoming call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.acceptCall();\n */\n acceptCall(): Promise<SuccessResponse>;\n\n /**\n * Reject an incoming call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.rejectCall();\n */\n rejectCall(): Promise<SuccessResponse>;\n isCameraEnabled(): Promise<CameraEnabledResponse>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @interface LoginOptions\n * @description Configuration options for logging into the Stream Video service\n * @property {string} token - Stream Video API token for authentication\n * @property {string} userId - Unique identifier for the current user\n * @property {string} name - Display name for the current user\n * @property {string} [imageURL] - Avatar URL for the current user\n * @property {string} apiKey - Stream Video API key for your application\n * @property {string} [magicDivId] - DOM element ID where video will be rendered\n */\nexport interface LoginOptions {\n /** Stream Video API token */\n token: string;\n /** User ID for the current user */\n userId: string;\n /** Display name for the current user */\n name: string;\n /** Optional avatar URL for the current user */\n imageURL?: string;\n /** Stream Video API key */\n apiKey: string;\n /** ID of the HTML element where the video will be rendered */\n magicDivId?: string;\n}\n\n/**\n * @typedef CallState\n * @description Represents all possible call states from API and UI\n */\nexport type CallState =\n // User-facing states\n | 'idle'\n | 'ringing'\n | 'joining'\n | 'reconnecting'\n | 'joined'\n | 'leaving'\n | 'left'\n // Event-specific states\n | 'created'\n | 'session_started'\n | 'rejected'\n | 'missed'\n | 'accepted'\n | 'ended'\n | 'unknown';\n\n/**\n * @typedef CallType\n * @description Represents the pre-defined types of a call.\n * - `default`: Simple 1-1 or group video calling with sensible defaults. Video/audio enabled, backstage disabled. Admins/hosts have elevated permissions.\n * - `audio_room`: For audio-only spaces (like Clubhouse). Backstage enabled (requires `goLive`), pre-configured permissions for requesting to speak.\n * - `livestream`: For one-to-many streaming. Backstage enabled (requires `goLive`), access granted to all authenticated users.\n * - `development`: For testing ONLY. All permissions enabled, backstage disabled. **Not recommended for production.**\n */\nexport type CallType = 'default' | 'audio_room' | 'livestream' | 'development';\n\n/**\n * @interface CallEvent\n * @description Event emitted when call state changes\n * @property {string} callId - Unique identifier of the call\n * @property {CallState} state - Current state of the call\n * @property {string} [userId] - User ID of the participant who triggered the event\n * @property {string} [reason] - Reason for the call state change\n */\nexport interface CallEvent {\n /** ID of the call */\n callId: string;\n /** Current state of the call */\n state: CallState;\n /** User ID of the participant in the call who triggered the event */\n userId?: string;\n /** Reason for the call state change, if applicable */\n reason?: string;\n}\n\nexport interface CameraEnabledResponse {\n enabled: boolean;\n}\n\n/**\n * @interface SuccessResponse\n * @description Standard response indicating operation success/failure\n * @property {boolean} success - Whether the operation succeeded\n */\nexport interface SuccessResponse {\n /** Whether the operation was successful */\n success: boolean;\n}\n\n/**\n * @interface CallOptions\n * @description Options for initiating a video call\n * @property {string[]} userIds - IDs of the users to call\n * @property {CallType} [type=default] - Type of call\n * @property {boolean} [ring=true] - Whether to send ring notification\n * @property {string} [team] - Team name to call\n */\nexport interface CallOptions {\n /** User ID of the person to call */\n userIds: string[];\n /** Type of call, defaults to 'default' */\n type?: CallType;\n /** Whether to ring the other user, defaults to true */\n ring?: boolean;\n /** Team name to call */\n team?: string;\n}\n\n/**\n * @interface StreamCallPlugin\n * @description Capacitor plugin for Stream Video calling functionality\n */\nexport interface StreamCallPlugin {\n /**\n * Login to Stream Video service\n * @param {LoginOptions} options - Login configuration\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.login({\n * token: 'your-token',\n * userId: 'user-123',\n * name: 'John Doe',\n * apiKey: 'your-api-key'\n * });\n */\n login(options: LoginOptions): Promise<SuccessResponse>;\n\n /**\n * Logout from Stream Video service\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.logout();\n */\n logout(): Promise<SuccessResponse>;\n\n /**\n * Initiate a call to another user\n * @param {CallOptions} options - Call configuration\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.call({\n * userId: 'user-456',\n * type: 'video',\n * ring: true\n * });\n */\n call(options: CallOptions): Promise<SuccessResponse>;\n\n /**\n * End the current call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.endCall();\n */\n endCall(): Promise<SuccessResponse>;\n\n /**\n * Enable or disable microphone\n * @param {{ enabled: boolean }} options - Microphone state\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.setMicrophoneEnabled({ enabled: false });\n */\n setMicrophoneEnabled(options: { enabled: boolean }): Promise<SuccessResponse>;\n\n /**\n * Enable or disable camera\n * @param {{ enabled: boolean }} options - Camera state\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.setCameraEnabled({ enabled: false });\n */\n setCameraEnabled(options: { enabled: boolean }): Promise<SuccessResponse>;\n\n /**\n * Add listener for call events\n * @param {'callEvent'} eventName - Name of the event to listen for\n * @param {(event: CallEvent) => void} listenerFunc - Callback function\n * @returns {Promise<{ remove: () => Promise<void> }>} Function to remove listener\n * @example\n * const listener = await StreamCall.addListener('callEvent', (event) => {\n * console.log(`Call ${event.callId} is now ${event.state}`);\n * });\n */\n addListener(\n eventName: 'callEvent',\n listenerFunc: (event: CallEvent) => void,\n ): Promise<{ remove: () => Promise<void> }>;\n\n /**\n * Remove all event listeners\n * @returns {Promise<void>}\n * @example\n * await StreamCall.removeAllListeners();\n */\n removeAllListeners(): Promise<void>;\n\n /**\n * Accept an incoming call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.acceptCall();\n */\n acceptCall(): Promise<SuccessResponse>;\n\n /**\n * Reject an incoming call\n * @returns {Promise<SuccessResponse>} Success status\n * @example\n * await StreamCall.rejectCall();\n */\n rejectCall(): Promise<SuccessResponse>;\n\n /**\n * Check if camera is enabled\n * @returns {Promise<CameraEnabledResponse>} Camera enabled status\n * @example\n * const isCameraEnabled = await StreamCall.isCameraEnabled();\n * console.log(isCameraEnabled);\n */\n isCameraEnabled(): Promise<CameraEnabledResponse>;\n\n /**\n * Get the current call status\n * @returns {Promise<CallEvent>} Current call status as a CallEvent\n * @example\n * const callStatus = await StreamCall.getCallStatus();\n * console.log(callStatus);\n */\n getCallStatus(): Promise<CallEvent>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
- import type { CallOptions, StreamCallPlugin, SuccessResponse, LoginOptions, CameraEnabledResponse } from './definitions';
2
+ import type { CallOptions, StreamCallPlugin, SuccessResponse, LoginOptions, CameraEnabledResponse, CallEvent } from './definitions';
3
3
  export declare class StreamCallWeb extends WebPlugin implements StreamCallPlugin {
4
4
  private client?;
5
5
  private currentCall?;
@@ -40,4 +40,5 @@ export declare class StreamCallWeb extends WebPlugin implements StreamCallPlugin
40
40
  acceptCall(): Promise<SuccessResponse>;
41
41
  rejectCall(): Promise<SuccessResponse>;
42
42
  isCameraEnabled(): Promise<CameraEnabledResponse>;
43
+ getCallStatus(): Promise<CallEvent>;
43
44
  }
package/dist/esm/web.js CHANGED
@@ -41,8 +41,9 @@ export class StreamCallWeb extends WebPlugin {
41
41
  }
42
42
  };
43
43
  this.callSessionStartedCallback = (event) => {
44
+ var _a, _b;
44
45
  console.log('Call created (session started)', event);
45
- if (event.call && event.call.session && event.call.session.participants) {
46
+ if ((_b = (_a = event.call) === null || _a === void 0 ? void 0 : _a.session) === null || _b === void 0 ? void 0 : _b.participants) {
46
47
  // Store the number of expected participants for this call
47
48
  const callCid = event.call.cid;
48
49
  const memberCount = event.call.session.participants.length;
@@ -50,7 +51,7 @@ export class StreamCallWeb extends WebPlugin {
50
51
  this.callMembersExpected.set(callCid, memberCount);
51
52
  // Store call members in callStates
52
53
  this.callStates.set(callCid, {
53
- members: event.call.session.participants.map(p => { var _a; return ({ user_id: ((_a = p.user) === null || _a === void 0 ? void 0 : _a.id) || '' }); }),
54
+ members: event.call.session.participants.map((p) => { var _a; return ({ user_id: ((_a = p.user) === null || _a === void 0 ? void 0 : _a.id) || '' }); }),
54
55
  participantResponses: new Map(),
55
56
  expectedMemberCount: memberCount,
56
57
  createdAt: new Date(),
@@ -66,8 +67,9 @@ export class StreamCallWeb extends WebPlugin {
66
67
  }
67
68
  };
68
69
  this.callRejectedCallback = (event) => {
70
+ var _a;
69
71
  console.log('Call rejected', event);
70
- if (event.user && event.user.id) {
72
+ if ((_a = event.user) === null || _a === void 0 ? void 0 : _a.id) {
71
73
  this.participantResponses.set(event.user.id, 'rejected');
72
74
  // Update the combined callStates map
73
75
  const callState = this.callStates.get(event.call_cid);
@@ -78,14 +80,15 @@ export class StreamCallWeb extends WebPlugin {
78
80
  this.notifyListeners('callEvent', {
79
81
  callId: event.call_cid,
80
82
  state: 'rejected',
81
- userId: event.user.id
83
+ userId: event.user.id,
82
84
  });
83
85
  this.checkAllParticipantsResponded();
84
86
  }
85
87
  };
86
88
  this.callAcceptedCallback = (event) => {
89
+ var _a;
87
90
  console.log('Call accepted', event);
88
- if (event.user && event.user.id) {
91
+ if ((_a = event.user) === null || _a === void 0 ? void 0 : _a.id) {
89
92
  this.participantResponses.set(event.user.id, 'accepted');
90
93
  // Update the combined callStates map
91
94
  const callState = this.callStates.get(event.call_cid);
@@ -101,13 +104,14 @@ export class StreamCallWeb extends WebPlugin {
101
104
  this.notifyListeners('callEvent', {
102
105
  callId: event.call_cid,
103
106
  state: 'accepted',
104
- userId: event.user.id
107
+ userId: event.user.id,
105
108
  });
106
109
  }
107
110
  };
108
111
  this.callMissedCallback = (event) => {
112
+ var _a;
109
113
  console.log('Call missed', event);
110
- if (event.user && event.user.id) {
114
+ if ((_a = event.user) === null || _a === void 0 ? void 0 : _a.id) {
111
115
  this.participantResponses.set(event.user.id, 'missed');
112
116
  // Update the combined callStates map
113
117
  const callState = this.callStates.get(event.call_cid);
@@ -118,7 +122,7 @@ export class StreamCallWeb extends WebPlugin {
118
122
  this.notifyListeners('callEvent', {
119
123
  callId: event.call_cid,
120
124
  state: 'missed',
121
- userId: event.user.id
125
+ userId: event.user.id,
122
126
  });
123
127
  this.checkAllParticipantsResponded();
124
128
  }
@@ -160,7 +164,7 @@ export class StreamCallWeb extends WebPlugin {
160
164
  }
161
165
  };
162
166
  this.participantLeftListener = (event) => {
163
- var _a, _b;
167
+ var _a, _b, _c;
164
168
  if (this.magicDivId && event.participant) {
165
169
  const videoId = `video-${event.participant.sessionId}`;
166
170
  const audioId = `audio-${event.participant.sessionId}`;
@@ -200,7 +204,7 @@ export class StreamCallWeb extends WebPlugin {
200
204
  }
201
205
  }
202
206
  // Check if we're the only participant left in the call
203
- if (this.currentCall && this.currentCall.state.session) {
207
+ if ((_a = this.currentCall) === null || _a === void 0 ? void 0 : _a.state.session) {
204
208
  // Get the remaining participants count (we need to subtract 1 as we haven't been removed from the list yet)
205
209
  const remainingParticipants = this.currentCall.state.session.participants.length - 1;
206
210
  // If we're the only one left, end the call
@@ -211,12 +215,12 @@ export class StreamCallWeb extends WebPlugin {
211
215
  // Clean up resources
212
216
  const callCid = this.currentCall.cid;
213
217
  // Invalidate and remove timer
214
- const callState = (_a = this.callStates) === null || _a === void 0 ? void 0 : _a.get(callCid);
218
+ const callState = (_b = this.callStates) === null || _b === void 0 ? void 0 : _b.get(callCid);
215
219
  if (callState === null || callState === void 0 ? void 0 : callState.timer) {
216
220
  clearInterval(callState.timer);
217
221
  }
218
222
  // Remove from callStates
219
- (_b = this.callStates) === null || _b === void 0 ? void 0 : _b.delete(callCid);
223
+ (_c = this.callStates) === null || _c === void 0 ? void 0 : _c.delete(callCid);
220
224
  // Reset the current call
221
225
  this.currentCall = undefined;
222
226
  // this.currentActiveCallId = undefined;
@@ -227,7 +231,7 @@ export class StreamCallWeb extends WebPlugin {
227
231
  this.notifyListeners('callEvent', {
228
232
  callId: callCid,
229
233
  state: 'left',
230
- reason: 'participant_left'
234
+ reason: 'participant_left',
231
235
  });
232
236
  }
233
237
  }
@@ -286,19 +290,18 @@ export class StreamCallWeb extends WebPlugin {
286
290
  if (elapsedSeconds >= 30) {
287
291
  console.log(`Call ${callCid} has timed out after ${elapsedSeconds} seconds`);
288
292
  // Check if anyone has accepted
289
- const hasAccepted = Array.from(callState.participantResponses.values())
290
- .some(response => response === 'accepted');
293
+ const hasAccepted = Array.from(callState.participantResponses.values()).some((response) => response === 'accepted');
291
294
  if (!hasAccepted) {
292
295
  console.log(`No one accepted call ${callCid}, marking all non-responders as missed`);
293
296
  // Mark all members who haven't responded as "missed"
294
- callState.members.forEach(member => {
297
+ callState.members.forEach((member) => {
295
298
  if (!callState.participantResponses.has(member.user_id)) {
296
299
  callState.participantResponses.set(member.user_id, 'missed');
297
300
  this.participantResponses.set(member.user_id, 'missed');
298
301
  this.notifyListeners('callEvent', {
299
302
  callId: callCid,
300
303
  state: 'missed',
301
- userId: member.user_id
304
+ userId: member.user_id,
302
305
  });
303
306
  }
304
307
  });
@@ -319,7 +322,7 @@ export class StreamCallWeb extends WebPlugin {
319
322
  this.notifyListeners('callEvent', {
320
323
  callId: callCid,
321
324
  state: 'ended',
322
- reason: 'timeout'
325
+ reason: 'timeout',
323
326
  });
324
327
  }
325
328
  }
@@ -336,7 +339,7 @@ export class StreamCallWeb extends WebPlugin {
336
339
  console.log(`Total expected participants: ${totalParticipants}`);
337
340
  // Count rejections and misses
338
341
  let rejectedOrMissedCount = 0;
339
- this.participantResponses.forEach(response => {
342
+ this.participantResponses.forEach((response) => {
340
343
  if (response === 'rejected' || response === 'missed') {
341
344
  rejectedOrMissedCount++;
342
345
  }
@@ -345,7 +348,7 @@ export class StreamCallWeb extends WebPlugin {
345
348
  console.log(`Rejected or missed: ${rejectedOrMissedCount}`);
346
349
  const allResponded = this.participantResponses.size >= totalParticipants;
347
350
  const allRejectedOrMissed = allResponded &&
348
- Array.from(this.participantResponses.values()).every(response => response === 'rejected' || response === 'missed');
351
+ Array.from(this.participantResponses.values()).every((response) => response === 'rejected' || response === 'missed');
349
352
  // If all participants have rejected or missed the call
350
353
  if (allResponded && allRejectedOrMissed) {
351
354
  console.log('All participants have rejected or missed the call');
@@ -366,7 +369,7 @@ export class StreamCallWeb extends WebPlugin {
366
369
  this.notifyListeners('callEvent', {
367
370
  callId: callCid,
368
371
  state: 'ended',
369
- reason: 'all_rejected_or_missed'
372
+ reason: 'all_rejected_or_missed',
370
373
  });
371
374
  }
372
375
  }
@@ -474,7 +477,7 @@ export class StreamCallWeb extends WebPlugin {
474
477
  if (this.client.streamClient.userID && !options.userIds.includes(this.client.streamClient.userID)) {
475
478
  members.push({ user_id: this.client.streamClient.userID });
476
479
  }
477
- await call.getOrCreate({ data: { members } });
480
+ await call.getOrCreate({ data: { members, team: options.team } });
478
481
  // Store the expected member count for this call
479
482
  // -1, because we don't count the caller themselves
480
483
  this.callMembersExpected.set(call.cid, members.length);
@@ -562,5 +565,38 @@ export class StreamCallWeb extends WebPlugin {
562
565
  const enabled = await this.currentCall.camera.enabled;
563
566
  return { enabled };
564
567
  }
568
+ async getCallStatus() {
569
+ if (!this.currentCall) {
570
+ throw new Error('No active call');
571
+ }
572
+ const callingState = this.currentCall.state.callingState;
573
+ let state;
574
+ switch (callingState) {
575
+ case CallingState.IDLE:
576
+ state = 'idle';
577
+ break;
578
+ case CallingState.RINGING:
579
+ state = 'ringing';
580
+ break;
581
+ case CallingState.JOINING:
582
+ state = 'joining';
583
+ break;
584
+ case CallingState.RECONNECTING:
585
+ state = 'reconnecting';
586
+ break;
587
+ case CallingState.JOINED:
588
+ state = 'joined';
589
+ break;
590
+ case CallingState.LEFT:
591
+ state = 'left';
592
+ break;
593
+ default:
594
+ state = 'unknown';
595
+ }
596
+ return {
597
+ callId: this.currentCall.id,
598
+ state,
599
+ };
600
+ }
565
601
  }
566
602
  //# sourceMappingURL=web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { AllClientEvents, Call, CallResponse, StreamVideoParticipant } from '@stream-io/video-client';\nimport { CallingState, StreamVideoClient } from '@stream-io/video-client';\n\nimport type {\n CallOptions,\n StreamCallPlugin,\n SuccessResponse,\n LoginOptions,\n CameraEnabledResponse,\n} from './definitions';\n\nexport class StreamCallWeb extends WebPlugin implements StreamCallPlugin {\n private client?: StreamVideoClient;\n private currentCall?: Call;\n private callStateSubscription?: { unsubscribe: () => void };\n private incomingCall?: CallResponse;\n private outgoingCall?: string;\n private magicDivId?: string;\n private videoBindings: Map<string, () => void> = new Map();\n private audioBindings: Map<string, () => void> = new Map();\n private participantJoinedListener?: (event: { participant?: { sessionId: string } }) => void;\n private participantLeftListener?: (event: { participant?: { sessionId: string } }) => void;\n private participantResponses: Map<string, string> = new Map();\n private callMembersExpected: Map<string, number> = new Map();\n// private currentActiveCallId?: string;\n\n private setupCallRingListener() {\n this.client?.off('call.ring', this.ringCallback);\n this.client?.off('call.session_started', this.callSessionStartedCallback);\n\n this.client?.on('call.ring', this.ringCallback);\n this.client?.on('call.session_started', this.callSessionStartedCallback);\n }\n\n private setupCallEventListeners() {\n // Clear previous listeners if any\n this.client?.off('call.rejected', this.callRejectedCallback);\n this.client?.off('call.accepted', this.callAcceptedCallback);\n this.client?.off('call.missed', this.callMissedCallback); \n // Register event listeners\n this.client?.on('call.rejected', this.callRejectedCallback);\n this.client?.on('call.accepted', this.callAcceptedCallback);\n this.client?.on('call.missed', this.callMissedCallback);\n }\n\n private ringCallback = (event: AllClientEvents['call.ring']) => {\n console.log('Call ringing', event, this.currentCall);\n this.incomingCall = event.call;\n if (!this.currentCall) {\n console.log('Creating new call', event.call.id);\n this.currentCall = this.client?.call(event.call.type, event.call.id);\n // this.currentActiveCallId = this.currentCall?.cid;\n this.notifyListeners('callEvent', { callId: event.call.id, state: CallingState.RINGING });\n // Clear previous responses when a new call starts\n this.participantResponses.clear();\n }\n if (this.currentCall) {\n console.log('Call found', this.currentCall.id);\n this.callStateSubscription = this.currentCall?.state.callingState$.subscribe((s) => {\n console.log('Call state', s);\n if (s === CallingState.JOINED) {\n this.setupParticipantListener();\n this.setupCallEventListeners();\n } else if (s === CallingState.LEFT || s === CallingState.RECONNECTING_FAILED) {\n this.cleanupCall();\n }\n if (this.outgoingCall && s === CallingState.RINGING) {\n this.outgoingCall = undefined;\n } else {\n this.notifyListeners('callEvent', { callId: this.currentCall?.id, state: s });\n }\n });\n }\n };\n\n private setupParticipantListener() {\n // Subscribe to participant changes\n this.incomingCall = undefined;\n if (!this.currentCall) return;\n\n this.participantJoinedListener = (event) => {\n if (this.magicDivId && event.participant) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv && this.currentCall) {\n this.setupParticipantVideo(this.currentCall, event.participant as StreamVideoParticipant, magicDiv);\n this.setupParticipantAudio(this.currentCall, event.participant as StreamVideoParticipant, magicDiv);\n }\n }\n };\n\n this.participantLeftListener = (event) => {\n if (this.magicDivId && event.participant) {\n const videoId = `video-${event.participant.sessionId}`;\n const audioId = `audio-${event.participant.sessionId}`;\n\n // Remove video element\n const videoEl = document.getElementById(videoId) as HTMLVideoElement;\n if (videoEl) {\n const unbindVideo = this.videoBindings.get(videoId);\n if (unbindVideo) {\n unbindVideo();\n this.videoBindings.delete(videoId);\n }\n const tracks = videoEl.srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n videoEl.srcObject = null;\n videoEl.remove();\n }\n\n // Remove audio element\n const audioEl = document.getElementById(audioId) as HTMLAudioElement;\n if (audioEl) {\n const unbindAudio = this.audioBindings.get(audioId);\n if (unbindAudio) {\n unbindAudio();\n this.audioBindings.delete(audioId);\n }\n const tracks = audioEl.srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n audioEl.srcObject = null;\n audioEl.remove();\n }\n }\n \n // Check if we're the only participant left in the call\n if (this.currentCall && this.currentCall.state.session) {\n // Get the remaining participants count (we need to subtract 1 as we haven't been removed from the list yet)\n const remainingParticipants = this.currentCall.state.session.participants.length - 1;\n \n // If we're the only one left, end the call\n if (remainingParticipants <= 1) {\n console.log(`We are left solo in a call. Ending. cID: ${this.currentCall.cid}`);\n \n // End the call\n this.currentCall.leave();\n \n // Clean up resources\n const callCid = this.currentCall.cid;\n \n // Invalidate and remove timer\n const callState = this.callStates?.get(callCid);\n if (callState?.timer) {\n clearInterval(callState.timer);\n }\n \n // Remove from callStates\n this.callStates?.delete(callCid);\n \n // Reset the current call\n this.currentCall = undefined;\n // this.currentActiveCallId = undefined;\n \n // Clean up\n this.cleanupCall();\n \n console.log(`Cleaned up resources for ended call: ${callCid}`);\n \n // Notify that the call has ended\n this.notifyListeners('callEvent', { \n callId: callCid, \n state: 'left',\n reason: 'participant_left'\n });\n }\n }\n };\n\n this.currentCall.on('participantJoined', this.participantJoinedListener);\n this.currentCall.on('participantLeft', this.participantLeftListener);\n\n // Setup initial participants\n const participants = this.currentCall.state.participants;\n if (this.magicDivId) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv) {\n participants.forEach((participant: StreamVideoParticipant) => {\n if (this.currentCall) {\n this.setupParticipantVideo(this.currentCall, participant, magicDiv);\n this.setupParticipantAudio(this.currentCall, participant, magicDiv);\n }\n });\n }\n }\n }\n\n private setupParticipantVideo(call: Call, participant: StreamVideoParticipant, container: HTMLElement) {\n const id = `video-${participant.sessionId}`;\n if (!document.getElementById(id)) {\n const videoEl = document.createElement('video');\n videoEl.id = id;\n videoEl.style.width = '100%';\n videoEl.style.maxWidth = '300px';\n videoEl.style.aspectRatio = '16/9';\n container.appendChild(videoEl);\n\n const unbind = call.bindVideoElement(videoEl, participant.sessionId, 'videoTrack');\n if (unbind) this.videoBindings.set(id, unbind);\n }\n }\n\n private setupParticipantAudio(call: Call, participant: StreamVideoParticipant, container: HTMLElement) {\n if (participant.isLocalParticipant) return;\n\n const id = `audio-${participant.sessionId}`;\n if (!document.getElementById(id)) {\n const audioEl = document.createElement('audio');\n audioEl.id = id;\n container.appendChild(audioEl);\n\n const unbind = call.bindAudioElement(audioEl, participant.sessionId);\n if (unbind) this.audioBindings.set(id, unbind);\n }\n }\n\n private callSessionStartedCallback = (event: AllClientEvents['call.session_started']) => {\n console.log('Call created (session started)', event);\n if (event.call && event.call.session && event.call.session.participants) {\n // Store the number of expected participants for this call\n const callCid = event.call.cid;\n const memberCount = event.call.session.participants.length;\n console.log(`Call ${callCid} created with ${memberCount} members`);\n this.callMembersExpected.set(callCid, memberCount);\n \n // Store call members in callStates\n this.callStates.set(callCid, {\n members: event.call.session.participants.map(p => ({ user_id: p.user?.id || '' })),\n participantResponses: new Map(),\n expectedMemberCount: memberCount,\n createdAt: new Date(),\n });\n \n // Start a timeout task that runs every second\n const timeoutTask = setInterval(() => this.checkCallTimeout(callCid), 1000);\n \n // Update the callState with the timeout task\n const callState = this.callStates.get(callCid);\n if (callState) {\n callState.timer = timeoutTask;\n this.callStates.set(callCid, callState);\n }\n }\n };\n\n private callRejectedCallback = (event: AllClientEvents['call.rejected']) => {\n console.log('Call rejected', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'rejected');\n \n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'rejected');\n this.callStates.set(event.call_cid, callState);\n }\n \n this.notifyListeners('callEvent', { \n callId: event.call_cid, \n state: 'rejected',\n userId: event.user.id\n });\n \n this.checkAllParticipantsResponded();\n }\n };\n\n private callAcceptedCallback = (event: AllClientEvents['call.accepted']) => {\n console.log('Call accepted', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'accepted');\n \n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'accepted');\n \n // If someone accepted, clear the timer as we don't need to check anymore\n if (callState.timer) {\n clearInterval(callState.timer);\n callState.timer = undefined;\n }\n \n this.callStates.set(event.call_cid, callState);\n }\n \n this.notifyListeners('callEvent', { \n callId: event.call_cid, \n state: 'accepted',\n userId: event.user.id\n });\n }\n };\n\n private callMissedCallback = (event: AllClientEvents['call.missed']) => {\n console.log('Call missed', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'missed');\n \n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'missed');\n this.callStates.set(event.call_cid, callState);\n }\n \n this.notifyListeners('callEvent', { \n callId: event.call_cid, \n state: 'missed',\n userId: event.user.id\n });\n \n this.checkAllParticipantsResponded();\n }\n };\n \n // Add a combined map for call states, mirroring the iOS implementation\n private callStates: Map<string, {\n members: { user_id: string }[],\n participantResponses: Map<string, string>,\n expectedMemberCount: number,\n createdAt: Date,\n timer?: ReturnType<typeof setInterval>\n }> = new Map();\n \n private checkCallTimeout(callCid: string) {\n const callState = this.callStates.get(callCid);\n if (!callState) return;\n \n // Calculate time elapsed since call creation\n const now = new Date();\n const elapsedSeconds = (now.getTime() - callState.createdAt.getTime()) / 1000;\n \n // Check if 30 seconds have passed\n if (elapsedSeconds >= 30) {\n console.log(`Call ${callCid} has timed out after ${elapsedSeconds} seconds`);\n \n // Check if anyone has accepted\n const hasAccepted = Array.from(callState.participantResponses.values())\n .some(response => response === 'accepted');\n \n if (!hasAccepted) {\n console.log(`No one accepted call ${callCid}, marking all non-responders as missed`);\n \n // Mark all members who haven't responded as \"missed\"\n callState.members.forEach(member => {\n if (!callState.participantResponses.has(member.user_id)) {\n callState.participantResponses.set(member.user_id, 'missed');\n this.participantResponses.set(member.user_id, 'missed');\n \n this.notifyListeners('callEvent', { \n callId: callCid, \n state: 'missed',\n userId: member.user_id\n });\n }\n });\n \n // End the call\n if (this.currentCall && this.currentCall.cid === callCid) {\n this.currentCall.leave();\n }\n \n // Clear the timeout task\n if (callState.timer) {\n clearInterval(callState.timer);\n callState.timer = undefined;\n }\n \n // Remove from callStates\n this.callStates.delete(callCid);\n \n // Clean up\n this.cleanupCall();\n \n // Notify that the call has ended\n this.notifyListeners('callEvent', { \n callId: callCid, \n state: 'ended',\n reason: 'timeout'\n });\n }\n }\n }\n\n private checkAllParticipantsResponded() {\n if (!this.currentCall) return;\n \n const callCid = this.currentCall.cid;\n const totalParticipants = this.callMembersExpected.get(callCid);\n \n if (!totalParticipants) {\n console.log(`No expected participant count found for call: ${callCid}`);\n return;\n }\n \n console.log(`Total expected participants: ${totalParticipants}`);\n \n // Count rejections and misses\n let rejectedOrMissedCount = 0;\n this.participantResponses.forEach(response => {\n if (response === 'rejected' || response === 'missed') {\n rejectedOrMissedCount++;\n }\n });\n \n console.log(`Participants responded: ${this.participantResponses.size}/${totalParticipants}`);\n console.log(`Rejected or missed: ${rejectedOrMissedCount}`);\n \n const allResponded = this.participantResponses.size >= totalParticipants;\n const allRejectedOrMissed = allResponded && \n Array.from(this.participantResponses.values()).every(response => \n response === 'rejected' || response === 'missed'\n );\n \n // If all participants have rejected or missed the call\n if (allResponded && allRejectedOrMissed) {\n console.log('All participants have rejected or missed the call');\n \n // End the call\n this.currentCall.leave();\n \n // Clean up the timer if exists in callStates\n const callState = this.callStates.get(callCid);\n if (callState?.timer) {\n clearInterval(callState.timer);\n }\n \n // Remove from callStates\n this.callStates.delete(callCid);\n \n // Clear the responses\n this.participantResponses.clear();\n \n // Clean up\n this.cleanupCall();\n \n // Notify that the call has ended\n this.notifyListeners('callEvent', { \n callId: callCid, \n state: 'ended',\n reason: 'all_rejected_or_missed'\n });\n }\n }\n\n private cleanupCall() {\n // First cleanup the call listeners\n if (this.currentCall) {\n if (this.participantJoinedListener) {\n this.currentCall.off('participantJoined', this.participantJoinedListener);\n this.participantJoinedListener = undefined;\n }\n if (this.participantLeftListener) {\n this.currentCall.off('participantLeft', this.participantLeftListener);\n this.participantLeftListener = undefined;\n }\n this.callStateSubscription?.unsubscribe();\n }\n\n if (this.magicDivId) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv) {\n // Remove all video elements\n const videoElements = magicDiv.querySelectorAll('video');\n videoElements.forEach((video) => {\n const id = video.id;\n const unbind = this.videoBindings.get(id);\n if (unbind) {\n unbind();\n this.videoBindings.delete(id);\n }\n // Stop all tracks\n const tracks = (video as HTMLVideoElement).srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n video.srcObject = null;\n }\n video.remove();\n });\n\n // Remove all audio elements\n const audioElements = magicDiv.querySelectorAll('audio');\n audioElements.forEach((audio) => {\n const id = audio.id;\n const unbind = this.audioBindings.get(id);\n if (unbind) {\n unbind();\n this.audioBindings.delete(id);\n }\n // Stop all tracks\n const tracks = (audio as HTMLAudioElement).srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n audio.srcObject = null;\n }\n audio.remove();\n });\n\n // Clear the container\n while (magicDiv.firstChild) {\n magicDiv.removeChild(magicDiv.firstChild);\n }\n }\n }\n\n // Clear all bindings\n this.videoBindings.clear();\n this.audioBindings.clear();\n\n // Clear call references\n this.currentCall = undefined;\n this.incomingCall = undefined;\n }\n\n async login(options: LoginOptions): Promise<SuccessResponse> {\n this.client = StreamVideoClient.getOrCreateInstance({\n apiKey: options.apiKey,\n user: { id: options.userId, name: options.name, image: options.imageURL },\n token: options.token,\n });\n\n this.magicDivId = options.magicDivId;\n this.setupCallRingListener();\n\n return { success: true };\n }\n\n async logout(): Promise<SuccessResponse> {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized');\n }\n\n // Cleanup subscription\n this.callStateSubscription?.unsubscribe();\n this.callStateSubscription = undefined;\n\n await this.client.disconnectUser();\n this.client = undefined;\n this.currentCall = undefined;\n return { success: true };\n }\n\n async call(options: CallOptions): Promise<SuccessResponse> {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized - Please login first');\n }\n\n const call = this.client.call(options.type || 'default', crypto.randomUUID());\n const members = options.userIds.map((userId) => ({ user_id: userId }));\n if (this.client.streamClient.userID && !options.userIds.includes(this.client.streamClient.userID)) {\n members.push({ user_id: this.client.streamClient.userID });\n }\n await call.getOrCreate({ data: { members } });\n \n // Store the expected member count for this call\n // -1, because we don't count the caller themselves\n this.callMembersExpected.set(call.cid, members.length);\n console.log(`Setting expected members for call ${call.cid}: ${members.length}`);\n \n this.currentCall = call;\n if (options.ring) {\n this.outgoingCall = call.cid;\n await call.ring();\n }\n\n await call.join();\n return { success: true };\n }\n\n async endCall(): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n await this.currentCall.leave();\n this.currentCall = undefined;\n this.cleanupCall();\n\n return { success: true };\n }\n\n async setMicrophoneEnabled(options: { enabled: boolean }): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n if (options.enabled) {\n await this.currentCall.microphone.enable();\n } else {\n await this.currentCall.microphone.disable();\n }\n\n return { success: true };\n }\n\n async setCameraEnabled(options: { enabled: boolean }): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n if (options.enabled) {\n await this.currentCall.camera.enable();\n } else {\n await this.currentCall.camera.disable();\n }\n\n return { success: true };\n }\n\n async acceptCall(): Promise<SuccessResponse> {\n if (!this.incomingCall || !this.client) {\n console.log('No incoming call to accept', this.incomingCall, this.client);\n throw new Error('No incoming call to accept');\n }\n console.log('Accepting call', this.incomingCall);\n const call = this.client.call(this.incomingCall.type, this.incomingCall.id);\n this.currentCall = call;\n console.log('Joining call', call);\n await call.accept();\n await call.join();\n console.log('Joined call', call);\n this.notifyListeners('callEvent', { callId: call.id, state: CallingState.JOINED });\n this.setupParticipantListener();\n return { success: true };\n }\n\n async rejectCall(): Promise<SuccessResponse> {\n if (!this.incomingCall || !this.client) {\n console.log('No incoming call to reject', this.incomingCall, this.client);\n throw new Error('No incoming call to reject');\n }\n console.log('Rejecting call', this.incomingCall);\n const call: Call = this.client.call(this.incomingCall.type, this.incomingCall.id);\n console.log('Leaving call', call);\n await call.reject();\n this.incomingCall = undefined;\n console.log('Rejected call', call);\n this.notifyListeners('callEvent', { callId: call.id, state: CallingState.LEFT });\n this.cleanupCall();\n return { success: true };\n }\n\n async isCameraEnabled(): Promise<CameraEnabledResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n const enabled = await this.currentCall.camera.enabled;\n return { enabled };\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { AllClientEvents, Call, CallResponse, StreamVideoParticipant } from '@stream-io/video-client';\nimport { CallingState, StreamVideoClient } from '@stream-io/video-client';\n\nimport type {\n CallOptions,\n StreamCallPlugin,\n SuccessResponse,\n LoginOptions,\n CameraEnabledResponse,\n CallEvent,\n CallState,\n} from './definitions';\n\nexport class StreamCallWeb extends WebPlugin implements StreamCallPlugin {\n private client?: StreamVideoClient;\n private currentCall?: Call;\n private callStateSubscription?: { unsubscribe: () => void };\n private incomingCall?: CallResponse;\n private outgoingCall?: string;\n private magicDivId?: string;\n private videoBindings: Map<string, () => void> = new Map();\n private audioBindings: Map<string, () => void> = new Map();\n private participantJoinedListener?: (event: { participant?: { sessionId: string } }) => void;\n private participantLeftListener?: (event: { participant?: { sessionId: string } }) => void;\n private participantResponses: Map<string, string> = new Map();\n private callMembersExpected: Map<string, number> = new Map();\n // private currentActiveCallId?: string;\n\n private setupCallRingListener() {\n this.client?.off('call.ring', this.ringCallback);\n this.client?.off('call.session_started', this.callSessionStartedCallback);\n\n this.client?.on('call.ring', this.ringCallback);\n this.client?.on('call.session_started', this.callSessionStartedCallback);\n }\n\n private setupCallEventListeners() {\n // Clear previous listeners if any\n this.client?.off('call.rejected', this.callRejectedCallback);\n this.client?.off('call.accepted', this.callAcceptedCallback);\n this.client?.off('call.missed', this.callMissedCallback);\n // Register event listeners\n this.client?.on('call.rejected', this.callRejectedCallback);\n this.client?.on('call.accepted', this.callAcceptedCallback);\n this.client?.on('call.missed', this.callMissedCallback);\n }\n\n private ringCallback = (event: AllClientEvents['call.ring']) => {\n console.log('Call ringing', event, this.currentCall);\n this.incomingCall = event.call;\n if (!this.currentCall) {\n console.log('Creating new call', event.call.id);\n this.currentCall = this.client?.call(event.call.type, event.call.id);\n // this.currentActiveCallId = this.currentCall?.cid;\n this.notifyListeners('callEvent', { callId: event.call.id, state: CallingState.RINGING });\n // Clear previous responses when a new call starts\n this.participantResponses.clear();\n }\n if (this.currentCall) {\n console.log('Call found', this.currentCall.id);\n this.callStateSubscription = this.currentCall?.state.callingState$.subscribe((s) => {\n console.log('Call state', s);\n if (s === CallingState.JOINED) {\n this.setupParticipantListener();\n this.setupCallEventListeners();\n } else if (s === CallingState.LEFT || s === CallingState.RECONNECTING_FAILED) {\n this.cleanupCall();\n }\n if (this.outgoingCall && s === CallingState.RINGING) {\n this.outgoingCall = undefined;\n } else {\n this.notifyListeners('callEvent', { callId: this.currentCall?.id, state: s });\n }\n });\n }\n };\n\n private setupParticipantListener() {\n // Subscribe to participant changes\n this.incomingCall = undefined;\n if (!this.currentCall) return;\n\n this.participantJoinedListener = (event) => {\n if (this.magicDivId && event.participant) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv && this.currentCall) {\n this.setupParticipantVideo(this.currentCall, event.participant as StreamVideoParticipant, magicDiv);\n this.setupParticipantAudio(this.currentCall, event.participant as StreamVideoParticipant, magicDiv);\n }\n }\n };\n\n this.participantLeftListener = (event) => {\n if (this.magicDivId && event.participant) {\n const videoId = `video-${event.participant.sessionId}`;\n const audioId = `audio-${event.participant.sessionId}`;\n\n // Remove video element\n const videoEl = document.getElementById(videoId) as HTMLVideoElement;\n if (videoEl) {\n const unbindVideo = this.videoBindings.get(videoId);\n if (unbindVideo) {\n unbindVideo();\n this.videoBindings.delete(videoId);\n }\n const tracks = videoEl.srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n videoEl.srcObject = null;\n videoEl.remove();\n }\n\n // Remove audio element\n const audioEl = document.getElementById(audioId) as HTMLAudioElement;\n if (audioEl) {\n const unbindAudio = this.audioBindings.get(audioId);\n if (unbindAudio) {\n unbindAudio();\n this.audioBindings.delete(audioId);\n }\n const tracks = audioEl.srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n audioEl.srcObject = null;\n audioEl.remove();\n }\n }\n\n // Check if we're the only participant left in the call\n if (this.currentCall?.state.session) {\n // Get the remaining participants count (we need to subtract 1 as we haven't been removed from the list yet)\n const remainingParticipants = this.currentCall.state.session.participants.length - 1;\n\n // If we're the only one left, end the call\n if (remainingParticipants <= 1) {\n console.log(`We are left solo in a call. Ending. cID: ${this.currentCall.cid}`);\n\n // End the call\n this.currentCall.leave();\n\n // Clean up resources\n const callCid = this.currentCall.cid;\n\n // Invalidate and remove timer\n const callState = this.callStates?.get(callCid);\n if (callState?.timer) {\n clearInterval(callState.timer);\n }\n\n // Remove from callStates\n this.callStates?.delete(callCid);\n\n // Reset the current call\n this.currentCall = undefined;\n // this.currentActiveCallId = undefined;\n\n // Clean up\n this.cleanupCall();\n\n console.log(`Cleaned up resources for ended call: ${callCid}`);\n\n // Notify that the call has ended\n this.notifyListeners('callEvent', {\n callId: callCid,\n state: 'left',\n reason: 'participant_left',\n });\n }\n }\n };\n\n this.currentCall.on('participantJoined', this.participantJoinedListener);\n this.currentCall.on('participantLeft', this.participantLeftListener);\n\n // Setup initial participants\n const participants = this.currentCall.state.participants;\n if (this.magicDivId) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv) {\n participants.forEach((participant: StreamVideoParticipant) => {\n if (this.currentCall) {\n this.setupParticipantVideo(this.currentCall, participant, magicDiv);\n this.setupParticipantAudio(this.currentCall, participant, magicDiv);\n }\n });\n }\n }\n }\n\n private setupParticipantVideo(call: Call, participant: StreamVideoParticipant, container: HTMLElement) {\n const id = `video-${participant.sessionId}`;\n if (!document.getElementById(id)) {\n const videoEl = document.createElement('video');\n videoEl.id = id;\n videoEl.style.width = '100%';\n videoEl.style.maxWidth = '300px';\n videoEl.style.aspectRatio = '16/9';\n container.appendChild(videoEl);\n\n const unbind = call.bindVideoElement(videoEl, participant.sessionId, 'videoTrack');\n if (unbind) this.videoBindings.set(id, unbind);\n }\n }\n\n private setupParticipantAudio(call: Call, participant: StreamVideoParticipant, container: HTMLElement) {\n if (participant.isLocalParticipant) return;\n\n const id = `audio-${participant.sessionId}`;\n if (!document.getElementById(id)) {\n const audioEl = document.createElement('audio');\n audioEl.id = id;\n container.appendChild(audioEl);\n\n const unbind = call.bindAudioElement(audioEl, participant.sessionId);\n if (unbind) this.audioBindings.set(id, unbind);\n }\n }\n\n private callSessionStartedCallback = (event: AllClientEvents['call.session_started']) => {\n console.log('Call created (session started)', event);\n if (event.call?.session?.participants) {\n // Store the number of expected participants for this call\n const callCid = event.call.cid;\n const memberCount = event.call.session.participants.length;\n console.log(`Call ${callCid} created with ${memberCount} members`);\n this.callMembersExpected.set(callCid, memberCount);\n\n // Store call members in callStates\n this.callStates.set(callCid, {\n members: event.call.session.participants.map((p) => ({ user_id: p.user?.id || '' })),\n participantResponses: new Map(),\n expectedMemberCount: memberCount,\n createdAt: new Date(),\n });\n\n // Start a timeout task that runs every second\n const timeoutTask = setInterval(() => this.checkCallTimeout(callCid), 1000);\n\n // Update the callState with the timeout task\n const callState = this.callStates.get(callCid);\n if (callState) {\n callState.timer = timeoutTask;\n this.callStates.set(callCid, callState);\n }\n }\n };\n\n private callRejectedCallback = (event: AllClientEvents['call.rejected']) => {\n console.log('Call rejected', event);\n if (event.user?.id) {\n this.participantResponses.set(event.user.id, 'rejected');\n\n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'rejected');\n this.callStates.set(event.call_cid, callState);\n }\n\n this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'rejected',\n userId: event.user.id,\n });\n\n this.checkAllParticipantsResponded();\n }\n };\n\n private callAcceptedCallback = (event: AllClientEvents['call.accepted']) => {\n console.log('Call accepted', event);\n if (event.user?.id) {\n this.participantResponses.set(event.user.id, 'accepted');\n\n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'accepted');\n\n // If someone accepted, clear the timer as we don't need to check anymore\n if (callState.timer) {\n clearInterval(callState.timer);\n callState.timer = undefined;\n }\n\n this.callStates.set(event.call_cid, callState);\n }\n\n this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'accepted',\n userId: event.user.id,\n });\n }\n };\n\n private callMissedCallback = (event: AllClientEvents['call.missed']) => {\n console.log('Call missed', event);\n if (event.user?.id) {\n this.participantResponses.set(event.user.id, 'missed');\n\n // Update the combined callStates map\n const callState = this.callStates.get(event.call_cid);\n if (callState) {\n callState.participantResponses.set(event.user.id, 'missed');\n this.callStates.set(event.call_cid, callState);\n }\n\n this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'missed',\n userId: event.user.id,\n });\n\n this.checkAllParticipantsResponded();\n }\n };\n\n // Add a combined map for call states, mirroring the iOS implementation\n private callStates: Map<\n string,\n {\n members: { user_id: string }[];\n participantResponses: Map<string, string>;\n expectedMemberCount: number;\n createdAt: Date;\n timer?: ReturnType<typeof setInterval>;\n }\n > = new Map();\n\n private checkCallTimeout(callCid: string) {\n const callState = this.callStates.get(callCid);\n if (!callState) return;\n\n // Calculate time elapsed since call creation\n const now = new Date();\n const elapsedSeconds = (now.getTime() - callState.createdAt.getTime()) / 1000;\n\n // Check if 30 seconds have passed\n if (elapsedSeconds >= 30) {\n console.log(`Call ${callCid} has timed out after ${elapsedSeconds} seconds`);\n\n // Check if anyone has accepted\n const hasAccepted = Array.from(callState.participantResponses.values()).some(\n (response) => response === 'accepted',\n );\n\n if (!hasAccepted) {\n console.log(`No one accepted call ${callCid}, marking all non-responders as missed`);\n\n // Mark all members who haven't responded as \"missed\"\n callState.members.forEach((member) => {\n if (!callState.participantResponses.has(member.user_id)) {\n callState.participantResponses.set(member.user_id, 'missed');\n this.participantResponses.set(member.user_id, 'missed');\n\n this.notifyListeners('callEvent', {\n callId: callCid,\n state: 'missed',\n userId: member.user_id,\n });\n }\n });\n\n // End the call\n if (this.currentCall && this.currentCall.cid === callCid) {\n this.currentCall.leave();\n }\n\n // Clear the timeout task\n if (callState.timer) {\n clearInterval(callState.timer);\n callState.timer = undefined;\n }\n\n // Remove from callStates\n this.callStates.delete(callCid);\n\n // Clean up\n this.cleanupCall();\n\n // Notify that the call has ended\n this.notifyListeners('callEvent', {\n callId: callCid,\n state: 'ended',\n reason: 'timeout',\n });\n }\n }\n }\n\n private checkAllParticipantsResponded() {\n if (!this.currentCall) return;\n\n const callCid = this.currentCall.cid;\n const totalParticipants = this.callMembersExpected.get(callCid);\n\n if (!totalParticipants) {\n console.log(`No expected participant count found for call: ${callCid}`);\n return;\n }\n\n console.log(`Total expected participants: ${totalParticipants}`);\n\n // Count rejections and misses\n let rejectedOrMissedCount = 0;\n this.participantResponses.forEach((response) => {\n if (response === 'rejected' || response === 'missed') {\n rejectedOrMissedCount++;\n }\n });\n\n console.log(`Participants responded: ${this.participantResponses.size}/${totalParticipants}`);\n console.log(`Rejected or missed: ${rejectedOrMissedCount}`);\n\n const allResponded = this.participantResponses.size >= totalParticipants;\n const allRejectedOrMissed =\n allResponded &&\n Array.from(this.participantResponses.values()).every(\n (response) => response === 'rejected' || response === 'missed',\n );\n\n // If all participants have rejected or missed the call\n if (allResponded && allRejectedOrMissed) {\n console.log('All participants have rejected or missed the call');\n\n // End the call\n this.currentCall.leave();\n\n // Clean up the timer if exists in callStates\n const callState = this.callStates.get(callCid);\n if (callState?.timer) {\n clearInterval(callState.timer);\n }\n\n // Remove from callStates\n this.callStates.delete(callCid);\n\n // Clear the responses\n this.participantResponses.clear();\n\n // Clean up\n this.cleanupCall();\n\n // Notify that the call has ended\n this.notifyListeners('callEvent', {\n callId: callCid,\n state: 'ended',\n reason: 'all_rejected_or_missed',\n });\n }\n }\n\n private cleanupCall() {\n // First cleanup the call listeners\n if (this.currentCall) {\n if (this.participantJoinedListener) {\n this.currentCall.off('participantJoined', this.participantJoinedListener);\n this.participantJoinedListener = undefined;\n }\n if (this.participantLeftListener) {\n this.currentCall.off('participantLeft', this.participantLeftListener);\n this.participantLeftListener = undefined;\n }\n this.callStateSubscription?.unsubscribe();\n }\n\n if (this.magicDivId) {\n const magicDiv = document.getElementById(this.magicDivId);\n if (magicDiv) {\n // Remove all video elements\n const videoElements = magicDiv.querySelectorAll('video');\n videoElements.forEach((video) => {\n const id = video.id;\n const unbind = this.videoBindings.get(id);\n if (unbind) {\n unbind();\n this.videoBindings.delete(id);\n }\n // Stop all tracks\n const tracks = (video as HTMLVideoElement).srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n video.srcObject = null;\n }\n video.remove();\n });\n\n // Remove all audio elements\n const audioElements = magicDiv.querySelectorAll('audio');\n audioElements.forEach((audio) => {\n const id = audio.id;\n const unbind = this.audioBindings.get(id);\n if (unbind) {\n unbind();\n this.audioBindings.delete(id);\n }\n // Stop all tracks\n const tracks = (audio as HTMLAudioElement).srcObject as MediaStream;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n audio.srcObject = null;\n }\n audio.remove();\n });\n\n // Clear the container\n while (magicDiv.firstChild) {\n magicDiv.removeChild(magicDiv.firstChild);\n }\n }\n }\n\n // Clear all bindings\n this.videoBindings.clear();\n this.audioBindings.clear();\n\n // Clear call references\n this.currentCall = undefined;\n this.incomingCall = undefined;\n }\n\n async login(options: LoginOptions): Promise<SuccessResponse> {\n this.client = StreamVideoClient.getOrCreateInstance({\n apiKey: options.apiKey,\n user: { id: options.userId, name: options.name, image: options.imageURL },\n token: options.token,\n });\n\n this.magicDivId = options.magicDivId;\n this.setupCallRingListener();\n\n return { success: true };\n }\n\n async logout(): Promise<SuccessResponse> {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized');\n }\n\n // Cleanup subscription\n this.callStateSubscription?.unsubscribe();\n this.callStateSubscription = undefined;\n\n await this.client.disconnectUser();\n this.client = undefined;\n this.currentCall = undefined;\n return { success: true };\n }\n\n async call(options: CallOptions): Promise<SuccessResponse> {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized - Please login first');\n }\n\n const call = this.client.call(options.type || 'default', crypto.randomUUID());\n const members = options.userIds.map((userId) => ({ user_id: userId }));\n if (this.client.streamClient.userID && !options.userIds.includes(this.client.streamClient.userID)) {\n members.push({ user_id: this.client.streamClient.userID });\n }\n await call.getOrCreate({ data: { members, team: options.team } });\n\n // Store the expected member count for this call\n // -1, because we don't count the caller themselves\n this.callMembersExpected.set(call.cid, members.length);\n console.log(`Setting expected members for call ${call.cid}: ${members.length}`);\n\n this.currentCall = call;\n if (options.ring) {\n this.outgoingCall = call.cid;\n await call.ring();\n }\n\n await call.join();\n return { success: true };\n }\n\n async endCall(): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n await this.currentCall.leave();\n this.currentCall = undefined;\n this.cleanupCall();\n\n return { success: true };\n }\n\n async setMicrophoneEnabled(options: { enabled: boolean }): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n if (options.enabled) {\n await this.currentCall.microphone.enable();\n } else {\n await this.currentCall.microphone.disable();\n }\n\n return { success: true };\n }\n\n async setCameraEnabled(options: { enabled: boolean }): Promise<SuccessResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n\n if (options.enabled) {\n await this.currentCall.camera.enable();\n } else {\n await this.currentCall.camera.disable();\n }\n\n return { success: true };\n }\n\n async acceptCall(): Promise<SuccessResponse> {\n if (!this.incomingCall || !this.client) {\n console.log('No incoming call to accept', this.incomingCall, this.client);\n throw new Error('No incoming call to accept');\n }\n console.log('Accepting call', this.incomingCall);\n const call = this.client.call(this.incomingCall.type, this.incomingCall.id);\n this.currentCall = call;\n console.log('Joining call', call);\n await call.accept();\n await call.join();\n console.log('Joined call', call);\n this.notifyListeners('callEvent', { callId: call.id, state: CallingState.JOINED });\n this.setupParticipantListener();\n return { success: true };\n }\n\n async rejectCall(): Promise<SuccessResponse> {\n if (!this.incomingCall || !this.client) {\n console.log('No incoming call to reject', this.incomingCall, this.client);\n throw new Error('No incoming call to reject');\n }\n console.log('Rejecting call', this.incomingCall);\n const call: Call = this.client.call(this.incomingCall.type, this.incomingCall.id);\n console.log('Leaving call', call);\n await call.reject();\n this.incomingCall = undefined;\n console.log('Rejected call', call);\n this.notifyListeners('callEvent', { callId: call.id, state: CallingState.LEFT });\n this.cleanupCall();\n return { success: true };\n }\n\n async isCameraEnabled(): Promise<CameraEnabledResponse> {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n const enabled = await this.currentCall.camera.enabled;\n return { enabled };\n }\n\n async getCallStatus(): Promise<CallEvent> {\n if (!this.currentCall) {\n throw new Error('No active call');\n }\n\n const callingState = this.currentCall.state.callingState;\n let state: CallState;\n\n switch (callingState) {\n case CallingState.IDLE:\n state = 'idle';\n break;\n case CallingState.RINGING:\n state = 'ringing';\n break;\n case CallingState.JOINING:\n state = 'joining';\n break;\n case CallingState.RECONNECTING:\n state = 'reconnecting';\n break;\n case CallingState.JOINED:\n state = 'joined';\n break;\n case CallingState.LEFT:\n state = 'left';\n break;\n default:\n state = 'unknown';\n }\n\n return {\n callId: this.currentCall.id,\n state,\n };\n }\n}\n"]}