mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
26 KiB
26 KiB
Backlog
Статус: active. Открытые задачи. Подробные планы, разбор решений и сырые находки —
docs/plan-seo.md,docs/plan-platform.md,docs/plan-fields-audit-fixes.md,docs/tools-audit.md,docs/decisions.md.Все пункты — чекбоксы; нумерация «Идея N» в тексте сквозная по документу и сохраняется ради перекрёстных ссылок («идея 4 зависит от идеи 3»). Оценки (S/M/L) — оценка труда, не приоритет.
Pipeline
- названия инструментов — в pipeline инструмент называется «обрезать png», но он работает с любыми картинками, наверное надо убрать; в заголовке страницы — возможно, надо указать все форматы (связано с SEO)
- кнопка «добавить инструмент» в pipeline — обдумать селектор с нормальным поиском, фильтром возможных инструментов и т.д.
- Идея 1. Заменить инструмент шага без удаления — оценка M. В заголовке карточки шага кнопка «поменять инструмент»: заменяет инструмент на месте (любой шаг, не только первый), остальные шаги и их параметры сохраняются, вход перечитывается. Открытый вопрос: что делать с несовместимыми входами (text-source ↔ file).
- Идея 2. Сворачивать инструменты в chain — оценка S. Тоггл сворачивания звена до заголовка «Шаг n: название» (превью скрываются). Состояние свёрнутости помнить в workspace-pipeline.
- Идея 3. Несколько цепочек: сохранение и загрузка — оценка M.
Именованные цепочки в localStorage (список, создать/переименовать/
удалить), быстрое переключение. Формат экспортного JSON расширить
опциональным полем имени; обратной совместимости со старыми выгрузками не
делаем — формат не устоялся: он появится вместе с фазой 11
docs/roadmap.mdи до её старта может измениться. Плюс отдельная страница со списком всех цепочек: удалить, переименовать, добавить новую, «использовать» (переход на страницу инструмента с этой цепочкой). На странице — упрощённый вид: только список инструментов цепочки, без реального выполнения и параметров. - Идея 4. Batch-обработка архивов выбранным chain — оценка L. Вход — zip-архив картинок (распаковка в браузере), прогон текущего или выбранного сохранённого chain по каждому файлу, сборка результата обратно в zip для скачивания. Зависит от идеи 3 (выбор цепочки) и от экспортного формата pipeline JSON; прогресс и ошибки — пофайлово.
- Идея 15. Набор файлов в пайплайне: 1 → many не должен быть
терминальным — оценка L. Сейчас
executeпринимает одинsource: PixelImage | undefinedи возвращает одинToolResult, аSchemaToolViewраскладывает вывод вresult/fileResult/textResultпоresultKind— поэтому шаг сresult: "files"упирается в конец цепочки. Направление: следующий инструмент применяется ко всем картинкам предыдущего результата (fan-out), а many → 1 (вход = архив или несколько файлов) — обратная сторона того же контракта. Терминальными остаются только результаты, которые не картинка (text, verdict). Что обдумать: - где проходит граница: один вызовrun(ctx)на файл (имя части склеивается вFileResult.files) или батч целиком на стороне исполнителя;executor/protocol.tsfilesуже сериализуются, но при батче нужен прогресс и отмена; - частичные ошибки: один битый файл не должен ронять весь шаг — нужен per-file отчёт, а не одинToolErrorна шаг; - имена частей на каждом шаге и Download для набора (сейчас zip поpage.slug,SchemaToolView.download()); - обратная сторона: распаковка zip в браузере, порядок файлов, поведение many → 1 → many в одной цепочке. Зависит от идеи 10 (остальные потребители 1 → many) и идеи 4 (batch по архиву),docs/roadmap.mdфаза 8 «batch-страница». - Идея 17. Промежуточные результаты шагов + выравнивание рядов — оценка M. Два режима просмотра цепочки: - без выравнивания (по умолчанию): в панели просмотра цепочка изображений по 2 в колонку «исходник → результат 1 → результат 2 → … → конечный результат»; - с выравниванием (галочка «выровнять инструменты и просмотр»): у каждого инструмента показаны его исходник и результат построчно «параметры — исходник — результат»; промежуточные картинки при этом осознанно дублируются на экране — результат шага является исходником следующего.
Инструменты
- qr code to text, text to qr code
- bar code to text, text to bar code
- split-into-parts-png - в результате надо выводить размеры получившихся файлов
- split-into-parts-png — режим «по размеру тайла»: указываешь размер тайла
(16×16, 32×32…, список
SIZE_PRESETS), инструмент сам считает сетку — сценарий «режу спрайтшит, знаю размер тайла, не знаю сетку» (новый режим: схема + core, из задачи C3) - нужен инструмент для удаления фона по выбранной точке - удалять внутри выделенной области
- сделать конвертацию в смайлики\награды для твитча (6 размеров или выбор какой размер - 112\56\28px или 72\36\18)
- сделать несколько проходное сжатие png для получения необходимого размера файлов, посмотреть реализацию в twitch-emote-resizer
- Пересмотреть прозрачность в инструментах - Create empty PNG - прозрачность должны быть настраиваемой 0-100%, а не переключателем
- Font Style - обдумать выбор шрифта (google fonts???) как организовать
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
наборе и лицензиях:
docs/plan-platform.md§4 — только OFL/Apache с паспортом, семейства с кириллицей) - проверить настройки range slider на crop-png - слишком большие значения
- Свести convert-страницы (
convert-png-to-jpg,convert-png-to-webp,png-to-bmp) на один инструментconvert— зависит от S1f (docs/plan-seo.md§4). Мешает не толькоquality(он живёт в схеме инструмента), а сама модель:outputс mime/ext — свойствоTool, аPageStepумеет только{ id, params? }, поэтому страницы на общийidполучат одинаковый формат вывода. Нужно научить шаг переопределять формат вывода - Идея 6. Конвертация формата — НЕ отдельный инструмент, а выбор в кнопке
Download — оценка M/L. Решение и продуктовое обоснование:
docs/plan-seo.md§0 и задача S1f; почему селектор не заменяет существующие convert-страницы —docs/plan-seo.md§5. Механическая часть уже есть:Tool.output(OutputFormat: mime/ext/qualityParamId) и кодирование по нему вSchemaToolView.download()—docs/architecture.md, раздел 3. Что осталось сверх S1f: - экспорт с лимитом размера → «сжатие до целевого КБ»: для lossy это quality в селекторе формата, для PNG — бинарный поиск по k из квантования. Нужна ли отдельная страница под этот интент — открытый вопрос с вордстатом, имя не выбрано (docs/plan-seo.md§5). Проработать вместе с достройкой download-флоу. - Идея 7. Страница
watermark-image-png(водяной знак картинкой) — оценка M. Нужна 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 выделения области на превью. Вне очереди.
- Идея 10. Мультифайловые инструменты-потребители (gif-to-frames,
separate-colors) — механизм «результат = набор файлов» (1 → many) уже есть
(
docs/architecture.md, раздел 7), первый потребитель —split-into-parts-png. Остальные подключаются по мере нужды. - Идея 11. Анимационные (slow-reveal/fade/scrolling) — выход не PNG; отдельное решение о формате.
- Идея 12. HARD-серия (glitch, barcode, signature-extract, handwritten-digital).
- Идея 14. Отображение маски для инструментов (
runMask) — придумать и реализовать процесс показа маски результата. Контекст: удалённый UI-v1 умел показывать ч/б превью-маску «что будет вырезано» отдельным полем; при переходе на единыйrun(ctx)этого поля не осталось — executor и schema-превью зовутrun()напрямую, маска не возвращается. Идея 1: дать каждомуrunвозможность вернуть (или инструмент — объявить)runMask— ч/б изображение маски изменений либо иной подход (отдельное полеmask+ функция маски, второй результат, overlay). Оценка — на усмотрение при проработке (S/M). Пока живём без неё. Идея 2: каждыйrunвозвращает два изображения — для отображения (показывает маску или сам результат) и для передачи в следующий инструмент (всегда результат). Оценка — на усмотрение при проработке (S/M). Пока живём без неё. Первые кандидаты на маску:remove-color-from-png,remove-background-png.
UI и качество
- мёртвый i18n-ключ
noParams(«нет параметров — результат готов»): его ничем не читают. Либо показывать подсказку для инструментов с пустой схемой (FA-E1), либо удалить ключ из обеих локалей - неудобно настраивать ползунками, некоторые инструменты удобнее настроить через drag-n-drop. звучит сложно, но надо придумать процесс
- не работает drag-n-drop на полях с range slider, похоже включается drag-n-drop для всей карточки настроек инструмента
- результат "split-into-parts" может занимать очень много место вертикально, возможно стоит придумать максимальную высоту и скролл\сворачивание
- просмотр картинки в оригинальном размере, и возможно с зумом отдельных областей, чтобы просмотреть мелкие артефакты, выбор разных подложек - черная\белая\цветные\серая для проверки прозрачных картинок
- обдумать объединение пар
inputMode + sourceиresultKind + resultв единую структуру, позволит упростить некоторые вещи - напримерsourceValue\resultValueвSchemaPreview.svelte - Рассмотреть необходимость всех этих пропсов в
SchemaPreview.svelteони дублируют друг другаontextsource,onrendertext,oncopytext,ondownloadtxt,ondownload, - Переделать внешний вид инструментов без настроек, например Remove alpha channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым.
- Пересмотреть поля - Plate, Position, Font Style - сейчас второй label
- поле ввода текста - сделать по умолчанию нормального размера, а не одну строку для svg - форматирование или подсветку синтаксиса??? для bin\hex - форматирование по колонкам??? для hex\bytes\rgba - пример в placeholder
- прикрутить кастомный color picker, добавить прозрачность (range?)
- обновить страницу kit или сделать storybook
PreviewTile: высота плитки задана толькоmin-height: clamp(...), поэтому она не следует за пропорциями результата — широкий результат уезжает в узкую полосу, а высокий упирается вmax-height: 100vh. Нужно, чтобы соотношение сторон выбиралось по результату в диапазоне 16:9…9:16 (web/src/lib/components/schema/PreviewTile.svelte).- Радиусы бордеров:
--radius-mненулевой и применён ко всем бордерам (app.css,SchemaToolView.svelte). Решить, где скругления реально есть в дизайне, а где должен быть 0 - Component-тесты
SchemaToolView/SchemaPreviewтребуют отдельного решения: node Vitest не имеет DOM/canvas, а e2e уже покрывает поведение. - Ошибка декодирования изображения из
createImageBitmapпока показывается сырым сообщением браузера; нуженToolError-маппер и i18n-ключ. - Идея 5. Избранные инструменты (fav tools) — оценка S/M. Тоггл-звёздочка на карточках каталога, результатах поиска и в шапке страницы инструмента; список slug в localStorage. Избранное показывается отдельной секцией сверху каталога и поднимается в выдаче поиска (бонус к popularity при скоринге).
- Идея 13. Контраст текста на акцентных кнопках — частично закрыт. Тона
--color-main/--color-accentподняты под текущий порогpalette.test.ts; targeted-тест проходит. Light-тема всё ещё ниже AA 4.5 для обычного текста, а--color-dangerв light-теме на границе: после завершения редизайна вернуть порог 4.5 и перепроверить оба токена. - Идея 16. Главная должна отличаться от каталога — оценка S. Сейчас
src/routes/+page.svelteиsrc/routes/list-tools/+page.svelteпобайтово идентичны (совпадают script, шаблон и стили), при этом/list-tools— рабочий маршрут: на него ссылается крошка в+layout.svelteи он открыт e2e-сценариямиcatalog.spec.ts,i18n.spec.ts,navigation.spec.ts. Замысел: главная — крупнее и с более простым поиском, без категорий; каталог остаётся группировкой с фильтрами. Детектор дублирования разметки сознательно не вводим —docs/decisions.md, раздел 1, поэтому расхождение ловится на ревью.
Тесты и lint
tseslint.config(...)deprecated: сигнатура(...configs: InfiniteDepthConfigWithExtends[]): ConfigArrayпомечена устаревшей, нужен переход наdefineConfigизeslint/config(ESLint core, а неtypescript-eslint) —web/eslint.config.js.- удалить мёртвые
tools.*.paramsиз root i18n после проверки потребителей; до этого действует pattern-based policy-исключение (web/eslint-plugins/README.md, разделdict-consistency) - e2e:
i18n.spec.tsиtext-and-verdicts.spec.tsдублируют локаторы изhelpers/page.tsвместо вызова — правило «спека зовёт helpers» (docs/testing-strategy.md, раздел 5) - e2e webkit: случайные падения по таймауту 5с (элемент не появляется),
каждый прогон падают разные тесты — webkit под Windows слишком медленный.
Рассмотреть увеличение timeout/expectTimeout для webkit-проекта в
playwright.config.ts. После фикса перепроверитьtool-flows.spec.ts«chain: remove step» — на webkit удаление шага не успевает за 5с (на остальных движках стабильно) - Пересмотреть тесты — убрать точные совпадения текстов и любые селекторы,
привязанные к разметке или svelte-классам (сейчас остались:
tool-flows.spec.ts,schema-tool-strings.test.ts) - можно ли в тестах получать i18n ключ вместо текста? можно ли написать lint правило такое (запретить toContain без i18n)
- убрать в тестах все нестандартные символы
→, длинные тире, русский язык и т.д., сделать lint правило - комментарии на английском, lint правило
- уменьшить количество и многословность комментариев (lint правило?)
SEO/GEO
- переименование бренда + домен: чек-лист в локальном файле
plan-domain.local.md(в git не входит, в клоне отсутствует; подробности и порядок —docs/plan-seo.md§6, R1/R2) - снять
noindexсо страниц инструментов, когда будут sitemap, canonical и контент (S1h; блокирует индексацию всего сайта) —docs/plan-seo.md§4 - форматные страницы по конкурентным слагам (
crop-jpeg, …) — только по вордстату с уникальным контентом; редиректы только для опечаток и переименований уже опубликованных страниц; клонов с canonical не делать (docs/plan-seo.md§5) - sitemap.xml из реестра +
Sitemap:в robots.txt (S1b/S1c) - Seo.svelte: canonical + OG-теги, per-tool OG-картинки (S1d/S1e)
- контент страницы инструмента: seo-блок в словарях, how-to/FAQ/related (S2)
- JSON-LD (SoftwareApplication/FAQPage/Breadcrumb) + llms.txt (S3)
- дистрибуция: закрепить репо, alternative.to, Product Hunt, Reddit/HN (S4c)
- GSC: подключить домен, отправить sitemap, мониторинг индексации (S4a)
- GA4: cookieless-конфигурация, отключить рекламные audiences и signals,
anonymize_ip— сейчас вweb/src/routes/+layout.svelteголыйgtag('config')(S4b)
Платформа (API/PWA)
- PWA: manifest + service worker, оффлайн-режим, установка (после S1)
- API: спайк серверного ядра (нативный Rust vs edge-wasm), ключи, free tier (после wasm-фаз 5–7)
- Шрифты: лицензирование (F1–F4) и DOM-free рендер (F5–F6) — до фазы 8
(
docs/plan-platform.md§4)
Переезд
- множественные числа (часть/части/частей; «N параметров», счётчики) —
функция
tPlural(path, n)и формаPluralForms(обязательноеother, опциональныеone/few/many); первые потребители —part/partsв подписи результата и счётчики параметров. Критерий приёмки: у ключа с plurals есть все формы, для которых нужен перевод,otherникогда не пустой, число подставляется в текст без склейки