window.BackOneRingingPopup = {
_audio: null,
showIncomingCall({ callerName, callType, callId, onAccept, onReject }) {
const el = document.getElementById('ringing-popup');
if (!el) return;
el.classList.remove('ringing-hidden');
el.innerHTML = `
Incoming ${callType} call
${callerName || 'Unknown peer'}
`;
el.querySelector('.ringing-accept').onclick = () => { this.dismiss(); onAccept && onAccept(callId); };
el.querySelector('.ringing-reject').onclick = () => { this.dismiss(); onReject && onReject(callId); };
this.playRingtone();
if (Notification.permission === 'default') Notification.requestPermission();
if (Notification.permission === 'granted') {
new Notification(`Incoming ${callType} call`, { body: callerName || 'BackOne peer' });
}
},
dismiss() {
const el = document.getElementById('ringing-popup');
if (el) { el.classList.add('ringing-hidden'); el.innerHTML = ''; }
this.stopRingtone();
},
playRingtone() {
this.stopRingtone();
try {
this._audio = new Audio('data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1fdJivrJBhNjVgodDbq2EcBj+a2/LDciUFLIHO8tiJNwgZaLvt559NEAxQp+PwtmMcBjiR1/LMeSwFJHfH8N2QQAoUXrTp66hVFApGn+DyvmwhBSuBzvLZiTYIG2m98OScTgwOUarm7blmHgU7k9n1unEiBC13y+/ek0EKElyx5+ytWBUIQ5zd8sFuJAUwgM/z2Ik6CBxpvfDknE4MDlGq5u25Zh4FO5PZ9br');
this._audio.loop = true;
this._audio.play().catch(() => {});
} catch (_) {}
},
stopRingtone() {
if (this._audio) { this._audio.pause(); this._audio = null; }
}
};
async function loadAddonManifest() {
const res = await fetch('/app/addons/manifest.json', { cache: 'no-store' });
if (!res.ok) {
console.warn('manifest.json fetch failed:', res.status);
return [];
}
const data = await res.json();
return Array.isArray(data) ? data : [];
}
async function loadAddonModule(entry) {
const entryPath = entry.frontend && entry.frontend.entry ? entry.frontend.entry : `/app/addons/${entry.id}/index.js`;
await import(entryPath);
const factory = window.BackOneAddons && window.BackOneAddons[entry.id];
return factory ? factory() : null;
}
window.BackOneAddonLoader = { loadAddonManifest, loadAddonModule };