Files
ds-galo/openspec/changes/lightroom-workspace-ui/proposal.md
T
iu 78996bc053 feat(frontend): select photo in album grid and show info in panel
- single click selects a photo (ring + aria-pressed) and shows its info in the right panel without navigating; double click opens the viewer
- shared 'selection' store; panel uses the route photo in viewer mode and the selected photo in album mode; selection resets on album change
- openspec: sync lightroom-workspace-ui (grid-selection requirement, viewer chrome wording without timers, nested f fullscreen, tasks 9.9/9.10)
2026-10-10 21:33:59 +03:00

97 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
- **Метаданные фото (EXIF).** При загрузке система извлекает все распознаваемые EXIF-атрибуты
(камера, объектив, экспозиция, ISO, дата съёмки, GPS и др.) и хранит их в `photos.exif`;
они возвращаются вместе с фото и показываются в разделе «Информация». Для ранее загруженных
фото есть команда бэкфилла метаданных из оригиналов.
- **Просмотр.** Полноэкранный режим (кнопка и `f`) с автоскрытием верхней/нижней панелей и
стрелок у кромок; зум колесом к указателю (без прокрутки, максимум 200%), `Space`
возвращает из любого зума во вписанный вид, в зуме догружается оригинал изображения;
удаление текущего фото с модальным подтверждением; возврат к обзору.
- **Разделы и панели.** Правая панель — сворачиваемые разделы (состояние сохраняется), с
разделом «Информация» (EXIF/метаданные); левая и правая панели ресайзятся перетаскиванием.
Выбор фото в сетке показывается в панели (одиночный клик), двойной клик открывает просмотр.
- **Настройки информации.** Раздел «Информация» получает кнопку-шестерёнку, открывающую
модалку со списком EXIF-атрибутов: галочки видимости (с действиями «отметить все»/«снять
все»), пользовательские подписи и сброс. Скрытые атрибуты сворачиваются под элементом «…»
(клик раскрывает все). Настройки хранятся в профиле пользователя (server-side), применяются
ко всем фото, а при отсутствии настроек показывается базовый набор; «Сбросить» удаляет
настройки из профиля.
- **Счётчики.** В ответе альбома — число фото и участников.
- **Темы и хром.** Существующие 4 темы сохраняются; `dark` — графит Lightroom и дефолт,
`neutral` — тёплый графит; переключатель упорядочен тёмная → нейтральная → светлая →
системная; добавляются токены `--chrome`/`--canvas`; скроллбары стилизованы в тон темы.
- **Адаптив.** На узких экранах рейл становится off-canvas drawer, правая панель —
bottom-sheet, filmstrip — горизонтальным скроллом.
## Capabilities
### New Capabilities
- `ui-workspace`: рабочий стол приложения — шелл, рейл альбомов, контекстная панель,
режим просмотра как маршрут, адаптивное поведение и тёмный хром.
### Modified Capabilities
- `albums`: отображение обложки, счётчики фото/участников и явный выбор обложки.
- `photos`: автообложка только при отсутствии выбора; переименование фото; лимит размера
загрузки; извлечение и хранение EXIF-метаданных.
- `auth`: хранение пользовательских настроек отображения информации в профиле.
## 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`; извлечение EXIF через
`github.com/dsoprea/go-exif/v3` в `photos.exif`, миграция `000003_photo_exif`, команда
`cmd/backfill-exif` и `storage.Get`); миграция `users.preferences`,
`models.User.Preferences`, `internal/auth` (`Me` отдаёт настройки,
`PATCH /auth/me/preferences` с валидацией).
- **Frontend:** реструктуризация `+layout.svelte` в группы `(app)`/`(public)`, `AppShell`
с ресайзом панелей и кнопкой полного экрана; компоненты рейла, контекстной панели со
сворачиваемыми разделами и EXIF, модалки создания/пикера обложки/подтверждения,
`Viewer` с полноэкранным режимом и зумом, общий стор альбомов, контрол плотности; новый
маршрут `albums/[id]/photos/[photoId]`; слот действий в `PanelSection`, модалка настроек
атрибутов с пользовательскими подписями, стор настроек, фильтрация и «…» в панели;
новые значения токенов темы и стили скроллбаров; `types.ts` (+`cover_thumb_url`, счётчики,
`photos_count`, `preferences`); новые иконки в реестре.
- **Спеки:** `ui-workspace` (новая), `albums`, `photos`, `auth` (дельты). `ui-iconography` не
затрагивается — иконки по-прежнему наследуют цвет темы.
- **Совместимость:** API-контракты сохраняются; добавляется поле ответа и один FK. Ломающих
изменений API нет.