Files
iu fa210e6c7f feat(android): album/photo attribute-actions and device gallery sync fixes
Album panel and photo sheet with attributes/actions for every album (server and
device), local album rename/cover/delete, EXIF attribute settings, and a unified
device-gallery sync check:

- add repository "Атрибуты и действия" panel (swipe left) on server and device
  albums: cover, info, navigation, rename/delete; album settings screen; photo
  sheet (swipe up) with info, tags and actions; EXIF attribute settings backed by
  profile preferences
- local albums use local metadata and actions: app-only display name and cover
  (new device_album_meta table), delete removes photos from the phone via the
  system delete consent
- unified mode x state policy (GallerySyncPolicy/SyncCheck) runs on start and on
  album open: upload/offload in move, restore originals in copy/off
- fix move->copy restore, offload of any linked-but-local original, provenance
  recovery that no longer overwrites the album mode, serialized reconcile and
  duplicate-upload suppression; prompt for "all files" access on start
- album card caption: name (with linked server name when different) and storage
  icons (memory card / cloud) with item count

Sync delta specs into android-client and archive the change
add-mobile-album-photo-actions.

Verified: unit/Robolectric suite green, :app:assembleDebug, :app:lint, and the
DeviceSyncE2ETest instrumented suite on the emulator (7/7).
2026-10-13 21:49:12 +03:00

10 KiB
Raw Permalink Blame History

Tasks

1. Клиентский API и DTO

  • 1.1 Добавить в PhotoDto/Photo поля exif, tags, uploader, download_url и разобрать их в маппере; проверить unit-тестом десериализации ответа GET /photos/:id
  • 1.2 Добавить preferences в ответ me() (UserDto/DTO профиля); проверить unit-тестом, что сохранённые photo_info читаются
  • 1.3 Добавить в GaloApi обновление альбома (PATCH /albums/:id с title/description/cover_photo_id/clear_cover), удаление (DELETE), список участников и share-ссылки; проверить unit-тестами запросов
  • 1.4 Добавить в GaloApi копирование (POST /photo-batch/copy), метки (POST/DELETE /photos/:id/tags, GET /tags?q=) и сохранение профиля (PATCH /auth/me/preferences); проверить unit-тестами
  • 1.5 Обновить android/README.md разделом о новых операциях API и проверить, что приведённые команды/примеры соответствуют коду

2. Модель атрибутов и резолвинг источника

  • 2.1 Ввести модель «атрибуты альбома» и резолвер источник→модель (серверный / локальный связанный / локальный без связи) отдельным классом домена; проверить unit-тестами все три случая
  • 2.2 Передавать сопоставление device-медиа→серверное фото (serverPhotoByMediaId) в DeviceViewerScreen; проверить unit-тестом, что элемент без сопоставления получает локальный источник, а со сопоставлением — серверный

3. Панель «Атрибуты и действия» на экранах альбомов

  • 3.1 Добавить на AlbumScreen end-drawer, открываемый свайпом справа налево, с общим контентом панели; проверить androidTest-жестом открытия и закрытия
  • 3.2 Добавить такой же end-drawer на DeviceAlbumScreen, не меняя левый drawer настроек синхронизации; проверить androidTest, что оба drawer'а открываются независимо
  • 3.3 Реализовать разделы «Обложка», «Информация», «Навигация» с гейтингом по роли (владелец/админ); проверить androidTest: у наблюдателя нет управления обложкой и навигации
  • 3.4 Реализовать действия «Переименовать» и «Удалить» с диалогом подтверждения и постановкой фото в корзину; проверить androidTest обоих сценариев
  • 3.5 Добавить экран настроек альбома (правка названия/описания, список участников, управление share-ссылками) и переход к нему из «Навигации»; проверить androidTest сохранения названия и создания/отзыва ссылки

