From 06c6716cf5c109f5abccf8bd6fc6c860f0faac11 Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Sat, 22 Aug 2026 14:59:05 +0500 Subject: [PATCH] docs: add update ux plan --- docs/plan-update-ux.md | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 docs/plan-update-ux.md diff --git a/docs/plan-update-ux.md b/docs/plan-update-ux.md new file mode 100644 index 0000000..cce8890 --- /dev/null +++ b/docs/plan-update-ux.md @@ -0,0 +1,64 @@ +# План: раскладка «исходник слева — результат справа» + вставка изображения + +Реализует пункт 3 из [backlog.md](./backlog.md). Выполняется поверх дизайн-системы (`design-system.md` выполнен). + +## 1. Целевое поведение + +1. **Постоянная двухпанельная раскладка** страницы инструмента — отдельного состояния «страница загрузки» больше нет: + - **Слева — исходник**, панель есть всегда. Не загружено → пустое дроп-поле (drag&drop или клик). Загружено → превью исходника. + - **Справа — результат**: до загрузки — `EmptyState` «Результат появится здесь»; во время обработки — `EmptyState` «Обработка…»; после — превью результата (для info-инструмента — `InfoPanel`). +2. **Ctrl+V** — картинка из буфера обмена вставляется как исходник с любого места страницы. +3. **Замена перетаскиванием** — новый файл, брошенный на левую панель с загруженной картинкой, заменяет исходник (с оверлеем-подсказкой во время перетаскивания). +4. **Кнопка «Заменить»** под превью исходника (переносится туда текущая «Загрузить другое изображение»). + +На мобильной ширине панели складываются в столбец: исходник сверху, результат снизу. + +## 2. Изменения по файлам + +Новые компоненты не вводим — `EmptyState`, `Preview`, `DropZone` покрывают всё. Меняем три файла: + +- **`core/io.ts`** — экспорт `isSupportedImage(file): boolean`: общая MIME-проверка на базе `ACCEPTED_IMAGE_TYPES`. +- **`DropZone.svelte`** — переходит на `isSupportedImage`; новый опциональный проп `overlay` — режим «невидимая зона приёма поверх контента» для замены перетаскиванием. +- **`ToolPage.svelte`** — постоянная сетка из двух панелей; ``; drag-оверлей левой панели; кнопки замены/сброса переезжают в левую панель; правая панель — три состояния через `EmptyState`. + +## 3. Этапы и проверки + +- **A. Общая валидация** — `isSupportedImage` в `io.ts`, `DropZone` переведён на неё. Проверка: `pnpm check`. +- **B. Раскладка** — две постоянные колонки в ToolPage; правая панель через EmptyState; кнопки уходят в левую панель; обёртка `{#if !source}` на всю страницу убирается. Проверка: визуальный осмотр всех инструментов, `check/build`. +- **C. Ctrl+V** — `onpaste` на окне → поиск image-item в `clipboardData` → тот же `handleFile`; не-изображения игнорируются молча. Проверка: ручной смоук со скриншотом из буфера. +- **D. Drag-замена** — оверлей DropZone(overlay) при dragover на левой панели; drop → `handleFile` нового файла. Проверка: ручной смоук «бросить файл на загруженный исходник». +- **E. Итог** — полный ручной смоук-чеклист (§5). Проверка: `test/check/build` зелёные. + +## 4. Нюансы и решения + +- **Мерцание dragleave** — классическая проблема оверлеев: используем счётчик `dragenter/dragleave`, оверлей скрывается только когда счётчик обнулился и произошёл `drop`/`dragend`. +- **Paste при фокусе в поле параметров** — обрабатываем всегда: если в буфере именно изображение, пользователь очевидно хочет заменить исходник; текстовые вставки обработчик не трогает. +- **Форматы буфера** — скриншоты приходят как PNG, часть приложений отдаёт JPEG/WebP; все проходят общую `isSupportedImage`. GIF/BMP из буфера редки, но тоже допустимы. +- **Info-инструменты** — ведут себя так же: слева исходник, справа после загрузки появляется `InfoPanel`. +- **Состояние ошибки** — баннер остаётся сверху страницы; неудачная замена не сбрасывает старый исходник. + +## 5. Чеклист ручного смоука + +1. Пустые обе панели → drag&drop файла слева → появился исходник и результат. +2. Клик по пустой левой панели → выбор файла. +3. Ctrl+V со скриншотом → исходник заменился, результат пересчитался. +4. Drag файла на загруженную левую панель → оверлей виден, после drop — замена. +5. Отмена перетаскивания (Esc / мимо) → оверлей скрылся, исходник не изменился. +6. Бросок неподдерживаемого файла (например .txt) → баннер ошибки, старый исходник цел. +7. Кнопка «Заменить» открывает выбор файла. +8. png-info: работает та же схема, справа сводка. +9. Мобильная ширина: панели в столбец, порядок исходник → результат. +10. Все 11 инструментов отвечают на замену исходника корректным пересчётом. + +## 6. Критерии готовности + +- На странице инструмента нет состояния «только дропзона на всю страницу» — раскладка двухпанельная всегда. +- Загрузка работает тремя способами: клик, drag&drop (включая замену), Ctrl+V. +- Ошибочные файлы и отмена перетаскивания не портят текущий исходник. +- `test/check/build` зелёные; чеклист §5 пройден. + +## 7. Что сознательно не делаем + +- Множественная загрузка / пакетная обработка — это batch-страница следующих фаз. +- Камера/скриншот-инструменты захвата — только буфер обмена. +- Прогресс-бары декодирования — файлы читаются быстро, достаточно индикации «Обработка…».