mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
255 lines
22 KiB
Markdown
255 lines
22 KiB
Markdown
# Backlog
|
||
|
||
## lint и прочие правила
|
||
|
||
- [x] Кросс-языковой линтер словарей (warn-only: паритет ключей, пустые
|
||
значения, совпадение `{placeholder}`-переменных между всеми локалями) —
|
||
правило `i18n/dict-consistency`, детали в §Фаза 8
|
||
`docs/plan-preview-i18n.md`. Правило реализовано; Q2 перевёл i18n baseline
|
||
к zero-warning через policy-aware fallback, не меняя `/v1`.
|
||
- [ ] проверка дублирования кода html - div с одинаковым классом и т.д. (глянуть
|
||
что за `SonarLint` или написать кастомный линтер)
|
||
- [ ] проверка текстов в svelte\ts\html - всё тексты должны быть через i18n
|
||
модуль
|
||
- [ ] консистентность комментариев - если есть описание к одному инструменту -
|
||
оно должно быть у всех или объяснено, почему этот инструмент такой
|
||
особенный и заслуживает комментарий
|
||
- [ ] удалить legacy `tools.*.params` из root i18n после проверки потребителей;
|
||
до этого Q2 держит pattern-based policy-исключение
|
||
|
||
## Мелочи всякие
|
||
|
||
- [ ] Пересмотреть тесты - исправить всякие хрупкие, которые проверяют
|
||
количество инструментов, точное совпадение текстов, поиск по
|
||
`img[alt="Result image"]`, svelte классам и тому подобные
|
||
- [ ] нужен инструмент для удаления фона по выбранной точке - удалять внутри
|
||
выделенной области
|
||
- [ ] сделать конвертацию в смайлики\награды для твитча (6 размеров или выбор
|
||
какой размер и 2 сетки)
|
||
- [ ] неудобно настраивать ползунками, некоторые инструменты удобнее настроить
|
||
через drag-n-drop. звучит сложно, но надо придумать процесс
|
||
- [ ] можно ли в тестах получать i18n ключ вместо текста?
|
||
- [ ] убрать в тестах все нестандартные символы `→`, длинные тире и т.д.
|
||
- [ ] Пересмотреть прозрачность в инструментах - Create empty PNG - прозрачность
|
||
должны быть настраиваемой 0-100%, а не переключателем
|
||
- [ ] обдумать объединение пар `inputMode + source` и `resultKind + result` в
|
||
единую структуру, позволит упростить некоторые вещи - например
|
||
`sourceValue` \ `resultValue` в `SchemaPreview.svelte`
|
||
- [ ] Рассмотреть необходимость всех этих пропсов в `SchemaPreview.svelte` они
|
||
дублируют друг друга `ontextsource`, `onrendertext`, `oncopytext`,
|
||
`ondownloadtxt`, `ondownload`,
|
||
- [ ] Переделать внешний вид инструментов без настроек, например Remove alpha
|
||
channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым.
|
||
- [ ] Убрать описание формата в отображении исходник\результат - это должно быть
|
||
в кнопке Download
|
||
- [ ] Кнопка download должна сразу писать какой формат сейчас, быть с селектором
|
||
формата и подсвечивать предупреждение если формат не совместим (альфа
|
||
канал)
|
||
- [ ] Пересмотреть поля - Plate, Position, Font Style - сейчас второй label
|
||
- [ ] Font Style - обдумать выбор шрифта (google fonts???) как организовать
|
||
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
|
||
наборе и лицензиях: `docs/plan-platform.md` §4 — только OFL/Apache с
|
||
паспортом, семейства с кириллицей)
|
||
- [ ] сделать загрузку картинки исходника по ctrl+v и drag-and-drop (dropzone)
|
||
- [ ] square-mask-png - проверить работу - параметры неверно считаются. width -
|
||
100, height - 100, x - 100, y - 100, обрезает 50% на 50% картинку
|
||
- [ ] прикрутить кастомный color picker (есть в old), добавить прозрачность
|
||
(range?)
|
||
- [ ] проверить настройки range slider на crop-png - слишком большие значения
|
||
- [ ] для range slider field - добавить поле для ввода цифр и кнопку сброса
|
||
значения
|
||
- [ ] для keep Aspect field - пересчитывать второе поле, учитывать какое было
|
||
изменено
|
||
- [ ] поле ввода текста - сделать по умолчанию нормального размера, а не одну
|
||
строку для svg - форматирование или подсветку синтаксиса??? для bin\hex -
|
||
форматирование по колонкам??? для hex\bytes\rgba - пример в placeholder
|
||
- [ ] обновить страницу kit или сделать storybook
|
||
- [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop,
|
||
удаление, добавление инструментов. переход один инструмент - pipeline без
|
||
перезагрузки
|
||
- [ ] Слаги инструментов (`*-png`) — надо переименовть, они работают с любыми
|
||
изображениями. Надо сделать отдельный интерфейс маппинга инструмент ->
|
||
ссылка
|
||
|
||
## Переезд
|
||
|
||
- [x] добавить i18n в preview
|
||
- [ ] множественные числа (часть/части/частей; «N параметров», счётчики) —
|
||
`tPlural()` и формат `PluralForms`, детали в §Фаза 9
|
||
`docs/plan-preview-i18n.md`
|
||
|
||
## SEO/GEO
|
||
|
||
Общий план: `docs/plan-seo.md` (S0–S4). C17 выполнен; старт возможен — пока
|
||
только domain-free часть S1.
|
||
|
||
- [ ] переименование бренда + домен: чек-лист в локальном плане
|
||
`docs/plan-domain.local.md` (вне git, имя домена в репо не публикуется;
|
||
план-seo §6, R1/R2)
|
||
- [ ] download с селектором формата PNG/JPG/WebP/BMP для всех инструментов (райз
|
||
№7 → S1f)
|
||
- [ ] форматные страницы (`crop-jpeg`, …) — только по вордстату с уникальным
|
||
контентом; редиректы только для опечаток; клонов с canonical не делать
|
||
(план §5)
|
||
- [ ] sitemap.xml из реестра + `Sitemap:` в robots.txt (S1b/S1c)
|
||
- [ ] Seo.svelte: canonical + OG-теги, per-tool OG-картинки (S1d/S1e)
|
||
- [ ] контент страницы инструмента: seo-блок в словарях, H1/how-to/FAQ/related
|
||
(S2)
|
||
- [ ] JSON-LD (SoftwareApplication/FAQPage/Breadcrumb) + llms.txt (S3)
|
||
- [ ] GSC + приватная аналитика (Plausible/Umami/CF), дистрибуция (S4)
|
||
|
||
## Платформа (API/PWA)
|
||
|
||
Общий план: `docs/plan-platform.md`; WASM-ядро и CLI уже в `docs/roadmap.md`
|
||
(фазы 3–8) — здесь только новые треки.
|
||
|
||
- [ ] PWA: manifest + service worker, оффлайн-режим, установка (после C17 и S1;
|
||
C19 отложен — не блокер)
|
||
- [ ] API: спайк серверного ядра (нативный Rust vs edge-wasm), ключи, free tier
|
||
(после wasm-фаз 5–7)
|
||
|
||
## Баги preview
|
||
|
||
Зарегистрированы при написании e2e (`web/e2e/`, `pnpm --dir web test:e2e`) и
|
||
ручного чек-листа — см. `docs/checklist-manual-testing.md` (раздел G). Каждый
|
||
пункт связан с соответствующим `test.fixme` или отдельным тестовым долгом. После
|
||
фикса: убрать `test.fixme` и отметить пункт G в чек-листе как пройденный.
|
||
|
||
1. **Генераторы без автоматического результата** — все 21 инструмент категории
|
||
GENERATE открываются, но в UI нет полей схемы и результата; доступны только
|
||
RU/EN/Reset. В `SchemaToolView.svelte` уже есть auto-run через debounce,
|
||
поэтому отдельная кнопка Generate не требуется. Ожидание: поля схемы,
|
||
автоматический запуск по дефолтам и результат-картинка. Fixme:
|
||
`web/e2e/generators.spec.ts`. Кнопка Generate не добавляется без отдельного
|
||
UX-решения.
|
||
2. **resize-png с дефолтами падает** — схема по умолчанию `size: 0×0` +
|
||
`keepAspect: true` → при загрузке ЛЮБОГО PNG сразу `errors.resizeSize`
|
||
(alert), результата нет. `web/src/lib/registry/geometry.ts`. Ожидание:
|
||
осмысленный дефолт-размер (например, исходный) либо отдельный режим ввода, а
|
||
не авто-ошибка.
|
||
3. **crop-png с дефолтами падает** — аналогично: `width: 0, height: 0` → сразу
|
||
`errors.cropSize`. `web/src/lib/registry/geometry.ts`. Ожидание: базовый кроп
|
||
по умолчанию либо внятное предзаполнение.
|
||
4. **Сырые ключи ошибок в UI** — alert на tool-странице показывает сырой ключ
|
||
i18n (`errors.resizeSize`), а не сообщение из `en.ts` / `ru.ts` (там
|
||
`resizeSize: "Width and/or height must be positive"`). Проверяется на
|
||
resize-png / crop-png. Ожидание: человекочитаемое сообщение на текущем языке.
|
||
Fixme: `web/e2e/known-issues.spec.ts` (тест «error message localized»).
|
||
5. **Theme storage key в e2e устарел** — production использует ключ `theme`, а
|
||
`web/e2e/navigation.spec.ts:30-48` проверяет `easy-png-tools:theme`.
|
||
Ожидание: исправить тест на фактический контракт и снять `test.fixme`.
|
||
6. **Reset и auto-run требуют решения** — `pipeline.spec.ts:55-63` ожидает
|
||
очистку результата, но текущий `SchemaToolView.svelte:162-173` может сразу
|
||
перезапустить обработку. Нужно определить семантику Reset, затем исправить
|
||
тест и снять `test.fixme`.
|
||
|
||
## Идеи
|
||
|
||
1. **Менять первый инструмент цепочки** — оценка M. Сейчас базовый инструмент
|
||
зафиксирован при открытии страницы; хочется заменить его на другой без
|
||
разборки цепочки: шаги и их параметры сохраняются, вход перечитывается.
|
||
Открытый вопрос: что делать с несовместимыми параметрами (text-source ↔
|
||
file).
|
||
|
||
2. **Сворачивать инструменты в chain** — оценка S. Тоггл сворачивания звена до
|
||
заголовка «Шаг n: название» (превью скрываются). Состояние свёрнутости
|
||
помнить в workspace-pipeline.
|
||
|
||
3. **Несколько цепочек: сохранение и загрузка** — оценка M. Именованные цепочки
|
||
в localStorage (список, создать/переименовать/удалить), быстрое переключение.
|
||
Формат экспортного JSON расширить опциональным полем имени, старые файлы
|
||
читаются как безымянные.
|
||
|
||
4. **Batch-обработка архивов выбранным chain** — оценка L. Вход — zip-архив
|
||
картинок (распаковка в браузере), прогон текущего или выбранного сохранённого
|
||
chain по каждому файлу, сборка результата обратно в zip для скачивания.
|
||
Зависит от п.4 (выбор цепочки) и от экспортного формата pipeline JSON;
|
||
прогресс и ошибки — пофайлово.
|
||
|
||
5. **Избранные инструменты (fav tools)** — оценка S/M. Тоггл-звёздочка на
|
||
карточках каталога, результатах поиска и в шапке страницы инструмента; список
|
||
id в localStorage. Избранное показывается отдельной секцией сверху каталога и
|
||
поднимается в выдаче поиска (бонус к popularity при скоринге).
|
||
|
||
6. **Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке Download**
|
||
— оценка M/L. Инструменты `convert-png-to-jpg` / `convert-png-to-webp` (и др.
|
||
форматы) не должны жить как самостоятельные инструменты цепочки. Вместо этого
|
||
— бесшовное внедрение выбора формата/качества прямо в кнопку/диалог
|
||
**Download**: юзер скачивает результат в нужном формате (mime/ext/quality), а
|
||
pipeline при этом не усложняется лишним звеном. **Сделано (2026-09):**
|
||
механическая часть реализована в preview — `ToolEntry.output`
|
||
(`OutputFormat`: mime/ext/qualityParamId) в `web/src/lib/registry/types.ts`;
|
||
`SchemaToolView.download()` кодирует по `output` (jpg/webp/bmp уже настроены;
|
||
`png-to-bmp` переведён сюда же). **Осталось (UX-райз «Download»):**
|
||
- выбор формата/качества прямо в кнопке/диалоге Download для любого
|
||
результата (не отдельными конвертерами);
|
||
- экспорт с лимитом размера → закрывает отложенный `reduce-to-size-png`
|
||
(целевой KB, бинарный поиск по k из квантования). Проработать вместе с
|
||
достройкой download-флоу нового UI.
|
||
|
||
7. **`watermark-image-png` (водяной знак картинкой)** — оценка M. Отложен из
|
||
миграции (`archive/plan-migrate-remaining.md`). Нужна overlay-механика:
|
||
второй источник изображения (getOverlay/store), параметры scale/opacity/
|
||
position/margin/aspect. Решается вместе с вопросом, как второй источник
|
||
картинки вписывается в schema-driven preview (`SchemaToolView`).
|
||
|
||
8. **`png-info` (детальная информация о PNG)** — оценка M/L. Отложен из
|
||
миграции. Отдельный райз: exif-теги, редактирование, структурированный вывод;
|
||
нужен свой отдельный случай в UI, не «ещё один text/verdict». возможно нужна
|
||
вообще отдельная страница, несовместимая с другими инструментами: 1) она
|
||
работает не с изображением, а с мета данными из файла, 2) она не может быть
|
||
частью цепочки, т.к. результат не является изображением, 3) если надо
|
||
изменить теги, никакого форматирования и изменения в изображение вносить не
|
||
надо, только в мета информацияю
|
||
|
||
9. **Region-инструменты** (censor/erase/pixelate-area/blur-area/sharpen-area/
|
||
reverse-area) — ждут UI выделения области на превью. Из
|
||
`archive/plan-gap-waves.md` («вне очереди»).
|
||
|
||
10. **Мультифайловые инструменты-потребители** (gif-to-frames, separate-colors)
|
||
— механизм «результат = набор файлов» (1 → many) реализован: `FileResult` +
|
||
`result: "files"` + скачивание zip-архивом + грид-превью частей. Первый
|
||
потребитель — `split-into-parts-png`. Остальные подключаются по мере нужды.
|
||
|
||
11. **Анимационные** (slow-reveal/fade/scrolling) — выход не PNG; отдельное
|
||
решение о формате. Из `archive/plan-gap-waves.md`.
|
||
|
||
12. **HARD-серия** (glitch, barcode, signature-extract, handwritten-digital). Из
|
||
`archive/plan-gap-waves.md`.
|
||
|
||
13. **Контраст текста на акцентных кнопках — частично закрыт**. Для dark-темы
|
||
`--color-main`/`--color-accent` подняты до tone 56, чтобы пройти текущий
|
||
порог `palette.test.ts` 4.0; targeted-тест проходит. Light-тема сохраняет
|
||
контраст ~4.1–4.3, что ниже AA 4.5 для обычного текста, поэтому после
|
||
завершения редизайна нужно повторно поднять тона и вернуть порог 4.5. Также
|
||
проверить `--color-danger` (dark, тон 55): текст на нём 4.93 — ок, но
|
||
light-danger tone 48 = 4.25 на границе.
|
||
|
||
14. **Отображение маски для инструментов (runMask/preview-mask)** — придумать и
|
||
реализовать процесс показа маски результата. **Контекст:** в старом
|
||
контракте поле `preview` у `remove-color`/`remove-background` показывало
|
||
быстрый ч/б превью-маску (`colorMask`/`backgroundMaskPreview`) того, что
|
||
будет вырезано. При миграции на единый `run(ctx)` поле убрано (шаг 8,
|
||
`web/src/lib/registry/alpha.ts`) — новый executor и schema-превью зовут
|
||
`run()` напрямую, маска пока не нужна. **Идея 1:** дать каждому `run`
|
||
возможность вернуть (или инструмент — объявить) `runMask` — ч/б изображение
|
||
маски изменений либо иной подход (отдельное поле `mask` + функция маски,
|
||
второй результат, overlay). Оценка — на усмотрение при проработке (S/M).
|
||
Пока живём без неё. **Идея 2:** каждый `run` возвращает два изображения -
|
||
для отображения (показывает маску или сам результат), и для передачи в
|
||
следующий инструмент (всегда результат. Оценка — на усмотрение при
|
||
проработке (S/M). Пока живём без неё.
|
||
|
||
15. **Процесс работы с инструментами 1 → many и many → 1** — абстракция
|
||
результата «набор файлов» оформлена и работает: тип `FileResult`,
|
||
`result: "files"` в реестре, сериализация через executor, скачивание
|
||
zip-архивом, грид-превью частей. Реализовано на первом потребителе
|
||
`split-into-parts-png` (2026-09, `docs/archive/plan-split-into-parts.md`).
|
||
**1 → many:** подключение остальных потребителей (gif-to-frames,
|
||
separate-colors) при необходимости; формат/качество файлов внутри zip —
|
||
отложено до UX-райза «Download» (п.7). **many → 1** (вход = архив/несколько
|
||
картинок → единый результат): не реализовано. Зависит от batch-обработки
|
||
архивов (п.5 идей, roadmap фаза 8 «batch-страница»). Нужна отдельная
|
||
проработка входа (распаковка zip в браузере, порядок файлов, поведение в
|
||
пайплайне — такие инструменты терминальны, как и 1 → many).
|