wa-dev-tools/docs/sessions/2026-09-22-2040.md

7.9 KiB
Raw Permalink Blame History

2026-09-22 20:40 — HEIC, конструктор «Картинки → PDF», белые фоны UI

Сделано:

  • HEIC в /compress. Раньше .HEIC проходил фильтр, но падал «Ошибка при сжатии»: prebuilt libvips в sharp декодирует только AV1-HEIF (AVIF), а не HEVC. Добавлен heic-decode (libheif на WASM, без нативных зависимостей), общий хелпер lib/image.js. В режиме «Оригинал» HEIC/BMP → JPEG с расширением .jpg; формат источника берётся из sharp.metadata(), а не из MIME браузера.
  • Конструктор «Картинки → PDF» в /pdf (старая вкладка была нерабочей: фронт слал поле files, бэкенд ждал images, и попасть туда можно было только после загрузки PDF): форматы JPG/PNG/WebP/HEIC/AVIF/TIFF/GIF/BMP; drag&drop-порядок, стрелки, сортировка (имя с natural-order/дата/размер), реверс, поворот по одной и всех, повтор страниц, удаление; размер листа (по картинке/A4/A3/A5/Letter), ориентация, поля, качество, имя файла; прогресс загрузки через XHR. Вход — кнопкой на шаге загрузки или броском одних картинок в основную зону. Превью HEIC/TIFF — серверные миниатюры (POST /pdf/thumb).
  • Попутные фиксы /pdf: потерянная обёртка <div id="panel-watermark"> — из-за лишнего </div> stepConfig закрывался рано, «Выполнить» и панели торчали на шаге загрузки; pdfIcon был недоступен из inline-onerror (вынесен в window); SVG больше не принимается.
  • Белый фон (--surface-800) у зон drag&drop, неактивных табов, кнопок-опций и карточек на страницах compress, pdf, video, converter, formatter, sanitizer, parser. Активные табы — светло-голубая заливка поверх белого (linear-gradient(...), var(--surface-800)).
  • Всё на проде (VPS 195.140.146.84, контейнер wadevelop), прод-файлы байт-в-байт = HEAD. heic-decode@2.1.0 установлен в контейнере (npm install в /app, node_modules на томе).
  • Git: два коммита запушены в Gitea (rpi4): dabc26d — незакоммиченная работа сессии 2026-09-05 (owner-реестр, лимиты, crash-guard ffmpeg/gs, водяной знак); c65b3f5 — эта сессия.

Изменённые / созданные файлы:

  • lib/image.js — новый: isHeic() (по ftyp-бренду + расширению), openImage() (HEIC через heic-decode → raw в sharp; непрозрачная альфа отбрасывается, иначе всё уходит в PNG)
  • routes/compress.js — openImage(), общий encodeImage() вместо двух копий if-цепочек, sourceFormatOf(metadata)
  • routes/pdf.js — новый /fromImages (опции в JSON-поле options, страницы [{f, r}], повторы встраиваются один раз, нетронутые JPEG/PNG — байт-в-байт), /thumb (свой лимитер 300/мин, стоит ДО общего router.use(limiter)), saveResult(..., displayName) + owner.displayName в скачивании, сообщение о лимите файлов, фильтр без SVG
  • public/pdf.html — блок #stepImages (CSS .ip-*, JS ip*), панель водяного знака, белые фоны
  • public/compress.html — accept с .heic, превью без битой картинки, белые summary/список
  • public/video.html, converter, formatter, sanitizer, parser — белые фоны
  • package.json — heic-decode

Решения:

  • HEIC декодируем через heic-decode (WASM), а не пересобираем sharp/libvips с libde265: не нужен свой libvips в образе, работает на node:20-slim.
  • Страницы PDF в режиме «По картинке»: 1 px = 1 pt (как было), длинная сторона ≤ 5080 pt.
  • Миниатюры HEIC/TIFF делает сервер: браузеры, кроме Safari, их не рисуют.
  • Табы httpclient (внутри белой панели), regex (уже белые), md (подчёркнутые) не трогали; редакторы (svgeditor, editor) — полноэкранные холсты, не трогали.

Открытые вопросы / следующие шаги:

  • Тёмная тема после смены фонов на --surface-800 визуально не проверена (эмуляция в headless не сработала) — глянуть руками.
  • В самом браузере под учёткой прод-страницы не открывались (они за авторизацией) — проверено сквозными запросами внутри контейнера и headless-тестом локальной копии.
  • Серверные бэкапы этой сессии можно удалить, когда всё устоится: find /opt/sites/www/wadevelop.ru -name '*.bak-20260922-*'.
  • Идея: смешанная сборка «PDF + картинки» в одном документе (сейчас конструктор — только картинки).

Как продолжить (для чистой сессии):

  • Контекст: CLAUDE.md, скилл /deploy-wadevelop. Перед правкой сверяй md5 файла с VPS: python3 C:/Users/tream/.claude/ssh_cmd.py root@195.140.146.84 "md5sum /opt/sites/www/wadevelop.ru/<file>".
  • ⚠️ Грабли Windows: Python в текстовом режиме пишет CRLF — править файлы через open(p,'rb'/'wb') или Edit-инструментом, иначе диф раздувается и хэши с продом расходятся (в репо — LF).
  • ⚠️ Заливка через ssh_cmd.run + base64 в аргументе упирается в «Argument list too long» на больших файлах (pdf.html ~100 КБ) — лить чанками по ~60 КБ; ssh_cmd.run вызывает sys.exit, поэтому на несколько файлов — отдельный вызов на каждый (или ловить SystemExit).
  • Локальный стенд без MySQL: мини-express с фейковой сессией (app.use((q,r,n)=>{q.session={user:{id:1}};n()}) + app.use('/pdf', require('./routes/pdf.js'))
    • express.static('public')), UI — headless Chrome через puppeteer-core (executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe').
  • Проверка на проде без логина: временный express-стенд внутри контейнера (docker exec -w /app wadevelop node -e "..." на порту 3998).

Ссылки: https://wadevelop.ru/compress · https://wadevelop.ru/pdf · Gitea http://192.168.31.200:3002/treamz/wa-dev-tools