Добавить смену профилей, но она пока не работает

This commit is contained in:
AidarKC
2026-09-03 12:37:23 +04:00
parent e7c8fd748c
commit ebc9143593
15 changed files with 672 additions and 44 deletions
+99 -4
View File
@@ -33,6 +33,9 @@ import {
addAppLogEntry,
authorizeSession,
hydrateMessagesFromStore,
getSavedProfiles,
closeSavedProfile,
switchToSavedProfile,
isSessionInvalidError,
refreshSessions,
setSessionAuthorizedHandler,
@@ -67,6 +70,7 @@ import * as publicSupportQueueView from './pages/public-support-queue-view.js';
import * as profileView from './pages/profile-view.js?v=202607150910';
import * as profileEditView from './pages/profile-edit-view.js';
import * as profilesView from './pages/profiles-view.js';
import * as walletView from './pages/wallet-view.js?v=202606281930';
import * as settingsView from './pages/settings-view.js';
import * as accessServersView from './pages/access-servers-view.js';
@@ -132,6 +136,7 @@ const routes = {
queue: publicSupportQueueView,
'profile-view': profileView,
'profile-edit-view': profileEditView,
'profiles-view': profilesView,
'wallet-view': walletView,
'settings-view': settingsView,
'access-servers-view': accessServersView,
@@ -213,6 +218,7 @@ const SCROLL_TO_BOTTOM_PAGE_IDS = new Set([
const FILLED_ACTION_BUTTON_PAGE_IDS = new Set([
...PRE_AUTH_PAGES.filter((pageId) => pageId !== 'entry-settings-view'),
'settings-view',
'profiles-view',
]);
const SETTINGS_BORDERED_ACTION_PAGE_IDS = new Set([
@@ -745,6 +751,77 @@ function consumeCallPushActionFromUrlIfAny() {
}
}
function pushTargetLogin(payload = {}) {
return String(payload?.toLogin || '').trim();
}
function pushTargetPath(payload = {}) {
const kind = String(payload?.kind || '').trim();
const fromLogin = String(payload?.fromLogin || '').trim();
if (kind === 'new_message' && fromLogin) return `/chat/${encodeURIComponent(fromLogin)}`;
return '/profile';
}
function savedProfileExists(login) {
const normalized = String(login || '').trim().toLowerCase();
if (!normalized) return false;
return getSavedProfiles().some((item) => String(item.login || '').trim().toLowerCase() === normalized);
}
async function ensurePushTargetProfile(payload = {}, { action = '' } = {}) {
const targetLogin = pushTargetLogin(payload);
const currentLogin = String(state.session.login || '').trim();
if (!targetLogin || targetLogin.toLowerCase() === currentLogin.toLowerCase()) return true;
if (!savedProfileExists(targetLogin)) {
showToast(`Уведомление пришло профилю ${targetLogin}, который не сохранён на этом устройстве.`);
return false;
}
const kind = String(payload?.kind || '').trim();
const question = kind === 'incoming_call'
? `Входящий звонок для профиля «${targetLogin}». Переключиться на этот профиль?`
: `Это сообщение пришло профилю «${targetLogin}». Переключиться, чтобы открыть его?`;
if (!window.confirm(question)) return false;
try {
await switchToSavedProfile(targetLogin);
if (action === 'accept' || action === 'decline') {
savePendingCallPushAction(action, payload);
window.location.assign(pushTargetPath(payload));
} else {
window.location.assign(pushTargetPath(payload));
}
return false;
} catch (error) {
showToast(`Не удалось переключить профиль: ${error?.message || 'unknown'}`);
return false;
}
}
async function handleNotificationClick(payload = {}) {
const canOpen = await ensurePushTargetProfile(payload);
if (!canOpen) return;
const path = pushTargetPath(payload);
navigate(path.replace(/^\//, ''));
}
function consumeNotificationOpenFromUrlIfAny() {
try {
const params = new URLSearchParams(window.location.search || '');
const rawPayload = String(params.get('pushOpenPayload') || '');
if (!rawPayload) return null;
let payload = {};
try { payload = JSON.parse(decodeURIComponent(rawPayload)); } catch {}
params.delete('pushOpenPayload');
const nextQuery = params.toString();
window.history.replaceState({}, '', `${window.location.pathname}${nextQuery ? `?${nextQuery}` : ''}`);
return payload;
} catch {
return null;
}
}
async function processPendingCallPushActionIfPossible() {
if (!state.session.isAuthorized) return;
const pending = loadPendingCallPushAction();
@@ -1286,6 +1363,11 @@ async function tryAutoLogin() {
} catch {}
} catch (error) {
if (isSessionInvalidError(error)) {
const result = await closeSavedProfile(state.session.login);
if (result?.nextProfile) {
window.location.assign('/profile');
return;
}
await terminateCurrentSession({
infoMessage: 'Сессия на этом устройстве уже завершена. Выполните вход заново.',
});
@@ -1338,6 +1420,7 @@ async function ensureSessionRuntimeStarted() {
async function init() {
consumeCallPushActionFromUrlIfAny();
const initialNotificationOpenPayload = consumeNotificationOpenFromUrlIfAny();
void tryLockPortraitOrientation();
if (state.session.isLocalDemo) {
@@ -1373,12 +1456,20 @@ async function init() {
const action = String(data.action || '').trim().toLowerCase();
const payload = data.payload || {};
if (action === 'accept' || action === 'decline') {
if (!isCallPushTargetForCurrentSession(payload)) return;
savePendingCallPushAction(action, payload);
void processPendingCallPushActionIfPossible();
void (async () => {
const canHandle = await ensurePushTargetProfile(payload, { action });
if (!canHandle) return;
if (!isCallPushTargetForCurrentSession(payload)) return;
savePendingCallPushAction(action, payload);
await processPendingCallPushActionIfPossible();
})();
}
return;
}
if (data.type === 'SHINE_NOTIFICATION_CLICK') {
void handleNotificationClick(data.payload || {});
return;
}
if (data.type !== 'SHINE_WEB_PUSH_EVENT') return;
const payload = data.payload || {};
@@ -1411,7 +1502,8 @@ async function init() {
}
authService.onEvent('SessionRevoked', async () => {
await terminateCurrentSession({ infoMessage: 'Сессия закрыта с другого устройства.' });
const result = await closeSavedProfile(state.session.login);
window.location.assign(result?.nextProfile ? '/profile' : '/start');
});
authService.onEvent('ForceUiReload', async (evt) => {
@@ -1714,6 +1806,9 @@ async function init() {
void (async () => {
try {
await tryAutoLogin();
if (initialNotificationOpenPayload) {
await handleNotificationClick(initialNotificationOpenPayload);
}
await hydrateMessagesFromStore();
if (!state.session.isLocalDemo) {
startConnectionMonitor();