SHA256
Звонки: WebPush incoming/stop, actions и TTL; обновлена логика
This commit is contained in:
@@ -5,8 +5,11 @@ import { initPwaInstallPromptHandling } from './services/pwa-install-service.js'
|
||||
import { initPwaPush } from './services/pwa-push-service.js';
|
||||
import { initCallUiOverlay } from './services/call-ui-service.js';
|
||||
import {
|
||||
handleCallPushAction,
|
||||
handleIncomingCallInvite,
|
||||
handleIncomingCallPush,
|
||||
handleIncomingCallSignal,
|
||||
handleStopCallPush,
|
||||
setCallDebugReporter,
|
||||
startDebugConnectionAsInitiator,
|
||||
startDebugConnectionAsResponder,
|
||||
@@ -127,6 +130,7 @@ let uiUpdateReloadScheduled = false;
|
||||
let pwaUpdateCheckAttempted = false;
|
||||
let uiVersionCheckInFlight = false;
|
||||
let uiVersionPeriodicIntervalId = null;
|
||||
const CALL_PUSH_PENDING_ACTION_KEY = 'shine-ui-call-push-pending-action-v1';
|
||||
|
||||
setClientErrorTransport((payload) => authService.reportClientError(payload));
|
||||
initPwaInstallPromptHandling();
|
||||
@@ -220,6 +224,85 @@ function startConnectionCountdown() {
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function savePendingCallPushAction(action, payload = {}) {
|
||||
try {
|
||||
const item = {
|
||||
action: String(action || '').trim().toLowerCase(),
|
||||
payload: payload || {},
|
||||
savedAtMs: Date.now(),
|
||||
};
|
||||
localStorage.setItem(CALL_PUSH_PENDING_ACTION_KEY, JSON.stringify(item));
|
||||
} catch {
|
||||
// ignore localStorage errors
|
||||
}
|
||||
}
|
||||
|
||||
function loadPendingCallPushAction() {
|
||||
try {
|
||||
const raw = localStorage.getItem(CALL_PUSH_PENDING_ACTION_KEY);
|
||||
if (!raw) return null;
|
||||
const parsed = JSON.parse(raw);
|
||||
const action = String(parsed?.action || '').trim().toLowerCase();
|
||||
if (action !== 'accept' && action !== 'decline') return null;
|
||||
return {
|
||||
action,
|
||||
payload: parsed?.payload || {},
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearPendingCallPushAction() {
|
||||
try {
|
||||
localStorage.removeItem(CALL_PUSH_PENDING_ACTION_KEY);
|
||||
} catch {
|
||||
// ignore localStorage errors
|
||||
}
|
||||
}
|
||||
|
||||
function consumeCallPushActionFromUrlIfAny() {
|
||||
try {
|
||||
const params = new URLSearchParams(window.location.search || '');
|
||||
const action = String(params.get('callPushAction') || '').trim().toLowerCase();
|
||||
const rawPayload = String(params.get('callPushPayload') || '');
|
||||
if (action !== 'accept' && action !== 'decline') return;
|
||||
let payload = {};
|
||||
if (rawPayload) {
|
||||
try {
|
||||
payload = JSON.parse(decodeURIComponent(rawPayload));
|
||||
} catch {
|
||||
payload = {};
|
||||
}
|
||||
}
|
||||
savePendingCallPushAction(action, payload);
|
||||
params.delete('callPushAction');
|
||||
params.delete('callPushPayload');
|
||||
const nextQuery = params.toString();
|
||||
const nextUrl = `${window.location.pathname}${nextQuery ? `?${nextQuery}` : ''}${window.location.hash || ''}`;
|
||||
window.history.replaceState({}, '', nextUrl);
|
||||
} catch {
|
||||
// ignore URL parsing errors
|
||||
}
|
||||
}
|
||||
|
||||
async function processPendingCallPushActionIfPossible() {
|
||||
if (!state.session.isAuthorized) return;
|
||||
const pending = loadPendingCallPushAction();
|
||||
if (!pending) return;
|
||||
clearPendingCallPushAction();
|
||||
try {
|
||||
await handleCallPushAction(pending.action, pending.payload || {});
|
||||
} catch (error) {
|
||||
addAppLogEntry({
|
||||
level: 'warn',
|
||||
source: 'web-push',
|
||||
message: 'Не удалось выполнить действие звонка из push',
|
||||
details: { action: pending.action, error: error?.message || 'unknown' },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setConnectionStatus(nextState, text = '') {
|
||||
const state = String(nextState || '').trim();
|
||||
if (!state) return;
|
||||
@@ -677,9 +760,13 @@ async function ensureSessionRuntimeStarted() {
|
||||
});
|
||||
}
|
||||
}, 15_000);
|
||||
|
||||
await processPendingCallPushActionIfPossible();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
consumeCallPushActionFromUrlIfAny();
|
||||
|
||||
addAppLogEntry({
|
||||
level: 'info',
|
||||
source: 'app',
|
||||
@@ -698,12 +785,23 @@ async function init() {
|
||||
|
||||
setSessionAuthorizedHandler(() => {
|
||||
void ensureSessionRuntimeStarted();
|
||||
void processPendingCallPushActionIfPossible();
|
||||
});
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.addEventListener('message', (event) => {
|
||||
const data = event?.data || {};
|
||||
if (data.type === 'SHINE_CALL_PUSH_ACTION') {
|
||||
const action = String(data.action || '').trim().toLowerCase();
|
||||
const payload = data.payload || {};
|
||||
if (action === 'accept' || action === 'decline') {
|
||||
savePendingCallPushAction(action, payload);
|
||||
void processPendingCallPushActionIfPossible();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (data.type !== 'SHINE_WEB_PUSH_EVENT') return;
|
||||
|
||||
const payload = data.payload || {};
|
||||
const kind = String(payload.kind || '').trim();
|
||||
const now = Date.now();
|
||||
@@ -723,6 +821,11 @@ async function init() {
|
||||
message: 'Получено push-событие в service worker',
|
||||
details: payload,
|
||||
});
|
||||
if (kind === 'incoming_call' && !payload.stale && state.session.isAuthorized) {
|
||||
void handleIncomingCallPush(payload);
|
||||
} else if (kind === 'stop_call' && state.session.isAuthorized) {
|
||||
void handleStopCallPush(payload);
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent('shine-push-diagnostics-update', { detail: payload }));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user