4. Лист «Атрибуты и действия» в просмотре

  • 4.1 Добавить ModalBottomSheet в ViewerScreen и DeviceViewerScreen с открытием по свайпу вверх и условием «не открывать при зуме, панораме и активном видео»; проверить androidTest: при зуме/панораме лист не открывается
  • 4.2 Реализовать раздел «Информация» (автор, файл, тип, разрешение, EXIF, снято, координаты, загружено) и раздел «Метки» с добавлением/снятием и поиском; проверить androidTest появления метки и обновления без перезагрузки
  • 4.3 Реализовать действия «Скачать», «Переместить», «Копировать», «Установить как обложку», «Удалить» (по правам) и переименование по тапу на имя; проверить androidTest каждого действия, включая подтверждение удаления

5. Настройки списка атрибутов

  • 5.1 Перенести каталог EXIF-атрибутов и базовый набор (эквивалент web exif.ts) в Android; проверить unit-тестом, что базовый набор и подписи совпадают с web
  • 5.2 Реализовать экран настроек атрибутов (галочки видимости, поля подписей, «отметить все»/«снять все») и сохранение/сброс через preferences; проверить androidTest сохранения и сброса настроек

6. Интеграция и проверка

  • 6.1 Прогнать сквозные сценарии: серверный альбом (панель+настройки), device-альбом связанный и без связи, просмотр серверный и device (лист, метки, действия); проверить androidTest-сценариями
  • 6.2 Собрать и прогнать статический анализ: ./gradlew :app:assembleDebug :app:lint :app:testDebugUnitTest без ошибок

7. Локальные атрибуты и действия (все альбомы)

  • 7.1 Добавить app-only метаданные локального альбома (Room device_album_meta: отображаемое имя и обложка) и применять их в панели и списке альбомов; проверить unit- и Robolectric-тестами
  • 7.2 Показывать раздел «Навигация» у всех альбомов; строки «Участники»/«Ссылки» активны только при связи с серверным альбомом, иначе неактивны; проверить тестом
  • 7.3 Реализовать «Переименовать» (отображаемое имя в приложении) и локальную обложку (выбор из медиа альбома/сброс) для локального альбома; проверить тестами
  • 7.4 Реализовать «Удалить» локального альбома: подтверждение + удаление медиа с телефона через системное согласие (MediaStore.createDeleteRequest); проверить тестами

8. Полная проверка синхронизации

  • 8.1 SyncWorker реконсилирует все известные галереи (связанные + с локальным индексом), восстанавливает частичные связи через recover и перевыставляет незавершённые загрузки; проверить unit-тестами (reconcileAll, indexedAlbumIds)
  • 8.2 Запускать стартовую проверку после загрузки настроек (base URL) и вызывать reconcile при смене режима на серверный (не создавая связь с пустым серверным альбомом); проверить сборкой и тестами
  • 8.3 Разгрузка в режиме переноса выполняется автоматически после загрузки и повторно на следующем проходе (без баннера и отдельных запросов согласия); проверить unit-тестом повтора AWAITING_FREE
  • 8.4 Проверять доступ «Все файлы» при запуске и предлагать включить (диалог + системный экран); проверить Robolectric-тестом
  • 8.5 Проверка и исправление при открытии галереи: любой ассет, уже загруженный на сервер, но всё ещё с оригиналом на телефоне, разгружается в режиме переноса; проверить unit-тестами
  • 8.6 Возврат оригиналов при перенос→копии/выключено: восстановление не обрывается на единичных ошибках + довосстановление при запуске и открытии альбома; проверить тестами (restoreTargets, матрица переходов)
  • 8.7 Единая политика и проверка «режим × состояние» (GallerySyncPolicy/SyncCheck) с восстановлением индекса по метке; применяется при запуске и открытии альбома; проверить тестами на все сочетания
  • 8.8 Устранить гонки и дубли: сериализация reconcile, пропуск повторной загрузки при наличии задания в очереди, метка происхождения хранит режим (не состояние); проверить unit-тестами и инструментальными E2E на эмуляторе

9. Подпись карточки альбома

  • 9.1 Переделать подпись карточки: первая строка — имя и «→ имя серверного» только при различии имён; вторая строка — значки расположения (карта памяти / карта памяти + облако / облако) и число элементов; проверить Robolectric-тестами

Workflow follow-up

  • Архивация change после прохождения ревью проекта.
  • Проверка результата архивации.