Показывать ошибки 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 client.version=1.2.203
server.version=1.2.191 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 toolsSettingsView from './pages/tools-settings-view.js';
import * as deviceView from './pages/device-view.js?v=202606131435'; import * as deviceView from './pages/device-view.js?v=202606131435';
import * as connectDeviceView from './pages/connect-device-view.js?v=202606142055'; 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 deviceQrView from './pages/device-qr-view.js';
import * as deviceCameraView from './pages/device-camera-view.js'; import * as deviceCameraView from './pages/device-camera-view.js';
import * as showKeysView from './pages/show-keys-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 dialogPasswordToggleBtn = passwordDialog.querySelector('#pairing-dialog-password-toggle');
const dialogPasswordConfirmToggleBtn = passwordDialog.querySelector('#pairing-dialog-password-confirm-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) => { const bindPasswordToggle = (input, button) => {
button.addEventListener('click', () => { button.addEventListener('click', () => {
if (input.type === 'password') { if (input.type === 'password') {
@ -244,6 +296,7 @@ export function render({ navigate }) {
const closePasswordDialog = () => { const closePasswordDialog = () => {
dialogMode = ''; dialogMode = '';
closeDialogOverlay();
passwordDialog.hidden = true; passwordDialog.hidden = true;
}; };
@ -404,16 +457,32 @@ 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 () => { dialogSaveBtn.addEventListener('click', async () => {
const password = String(dialogPasswordInput.value || ''); const password = String(dialogPasswordInput.value || '');
const confirm = String(dialogPasswordConfirmInput.value || ''); const confirm = String(dialogPasswordConfirmInput.value || '');
const currentMode = dialogMode; const currentMode = dialogMode;
if (!password && !confirm) { if (!password && !confirm) {
const shouldRemove = window.confirm('Пароль не задан. Хотите убрать дополнительный пароль?'); showDialogConfirm('Пароль не задан. Хотите убрать дополнительный пароль?', {
if (!shouldRemove) { title: 'Пароль не задан',
setStatus(status, 'Введите пароль или отмените изменение.', 'error'); confirmLabel: 'Да',
return; cancelLabel: 'Нет',
} onConfirm: async () => {
closeDialogOverlay();
dialogSaveBtn.disabled = true; dialogSaveBtn.disabled = true;
try { try {
await removeAdditionalPassword(); await removeAdditionalPassword();
@ -422,18 +491,23 @@ export function render({ navigate }) {
} catch (error) { } catch (error) {
const message = toUserMessage(error, 'Не удалось убрать дополнительный пароль.'); const message = toUserMessage(error, 'Не удалось убрать дополнительный пароль.');
setAuthError(message); setAuthError(message);
setStatus(status, message, 'error'); showDialogAlert(message);
} finally { } finally {
dialogSaveBtn.disabled = false; dialogSaveBtn.disabled = false;
} }
},
onCancel: () => {
closeDialogOverlay();
},
});
return; return;
} }
if (!password || !confirm) { if (!password || !confirm) {
setStatus(status, 'Заполните пароль и подтверждение пароля.', 'error'); showDialogAlert('Заполните пароль и подтверждение пароля.');
return; return;
} }
if (password !== confirm) { if (password !== confirm) {
setStatus(status, 'Пароли не совпадают.', 'error'); showDialogAlert('Пароли не совпадают.');
return; return;
} }
dialogSaveBtn.disabled = true; dialogSaveBtn.disabled = true;
@ -455,7 +529,7 @@ export function render({ navigate }) {
} catch (error) { } catch (error) {
const message = toUserMessage(error, 'Не удалось сохранить дополнительный пароль.'); const message = toUserMessage(error, 'Не удалось сохранить дополнительный пароль.');
setAuthError(message); setAuthError(message);
setStatus(status, message, 'error'); showDialogAlert(message);
} finally { } finally {
dialogSaveBtn.disabled = false; dialogSaveBtn.disabled = false;
} }