UNPKG

call-screen

Version:

Capacitor plugin for full-screen call UI with Accept/Reject buttons, OneSignal integration, and cross-platform support

255 lines (249 loc) 9.77 kB
'use strict'; var core = require('@capacitor/core'); const CallScreen = core.registerPlugin('CallScreen', { web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CallScreenWeb()), }); class CallScreenWeb extends core.WebPlugin { constructor() { super(...arguments); this._isCallActive = false; this.audioContext = null; this.oscillator = null; this.callModal = null; } async showCallScreen(options) { console.log('Showing call screen on web:', options); // Create and show call modal this.createCallModal(options.username, options.callId, options.roomName); // Play ringtone this.playWebRingtone(); this._isCallActive = true; // For web, you could show a browser notification or modal if ('Notification' in window && Notification.permission === 'granted') { new Notification('Incoming Call', { body: `Call from ${options.username}`, icon: '/assets/icon/call-icon.png', tag: 'call-notification', requireInteraction: true }); } } async handleIncomingCall(options) { console.log('Handling incoming call on web:', options); // Request notification permission if not granted if ('Notification' in window && Notification.permission === 'default') { const permission = await Notification.requestPermission(); if (permission !== 'granted') { console.warn('Notification permission denied'); } } // Show call screen await this.showCallScreen(options); // Trigger custom event for web apps this.notifyListeners('incomingCall', options); } async stopCall() { console.log('Stopping call on web'); this._isCallActive = false; // Stop audio this.stopWebRingtone(); // Remove call modal this.removeCallModal(); this.notifyListeners('callEnded', {}); } async isCallActive() { console.log('Checking call status on web'); return { isActive: this._isCallActive }; } createCallModal(username, callId, roomName) { // Remove existing modal if any this.removeCallModal(); // Create modal container this.callModal = document.createElement('div'); this.callModal.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 9999; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; `; // Create call content const callContent = document.createElement('div'); callContent.style.cssText = ` background: #1a1a1a; border-radius: 20px; padding: 40px; text-align: center; max-width: 400px; width: 90%; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); `; // Username const usernameEl = document.createElement('h2'); usernameEl.textContent = username; usernameEl.style.cssText = ` color: white; font-size: 24px; margin: 0 0 30px 0; font-weight: 500; `; // Call ID (if provided) if (callId) { const callIdEl = document.createElement('p'); callIdEl.textContent = `Call ID: ${callId}`; callIdEl.style.cssText = ` color: #888; font-size: 12px; margin: 0 0 20px 0; `; callContent.appendChild(callIdEl); } // Call status const statusEl = document.createElement('p'); if (roomName && roomName.trim()) { statusEl.textContent = `Incoming call - ${roomName}`; } else { statusEl.textContent = 'Incoming call...'; } statusEl.style.cssText = ` color: #888; font-size: 16px; margin: 0 0 40px 0; `; // Buttons container const buttonsContainer = document.createElement('div'); buttonsContainer.style.cssText = ` display: flex; gap: 20px; justify-content: center; `; // Accept button const acceptBtn = document.createElement('button'); acceptBtn.textContent = 'Accept'; acceptBtn.style.cssText = ` background: #4CAF50; color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 16px; cursor: pointer; min-width: 120px; transition: background 0.3s; `; acceptBtn.onmouseover = () => acceptBtn.style.background = '#45a049'; acceptBtn.onmouseout = () => acceptBtn.style.background = '#4CAF50'; acceptBtn.onclick = () => this.handleCallAction('accept'); // Reject button const rejectBtn = document.createElement('button'); rejectBtn.textContent = 'Reject'; rejectBtn.style.cssText = ` background: #f44336; color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 16px; cursor: pointer; min-width: 120px; transition: background 0.3s; `; rejectBtn.onmouseover = () => rejectBtn.style.background = '#da190b'; rejectBtn.onmouseout = () => rejectBtn.style.background = '#f44336'; rejectBtn.onclick = () => this.handleCallAction('reject'); // Assemble modal buttonsContainer.appendChild(acceptBtn); buttonsContainer.appendChild(rejectBtn); callContent.appendChild(usernameEl); callContent.appendChild(statusEl); callContent.appendChild(buttonsContainer); this.callModal.appendChild(callContent); // Add to document document.body.appendChild(this.callModal); // Prevent body scroll document.body.style.overflow = 'hidden'; } removeCallModal() { if (this.callModal) { document.body.removeChild(this.callModal); this.callModal = null; document.body.style.overflow = ''; } } handleCallAction(action) { var _a, _b, _c, _d, _e, _f, _g, _h; console.log(`Call ${action}ed on web`); // Get call details from the modal const username = ((_b = (_a = this.callModal) === null || _a === void 0 ? void 0 : _a.querySelector('h2')) === null || _b === void 0 ? void 0 : _b.textContent) || 'Unknown'; const callId = ((_e = (_d = (_c = this.callModal) === null || _c === void 0 ? void 0 : _c.querySelector('p')) === null || _d === void 0 ? void 0 : _d.textContent) === null || _e === void 0 ? void 0 : _e.replace('Call ID: ', '')) || ''; const roomName = ((_h = (_g = (_f = this.callModal) === null || _f === void 0 ? void 0 : _f.querySelector('p:nth-child(3)')) === null || _g === void 0 ? void 0 : _g.textContent) === null || _h === void 0 ? void 0 : _h.replace('Incoming call - ', '')) || ''; // Stop the call this.stopCall(); // Notify listeners with call action event this.notifyListeners('callAction', { action: action === 'accept' ? 'accepted' : 'rejected', username, callId, roomName: roomName !== 'Incoming call...' ? roomName : undefined }); } playWebRingtone() { try { // Create audio context for web ringtone this.audioContext = new (window.AudioContext || window.webkitAudioContext)(); // Create oscillator for ringtone sound this.oscillator = this.audioContext.createOscillator(); const gainNode = this.audioContext.createGain(); // Configure oscillator this.oscillator.type = 'sine'; this.oscillator.frequency.setValueAtTime(800, this.audioContext.currentTime); this.oscillator.frequency.setValueAtTime(600, this.audioContext.currentTime + 0.5); // Configure gain for volume control gainNode.gain.setValueAtTime(0.3, this.audioContext.currentTime); // Connect nodes this.oscillator.connect(gainNode); gainNode.connect(this.audioContext.destination); // Start playing this.oscillator.start(); // Create a simple ringtone pattern let time = this.audioContext.currentTime; const ringPattern = () => { var _a, _b; if (!this._isCallActive) return; (_a = this.oscillator) === null || _a === void 0 ? void 0 : _a.frequency.setValueAtTime(800, time); (_b = this.oscillator) === null || _b === void 0 ? void 0 : _b.frequency.setValueAtTime(600, time + 0.5); time += 2; // 2 second cycle setTimeout(ringPattern, 2000); }; ringPattern(); } catch (error) { console.warn('Could not play web ringtone:', error); } } stopWebRingtone() { if (this.oscillator) { this.oscillator.stop(); this.oscillator = null; } if (this.audioContext) { this.audioContext.close(); this.audioContext = null; } } } var web = /*#__PURE__*/Object.freeze({ __proto__: null, CallScreenWeb: CallScreenWeb }); exports.CallScreen = CallScreen; //# sourceMappingURL=plugin.cjs.js.map