@capgo/capacitor-stream-call 0.0.3 → 0.0.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst StreamCall = registerPlugin('StreamCall', {\n web: () => import('./web').then((m) => new m.StreamCallWeb()),\n});\nexport * from './definitions';\nexport { StreamCall };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { CallingState, StreamVideoClient } from '@stream-io/video-client';\nexport class StreamCallWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.videoBindings = new Map();\n this.audioBindings = new Map();\n this.ringCallback = (event) => {\n var _a, _b;\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 = (_a = this.client) === null || _a === void 0 ? void 0 : _a.call(event.call.type, event.call.id);\n this.notifyListeners('callEvent', { callId: event.call.id, state: CallingState.RINGING });\n }\n if (this.currentCall) {\n console.log('Call found', this.currentCall.id);\n this.callStateSubscription = (_b = this.currentCall) === null || _b === void 0 ? void 0 : _b.state.callingState$.subscribe((s) => {\n var _a;\n console.log('Call state', s);\n if (s === CallingState.JOINED) {\n this.setupParticipantListener();\n }\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 }\n else {\n this.notifyListeners('callEvent', { callId: (_a = this.currentCall) === null || _a === void 0 ? void 0 : _a.id, state: s });\n }\n });\n }\n };\n }\n setupCallRingListener() {\n var _a, _b;\n (_a = this.client) === null || _a === void 0 ? void 0 : _a.off('call.ring', this.ringCallback);\n (_b = this.client) === null || _b === void 0 ? void 0 : _b.on('call.ring', this.ringCallback);\n }\n setupParticipantListener() {\n // Subscribe to participant changes\n this.incomingCall = undefined;\n if (!this.currentCall)\n return;\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, magicDiv);\n this.setupParticipantAudio(this.currentCall, event.participant, magicDiv);\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 // Remove video element\n const videoEl = document.getElementById(videoId);\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;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n videoEl.srcObject = null;\n }\n videoEl.remove();\n }\n // Remove audio element\n const audioEl = document.getElementById(audioId);\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;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n track.enabled = false;\n });\n audioEl.srcObject = null;\n }\n audioEl.remove();\n }\n }\n };\n this.currentCall.on('participantJoined', this.participantJoinedListener);\n this.currentCall.on('participantLeft', this.participantLeftListener);\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) => {\n if (this.currentCall) {\n this.setupParticipantVideo(this.currentCall, participant, magicDiv);\n this.setupParticipantAudio(this.currentCall, participant, magicDiv);\n }\n });\n }\n }\n }\n setupParticipantVideo(call, participant, container) {\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 const unbind = call.bindVideoElement(videoEl, participant.sessionId, 'videoTrack');\n if (unbind)\n this.videoBindings.set(id, unbind);\n }\n }\n setupParticipantAudio(call, participant, container) {\n if (participant.isLocalParticipant)\n return;\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 const unbind = call.bindAudioElement(audioEl, participant.sessionId);\n if (unbind)\n this.audioBindings.set(id, unbind);\n }\n }\n cleanupCall() {\n var _a;\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 (_a = this.callStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();\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.srcObject;\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 // 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.srcObject;\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 // Clear the container\n while (magicDiv.firstChild) {\n magicDiv.removeChild(magicDiv.firstChild);\n }\n }\n }\n // Clear all bindings\n this.videoBindings.clear();\n this.audioBindings.clear();\n // Clear call references\n this.currentCall = undefined;\n this.incomingCall = undefined;\n }\n async login(options) {\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 this.magicDivId = options.magicDivId;\n this.setupCallRingListener();\n return { success: true };\n }\n async logout() {\n var _a;\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized');\n }\n // Cleanup subscription\n (_a = this.callStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();\n this.callStateSubscription = undefined;\n await this.client.disconnectUser();\n this.client = undefined;\n this.currentCall = undefined;\n return { success: true };\n }\n async call(options) {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized - Please login first');\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 this.currentCall = call;\n if (options.ring) {\n this.outgoingCall = call.cid;\n await call.ring();\n }\n await call.join();\n return { success: true };\n }\n async endCall() {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n await this.currentCall.leave();\n this.currentCall = undefined;\n this.cleanupCall();\n return { success: true };\n }\n async setMicrophoneEnabled(options) {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n if (options.enabled) {\n await this.currentCall.microphone.enable();\n }\n else {\n await this.currentCall.microphone.disable();\n }\n return { success: true };\n }\n async setCameraEnabled(options) {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n if (options.enabled) {\n await this.currentCall.camera.enable();\n }\n else {\n await this.currentCall.camera.disable();\n }\n return { success: true };\n }\n async acceptCall() {\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 async rejectCall() {\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 = this.client.call(this.incomingCall.type, this.incomingCall.id);\n console.log('Leaving call', call);\n await call.leave();\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 async isCameraEnabled() {\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//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin","CallingState","StreamVideoClient"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst StreamCall = registerPlugin('StreamCall', {\n web: () => import('./web').then((m) => new m.StreamCallWeb()),\n});\nexport * from './definitions';\nexport { StreamCall };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { CallingState, StreamVideoClient } from '@stream-io/video-client';\nexport class StreamCallWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.videoBindings = new Map();\n this.audioBindings = new Map();\n this.participantResponses = new Map();\n this.callMembersExpected = new Map();\n this.ringCallback = (event) => {\n var _a, _b;\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 = (_a = this.client) === null || _a === void 0 ? void 0 : _a.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 = (_b = this.currentCall) === null || _b === void 0 ? void 0 : _b.state.callingState$.subscribe((s) => {\n var _a;\n console.log('Call state', s);\n if (s === CallingState.JOINED) {\n this.setupParticipantListener();\n this.setupCallEventListeners();\n }\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 }\n else {\n this.notifyListeners('callEvent', { callId: (_a = this.currentCall) === null || _a === void 0 ? void 0 : _a.id, state: s });\n }\n });\n }\n };\n this.callSessionStartedCallback = (event) => {\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 // Store call members in callStates\n this.callStates.set(callCid, {\n members: event.call.session.participants.map(p => { var _a; return ({ user_id: ((_a = p.user) === null || _a === void 0 ? void 0 : _a.id) || '' }); }),\n participantResponses: new Map(),\n expectedMemberCount: memberCount,\n createdAt: new Date(),\n });\n // Start a timeout task that runs every second\n const timeoutTask = setInterval(() => this.checkCallTimeout(callCid), 1000);\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 this.callRejectedCallback = (event) => {\n console.log('Call rejected', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'rejected');\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 this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'rejected',\n userId: event.user.id\n });\n this.checkAllParticipantsResponded();\n }\n };\n this.callAcceptedCallback = (event) => {\n console.log('Call accepted', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'accepted');\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 // 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 this.callStates.set(event.call_cid, callState);\n }\n this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'accepted',\n userId: event.user.id\n });\n }\n };\n this.callMissedCallback = (event) => {\n console.log('Call missed', event);\n if (event.user && event.user.id) {\n this.participantResponses.set(event.user.id, 'missed');\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 this.notifyListeners('callEvent', {\n callId: event.call_cid,\n state: 'missed',\n userId: event.user.id\n });\n this.checkAllParticipantsResponded();\n }\n };\n // Add a combined map for call states, mirroring the iOS implementation\n this.callStates = new Map();\n }\n // private currentActiveCallId?: string;\n setupCallRingListener() {\n var _a, _b, _c, _d;\n (_a = this.client) === null || _a === void 0 ? void 0 : _a.off('call.ring', this.ringCallback);\n (_b = this.client) === null || _b === void 0 ? void 0 : _b.off('call.session_started', this.callSessionStartedCallback);\n (_c = this.client) === null || _c === void 0 ? void 0 : _c.on('call.ring', this.ringCallback);\n (_d = this.client) === null || _d === void 0 ? void 0 : _d.on('call.session_started', this.callSessionStartedCallback);\n }\n setupCallEventListeners() {\n var _a, _b, _c, _d, _e, _f;\n // Clear previous listeners if any\n (_a = this.client) === null || _a === void 0 ? void 0 : _a.off('call.rejected', this.callRejectedCallback);\n (_b = this.client) === null || _b === void 0 ? void 0 : _b.off('call.accepted', this.callAcceptedCallback);\n (_c = this.client) === null || _c === void 0 ? void 0 : _c.off('call.missed', this.callMissedCallback);\n // Register event listeners\n (_d = this.client) === null || _d === void 0 ? void 0 : _d.on('call.rejected', this.callRejectedCallback);\n (_e = this.client) === null || _e === void 0 ? void 0 : _e.on('call.accepted', this.callAcceptedCallback);\n (_f = this.client) === null || _f === void 0 ? void 0 : _f.on('call.missed', this.callMissedCallback);\n }\n setupParticipantListener() {\n // Subscribe to participant changes\n this.incomingCall = undefined;\n if (!this.currentCall)\n return;\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, magicDiv);\n this.setupParticipantAudio(this.currentCall, event.participant, magicDiv);\n }\n }\n };\n this.participantLeftListener = (event) => {\n var _a, _b;\n if (this.magicDivId && event.participant) {\n const videoId = `video-${event.participant.sessionId}`;\n const audioId = `audio-${event.participant.sessionId}`;\n // Remove video element\n const videoEl = document.getElementById(videoId);\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;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n videoEl.srcObject = null;\n videoEl.remove();\n }\n // Remove audio element\n const audioEl = document.getElementById(audioId);\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;\n if (tracks) {\n tracks.getTracks().forEach((track) => {\n track.stop();\n });\n }\n audioEl.srcObject = null;\n audioEl.remove();\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 // 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 // End the call\n this.currentCall.leave();\n // Clean up resources\n const callCid = this.currentCall.cid;\n // Invalidate and remove timer\n const callState = (_a = this.callStates) === null || _a === void 0 ? void 0 : _a.get(callCid);\n if (callState === null || callState === void 0 ? void 0 : callState.timer) {\n clearInterval(callState.timer);\n }\n // Remove from callStates\n (_b = this.callStates) === null || _b === void 0 ? void 0 : _b.delete(callCid);\n // Reset the current call\n this.currentCall = undefined;\n // this.currentActiveCallId = undefined;\n // Clean up\n this.cleanupCall();\n console.log(`Cleaned up resources for ended call: ${callCid}`);\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 this.currentCall.on('participantJoined', this.participantJoinedListener);\n this.currentCall.on('participantLeft', this.participantLeftListener);\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) => {\n if (this.currentCall) {\n this.setupParticipantVideo(this.currentCall, participant, magicDiv);\n this.setupParticipantAudio(this.currentCall, participant, magicDiv);\n }\n });\n }\n }\n }\n setupParticipantVideo(call, participant, container) {\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 const unbind = call.bindVideoElement(videoEl, participant.sessionId, 'videoTrack');\n if (unbind)\n this.videoBindings.set(id, unbind);\n }\n }\n setupParticipantAudio(call, participant, container) {\n if (participant.isLocalParticipant)\n return;\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 const unbind = call.bindAudioElement(audioEl, participant.sessionId);\n if (unbind)\n this.audioBindings.set(id, unbind);\n }\n }\n checkCallTimeout(callCid) {\n const callState = this.callStates.get(callCid);\n if (!callState)\n return;\n // Calculate time elapsed since call creation\n const now = new Date();\n const elapsedSeconds = (now.getTime() - callState.createdAt.getTime()) / 1000;\n // Check if 30 seconds have passed\n if (elapsedSeconds >= 30) {\n console.log(`Call ${callCid} has timed out after ${elapsedSeconds} seconds`);\n // Check if anyone has accepted\n const hasAccepted = Array.from(callState.participantResponses.values())\n .some(response => response === 'accepted');\n if (!hasAccepted) {\n console.log(`No one accepted call ${callCid}, marking all non-responders as missed`);\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 this.notifyListeners('callEvent', {\n callId: callCid,\n state: 'missed',\n userId: member.user_id\n });\n }\n });\n // End the call\n if (this.currentCall && this.currentCall.cid === callCid) {\n this.currentCall.leave();\n }\n // Clear the timeout task\n if (callState.timer) {\n clearInterval(callState.timer);\n callState.timer = undefined;\n }\n // Remove from callStates\n this.callStates.delete(callCid);\n // Clean up\n this.cleanupCall();\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 checkAllParticipantsResponded() {\n if (!this.currentCall)\n return;\n const callCid = this.currentCall.cid;\n const totalParticipants = this.callMembersExpected.get(callCid);\n if (!totalParticipants) {\n console.log(`No expected participant count found for call: ${callCid}`);\n return;\n }\n console.log(`Total expected participants: ${totalParticipants}`);\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 console.log(`Participants responded: ${this.participantResponses.size}/${totalParticipants}`);\n console.log(`Rejected or missed: ${rejectedOrMissedCount}`);\n const allResponded = this.participantResponses.size >= totalParticipants;\n const allRejectedOrMissed = allResponded &&\n Array.from(this.participantResponses.values()).every(response => response === 'rejected' || response === 'missed');\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 // End the call\n this.currentCall.leave();\n // Clean up the timer if exists in callStates\n const callState = this.callStates.get(callCid);\n if (callState === null || callState === void 0 ? void 0 : callState.timer) {\n clearInterval(callState.timer);\n }\n // Remove from callStates\n this.callStates.delete(callCid);\n // Clear the responses\n this.participantResponses.clear();\n // Clean up\n this.cleanupCall();\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 cleanupCall() {\n var _a;\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 (_a = this.callStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();\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.srcObject;\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 // 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.srcObject;\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 // Clear the container\n while (magicDiv.firstChild) {\n magicDiv.removeChild(magicDiv.firstChild);\n }\n }\n }\n // Clear all bindings\n this.videoBindings.clear();\n this.audioBindings.clear();\n // Clear call references\n this.currentCall = undefined;\n this.incomingCall = undefined;\n }\n async login(options) {\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 this.magicDivId = options.magicDivId;\n this.setupCallRingListener();\n return { success: true };\n }\n async logout() {\n var _a;\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized');\n }\n // Cleanup subscription\n (_a = this.callStateSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();\n this.callStateSubscription = undefined;\n await this.client.disconnectUser();\n this.client = undefined;\n this.currentCall = undefined;\n return { success: true };\n }\n async call(options) {\n if (!this.client) {\n console.log('No client', this.client);\n throw new Error('Client not initialized - Please login first');\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 // 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 this.currentCall = call;\n if (options.ring) {\n this.outgoingCall = call.cid;\n await call.ring();\n }\n await call.join();\n return { success: true };\n }\n async endCall() {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n await this.currentCall.leave();\n this.currentCall = undefined;\n this.cleanupCall();\n return { success: true };\n }\n async setMicrophoneEnabled(options) {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n if (options.enabled) {\n await this.currentCall.microphone.enable();\n }\n else {\n await this.currentCall.microphone.disable();\n }\n return { success: true };\n }\n async setCameraEnabled(options) {\n if (!this.currentCall) {\n console.log('No active call', this.currentCall);\n throw new Error('No active call');\n }\n if (options.enabled) {\n await this.currentCall.camera.enable();\n }\n else {\n await this.currentCall.camera.disable();\n }\n return { success: true };\n }\n async acceptCall() {\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 async rejectCall() {\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 = 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 async isCameraEnabled() {\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//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin","CallingState","StreamVideoClient"],"mappings":"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"}
@@ -48,10 +48,16 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
48
48
 
49
49
  private var streamVideo: StreamVideo?
50
50
 
51
+ // Track the current active call ID
52
+ private var currentActiveCallId: String?
53
+
51
54
  @Injected(\.callKitAdapter) var callKitAdapter
52
55
  @Injected(\.callKitPushNotificationAdapter) var callKitPushNotificationAdapter
53
56
  private var webviewDelegate: WebviewNavigationDelegate?
54
57
 
58
+ // Add class property to store call states
59
+ private var callStates: [String: (members: [MemberResponse], participantResponses: [String: String], createdAt: Date, timer: Timer?)] = [:]
60
+
55
61
  override public func load() {
56
62
  // Read API key from Info.plist
57
63
  if let apiKey = Bundle.main.object(forInfoDictionaryKey: "CAPACITOR_STREAM_VIDEO_APIKEY") as? String {
@@ -158,55 +164,139 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
158
164
 
159
165
  private func setupActiveCallSubscription() {
160
166
  if let streamVideo = streamVideo {
161
- // Track participants responses
162
- var participantResponses: [String: String] = [:]
163
-
164
167
  Task {
165
168
  for await event in streamVideo.subscribe() {
166
- print("Event", event)
169
+ // print("Event", event)
167
170
  if let ringingEvent = event.rawValue as? CallRingEvent {
168
171
  notifyListeners("callEvent", data: [
169
172
  "callId": ringingEvent.callCid,
170
173
  "state": "ringing"
171
174
  ])
172
- return
175
+ continue
176
+ }
177
+
178
+ if let callCreatedEvent = event.rawValue as? CallCreatedEvent {
179
+ print("CallCreatedEvent \(String(describing: userId))")
180
+
181
+ let callCid = callCreatedEvent.callCid
182
+ let members = callCreatedEvent.members
183
+
184
+ // Create timer on main thread
185
+ await MainActor.run {
186
+ // Store in the combined callStates map
187
+ self.callStates[callCid] = (
188
+ members: members,
189
+ participantResponses: [:],
190
+ createdAt: Date(),
191
+ timer: nil
192
+ )
193
+
194
+ // Start timer to check for timeout every second
195
+ // Use @objc method as timer target to avoid sendable closure issues
196
+ let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.checkCallTimeoutTimer(_:)), userInfo: callCid, repeats: true)
197
+
198
+ // Update timer in callStates
199
+ self.callStates[callCid]?.timer = timer
200
+ }
173
201
  }
174
202
 
175
203
  if let rejectedEvent = event.rawValue as? CallRejectedEvent {
176
204
  let userId = rejectedEvent.user.id
177
- participantResponses[userId] = "rejected"
205
+ let callCid = rejectedEvent.callCid
206
+
207
+ // Operate on callStates on the main thread
208
+ await MainActor.run {
209
+ // Update the combined callStates map
210
+ if var callState = self.callStates[callCid] {
211
+ callState.participantResponses[userId] = "rejected"
212
+ self.callStates[callCid] = callState
213
+ }
214
+ }
215
+
216
+ print("CallRejectedEvent \(userId)")
178
217
  notifyListeners("callEvent", data: [
179
- "callId": rejectedEvent.callCid,
218
+ "callId": callCid,
180
219
  "state": "rejected",
181
220
  "userId": userId
182
221
  ])
183
222
 
184
- await checkAllParticipantsResponded(participantResponses: participantResponses)
185
- return
223
+ await checkAllParticipantsResponded(callCid: callCid)
224
+ continue
186
225
  }
187
226
 
188
227
  if let missedEvent = event.rawValue as? CallMissedEvent {
189
228
  let userId = missedEvent.user.id
190
- participantResponses[userId] = "missed"
229
+ let callCid = missedEvent.callCid
230
+
231
+ // Operate on callStates on the main thread
232
+ await MainActor.run {
233
+ // Update the combined callStates map
234
+ if var callState = self.callStates[callCid] {
235
+ callState.participantResponses[userId] = "missed"
236
+ self.callStates[callCid] = callState
237
+ }
238
+ }
239
+
240
+ print("CallMissedEvent \(userId)")
191
241
  notifyListeners("callEvent", data: [
192
- "callId": missedEvent.callCid,
242
+ "callId": callCid,
193
243
  "state": "missed",
194
244
  "userId": userId
195
245
  ])
196
246
 
197
- await checkAllParticipantsResponded(participantResponses: participantResponses)
198
- return
247
+ await checkAllParticipantsResponded(callCid: callCid)
248
+ continue
249
+ }
250
+
251
+ if let participantLeftEvent = event.rawValue as? CallSessionParticipantLeftEvent {
252
+ let callIdSplit = participantLeftEvent.callCid.split(separator: ":")
253
+ if (callIdSplit.count != 2) {
254
+ print("CallSessionParticipantLeftEvent invalid cID \(participantLeftEvent.callCid)")
255
+ continue
256
+ }
257
+
258
+ let callType = callIdSplit[0]
259
+ let callId = callIdSplit[1]
260
+
261
+ let call = streamVideo.call(callType: String(callType), callId: String(callId))
262
+ if await MainActor.run(body: { (call.state.session?.participants.count ?? 1) - 1 <= 1 }) {
263
+
264
+
265
+ print("We are left solo in a call. Ending. cID: \(participantLeftEvent.callCid)")
266
+
267
+ Task {
268
+ if let activeCall = streamVideo.state.activeCall {
269
+ activeCall.leave()
270
+ }
271
+ }
272
+ }
199
273
  }
200
274
 
201
275
  if let acceptedEvent = event.rawValue as? CallAcceptedEvent {
202
276
  let userId = acceptedEvent.user.id
203
- participantResponses[userId] = "accepted"
277
+ let callCid = acceptedEvent.callCid
278
+
279
+ // Operate on callStates on the main thread
280
+ await MainActor.run {
281
+ // Update the combined callStates map
282
+ if var callState = self.callStates[callCid] {
283
+ callState.participantResponses[userId] = "accepted"
284
+
285
+ // If someone accepted, invalidate the timer as we don't need to check anymore
286
+ callState.timer?.invalidate()
287
+ callState.timer = nil
288
+
289
+ self.callStates[callCid] = callState
290
+ }
291
+ }
292
+
293
+ print("CallAcceptedEvent \(userId)")
204
294
  notifyListeners("callEvent", data: [
205
- "callId": acceptedEvent.callCid,
295
+ "callId": callCid,
206
296
  "state": "accepted",
207
297
  "userId": userId
208
298
  ])
209
- return
299
+ continue
210
300
  }
211
301
 
212
302
  notifyListeners("callEvent", data: [
@@ -221,17 +311,23 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
221
311
  // Create new subscription
222
312
  activeCallSubscription = streamVideo?.state.$activeCall.sink { [weak self] newState in
223
313
  guard let self = self else { return }
314
+
224
315
  Task { @MainActor in
225
316
  do {
226
317
  try self.requireInitialized()
227
318
  print("Call State Update:")
228
319
  print("- Call is nil: \(newState == nil)")
320
+
229
321
  if let state = newState?.state {
230
322
  print("- state: \(state)")
231
323
  print("- Session ID: \(state.sessionId)")
232
324
  print("- All participants: \(String(describing: state.participants))")
233
325
  print("- Remote participants: \(String(describing: state.remoteParticipants))")
234
326
 
327
+ // Store the active call ID when a call becomes active
328
+ self.currentActiveCallId = newState?.cId
329
+ print("Updated current active call ID: \(String(describing: self.currentActiveCallId))")
330
+
235
331
  // Update overlay and make visible when there's an active call
236
332
  self.overlayViewModel?.updateCall(newState)
237
333
  self.overlayView?.isHidden = false
@@ -243,16 +339,34 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
243
339
  "state": "joined"
244
340
  ])
245
341
  } else {
342
+ // Get the call ID that was active before the state changed to nil
343
+ let endingCallId = self.currentActiveCallId
344
+ print("Call ending: \(String(describing: endingCallId))")
345
+
246
346
  // If newState is nil, hide overlay and clear call
247
347
  self.overlayViewModel?.updateCall(nil)
248
348
  self.overlayView?.isHidden = true
249
349
  self.webView?.isOpaque = true
250
350
 
251
- // Notify that call has ended
351
+ // Notify that call has ended - use the properly tracked call ID
252
352
  self.notifyListeners("callEvent", data: [
253
- "callId": newState?.cId ?? "",
353
+ "callId": endingCallId ?? "",
254
354
  "state": "left"
255
355
  ])
356
+
357
+ // Clean up any resources for this call
358
+ if let callCid = endingCallId {
359
+ // Invalidate and remove the timer
360
+ self.callStates[callCid]?.timer?.invalidate()
361
+
362
+ // Remove call from callStates
363
+ self.callStates.removeValue(forKey: callCid)
364
+
365
+ print("Cleaned up resources for ended call: \(callCid)")
366
+ }
367
+
368
+ // Clear the active call ID
369
+ self.currentActiveCallId = nil
256
370
  }
257
371
  } catch {
258
372
  log.error("Error handling call state update: \(String(describing: error))")
@@ -261,16 +375,134 @@ public class StreamCallPlugin: CAPPlugin, CAPBridgedPlugin {
261
375
  }
262
376
  }
263
377
 
264
- private func checkAllParticipantsResponded(participantResponses: [String: String]) async {
265
- let call = streamVideo?.state.activeCall
266
- let totalParticipants = await call?.state.participants.count ?? 0
267
- let allResponded = participantResponses.count == totalParticipants
268
- let allRejectedOrMissed = participantResponses.values.allSatisfy { $0 == "rejected" || $0 == "missed" }
378
+ @objc private func checkCallTimeoutTimer(_ timer: Timer) {
379
+ guard let callCid = timer.userInfo as? String else { return }
380
+
381
+ Task { [weak self] in
382
+ guard let self = self else { return }
383
+ await self.checkCallTimeout(callCid: callCid)
384
+ }
385
+ }
386
+
387
+ private func checkCallTimeout(callCid: String) async {
388
+ // Get a local copy of the call state from the main thread
389
+ let callState: (members: [MemberResponse], participantResponses: [String: String], createdAt: Date, timer: Timer?)? = await MainActor.run {
390
+ return self.callStates[callCid]
391
+ }
392
+
393
+ guard let callState = callState else { return }
394
+
395
+ // Calculate time elapsed since call creation
396
+ let now = Date()
397
+ let elapsedSeconds = now.timeIntervalSince(callState.createdAt)
398
+
399
+ // Check if 30 seconds have passed
400
+ if elapsedSeconds >= 30.0 {
401
+
402
+ // Check if anyone has accepted
403
+ let hasAccepted = callState.participantResponses.values.contains { $0 == "accepted" }
404
+
405
+ if !hasAccepted {
406
+ print("Call \(callCid) has timed out after \(elapsedSeconds) seconds")
407
+ print("No one accepted call \(callCid), marking all non-responders as missed")
408
+
409
+ // Mark all members who haven't responded as "missed"
410
+ for member in callState.members {
411
+ let memberId = member.userId
412
+ let needsToBeMarkedAsMissed = await MainActor.run {
413
+ return self.callStates[callCid]?.participantResponses[memberId] == nil
414
+ }
415
+
416
+ if needsToBeMarkedAsMissed {
417
+ // Update callStates map on main thread
418
+ await MainActor.run {
419
+ var updatedCallState = self.callStates[callCid]
420
+ updatedCallState?.participantResponses[memberId] = "missed"
421
+ if let updatedCallState = updatedCallState {
422
+ self.callStates[callCid] = updatedCallState
423
+ }
424
+ }
425
+
426
+ // Notify listeners
427
+ await MainActor.run {
428
+ self.notifyListeners("callEvent", data: [
429
+ "callId": callCid,
430
+ "state": "missed",
431
+ "userId": memberId
432
+ ])
433
+ }
434
+ }
435
+ }
436
+
437
+ // End the call
438
+ if let call = streamVideo?.state.activeCall, call.cId == callCid {
439
+ call.leave()
440
+ }
441
+
442
+ // Clean up timer on main thread
443
+ await MainActor.run {
444
+ self.callStates[callCid]?.timer?.invalidate()
445
+ var updatedCallState = self.callStates[callCid]
446
+ updatedCallState?.timer = nil
447
+ if let updatedCallState = updatedCallState {
448
+ self.callStates[callCid] = updatedCallState
449
+ }
450
+
451
+ // Remove from callStates
452
+ self.callStates.removeValue(forKey: callCid)
453
+ }
454
+
455
+ // Update UI
456
+ await MainActor.run {
457
+ self.overlayViewModel?.updateCall(nil)
458
+ self.overlayView?.isHidden = true
459
+ self.webView?.isOpaque = true
460
+ self.notifyListeners("callEvent", data: [
461
+ "callId": callCid,
462
+ "state": "ended",
463
+ "reason": "timeout"
464
+ ])
465
+ }
466
+ }
467
+ }
468
+ }
469
+
470
+ private func checkAllParticipantsResponded(callCid: String) async {
471
+ // Get a local copy of the call state from the main thread
472
+ let callState: (members: [MemberResponse], participantResponses: [String: String], createdAt: Date, timer: Timer?)? = await MainActor.run {
473
+ return self.callStates[callCid]
474
+ }
475
+
476
+ guard let callState = callState else {
477
+ print("Call state not found for cId: \(callCid)")
478
+ return
479
+ }
480
+
481
+ let totalParticipants = callState.members.count
482
+ let responseCount = callState.participantResponses.count
483
+
484
+ print("Total participants: \(totalParticipants), Responses: \(responseCount)")
485
+
486
+ let allResponded = responseCount >= totalParticipants
487
+ let allRejectedOrMissed = allResponded &&
488
+ callState.participantResponses.values.allSatisfy { $0 == "rejected" || $0 == "missed" }
269
489
 
270
490
  if allResponded && allRejectedOrMissed {
271
491
  print("All participants have rejected or missed the call")
272
- call?.leave()
492
+
493
+ // End the call
494
+ if let call = streamVideo?.state.activeCall, call.cId == callCid {
495
+ call.leave()
496
+ }
497
+
498
+ // Clean up timer and remove from callStates on main thread
273
499
  await MainActor.run {
500
+ // Clean up timer
501
+ self.callStates[callCid]?.timer?.invalidate()
502
+
503
+ // Remove from callStates
504
+ self.callStates.removeValue(forKey: callCid)
505
+
274
506
  self.overlayViewModel?.updateCall(nil)
275
507
  self.overlayView?.isHidden = true
276
508
  self.webView?.isOpaque = true
@@ -132,8 +132,8 @@ class TouchInterceptView: UIView {
132
132
  // Convert point to global coordinates for labeled frame checking
133
133
  let globalPoint = convert(point, to: nil)
134
134
 
135
- print("TouchInterceptView - Hit test at global point: \(globalPoint)")
136
- print("Current labeled frames: \(labeledFrames.map { "\($0.label): \($0.frame)" }.joined(separator: ", "))")
135
+ //print("TouchInterceptView - Hit test at global point: \(globalPoint)")
136
+ //print("Current labeled frames: \(labeledFrames.map { "\($0.label): \($0.frame)" }.joined(separator: ", "))")
137
137
 
138
138
  // Convert point for both views
139
139
  let webViewPoint = convert(point, to: webView)
@@ -142,7 +142,7 @@ class TouchInterceptView: UIView {
142
142
  // First check if the point is inside any labeled frame
143
143
  for labeledFrame in labeledFrames {
144
144
  if labeledFrame.frame.contains(globalPoint) {
145
- print("Hit labeled frame: \(labeledFrame.label)")
145
+ //print("Hit labeled frame: \(labeledFrame.label)")
146
146
  // If it's in a labeled frame, let the overlay handle it
147
147
  if overlayView.point(inside: overlayPoint, with: event),
148
148
  let overlayHitView = overlayView.hitTest(overlayPoint, with: event) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-stream-call",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Uses the https://getstream.io/ SDK to implement calling in Capacitor",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -39,7 +39,7 @@
39
39
  "ios",
40
40
  "android",
41
41
  "web",
42
- "capacitor-plugin"
42
+ "capacitor-plugin"
43
43
  ],
44
44
  "scripts": {
45
45
  "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",