Files
ds-galo/openspec/changes/lightroom-workspace-ui/proposal.md
T
iu dbf116999d chore(openspec): sync lightroom-workspace-ui with implemented changes
Reflect post-planning work in proposal, design, specs (albums/photos/
ui-workspace) and tasks: photo rename, viewer delete/zoom/fullscreen,
resizable and collapsible panels with EXIF, upload size limit, album
counts, themes/scrollbars, back navigation.
2026-10-10 19:45:55 +03:00

77 lines
6.9 KiB
Markdown

# Proposal
## Why
Сейчас интерфейс — это центрированный «маркетинговый» лейаут: список альбомов с
инлайн-формой создания, серая заглушка вместо обложек, отдельные страницы «Участники» и
«Настройки», лайтбокс-оверлей. Обложки в бэкенде уже есть (`albums.cover_photo_id`,
`PATCH /albums/:id`), но до UI не доходят. Пользователь хочет полноценный «рабочий стол»
в духе Adobe Lightroom: постоянный рейл альбомов, контекстная панель, плотная сетка,
режим просмотра как часть рабочего стола, обложки с явным выбором и единый тёмный
графитовый хром.
## What Changes
- **Рабочий стол (шелл).** Группа `(app)` с постоянным левым рейлом альбомов, топбаром и
контекстной правой панелью. Публичные маршруты (`/login`, `/invites/[token]`,
`/share/[token]`) остаются вне шелла, но в тех же токенах.
- **Создание альбома.** Инлайн-форма заменяется иконочной кнопкой с хинтом, открывающей
модалку ввода названия.
- **Обложки.** `Album` получает `cover_thumb_url`; карточки и рейл показывают реальную
миниатюру. Выбор обложки: пикер в правой панели и действие «сделать обложкой» в
просмотре. Автообложка пишется только когда обложка ещё не задана; FK
`albums.cover_photo_id -> photos(id) ON DELETE SET NULL` чинит висячие ссылки.
- **Просмотр как маршрут.** `Lightbox`-оверлей заменяется маршрутом
`/albums/:id/photos/:photoId` внутри шелла: крупное фото, filmstrip снизу, панель
метаданных/комментариев. `share/[token]` переиспользует тот же компонент.
- **Плотность сетки.** Слайдер размера миниатюр в тулбаре (состояние в localStorage).
Мультивыбор и массовые действия — вне объёма.
- **Загрузка.** Крупный dropzone заменяется кнопкой в тулбаре, полноэкранным
drag-overlay и dropzone-намёком только в пустом альбоме. Лимит — 100 МБ с понятной
ошибкой при превышении.
- **Переименование фото.** `PATCH /photos/:id` меняет `original_filename`; инлайн-редактор
в правой панели, доступный автору фото и owner/admin.
- **Просмотр.** Полноэкранный режим (кнопка и хоткей `f`), зум колесом мыши, `Space` — 100%
с панорамированием; удаление текущего фото с модальным подтверждением; возврат к обзору.
- **Разделы и панели.** Правая панель — сворачиваемые разделы (состояние сохраняется), с
разделом «Информация» (EXIF/метаданные); левая и правая панели ресайзятся перетаскиванием.
- **Счётчики.** В ответе альбома — число фото и участников.
- **Темы и хром.** Существующие 4 темы сохраняются; `dark` — графит Lightroom и дефолт,
`neutral` — тёплый графит; переключатель упорядочен тёмная → нейтральная → светлая →
системная; добавляются токены `--chrome`/`--canvas`; скроллбары стилизованы в тон темы.
- **Адаптив.** На узких экранах рейл становится off-canvas drawer, правая панель —
bottom-sheet, filmstrip — горизонтальным скроллом.
## Capabilities
### New Capabilities
- `ui-workspace`: рабочий стол приложения — шелл, рейл альбомов, контекстная панель,
режим просмотра как маршрут, адаптивное поведение и тёмный хром.
### Modified Capabilities
- `albums`: отображение обложки, счётчики фото/участников и явный выбор обложки.
- `photos`: автообложка только при отсутствии выбора; переименование фото; лимит размера
загрузки.
## Impact
- **Backend:** миграция FK `albums.cover_photo_id -> photos(id) ON DELETE SET NULL`;
`internal/albums/store.go` (LEFT JOIN `photos` → `cover_thumb_key` и счётчики
`photos_count`/`members_count` в `ListForUser`/`GetByID`); `internal/albums/service.go`
(presign → `CoverThumbURL`, обогащение списка); `internal/models` (`Album.CoverThumbURL`,
`PhotosCount`, `MembersCount`); `internal/photos` (автообложка только при
`cover_photo_id IS NULL`; `PATCH /photos/:id` для переименования; лимит загрузки 100 МБ с
`413 file_too_large`; событие `photo.updated`).
- **Frontend:** реструктуризация `+layout.svelte` в группы `(app)`/`(public)`, `AppShell`
с ресайзом панелей и кнопкой полного экрана; компоненты рейла, контекстной панели со
сворачиваемыми разделами и EXIF, модалки создания/пикера обложки/подтверждения,
`Viewer` с полноэкранным режимом и зумом, общий стор альбомов, контрол плотности; новый
маршрут `albums/[id]/photos/[photoId]`; новые значения токенов темы и стили скроллбаров;
`types.ts` (+`cover_thumb_url`, счётчики, `photos_count`); новые иконки в реестре.
- **Спеки:** `ui-workspace` (новая), `albums`, `photos` (дельты). `ui-iconography` не
затрагивается — иконки по-прежнему наследуют цвет темы.
- **Совместимость:** API-контракты сохраняются; добавляется поле ответа и один FK. Ломающих
изменений API нет.