Показывать ошибки pairing-пароля в отдельном окне

This commit is contained in:
AidarKC 2026-06-15 15:31:19 +04:00
parent e1f2b54de3
commit 41d199e24a
3 changed files with 97 additions and 23 deletions

View File

@ -1,2 +1,2 @@
client.version=1.2.202
server.version=1.2.191
client.version=1.2.203
server.version=1.2.192

View File

@ -55,7 +55,7 @@ import * as serverSettingsView from './pages/server-settings-view.js';
import * as toolsSettingsView from './pages/tools-settings-view.js';
import * as deviceView from './pages/device-view.js?v=202606131435';
import * as connectDeviceView from './pages/connect-device-view.js?v=202606142055';
import * as devicePairingView from './pages/device-pairing-view.js?v=202606151030';
import * as devicePairingView from './pages/device-pairing-view.js?v=202606151050';
import * as deviceQrView from './pages/device-qr-view.js';
import * as deviceCameraView from './pages/device-camera-view.js';
import * as showKeysView from './pages/show-keys-view.js';

View File

@ -208,6 +208,58 @@ export function render({ navigate }) {
const dialogPasswordToggleBtn = passwordDialog.querySelector('#pairing-dialog-password-toggle');
const dialogPasswordConfirmToggleBtn = passwordDialog.querySelector('#pairing-dialog-password-confirm-toggle');
const dialogOverlay = document.createElement('div');
dialogOverlay.hidden = true;
dialogOverlay.style.position = 'absolute';
dialogOverlay.style.inset = '0';
dialogOverlay.style.zIndex = '2';
dialogOverlay.innerHTML = `
<div style="position:absolute; inset:0; background:rgba(5,9,16,0.78);"></div>
<div class="card stack" style="position:absolute; left:50%; top:50%; width:min(calc(100% - 32px), 320px); transform:translate(-50%, -50%); gap:12px; box-shadow:var(--shadow);">
<p class="field-label" id="pairing-dialog-overlay-title">Ошибка</p>
<p class="meta-muted" id="pairing-dialog-overlay-text"></p>
<div class="row" style="justify-content:flex-end; flex-wrap:wrap;">
<button class="ghost-btn" type="button" id="pairing-dialog-overlay-cancel" hidden>Нет</button>
<button class="primary-btn" type="button" id="pairing-dialog-overlay-confirm">Ок</button>
</div>
</div>
`;
passwordDialog.append(dialogOverlay);
const dialogOverlayTitleEl = dialogOverlay.querySelector('#pairing-dialog-overlay-title');
const dialogOverlayTextEl = dialogOverlay.querySelector('#pairing-dialog-overlay-text');
const dialogOverlayCancelBtn = dialogOverlay.querySelector('#pairing-dialog-overlay-cancel');
const dialogOverlayConfirmBtn = dialogOverlay.querySelector('#pairing-dialog-overlay-confirm');
let dialogOverlayOnConfirm = null;
let dialogOverlayOnCancel = null;
const closeDialogOverlay = () => {
dialogOverlay.hidden = true;
dialogOverlayOnConfirm = null;
dialogOverlayOnCancel = null;
};
const showDialogAlert = (message) => {
dialogOverlayTitleEl.textContent = 'Ошибка';
dialogOverlayTextEl.textContent = message;
dialogOverlayCancelBtn.hidden = true;
dialogOverlayConfirmBtn.textContent = 'Ок';
dialogOverlay.hidden = false;
dialogOverlayOnConfirm = () => closeDialogOverlay();
dialogOverlayOnCancel = null;
};
const showDialogConfirm = (message, { title = 'Подтверждение', confirmLabel = 'Да', cancelLabel = 'Нет', onConfirm, onCancel } = {}) => {
dialogOverlayTitleEl.textContent = title;
dialogOverlayTextEl.textContent = message;
dialogOverlayCancelBtn.hidden = false;
dialogOverlayCancelBtn.textContent = cancelLabel;
dialogOverlayConfirmBtn.textContent = confirmLabel;
dialogOverlay.hidden = false;
dialogOverlayOnConfirm = onConfirm || (() => closeDialogOverlay());
dialogOverlayOnCancel = onCancel || (() => closeDialogOverlay());
};
const bindPasswordToggle = (input, button) => {
button.addEventListener('click', () => {
if (input.type === 'password') {
@ -244,6 +296,7 @@ export function render({ navigate }) {
const closePasswordDialog = () => {
dialogMode = '';
closeDialogOverlay();
passwordDialog.hidden = true;
};
@ -404,36 +457,57 @@ export function render({ navigate }) {
}
});
dialogOverlayConfirmBtn.addEventListener('click', async () => {
const handler = dialogOverlayOnConfirm;
if (!handler) return;
await handler();
});
dialogOverlayCancelBtn.addEventListener('click', async () => {
const handler = dialogOverlayOnCancel;
if (!handler) {
closeDialogOverlay();
return;
}
await handler();
});
dialogSaveBtn.addEventListener('click', async () => {
const password = String(dialogPasswordInput.value || '');
const confirm = String(dialogPasswordConfirmInput.value || '');
const currentMode = dialogMode;
if (!password && !confirm) {
const shouldRemove = window.confirm('Пароль не задан. Хотите убрать дополнительный пароль?');
if (!shouldRemove) {
setStatus(status, 'Введите пароль или отмените изменение.', 'error');
return;
}
dialogSaveBtn.disabled = true;
try {
await removeAdditionalPassword();
closePasswordDialog();
renderSettingsCard();
} catch (error) {
const message = toUserMessage(error, 'Не удалось убрать дополнительный пароль.');
setAuthError(message);
setStatus(status, message, 'error');
} finally {
dialogSaveBtn.disabled = false;
}
showDialogConfirm('Пароль не задан. Хотите убрать дополнительный пароль?', {
title: 'Пароль не задан',
confirmLabel: 'Да',
cancelLabel: 'Нет',
onConfirm: async () => {
closeDialogOverlay();
dialogSaveBtn.disabled = true;
try {
await removeAdditionalPassword();
closePasswordDialog();
renderSettingsCard();
} catch (error) {
const message = toUserMessage(error, 'Не удалось убрать дополнительный пароль.');
setAuthError(message);
showDialogAlert(message);
} finally {
dialogSaveBtn.disabled = false;
}
},
onCancel: () => {
closeDialogOverlay();
},
});
return;
}
if (!password || !confirm) {
setStatus(status, 'Заполните пароль и подтверждение пароля.', 'error');
showDialogAlert('Заполните пароль и подтверждение пароля.');
return;
}
if (password !== confirm) {
setStatus(status, 'Пароли не совпадают.', 'error');
showDialogAlert('Пароли не совпадают.');
return;
}
dialogSaveBtn.disabled = true;
@ -455,7 +529,7 @@ export function render({ navigate }) {
} catch (error) {
const message = toUserMessage(error, 'Не удалось сохранить дополнительный пароль.');
setAuthError(message);
setStatus(status, message, 'error');
showDialogAlert(message);
} finally {
dialogSaveBtn.disabled = false;
}