From 9ecdd88163110c66cb2364831e3a4a21e9258af0 Mon Sep 17 00:00:00 2001 From: treamz Date: Tue, 22 Sep 2026 20:41:29 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20session=20handoff=202026-09-22=2020:40?= =?UTF-8?q?=20(HEIC,=20images=E2=86=92PDF,=20white=20UI)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/SESSION_LOG.md | 1 + docs/sessions/2026-09-22-2040.md | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 docs/sessions/2026-09-22-2040.md diff --git a/docs/SESSION_LOG.md b/docs/SESSION_LOG.md index 95451a3..e7975c1 100644 --- a/docs/SESSION_LOG.md +++ b/docs/SESSION_LOG.md @@ -4,6 +4,7 @@ с итогами, решениями, открытыми вопросами и инструкцией «как продолжить». Ведётся скиллом `/session-handoff`. +- [2026-09-22 20:40 — HEIC, конструктор «Картинки → PDF», белые фоны UI](sessions/2026-09-22-2040.md) - [2026-09-05 02:31 — ffmpeg/ghostscript в образ, водяной знак PDF, снятие лимитов админа](sessions/2026-09-05-0231.md) - [2026-07-24 23:48 — Аудит безопасности (19 фиксов) + снятие лимитов /compress, деплой на VPS](sessions/2026-07-24-2348.md) - [2026-07-24 17:43 — Локальная копия, снятие лимитов /compress, скилл деплоя под VPS](sessions/2026-07-24-1743.md) diff --git a/docs/sessions/2026-09-22-2040.md b/docs/sessions/2026-09-22-2040.md new file mode 100644 index 0000000..fdf8c8d --- /dev/null +++ b/docs/sessions/2026-09-22-2040.md @@ -0,0 +1,78 @@ +# 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:** потерянная обёртка `
` — из-за лишнего `
` + `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](../../lib/image.js) — **новый**: `isHeic()` (по ftyp-бренду + расширению), `openImage()` + (HEIC через heic-decode → raw в sharp; непрозрачная альфа отбрасывается, иначе всё уходит в PNG) +- [routes/compress.js](../../routes/compress.js) — `openImage()`, общий `encodeImage()` вместо двух копий + if-цепочек, `sourceFormatOf(metadata)` +- [routes/pdf.js](../../routes/pdf.js) — новый `/fromImages` (опции в JSON-поле `options`, страницы + `[{f, r}]`, повторы встраиваются один раз, нетронутые JPEG/PNG — байт-в-байт), `/thumb` + (свой лимитер 300/мин, стоит ДО общего `router.use(limiter)`), `saveResult(..., displayName)` + + `owner.displayName` в скачивании, сообщение о лимите файлов, фильтр без SVG +- [public/pdf.html](../../public/pdf.html) — блок `#stepImages` (CSS `.ip-*`, JS `ip*`), панель + водяного знака, белые фоны +- [public/compress.html](../../public/compress.html) — `accept` с `.heic`, превью без битой картинки, + белые summary/список +- [public/video.html](../../public/video.html), [converter](../../public/converter.html), + [formatter](../../public/formatter.html), [sanitizer](../../public/sanitizer.html), + [parser](../../public/parser.html) — белые фоны +- [package.json](../../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](../../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/"`. +- ⚠️ Грабли 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`