Отчёт весит сотни килобайт вместе со встроенным шрифтом, поэтому между
приходом данных и первой отрисовкой есть заметная пауза. Всё это время на
экране была пустая тёмная коробка, зато с готовыми кнопками зума, которым
нечего масштабировать. Теперь до отрисовки показывается скелетон, повторяющий
ритм отчёта, а панель зума появляется вместе с картинкой.
Перезапуск проверки наследовал зум и сдвиг от предыдущего отчёта. Новый отчёт
должен открываться в исходном масштабе, поэтому его подпись входит в ключ
просмотрщика.
Подпись — хеш всей строки, посчитанный один раз на отчёт. Первая попытка
брала длину и хвост base64, и этого оказалось мало: отчёты одного узла
кончаются одинаково, подписи совпадали, зум не сбрасывался. Поймано
проверкой, а не рассуждением.
Готовность хранится как «какая картинка отрисована», а не булевым флагом:
тогда новый отчёт автоматически считается незагруженным и сбрасывающий
эффект не нужен.
Проверено в браузере: при задержке картинки — скелетон есть, панели зума нет;
после загрузки наоборот. Зум со сдвигом после перезапуска возвращается к
исходному преобразованию, дважды подряд.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Кнопка в карточке ноды открывает модалку: выбор маршрута (по умолчанию /
IP-адрес / интерфейс) с подсказками из данных ноды, ожидание, затем отчёт
картинкой либо тем же отчётом в JSON. Есть копирование JSON, скачивание
SVG, повтор проверки и полноэкранный режим.
Кнопка показывается только для узлов 3.3.0+ (versions.node) и только для
подключённых — иначе админ упирался бы в ошибку панели.
Отчёт вставляется как <img src="data:...">, а не сырым SVG в разметку: он
несёт встроенный моноширинный шрифт и <style>, на которых держится
выравнивание колонок, и санитайзер их выбрасывает. В <img> SVG рисуется в
изолированном контексте без скриптов и внешних запросов — и безопаснее, и
вернее по виду.
Зум и панорамирование — react-zoom-pan-pinch с той же конфигурацией, что в
самой панели Remnawave. Своя реализация обязательна: index.html задаёт
user-scalable=no, поэтому браузерного пинча нет ни в мобильном вебе, ни в
Mini App. Колесо намеренно не масштабирует, иначе прокрутка над отчётом
превращается в зум.
В отличие от панели стартовый масштаб считается от читаемой ширины: на
телефоне «вписано по ширине» превращает отчёт в серую рябь. На 390px это
2.42x с панорамированием, на десктопе — 1x. При смене ширины (полный
экран, поворот) масштаб пересчитывается.
Опрос задачи с потолком в три минуты — иначе забытая открытой модалка
опрашивала бы панель бесконечно. Пока проверка идёт, модалка не
закрывается: задача уже поставлена, терять её результат молча хуже.
Заодно в AdminRemnawave.tsx осели автоправки biome (import type,
Math.pow -> **) — файл всё равно правился, они механические.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>