call-screen
Version:
Capacitor plugin for full-screen call UI with Accept/Reject buttons, OneSignal integration, and cross-platform support
258 lines (251 loc) • 10.6 kB
JavaScript
var capacitorCallScreen = (function (exports, core) {
'use strict';
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;
return exports;
})({}, capacitorExports);
//# sourceMappingURL=plugin.js.map