SHiNE-server/shine-UI/js/services/call-ui-service.js

110 lines
2.9 KiB
JavaScript

import {
acceptIncomingCall,
declineIncomingCall,
hangupActiveCall,
setMicMuted,
subscribeCallState,
} from './call-service.js';
let shellEl = null;
let panelEl = null;
let titleEl = null;
let statusEl = null;
let muteBtn = null;
let acceptBtn = null;
let declineBtn = null;
let hangupBtn = null;
let unbind = null;
function ensureUi() {
if (shellEl) return;
shellEl = document.createElement('section');
shellEl.className = 'call-overlay';
shellEl.hidden = true;
panelEl = document.createElement('div');
panelEl.className = 'call-overlay-panel';
titleEl = document.createElement('h2');
titleEl.className = 'call-overlay-title';
statusEl = document.createElement('div');
statusEl.className = 'call-overlay-status';
const controls = document.createElement('div');
controls.className = 'call-overlay-controls';
muteBtn = document.createElement('button');
muteBtn.type = 'button';
muteBtn.className = 'secondary-btn';
muteBtn.textContent = 'Микрофон';
muteBtn.addEventListener('click', async () => {
const nowMuted = muteBtn.dataset.muted === '1';
await setMicMuted(!nowMuted);
});
acceptBtn = document.createElement('button');
acceptBtn.type = 'button';
acceptBtn.className = 'primary-btn';
acceptBtn.textContent = 'Ответить';
acceptBtn.addEventListener('click', async () => {
await acceptIncomingCall();
});
declineBtn = document.createElement('button');
declineBtn.type = 'button';
declineBtn.className = 'destructive-btn';
declineBtn.textContent = 'Сбросить';
declineBtn.addEventListener('click', async () => {
await declineIncomingCall();
});
hangupBtn = document.createElement('button');
hangupBtn.type = 'button';
hangupBtn.className = 'destructive-btn';
hangupBtn.textContent = 'Положить трубку';
hangupBtn.addEventListener('click', async () => {
await hangupActiveCall();
});
controls.append(muteBtn, acceptBtn, declineBtn, hangupBtn);
panelEl.append(titleEl, statusEl, controls);
shellEl.append(panelEl);
document.body.append(shellEl);
}
function applyCallState(snapshot) {
ensureUi();
if (!snapshot) {
shellEl.hidden = true;
return;
}
shellEl.hidden = false;
titleEl.textContent = `Звонок: ${snapshot.peerLogin || 'пользователь'}`;
statusEl.textContent = snapshot.statusText || '';
const muted = Boolean(snapshot.muted);
muteBtn.dataset.muted = muted ? '1' : '0';
muteBtn.textContent = muted ? 'Включить микрофон' : 'Выключить микрофон';
muteBtn.hidden = !snapshot.canMute;
muteBtn.disabled = !snapshot.canMute;
acceptBtn.hidden = !snapshot.canAnswer;
declineBtn.hidden = !snapshot.canDecline;
hangupBtn.hidden = !snapshot.canHangup;
}
export function initCallUiOverlay() {
ensureUi();
if (unbind) {
unbind();
unbind = null;
}
unbind = subscribeCallState(applyCallState);
}