Обновить pairing устройств и доработать ESP32 UI

This commit is contained in:
AidarKC
2026-06-19 20:47:56 +04:00
parent cc074a941f
commit a788d8bcf5
18 changed files with 1020 additions and 126 deletions
+48 -11
View File
@@ -362,6 +362,7 @@ function startTone(nextToneName) {
function getCallStateSnapshot() {
const call = getActiveCall();
if (!call) return null;
if (call.localUiDismissed) return null;
const callPhase = String(call.phase || '').trim();
return {
callId: call.callId,
@@ -386,6 +387,12 @@ function notifyCallState() {
});
}
function dismissCallUiLocally(call) {
if (!call) return;
call.localUiDismissed = true;
notifyCallState();
}
function setStatus(call, statusText, phase = '') {
if (!call) return;
call.statusText = String(statusText || '').trim();
@@ -1453,10 +1460,18 @@ export async function acceptIncomingCall() {
export async function declineIncomingCall() {
const call = getActiveCall();
if (!call || call.direction !== 'in' || call.phase !== 'incoming') return;
try {
await sendSignal(call, TYPES.DECLINE_BUSY, 'decline');
} catch {}
await finalizeCall(call, { localReasonCode: 'declined', debugReason: 'declined_by_user' });
dismissCallUiLocally(call);
const declinePromise = (async () => {
try {
await sendSignal(call, TYPES.DECLINE_BUSY, 'decline');
} catch {}
})();
await finalizeCall(call, {
localReasonCode: 'declined',
debugReason: 'declined_by_user',
suppressRemoteSignal: true,
});
await declinePromise;
}
export async function handleIncomingCallSignal(evt) {
@@ -1499,14 +1514,35 @@ export async function handleIncomingCallSignal(evt) {
}
}
} else {
const remoteSessionLocked = Boolean(
call.initialOfferSent
|| call.connectedAtMs
|| call.phase === 'connecting'
|| call.phase === 'active'
|| call.phase === 'reconnecting',
);
const terminalSignalFromAnotherSession =
Boolean(call.remoteSessionId)
&& Boolean(fromSessionId)
&& call.remoteSessionId !== fromSessionId
&& (type === TYPES.DECLINE_BUSY || type === TYPES.TIMEOUT || type === TYPES.HANGUP);
if (call.remoteSessionId && fromSessionId && call.remoteSessionId !== fromSessionId) {
await emitDebug(
call,
'info',
'signal_from_non_selected_session_ignored',
`type=${type}; selected=${call.remoteSessionId}; from=${fromSessionId}`,
);
return;
if (terminalSignalFromAnotherSession && !remoteSessionLocked) {
await emitDebug(
call,
'info',
'terminal_signal_from_non_selected_session_allowed_before_lock',
`type=${type}; selected=${call.remoteSessionId}; from=${fromSessionId}`,
);
} else {
await emitDebug(
call,
'info',
'signal_from_non_selected_session_ignored',
`type=${type}; selected=${call.remoteSessionId}; from=${fromSessionId}`,
);
return;
}
}
if (!call.remoteSessionId && fromSessionId) {
call.remoteSessionId = fromSessionId;
@@ -1632,6 +1668,7 @@ export async function handleIncomingCallSignal(evt) {
export async function hangupActiveCall() {
if (!activeCallId) return;
const call = getCall(activeCallId);
dismissCallUiLocally(call);
await finalizeCall(call, {
localReasonCode: call?.connectedAtMs ? 'completed' : 'no_answer',
debugReason: 'hangup_by_user',
@@ -101,6 +101,15 @@ export async function createRequesterPairingMaterial() {
};
}
export function normalizePairingShortCode(value, digits = 10) {
return String(value || '').replace(/\D+/g, '').slice(0, digits).padStart(digits, '0');
}
export function formatPairingShortCode(value) {
const normalized = normalizePairingShortCode(value, 10);
return normalized.match(/.{1,2}/g)?.join(' ') || normalized;
}
export async function encryptPairingPayloadForRequester(requesterSessionKey, payload) {
const requesterPublicB64 = extractSessionPublicKeyB64(requesterSessionKey);
const requesterMontPub = edwardsToMontgomeryPub(base64ToBytes(requesterPublicB64));