135 lines
5.0 KiB
JavaScript
135 lines
5.0 KiB
JavaScript
import { renderHeader } from '../components/header.js';
|
|
import { addAppLogEntry, authService, closeCurrentSessionAndSignOut } from '../state.js';
|
|
|
|
export const pageMeta = { id: 'settings-view', title: 'Настройки' };
|
|
|
|
function formatBuildStamp(rawValue) {
|
|
const value = String(rawValue || '').trim();
|
|
if (!/^\d{14}$/.test(value)) return value;
|
|
const yyyy = value.slice(0, 4);
|
|
const mm = value.slice(4, 6);
|
|
const dd = value.slice(6, 8);
|
|
const hh = value.slice(8, 10);
|
|
const min = value.slice(10, 12);
|
|
const ss = value.slice(12, 14);
|
|
return `${yyyy}-${mm}-${dd}/${hh}:${min}__${ss}`;
|
|
}
|
|
|
|
function formatVersionForUi(rawValue) {
|
|
const value = String(rawValue || '').trim();
|
|
if (!value) return 'n/a';
|
|
const formatted = formatBuildStamp(value);
|
|
if (formatted && formatted !== value) {
|
|
return `${formatted} (${value})`;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
export function render({ navigate }) {
|
|
const screen = document.createElement('section');
|
|
screen.className = 'stack';
|
|
let isDisposed = false;
|
|
|
|
screen.append(
|
|
renderHeader({
|
|
title: 'Настройки',
|
|
leftAction: { label: '←', onClick: () => navigate('profile-view') },
|
|
}),
|
|
);
|
|
|
|
const card = document.createElement('div');
|
|
card.className = 'card stack';
|
|
card.innerHTML = `
|
|
<button class="text-btn" type="button" id="settings-device">Устройства</button>
|
|
<button class="text-btn" type="button" id="settings-servers">Настройки серверов</button>
|
|
<button class="text-btn" type="button" id="settings-tools">Настройки инструментов ввода</button>
|
|
<button class="text-btn" type="button" id="settings-language">Язык / Language</button>
|
|
<button class="text-btn" type="button" id="settings-signout">Завершить текущий сеанс</button>
|
|
`;
|
|
|
|
card.querySelector('#settings-device').addEventListener('click', () => navigate('device-view'));
|
|
card.querySelector('#settings-servers').addEventListener('click', () => navigate('server-settings-view'));
|
|
card.querySelector('#settings-tools').addEventListener('click', () => navigate('tools-settings-view'));
|
|
card.querySelector('#settings-language').addEventListener('click', () => navigate('language-view'));
|
|
|
|
const signOutBtn = card.querySelector('#settings-signout');
|
|
signOutBtn.addEventListener('click', async () => {
|
|
const confirmed = window.confirm(
|
|
'Завершить текущую сессию на сервере, отключиться, очистить локальные данные и перейти на стартовый экран?'
|
|
);
|
|
if (!confirmed) return;
|
|
|
|
signOutBtn.disabled = true;
|
|
try {
|
|
addAppLogEntry({
|
|
level: 'info',
|
|
source: 'session',
|
|
message: 'Запрошено завершение текущей сессии',
|
|
});
|
|
await closeCurrentSessionAndSignOut({
|
|
infoMessage: 'Сеанс завершён. Выполните вход заново.',
|
|
});
|
|
} finally {
|
|
signOutBtn.disabled = false;
|
|
}
|
|
});
|
|
|
|
const versionCard = document.createElement('div');
|
|
versionCard.className = 'card stack';
|
|
|
|
const title = document.createElement('p');
|
|
title.className = 'field-label';
|
|
title.textContent = 'Версии';
|
|
|
|
const clientVersion = document.createElement('p');
|
|
clientVersion.className = 'meta-muted';
|
|
clientVersion.textContent = `Клиент: ${formatVersionForUi(window.__SHINE_CLIENT_VERSION__)}`;
|
|
|
|
const uiBuild = document.createElement('p');
|
|
uiBuild.className = 'meta-muted';
|
|
uiBuild.textContent = `Сборка UI: ${formatVersionForUi(window.__SHINE_BUILD_HASH__)}`;
|
|
|
|
const serverVersion = document.createElement('p');
|
|
serverVersion.className = 'meta-muted';
|
|
serverVersion.textContent = 'Сервер: загружается...';
|
|
|
|
versionCard.append(title, clientVersion, uiBuild, serverVersion);
|
|
|
|
const developerCard = document.createElement('div');
|
|
developerCard.className = 'card stack';
|
|
developerCard.innerHTML = `
|
|
<button class="text-btn" type="button" id="settings-developer">Настройки разработчика</button>
|
|
`;
|
|
developerCard.querySelector('#settings-developer').addEventListener('click', () => navigate('developer-settings-view'));
|
|
|
|
void (async () => {
|
|
try {
|
|
let value = '';
|
|
try {
|
|
const pingResp = await authService.ws.request('Ping', { ts: Date.now() }, 7000);
|
|
value = String(pingResp?.payload?.serverVersion || pingResp?.serverVersion || '').trim();
|
|
} catch {
|
|
// fallback below
|
|
}
|
|
|
|
if (!value) {
|
|
const infoResp = await authService.ws.request('GetServerInfo', {});
|
|
value = String(infoResp?.payload?.version || '').trim();
|
|
}
|
|
if (!isDisposed) serverVersion.textContent = `Сервер: ${formatVersionForUi(value)}`;
|
|
} catch {
|
|
if (!isDisposed) {
|
|
serverVersion.textContent = 'Сервер: недоступно';
|
|
}
|
|
}
|
|
})();
|
|
|
|
screen.cleanup = () => {
|
|
isDisposed = true;
|
|
};
|
|
screen.append(card);
|
|
screen.append(versionCard);
|
|
screen.append(developerCard);
|
|
return screen;
|
|
}
|