Убрать QR-заглушку и очищать код после reject

This commit is contained in:
AidarKC 2026-06-15 02:37:26 +04:00
parent af1304022e
commit 9fcdcd087b
5 changed files with 20 additions and 38 deletions

View File

@ -16,6 +16,8 @@
- с передачей выбранных ключей; - с передачей выбранных ключей;
- убедиться, что новое устройство реально входит в аккаунт и сохраняет нужные ключи; - убедиться, что новое устройство реально входит в аккаунт и сохраняет нужные ключи;
- отдельно проверить отклонение заявки и истечение TTL. - отдельно проверить отклонение заявки и истечение TTL.
- при отклонении заявки убедиться, что на новом устройстве сразу исчезает карточка со старым 7-значным кодом и остаётся только сообщение об отклонении;
- убедиться, что экран `Войти` больше не показывает неработающую QR-заглушку сверху.
- ожидаемый результат: - ожидаемый результат:
- новое устройство получает код, доверённое устройство видит ту же заявку и может её подтвердить или отклонить; - новое устройство получает код, доверённое устройство видит ту же заявку и может её подтвердить или отклонить;

View File

@ -1,2 +1,2 @@
client.version=1.2.198 client.version=1.2.199
server.version=1.2.187 server.version=1.2.188

View File

@ -40,9 +40,9 @@ import * as registrationKeysView from './pages/registration-keys-view.js';
import * as registrationDraftKeysView from './pages/registration-draft-keys-view.js'; import * as registrationDraftKeysView from './pages/registration-draft-keys-view.js';
import * as topupView from './pages/topup-view.js'; import * as topupView from './pages/topup-view.js';
import * as devnetTopupView from './pages/devnet-topup-view.js'; import * as devnetTopupView from './pages/devnet-topup-view.js';
import * as loginView from './pages/login-view.js?v=202606142055'; import * as loginView from './pages/login-view.js?v=202606150110';
import * as loginCameraView from './pages/login-camera-view.js'; import * as loginCameraView from './pages/login-camera-view.js';
import * as loginOtherDeviceView from './pages/login-other-device-view.js?v=202606150010'; import * as loginOtherDeviceView from './pages/login-other-device-view.js?v=202606150110';
import * as loginPasswordView from './pages/login-password-view.js'; import * as loginPasswordView from './pages/login-password-view.js';
import * as keyStorageView from './pages/key-storage-view.js'; import * as keyStorageView from './pages/key-storage-view.js';

View File

@ -44,6 +44,14 @@ function formatExpiresAt(ms) {
return new Date(ts).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); return new Date(ts).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
} }
function resetCodeCard(resultWrap, shortCodeEl, statusHintEl, onlineHintEl, expireHintEl) {
resultWrap.style.display = 'none';
shortCodeEl.textContent = '0000000';
statusHintEl.textContent = 'Покажите этот код на уже подключённом устройстве в разделе «Подключить по коду».';
onlineHintEl.textContent = '';
expireHintEl.textContent = '';
}
export function render({ navigate }) { export function render({ navigate }) {
const screen = document.createElement('section'); const screen = document.createElement('section');
screen.className = 'stack'; screen.className = 'stack';
@ -161,16 +169,18 @@ export function render({ navigate }) {
} }
if (stateValue === 'rejected') { if (stateValue === 'rejected') {
stopPolling(); stopPolling();
activePairingId = '';
startBtn.disabled = false; startBtn.disabled = false;
resetCodeCard(resultWrap, shortCodeEl, statusHintEl, onlineHintEl, expireHintEl);
setStatus(status, 'Подключение отклонено на доверенном устройстве.', 'error'); setStatus(status, 'Подключение отклонено на доверенном устройстве.', 'error');
statusHintEl.textContent = 'Заявка отклонена. Можно попробовать снова.';
return; return;
} }
if (stateValue === 'expired') { if (stateValue === 'expired') {
stopPolling(); stopPolling();
activePairingId = '';
startBtn.disabled = false; startBtn.disabled = false;
resetCodeCard(resultWrap, shortCodeEl, statusHintEl, onlineHintEl, expireHintEl);
setStatus(status, 'Время ожидания истекло. Получите новый код.', 'error'); setStatus(status, 'Время ожидания истекло. Получите новый код.', 'error');
statusHintEl.textContent = 'Заявка истекла. Создайте новую заявку.';
return; return;
} }
schedulePoll(); schedulePoll();
@ -205,8 +215,9 @@ export function render({ navigate }) {
setAuthError(''); setAuthError('');
setAuthInfo(''); setAuthInfo('');
setStatus(status, 'Проверяем пользователя и создаём pairing-заявку...', 'info'); setStatus(status, 'Проверяем пользователя и создаём pairing-заявку...', 'info');
resultWrap.style.display = 'none';
stopPolling(); stopPolling();
activePairingId = '';
resetCodeCard(resultWrap, shortCodeEl, statusHintEl, onlineHintEl, expireHintEl);
try { try {
await authService.reconnect(state.entrySettings.shineServer); await authService.reconnect(state.entrySettings.shineServer);

View File

@ -2,40 +2,10 @@ import { renderHeader } from '../components/header.js';
export const pageMeta = { id: 'login-view', title: 'Войти', showAppChrome: false }; export const pageMeta = { id: 'login-view', title: 'Войти', showAppChrome: false };
function createQrCode() {
const svgNS = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(svgNS, 'svg');
svg.setAttribute('viewBox', '0 0 100 100');
svg.classList.add('qr-code');
const cells = [
[6, 6, 22, 22], [72, 6, 22, 22], [6, 72, 22, 22], [14, 14, 6, 6], [80, 14, 6, 6], [14, 80, 6, 6],
[38, 12, 8, 8], [52, 12, 8, 8], [38, 26, 8, 8], [52, 26, 8, 8], [32, 40, 10, 10], [48, 40, 10, 10],
[64, 40, 10, 10], [40, 56, 8, 8], [56, 56, 8, 8], [72, 56, 8, 8], [32, 72, 8, 8], [48, 72, 8, 8],
[64, 72, 8, 8], [48, 86, 8, 8],
];
cells.forEach(([x, y, width, height]) => {
const rect = document.createElementNS(svgNS, 'rect');
rect.setAttribute('x', x);
rect.setAttribute('y', y);
rect.setAttribute('width', width);
rect.setAttribute('height', height);
rect.setAttribute('rx', '2');
svg.append(rect);
});
return svg;
}
export function render({ navigate }) { export function render({ navigate }) {
const screen = document.createElement('section'); const screen = document.createElement('section');
screen.className = 'stack'; screen.className = 'stack';
const qrCard = document.createElement('div');
qrCard.className = 'card stack qr-card';
qrCard.append(createQrCode());
const cameraButton = document.createElement('button'); const cameraButton = document.createElement('button');
cameraButton.className = 'primary-btn'; cameraButton.className = 'primary-btn';
cameraButton.type = 'button'; cameraButton.type = 'button';
@ -69,7 +39,6 @@ export function render({ navigate }) {
title: 'Войти', title: 'Войти',
leftAction: { label: '←', onClick: () => navigate('start-view') }, leftAction: { label: '←', onClick: () => navigate('start-view') },
}), }),
qrCard,
actions, actions,
backButton, backButton,
); );